@koda-sl/baker-cli 0.384.0 → 0.385.0-dev.f7ef4c7e1

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 (964) hide show
  1. package/README.md +1102 -218
  2. package/canvas/tiktok-captions-composition/index.html +5 -6
  3. package/canvas/tiktok-captions-composition/meta.json +5 -0
  4. package/dist/account-4UEZAY5T.js +49 -0
  5. package/dist/account-4UEZAY5T.js.map +1 -0
  6. package/dist/account-G6QK2VXQ.js +79 -0
  7. package/dist/account-G6QK2VXQ.js.map +1 -0
  8. package/dist/account-OINZG6UP.js +80 -0
  9. package/dist/account-OINZG6UP.js.map +1 -0
  10. package/dist/account-reads-ZKKDYHK5.js +218 -0
  11. package/dist/account-reads-ZKKDYHK5.js.map +1 -0
  12. package/dist/account-writes-N4JDIDRB.js +66 -0
  13. package/dist/account-writes-N4JDIDRB.js.map +1 -0
  14. package/dist/accounts-7KRRRVLB.js +611 -0
  15. package/dist/accounts-7KRRRVLB.js.map +1 -0
  16. package/dist/accounts-AEBQFCNH.js +114 -0
  17. package/dist/accounts-AEBQFCNH.js.map +1 -0
  18. package/dist/accounts-CNTOHRQ2.js +77 -0
  19. package/dist/accounts-CNTOHRQ2.js.map +1 -0
  20. package/dist/accounts-HP4BLKK5.js +75 -0
  21. package/dist/accounts-HP4BLKK5.js.map +1 -0
  22. package/dist/accounts-Z4CLGQXJ.js +115 -0
  23. package/dist/accounts-Z4CLGQXJ.js.map +1 -0
  24. package/dist/actions-QO7VQ6UV.js +55 -0
  25. package/dist/actions-QO7VQ6UV.js.map +1 -0
  26. package/dist/active-entities-YB46ADQN.js +103 -0
  27. package/dist/active-entities-YB46ADQN.js.map +1 -0
  28. package/dist/activities-DUAIQJLN.js +74 -0
  29. package/dist/activities-DUAIQJLN.js.map +1 -0
  30. package/dist/ad-group-writes-HL3EZ3BT.js +170 -0
  31. package/dist/ad-group-writes-HL3EZ3BT.js.map +1 -0
  32. package/dist/ad-groups-FGS5JJGN.js +68 -0
  33. package/dist/ad-groups-FGS5JJGN.js.map +1 -0
  34. package/dist/ad-writes-LX4ACUHB.js +174 -0
  35. package/dist/ad-writes-LX4ACUHB.js.map +1 -0
  36. package/dist/add-5CUXNOUM.js +97 -0
  37. package/dist/add-5CUXNOUM.js.map +1 -0
  38. package/dist/add-5JBMJHNW.js +302 -0
  39. package/dist/add-5JBMJHNW.js.map +1 -0
  40. package/dist/add-E66HBIZV.js +105 -0
  41. package/dist/add-E66HBIZV.js.map +1 -0
  42. package/dist/add-O76R2SPE.js +104 -0
  43. package/dist/add-O76R2SPE.js.map +1 -0
  44. package/dist/add-accounts-YME5SCXD.js +91 -0
  45. package/dist/add-accounts-YME5SCXD.js.map +1 -0
  46. package/dist/ads-65R3WMDU.js +128 -0
  47. package/dist/ads-65R3WMDU.js.map +1 -0
  48. package/dist/ads-O63J7BDF.js +113 -0
  49. package/dist/ads-O63J7BDF.js.map +1 -0
  50. package/dist/ads-T5JWNFSA.js +40 -0
  51. package/dist/ads-T5JWNFSA.js.map +1 -0
  52. package/dist/ads-TFZ5PXKS.js +77 -0
  53. package/dist/ads-TFZ5PXKS.js.map +1 -0
  54. package/dist/adsets-Y62JOOTV.js +176 -0
  55. package/dist/adsets-Y62JOOTV.js.map +1 -0
  56. package/dist/advertisers-LJ2HKJ4W.js +125 -0
  57. package/dist/advertisers-LJ2HKJ4W.js.map +1 -0
  58. package/dist/advertisers-WJW5DK3Q.js +120 -0
  59. package/dist/advertisers-WJW5DK3Q.js.map +1 -0
  60. package/dist/analytics-HIOC3TUK.js +1976 -0
  61. package/dist/analytics-HIOC3TUK.js.map +1 -0
  62. package/dist/analytics-U2NLDV2V.js +433 -0
  63. package/dist/analytics-U2NLDV2V.js.map +1 -0
  64. package/dist/animate-E3SKQ6SI.js +480 -0
  65. package/dist/animate-E3SKQ6SI.js.map +1 -0
  66. package/dist/assign-V7EAR7VD.js +77 -0
  67. package/dist/assign-V7EAR7VD.js.map +1 -0
  68. package/dist/audience-size-GS7EDBDP.js +94 -0
  69. package/dist/audience-size-GS7EDBDP.js.map +1 -0
  70. package/dist/audiences-5A6BCWSA.js +268 -0
  71. package/dist/audiences-5A6BCWSA.js.map +1 -0
  72. package/dist/audiences-6QOCASVV.js +78 -0
  73. package/dist/audiences-6QOCASVV.js.map +1 -0
  74. package/dist/audiences-O67NGIP5.js +85 -0
  75. package/dist/audiences-O67NGIP5.js.map +1 -0
  76. package/dist/audit-HWK24VXI.js +88 -0
  77. package/dist/audit-HWK24VXI.js.map +1 -0
  78. package/dist/audit-WMZERUAA.js +151 -0
  79. package/dist/audit-WMZERUAA.js.map +1 -0
  80. package/dist/autocomplete-KQSTLQFS.js +111 -0
  81. package/dist/autocomplete-KQSTLQFS.js.map +1 -0
  82. package/dist/avatars-HAFQZD63.js +38 -0
  83. package/dist/avatars-HAFQZD63.js.map +1 -0
  84. package/dist/bid-pricing-5SORFAPE.js +99 -0
  85. package/dist/bid-pricing-5SORFAPE.js.map +1 -0
  86. package/dist/brand-EBG436YV.js +22 -0
  87. package/dist/brand-EBG436YV.js.map +1 -0
  88. package/dist/brief-AYXXPTHC.js +490 -0
  89. package/dist/brief-AYXXPTHC.js.map +1 -0
  90. package/dist/businesses-65EWTK5E.js +53 -0
  91. package/dist/businesses-65EWTK5E.js.map +1 -0
  92. package/dist/campaign-groups-U7723BBE.js +95 -0
  93. package/dist/campaign-groups-U7723BBE.js.map +1 -0
  94. package/dist/campaign-writes-CXS4KYB5.js +165 -0
  95. package/dist/campaign-writes-CXS4KYB5.js.map +1 -0
  96. package/dist/campaign-writes-M6JLF5AC.js +170 -0
  97. package/dist/campaign-writes-M6JLF5AC.js.map +1 -0
  98. package/dist/campaigns-6SM2ZSIH.js +76 -0
  99. package/dist/campaigns-6SM2ZSIH.js.map +1 -0
  100. package/dist/campaigns-7DWD2A5U.js +109 -0
  101. package/dist/campaigns-7DWD2A5U.js.map +1 -0
  102. package/dist/campaigns-F66OYA6N.js +107 -0
  103. package/dist/campaigns-F66OYA6N.js.map +1 -0
  104. package/dist/campaigns-TD7ZB5DG.js +110 -0
  105. package/dist/campaigns-TD7ZB5DG.js.map +1 -0
  106. package/dist/canvas-3NYM5Y7G.js +46 -0
  107. package/dist/canvas-3NYM5Y7G.js.map +1 -0
  108. package/dist/capabilities-JNFYSGRD.js +144 -0
  109. package/dist/capabilities-JNFYSGRD.js.map +1 -0
  110. package/dist/cards-7HRC4UQQ.js +85 -0
  111. package/dist/cards-7HRC4UQQ.js.map +1 -0
  112. package/dist/catalog-N6MDMIVL.js +64 -0
  113. package/dist/catalog-N6MDMIVL.js.map +1 -0
  114. package/dist/catalogs-PB46L7FH.js +128 -0
  115. package/dist/catalogs-PB46L7FH.js.map +1 -0
  116. package/dist/changes-SASUQK62.js +135 -0
  117. package/dist/changes-SASUQK62.js.map +1 -0
  118. package/dist/chatgpt-JKBSAG25.js +47 -0
  119. package/dist/chatgpt-JKBSAG25.js.map +1 -0
  120. package/dist/chats-TUZANLQH.js +262 -0
  121. package/dist/chats-TUZANLQH.js.map +1 -0
  122. package/dist/chunk-25E6SC3F.js +363 -0
  123. package/dist/chunk-25E6SC3F.js.map +1 -0
  124. package/dist/chunk-2GVXNKAE.js +42 -0
  125. package/dist/chunk-2GVXNKAE.js.map +1 -0
  126. package/dist/{chunk-VLUGGVJL.js → chunk-2UFRHW3T.js} +12 -4
  127. package/dist/chunk-2UFRHW3T.js.map +1 -0
  128. package/dist/chunk-2Y5V23PU.js +29 -0
  129. package/dist/chunk-2Y5V23PU.js.map +1 -0
  130. package/dist/chunk-35NYNRRB.js +111 -0
  131. package/dist/chunk-35NYNRRB.js.map +1 -0
  132. package/dist/chunk-3ACMDRSE.js +39 -0
  133. package/dist/chunk-3ACMDRSE.js.map +1 -0
  134. package/dist/chunk-3M6RNCDD.js +26 -0
  135. package/dist/chunk-3M6RNCDD.js.map +1 -0
  136. package/dist/chunk-3VXQYDJN.js +1743 -0
  137. package/dist/chunk-3VXQYDJN.js.map +1 -0
  138. package/dist/chunk-42DF5DF3.js +304 -0
  139. package/dist/chunk-42DF5DF3.js.map +1 -0
  140. package/dist/chunk-44VXKO65.js +106 -0
  141. package/dist/chunk-44VXKO65.js.map +1 -0
  142. package/dist/chunk-4NZ47VXO.js +137 -0
  143. package/dist/chunk-4NZ47VXO.js.map +1 -0
  144. package/dist/chunk-4X3UR372.js +225 -0
  145. package/dist/chunk-4X3UR372.js.map +1 -0
  146. package/dist/chunk-5FEBUCJU.js +25 -0
  147. package/dist/chunk-5FEBUCJU.js.map +1 -0
  148. package/dist/chunk-5HYSKH77.js +315 -0
  149. package/dist/chunk-5HYSKH77.js.map +1 -0
  150. package/dist/chunk-5LBGFQWF.js +310 -0
  151. package/dist/chunk-5LBGFQWF.js.map +1 -0
  152. package/dist/chunk-5MBPIONY.js +29 -0
  153. package/dist/chunk-5MBPIONY.js.map +1 -0
  154. package/dist/chunk-6YMHGIHP.js +346 -0
  155. package/dist/chunk-6YMHGIHP.js.map +1 -0
  156. package/dist/{chunk-VZEDAFAR.js → chunk-6YYSUISH.js} +47 -8
  157. package/dist/chunk-6YYSUISH.js.map +1 -0
  158. package/dist/chunk-7GNU3P7X.js +175 -0
  159. package/dist/chunk-7GNU3P7X.js.map +1 -0
  160. package/dist/chunk-7OHWEF3I.js +98 -0
  161. package/dist/chunk-7OHWEF3I.js.map +1 -0
  162. package/dist/chunk-7TR3QVWM.js +57 -0
  163. package/dist/chunk-7TR3QVWM.js.map +1 -0
  164. package/dist/chunk-AADVCEL4.js +817 -0
  165. package/dist/chunk-AADVCEL4.js.map +1 -0
  166. package/dist/chunk-AG62YO7C.js +96 -0
  167. package/dist/chunk-AG62YO7C.js.map +1 -0
  168. package/dist/chunk-AIRIT4GF.js +75 -0
  169. package/dist/chunk-AIRIT4GF.js.map +1 -0
  170. package/dist/chunk-AP3TP6VG.js +139 -0
  171. package/dist/chunk-AP3TP6VG.js.map +1 -0
  172. package/dist/chunk-APP475IQ.js +474 -0
  173. package/dist/chunk-APP475IQ.js.map +1 -0
  174. package/dist/chunk-AR7PU7BB.js +76 -0
  175. package/dist/chunk-AR7PU7BB.js.map +1 -0
  176. package/dist/chunk-B4S72KSS.js +172 -0
  177. package/dist/chunk-B4S72KSS.js.map +1 -0
  178. package/dist/chunk-BIPIL4QA.js +486 -0
  179. package/dist/chunk-BIPIL4QA.js.map +1 -0
  180. package/dist/chunk-BPUSL5Y2.js +58 -0
  181. package/dist/chunk-BPUSL5Y2.js.map +1 -0
  182. package/dist/chunk-BR32GHYD.js +65 -0
  183. package/dist/chunk-BR32GHYD.js.map +1 -0
  184. package/dist/chunk-CAMX6OHF.js +3182 -0
  185. package/dist/chunk-CAMX6OHF.js.map +1 -0
  186. package/dist/chunk-CE7RTOX6.js +494 -0
  187. package/dist/chunk-CE7RTOX6.js.map +1 -0
  188. package/dist/{chunk-MF7YA62W.js → chunk-CUL3VB4L.js} +10 -5
  189. package/dist/chunk-CUL3VB4L.js.map +1 -0
  190. package/dist/chunk-CVEY353K.js +66 -0
  191. package/dist/chunk-CVEY353K.js.map +1 -0
  192. package/dist/chunk-CWXADUKL.js +1599 -0
  193. package/dist/chunk-CWXADUKL.js.map +1 -0
  194. package/dist/chunk-D46NOXRY.js +6212 -0
  195. package/dist/chunk-D46NOXRY.js.map +1 -0
  196. package/dist/chunk-D5FY4FAK.js +24 -0
  197. package/dist/chunk-D5FY4FAK.js.map +1 -0
  198. package/dist/chunk-DGCUPJZD.js +39 -0
  199. package/dist/chunk-DGCUPJZD.js.map +1 -0
  200. package/dist/chunk-DNCLWSHO.js +41 -0
  201. package/dist/chunk-DNCLWSHO.js.map +1 -0
  202. package/dist/chunk-DUPURL26.js +97 -0
  203. package/dist/chunk-DUPURL26.js.map +1 -0
  204. package/dist/chunk-DXJYQ5P2.js +625 -0
  205. package/dist/chunk-DXJYQ5P2.js.map +1 -0
  206. package/dist/chunk-E2ZOSNF5.js +96 -0
  207. package/dist/chunk-E2ZOSNF5.js.map +1 -0
  208. package/dist/chunk-E3HYHT7C.js +274 -0
  209. package/dist/chunk-E3HYHT7C.js.map +1 -0
  210. package/dist/chunk-EDLZGTGN.js +216 -0
  211. package/dist/chunk-EDLZGTGN.js.map +1 -0
  212. package/dist/{chunk-XHC4LMK4.js → chunk-EIGXX6KI.js} +16 -8
  213. package/dist/chunk-EIGXX6KI.js.map +1 -0
  214. package/dist/chunk-EPDE7ZRU.js +174 -0
  215. package/dist/chunk-EPDE7ZRU.js.map +1 -0
  216. package/dist/chunk-ERSX3MKH.js +34 -0
  217. package/dist/chunk-ERSX3MKH.js.map +1 -0
  218. package/dist/chunk-F7HRLPR5.js +67 -0
  219. package/dist/chunk-F7HRLPR5.js.map +1 -0
  220. package/dist/chunk-FEG6MN4H.js +84 -0
  221. package/dist/chunk-FEG6MN4H.js.map +1 -0
  222. package/dist/chunk-FKOECEVC.js +126 -0
  223. package/dist/chunk-FKOECEVC.js.map +1 -0
  224. package/dist/chunk-FMGW2NZI.js +106 -0
  225. package/dist/chunk-FMGW2NZI.js.map +1 -0
  226. package/dist/chunk-FPZKKNDK.js +98 -0
  227. package/dist/chunk-FPZKKNDK.js.map +1 -0
  228. package/dist/chunk-G3ZDLPNZ.js +206 -0
  229. package/dist/chunk-G3ZDLPNZ.js.map +1 -0
  230. package/dist/chunk-GIWHHCD6.js +145 -0
  231. package/dist/chunk-GIWHHCD6.js.map +1 -0
  232. package/dist/chunk-GOJXKIFQ.js +1605 -0
  233. package/dist/chunk-GOJXKIFQ.js.map +1 -0
  234. package/dist/chunk-GRQ2AXDX.js +9 -0
  235. package/dist/chunk-GRQ2AXDX.js.map +1 -0
  236. package/dist/chunk-GXDLWBOY.js +73 -0
  237. package/dist/chunk-GXDLWBOY.js.map +1 -0
  238. package/dist/chunk-HAE4WWFQ.js +455 -0
  239. package/dist/chunk-HAE4WWFQ.js.map +1 -0
  240. package/dist/chunk-HEEAC2YG.js +541 -0
  241. package/dist/chunk-HEEAC2YG.js.map +1 -0
  242. package/dist/chunk-I2DNBEV6.js +4227 -0
  243. package/dist/chunk-I2DNBEV6.js.map +1 -0
  244. package/dist/chunk-I4FTS5EE.js +455 -0
  245. package/dist/chunk-I4FTS5EE.js.map +1 -0
  246. package/dist/chunk-IA4KJU7O.js +3151 -0
  247. package/dist/chunk-IA4KJU7O.js.map +1 -0
  248. package/dist/chunk-IELPT4K2.js +74 -0
  249. package/dist/chunk-IELPT4K2.js.map +1 -0
  250. package/dist/chunk-IJMWEO4P.js +57 -0
  251. package/dist/chunk-IJMWEO4P.js.map +1 -0
  252. package/dist/chunk-IVIJJXXT.js +62 -0
  253. package/dist/chunk-IVIJJXXT.js.map +1 -0
  254. package/dist/chunk-JAU6OAFK.js +455 -0
  255. package/dist/chunk-JAU6OAFK.js.map +1 -0
  256. package/dist/chunk-JD3W3ON7.js +188 -0
  257. package/dist/chunk-JD3W3ON7.js.map +1 -0
  258. package/dist/chunk-JLWBK3VC.js +5187 -0
  259. package/dist/chunk-JLWBK3VC.js.map +1 -0
  260. package/dist/chunk-JPK34QPS.js +134 -0
  261. package/dist/chunk-JPK34QPS.js.map +1 -0
  262. package/dist/chunk-JXJD6RC5.js +169 -0
  263. package/dist/chunk-JXJD6RC5.js.map +1 -0
  264. package/dist/chunk-JXMZEOHV.js +333 -0
  265. package/dist/chunk-JXMZEOHV.js.map +1 -0
  266. package/dist/chunk-K6TDB2KV.js +1442 -0
  267. package/dist/chunk-K6TDB2KV.js.map +1 -0
  268. package/dist/chunk-KIGGMKAE.js +66 -0
  269. package/dist/chunk-KIGGMKAE.js.map +1 -0
  270. package/dist/chunk-KKJ4KJCW.js +29 -0
  271. package/dist/chunk-KKJ4KJCW.js.map +1 -0
  272. package/dist/chunk-KONA5PSR.js +55 -0
  273. package/dist/chunk-KONA5PSR.js.map +1 -0
  274. package/dist/chunk-KVHRW7KO.js +60 -0
  275. package/dist/chunk-KVHRW7KO.js.map +1 -0
  276. package/dist/chunk-LA6PPSNA.js +65 -0
  277. package/dist/chunk-LA6PPSNA.js.map +1 -0
  278. package/dist/chunk-LKPJADL2.js +74 -0
  279. package/dist/chunk-LKPJADL2.js.map +1 -0
  280. package/dist/chunk-LM7N7IQR.js +297 -0
  281. package/dist/chunk-LM7N7IQR.js.map +1 -0
  282. package/dist/chunk-LWAEHLKV.js +74 -0
  283. package/dist/chunk-LWAEHLKV.js.map +1 -0
  284. package/dist/chunk-M6UNISGO.js +66 -0
  285. package/dist/chunk-M6UNISGO.js.map +1 -0
  286. package/dist/chunk-MFSIACRB.js +207 -0
  287. package/dist/chunk-MFSIACRB.js.map +1 -0
  288. package/dist/chunk-MIJAGBEP.js +23992 -0
  289. package/dist/chunk-MIJAGBEP.js.map +1 -0
  290. package/dist/chunk-MYTDK3AL.js +2102 -0
  291. package/dist/chunk-MYTDK3AL.js.map +1 -0
  292. package/dist/chunk-MYURCD23.js +6667 -0
  293. package/dist/chunk-MYURCD23.js.map +1 -0
  294. package/dist/chunk-MZQ5DX6S.js +125 -0
  295. package/dist/chunk-MZQ5DX6S.js.map +1 -0
  296. package/dist/chunk-NFSLRRIE.js +77 -0
  297. package/dist/chunk-NFSLRRIE.js.map +1 -0
  298. package/dist/chunk-NMDP7FZP.js +479 -0
  299. package/dist/chunk-NMDP7FZP.js.map +1 -0
  300. package/dist/chunk-NMGELUIA.js +183 -0
  301. package/dist/chunk-NMGELUIA.js.map +1 -0
  302. package/dist/chunk-NOK7MSVJ.js +533 -0
  303. package/dist/chunk-NOK7MSVJ.js.map +1 -0
  304. package/dist/chunk-O2EVJALZ.js +133 -0
  305. package/dist/chunk-O2EVJALZ.js.map +1 -0
  306. package/dist/chunk-OIL6PU5W.js +35 -0
  307. package/dist/chunk-OIL6PU5W.js.map +1 -0
  308. package/dist/chunk-P4NSJS54.js +20 -0
  309. package/dist/chunk-P4NSJS54.js.map +1 -0
  310. package/dist/chunk-P5T7OZKV.js +26 -0
  311. package/dist/chunk-P5T7OZKV.js.map +1 -0
  312. package/dist/chunk-PFBQERWX.js +10 -0
  313. package/dist/chunk-PFBQERWX.js.map +1 -0
  314. package/dist/chunk-PSWVSLJU.js +56 -0
  315. package/dist/chunk-PSWVSLJU.js.map +1 -0
  316. package/dist/chunk-PY2NJ6XZ.js +191 -0
  317. package/dist/chunk-PY2NJ6XZ.js.map +1 -0
  318. package/dist/chunk-PZ4OM2LK.js +45 -0
  319. package/dist/chunk-PZ4OM2LK.js.map +1 -0
  320. package/dist/chunk-Q2EKN7NI.js +1079 -0
  321. package/dist/chunk-Q2EKN7NI.js.map +1 -0
  322. package/dist/chunk-Q6ULQMWG.js +41 -0
  323. package/dist/chunk-Q6ULQMWG.js.map +1 -0
  324. package/dist/chunk-QMLGJ5OW.js +2891 -0
  325. package/dist/chunk-QMLGJ5OW.js.map +1 -0
  326. package/dist/chunk-R7QV5N2S.js +846 -0
  327. package/dist/chunk-R7QV5N2S.js.map +1 -0
  328. package/dist/chunk-RCS4JKUD.js +23 -0
  329. package/dist/chunk-RCS4JKUD.js.map +1 -0
  330. package/dist/chunk-RR3KT2E7.js +665 -0
  331. package/dist/chunk-RR3KT2E7.js.map +1 -0
  332. package/dist/chunk-SEPPFM5S.js +228 -0
  333. package/dist/chunk-SEPPFM5S.js.map +1 -0
  334. package/dist/chunk-SQ7DRYCC.js +150 -0
  335. package/dist/chunk-SQ7DRYCC.js.map +1 -0
  336. package/dist/chunk-SYULM665.js +610 -0
  337. package/dist/chunk-SYULM665.js.map +1 -0
  338. package/dist/chunk-TKT3OHZ6.js +170 -0
  339. package/dist/chunk-TKT3OHZ6.js.map +1 -0
  340. package/dist/chunk-TNOSX3PJ.js +136 -0
  341. package/dist/chunk-TNOSX3PJ.js.map +1 -0
  342. package/dist/chunk-TTVKI54A.js +160 -0
  343. package/dist/chunk-TTVKI54A.js.map +1 -0
  344. package/dist/chunk-U55UZRIB.js +592 -0
  345. package/dist/chunk-U55UZRIB.js.map +1 -0
  346. package/dist/chunk-UI6BKYQD.js +225 -0
  347. package/dist/chunk-UI6BKYQD.js.map +1 -0
  348. package/dist/chunk-UKE4IZSA.js +337 -0
  349. package/dist/chunk-UKE4IZSA.js.map +1 -0
  350. package/dist/chunk-UKLDW4UW.js +46 -0
  351. package/dist/chunk-UKLDW4UW.js.map +1 -0
  352. package/dist/chunk-V6XXXEXZ.js +76 -0
  353. package/dist/chunk-V6XXXEXZ.js.map +1 -0
  354. package/dist/chunk-VCZSZCXY.js +197 -0
  355. package/dist/chunk-VCZSZCXY.js.map +1 -0
  356. package/dist/chunk-VJQWUF66.js +92 -0
  357. package/dist/chunk-VJQWUF66.js.map +1 -0
  358. package/dist/chunk-VSU5R34H.js +76 -0
  359. package/dist/chunk-VSU5R34H.js.map +1 -0
  360. package/dist/chunk-W4SA4CMR.js +296 -0
  361. package/dist/chunk-W4SA4CMR.js.map +1 -0
  362. package/dist/chunk-WFUMNDCE.js +111 -0
  363. package/dist/chunk-WFUMNDCE.js.map +1 -0
  364. package/dist/chunk-WGCGKU3M.js +51 -0
  365. package/dist/chunk-WGCGKU3M.js.map +1 -0
  366. package/dist/chunk-WHWNXLTD.js +166 -0
  367. package/dist/chunk-WHWNXLTD.js.map +1 -0
  368. package/dist/chunk-WN42X2OE.js +509 -0
  369. package/dist/chunk-WN42X2OE.js.map +1 -0
  370. package/dist/chunk-WN4KX7GE.js +25 -0
  371. package/dist/chunk-WN4KX7GE.js.map +1 -0
  372. package/dist/chunk-XIY7P54H.js +84 -0
  373. package/dist/chunk-XIY7P54H.js.map +1 -0
  374. package/dist/chunk-XPLTWUMN.js +103 -0
  375. package/dist/chunk-XPLTWUMN.js.map +1 -0
  376. package/dist/chunk-Y6T5ZKBK.js +19 -0
  377. package/dist/chunk-Y6T5ZKBK.js.map +1 -0
  378. package/dist/chunk-YGGRQXDP.js +382 -0
  379. package/dist/chunk-YGGRQXDP.js.map +1 -0
  380. package/dist/chunk-YMBB4JBD.js +1830 -0
  381. package/dist/chunk-YMBB4JBD.js.map +1 -0
  382. package/dist/chunk-YNWM426O.js +159 -0
  383. package/dist/chunk-YNWM426O.js.map +1 -0
  384. package/dist/chunk-YQSBHWOI.js +41 -0
  385. package/dist/chunk-YTF3IVMF.js +149 -0
  386. package/dist/chunk-YTF3IVMF.js.map +1 -0
  387. package/dist/chunk-Z3ENMCFE.js +94 -0
  388. package/dist/chunk-Z3ENMCFE.js.map +1 -0
  389. package/dist/chunk-Z7MWSXLG.js +94 -0
  390. package/dist/chunk-Z7MWSXLG.js.map +1 -0
  391. package/dist/chunk-ZIXHS6AM.js +42 -0
  392. package/dist/chunk-ZIXHS6AM.js.map +1 -0
  393. package/dist/chunk-ZJ7TQUCU.js +4410 -0
  394. package/dist/chunk-ZJ7TQUCU.js.map +1 -0
  395. package/dist/chunk-ZNQRDLSS.js +52 -0
  396. package/dist/chunk-ZNQRDLSS.js.map +1 -0
  397. package/dist/chunk-ZPGGSXU3.js +275 -0
  398. package/dist/chunk-ZPGGSXU3.js.map +1 -0
  399. package/dist/claim-NXYQZEMC.js +197 -0
  400. package/dist/claim-NXYQZEMC.js.map +1 -0
  401. package/dist/cli.js +104 -69952
  402. package/dist/cli.js.map +1 -1
  403. package/dist/client-EURRWXPW.js +19 -0
  404. package/dist/code-FKQW7V7N.js +76 -0
  405. package/dist/code-FKQW7V7N.js.map +1 -0
  406. package/dist/companies-5ZH47E4H.js +195 -0
  407. package/dist/companies-5ZH47E4H.js.map +1 -0
  408. package/dist/complete-62OQPRHW.js +81 -0
  409. package/dist/complete-62OQPRHW.js.map +1 -0
  410. package/dist/config-OZOHIAOJ.js +88 -0
  411. package/dist/config-OZOHIAOJ.js.map +1 -0
  412. package/dist/connect-6DQFYKGN.js +42 -0
  413. package/dist/content-PCGSX2QU.js +85 -0
  414. package/dist/content-PCGSX2QU.js.map +1 -0
  415. package/dist/conversation-NS7JHTPK.js +93 -0
  416. package/dist/conversation-NS7JHTPK.js.map +1 -0
  417. package/dist/conversion-report-7QSWB2FY.js +125 -0
  418. package/dist/conversion-report-7QSWB2FY.js.map +1 -0
  419. package/dist/conversion-upload-command-XESIAQPU.js +438 -0
  420. package/dist/conversion-upload-command-XESIAQPU.js.map +1 -0
  421. package/dist/conversion-writes-BGOVLBS5.js +120 -0
  422. package/dist/conversion-writes-BGOVLBS5.js.map +1 -0
  423. package/dist/conversions-46MI57VC.js +135 -0
  424. package/dist/conversions-46MI57VC.js.map +1 -0
  425. package/dist/conversions-IYIWW4O7.js +76 -0
  426. package/dist/conversions-IYIWW4O7.js.map +1 -0
  427. package/dist/countries-5OBUVLLD.js +82 -0
  428. package/dist/countries-5OBUVLLD.js.map +1 -0
  429. package/dist/create-BEDPXUB7.js +236 -0
  430. package/dist/create-BEDPXUB7.js.map +1 -0
  431. package/dist/create-LLTMBBGV.js +207 -0
  432. package/dist/create-LLTMBBGV.js.map +1 -0
  433. package/dist/create-VNJ2VH3A.js +59 -0
  434. package/dist/create-VNJ2VH3A.js.map +1 -0
  435. package/dist/create-ZYKG2XOP.js +138 -0
  436. package/dist/create-ZYKG2XOP.js.map +1 -0
  437. package/dist/creatives-2LL66X4E.js +51 -0
  438. package/dist/creatives-2LL66X4E.js.map +1 -0
  439. package/dist/creatives-3MEMSUKJ.js +182 -0
  440. package/dist/creatives-3MEMSUKJ.js.map +1 -0
  441. package/dist/creatives-XI2DGQUZ.js +87 -0
  442. package/dist/creatives-XI2DGQUZ.js.map +1 -0
  443. package/dist/credentials-63PRTM3K.js +287 -0
  444. package/dist/credentials-63PRTM3K.js.map +1 -0
  445. package/dist/critique-IQI7CCTT.js +213 -0
  446. package/dist/critique-IQI7CCTT.js.map +1 -0
  447. package/dist/critique-UV7FPG45.js +1449 -0
  448. package/dist/critique-UV7FPG45.js.map +1 -0
  449. package/dist/crm-OERYUOBS.js +224 -0
  450. package/dist/crm-OERYUOBS.js.map +1 -0
  451. package/dist/crm-VNO3QTQG.js +318 -0
  452. package/dist/crm-VNO3QTQG.js.map +1 -0
  453. package/dist/crop-B52KIQ4O.js +113 -0
  454. package/dist/crop-B52KIQ4O.js.map +1 -0
  455. package/dist/currency-GGWF5DMU.js +88 -0
  456. package/dist/currency-GGWF5DMU.js.map +1 -0
  457. package/dist/custom-conversions-7WDBTC4X.js +125 -0
  458. package/dist/custom-conversions-7WDBTC4X.js.map +1 -0
  459. package/dist/customers-FOPXEGCB.js +56 -0
  460. package/dist/decide-PK7WNSQ2.js +199 -0
  461. package/dist/decide-PK7WNSQ2.js.map +1 -0
  462. package/dist/delete-56LKNEGA.js +71 -0
  463. package/dist/delete-56LKNEGA.js.map +1 -0
  464. package/dist/delete-EZ7HHOOD.js +69 -0
  465. package/dist/delete-EZ7HHOOD.js.map +1 -0
  466. package/dist/delete-JSYM7QKN.js +54 -0
  467. package/dist/delete-JSYM7QKN.js.map +1 -0
  468. package/dist/delete-NOUWBNZM.js +66 -0
  469. package/dist/delete-NOUWBNZM.js.map +1 -0
  470. package/dist/delete-T33AWV63.js +63 -0
  471. package/dist/delete-T33AWV63.js.map +1 -0
  472. package/dist/delete-YSYVFL6W.js +71 -0
  473. package/dist/delete-YSYVFL6W.js.map +1 -0
  474. package/dist/demographics-LQGFUS4F.js +138 -0
  475. package/dist/demographics-LQGFUS4F.js.map +1 -0
  476. package/dist/describe-AAVYIFE3.js +97 -0
  477. package/dist/describe-AAVYIFE3.js.map +1 -0
  478. package/dist/describe-UQFLWVFR.js +97 -0
  479. package/dist/describe-UQFLWVFR.js.map +1 -0
  480. package/dist/dimensions-QDXBG2XC.js +101 -0
  481. package/dist/dimensions-QDXBG2XC.js.map +1 -0
  482. package/dist/discard-V4LQ7ZGA.js +66 -0
  483. package/dist/discard-V4LQ7ZGA.js.map +1 -0
  484. package/dist/discover-6TEBPVNC.js +93 -0
  485. package/dist/discover-6TEBPVNC.js.map +1 -0
  486. package/dist/discover-SBZPB7T2.js +172 -0
  487. package/dist/discover-SBZPB7T2.js.map +1 -0
  488. package/dist/domain-65J2DEDB.js +98 -0
  489. package/dist/domain-65J2DEDB.js.map +1 -0
  490. package/dist/download-LV3GPOWV.js +299 -0
  491. package/dist/download-LV3GPOWV.js.map +1 -0
  492. package/dist/draft-DDFFTZ43.js +233 -0
  493. package/dist/draft-DDFFTZ43.js.map +1 -0
  494. package/dist/draft-FIKJXNIQ.js +281 -0
  495. package/dist/draft-FIKJXNIQ.js.map +1 -0
  496. package/dist/draft-GYGWTMBU.js +307 -0
  497. package/dist/draft-GYGWTMBU.js.map +1 -0
  498. package/dist/draft-KNXVZAZV.js +217 -0
  499. package/dist/draft-KNXVZAZV.js.map +1 -0
  500. package/dist/draft-N4LFPKTA.js +100 -0
  501. package/dist/draft-N4LFPKTA.js.map +1 -0
  502. package/dist/draft-NG2DPL2X.js +306 -0
  503. package/dist/draft-NG2DPL2X.js.map +1 -0
  504. package/dist/draft-QILZ7M7N.js +328 -0
  505. package/dist/draft-QILZ7M7N.js.map +1 -0
  506. package/dist/draft-XPO5RWST.js +103 -0
  507. package/dist/draft-XPO5RWST.js.map +1 -0
  508. package/dist/engine/index.d.ts +213 -127
  509. package/dist/engine/index.js +18 -4
  510. package/dist/{env-4P5HOGNA.js → env-TQ2XS2KY.js} +12 -2
  511. package/dist/env-TQ2XS2KY.js.map +1 -0
  512. package/dist/experiment-FQNKMORZ.js +1397 -0
  513. package/dist/experiment-FQNKMORZ.js.map +1 -0
  514. package/dist/export-4IZQZAPF.js +168 -0
  515. package/dist/export-4IZQZAPF.js.map +1 -0
  516. package/dist/extract-DZMGVQ7D.js +113 -0
  517. package/dist/extract-DZMGVQ7D.js.map +1 -0
  518. package/dist/facets-FAAOFHBF.js +114 -0
  519. package/dist/facets-FAAOFHBF.js.map +1 -0
  520. package/dist/favorites-DD2LNSTG.js +178 -0
  521. package/dist/favorites-DD2LNSTG.js.map +1 -0
  522. package/dist/feed-TUVFNX2U.js +177 -0
  523. package/dist/feed-TUVFNX2U.js.map +1 -0
  524. package/dist/feedback-NWOOZOFW.js +66 -0
  525. package/dist/feedback-NWOOZOFW.js.map +1 -0
  526. package/dist/feedback-record-CFPUKLMY.js +175 -0
  527. package/dist/feedback-record-CFPUKLMY.js.map +1 -0
  528. package/dist/fetch-LEY77E7V.js +176 -0
  529. package/dist/fetch-LEY77E7V.js.map +1 -0
  530. package/dist/fetch-O6UHNXWB.js +139 -0
  531. package/dist/fetch-O6UHNXWB.js.map +1 -0
  532. package/dist/find-4XKIBF4D.js +134 -0
  533. package/dist/find-4XKIBF4D.js.map +1 -0
  534. package/dist/fit-ODVVXV2Q.js +45 -0
  535. package/dist/fit-ODVVXV2Q.js.map +1 -0
  536. package/dist/flows-QKPC63AF.js +247 -0
  537. package/dist/flows-QKPC63AF.js.map +1 -0
  538. package/dist/follow-RCOXTZGY.js +94 -0
  539. package/dist/follow-RCOXTZGY.js.map +1 -0
  540. package/dist/follow-competitors-SQ5XBFTK.js +112 -0
  541. package/dist/follow-competitors-SQ5XBFTK.js.map +1 -0
  542. package/dist/following-VDU3BHC4.js +113 -0
  543. package/dist/following-VDU3BHC4.js.map +1 -0
  544. package/dist/fonts-WM2MJDVJ.js +34 -0
  545. package/dist/fonts-WM2MJDVJ.js.map +1 -0
  546. package/dist/forecast-2GJKBNBM.js +168 -0
  547. package/dist/forecast-2GJKBNBM.js.map +1 -0
  548. package/dist/forecast-7K3TAHDL.js +104 -0
  549. package/dist/forecast-7K3TAHDL.js.map +1 -0
  550. package/dist/funding-HTFVZLLG.js +85 -0
  551. package/dist/funding-HTFVZLLG.js.map +1 -0
  552. package/dist/funnel-CSPK5SPZ.js +394 -0
  553. package/dist/funnel-CSPK5SPZ.js.map +1 -0
  554. package/dist/ga4-2RC4EH7V.js +55 -0
  555. package/dist/ga4-2RC4EH7V.js.map +1 -0
  556. package/dist/generate-TPDOBCKQ.js +262 -0
  557. package/dist/generate-TPDOBCKQ.js.map +1 -0
  558. package/dist/get-4YZ4PI3B.js +56 -0
  559. package/dist/get-4YZ4PI3B.js.map +1 -0
  560. package/dist/get-FH2LIEYL.js +63 -0
  561. package/dist/get-FH2LIEYL.js.map +1 -0
  562. package/dist/get-GZLCDXXW.js +61 -0
  563. package/dist/get-GZLCDXXW.js.map +1 -0
  564. package/dist/get-HFU6ZJPX.js +78 -0
  565. package/dist/get-HFU6ZJPX.js.map +1 -0
  566. package/dist/get-TSPQYEKC.js +59 -0
  567. package/dist/get-TSPQYEKC.js.map +1 -0
  568. package/dist/get-TY3RXYNZ.js +63 -0
  569. package/dist/get-TY3RXYNZ.js.map +1 -0
  570. package/dist/get-VPW33XTN.js +92 -0
  571. package/dist/get-VPW33XTN.js.map +1 -0
  572. package/dist/gif-JFEYPFFI.js +94 -0
  573. package/dist/gif-JFEYPFFI.js.map +1 -0
  574. package/dist/google-R6RD4L6Z.js +136 -0
  575. package/dist/google-R6RD4L6Z.js.map +1 -0
  576. package/dist/google-VPQNRVIB.js +3190 -0
  577. package/dist/google-VPQNRVIB.js.map +1 -0
  578. package/dist/google-ads-WWM5KIRS.js +195 -0
  579. package/dist/google-ads-WWM5KIRS.js.map +1 -0
  580. package/dist/group-7AV6UL26.js +43 -0
  581. package/dist/group-7AV6UL26.js.map +1 -0
  582. package/dist/group-BVQZEZIC.js +43 -0
  583. package/dist/group-BVQZEZIC.js.map +1 -0
  584. package/dist/gsc-SQ42WAQE.js +30 -0
  585. package/dist/gsc-SQ42WAQE.js.map +1 -0
  586. package/dist/history-BNNHFURR.js +67 -0
  587. package/dist/history-BNNHFURR.js.map +1 -0
  588. package/dist/history-KBK5TP65.js +133 -0
  589. package/dist/history-KBK5TP65.js.map +1 -0
  590. package/dist/hubspot-GAAWWVLL.js +779 -0
  591. package/dist/hubspot-GAAWWVLL.js.map +1 -0
  592. package/dist/icon-OYTTSNSL.js +137 -0
  593. package/dist/icon-OYTTSNSL.js.map +1 -0
  594. package/dist/ideas-CELMD3BL.js +32 -0
  595. package/dist/ideas-CELMD3BL.js.map +1 -0
  596. package/dist/images-QHV4ECAP.js +90 -0
  597. package/dist/images-QHV4ECAP.js.map +1 -0
  598. package/dist/improve-W6GZNT2A.js +86 -0
  599. package/dist/improve-W6GZNT2A.js.map +1 -0
  600. package/dist/ingest-SH35YX6X.js +23 -0
  601. package/dist/ingest-SH35YX6X.js.map +1 -0
  602. package/dist/ingest-UWCGJZXV.js +107 -0
  603. package/dist/ingest-UWCGJZXV.js.map +1 -0
  604. package/dist/insights-IW7LGAWU.js +423 -0
  605. package/dist/insights-IW7LGAWU.js.map +1 -0
  606. package/dist/insights-QH54F56A.js +122 -0
  607. package/dist/insights-QH54F56A.js.map +1 -0
  608. package/dist/inspect-6Z6HEMBI.js +189 -0
  609. package/dist/inspect-6Z6HEMBI.js.map +1 -0
  610. package/dist/inspiration-RDQ3Y3N3.js +53 -0
  611. package/dist/inspiration-RDQ3Y3N3.js.map +1 -0
  612. package/dist/intent-5GSSCFZ2.js +95 -0
  613. package/dist/intent-5GSSCFZ2.js.map +1 -0
  614. package/dist/job-URVXJP75.js +202 -0
  615. package/dist/job-URVXJP75.js.map +1 -0
  616. package/dist/job-create-S4SECUVF.js +109 -0
  617. package/dist/job-create-S4SECUVF.js.map +1 -0
  618. package/dist/job-status-253SUCTJ.js +74 -0
  619. package/dist/job-status-253SUCTJ.js.map +1 -0
  620. package/dist/keep-GPSYDIGJ.js +78 -0
  621. package/dist/keep-GPSYDIGJ.js.map +1 -0
  622. package/dist/keyword-gap-NTFDX43B.js +130 -0
  623. package/dist/keyword-gap-NTFDX43B.js.map +1 -0
  624. package/dist/keyword-metrics-NKZRCF4L.js +197 -0
  625. package/dist/keyword-metrics-NKZRCF4L.js.map +1 -0
  626. package/dist/keywords-for-site-NQUPJNUR.js +128 -0
  627. package/dist/keywords-for-site-NQUPJNUR.js.map +1 -0
  628. package/dist/landing-AHNZSZHY.js +28 -0
  629. package/dist/landing-AHNZSZHY.js.map +1 -0
  630. package/dist/landings-NEF4PQL2.js +151 -0
  631. package/dist/landings-NEF4PQL2.js.map +1 -0
  632. package/dist/languages-3RDPPPTE.js +55 -0
  633. package/dist/languages-3RDPPPTE.js.map +1 -0
  634. package/dist/languages-CQX3YOIT.js +40 -0
  635. package/dist/languages-CQX3YOIT.js.map +1 -0
  636. package/dist/launches-GBHLJH5S.js +19 -0
  637. package/dist/launches-GBHLJH5S.js.map +1 -0
  638. package/dist/layerize-Q56C6LFG.js +190 -0
  639. package/dist/layerize-Q56C6LFG.js.map +1 -0
  640. package/dist/leads-5MUVPXA2.js +90 -0
  641. package/dist/leads-5MUVPXA2.js.map +1 -0
  642. package/dist/leads-JHUM6FYR.js +293 -0
  643. package/dist/leads-JHUM6FYR.js.map +1 -0
  644. package/dist/learn-EMV7RWTB.js +203 -0
  645. package/dist/learn-EMV7RWTB.js.map +1 -0
  646. package/dist/library-6VUFHTEK.js +109 -0
  647. package/dist/library-6VUFHTEK.js.map +1 -0
  648. package/dist/lighthouse-57U2GMPV.js +75 -0
  649. package/dist/lighthouse-57U2GMPV.js.map +1 -0
  650. package/dist/line-item-writes-GMIZYHLB.js +208 -0
  651. package/dist/line-item-writes-GMIZYHLB.js.map +1 -0
  652. package/dist/line-items-B5HAC47U.js +103 -0
  653. package/dist/line-items-B5HAC47U.js.map +1 -0
  654. package/dist/link-B6ZJFGFE.js +64 -0
  655. package/dist/link-B6ZJFGFE.js.map +1 -0
  656. package/dist/linkedin-FJ3OUYT2.js +1008 -0
  657. package/dist/linkedin-FJ3OUYT2.js.map +1 -0
  658. package/dist/list-2MBSU4ZX.js +63 -0
  659. package/dist/list-2MBSU4ZX.js.map +1 -0
  660. package/dist/list-EFUPHLG3.js +303 -0
  661. package/dist/list-EFUPHLG3.js.map +1 -0
  662. package/dist/list-G57ZO4PG.js +50 -0
  663. package/dist/list-G57ZO4PG.js.map +1 -0
  664. package/dist/list-JCSWZWDI.js +57 -0
  665. package/dist/list-JCSWZWDI.js.map +1 -0
  666. package/dist/list-QOSPRCH4.js +151 -0
  667. package/dist/list-QOSPRCH4.js.map +1 -0
  668. package/dist/list-RINCJOAC.js +76 -0
  669. package/dist/list-RINCJOAC.js.map +1 -0
  670. package/dist/list-SRNXHS6L.js +51 -0
  671. package/dist/list-SRNXHS6L.js.map +1 -0
  672. package/dist/list-YJSO4M5Q.js +65 -0
  673. package/dist/list-YJSO4M5Q.js.map +1 -0
  674. package/dist/locations-HW2Y5OJO.js +67 -0
  675. package/dist/locations-HW2Y5OJO.js.map +1 -0
  676. package/dist/locations-XOHI3VWI.js +40 -0
  677. package/dist/locations-XOHI3VWI.js.map +1 -0
  678. package/dist/log-SZDYUMM3.js +92 -0
  679. package/dist/log-SZDYUMM3.js.map +1 -0
  680. package/dist/logo-KXTGIYBI.js +18 -0
  681. package/dist/logo-KXTGIYBI.js.map +1 -0
  682. package/dist/lookup-X6O5UNJH.js +22 -0
  683. package/dist/lookup-X6O5UNJH.js.map +1 -0
  684. package/dist/make-SGCBJTRR.js +633 -0
  685. package/dist/make-SGCBJTRR.js.map +1 -0
  686. package/dist/map-ZK46VVL3.js +404 -0
  687. package/dist/map-ZK46VVL3.js.map +1 -0
  688. package/dist/mcp-NCM5TQUG.js +463 -0
  689. package/dist/mcp-NCM5TQUG.js.map +1 -0
  690. package/dist/media-MI4EE7L4.js +89 -0
  691. package/dist/media-MI4EE7L4.js.map +1 -0
  692. package/dist/media-QUTQOBA7.js +15 -0
  693. package/dist/media-QUTQOBA7.js.map +1 -0
  694. package/dist/media-sources-MS3RMQ6A.js +32 -0
  695. package/dist/media-sources-MS3RMQ6A.js.map +1 -0
  696. package/dist/members-IGHLTQKW.js +44 -0
  697. package/dist/members-IGHLTQKW.js.map +1 -0
  698. package/dist/meta-E3JOUOSS.js +69 -0
  699. package/dist/meta-E3JOUOSS.js.map +1 -0
  700. package/dist/metrics-HQ7XJAYQ.js +152 -0
  701. package/dist/metrics-HQ7XJAYQ.js.map +1 -0
  702. package/dist/models-PGX3FBHU.js +155 -0
  703. package/dist/models-PGX3FBHU.js.map +1 -0
  704. package/dist/normalize-FPJ6GSOY.js +806 -0
  705. package/dist/normalize-FPJ6GSOY.js.map +1 -0
  706. package/dist/normalize-LHD5LVFK.js +141 -0
  707. package/dist/normalize-LHD5LVFK.js.map +1 -0
  708. package/dist/options-CPHN3RMO.js +121 -0
  709. package/dist/options-CPHN3RMO.js.map +1 -0
  710. package/dist/output-GQFJ2T5B.js +24 -0
  711. package/dist/output-GQFJ2T5B.js.map +1 -0
  712. package/dist/page-VTTSBC6Y.js +105 -0
  713. package/dist/page-VTTSBC6Y.js.map +1 -0
  714. package/dist/pages-PMZVNVQM.js +66 -0
  715. package/dist/pages-PMZVNVQM.js.map +1 -0
  716. package/dist/performance-ECIJJEFV.js +24 -0
  717. package/dist/performance-ECIJJEFV.js.map +1 -0
  718. package/dist/pinterest-UDNGOWDM.js +96 -0
  719. package/dist/pinterest-UDNGOWDM.js.map +1 -0
  720. package/dist/pixels-OYZDGCH3.js +108 -0
  721. package/dist/pixels-OYZDGCH3.js.map +1 -0
  722. package/dist/pixels-XKGNTCFX.js +60 -0
  723. package/dist/pixels-XKGNTCFX.js.map +1 -0
  724. package/dist/plan-DZS3TVIJ.js +207 -0
  725. package/dist/plan-DZS3TVIJ.js.map +1 -0
  726. package/dist/preview-DR6MXOGI.js +169 -0
  727. package/dist/preview-DR6MXOGI.js.map +1 -0
  728. package/dist/profile-VOVZG44G.js +159 -0
  729. package/dist/profile-VOVZG44G.js.map +1 -0
  730. package/dist/promoted-tweet-writes-UJJI5SQL.js +180 -0
  731. package/dist/promoted-tweet-writes-UJJI5SQL.js.map +1 -0
  732. package/dist/promoted-tweets-O5RCETPX.js +119 -0
  733. package/dist/promoted-tweets-O5RCETPX.js.map +1 -0
  734. package/dist/properties-MKVF7MUK.js +101 -0
  735. package/dist/properties-MKVF7MUK.js.map +1 -0
  736. package/dist/publish-RRYU3NNX.js +322 -0
  737. package/dist/publish-RRYU3NNX.js.map +1 -0
  738. package/dist/query-CNWQ6STR.js +61 -0
  739. package/dist/query-CNWQ6STR.js.map +1 -0
  740. package/dist/query-DBSBZ73C.js +247 -0
  741. package/dist/query-DBSBZ73C.js.map +1 -0
  742. package/dist/query-QK4U4TEL.js +236 -0
  743. package/dist/query-QK4U4TEL.js.map +1 -0
  744. package/dist/questionnaire-OVJWNUVV.js +93 -0
  745. package/dist/questionnaire-OVJWNUVV.js.map +1 -0
  746. package/dist/read-L2QIVJTL.js +141 -0
  747. package/dist/read-L2QIVJTL.js.map +1 -0
  748. package/dist/reddit-K6CKJZRF.js +26 -0
  749. package/dist/reddit-K6CKJZRF.js.map +1 -0
  750. package/dist/refresh-IF4P57JJ.js +94 -0
  751. package/dist/refresh-IF4P57JJ.js.map +1 -0
  752. package/dist/release-H4EL3J6R.js +60 -0
  753. package/dist/release-H4EL3J6R.js.map +1 -0
  754. package/dist/relevant-pages-CRI2NLWG.js +99 -0
  755. package/dist/relevant-pages-CRI2NLWG.js.map +1 -0
  756. package/dist/remove-DKSHQRNS.js +50 -0
  757. package/dist/remove-DKSHQRNS.js.map +1 -0
  758. package/dist/remove-JKSCGKQG.js +48 -0
  759. package/dist/remove-JKSCGKQG.js.map +1 -0
  760. package/dist/reopen-B26V2GEJ.js +63 -0
  761. package/dist/reopen-B26V2GEJ.js.map +1 -0
  762. package/dist/rerun-6WKE4MPY.js +84 -0
  763. package/dist/rerun-6WKE4MPY.js.map +1 -0
  764. package/dist/research-O3IVF3MM.js +62 -0
  765. package/dist/research-O3IVF3MM.js.map +1 -0
  766. package/dist/research-SC7S6IPV.js +262 -0
  767. package/dist/research-SC7S6IPV.js.map +1 -0
  768. package/dist/reset-7HMOB2KE.js +54 -0
  769. package/dist/reset-7HMOB2KE.js.map +1 -0
  770. package/dist/reset-THPEXZDK.js +54 -0
  771. package/dist/reset-THPEXZDK.js.map +1 -0
  772. package/dist/resolve-HX5R52A3.js +121 -0
  773. package/dist/resolve-HX5R52A3.js.map +1 -0
  774. package/dist/retry-4ENRUJOJ.js +62 -0
  775. package/dist/retry-4ENRUJOJ.js.map +1 -0
  776. package/dist/retry-ELIMI7U5.js +60 -0
  777. package/dist/retry-ELIMI7U5.js.map +1 -0
  778. package/dist/retry-failed-2OYMCB55.js +45 -0
  779. package/dist/retry-failed-2OYMCB55.js.map +1 -0
  780. package/dist/run-CY4BAIQI.js +65 -0
  781. package/dist/run-CY4BAIQI.js.map +1 -0
  782. package/dist/run-GXPPPDGI.js +59 -0
  783. package/dist/run-GXPPPDGI.js.map +1 -0
  784. package/dist/scaffold-ad-X6VPBVTB.js +1548 -0
  785. package/dist/scaffold-ad-X6VPBVTB.js.map +1 -0
  786. package/dist/scaffold-static-ad-LKOOZSDP.js +971 -0
  787. package/dist/scaffold-static-ad-LKOOZSDP.js.map +1 -0
  788. package/dist/scaffold-video-NAOIFIM4.js +872 -0
  789. package/dist/scaffold-video-NAOIFIM4.js.map +1 -0
  790. package/dist/schedule-TLYT5UXM.js +66 -0
  791. package/dist/schedule-TLYT5UXM.js.map +1 -0
  792. package/dist/schedule-V654LLZ2.js +61 -0
  793. package/dist/schedule-V654LLZ2.js.map +1 -0
  794. package/dist/scheduled-agents-MJNUZYEK.js +49 -0
  795. package/dist/scheduled-agents-MJNUZYEK.js.map +1 -0
  796. package/dist/schema-DN4WKWUM.js +132 -0
  797. package/dist/schema-DN4WKWUM.js.map +1 -0
  798. package/dist/schema-MZTVCNP4.js +63 -0
  799. package/dist/schema-MZTVCNP4.js.map +1 -0
  800. package/dist/scrape-T3DA7ER7.js +2241 -0
  801. package/dist/scrape-T3DA7ER7.js.map +1 -0
  802. package/dist/screenshot-EIGC6SZB.js +102 -0
  803. package/dist/screenshot-EIGC6SZB.js.map +1 -0
  804. package/dist/search-2SVUDZIX.js +224 -0
  805. package/dist/search-2SVUDZIX.js.map +1 -0
  806. package/dist/search-34NFJ5F6.js +26 -0
  807. package/dist/search-34NFJ5F6.js.map +1 -0
  808. package/dist/search-BWE3OPOY.js +91 -0
  809. package/dist/search-BWE3OPOY.js.map +1 -0
  810. package/dist/search-EYYAOZND.js +92 -0
  811. package/dist/search-EYYAOZND.js.map +1 -0
  812. package/dist/search-EZZMYU4Y.js +174 -0
  813. package/dist/search-EZZMYU4Y.js.map +1 -0
  814. package/dist/search-copy-VKQ2OOBM.js +168 -0
  815. package/dist/search-copy-VKQ2OOBM.js.map +1 -0
  816. package/dist/seeds-HQYSVFIX.js +101 -0
  817. package/dist/seeds-HQYSVFIX.js.map +1 -0
  818. package/dist/select-3SIBANY6.js +94 -0
  819. package/dist/select-3SIBANY6.js.map +1 -0
  820. package/dist/sends-I7VQFE4S.js +309 -0
  821. package/dist/sends-I7VQFE4S.js.map +1 -0
  822. package/dist/sequences-JHSEJJGN.js +146 -0
  823. package/dist/sequences-JHSEJJGN.js.map +1 -0
  824. package/dist/set-prompt-RAG7RJOD.js +185 -0
  825. package/dist/set-prompt-RAG7RJOD.js.map +1 -0
  826. package/dist/setup-links-TNRBFS5Z.js +141 -0
  827. package/dist/setup-links-TNRBFS5Z.js.map +1 -0
  828. package/dist/{shared-J7DQZ2ED.js → shared-AT3FXPAG.js} +8 -6
  829. package/dist/shared-AT3FXPAG.js.map +1 -0
  830. package/dist/shopify-LUETQ5NT.js +3819 -0
  831. package/dist/shopify-LUETQ5NT.js.map +1 -0
  832. package/dist/site-SDL6LF6D.js +177 -0
  833. package/dist/site-SDL6LF6D.js.map +1 -0
  834. package/dist/sitemaps-FG37N5EB.js +87 -0
  835. package/dist/sitemaps-FG37N5EB.js.map +1 -0
  836. package/dist/sites-FIXK4Y3O.js +101 -0
  837. package/dist/sites-FIXK4Y3O.js.map +1 -0
  838. package/dist/skills-OKVCVQVD.js +47 -0
  839. package/dist/skills-OKVCVQVD.js.map +1 -0
  840. package/dist/sources-ISAUZFRN.js +30 -0
  841. package/dist/sources-ISAUZFRN.js.map +1 -0
  842. package/dist/sources-LQTJXAJG.js +421 -0
  843. package/dist/sources-LQTJXAJG.js.map +1 -0
  844. package/dist/stale-2L7NTLC6.js +63 -0
  845. package/dist/stale-2L7NTLC6.js.map +1 -0
  846. package/dist/stats-ZWZ7BAHV.js +34 -0
  847. package/dist/stats-ZWZ7BAHV.js.map +1 -0
  848. package/dist/status-4QBSIHO7.js +62 -0
  849. package/dist/status-4QBSIHO7.js.map +1 -0
  850. package/dist/sticker-FLRZM3BI.js +94 -0
  851. package/dist/sticker-FLRZM3BI.js.map +1 -0
  852. package/dist/stock-2CSMWRWV.js +179 -0
  853. package/dist/stock-2CSMWRWV.js.map +1 -0
  854. package/dist/studio-TTTR6N7D.js +49 -0
  855. package/dist/studio-TTTR6N7D.js.map +1 -0
  856. package/dist/sync-DH7FTPGG.js +54 -0
  857. package/dist/sync-DH7FTPGG.js.map +1 -0
  858. package/dist/sync-G5CS2RYV.js +54 -0
  859. package/dist/sync-G5CS2RYV.js.map +1 -0
  860. package/dist/sync-UADA6M33.js +265 -0
  861. package/dist/sync-UADA6M33.js.map +1 -0
  862. package/dist/sync-definition-ATMMOJ37.js +52 -0
  863. package/dist/sync-definition-ATMMOJ37.js.map +1 -0
  864. package/dist/tag-manager-NK3ZHSJB.js +43 -0
  865. package/dist/tag-manager-NK3ZHSJB.js.map +1 -0
  866. package/dist/tags-4RBZWDHS.js +20 -0
  867. package/dist/tags-4RBZWDHS.js.map +1 -0
  868. package/dist/tags-M7ATU2R7.js +26 -0
  869. package/dist/tags-M7ATU2R7.js.map +1 -0
  870. package/dist/tags-MXJKIBL4.js +20 -0
  871. package/dist/tags-MXJKIBL4.js.map +1 -0
  872. package/dist/tags-YG5EGPBW.js +20 -0
  873. package/dist/tags-YG5EGPBW.js.map +1 -0
  874. package/dist/tags-ZP4O3I2F.js +224 -0
  875. package/dist/tags-ZP4O3I2F.js.map +1 -0
  876. package/dist/targeting-constants-ZGBX3VWU.js +118 -0
  877. package/dist/targeting-constants-ZGBX3VWU.js.map +1 -0
  878. package/dist/targeting-criteria-BTB2RVI4.js +113 -0
  879. package/dist/targeting-criteria-BTB2RVI4.js.map +1 -0
  880. package/dist/targets-DEGJD2N6.js +102 -0
  881. package/dist/targets-DEGJD2N6.js.map +1 -0
  882. package/dist/templates-FZDWQSTV.js +178 -0
  883. package/dist/templates-FZDWQSTV.js.map +1 -0
  884. package/dist/testimonials-TI5EDABS.js +32 -0
  885. package/dist/testimonials-TI5EDABS.js.map +1 -0
  886. package/dist/themes-3RV3HNNE.js +94 -0
  887. package/dist/themes-3RV3HNNE.js.map +1 -0
  888. package/dist/top-companies-OKH7UNKX.js +108 -0
  889. package/dist/top-companies-OKH7UNKX.js.map +1 -0
  890. package/dist/translate-IUQBBVE6.js +598 -0
  891. package/dist/translate-IUQBBVE6.js.map +1 -0
  892. package/dist/triggers-2NWMXQ5P.js +141 -0
  893. package/dist/triggers-2NWMXQ5P.js.map +1 -0
  894. package/dist/tweets-X64YDEAA.js +123 -0
  895. package/dist/tweets-X64YDEAA.js.map +1 -0
  896. package/dist/unfollow-PIONCSBL.js +46 -0
  897. package/dist/unfollow-PIONCSBL.js.map +1 -0
  898. package/dist/unlink-UAPLQMK6.js +67 -0
  899. package/dist/unlink-UAPLQMK6.js.map +1 -0
  900. package/dist/unstage-BJJ5M7MK.js +95 -0
  901. package/dist/unstage-BJJ5M7MK.js.map +1 -0
  902. package/dist/unstage-X2BYGH2S.js +84 -0
  903. package/dist/unstage-X2BYGH2S.js.map +1 -0
  904. package/dist/update-7YK3VSOK.js +142 -0
  905. package/dist/update-7YK3VSOK.js.map +1 -0
  906. package/dist/update-BHG7BTK3.js +155 -0
  907. package/dist/update-BHG7BTK3.js.map +1 -0
  908. package/dist/update-CDJXKEVA.js +63 -0
  909. package/dist/update-CDJXKEVA.js.map +1 -0
  910. package/dist/update-RZXDAMAG.js +98 -0
  911. package/dist/update-RZXDAMAG.js.map +1 -0
  912. package/dist/upload-DSZEXNHH.js +126 -0
  913. package/dist/upload-DSZEXNHH.js.map +1 -0
  914. package/dist/upload-IWFYKD7A.js +150 -0
  915. package/dist/upload-IWFYKD7A.js.map +1 -0
  916. package/dist/upscale-EYCEYRWE.js +109 -0
  917. package/dist/upscale-EYCEYRWE.js.map +1 -0
  918. package/dist/url-options-RA3XISLN.js +130 -0
  919. package/dist/url-options-RA3XISLN.js.map +1 -0
  920. package/dist/url-params-OGZXF6MT.js +98 -0
  921. package/dist/url-params-OGZXF6MT.js.map +1 -0
  922. package/dist/use-E2TA2K6J.js +95 -0
  923. package/dist/use-E2TA2K6J.js.map +1 -0
  924. package/dist/validate-C6HWDI6K.js +88 -0
  925. package/dist/validate-C6HWDI6K.js.map +1 -0
  926. package/dist/variant-ETHB6XUM.js +338 -0
  927. package/dist/variant-ETHB6XUM.js.map +1 -0
  928. package/dist/videos-A2X5AARB.js +39 -0
  929. package/dist/videos-A2X5AARB.js.map +1 -0
  930. package/dist/view-BVEZRRV2.js +121 -0
  931. package/dist/view-BVEZRRV2.js.map +1 -0
  932. package/dist/viewer-check-W4ICSBHO.js +68 -0
  933. package/dist/viewer-check-W4ICSBHO.js.map +1 -0
  934. package/dist/web-GJSFDBBE.js +140 -0
  935. package/dist/web-GJSFDBBE.js.map +1 -0
  936. package/dist/winners-MJDKCGEZ.js +113 -0
  937. package/dist/winners-MJDKCGEZ.js.map +1 -0
  938. package/dist/winning-ads-NNU5MM75.js +84 -0
  939. package/dist/winning-ads-NNU5MM75.js.map +1 -0
  940. package/dist/write-commands-5I5KY6ZS.js +1015 -0
  941. package/dist/write-commands-5I5KY6ZS.js.map +1 -0
  942. package/dist/write-commands-DA6FIFAO.js +737 -0
  943. package/dist/write-commands-DA6FIFAO.js.map +1 -0
  944. package/dist/write-commands-KTPISQRE.js +206 -0
  945. package/dist/write-commands-KTPISQRE.js.map +1 -0
  946. package/dist/write-commands-QBGIWU27.js +713 -0
  947. package/dist/write-commands-QBGIWU27.js.map +1 -0
  948. package/dist/x-VCL5VRXC.js +47 -0
  949. package/dist/x-VCL5VRXC.js.map +1 -0
  950. package/package.json +9 -2
  951. package/dist/chunk-FGHMWBUD.js +0 -9989
  952. package/dist/chunk-FGHMWBUD.js.map +0 -1
  953. package/dist/chunk-HJEMOSPH.js +0 -1292
  954. package/dist/chunk-HJEMOSPH.js.map +0 -1
  955. package/dist/chunk-MF7YA62W.js.map +0 -1
  956. package/dist/chunk-VLUGGVJL.js.map +0 -1
  957. package/dist/chunk-VZEDAFAR.js.map +0 -1
  958. package/dist/chunk-XHC4LMK4.js.map +0 -1
  959. package/dist/client-GR6YL3YX.js +0 -17
  960. package/dist/output-NMQXZF3Z.js +0 -18
  961. /package/dist/{client-GR6YL3YX.js.map → chunk-YQSBHWOI.js.map} +0 -0
  962. /package/dist/{env-4P5HOGNA.js.map → client-EURRWXPW.js.map} +0 -0
  963. /package/dist/{output-NMQXZF3Z.js.map → connect-6DQFYKGN.js.map} +0 -0
  964. /package/dist/{shared-J7DQZ2ED.js.map → customers-FOPXEGCB.js.map} +0 -0
@@ -0,0 +1,216 @@
1
+ // ../api/src/identity/digest.ts
2
+ var SHA256_HEX = /^[0-9a-fA-F]{64}$/;
3
+ function isSha256Hex(value) {
4
+ return SHA256_HEX.test(value);
5
+ }
6
+
7
+ // ../api/src/identity/email.ts
8
+ function normalizeEmailV1(raw) {
9
+ const trimmed = raw.trim().toLowerCase();
10
+ return trimmed === "" ? null : trimmed;
11
+ }
12
+ var EMAIL = /^[^\s@]+@[^\s@.]+(?:\.[^\s@.]+)+$/;
13
+ function normalizeEmailV2(raw) {
14
+ const trimmed = raw.trim().toLowerCase();
15
+ return EMAIL.test(trimmed) ? trimmed : null;
16
+ }
17
+
18
+ // ../api/src/identity/phone.ts
19
+ function normalizePhoneV1(raw) {
20
+ const digits = raw.trim().toLowerCase().replace(/[^0-9]/g, "");
21
+ return digits === "" ? null : `+${digits}`;
22
+ }
23
+ var PHONE_PUNCTUATION = /[\s()./-]/g;
24
+ var E164 = /^\+[1-9]\d{7,14}$/;
25
+ function normalizePhoneV2(raw) {
26
+ const compact = raw.replace(PHONE_PUNCTUATION, "");
27
+ const e164 = compact.startsWith("00") ? `+${compact.slice(2)}` : compact;
28
+ return E164.test(e164) ? e164 : null;
29
+ }
30
+
31
+ // ../api/src/identity/index.ts
32
+ function normalizeIdentity(raw, version) {
33
+ const value = raw.kind === "email" ? version === 1 ? normalizeEmailV1(raw.value) : normalizeEmailV2(raw.value) : version === 1 ? normalizePhoneV1(raw.value) : normalizePhoneV2(raw.value);
34
+ return value === null ? null : { kind: raw.kind, value, normalizationVersion: version };
35
+ }
36
+
37
+ // ../api/src/event-ingest/matching.ts
38
+ var MATCH_FIELDS = [
39
+ "first_name",
40
+ "last_name",
41
+ "date_of_birth",
42
+ "gender",
43
+ "city",
44
+ "region",
45
+ "postal_code",
46
+ "country"
47
+ ];
48
+ var MATCH_COOKIES = ["fbp", "fbc"];
49
+ function tightened(value) {
50
+ const stripped = value.toLowerCase().replace(/[^\p{L}\p{N}]/gu, "");
51
+ return stripped === "" ? null : stripped;
52
+ }
53
+ function loosened(value) {
54
+ const collapsed = value.trim().toLowerCase().replace(/\s+/g, " ");
55
+ return collapsed === "" ? null : collapsed;
56
+ }
57
+ function birthDate(value) {
58
+ const digits = value.replace(/\D/g, "");
59
+ if (!/^\d{8}$/.test(digits)) return null;
60
+ const month = Number(digits.slice(4, 6));
61
+ const day = Number(digits.slice(6, 8));
62
+ if (month < 1 || month > 12 || day < 1 || day > 31) return null;
63
+ return digits;
64
+ }
65
+ function genderLetter(value) {
66
+ const first = value.trim().toLowerCase().charAt(0);
67
+ return first === "f" || first === "m" ? first : null;
68
+ }
69
+ function countryCode(value) {
70
+ const code = value.trim().toLowerCase();
71
+ return /^[a-z]{2}$/.test(code) ? code : null;
72
+ }
73
+ var MATCH_SPECS = {
74
+ first_name: { keep: "hashed", normalize: tightened, meta: "fn", google: "hashed_first_name" },
75
+ last_name: { keep: "hashed", normalize: tightened, meta: "ln", google: "hashed_last_name" },
76
+ // Meta only. Google's enhanced conversions have no date of birth, so there is
77
+ // no destination wanting it in the clear and every reason not to keep one.
78
+ date_of_birth: { keep: "hashed", normalize: birthDate, meta: "db", google: null },
79
+ gender: { keep: "plain", normalize: genderLetter, meta: "ge", google: null },
80
+ city: { keep: "plain", normalize: loosened, meta: "ct", google: "city" },
81
+ region: { keep: "plain", normalize: loosened, meta: "st", google: "state" },
82
+ postal_code: { keep: "plain", normalize: loosened, meta: "zp", google: "postal_code" },
83
+ country: { keep: "plain", normalize: countryCode, meta: "country", google: "country_code" }
84
+ };
85
+ var MATCH_FIELD_FORWARDING = [
86
+ { field: "email", meta: "em", google: "hashed_email", hashed: true },
87
+ { field: "phone", meta: "ph", google: "hashed_phone_number", hashed: true },
88
+ // Kept in the clear — see `resolveOwnId`. The digest is still computed and
89
+ // still stored beside it, so a Meta forward has one; what changed is that the
90
+ // sender's own key is now readable, which is the entire reason they sent it.
91
+ { field: "external_id", meta: "external_id", google: null, hashed: false },
92
+ ...MATCH_FIELDS.map((field) => ({
93
+ field,
94
+ meta: MATCH_SPECS[field].meta,
95
+ google: MATCH_SPECS[field].google,
96
+ hashed: MATCH_SPECS[field].keep === "hashed"
97
+ })),
98
+ { field: "fbp", meta: "fbp", google: null, hashed: false },
99
+ { field: "fbc", meta: "fbc", google: null, hashed: false }
100
+ ];
101
+
102
+ // ../api/src/event-ingest/vocabulary.ts
103
+ var INGEST_CLICK_ID_PARAMS = [
104
+ "gclid",
105
+ "wbraid",
106
+ "gbraid",
107
+ "dclid",
108
+ "fbclid",
109
+ "ttclid",
110
+ "twclid",
111
+ "li_fat_id",
112
+ "msclkid",
113
+ "rdt_cid",
114
+ "epik",
115
+ "sccid",
116
+ "oppref"
117
+ ];
118
+
119
+ // ../api/src/event-sources/fields.ts
120
+ var MATCH_LABELS = {
121
+ first_name: "First name",
122
+ last_name: "Last name",
123
+ date_of_birth: "Date of birth",
124
+ gender: "Gender",
125
+ city: "City",
126
+ region: "Region",
127
+ postal_code: "Postcode",
128
+ country: "Country"
129
+ };
130
+ var CLICK_LABELS = {
131
+ gclid: "Google click id",
132
+ wbraid: "Google click id (iOS, web to app)",
133
+ gbraid: "Google click id (iOS, app)",
134
+ dclid: "Google click id (Display & Video)",
135
+ fbclid: "Meta click id",
136
+ ttclid: "TikTok click id",
137
+ twclid: "X click id",
138
+ li_fat_id: "LinkedIn click id",
139
+ msclkid: "Microsoft click id",
140
+ rdt_cid: "Reddit click id",
141
+ epik: "Pinterest click id",
142
+ sccid: "Snapchat click id",
143
+ oppref: "ChatGPT Ads click id"
144
+ };
145
+ var SOURCE_FIELDS = [
146
+ { field: "event_name", label: "What happened", group: "event" },
147
+ { field: "event_time", label: "When it happened", group: "event" },
148
+ { field: "event_id", label: "Its id", group: "event" },
149
+ { field: "email", label: "Email", group: "person" },
150
+ { field: "phone", label: "Phone", group: "person" },
151
+ { field: "external_id", label: "Your own id for the person", group: "person" },
152
+ ...MATCH_FIELDS.map((field) => ({ field, label: MATCH_LABELS[field], group: "person" })),
153
+ { field: "value", label: "Amount", group: "money" },
154
+ { field: "currency", label: "Currency", group: "money" },
155
+ ...INGEST_CLICK_ID_PARAMS.map((field) => ({ field, label: CLICK_LABELS[field], group: "click" }))
156
+ ];
157
+ var SOURCE_FIELD_NAMES = SOURCE_FIELDS.map((spec) => spec.field);
158
+ var FIELD_SET = new Set(SOURCE_FIELD_NAMES);
159
+ function isSourceField(value) {
160
+ return FIELD_SET.has(value);
161
+ }
162
+ var PROPERTY_ROW_PREFIX = "properties.";
163
+ var PROPERTY_KEY_MAX = 64;
164
+ var PROPERTY_KEY = /^[A-Za-z0-9_][A-Za-z0-9_.-]*$/;
165
+ var RESERVED_PROPERTY_KEYS = ["baker_source", "hubspot_property", "hubspot_value"];
166
+ function isPropertyRow(row) {
167
+ return row.startsWith(PROPERTY_ROW_PREFIX);
168
+ }
169
+ function propertyKeyOf(row) {
170
+ return isPropertyRow(row) ? row.slice(PROPERTY_ROW_PREFIX.length) : null;
171
+ }
172
+ function propertyKeyProblem(key) {
173
+ const trimmed = key.trim();
174
+ if (trimmed === "") return "A property needs a name.";
175
+ if (trimmed.length > PROPERTY_KEY_MAX) return `A property name is at most ${PROPERTY_KEY_MAX} characters.`;
176
+ if (!PROPERTY_KEY.test(trimmed)) {
177
+ return `"${trimmed}" is not a property name: letters, digits, underscore, dash and dot only, starting with a letter or digit.`;
178
+ }
179
+ if (RESERVED_PROPERTY_KEYS.includes(trimmed)) return `"${trimmed}" is written by Baker itself; pick another name.`;
180
+ return null;
181
+ }
182
+ function mappingRowProblem(row) {
183
+ if (isSourceField(row)) return null;
184
+ const key = propertyKeyOf(row);
185
+ if (key === null) {
186
+ return `"${row}" is not a field an event can carry. A field is one of ${SOURCE_FIELD_NAMES.join(", ")}; an extra property is spelled properties.<name>.`;
187
+ }
188
+ return propertyKeyProblem(key);
189
+ }
190
+
191
+ // ../api/src/event-sources/template.ts
192
+ var MENTION = /\{\{\s*([^{}]+?)\s*\}\}/g;
193
+ function mentionOf(path) {
194
+ return `{{${path}}}`;
195
+ }
196
+ function templateMentions(template) {
197
+ const seen = [];
198
+ for (const match of template.matchAll(MENTION)) {
199
+ const path = (match[1] ?? "").trim();
200
+ if (path !== "" && !seen.includes(path)) seen.push(path);
201
+ }
202
+ return seen;
203
+ }
204
+
205
+ export {
206
+ isSha256Hex,
207
+ normalizeIdentity,
208
+ MATCH_COOKIES,
209
+ MATCH_FIELD_FORWARDING,
210
+ INGEST_CLICK_ID_PARAMS,
211
+ SOURCE_FIELD_NAMES,
212
+ mappingRowProblem,
213
+ mentionOf,
214
+ templateMentions
215
+ };
216
+ //# sourceMappingURL=chunk-EDLZGTGN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../api/src/identity/digest.ts","../../api/src/identity/email.ts","../../api/src/identity/phone.ts","../../api/src/identity/index.ts","../../api/src/event-ingest/matching.ts","../../api/src/event-ingest/vocabulary.ts","../../api/src/event-sources/fields.ts","../../api/src/event-sources/template.ts"],"sourcesContent":["/**\n * The one hash, and the one way to recognise one.\n *\n * Web Crypto, so the same code runs in the Convex runtime, a Worker, Node and a\n * browser — an identity digest that differs by runtime is a digest that matches\n * nothing, and nothing about that failure is visible from either end.\n */\n\n/** SHA-256 in lowercase hex. The form every ad platform documents. */\nexport async function sha256Hex(value: string): Promise<string> {\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(value));\n return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nconst SHA256_HEX = /^[0-9a-fA-F]{64}$/;\n\n/**\n * Whether a value is already a SHA-256 digest — the check that decides whether\n * a field holds plain text to normalize and hash, or a digest someone else\n * computed. Hashing a hash produces a key that matches nothing, forever, with\n * no way to tell afterwards.\n */\nexport function isSha256Hex(value: string): boolean {\n return SHA256_HEX.test(value);\n}\n\n/** The storable form of a supplied digest, or `null` if it is not one. */\nexport function normalizeSha256Hex(value: string): string | null {\n const trimmed = value.trim();\n return SHA256_HEX.test(trimmed) ? trimmed.toLowerCase() : null;\n}\n\n/**\n * The canonical form of a site's own id for a person, before it is hashed.\n *\n * Trim and lowercase, and deliberately nothing else. An `external_id` is an\n * opaque key in somebody else's system — a customer number, a CRM contact id, a\n * membership code — so there is no shape to check and no punctuation that means\n * anything. What matters is only that **both ends canonicalise it the same\n * way**: the browser hashing `Cust-4821` and the CRM hashing `cust-4821` would\n * produce two people out of one, with nothing anywhere to report it.\n *\n * Not part of the versioned normalizer beside it, on purpose. Those versions\n * exist because an address has a *correct* form that we learned late; this has\n * never had one and never will.\n */\nexport function normalizeExternalId(raw: string): string | null {\n const trimmed = raw.trim().toLowerCase();\n return trimmed === \"\" ? null : trimmed;\n}\n\n/** The digest a site's own id joins on, or `null` when there is nothing to hash. */\nexport async function externalIdDigest(raw: string): Promise<string | null> {\n const canonical = normalizeExternalId(raw);\n return canonical === null ? null : await sha256Hex(canonical);\n}\n","/**\n * Email normalization, one rule per version.\n *\n * A version is not a preference: a digest computed under v1 and stored a year\n * ago can never be recomputed, because the address that produced it was dropped\n * on purpose. So v1 is frozen at whatever the browser did on the day it ran, and\n * a better rule arrives as v2 alongside it rather than in place of it.\n */\n\n/**\n * **v1 — frozen.** Trim and lowercase, exactly what\n * the beacon's own rule (now `src/lib/tracking/identity-normalize.ts`) has always done. No shape check:\n * whatever the visitor typed was hashed, and every historical digest was\n * produced this way.\n *\n * `null` only for an empty result, which is the one case the beacon also\n * declines to report.\n */\nexport function normalizeEmailV1(raw: string): string | null {\n const trimmed = raw.trim().toLowerCase();\n return trimmed === \"\" ? null : trimmed;\n}\n\n/** No dots-as-separators, no length games: one `@`, a local part, a dotted domain. */\nconst EMAIL = /^[^\\s@]+@[^\\s@.]+(?:\\.[^\\s@.]+)+$/;\n\n/**\n * **v2.** v1 plus a shape check, so an unusable value is declined instead of\n * hashed into a key that can never match.\n */\nexport function normalizeEmailV2(raw: string): string | null {\n const trimmed = raw.trim().toLowerCase();\n return EMAIL.test(trimmed) ? trimmed : null;\n}\n\n/**\n * Google's own email canonicalization, applied on top of a normalized address:\n * for `gmail.com` and `googlemail.com`, drop the dots and any `+tag` from the\n * local part.\n *\n * `null` when there is no address left to send — a local part that was nothing\n * but a `+tag`. Google is the only platform that asks for this; Meta and\n * LinkedIn hash the address as written, which is why this is a provider step\n * and not part of the version.\n */\nexport function googleEmail(normalizedEmail: string): string | null {\n const [localPart, domain, ...extraParts] = normalizedEmail.split(\"@\");\n if (!localPart || !domain || extraParts.length > 0) return normalizedEmail;\n if (domain !== \"gmail.com\" && domain !== \"googlemail.com\") return normalizedEmail;\n const canonicalLocalPart = localPart.split(\"+\", 1)[0]?.replace(/\\./g, \"\") ?? \"\";\n return canonicalLocalPart ? `${canonicalLocalPart}@${domain}` : null;\n}\n","/**\n * Phone normalization, one rule per version, plus the shape each platform\n * hashes.\n *\n * Three copies of this used to exist — the beacon's, the funnel contract's and\n * `lib/capi.ts` — and they disagreed on the `+`. A digest of `34600111222` and a\n * digest of `+34600111222` are two unrelated keys for one person, and neither\n * end reports anything when they fail to meet.\n */\n\n/**\n * **v1 — frozen.** Digits only, with a `+` in front, exactly what\n * the beacon's own rule (now `src/lib/tracking/identity-normalize.ts`) has always done. It guesses no\n * country code and validates nothing: a national number becomes `+600111222`,\n * and that is the digest sitting in the store for every visitor who identified\n * before v2 existed.\n */\nexport function normalizePhoneV1(raw: string): string | null {\n const digits = raw\n .trim()\n .toLowerCase()\n .replace(/[^0-9]/g, \"\");\n return digits === \"\" ? null : `+${digits}`;\n}\n\n/** What a CRM writes around the digits and what E.164 does not keep. */\nconst PHONE_PUNCTUATION = /[\\s()./-]/g;\n/** E.164: `+`, a country code that cannot start at 0, up to 15 digits total. */\nconst E164 = /^\\+[1-9]\\d{7,14}$/;\n\n/**\n * **v2 — strict E.164.**\n *\n * A number with no international prefix is refused rather than guessed at. The\n * country code cannot be inferred from the value, and inventing one produces a\n * hash that silently matches nothing — worse than declining the key, because\n * the event still resolves by some other rung and nobody learns the phone was\n * lost. Both `+34…` and the access prefix `0034…` are accepted; a bare\n * `600111222` is not.\n */\nexport function normalizePhoneV2(raw: string): string | null {\n const compact = raw.replace(PHONE_PUNCTUATION, \"\");\n const e164 = compact.startsWith(\"00\") ? `+${compact.slice(2)}` : compact;\n return E164.test(e164) ? e164 : null;\n}\n\n/**\n * E.164 without the `+` — what Meta, LinkedIn and Twitter hash.\n *\n * Google hashes the same number *with* the `+`, and that single character is\n * the whole reason this function has a name.\n */\nexport function phoneWithoutPlus(normalizedPhone: string): string {\n return normalizedPhone.startsWith(\"+\") ? normalizedPhone.slice(1) : normalizedPhone;\n}\n","/**\n * Versioned identity normalization — one rule set, in one place, for the whole\n * platform.\n *\n * Several copies of \"normalize an email or a phone and hash it\" exist: the\n * browser beacon's, the one every Conversions API dispatcher shares\n * (`convex/lib/capi.ts`), and Google Ads' own on top of it\n * (`convex/sideEffects/googleAdsCapi/utils.ts`). They disagree about the `+` on\n * a phone, about whether a malformed address should be declined, and about\n * Gmail. Each disagreement is the same failure: two digests for one person, no\n * error anywhere, and an attribution that quietly matches nobody.\n *\n * **This module has taken over exactly one of them so far — the beacon's.** The\n * CAPI dispatchers still hold their own, because they sit on live conversion\n * uploads where a changed digest is money mis-attributed, so they move in their\n * own change with their own evidence. What is done instead, and now, is to make\n * the drift *detectable*: `capi.parity.test.ts` in `packages/backend` runs those\n * copies over the same table as these and fails when they stop agreeing. That is\n * the whole problem — the copies are identical today and nothing was watching.\n * One of them, Google Ads' phone rule, is genuinely a third rule and cannot be\n * pinned to either version; the test says so in place of pretending otherwise.\n *\n * Two ideas make that fixable rather than merely fixed:\n *\n * - **The version is data.** A digest cannot be recomputed — the plaintext was\n * dropped on purpose, which is the point of holding a digest at all. So the\n * rule that produced it is frozen as v1 and kept, and a better rule ships\n * beside it as v2. Anything holding plaintext produces both and looks up\n * both, which is why a normalization change cannot orphan the history.\n * - **The provider form is not the version.** Meta hashes E.164 without the\n * `+`, Google hashes it with the `+` and canonicalizes Gmail addresses. Those\n * are three digests of one canonical value, not three normalizations.\n */\n\nimport { sha256Hex } from \"./digest\";\nimport { normalizeEmailV1, normalizeEmailV2 } from \"./email\";\nimport { normalizePhoneV1, normalizePhoneV2 } from \"./phone\";\nimport { providerPlain } from \"./providers\";\nimport type { CanonicalIdentity, IdentityInput, NormalizationVersion } from \"./types\";\n\nexport { externalIdDigest, isSha256Hex, normalizeExternalId, normalizeSha256Hex, sha256Hex } from \"./digest\";\nexport { googleEmail, normalizeEmailV1, normalizeEmailV2 } from \"./email\";\nexport { normalizePhoneV1, normalizePhoneV2, phoneWithoutPlus } from \"./phone\";\nexport { type ProviderPlain, providerPlain } from \"./providers\";\nexport {\n type CanonicalIdentity,\n type IdentityInput,\n type IdentityKind,\n NORMALIZATION_VERSIONS,\n type NormalizationVersion,\n} from \"./types\";\nexport { extractDomain, isPublicEmailDomain, workEmailDomain } from \"./workDomain\";\n\n/**\n * Apply one version's rule to plain text, or decline it.\n *\n * `null` means this version has no usable form of this value — not that the\n * person has no phone. Under v2 that happens to any national number, on\n * purpose: see {@link normalizePhoneV2}.\n */\nexport function normalizeIdentity(raw: IdentityInput, version: NormalizationVersion): CanonicalIdentity | null {\n const value =\n raw.kind === \"email\"\n ? version === 1\n ? normalizeEmailV1(raw.value)\n : normalizeEmailV2(raw.value)\n : version === 1\n ? normalizePhoneV1(raw.value)\n : normalizePhoneV2(raw.value);\n return value === null ? null : { kind: raw.kind, value, normalizationVersion: version };\n}\n\n/**\n * The digests one canonical value produces, keyed by who asks for them.\n *\n * Snake case because this is a wire shape: it is what the browser sends, what\n * the ingest stores, and what an activation payload reads. `google_sha256` is\n * `null` when Google has no usable form of the value — a Gmail address whose\n * local part was only a `+tag`.\n */\nexport type IdentityDigests = {\n canonical_sha256: string;\n meta_sha256: string;\n google_sha256: string | null;\n normalization_version: NormalizationVersion;\n};\n\nexport async function providerDigests(canonical: CanonicalIdentity): Promise<IdentityDigests> {\n const plain = providerPlain(canonical);\n const [canonicalSha, metaSha, googleSha] = await Promise.all([\n sha256Hex(plain.canonical),\n sha256Hex(plain.meta),\n plain.google === null ? Promise.resolve(null) : sha256Hex(plain.google),\n ]);\n return {\n canonical_sha256: canonicalSha,\n meta_sha256: metaSha,\n google_sha256: googleSha,\n normalization_version: canonical.normalizationVersion,\n };\n}\n\n/**\n * The compact set a page sends and an ingest reads: one entry per version, plus\n * the two provider digests, for one plaintext value.\n *\n * `meta` and `google` are computed from the best version that produced a value\n * — v2 when it accepted the value, v1 otherwise — because a platform wants one\n * digest, not a history. `v1` and `v2` are both present when both rules\n * accepted the value, and they are equal when the two rules agreed.\n *\n * `null` when no version has a usable form: there is nothing to report, and\n * reporting an empty digest would be reporting the hash of the empty string.\n */\nexport type IdentityDigestSet = {\n v1?: string;\n v2?: string;\n meta: string;\n google?: string;\n};\n\nexport async function identityDigestSet(raw: IdentityInput): Promise<IdentityDigestSet | null> {\n const v1 = normalizeIdentity(raw, 1);\n const v2 = normalizeIdentity(raw, 2);\n const best = v2 ?? v1;\n if (best === null) return null;\n const digests = await providerDigests(best);\n return {\n ...(v1 === null ? {} : { v1: v1.value === best.value ? digests.canonical_sha256 : await sha256Hex(v1.value) }),\n ...(v2 === null ? {} : { v2: digests.canonical_sha256 }),\n meta: digests.meta_sha256,\n ...(digests.google_sha256 === null ? {} : { google: digests.google_sha256 }),\n };\n}\n","/**\n * The customer-matching block: one vocabulary for everything Meta calls\n * *advanced matching* and Google calls *enhanced conversions*.\n *\n * ## Why these fields are here at all\n *\n * A server event is worth what it can be joined to. An email is the join that\n * works, and everything in this file is the second-best set for when the join\n * has to happen *outward* instead — Meta and Google both accept an event with\n * no email at all if it carries enough of a person: a name and a postcode, a\n * click id, a browser cookie. They disagree about spelling and about what has\n * to be hashed, and they do not disagree about the set.\n *\n * Two things follow, and they are the whole design:\n *\n * - **One block, one spelling.** A sender maps their CRM once, here, rather\n * than once per destination. `MATCH_FIELD_FORWARDING` is the table that says\n * what each field is called on the other side, so the mapping is published\n * rather than folklore.\n * - **Kept in the form every destination can still be derived from.** That rule\n * decides, per field, whether it is stored hashed or in the clear, and it is\n * the only rule here worth remembering: **a digest can be computed later and\n * never undone.** A city hashed on arrival can never be sent to Google, which\n * wants `address_info.city` in plain text; a city kept in the clear can be\n * hashed for Meta at the moment of sending, for free.\n *\n * So: hashed here are the fields **both** destinations want hashed and which\n * identify a person on their own — email, phone, the two names, the date of\n * birth, and the sender's own id. Kept in the clear are the coarse ones that\n * identify nobody by themselves and that Google wants unhashed: city, region,\n * postal code, country, and the gender letter. Hashing that second set would\n * buy no privacy — the digest of `es` is not a secret — and would cost the\n * ability to send them anywhere.\n *\n * ## A value that arrives already hashed\n *\n * Accepted for every field, and detected rather than declared. There is no\n * `email_sha256` beside `email` any more, because two fields for one idea is a\n * choice a sender should never have had to make: a 64-character hex string is\n * unambiguously a digest — no address, phone number, city or name can be one —\n * so the field can hold either and we can tell. What we cannot do is *unhash*,\n * so a digest arriving for a field this module would otherwise keep in the\n * clear is stored under `<field>_sha256`: the key says what is inside it, and a\n * forward that needs the plain value knows it does not have one.\n *\n * ## Normalization is Meta's, and the divergence is stated\n *\n * The hashed fields are normalized under the rule Meta publishes (lower case,\n * trimmed, punctuation and spacing removed) because a digest can only be\n * computed under one rule and Meta's is the stricter of the two. Google's rule\n * for a name is lower-case-and-trim only, so the two agree on every name\n * without punctuation in it and differ on `O'Brien`. Email and phone do not\n * have this problem: they go through `../identity`, which is the platform's one\n * versioned rule and the same one the browser beacon writes with — which is\n * what makes a server event and a Form submission land on one person.\n */\n\nimport { isSha256Hex, sha256Hex } from \"../identity\";\n\n/**\n * A field of `user_data` that describes the person rather than naming a click.\n *\n * `email` and `phone` are deliberately not here: they are resolved by\n * `./identity` into the row's own `identity_hash`, under the platform's\n * versioned rule, and this module reads that result rather than hashing them a\n * second time under a different one.\n */\nexport const MATCH_FIELDS = [\n \"first_name\",\n \"last_name\",\n \"date_of_birth\",\n \"gender\",\n \"city\",\n \"region\",\n \"postal_code\",\n \"country\",\n] as const;\nexport type MatchField = (typeof MATCH_FIELDS)[number];\n\n/**\n * The browser cookies Meta's pixel sets, which name a browser rather than a\n * person.\n *\n * `fbp` is the pixel's own first-party cookie and `fbc` is the one it derives\n * from a click. Both are sent to Meta **unhashed and verbatim** — they are\n * opaque strings of Meta's own making, and hashing one destroys it — so they\n * are stored exactly as they arrived.\n *\n * They are not in {@link MATCH_FIELDS} and not in the click-id list either.\n * They are not click ids: a `gclid` is stamped on a URL by the ad platform and\n * has a column of its own here because reports filter on it, while `fbp` is a\n * cookie a script wrote and nothing reports on. But they *do* name somebody,\n * which is why `namesSomebody` counts them — an event carrying only an `fbp` is\n * still an event Meta can attribute, and refusing it would lose exactly the\n * conversions this block exists to make sendable.\n */\nexport const MATCH_COOKIES = [\"fbp\", \"fbc\"] as const;\nexport type MatchCookie = (typeof MATCH_COOKIES)[number];\n\n/** How a field is stored, once it has been normalized. */\ntype Keeping = \"hashed\" | \"plain\";\n\ntype MatchSpec = {\n keep: Keeping;\n /** The canonical form, or `null` when the value says nothing usable. */\n normalize: (value: string) => string | null;\n /** What Meta and Google call this field, for the published mapping. */\n meta: string;\n google: string | null;\n};\n\n/** Lower-cased, trimmed, and stripped of everything that is not a letter or a digit. Meta's rule. */\nfunction tightened(value: string): string | null {\n const stripped = value.toLowerCase().replace(/[^\\p{L}\\p{N}]/gu, \"\");\n return stripped === \"\" ? null : stripped;\n}\n\n/** Lower-cased and trimmed, with runs of whitespace collapsed. Nothing else is removed. */\nfunction loosened(value: string): string | null {\n const collapsed = value.trim().toLowerCase().replace(/\\s+/g, \" \");\n return collapsed === \"\" ? null : collapsed;\n}\n\n/**\n * `1985-04-09`, `1985/04/09`, `19850409` — eight digits in year-month-day\n * order, however they are punctuated.\n *\n * The order is not guessed. `09/04/1985` is refused rather than read as the\n * ninth of April or the fourth of September: nothing in the value says which,\n * and a birth date hashed under the wrong reading is a digest that matches\n * nobody at Meta, with no error anywhere to say so. A refusal costs one field\n * on one event and is visible in the arrival log; a wrong guess costs the match\n * and is not.\n */\nfunction birthDate(value: string): string | null {\n const digits = value.replace(/\\D/g, \"\");\n if (!/^\\d{8}$/.test(digits)) return null;\n const month = Number(digits.slice(4, 6));\n const day = Number(digits.slice(6, 8));\n if (month < 1 || month > 12 || day < 1 || day > 31) return null;\n return digits;\n}\n\n/** `f` or `m`, from whatever word or letter the sender's system stores. */\nfunction genderLetter(value: string): string | null {\n const first = value.trim().toLowerCase().charAt(0);\n return first === \"f\" || first === \"m\" ? first : null;\n}\n\n/** ISO-3166 alpha-2, lower-cased. A country name is refused rather than guessed at. */\nfunction countryCode(value: string): string | null {\n const code = value.trim().toLowerCase();\n return /^[a-z]{2}$/.test(code) ? code : null;\n}\n\nexport const MATCH_SPECS: Readonly<Record<MatchField, MatchSpec>> = {\n first_name: { keep: \"hashed\", normalize: tightened, meta: \"fn\", google: \"hashed_first_name\" },\n last_name: { keep: \"hashed\", normalize: tightened, meta: \"ln\", google: \"hashed_last_name\" },\n // Meta only. Google's enhanced conversions have no date of birth, so there is\n // no destination wanting it in the clear and every reason not to keep one.\n date_of_birth: { keep: \"hashed\", normalize: birthDate, meta: \"db\", google: null },\n gender: { keep: \"plain\", normalize: genderLetter, meta: \"ge\", google: null },\n city: { keep: \"plain\", normalize: loosened, meta: \"ct\", google: \"city\" },\n region: { keep: \"plain\", normalize: loosened, meta: \"st\", google: \"state\" },\n postal_code: { keep: \"plain\", normalize: loosened, meta: \"zp\", google: \"postal_code\" },\n country: { keep: \"plain\", normalize: countryCode, meta: \"country\", google: \"country_code\" },\n};\n\n/** One row of the published mapping: our name, Meta's, Google's, and whether we hold it hashed. */\nexport type MatchFieldForwarding = {\n field: string;\n meta: string;\n google: string | null;\n hashed: boolean;\n};\n\n/**\n * What each field of the matching block is called at the destinations that\n * accept it — the table the dialog and the docs both read.\n *\n * Published rather than described, because \"it maps onto Meta's user_data\" is\n * a promise a sender cannot check and this is the same promise they can.\n */\nexport const MATCH_FIELD_FORWARDING: readonly MatchFieldForwarding[] = [\n { field: \"email\", meta: \"em\", google: \"hashed_email\", hashed: true },\n { field: \"phone\", meta: \"ph\", google: \"hashed_phone_number\", hashed: true },\n // Kept in the clear — see `resolveOwnId`. The digest is still computed and\n // still stored beside it, so a Meta forward has one; what changed is that the\n // sender's own key is now readable, which is the entire reason they sent it.\n { field: \"external_id\", meta: \"external_id\", google: null, hashed: false },\n ...MATCH_FIELDS.map((field) => ({\n field,\n meta: MATCH_SPECS[field].meta,\n google: MATCH_SPECS[field].google,\n hashed: MATCH_SPECS[field].keep === \"hashed\",\n })),\n { field: \"fbp\", meta: \"fbp\", google: null, hashed: false },\n { field: \"fbc\", meta: \"fbc\", google: null, hashed: false },\n];\n\n/** The longest a stored match value may be, matching the width the map's values are held at. */\nconst MAX_MATCH_VALUE = 255;\n\n/**\n * One field, resolved to the key it is stored under and the value stored there.\n *\n * `null` when the field said nothing usable — `gender: \"unknown\"`, a country\n * spelled out in full, a postcode of whitespace. A field that is present and\n * unusable contributes nothing rather than storing something that matches\n * nobody, which is the same rule the identity resolution follows.\n */\nexport async function resolveMatchField(\n field: MatchField,\n raw: string,\n): Promise<{ key: string; value: string } | null> {\n const value = raw.trim();\n if (value === \"\") return null;\n const spec = MATCH_SPECS[field];\n // Already a digest, whatever this field would otherwise keep. Taken at face\n // value — hashing a hash matches nothing, forever — and keyed so that the\n // name says what is inside, because a plain-text destination cannot use it.\n if (isSha256Hex(value)) return { key: `${field}_sha256`, value: value.toLowerCase() };\n const normalized = spec.normalize(value);\n if (normalized === null) return null;\n if (spec.keep === \"plain\") return { key: field, value: normalized.slice(0, MAX_MATCH_VALUE) };\n return { key: `${field}_sha256`, value: await sha256Hex(normalized) };\n}\n\n/**\n * The two ids that are not facts about a person but *names the sender chose*,\n * kept exactly as they were sent.\n *\n * `external_id` is the client's own key — a HubSpot contact id, a Salesforce\n * record id — and `baker_id` is a cookie value one of our own pages minted.\n * Neither describes anybody: they are pointers, and a pointer is worth only\n * what it can be followed with.\n *\n * ## Why these are the exception to \"identifying fields are hashed\"\n *\n * `external_id` used to be hashed here and nothing else, on the reasoning that\n * it is sometimes an email or a document number in disguise. That reasoning\n * held and the consequence did not: it made the field **useless to the person\n * who sent it**. An integrator posting `external_id: \"hs:contact:12345\"` opened\n * the event and read *Provided, stored hashed* — no way to check we had read\n * the right record, no way to paste the id back into their CRM, and no way to\n * tell a working integration from one silently keyed on the wrong column. The\n * whole point of the field is to be recognised on the way back out.\n *\n * The privacy this bought was also smaller than it looked. The digest is still\n * computed, still what `identity_hash` stores and still what the identity graph\n * joins on — see `./identity` — so nothing about the joining changed. What is\n * new is a second copy in the clear, under the key that says so.\n *\n * A value that arrives *already* a digest still keeps `<field>_sha256`, for the\n * rule that governs every field here: a digest cannot be undone, so the key has\n * to say what is inside it.\n */\nexport function resolveOwnId(field: \"external_id\" | \"baker_id\", raw: string): { key: string; value: string } | null {\n const value = raw.trim();\n if (value === \"\") return null;\n if (isSha256Hex(value)) return { key: `${field}_sha256`, value: value.toLowerCase() };\n return { key: field, value: value.slice(0, MAX_MATCH_VALUE) };\n}\n\n/** A cookie value, as Meta minted it: bounded, and otherwise untouched. */\nexport function resolveMatchCookie(raw: string): string | null {\n const value = raw.trim();\n return value === \"\" ? null : value.slice(0, MAX_MATCH_VALUE);\n}\n\n/**\n * The `fbclid` hiding inside an `fbc`, or `null`.\n *\n * `fbc` is `fb.<subdomain index>.<timestamp>.<fbclid>` — Meta's own encoding of\n * a click id it already saw. A sender whose system stored the cookie has the\n * click id and does not know it, so reading it out costs one split and gives\n * the event the same paid-attribution column a landing page would have written\n * from the URL. Nothing is invented: the value was there.\n */\nexport function fbclidFromFbc(fbc: string): string | null {\n const parts = fbc.split(\".\");\n if (parts.length < 4 || parts[0] !== \"fb\") return null;\n const id = parts.slice(3).join(\".\");\n return id === \"\" ? null : id;\n}\n","/**\n * The click ids a sender may hand over, named the way their own system stored\n * them.\n *\n * The wire uses the **URL parameter** spelling (`li_fat_id`) rather than the\n * analytics row's field spelling (`liFatId`), because a client's CRM captured\n * these off a landing URL and that is the name it wrote them down under.\n * {@link clickIdsFromWire} is the one place the two vocabularies meet.\n *\n * Mirrored from `CLICK_ID_FIELDS` in `../analytics/normalize.ts`, which is the\n * source of truth for which click ids the store has columns for.\n * `vocabulary.parity.test.ts` reads that file and fails if the two drift — a\n * missing entry here is an attribution a client sent and we dropped.\n */\n\nimport type { ClickIdFields } from \"../analytics/normalize\";\n\nexport const INGEST_CLICK_ID_PARAMS = [\n \"gclid\",\n \"wbraid\",\n \"gbraid\",\n \"dclid\",\n \"fbclid\",\n \"ttclid\",\n \"twclid\",\n \"li_fat_id\",\n \"msclkid\",\n \"rdt_cid\",\n \"epik\",\n \"sccid\",\n \"oppref\",\n] as const;\nexport type IngestClickIdParam = (typeof INGEST_CLICK_ID_PARAMS)[number];\n\nconst FIELD_FOR_PARAM: Readonly<Record<IngestClickIdParam, keyof ClickIdFields>> = {\n gclid: \"gclid\",\n wbraid: \"wbraid\",\n gbraid: \"gbraid\",\n dclid: \"dclid\",\n fbclid: \"fbclid\",\n ttclid: \"ttclid\",\n twclid: \"twclid\",\n li_fat_id: \"liFatId\",\n msclkid: \"msclkid\",\n rdt_cid: \"rdtCid\",\n epik: \"epik\",\n sccid: \"sccid\",\n oppref: \"oppref\",\n};\n\n/** The wire's click block as the analytics row builder names its fields. Empty values are dropped. */\nexport function clickIdsFromWire(click: Partial<Record<IngestClickIdParam, string | null>> | null | undefined): {\n clickIds: ClickIdFields;\n kinds: IngestClickIdParam[];\n} {\n const clickIds: ClickIdFields = {};\n const kinds: IngestClickIdParam[] = [];\n for (const param of INGEST_CLICK_ID_PARAMS) {\n const value = click?.[param];\n if (typeof value !== \"string\" || value === \"\") continue;\n clickIds[FIELD_FOR_PARAM[param]] = value;\n kinds.push(param);\n }\n return { clickIds, kinds };\n}\n","/**\n * What a source can be read into: the fields of an event, named the way\n * `POST /v1/events` already names them.\n *\n * Assembled from the ingest vocabulary rather than spelled a fourth time. A\n * mapping is `SourceField → dotted path`, and the field half of that pair has\n * to be a name the wire already accepts, because the whole of what a source\n * does is build an `IngestEventInput` and hand it to the same door the\n * client's own server would have used. A field that existed only here would be\n * a field the event could not carry.\n */\n\nimport { MATCH_FIELDS, type MatchField } from \"../event-ingest/matching\";\nimport type { IngestClickIdParam } from \"../event-ingest/vocabulary\";\nimport { INGEST_CLICK_ID_PARAMS } from \"../event-ingest/vocabulary\";\n\n/** Where a field sits on the sheet: one row per group, in this order. */\nexport type SourceFieldGroup = \"event\" | \"person\" | \"money\" | \"click\";\n\nexport type SourceField =\n | \"event_name\"\n | \"event_time\"\n | \"event_id\"\n | \"email\"\n | \"phone\"\n | \"external_id\"\n | MatchField\n | \"value\"\n | \"currency\"\n | IngestClickIdParam;\n\nexport interface SourceFieldSpec {\n field: SourceField;\n /** The product word for it — what the sheet and the CLI show. */\n label: string;\n group: SourceFieldGroup;\n}\n\nconst MATCH_LABELS: Readonly<Record<MatchField, string>> = {\n first_name: \"First name\",\n last_name: \"Last name\",\n date_of_birth: \"Date of birth\",\n gender: \"Gender\",\n city: \"City\",\n region: \"Region\",\n postal_code: \"Postcode\",\n country: \"Country\",\n};\n\nconst CLICK_LABELS: Readonly<Record<IngestClickIdParam, string>> = {\n gclid: \"Google click id\",\n wbraid: \"Google click id (iOS, web to app)\",\n gbraid: \"Google click id (iOS, app)\",\n dclid: \"Google click id (Display & Video)\",\n fbclid: \"Meta click id\",\n ttclid: \"TikTok click id\",\n twclid: \"X click id\",\n li_fat_id: \"LinkedIn click id\",\n msclkid: \"Microsoft click id\",\n rdt_cid: \"Reddit click id\",\n epik: \"Pinterest click id\",\n sccid: \"Snapchat click id\",\n oppref: \"ChatGPT Ads click id\",\n};\n\nexport const SOURCE_FIELDS: readonly SourceFieldSpec[] = [\n { field: \"event_name\", label: \"What happened\", group: \"event\" },\n { field: \"event_time\", label: \"When it happened\", group: \"event\" },\n { field: \"event_id\", label: \"Its id\", group: \"event\" },\n { field: \"email\", label: \"Email\", group: \"person\" },\n { field: \"phone\", label: \"Phone\", group: \"person\" },\n { field: \"external_id\", label: \"Your own id for the person\", group: \"person\" },\n ...MATCH_FIELDS.map((field) => ({ field, label: MATCH_LABELS[field], group: \"person\" as const })),\n { field: \"value\", label: \"Amount\", group: \"money\" },\n { field: \"currency\", label: \"Currency\", group: \"money\" },\n ...INGEST_CLICK_ID_PARAMS.map((field) => ({ field, label: CLICK_LABELS[field], group: \"click\" as const })),\n];\n\nexport const SOURCE_FIELD_NAMES: readonly SourceField[] = SOURCE_FIELDS.map((spec) => spec.field);\n\nconst FIELD_SET: ReadonlySet<string> = new Set(SOURCE_FIELD_NAMES);\n\nexport function isSourceField(value: string): value is SourceField {\n return FIELD_SET.has(value);\n}\n\nexport const SOURCE_FIELD_GROUPS: readonly { group: SourceFieldGroup; label: string; detail: string }[] = [\n { group: \"event\", label: \"The event\", detail: \"What it is called, when it happened, and its own id.\" },\n {\n group: \"person\",\n label: \"Who it is about\",\n detail: \"How the platforms find the person. Email or phone is the one that matters.\",\n },\n {\n group: \"money\",\n label: \"What it was worth\",\n detail: \"The amount and its currency, for revenue and for the platforms.\",\n },\n {\n group: \"click\",\n label: \"The ad click that brought them\",\n detail: \"When the source keeps the click id, the campaign gets the credit.\",\n },\n];\n\n/**\n * A row that is not a field of the event but one of its own **properties** —\n * the flat `properties` object every event carries, which Measure → Events\n * breaks an event down by and which a send can forward to a platform as an\n * extra parameter (Meta's `custom_data`, a GA4 event parameter).\n *\n * Spelled `properties.<key>` in the mapping so the row shares the table with\n * the fields and the CLI's `--field` takes it unchanged, while an unknown bare\n * key is still refused: the namespace is what tells a deliberate extra\n * property from a typo that would otherwise silently map nothing.\n */\nexport const PROPERTY_ROW_PREFIX = \"properties.\";\n\n/** The longest a property's key may be. Keys are a shared dictionary in the store, so they are kept short and plain. */\nexport const PROPERTY_KEY_MAX = 64;\n\n/** Letters, digits, underscore, dash and dot — what a property key of `POST /v1/events` may be, and what a platform parameter name may be. */\nconst PROPERTY_KEY = /^[A-Za-z0-9_][A-Za-z0-9_.-]*$/;\n\n/** Keys a source writes itself; a row naming one would be overwritten in silence. */\nexport const RESERVED_PROPERTY_KEYS: readonly string[] = [\"baker_source\", \"hubspot_property\", \"hubspot_value\"];\n\n/** Whether a mapping row names a property rather than a field. */\nexport function isPropertyRow(row: string): boolean {\n return row.startsWith(PROPERTY_ROW_PREFIX);\n}\n\n/** The property's own key, for a `properties.<key>` row; null for anything else. */\nexport function propertyKeyOf(row: string): string | null {\n return isPropertyRow(row) ? row.slice(PROPERTY_ROW_PREFIX.length) : null;\n}\n\n/** The mapping row for a property key. */\nexport function propertyRow(key: string): string {\n return `${PROPERTY_ROW_PREFIX}${key}`;\n}\n\n/**\n * Why a property key cannot be used, in one sentence, or null when it can.\n * The same rule for a source's extra properties and for a send's parameters.\n */\nexport function propertyKeyProblem(key: string): string | null {\n const trimmed = key.trim();\n if (trimmed === \"\") return \"A property needs a name.\";\n if (trimmed.length > PROPERTY_KEY_MAX) return `A property name is at most ${PROPERTY_KEY_MAX} characters.`;\n if (!PROPERTY_KEY.test(trimmed)) {\n return `\"${trimmed}\" is not a property name: letters, digits, underscore, dash and dot only, starting with a letter or digit.`;\n }\n if (RESERVED_PROPERTY_KEYS.includes(trimmed)) return `\"${trimmed}\" is written by Baker itself; pick another name.`;\n return null;\n}\n\n/**\n * Whether a mapping row is one a source can hold: a field of the event, or a\n * well-named property. The reason when it is not.\n */\nexport function mappingRowProblem(row: string): string | null {\n if (isSourceField(row)) return null;\n const key = propertyKeyOf(row);\n if (key === null) {\n return `\"${row}\" is not a field an event can carry. A field is one of ${SOURCE_FIELD_NAMES.join(\", \")}; an extra property is spelled properties.<name>.`;\n }\n return propertyKeyProblem(key);\n}\n\n/** The property rows of a mapping, as `key → template`, in the order stored. */\nexport function propertyRows(mapping: Readonly<Record<string, string>>): { key: string; template: string }[] {\n return Object.entries(mapping).flatMap(([row, template]) => {\n const key = propertyKeyOf(row);\n return key === null ? [] : [{ key, template }];\n });\n}\n","/**\n * A mapping row is a template: literal text with `{{mentions}}` in it.\n *\n * ## Why a template and not a path\n *\n * A row used to hold one dotted path, and one path answers one question —\n * \"which field of the payload is the email\". It cannot answer the next three:\n * a currency the tool never sends but the company knows (`EUR`), a name split\n * over two fields (`{{firstname}} {{lastname}}`), or an amount a HubSpot\n * contact carries under a property nobody would guess. A template answers all\n * of them with one rule the Forms builder already teaches: type text, insert\n * a variable. The same spelling is what the CLI takes, so an agent and a\n * person write the same thing.\n *\n * ## What a mention points at\n *\n * Whatever the source can read. For an address it is a dotted path into the\n * payload (`contact.email`, `deal.contacts.0.email`); for a HubSpot read it\n * is a contact property's internal name (`hs_google_click_id`), plus `id` for\n * the contact's own id. The template does not know which — the lookup passed\n * to `renderTemplate` does.\n *\n * A mention names exactly one thing. There was a `{{phone|mobilephone}}`\n * spelling for \"the first that holds anything\"; it is gone, because it was a\n * rule the Forms builder's variables do not have, and a row that reads\n * differently from every other variable field in the product is a row nobody\n * can predict. A person who wants the mobile picks the mobile.\n */\n\nconst MENTION = /\\{\\{\\s*([^{}]+?)\\s*\\}\\}/g;\n\n/** The path a mention names, with the braces on. */\nexport function mentionOf(path: string): string {\n return `{{${path}}}`;\n}\n\n/** Every path a template reads, in order, once each. */\nexport function templateMentions(template: string): string[] {\n const seen: string[] = [];\n for (const match of template.matchAll(MENTION)) {\n const path = (match[1] ?? \"\").trim();\n if (path !== \"\" && !seen.includes(path)) seen.push(path);\n }\n return seen;\n}\n\n/**\n * The template with every mention replaced by what it points at, trimmed —\n * or nothing, when what is left is empty. An empty mention reads as empty\n * text rather than as its own spelling, so a template made only of mentions\n * the payload did not fill is \"not sent\", not the literal `{{phone}}`.\n */\nexport function renderTemplate(template: string, lookup: (path: string) => string | undefined): string | undefined {\n const rendered = template.replace(MENTION, (_whole, path: string) => lookup(path.trim()) ?? \"\").trim();\n return rendered === \"\" ? undefined : rendered;\n}\n\n/** The one path a template is, when it is exactly one mention and nothing else. */\nexport function isBareMention(template: string): string | null {\n const match = /^\\{\\{\\s*([^{}]+?)\\s*\\}\\}$/.exec(template.trim());\n return match === null ? null : (match[1] ?? null);\n}\n"],"mappings":"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","names":[]}
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  ApiError,
3
3
  apiGet
4
- } from "./chunk-MF7YA62W.js";
4
+ } from "./chunk-CUL3VB4L.js";
5
5
  import {
6
6
  getEnv
7
- } from "./chunk-HJEMOSPH.js";
7
+ } from "./chunk-I4FTS5EE.js";
8
8
 
9
9
  // src/error-handler.ts
10
10
  var REQUEST_CONNECTION_PLATFORM = {
@@ -153,6 +153,12 @@ function writeJsonEnvelope(envelope) {
153
153
  process.stdout.write(`${JSON.stringify(envelope, null, 2)}
154
154
  `);
155
155
  }
156
+ var TABLE_OUTPUT_FORMATS = ["json", "csv", "jsonl", "md"];
157
+ function outputFormatRefusal(format, supported) {
158
+ if (supported.includes(format)) return null;
159
+ const list = supported.length > 1 ? `${supported.slice(0, -1).join(", ")} or ${supported.at(-1)}` : supported.join("");
160
+ return `--output ${format} is not supported \u2014 use ${list}`;
161
+ }
156
162
  function toCsvRow(values) {
157
163
  return values.map((v) => {
158
164
  if (v.includes(",") || v.includes('"') || v.includes("\n")) {
@@ -288,14 +294,16 @@ export {
288
294
  getQueryTtl,
289
295
  buildQueryCacheKey,
290
296
  getManagerIdForCustomer,
291
- connectionFixExplanation,
292
- handleConnectionError,
293
- isNotConnectedError,
294
- needsConnectionFix,
295
297
  writeAdsJson,
296
298
  writeJsonEnvelope,
299
+ TABLE_OUTPUT_FORMATS,
300
+ outputFormatRefusal,
297
301
  toCsvRow,
298
302
  writeAdsOutput,
299
- resolveCustomerId
303
+ resolveCustomerId,
304
+ connectionFixExplanation,
305
+ handleConnectionError,
306
+ isNotConnectedError,
307
+ needsConnectionFix
300
308
  };
301
- //# sourceMappingURL=chunk-XHC4LMK4.js.map
309
+ //# sourceMappingURL=chunk-EIGXX6KI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/error-handler.ts","../src/commands/ads/cache.ts","../src/commands/ads/output.ts"],"sourcesContent":["import { writeJsonEnvelope } from \"./commands/ads/output.ts\";\n\ntype ConnectionPlatform = \"google_ads\" | \"ga4\" | \"gsc\" | \"x_ads\" | \"meta_ads\" | \"linkedin_ads\";\n\n/**\n * Platforms the agent can get connected without the user leaving the chat, via\n * the blocking `request_connection` tool, and the id that tool expects. Every\n * platform this CLI can talk to is here — keep it in step with\n * `CONNECTION_PLATFORMS` in `packages/bridge/src/hono/connection-input.ts`: a\n * platform the tool accepts but this map omits sends the user to Settings for a\n * door the agent could have opened itself.\n */\nconst REQUEST_CONNECTION_PLATFORM: Record<ConnectionPlatform, string> = {\n google_ads: \"google-ads\",\n ga4: \"google-analytics\",\n gsc: \"google-search-console\",\n linkedin_ads: \"linkedin\",\n meta_ads: \"meta\",\n x_ads: \"x-ads\",\n};\n\nconst PLATFORM_NAME: Record<ConnectionPlatform, string> = {\n google_ads: \"Google Ads\",\n ga4: \"Google Analytics 4\",\n gsc: \"Google Search Console\",\n x_ads: \"X Ads\",\n meta_ads: \"Meta Ads\",\n linkedin_ads: \"LinkedIn Ads\",\n};\n\n/**\n * How to tell the agent to get a platform connected. Never \"send them to\n * Settings\" for a platform `request_connection` covers — that ends the turn on a\n * wall the agent could have opened itself, and it now covers every platform this\n * CLI talks to. The fallback line matters too: if the `request_connection` call\n * fails, the agent must still be able to say where the connect button is instead\n * of stalling.\n */\nexport function connectionFixExplanation(platform: ConnectionPlatform): string {\n const name = PLATFORM_NAME[platform];\n const slug = REQUEST_CONNECTION_PLATFORM[platform];\n return (\n `${name} is not connected for this company (or no account has been picked). Don't send the user to Settings ` +\n `or end the turn here — call the \\`request_connection\\` tool with { platform: \"${slug}\", reason } and ` +\n `they connect and pick their accounts from inside the chat. If the \\`request_connection\\` call fails, say so ` +\n `plainly and give the exact route: dashboard → Brain → Integrations → Platforms → ${name}. Then carry on with the ` +\n `rest of the task and say what stays unavailable until it is connected.`\n );\n}\n\n/**\n * Shared error handler for \"No Connection\" scenarios.\n * Provides a structured error for AI agents with a suggested fix and alternative commands.\n */\nexport function handleConnectionError(platform: ConnectionPlatform, originalMessage?: string): never {\n const platformName = PLATFORM_NAME[platform];\n\n const alternative = {\n google_ads: \"keywords-for-site or research advertisers\",\n ga4: \"lighthouse for page performance\",\n gsc: \"keywords-for-site or research keyword-gap\",\n x_ads: \"research advertisers\",\n meta_ads: \"research advertisers or research keyword-ideas\",\n linkedin_ads: \"research advertisers (LinkedIn Ad Library) or research keyword-ideas\",\n }[platform];\n\n const code = {\n google_ads: \"NO_GOOGLE_ADS_CONNECTION\",\n ga4: \"NO_GA4_CONNECTION\",\n gsc: \"NO_GSC_CONNECTION\",\n x_ads: \"NO_X_ADS_CONNECTION\",\n meta_ads: \"NO_META_ADS_CONNECTION\",\n linkedin_ads: \"NO_LINKEDIN_ADS_CONNECTION\",\n }[platform];\n\n const envelope = {\n ok: false,\n error: {\n code,\n message: originalMessage || `No ${platformName} connection found for this company.`,\n fix: {\n action: \"request_connection\",\n explanation: `${connectionFixExplanation(platform)} (Optional fallback for estimated external insights: 'baker research ${alternative}'.)`,\n },\n retryable: false,\n },\n };\n\n writeJsonEnvelope(envelope);\n process.exit(1);\n}\n\n/**\n * Does this API failure mean \"the platform isn't connected\"? The read commands\n * surface the backend's own 404/403 verbatim, so the connect fix has to be\n * recognised from the code the client mapped it to plus the message.\n */\nexport function isNotConnectedError(code: string, message: string): boolean {\n if (code !== \"NOT_FOUND\" && code !== \"UNAUTHORIZED\" && code !== \"FORBIDDEN\") {\n return false;\n }\n // The last alternative is the write-path 403 (\"customer X is not in this\n // company's connected Google Ads accounts\") — a different sentence for the\n // same remedy: connect, and pick the account.\n return /no .* connection found|not connected|no .* (selected|picked)|is not in .* connected/i.test(message);\n}\n\n/**\n * Does this failure warrant the connect form? A dead token (401) always does —\n * whatever the wording, the remedy is to sign in again.\n *\n * A 404 or 403 only does when the backend says so. Both codes are overloaded:\n * 403 is also an asset-level refusal on a live connection (reconnecting cannot\n * grant it), and 404 is also how \"no staged op <ref> in this draft\" and a\n * mistyped `--chat` come back. Answering either with \"ask the user to connect\n * Meta Ads\" sends the agent to fix something that was never broken, and the\n * real missing-connection 404 says \"No <platform> connection found\" anyway.\n */\nexport function needsConnectionFix(code: string, message: string): boolean {\n if (code === \"UNAUTHORIZED\") {\n return true;\n }\n return isNotConnectedError(code, message);\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type { CacheEntry } from \"./types.ts\";\n\nconst CACHE_DIR = join(homedir(), \".baker\", \"cache\", \"ads\");\n\nfunction ensureDir(dir: string): void {\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true });\n }\n}\n\nfunction hashKey(key: string): string {\n return createHash(\"sha256\").update(key).digest(\"hex\").slice(0, 16);\n}\n\nfunction cachePath(category: string, key: string): string {\n const dir = join(CACHE_DIR, category);\n ensureDir(dir);\n return join(dir, `${hashKey(key)}.json`);\n}\n\nexport function cacheGet<T>(category: string, key: string): CacheEntry<T> | null {\n const path = cachePath(category, key);\n if (!existsSync(path)) {\n return null;\n }\n try {\n const raw = readFileSync(path, \"utf-8\");\n const entry = JSON.parse(raw) as CacheEntry<T>;\n if (entry.expiresAt < Date.now()) {\n rmSync(path, { force: true });\n return null;\n }\n return entry;\n } catch {\n rmSync(path, { force: true });\n return null;\n }\n}\n\nexport function cacheSet<T>(\n category: string,\n key: string,\n data: T,\n ttlMs: number,\n fields?: Record<string, string>,\n): void {\n const path = cachePath(category, key);\n const entry: CacheEntry<T> = {\n expiresAt: Date.now() + ttlMs,\n data,\n fields,\n };\n writeFileSync(path, JSON.stringify(entry), \"utf-8\");\n}\n\nconst HOUR = 60 * 60 * 1000;\nconst MINUTE = 60 * 1000;\n\nexport function getQueryTtl(query: string): number {\n const upper = query.toUpperCase();\n if (upper.includes(\"TODAY\")) {\n return 15 * MINUTE;\n }\n if (upper.includes(\"LAST_7_DAYS\") || upper.includes(\"LAST_14_DAYS\")) {\n return 1 * HOUR;\n }\n // Historical data (BETWEEN, LAST_30_DAYS, LAST_90_DAYS, etc.)\n return 6 * HOUR;\n}\n\nexport function buildQueryCacheKey(customerId: string, query: string): string {\n const today = new Date().toISOString().slice(0, 10);\n return `${customerId}:${today}:${query.trim().replace(/\\s+/g, \" \")}`;\n}\n\ninterface CachedAccount {\n id: string;\n access_type: \"direct\" | \"managed\";\n manager_id?: string;\n}\n\nexport function getManagerIdForCustomer(customerId: string): string | undefined {\n const cached = cacheGet<CachedAccount[]>(\"accounts\", \"list\");\n if (!cached) return undefined;\n const account = cached.data.find((a) => a.id === customerId);\n if (account?.access_type === \"managed\") return account.manager_id;\n return undefined;\n}\n","import { ApiError, apiGet } from \"../../client.ts\";\nimport { getEnv } from \"../../env.ts\";\nimport { handleConnectionError, isNotConnectedError } from \"../../error-handler.ts\";\nimport type { QueryContext } from \"../../geo-context.ts\";\nimport { cacheGet, cacheSet } from \"./cache.ts\";\nimport type { AdsErrorEnvelope, AdsFileSummary, AdsSuccessEnvelope } from \"./types.ts\";\n\ntype AdsOutput =\n | AdsSuccessEnvelope<unknown>\n | AdsErrorEnvelope\n | AdsFileSummary\n | { ok: true; data: unknown; query_context?: QueryContext; cached?: true; fields?: Record<string, string> }\n | { ok: false; error: { code: string; message: string } };\n\nexport function writeAdsJson(envelope: AdsOutput): void {\n process.stdout.write(`${JSON.stringify(envelope, null, 2)}\\n`);\n}\n\nexport function writeJsonEnvelope(envelope: Record<string, unknown>): void {\n process.stdout.write(`${JSON.stringify(envelope, null, 2)}\\n`);\n}\n\n/** The formats `writeAdsOutput` prints. */\nexport const TABLE_OUTPUT_FORMATS = [\"json\", \"csv\", \"jsonl\", \"md\"] as const;\n\n/** Why `--output <format>` cannot be printed, or null — rather than quietly falling back to JSON. */\nexport function outputFormatRefusal(format: string, supported: readonly string[]): string | null {\n if (supported.includes(format)) return null;\n const list =\n supported.length > 1 ? `${supported.slice(0, -1).join(\", \")} or ${supported.at(-1)}` : supported.join(\"\");\n return `--output ${format} is not supported — use ${list}`;\n}\n\nexport function toCsvRow(values: string[]): string {\n return values\n .map((v) => {\n if (v.includes(\",\") || v.includes('\"') || v.includes(\"\\n\")) {\n return `\"${v.replace(/\"/g, '\"\"')}\"`;\n }\n return v;\n })\n .join(\",\");\n}\n\nfunction flattenRow(row: Record<string, unknown>): Record<string, string> {\n const flat: Record<string, string> = {};\n for (const [key, val] of Object.entries(row)) {\n flat[key] = typeof val === \"object\" && val !== null ? JSON.stringify(val) : String(val ?? \"\");\n }\n return flat;\n}\n\n/**\n * One write per table: a line-by-line write piped into `head` hits a closed pipe on\n * the next line and crashes with EPIPE, where a single write lands in the pipe buffer.\n */\nfunction writeWhole(lines: string[]): void {\n process.stdout.write(`${lines.join(\"\\n\")}\\n`);\n}\n\nfunction writeAdsCsv(data: Array<Record<string, unknown>>, fields?: string[]): void {\n if (data.length === 0) return;\n const cols = fields ?? Object.keys(data[0] ?? {});\n const lines = [toCsvRow(cols)];\n for (const row of data) {\n const flat = flattenRow(row);\n lines.push(toCsvRow(cols.map((f) => flat[f] ?? \"\")));\n }\n writeWhole(lines);\n}\n\nfunction writeAdsJsonl(data: Array<Record<string, unknown>>): void {\n if (data.length === 0) return;\n writeWhole(data.map((row) => JSON.stringify(row)));\n}\n\n/** A `|` or line break in a name would split its cell and shift every later column. */\nfunction mdCell(value: string): string {\n return value.replace(/\\|/g, \"\\\\|\").replace(/\\r?\\n/g, \" \");\n}\n\nfunction writeAdsMd(data: Array<Record<string, unknown>>, fields?: string[]): void {\n if (data.length === 0) return;\n const cols = fields ?? Object.keys(data[0] ?? {});\n const lines = [`| ${cols.join(\" | \")} |`, `| ${cols.map(() => \"---\").join(\" | \")} |`];\n for (const row of data) {\n const flat = flattenRow(row);\n lines.push(`| ${cols.map((f) => mdCell(flat[f] ?? \"\")).join(\" | \")} |`);\n }\n writeWhole(lines);\n}\n\n/**\n * `hints` ride in the JSON envelope; csv/jsonl/md stdout has no room for them,\n * and an empty result is exactly when the hint matters, so they go to stderr.\n */\nexport function writeAdsOutput(\n data: Array<Record<string, unknown>>,\n format: string,\n fields?: string[],\n hints: string[] = [],\n): void {\n switch (format) {\n case \"csv\":\n writeAdsCsv(data, fields);\n break;\n case \"jsonl\":\n writeAdsJsonl(data);\n break;\n case \"md\":\n writeAdsMd(data, fields);\n break;\n default:\n writeJsonEnvelope(hints.length > 0 ? { ok: true, data, hints } : { ok: true, data });\n return;\n }\n for (const hint of hints) process.stderr.write(`${hint}\\n`);\n}\n\ninterface AccountInfo {\n id: string;\n name: string;\n access_type: \"direct\" | \"managed\";\n level: number;\n manager_id?: string;\n}\n\nasync function fetchAccounts(useCache = true): Promise<AccountInfo[]> {\n if (useCache) {\n const cached = cacheGet<AccountInfo[]>(\"accounts\", \"list\");\n if (cached) return cached.data;\n }\n const params = !useCache ? { \"skip-cache\": \"true\" } : undefined;\n const data = await apiGet<AccountInfo[]>(\"/api/ads/google/accounts\", params);\n if (useCache) {\n cacheSet(\"accounts\", \"list\", data, 60 * 60 * 1000);\n }\n return data;\n}\n\nexport async function resolveCustomerId(args: Record<string, unknown>): Promise<string> {\n const fromArgs = args[\"customer-id\"] as string | undefined;\n const customerId = fromArgs || getEnv().BAKER_GOOGLE_ADS_CUSTOMER_ID;\n\n if (customerId) {\n if (!/^\\d{10}$/.test(customerId)) {\n writeAdsJson({\n ok: false,\n error: {\n code: \"INVALID_CUSTOMER_ID\",\n message:\n \"Customer ID must be exactly 10 digits without dashes. Pass --customer-id or set BAKER_GOOGLE_ADS_CUSTOMER_ID.\",\n },\n });\n process.exit(1);\n }\n return customerId;\n }\n\n const useCache = !args[\"no-cache\"];\n\n try {\n const accounts = await fetchAccounts(useCache);\n const [single] = accounts;\n if (accounts.length === 1 && single) {\n process.stderr.write(`Using account \"${single.name}\" (${single.id})\\n`);\n return single.id;\n }\n if (accounts.length === 0) {\n handleConnectionError(\"google_ads\");\n }\n const list = accounts.map((a) => ` ${a.id} ${a.name}`).join(\"\\n\");\n writeAdsJson({\n ok: false,\n error: {\n code: \"MULTIPLE_ACCOUNTS\",\n message: `Multiple accounts found. Pass --customer-id or set BAKER_GOOGLE_ADS_CUSTOMER_ID:\\n${list}`,\n },\n });\n process.exit(1);\n } catch (err) {\n // \"No connection\" reaches here as a 404/403 from the accounts lookup. Reporting it as\n // an unusable customer id sends the agent hunting for an id that cannot exist yet.\n if (err instanceof ApiError && isNotConnectedError(err.code, err.message)) {\n handleConnectionError(\"google_ads\", err.message);\n }\n writeAdsJson({\n ok: false,\n error: {\n code: \"INVALID_CUSTOMER_ID\",\n message: \"Could not auto-detect account. Pass --customer-id or set BAKER_GOOGLE_ADS_CUSTOMER_ID.\",\n },\n });\n process.exit(1);\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,174 @@
1
+ import {
2
+ metaDraftOpInputSchema
3
+ } from "./chunk-GOJXKIFQ.js";
4
+ import {
5
+ handleMetaError,
6
+ resolveAccountIdArg
7
+ } from "./chunk-2UFRHW3T.js";
8
+ import {
9
+ adCopyHints,
10
+ booleanWordPositionalError,
11
+ capabilityFix
12
+ } from "./chunk-WHWNXLTD.js";
13
+ import {
14
+ withHints
15
+ } from "./chunk-D5FY4FAK.js";
16
+ import {
17
+ writeJsonEnvelope
18
+ } from "./chunk-EIGXX6KI.js";
19
+ import {
20
+ apiPost
21
+ } from "./chunk-CUL3VB4L.js";
22
+ import {
23
+ requireChatId
24
+ } from "./chunk-I4FTS5EE.js";
25
+
26
+ // src/commands/ads/meta/write-shared.ts
27
+ import { readFileSync } from "fs";
28
+ function bareAccountId(args) {
29
+ return resolveAccountIdArg(args).replace(/^act_/, "");
30
+ }
31
+ function failWriteValidation(message) {
32
+ writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
33
+ process.exit(1);
34
+ }
35
+ function refuseDeleteByUpdate(payload, group) {
36
+ if (payload.status === "DELETED") {
37
+ failWriteValidation(
38
+ `update does not delete \u2014 deleting is permanent. Use \`baker ads meta ${group} delete <id>\` if the user asked to delete; otherwise pause or archive.`
39
+ );
40
+ }
41
+ }
42
+ function loadJsonFileArg(path) {
43
+ if (typeof path !== "string" || path.length === 0) {
44
+ return {};
45
+ }
46
+ try {
47
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
48
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
49
+ failWriteValidation(`${path} must contain a JSON object`);
50
+ }
51
+ return parsed;
52
+ } catch (err) {
53
+ if (err instanceof SyntaxError) {
54
+ failWriteValidation(`${path} is not valid JSON: ${err.message}`);
55
+ }
56
+ throw err;
57
+ }
58
+ }
59
+ function mergePayload(file, flags) {
60
+ const merged = { ...file };
61
+ for (const [key, value] of Object.entries(flags)) {
62
+ if (value !== void 0) {
63
+ merged[key] = value;
64
+ }
65
+ }
66
+ return merged;
67
+ }
68
+ function parseMoneyFlag(amount, currency, flag) {
69
+ if (amount === void 0 || amount === null || amount === "") {
70
+ return void 0;
71
+ }
72
+ if (currency === void 0 || currency === null || currency === "") {
73
+ return { amount: String(amount) };
74
+ }
75
+ if (typeof currency !== "string" || currency.length !== 3) {
76
+ failWriteValidation(`${flag} got an invalid --currency (expected a 3-letter code like USD)`);
77
+ }
78
+ return { amount: String(amount), currencyCode: currency.toUpperCase() };
79
+ }
80
+ function parseDateFlag(value, flag) {
81
+ if (value === void 0 || value === null || value === "") {
82
+ return void 0;
83
+ }
84
+ const raw = String(value);
85
+ if (/^\d{10,}$/.test(raw)) {
86
+ return Number(raw);
87
+ }
88
+ const parsed = Date.parse(raw);
89
+ if (Number.isNaN(parsed)) {
90
+ failWriteValidation(`${flag} must be an ISO date (2026-07-10) or epoch milliseconds`);
91
+ }
92
+ return parsed;
93
+ }
94
+ function listFlag(value) {
95
+ if (typeof value !== "string" || value.trim().length === 0) {
96
+ return void 0;
97
+ }
98
+ const items = value.split(",").map((item) => item.trim()).filter(Boolean);
99
+ return items.length > 0 ? items : void 0;
100
+ }
101
+ function upper(value) {
102
+ return typeof value === "string" && value.length > 0 ? value.toUpperCase() : void 0;
103
+ }
104
+ function numberFlag(value, flag) {
105
+ if (value === void 0 || value === null || value === "") {
106
+ return void 0;
107
+ }
108
+ const n = Number(value);
109
+ if (!Number.isFinite(n)) {
110
+ failWriteValidation(`${flag} must be a number`);
111
+ }
112
+ return n;
113
+ }
114
+ function requireTarget(args, entity) {
115
+ const inverted = booleanWordPositionalError(args, entity);
116
+ if (inverted !== void 0) {
117
+ failWriteValidation(inverted);
118
+ }
119
+ const positional = Array.isArray(args._) ? args._[0] : void 0;
120
+ const target = args.id ?? args.target ?? args.ref ?? positional;
121
+ if (typeof target !== "string" || target.length === 0) {
122
+ failWriteValidation(`pass the ${entity} id as the positional argument`);
123
+ }
124
+ return target;
125
+ }
126
+ async function stageOp(raw) {
127
+ const preflight = metaDraftOpInputSchema.safeParse(raw);
128
+ if (!preflight.success) {
129
+ const fields = preflight.error.issues.map((issue) => ({ path: issue.path.join("."), message: issue.message }));
130
+ writeJsonEnvelope({
131
+ ok: false,
132
+ error: {
133
+ code: "VALIDATION_ERROR",
134
+ message: fields.map((field) => field.path ? `${field.path}: ${field.message}` : field.message).join("; "),
135
+ fields,
136
+ fix: capabilityFix("meta-ads")
137
+ }
138
+ });
139
+ process.exit(1);
140
+ }
141
+ try {
142
+ const chatId = requireChatId();
143
+ const response = await apiPost("/api/ads/meta/draft/stage", { chatId, op: preflight.data });
144
+ const copyHints = await adCopyHints(preflight.data);
145
+ writeJsonEnvelope(withHints(response, copyHints));
146
+ } catch (err) {
147
+ handleMetaError(err);
148
+ }
149
+ }
150
+ async function stageStatusChange(input) {
151
+ await stageOp({
152
+ kind: input.kind,
153
+ accountId: input.accountId,
154
+ target: input.target,
155
+ payload: { status: input.status }
156
+ });
157
+ }
158
+
159
+ export {
160
+ bareAccountId,
161
+ failWriteValidation,
162
+ refuseDeleteByUpdate,
163
+ loadJsonFileArg,
164
+ mergePayload,
165
+ parseMoneyFlag,
166
+ parseDateFlag,
167
+ listFlag,
168
+ upper,
169
+ numberFlag,
170
+ requireTarget,
171
+ stageOp,
172
+ stageStatusChange
173
+ };
174
+ //# sourceMappingURL=chunk-EPDE7ZRU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/commands/ads/meta/write-shared.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { type MetaDraftStageResponse, metaDraftOpInputSchema } from \"@baker/api/ads-meta\";\nimport { apiPost } from \"../../../client.ts\";\nimport { requireChatId } from \"../../../env.ts\";\nimport { capabilityFix } from \"../../capabilities/fix.ts\";\nimport { booleanWordPositionalError } from \"../boolean-word-positional.ts\";\nimport { adCopyHints } from \"../copy-hints.ts\";\nimport { withHints } from \"../hints.ts\";\nimport { writeJsonEnvelope } from \"../output.ts\";\nimport { handleMetaError, resolveAccountIdArg } from \"./shared.ts\";\n\n/**\n * Shared plumbing for the staged Meta write commands. Writes NEVER hit Meta\n * directly: every command stages an op against this chat's draft\n * (`/api/ads/meta/draft/stage`), the dashboard shows it as a pending Meta\n * change, and it applies when the chat is published.\n */\n\n/** Backend account ids are bare numeric — strip the `act_` prefix resolveAccountIdArg adds. */\nexport function bareAccountId(args: Record<string, unknown>): string {\n return resolveAccountIdArg(args).replace(/^act_/, \"\");\n}\n\nexport function failWriteValidation(message: string): never {\n writeJsonEnvelope({ ok: false, error: { code: \"VALIDATION_ERROR\", message } });\n process.exit(1);\n}\n\n/** Deleting is permanent, so it only stages through `delete`, whose description carries that warning. */\nexport function refuseDeleteByUpdate(payload: Record<string, unknown>, group: \"campaigns\" | \"adsets\" | \"ads\"): void {\n if (payload.status === \"DELETED\") {\n failWriteValidation(\n `update does not delete — deleting is permanent. Use \\`baker ads meta ${group} delete <id>\\` if the user asked to delete; otherwise pause or archive.`,\n );\n }\n}\n\nexport function loadJsonFileArg(path: unknown): Record<string, unknown> {\n if (typeof path !== \"string\" || path.length === 0) {\n return {};\n }\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n failWriteValidation(`${path} must contain a JSON object`);\n }\n return parsed as Record<string, unknown>;\n } catch (err) {\n if (err instanceof SyntaxError) {\n failWriteValidation(`${path} is not valid JSON: ${err.message}`);\n }\n throw err;\n }\n}\n\n/** Flags override file keys — the file is the base, flags are the overrides. */\nexport function mergePayload(file: Record<string, unknown>, flags: Record<string, unknown>): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...file };\n for (const [key, value] of Object.entries(flags)) {\n if (value !== undefined) {\n merged[key] = value;\n }\n }\n return merged;\n}\n\nexport function parseMoneyFlag(\n amount: unknown,\n currency: unknown,\n flag: string,\n): { amount: string; currencyCode?: string } | undefined {\n if (amount === undefined || amount === null || amount === \"\") {\n return undefined;\n }\n if (currency === undefined || currency === null || currency === \"\") {\n // Meta ad accounts are single-currency — the backend fills it in.\n return { amount: String(amount) };\n }\n if (typeof currency !== \"string\" || currency.length !== 3) {\n failWriteValidation(`${flag} got an invalid --currency (expected a 3-letter code like USD)`);\n }\n return { amount: String(amount), currencyCode: currency.toUpperCase() };\n}\n\n/** Accepts ISO dates (2026-07-10), ISO datetimes, or epoch millis. */\nexport function parseDateFlag(value: unknown, flag: string): number | undefined {\n if (value === undefined || value === null || value === \"\") {\n return undefined;\n }\n const raw = String(value);\n if (/^\\d{10,}$/.test(raw)) {\n return Number(raw);\n }\n const parsed = Date.parse(raw);\n if (Number.isNaN(parsed)) {\n failWriteValidation(`${flag} must be an ISO date (2026-07-10) or epoch milliseconds`);\n }\n return parsed;\n}\n\n/** Split a comma-separated flag into a trimmed, non-empty array. */\nexport function listFlag(value: unknown): string[] | undefined {\n if (typeof value !== \"string\" || value.trim().length === 0) {\n return undefined;\n }\n const items = value\n .split(\",\")\n .map((item) => item.trim())\n .filter(Boolean);\n return items.length > 0 ? items : undefined;\n}\n\nexport function upper(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value.toUpperCase() : undefined;\n}\n\nexport function numberFlag(value: unknown, flag: string): number | undefined {\n if (value === undefined || value === null || value === \"\") {\n return undefined;\n }\n const n = Number(value);\n if (!Number.isFinite(n)) {\n failWriteValidation(`${flag} must be a number`);\n }\n return n;\n}\n\n/**\n * Accepts whichever positional the command declared (`id`, `target`, `ref`) or the raw positional.\n *\n * `--flag false` is refused first: citty turns it into the flag set to TRUE plus a stray positional,\n * so on `campaigns duplicate 6123 --replace false` the copy stages AND the live original is staged\n * for pause — the opposite of what was typed, with an \"ok\" receipt. This is the only place on this\n * surface that reads positionals, and every target-taking command goes through it.\n */\nexport function requireTarget(args: Record<string, unknown>, entity: string): string {\n const inverted = booleanWordPositionalError(args, entity);\n if (inverted !== undefined) {\n failWriteValidation(inverted);\n }\n const positional = Array.isArray(args._) ? args._[0] : undefined;\n const target = args.id ?? args.target ?? args.ref ?? positional;\n if (typeof target !== \"string\" || target.length === 0) {\n failWriteValidation(`pass the ${entity} id as the positional argument`);\n }\n return target;\n}\n\ninterface StageEnvelope extends Record<string, unknown> {\n ok: true;\n data: MetaDraftStageResponse;\n}\n\n/**\n * Preflight-validates the op against the shared `@baker/api/ads-meta` contract\n * (same schema the backend enforces), then stages it. Prints the staged\n * envelope — ref, mode (always `live`: publishing reaches the real ad account),\n * summary, warnings.\n */\nexport async function stageOp(raw: Record<string, unknown>): Promise<void> {\n const preflight = metaDraftOpInputSchema.safeParse(raw);\n if (!preflight.success) {\n const fields = preflight.error.issues.map((issue) => ({ path: issue.path.join(\".\"), message: issue.message }));\n writeJsonEnvelope({\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: fields.map((field) => (field.path ? `${field.path}: ${field.message}` : field.message)).join(\"; \"),\n fields,\n fix: capabilityFix(\"meta-ads\"),\n },\n });\n process.exit(1);\n }\n try {\n const chatId = requireChatId();\n const response = await apiPost<StageEnvelope>(\"/api/ads/meta/draft/stage\", { chatId, op: preflight.data });\n const copyHints = await adCopyHints(preflight.data);\n writeJsonEnvelope(withHints(response, copyHints));\n } catch (err) {\n handleMetaError(err);\n }\n}\n\nexport async function stageStatusChange(input: {\n kind: \"campaign.update\" | \"adSet.update\" | \"adCreative.update\" | \"ad.update\" | \"customAudience.update\";\n accountId: string;\n target: string;\n status: \"ACTIVE\" | \"PAUSED\" | \"ARCHIVED\" | \"DELETED\";\n}): Promise<void> {\n await stageOp({\n kind: input.kind,\n accountId: input.accountId,\n target: input.target,\n payload: { status: input.status },\n });\n}\n"],"mappings":"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","names":[]}