@koda-sl/baker-cli 0.386.0-dev.8b1f99042 → 0.386.0-dev.d6e55699d
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1091 -211
- package/canvas/tiktok-captions-composition/index.html +5 -6
- package/canvas/tiktok-captions-composition/meta.json +5 -0
- package/dist/account-5TGX45FO.js +79 -0
- package/dist/account-5TGX45FO.js.map +1 -0
- package/dist/account-CLOKMTTC.js +49 -0
- package/dist/account-CLOKMTTC.js.map +1 -0
- package/dist/account-XFK6VX2R.js +80 -0
- package/dist/account-XFK6VX2R.js.map +1 -0
- package/dist/account-reads-ZK5RMLB2.js +218 -0
- package/dist/account-reads-ZK5RMLB2.js.map +1 -0
- package/dist/account-writes-Y7EQXDXF.js +66 -0
- package/dist/account-writes-Y7EQXDXF.js.map +1 -0
- package/dist/accounts-7YD457YN.js +114 -0
- package/dist/accounts-7YD457YN.js.map +1 -0
- package/dist/accounts-BJ3X5JQT.js +115 -0
- package/dist/accounts-BJ3X5JQT.js.map +1 -0
- package/dist/accounts-HGAFFOA7.js +77 -0
- package/dist/accounts-HGAFFOA7.js.map +1 -0
- package/dist/accounts-OWMXUT6D.js +611 -0
- package/dist/accounts-OWMXUT6D.js.map +1 -0
- package/dist/accounts-RYBDLQ6H.js +75 -0
- package/dist/accounts-RYBDLQ6H.js.map +1 -0
- package/dist/actions-NSQYW7YS.js +55 -0
- package/dist/actions-NSQYW7YS.js.map +1 -0
- package/dist/active-entities-R6GZIO6Z.js +103 -0
- package/dist/active-entities-R6GZIO6Z.js.map +1 -0
- package/dist/activities-ESBF3GFS.js +74 -0
- package/dist/activities-ESBF3GFS.js.map +1 -0
- package/dist/ad-group-writes-I225OYDZ.js +170 -0
- package/dist/ad-group-writes-I225OYDZ.js.map +1 -0
- package/dist/ad-groups-O35MWNF6.js +68 -0
- package/dist/ad-groups-O35MWNF6.js.map +1 -0
- package/dist/ad-writes-SS5YZO5W.js +174 -0
- package/dist/ad-writes-SS5YZO5W.js.map +1 -0
- package/dist/add-HWIE5PGR.js +302 -0
- package/dist/add-HWIE5PGR.js.map +1 -0
- package/dist/add-IIW3NHZH.js +104 -0
- package/dist/add-IIW3NHZH.js.map +1 -0
- package/dist/add-QZHAWUBA.js +97 -0
- package/dist/add-QZHAWUBA.js.map +1 -0
- package/dist/add-TGQIVVXH.js +105 -0
- package/dist/add-TGQIVVXH.js.map +1 -0
- package/dist/add-accounts-6QYPOPR2.js +91 -0
- package/dist/add-accounts-6QYPOPR2.js.map +1 -0
- package/dist/ads-AUSRB4GU.js +128 -0
- package/dist/ads-AUSRB4GU.js.map +1 -0
- package/dist/ads-COYOTEKE.js +77 -0
- package/dist/ads-COYOTEKE.js.map +1 -0
- package/dist/ads-D6KKCQ3Q.js +40 -0
- package/dist/ads-D6KKCQ3Q.js.map +1 -0
- package/dist/ads-QKIHHXP5.js +113 -0
- package/dist/ads-QKIHHXP5.js.map +1 -0
- package/dist/adsets-7WMWU45E.js +176 -0
- package/dist/adsets-7WMWU45E.js.map +1 -0
- package/dist/advertisers-6NZ2M57X.js +120 -0
- package/dist/advertisers-6NZ2M57X.js.map +1 -0
- package/dist/advertisers-BCGKUMEH.js +125 -0
- package/dist/advertisers-BCGKUMEH.js.map +1 -0
- package/dist/analytics-QJC2BTZY.js +433 -0
- package/dist/analytics-QJC2BTZY.js.map +1 -0
- package/dist/analytics-SN6K7J7M.js +1980 -0
- package/dist/analytics-SN6K7J7M.js.map +1 -0
- package/dist/animate-JXIT77Y5.js +480 -0
- package/dist/animate-JXIT77Y5.js.map +1 -0
- package/dist/assign-XFDA42KL.js +77 -0
- package/dist/assign-XFDA42KL.js.map +1 -0
- package/dist/audience-size-DJPFYHPJ.js +94 -0
- package/dist/audience-size-DJPFYHPJ.js.map +1 -0
- package/dist/audiences-DC3IOG34.js +85 -0
- package/dist/audiences-DC3IOG34.js.map +1 -0
- package/dist/audiences-NEW3LLQR.js +268 -0
- package/dist/audiences-NEW3LLQR.js.map +1 -0
- package/dist/audiences-VXTIBZP6.js +78 -0
- package/dist/audiences-VXTIBZP6.js.map +1 -0
- package/dist/audit-M5B7TZGT.js +151 -0
- package/dist/audit-M5B7TZGT.js.map +1 -0
- package/dist/audit-UIPMTI5C.js +88 -0
- package/dist/audit-UIPMTI5C.js.map +1 -0
- package/dist/autocomplete-NWHEASQY.js +111 -0
- package/dist/autocomplete-NWHEASQY.js.map +1 -0
- package/dist/avatars-RNMUVMFM.js +38 -0
- package/dist/avatars-RNMUVMFM.js.map +1 -0
- package/dist/bid-pricing-EAY3HAHY.js +99 -0
- package/dist/bid-pricing-EAY3HAHY.js.map +1 -0
- package/dist/brand-XBHWYPMT.js +22 -0
- package/dist/brand-XBHWYPMT.js.map +1 -0
- package/dist/brief-XBAAPKRR.js +492 -0
- package/dist/brief-XBAAPKRR.js.map +1 -0
- package/dist/businesses-J7OP7MSK.js +53 -0
- package/dist/businesses-J7OP7MSK.js.map +1 -0
- package/dist/campaign-groups-7KA2RA5V.js +95 -0
- package/dist/campaign-groups-7KA2RA5V.js.map +1 -0
- package/dist/campaign-writes-5XA727KI.js +170 -0
- package/dist/campaign-writes-5XA727KI.js.map +1 -0
- package/dist/campaign-writes-D2UID2I6.js +165 -0
- package/dist/campaign-writes-D2UID2I6.js.map +1 -0
- package/dist/campaigns-JPYNVFQI.js +76 -0
- package/dist/campaigns-JPYNVFQI.js.map +1 -0
- package/dist/campaigns-NJ3KOPJS.js +107 -0
- package/dist/campaigns-NJ3KOPJS.js.map +1 -0
- package/dist/campaigns-QUTTH2TB.js +110 -0
- package/dist/campaigns-QUTTH2TB.js.map +1 -0
- package/dist/campaigns-SOO5RHYG.js +109 -0
- package/dist/campaigns-SOO5RHYG.js.map +1 -0
- package/dist/canvas-3VZ46BCF.js +46 -0
- package/dist/canvas-3VZ46BCF.js.map +1 -0
- package/dist/capabilities-KAYDPH7E.js +144 -0
- package/dist/capabilities-KAYDPH7E.js.map +1 -0
- package/dist/cards-7H32TNMO.js +85 -0
- package/dist/cards-7H32TNMO.js.map +1 -0
- package/dist/catalog-OTICZPJA.js +64 -0
- package/dist/catalog-OTICZPJA.js.map +1 -0
- package/dist/catalogs-ABCQLCDU.js +128 -0
- package/dist/catalogs-ABCQLCDU.js.map +1 -0
- package/dist/changes-22EO52IY.js +135 -0
- package/dist/changes-22EO52IY.js.map +1 -0
- package/dist/chatgpt-B3NHRJUE.js +47 -0
- package/dist/chatgpt-B3NHRJUE.js.map +1 -0
- package/dist/chats-QG3IRHOD.js +262 -0
- package/dist/chats-QG3IRHOD.js.map +1 -0
- package/dist/chunk-2CV7LX23.js +474 -0
- package/dist/chunk-2CV7LX23.js.map +1 -0
- package/dist/chunk-2SQJL7ZN.js +56 -0
- package/dist/chunk-2SQJL7ZN.js.map +1 -0
- package/dist/chunk-2Y5V23PU.js +29 -0
- package/dist/chunk-2Y5V23PU.js.map +1 -0
- package/dist/chunk-32CPGJPL.js +149 -0
- package/dist/chunk-32CPGJPL.js.map +1 -0
- package/dist/chunk-32PSERWG.js +363 -0
- package/dist/chunk-32PSERWG.js.map +1 -0
- package/dist/chunk-3ACMDRSE.js +39 -0
- package/dist/chunk-3ACMDRSE.js.map +1 -0
- package/dist/chunk-3UDSYYND.js +42 -0
- package/dist/chunk-3UDSYYND.js.map +1 -0
- package/dist/chunk-3V5E5SVE.js +382 -0
- package/dist/chunk-3V5E5SVE.js.map +1 -0
- package/dist/chunk-455BTAHM.js +57 -0
- package/dist/chunk-455BTAHM.js.map +1 -0
- package/dist/chunk-4MH6LONO.js +274 -0
- package/dist/chunk-4MH6LONO.js.map +1 -0
- package/dist/chunk-4NZ47VXO.js +137 -0
- package/dist/chunk-4NZ47VXO.js.map +1 -0
- package/dist/chunk-4OBO75XU.js +275 -0
- package/dist/chunk-4OBO75XU.js.map +1 -0
- package/dist/chunk-5HYSKH77.js +315 -0
- package/dist/chunk-5HYSKH77.js.map +1 -0
- package/dist/chunk-5MBPIONY.js +29 -0
- package/dist/chunk-5MBPIONY.js.map +1 -0
- package/dist/chunk-5OVOLYY3.js +74 -0
- package/dist/chunk-5OVOLYY3.js.map +1 -0
- package/dist/chunk-66USKCVY.js +4410 -0
- package/dist/chunk-66USKCVY.js.map +1 -0
- package/dist/chunk-6I7SYEYN.js +166 -0
- package/dist/chunk-6I7SYEYN.js.map +1 -0
- package/dist/chunk-6O7ISBC7.js +65 -0
- package/dist/chunk-6O7ISBC7.js.map +1 -0
- package/dist/chunk-752S7JF6.js +35 -0
- package/dist/chunk-752S7JF6.js.map +1 -0
- package/dist/chunk-AFJGYJ7Z.js +45 -0
- package/dist/chunk-AFJGYJ7Z.js.map +1 -0
- package/dist/chunk-AR7PU7BB.js +76 -0
- package/dist/chunk-AR7PU7BB.js.map +1 -0
- package/dist/chunk-ASL7JFBD.js +96 -0
- package/dist/chunk-ASL7JFBD.js.map +1 -0
- package/dist/chunk-AUCITRRT.js +310 -0
- package/dist/chunk-AUCITRRT.js.map +1 -0
- package/dist/chunk-AUSKKFVH.js +84 -0
- package/dist/chunk-AUSKKFVH.js.map +1 -0
- package/dist/chunk-BEGARAVC.js +174 -0
- package/dist/chunk-BEGARAVC.js.map +1 -0
- package/dist/{chunk-XHC4LMK4.js → chunk-BVM5IRZW.js} +16 -8
- package/dist/chunk-BVM5IRZW.js.map +1 -0
- package/dist/chunk-CAMX6OHF.js +3182 -0
- package/dist/chunk-CAMX6OHF.js.map +1 -0
- package/dist/chunk-CKI3RLMU.js +159 -0
- package/dist/chunk-CKI3RLMU.js.map +1 -0
- package/dist/chunk-CZENWCBS.js +333 -0
- package/dist/chunk-CZENWCBS.js.map +1 -0
- package/dist/chunk-D5FY4FAK.js +24 -0
- package/dist/chunk-D5FY4FAK.js.map +1 -0
- package/dist/chunk-DGCUPJZD.js +39 -0
- package/dist/chunk-DGCUPJZD.js.map +1 -0
- package/dist/chunk-DIICZGIS.js +509 -0
- package/dist/chunk-DIICZGIS.js.map +1 -0
- package/dist/chunk-DNCLWSHO.js +41 -0
- package/dist/chunk-DNCLWSHO.js.map +1 -0
- package/dist/chunk-DX4GIDO7.js +296 -0
- package/dist/chunk-DX4GIDO7.js.map +1 -0
- package/dist/chunk-DYZJBWT2.js +1079 -0
- package/dist/chunk-DYZJBWT2.js.map +1 -0
- package/dist/chunk-EDLZGTGN.js +216 -0
- package/dist/chunk-EDLZGTGN.js.map +1 -0
- package/dist/chunk-EDNX3AOS.js +76 -0
- package/dist/chunk-EDNX3AOS.js.map +1 -0
- package/dist/chunk-EF5DP6EB.js +52 -0
- package/dist/chunk-EF5DP6EB.js.map +1 -0
- package/dist/chunk-EQEZAYPL.js +541 -0
- package/dist/chunk-EQEZAYPL.js.map +1 -0
- package/dist/chunk-ERSX3MKH.js +34 -0
- package/dist/chunk-ERSX3MKH.js.map +1 -0
- package/dist/chunk-FKOECEVC.js +126 -0
- package/dist/chunk-FKOECEVC.js.map +1 -0
- package/dist/chunk-FYWWTMXP.js +2902 -0
- package/dist/chunk-FYWWTMXP.js.map +1 -0
- package/dist/chunk-G7AFVTUS.js +106 -0
- package/dist/chunk-G7AFVTUS.js.map +1 -0
- package/dist/chunk-GIW7ABMM.js +74 -0
- package/dist/chunk-GIW7ABMM.js.map +1 -0
- package/dist/chunk-GIWHHCD6.js +145 -0
- package/dist/chunk-GIWHHCD6.js.map +1 -0
- package/dist/chunk-GOJXKIFQ.js +1605 -0
- package/dist/chunk-GOJXKIFQ.js.map +1 -0
- package/dist/chunk-GPXIUYIA.js +592 -0
- package/dist/chunk-GPXIUYIA.js.map +1 -0
- package/dist/chunk-GRQ2AXDX.js +9 -0
- package/dist/chunk-GRQ2AXDX.js.map +1 -0
- package/dist/chunk-GXDLWBOY.js +73 -0
- package/dist/chunk-GXDLWBOY.js.map +1 -0
- package/dist/chunk-H7MLHG2I.js +94 -0
- package/dist/chunk-H7MLHG2I.js.map +1 -0
- package/dist/chunk-HAE4WWFQ.js +455 -0
- package/dist/chunk-HAE4WWFQ.js.map +1 -0
- package/dist/chunk-HB3LNR4Y.js +197 -0
- package/dist/chunk-HB3LNR4Y.js.map +1 -0
- package/dist/chunk-HDHWIEJJ.js +136 -0
- package/dist/chunk-HDHWIEJJ.js.map +1 -0
- package/dist/chunk-HJTIBTF7.js +98 -0
- package/dist/chunk-HJTIBTF7.js.map +1 -0
- package/dist/{chunk-VZEDAFAR.js → chunk-HLXWKMTK.js} +47 -8
- package/dist/chunk-HLXWKMTK.js.map +1 -0
- package/dist/{chunk-MF7YA62W.js → chunk-HREWXNTO.js} +10 -5
- package/dist/chunk-HREWXNTO.js.map +1 -0
- package/dist/chunk-HVJUMQYY.js +494 -0
- package/dist/chunk-HVJUMQYY.js.map +1 -0
- package/dist/chunk-I3DIZWN5.js +97 -0
- package/dist/chunk-I3DIZWN5.js.map +1 -0
- package/dist/chunk-IJMWEO4P.js +57 -0
- package/dist/chunk-IJMWEO4P.js.map +1 -0
- package/dist/chunk-IMORFIUT.js +207 -0
- package/dist/chunk-IMORFIUT.js.map +1 -0
- package/dist/chunk-IOCSDFF2.js +23992 -0
- package/dist/chunk-IOCSDFF2.js.map +1 -0
- package/dist/chunk-IRTYTT5D.js +665 -0
- package/dist/chunk-IRTYTT5D.js.map +1 -0
- package/dist/chunk-IVIJJXXT.js +62 -0
- package/dist/chunk-IVIJJXXT.js.map +1 -0
- package/dist/chunk-J57GWTPK.js +106 -0
- package/dist/chunk-J57GWTPK.js.map +1 -0
- package/dist/chunk-JAYT43KX.js +4227 -0
- package/dist/chunk-JAYT43KX.js.map +1 -0
- package/dist/chunk-JPK34QPS.js +134 -0
- package/dist/chunk-JPK34QPS.js.map +1 -0
- package/dist/chunk-JRCFCIE3.js +188 -0
- package/dist/chunk-JRCFCIE3.js.map +1 -0
- package/dist/chunk-JRGPCPT2.js +479 -0
- package/dist/chunk-JRGPCPT2.js.map +1 -0
- package/dist/chunk-JUAIGJ2A.js +76 -0
- package/dist/chunk-JUAIGJ2A.js.map +1 -0
- package/dist/chunk-K2RYUZ5Y.js +51 -0
- package/dist/chunk-K2RYUZ5Y.js.map +1 -0
- package/dist/chunk-K5OQES4V.js +58 -0
- package/dist/chunk-K5OQES4V.js.map +1 -0
- package/dist/chunk-KAHMADFH.js +455 -0
- package/dist/chunk-KAHMADFH.js.map +1 -0
- package/dist/chunk-KIGGMKAE.js +66 -0
- package/dist/chunk-KIGGMKAE.js.map +1 -0
- package/dist/chunk-KKJ4KJCW.js +29 -0
- package/dist/chunk-KKJ4KJCW.js.map +1 -0
- package/dist/chunk-KLK6KQLQ.js +55 -0
- package/dist/chunk-KLK6KQLQ.js.map +1 -0
- package/dist/chunk-KRIK2JR4.js +6212 -0
- package/dist/chunk-KRIK2JR4.js.map +1 -0
- package/dist/chunk-KZUHRZ2C.js +5187 -0
- package/dist/chunk-KZUHRZ2C.js.map +1 -0
- package/dist/chunk-L5WIRYNB.js +19 -0
- package/dist/chunk-L5WIRYNB.js.map +1 -0
- package/dist/chunk-LA6PPSNA.js +65 -0
- package/dist/chunk-LA6PPSNA.js.map +1 -0
- package/dist/chunk-LEIQAHWF.js +25 -0
- package/dist/chunk-LEIQAHWF.js.map +1 -0
- package/dist/chunk-LWBWCIWL.js +297 -0
- package/dist/chunk-LWBWCIWL.js.map +1 -0
- package/dist/chunk-M4PPFVYL.js +346 -0
- package/dist/chunk-M4PPFVYL.js.map +1 -0
- package/dist/chunk-M6UNISGO.js +66 -0
- package/dist/chunk-M6UNISGO.js.map +1 -0
- package/dist/chunk-MGKHFGLV.js +75 -0
- package/dist/chunk-MGKHFGLV.js.map +1 -0
- package/dist/chunk-MUVSWFLL.js +111 -0
- package/dist/chunk-MUVSWFLL.js.map +1 -0
- package/dist/chunk-NFSLRRIE.js +77 -0
- package/dist/chunk-NFSLRRIE.js.map +1 -0
- package/dist/chunk-NHU33T2S.js +60 -0
- package/dist/chunk-NHU33T2S.js.map +1 -0
- package/dist/chunk-O6QKCJE4.js +455 -0
- package/dist/chunk-O6QKCJE4.js.map +1 -0
- package/dist/chunk-OBNWER4H.js +1599 -0
- package/dist/chunk-OBNWER4H.js.map +1 -0
- package/dist/chunk-OFFAMC5H.js +225 -0
- package/dist/chunk-OFFAMC5H.js.map +1 -0
- package/dist/chunk-P4NSJS54.js +20 -0
- package/dist/chunk-P4NSJS54.js.map +1 -0
- package/dist/chunk-P5T7OZKV.js +26 -0
- package/dist/chunk-P5T7OZKV.js.map +1 -0
- package/dist/chunk-PAHLJMC3.js +175 -0
- package/dist/chunk-PAHLJMC3.js.map +1 -0
- package/dist/chunk-PBVLPFJ6.js +169 -0
- package/dist/chunk-PBVLPFJ6.js.map +1 -0
- package/dist/chunk-PFBQERWX.js +10 -0
- package/dist/chunk-PFBQERWX.js.map +1 -0
- package/dist/chunk-Q6ULQMWG.js +41 -0
- package/dist/chunk-Q6ULQMWG.js.map +1 -0
- package/dist/chunk-QKE7GXZ7.js +6683 -0
- package/dist/chunk-QKE7GXZ7.js.map +1 -0
- package/dist/chunk-QL573PLH.js +150 -0
- package/dist/chunk-QL573PLH.js.map +1 -0
- package/dist/chunk-QO23YHLK.js +84 -0
- package/dist/chunk-QO23YHLK.js.map +1 -0
- package/dist/chunk-R5OQM7FF.js +179 -0
- package/dist/chunk-R5OQM7FF.js.map +1 -0
- package/dist/chunk-RDLB54KF.js +629 -0
- package/dist/chunk-RDLB54KF.js.map +1 -0
- package/dist/chunk-RGIXQEGJ.js +502 -0
- package/dist/chunk-RGIXQEGJ.js.map +1 -0
- package/dist/chunk-RRIAHUWP.js +304 -0
- package/dist/chunk-RRIAHUWP.js.map +1 -0
- package/dist/chunk-S4LZ7KTG.js +160 -0
- package/dist/chunk-S4LZ7KTG.js.map +1 -0
- package/dist/chunk-SHTESUB6.js +1442 -0
- package/dist/chunk-SHTESUB6.js.map +1 -0
- package/dist/chunk-SLB46MSS.js +64 -0
- package/dist/chunk-SLB46MSS.js.map +1 -0
- package/dist/chunk-T7M4WFNV.js +172 -0
- package/dist/chunk-T7M4WFNV.js.map +1 -0
- package/dist/{chunk-VLUGGVJL.js → chunk-TPXI2GCW.js} +12 -4
- package/dist/chunk-TPXI2GCW.js.map +1 -0
- package/dist/chunk-TWNFQUBS.js +23 -0
- package/dist/chunk-TWNFQUBS.js.map +1 -0
- package/dist/chunk-U6VRBDNQ.js +1830 -0
- package/dist/chunk-U6VRBDNQ.js.map +1 -0
- package/dist/chunk-U7BBXM67.js +1743 -0
- package/dist/chunk-U7BBXM67.js.map +1 -0
- package/dist/chunk-UI6BKYQD.js +225 -0
- package/dist/chunk-UI6BKYQD.js.map +1 -0
- package/dist/chunk-USL5ARRE.js +26 -0
- package/dist/chunk-USL5ARRE.js.map +1 -0
- package/dist/chunk-UYC45JNS.js +139 -0
- package/dist/chunk-UYC45JNS.js.map +1 -0
- package/dist/chunk-V5GSRREZ.js +846 -0
- package/dist/chunk-V5GSRREZ.js.map +1 -0
- package/dist/chunk-V5HDRJQW.js +337 -0
- package/dist/chunk-V5HDRJQW.js.map +1 -0
- package/dist/chunk-VS4C7VAR.js +533 -0
- package/dist/chunk-VS4C7VAR.js.map +1 -0
- package/dist/chunk-W4W4ZRBP.js +191 -0
- package/dist/chunk-W4W4ZRBP.js.map +1 -0
- package/dist/chunk-WIRBRCTJ.js +228 -0
- package/dist/chunk-WIRBRCTJ.js.map +1 -0
- package/dist/chunk-WN4KX7GE.js +25 -0
- package/dist/chunk-WN4KX7GE.js.map +1 -0
- package/dist/chunk-WNFTXSGR.js +111 -0
- package/dist/chunk-WNFTXSGR.js.map +1 -0
- package/dist/chunk-WOTDHRNF.js +2109 -0
- package/dist/chunk-WOTDHRNF.js.map +1 -0
- package/dist/chunk-WPKOEFOE.js +103 -0
- package/dist/chunk-WPKOEFOE.js.map +1 -0
- package/dist/chunk-XE3WS3QE.js +183 -0
- package/dist/chunk-XE3WS3QE.js.map +1 -0
- package/dist/chunk-XGWKTYXQ.js +67 -0
- package/dist/chunk-XGWKTYXQ.js.map +1 -0
- package/dist/chunk-XIGIJJSF.js +66 -0
- package/dist/chunk-XIGIJJSF.js.map +1 -0
- package/dist/chunk-XNUXB63I.js +817 -0
- package/dist/chunk-XNUXB63I.js.map +1 -0
- package/dist/chunk-XQ3CCNJD.js +610 -0
- package/dist/chunk-XQ3CCNJD.js.map +1 -0
- package/dist/chunk-Y362QH54.js +98 -0
- package/dist/chunk-Y362QH54.js.map +1 -0
- package/dist/chunk-Y4HZNSBN.js +3151 -0
- package/dist/chunk-Y4HZNSBN.js.map +1 -0
- package/dist/chunk-Y4T6ATDQ.js +74 -0
- package/dist/chunk-Y4T6ATDQ.js.map +1 -0
- package/dist/chunk-YIMGUMXX.js +206 -0
- package/dist/chunk-YIMGUMXX.js.map +1 -0
- package/dist/chunk-YQSBHWOI.js +41 -0
- package/dist/chunk-YU26SDNT.js +46 -0
- package/dist/chunk-YU26SDNT.js.map +1 -0
- package/dist/chunk-YULENNA7.js +501 -0
- package/dist/chunk-YULENNA7.js.map +1 -0
- package/dist/chunk-YYSZYSAG.js +150 -0
- package/dist/chunk-YYSZYSAG.js.map +1 -0
- package/dist/chunk-Z3ENMCFE.js +94 -0
- package/dist/chunk-Z3ENMCFE.js.map +1 -0
- package/dist/chunk-ZCFSHQBF.js +92 -0
- package/dist/chunk-ZCFSHQBF.js.map +1 -0
- package/dist/chunk-ZH7ZM3ZM.js +125 -0
- package/dist/chunk-ZH7ZM3ZM.js.map +1 -0
- package/dist/chunk-ZIXHS6AM.js +42 -0
- package/dist/chunk-ZIXHS6AM.js.map +1 -0
- package/dist/chunk-ZLLJKSNS.js +96 -0
- package/dist/chunk-ZLLJKSNS.js.map +1 -0
- package/dist/claim-4AFNDV3A.js +197 -0
- package/dist/claim-4AFNDV3A.js.map +1 -0
- package/dist/cli.js +104 -69909
- package/dist/cli.js.map +1 -1
- package/dist/client-26SAJ46D.js +19 -0
- package/dist/code-MOWYJMDH.js +76 -0
- package/dist/code-MOWYJMDH.js.map +1 -0
- package/dist/companies-PZRRZZNV.js +195 -0
- package/dist/companies-PZRRZZNV.js.map +1 -0
- package/dist/complete-IBW5DNVZ.js +81 -0
- package/dist/complete-IBW5DNVZ.js.map +1 -0
- package/dist/config-X6GKOVQ6.js +88 -0
- package/dist/config-X6GKOVQ6.js.map +1 -0
- package/dist/connect-WYUYS5V4.js +42 -0
- package/dist/content-UYZC4AKN.js +85 -0
- package/dist/content-UYZC4AKN.js.map +1 -0
- package/dist/conversation-6AG3UBYY.js +93 -0
- package/dist/conversation-6AG3UBYY.js.map +1 -0
- package/dist/conversion-report-R4GJWWTK.js +125 -0
- package/dist/conversion-report-R4GJWWTK.js.map +1 -0
- package/dist/conversion-upload-command-YML2UNJB.js +438 -0
- package/dist/conversion-upload-command-YML2UNJB.js.map +1 -0
- package/dist/conversion-writes-WHFFUWWL.js +120 -0
- package/dist/conversion-writes-WHFFUWWL.js.map +1 -0
- package/dist/conversions-NOBBFNIU.js +135 -0
- package/dist/conversions-NOBBFNIU.js.map +1 -0
- package/dist/conversions-OXJAX5GB.js +76 -0
- package/dist/conversions-OXJAX5GB.js.map +1 -0
- package/dist/countries-PBXNB3BR.js +82 -0
- package/dist/countries-PBXNB3BR.js.map +1 -0
- package/dist/create-JK42P564.js +59 -0
- package/dist/create-JK42P564.js.map +1 -0
- package/dist/create-LAWUVPCY.js +207 -0
- package/dist/create-LAWUVPCY.js.map +1 -0
- package/dist/create-MUPQ5CTH.js +138 -0
- package/dist/create-MUPQ5CTH.js.map +1 -0
- package/dist/create-NQJNCFRO.js +236 -0
- package/dist/create-NQJNCFRO.js.map +1 -0
- package/dist/creatives-KCWFZIM5.js +182 -0
- package/dist/creatives-KCWFZIM5.js.map +1 -0
- package/dist/creatives-NNDWCSKJ.js +51 -0
- package/dist/creatives-NNDWCSKJ.js.map +1 -0
- package/dist/creatives-RHNHTS2R.js +87 -0
- package/dist/creatives-RHNHTS2R.js.map +1 -0
- package/dist/credentials-CEKGXR2C.js +287 -0
- package/dist/credentials-CEKGXR2C.js.map +1 -0
- package/dist/critique-HDDYER52.js +1449 -0
- package/dist/critique-HDDYER52.js.map +1 -0
- package/dist/critique-QIN2FO4F.js +216 -0
- package/dist/critique-QIN2FO4F.js.map +1 -0
- package/dist/crm-KBPWZC6J.js +318 -0
- package/dist/crm-KBPWZC6J.js.map +1 -0
- package/dist/crm-QBWD7CWB.js +224 -0
- package/dist/crm-QBWD7CWB.js.map +1 -0
- package/dist/crop-U3AD4DDR.js +113 -0
- package/dist/crop-U3AD4DDR.js.map +1 -0
- package/dist/currency-XTFGZFGB.js +88 -0
- package/dist/currency-XTFGZFGB.js.map +1 -0
- package/dist/custom-conversions-W3K33V33.js +125 -0
- package/dist/custom-conversions-W3K33V33.js.map +1 -0
- package/dist/customers-HYE7N2H5.js +56 -0
- package/dist/decide-YTHCBKM6.js +199 -0
- package/dist/decide-YTHCBKM6.js.map +1 -0
- package/dist/delete-64REPCY2.js +54 -0
- package/dist/delete-64REPCY2.js.map +1 -0
- package/dist/delete-AY3KL3N3.js +63 -0
- package/dist/delete-AY3KL3N3.js.map +1 -0
- package/dist/delete-DZUDLYPC.js +69 -0
- package/dist/delete-DZUDLYPC.js.map +1 -0
- package/dist/delete-NZGZP4YP.js +71 -0
- package/dist/delete-NZGZP4YP.js.map +1 -0
- package/dist/delete-VO2LZXE4.js +66 -0
- package/dist/delete-VO2LZXE4.js.map +1 -0
- package/dist/delete-VQMU56OH.js +71 -0
- package/dist/delete-VQMU56OH.js.map +1 -0
- package/dist/demographics-KOFLMGVW.js +138 -0
- package/dist/demographics-KOFLMGVW.js.map +1 -0
- package/dist/describe-JNTCQZNL.js +97 -0
- package/dist/describe-JNTCQZNL.js.map +1 -0
- package/dist/describe-MT4334NG.js +97 -0
- package/dist/describe-MT4334NG.js.map +1 -0
- package/dist/dimensions-FEZUJRAG.js +101 -0
- package/dist/dimensions-FEZUJRAG.js.map +1 -0
- package/dist/discard-H4RPXZHX.js +66 -0
- package/dist/discard-H4RPXZHX.js.map +1 -0
- package/dist/discover-4GD7QSF5.js +93 -0
- package/dist/discover-4GD7QSF5.js.map +1 -0
- package/dist/discover-L7OVXW4V.js +172 -0
- package/dist/discover-L7OVXW4V.js.map +1 -0
- package/dist/domain-HURQ23KR.js +98 -0
- package/dist/domain-HURQ23KR.js.map +1 -0
- package/dist/download-L27HWEOE.js +299 -0
- package/dist/download-L27HWEOE.js.map +1 -0
- package/dist/draft-25G2P2TE.js +281 -0
- package/dist/draft-25G2P2TE.js.map +1 -0
- package/dist/draft-5VH2PW3R.js +307 -0
- package/dist/draft-5VH2PW3R.js.map +1 -0
- package/dist/draft-D6UTKSAA.js +217 -0
- package/dist/draft-D6UTKSAA.js.map +1 -0
- package/dist/draft-KLULNBWP.js +233 -0
- package/dist/draft-KLULNBWP.js.map +1 -0
- package/dist/draft-MI7RWY2K.js +100 -0
- package/dist/draft-MI7RWY2K.js.map +1 -0
- package/dist/draft-P4IVYTY3.js +103 -0
- package/dist/draft-P4IVYTY3.js.map +1 -0
- package/dist/draft-UQYWDZS7.js +306 -0
- package/dist/draft-UQYWDZS7.js.map +1 -0
- package/dist/draft-YFAJHCKM.js +328 -0
- package/dist/draft-YFAJHCKM.js.map +1 -0
- package/dist/engine/index.d.ts +213 -127
- package/dist/engine/index.js +18 -4
- package/dist/{env-4P5HOGNA.js → env-FBTHZKGN.js} +12 -2
- package/dist/env-FBTHZKGN.js.map +1 -0
- package/dist/experiment-HDYTJPUY.js +1397 -0
- package/dist/experiment-HDYTJPUY.js.map +1 -0
- package/dist/export-TS5GYEMA.js +168 -0
- package/dist/export-TS5GYEMA.js.map +1 -0
- package/dist/extract-QVQFUOIK.js +113 -0
- package/dist/extract-QVQFUOIK.js.map +1 -0
- package/dist/facets-WYQUZMFJ.js +114 -0
- package/dist/facets-WYQUZMFJ.js.map +1 -0
- package/dist/favorites-7QP7BY5K.js +178 -0
- package/dist/favorites-7QP7BY5K.js.map +1 -0
- package/dist/feed-EETRO2FG.js +177 -0
- package/dist/feed-EETRO2FG.js.map +1 -0
- package/dist/feedback-SIMPRE37.js +66 -0
- package/dist/feedback-SIMPRE37.js.map +1 -0
- package/dist/feedback-record-L4MPIVML.js +177 -0
- package/dist/feedback-record-L4MPIVML.js.map +1 -0
- package/dist/fetch-DTBM3DE2.js +176 -0
- package/dist/fetch-DTBM3DE2.js.map +1 -0
- package/dist/fetch-Z7O3ZL4D.js +139 -0
- package/dist/fetch-Z7O3ZL4D.js.map +1 -0
- package/dist/find-KAQ6JDMO.js +134 -0
- package/dist/find-KAQ6JDMO.js.map +1 -0
- package/dist/fit-MY5GVZZZ.js +45 -0
- package/dist/fit-MY5GVZZZ.js.map +1 -0
- package/dist/flows-IUDXVDOS.js +247 -0
- package/dist/flows-IUDXVDOS.js.map +1 -0
- package/dist/follow-IX4XVK5Y.js +94 -0
- package/dist/follow-IX4XVK5Y.js.map +1 -0
- package/dist/follow-competitors-UZBUOYTH.js +112 -0
- package/dist/follow-competitors-UZBUOYTH.js.map +1 -0
- package/dist/following-VGOIUCIZ.js +113 -0
- package/dist/following-VGOIUCIZ.js.map +1 -0
- package/dist/fonts-EUDHI6CA.js +34 -0
- package/dist/fonts-EUDHI6CA.js.map +1 -0
- package/dist/forecast-BRSEH2H3.js +104 -0
- package/dist/forecast-BRSEH2H3.js.map +1 -0
- package/dist/forecast-QV4U7TOY.js +168 -0
- package/dist/forecast-QV4U7TOY.js.map +1 -0
- package/dist/funding-H5YO37OW.js +85 -0
- package/dist/funding-H5YO37OW.js.map +1 -0
- package/dist/funnel-JLF77MLF.js +394 -0
- package/dist/funnel-JLF77MLF.js.map +1 -0
- package/dist/ga4-YHJ2XMLC.js +55 -0
- package/dist/ga4-YHJ2XMLC.js.map +1 -0
- package/dist/generate-M2ZX5DMI.js +262 -0
- package/dist/generate-M2ZX5DMI.js.map +1 -0
- package/dist/get-4EYKCZ6F.js +59 -0
- package/dist/get-4EYKCZ6F.js.map +1 -0
- package/dist/get-637GALM2.js +63 -0
- package/dist/get-637GALM2.js.map +1 -0
- package/dist/get-AYX5HS64.js +56 -0
- package/dist/get-AYX5HS64.js.map +1 -0
- package/dist/get-AZARFR6O.js +61 -0
- package/dist/get-AZARFR6O.js.map +1 -0
- package/dist/get-EG2U7MIL.js +78 -0
- package/dist/get-EG2U7MIL.js.map +1 -0
- package/dist/get-N4BPOQCB.js +63 -0
- package/dist/get-N4BPOQCB.js.map +1 -0
- package/dist/get-RPZHLQ56.js +92 -0
- package/dist/get-RPZHLQ56.js.map +1 -0
- package/dist/gif-6PRTB2VR.js +94 -0
- package/dist/gif-6PRTB2VR.js.map +1 -0
- package/dist/google-52JRH7X3.js +136 -0
- package/dist/google-52JRH7X3.js.map +1 -0
- package/dist/google-ITTPCJ7N.js +3190 -0
- package/dist/google-ITTPCJ7N.js.map +1 -0
- package/dist/google-ads-U3JFFQLU.js +195 -0
- package/dist/google-ads-U3JFFQLU.js.map +1 -0
- package/dist/group-AAZ5QKC3.js +43 -0
- package/dist/group-AAZ5QKC3.js.map +1 -0
- package/dist/group-GSYCZORC.js +43 -0
- package/dist/group-GSYCZORC.js.map +1 -0
- package/dist/gsc-TS5T7ML2.js +30 -0
- package/dist/gsc-TS5T7ML2.js.map +1 -0
- package/dist/history-EW6LFFCX.js +67 -0
- package/dist/history-EW6LFFCX.js.map +1 -0
- package/dist/history-YTNCWSV3.js +133 -0
- package/dist/history-YTNCWSV3.js.map +1 -0
- package/dist/hubspot-LXWQNKKB.js +779 -0
- package/dist/hubspot-LXWQNKKB.js.map +1 -0
- package/dist/icon-K75KI6BV.js +137 -0
- package/dist/icon-K75KI6BV.js.map +1 -0
- package/dist/ideas-JJIHQFV4.js +35 -0
- package/dist/ideas-JJIHQFV4.js.map +1 -0
- package/dist/images-MWETBYKB.js +90 -0
- package/dist/images-MWETBYKB.js.map +1 -0
- package/dist/improve-L3BW4EQG.js +86 -0
- package/dist/improve-L3BW4EQG.js.map +1 -0
- package/dist/ingest-THFAV4NO.js +107 -0
- package/dist/ingest-THFAV4NO.js.map +1 -0
- package/dist/ingest-U6B7GR4A.js +23 -0
- package/dist/ingest-U6B7GR4A.js.map +1 -0
- package/dist/insights-FA6T6PT6.js +423 -0
- package/dist/insights-FA6T6PT6.js.map +1 -0
- package/dist/insights-PELVD4RY.js +122 -0
- package/dist/insights-PELVD4RY.js.map +1 -0
- package/dist/inspect-N2WVVWGP.js +189 -0
- package/dist/inspect-N2WVVWGP.js.map +1 -0
- package/dist/inspiration-Y2J2PUPC.js +53 -0
- package/dist/inspiration-Y2J2PUPC.js.map +1 -0
- package/dist/intent-YNAAVNHK.js +95 -0
- package/dist/intent-YNAAVNHK.js.map +1 -0
- package/dist/job-E2U4FS5P.js +202 -0
- package/dist/job-E2U4FS5P.js.map +1 -0
- package/dist/job-create-DFYCHVQ7.js +109 -0
- package/dist/job-create-DFYCHVQ7.js.map +1 -0
- package/dist/job-status-FFPMTSHB.js +74 -0
- package/dist/job-status-FFPMTSHB.js.map +1 -0
- package/dist/keep-GYZS2UTL.js +78 -0
- package/dist/keep-GYZS2UTL.js.map +1 -0
- package/dist/keyword-gap-4JKLWIBJ.js +130 -0
- package/dist/keyword-gap-4JKLWIBJ.js.map +1 -0
- package/dist/keyword-metrics-KU3OHTQK.js +197 -0
- package/dist/keyword-metrics-KU3OHTQK.js.map +1 -0
- package/dist/keywords-for-site-M4MFWMVK.js +128 -0
- package/dist/keywords-for-site-M4MFWMVK.js.map +1 -0
- package/dist/landing-7UVZ7IPP.js +28 -0
- package/dist/landing-7UVZ7IPP.js.map +1 -0
- package/dist/landings-F7LOAEJE.js +151 -0
- package/dist/landings-F7LOAEJE.js.map +1 -0
- package/dist/languages-PKYCZNUB.js +40 -0
- package/dist/languages-PKYCZNUB.js.map +1 -0
- package/dist/languages-XEJKTIFP.js +55 -0
- package/dist/languages-XEJKTIFP.js.map +1 -0
- package/dist/launches-TCFAYUA5.js +19 -0
- package/dist/launches-TCFAYUA5.js.map +1 -0
- package/dist/layerize-ZSKFIPZA.js +190 -0
- package/dist/layerize-ZSKFIPZA.js.map +1 -0
- package/dist/leads-CSRESOB2.js +293 -0
- package/dist/leads-CSRESOB2.js.map +1 -0
- package/dist/leads-MQPEA7DG.js +90 -0
- package/dist/leads-MQPEA7DG.js.map +1 -0
- package/dist/learn-K5YBUMBT.js +203 -0
- package/dist/learn-K5YBUMBT.js.map +1 -0
- package/dist/library-IP2UKNRU.js +109 -0
- package/dist/library-IP2UKNRU.js.map +1 -0
- package/dist/lighthouse-57XBJRCO.js +75 -0
- package/dist/lighthouse-57XBJRCO.js.map +1 -0
- package/dist/line-item-writes-73NR2J5L.js +208 -0
- package/dist/line-item-writes-73NR2J5L.js.map +1 -0
- package/dist/line-items-2YBGXOAQ.js +103 -0
- package/dist/line-items-2YBGXOAQ.js.map +1 -0
- package/dist/link-GVAWECJO.js +64 -0
- package/dist/link-GVAWECJO.js.map +1 -0
- package/dist/linkedin-PZDT22AT.js +1008 -0
- package/dist/linkedin-PZDT22AT.js.map +1 -0
- package/dist/list-6IKPWQGG.js +57 -0
- package/dist/list-6IKPWQGG.js.map +1 -0
- package/dist/list-CAUH3BMG.js +65 -0
- package/dist/list-CAUH3BMG.js.map +1 -0
- package/dist/list-FNDRV25Y.js +151 -0
- package/dist/list-FNDRV25Y.js.map +1 -0
- package/dist/list-GTOSN7DP.js +50 -0
- package/dist/list-GTOSN7DP.js.map +1 -0
- package/dist/list-HLJP4NVE.js +51 -0
- package/dist/list-HLJP4NVE.js.map +1 -0
- package/dist/list-LCUPF7EF.js +76 -0
- package/dist/list-LCUPF7EF.js.map +1 -0
- package/dist/list-REZGFWC5.js +63 -0
- package/dist/list-REZGFWC5.js.map +1 -0
- package/dist/list-S6MNXDTV.js +303 -0
- package/dist/list-S6MNXDTV.js.map +1 -0
- package/dist/locations-2BYWKIYA.js +67 -0
- package/dist/locations-2BYWKIYA.js.map +1 -0
- package/dist/locations-GJHHMV6Z.js +40 -0
- package/dist/locations-GJHHMV6Z.js.map +1 -0
- package/dist/log-HGDNLDUX.js +92 -0
- package/dist/log-HGDNLDUX.js.map +1 -0
- package/dist/logo-AJK2TDQU.js +18 -0
- package/dist/logo-AJK2TDQU.js.map +1 -0
- package/dist/lookup-H5GEM77H.js +22 -0
- package/dist/lookup-H5GEM77H.js.map +1 -0
- package/dist/make-BT26YJXZ.js +640 -0
- package/dist/make-BT26YJXZ.js.map +1 -0
- package/dist/map-J5EX4HOX.js +404 -0
- package/dist/map-J5EX4HOX.js.map +1 -0
- package/dist/mcp-MHDW6AFL.js +463 -0
- package/dist/mcp-MHDW6AFL.js.map +1 -0
- package/dist/media-RAGEJTZX.js +89 -0
- package/dist/media-RAGEJTZX.js.map +1 -0
- package/dist/media-RNB7JFJP.js +15 -0
- package/dist/media-RNB7JFJP.js.map +1 -0
- package/dist/media-sources-4NN3DWSG.js +32 -0
- package/dist/media-sources-4NN3DWSG.js.map +1 -0
- package/dist/members-AIWMXAQD.js +44 -0
- package/dist/members-AIWMXAQD.js.map +1 -0
- package/dist/meta-WAPZMZI7.js +69 -0
- package/dist/meta-WAPZMZI7.js.map +1 -0
- package/dist/metrics-6EHC4ESN.js +152 -0
- package/dist/metrics-6EHC4ESN.js.map +1 -0
- package/dist/models-5J4WFUD3.js +155 -0
- package/dist/models-5J4WFUD3.js.map +1 -0
- package/dist/normalize-DSFVTRXN.js +806 -0
- package/dist/normalize-DSFVTRXN.js.map +1 -0
- package/dist/normalize-ZAWN4XCS.js +141 -0
- package/dist/normalize-ZAWN4XCS.js.map +1 -0
- package/dist/options-3CZNT5KP.js +121 -0
- package/dist/options-3CZNT5KP.js.map +1 -0
- package/dist/output-DTCLVPUF.js +24 -0
- package/dist/output-DTCLVPUF.js.map +1 -0
- package/dist/page-N2ZO3O7F.js +105 -0
- package/dist/page-N2ZO3O7F.js.map +1 -0
- package/dist/pages-FQ4CBAJ2.js +66 -0
- package/dist/pages-FQ4CBAJ2.js.map +1 -0
- package/dist/performance-GOMJMHPE.js +24 -0
- package/dist/performance-GOMJMHPE.js.map +1 -0
- package/dist/pinterest-NV5XTNJE.js +96 -0
- package/dist/pinterest-NV5XTNJE.js.map +1 -0
- package/dist/pixels-CTJ43FZ4.js +108 -0
- package/dist/pixels-CTJ43FZ4.js.map +1 -0
- package/dist/pixels-HKINGZCH.js +60 -0
- package/dist/pixels-HKINGZCH.js.map +1 -0
- package/dist/plan-ZYTWLGWK.js +207 -0
- package/dist/plan-ZYTWLGWK.js.map +1 -0
- package/dist/preview-UKYLPAW2.js +169 -0
- package/dist/preview-UKYLPAW2.js.map +1 -0
- package/dist/profile-Q3PHR6FU.js +159 -0
- package/dist/profile-Q3PHR6FU.js.map +1 -0
- package/dist/promoted-tweet-writes-IYOAZTA5.js +180 -0
- package/dist/promoted-tweet-writes-IYOAZTA5.js.map +1 -0
- package/dist/promoted-tweets-G3XFD5YM.js +119 -0
- package/dist/promoted-tweets-G3XFD5YM.js.map +1 -0
- package/dist/properties-WLL6M2P6.js +101 -0
- package/dist/properties-WLL6M2P6.js.map +1 -0
- package/dist/publish-ZG4J2GTH.js +322 -0
- package/dist/publish-ZG4J2GTH.js.map +1 -0
- package/dist/query-7AGG77WH.js +61 -0
- package/dist/query-7AGG77WH.js.map +1 -0
- package/dist/query-IYZN5KHO.js +236 -0
- package/dist/query-IYZN5KHO.js.map +1 -0
- package/dist/query-UN2P6DBA.js +247 -0
- package/dist/query-UN2P6DBA.js.map +1 -0
- package/dist/questionnaire-Z2ZIKNBV.js +93 -0
- package/dist/questionnaire-Z2ZIKNBV.js.map +1 -0
- package/dist/read-GM7PQYJA.js +141 -0
- package/dist/read-GM7PQYJA.js.map +1 -0
- package/dist/reddit-FTO4SFQE.js +26 -0
- package/dist/reddit-FTO4SFQE.js.map +1 -0
- package/dist/refresh-OUENQ2FS.js +94 -0
- package/dist/refresh-OUENQ2FS.js.map +1 -0
- package/dist/release-5OG7AAFY.js +60 -0
- package/dist/release-5OG7AAFY.js.map +1 -0
- package/dist/relevant-pages-KUVDZPRU.js +99 -0
- package/dist/relevant-pages-KUVDZPRU.js.map +1 -0
- package/dist/remove-33HI27KM.js +50 -0
- package/dist/remove-33HI27KM.js.map +1 -0
- package/dist/remove-GOYW2G4R.js +48 -0
- package/dist/remove-GOYW2G4R.js.map +1 -0
- package/dist/reopen-KFFYE53A.js +63 -0
- package/dist/reopen-KFFYE53A.js.map +1 -0
- package/dist/rerun-P6XACA5Z.js +86 -0
- package/dist/rerun-P6XACA5Z.js.map +1 -0
- package/dist/research-BEO3JMZI.js +262 -0
- package/dist/research-BEO3JMZI.js.map +1 -0
- package/dist/research-QOC53DLS.js +62 -0
- package/dist/research-QOC53DLS.js.map +1 -0
- package/dist/reset-E3OWE2WF.js +54 -0
- package/dist/reset-E3OWE2WF.js.map +1 -0
- package/dist/reset-I7M3HYMB.js +54 -0
- package/dist/reset-I7M3HYMB.js.map +1 -0
- package/dist/resolve-GP7BHM6L.js +121 -0
- package/dist/resolve-GP7BHM6L.js.map +1 -0
- package/dist/retry-33ZJCNQI.js +62 -0
- package/dist/retry-33ZJCNQI.js.map +1 -0
- package/dist/retry-X5PU7QO3.js +60 -0
- package/dist/retry-X5PU7QO3.js.map +1 -0
- package/dist/retry-failed-BEFWRV4Z.js +45 -0
- package/dist/retry-failed-BEFWRV4Z.js.map +1 -0
- package/dist/run-REK3TEGY.js +65 -0
- package/dist/run-REK3TEGY.js.map +1 -0
- package/dist/run-TH2662IC.js +61 -0
- package/dist/run-TH2662IC.js.map +1 -0
- package/dist/scaffold-ad-3WDRKUFT.js +1550 -0
- package/dist/scaffold-ad-3WDRKUFT.js.map +1 -0
- package/dist/scaffold-static-ad-X5NT52NF.js +973 -0
- package/dist/scaffold-static-ad-X5NT52NF.js.map +1 -0
- package/dist/scaffold-video-WZPVACLE.js +874 -0
- package/dist/scaffold-video-WZPVACLE.js.map +1 -0
- package/dist/schedule-KQ7UIR3N.js +66 -0
- package/dist/schedule-KQ7UIR3N.js.map +1 -0
- package/dist/schedule-V4UHGY3V.js +61 -0
- package/dist/schedule-V4UHGY3V.js.map +1 -0
- package/dist/scheduled-agents-KLQ5H2PA.js +49 -0
- package/dist/scheduled-agents-KLQ5H2PA.js.map +1 -0
- package/dist/schema-G3T4PZDI.js +132 -0
- package/dist/schema-G3T4PZDI.js.map +1 -0
- package/dist/schema-QXTDLZVC.js +63 -0
- package/dist/schema-QXTDLZVC.js.map +1 -0
- package/dist/scrape-7YKJWFZE.js +2241 -0
- package/dist/scrape-7YKJWFZE.js.map +1 -0
- package/dist/screenshot-ZHBSG3SI.js +102 -0
- package/dist/screenshot-ZHBSG3SI.js.map +1 -0
- package/dist/search-332KFYZ6.js +224 -0
- package/dist/search-332KFYZ6.js.map +1 -0
- package/dist/search-4PBMXXUY.js +91 -0
- package/dist/search-4PBMXXUY.js.map +1 -0
- package/dist/search-6XKEGABN.js +174 -0
- package/dist/search-6XKEGABN.js.map +1 -0
- package/dist/search-AVNUU6TJ.js +26 -0
- package/dist/search-AVNUU6TJ.js.map +1 -0
- package/dist/search-F5INRFFK.js +92 -0
- package/dist/search-F5INRFFK.js.map +1 -0
- package/dist/search-copy-DZVBYG2B.js +168 -0
- package/dist/search-copy-DZVBYG2B.js.map +1 -0
- package/dist/seeds-5JTQN5WI.js +101 -0
- package/dist/seeds-5JTQN5WI.js.map +1 -0
- package/dist/select-N2V55BEX.js +96 -0
- package/dist/select-N2V55BEX.js.map +1 -0
- package/dist/sends-3L6QBS46.js +309 -0
- package/dist/sends-3L6QBS46.js.map +1 -0
- package/dist/sequences-YKFV7BDH.js +146 -0
- package/dist/sequences-YKFV7BDH.js.map +1 -0
- package/dist/set-prompt-7HVHERRU.js +188 -0
- package/dist/set-prompt-7HVHERRU.js.map +1 -0
- package/dist/setup-links-4VVNQVPU.js +141 -0
- package/dist/setup-links-4VVNQVPU.js.map +1 -0
- package/dist/{shared-J7DQZ2ED.js → shared-QAMP7FZV.js} +8 -6
- package/dist/shared-QAMP7FZV.js.map +1 -0
- package/dist/shopify-FSHM5M4I.js +3346 -0
- package/dist/shopify-FSHM5M4I.js.map +1 -0
- package/dist/site-Q2HTRLIW.js +177 -0
- package/dist/site-Q2HTRLIW.js.map +1 -0
- package/dist/sitemaps-XPGLW24S.js +87 -0
- package/dist/sitemaps-XPGLW24S.js.map +1 -0
- package/dist/sites-WMBY2HJV.js +101 -0
- package/dist/sites-WMBY2HJV.js.map +1 -0
- package/dist/skills-3HEILQCU.js +47 -0
- package/dist/skills-3HEILQCU.js.map +1 -0
- package/dist/sources-2KN4RJNJ.js +30 -0
- package/dist/sources-2KN4RJNJ.js.map +1 -0
- package/dist/sources-4I2YMS2K.js +421 -0
- package/dist/sources-4I2YMS2K.js.map +1 -0
- package/dist/stale-IN7WSBLC.js +66 -0
- package/dist/stale-IN7WSBLC.js.map +1 -0
- package/dist/stats-GNILHSKK.js +34 -0
- package/dist/stats-GNILHSKK.js.map +1 -0
- package/dist/status-6SLKZWNR.js +62 -0
- package/dist/status-6SLKZWNR.js.map +1 -0
- package/dist/sticker-KCV3VZHY.js +94 -0
- package/dist/sticker-KCV3VZHY.js.map +1 -0
- package/dist/stock-VTORKR4C.js +179 -0
- package/dist/stock-VTORKR4C.js.map +1 -0
- package/dist/studio-QCRA6BY5.js +49 -0
- package/dist/studio-QCRA6BY5.js.map +1 -0
- package/dist/sync-455DB46Y.js +54 -0
- package/dist/sync-455DB46Y.js.map +1 -0
- package/dist/sync-A4KKQ3B6.js +265 -0
- package/dist/sync-A4KKQ3B6.js.map +1 -0
- package/dist/sync-LFZV5NBN.js +54 -0
- package/dist/sync-LFZV5NBN.js.map +1 -0
- package/dist/sync-definition-IJISZ5VQ.js +55 -0
- package/dist/sync-definition-IJISZ5VQ.js.map +1 -0
- package/dist/tag-manager-E7QTXBWQ.js +43 -0
- package/dist/tag-manager-E7QTXBWQ.js.map +1 -0
- package/dist/tags-6OAZOQYO.js +26 -0
- package/dist/tags-6OAZOQYO.js.map +1 -0
- package/dist/tags-6YRMDX3R.js +20 -0
- package/dist/tags-6YRMDX3R.js.map +1 -0
- package/dist/tags-EWXZSZYE.js +20 -0
- package/dist/tags-EWXZSZYE.js.map +1 -0
- package/dist/tags-SZCNPE2D.js +224 -0
- package/dist/tags-SZCNPE2D.js.map +1 -0
- package/dist/tags-TCFFP534.js +20 -0
- package/dist/tags-TCFFP534.js.map +1 -0
- package/dist/targeting-constants-D64YO3E7.js +118 -0
- package/dist/targeting-constants-D64YO3E7.js.map +1 -0
- package/dist/targeting-criteria-ESOC7KNX.js +113 -0
- package/dist/targeting-criteria-ESOC7KNX.js.map +1 -0
- package/dist/targets-IPBEB5KU.js +102 -0
- package/dist/targets-IPBEB5KU.js.map +1 -0
- package/dist/templates-IJ7FR3LA.js +178 -0
- package/dist/templates-IJ7FR3LA.js.map +1 -0
- package/dist/testimonials-IXS7CP6P.js +32 -0
- package/dist/testimonials-IXS7CP6P.js.map +1 -0
- package/dist/themes-MXNKJWMW.js +94 -0
- package/dist/themes-MXNKJWMW.js.map +1 -0
- package/dist/top-companies-NO6L2V6M.js +108 -0
- package/dist/top-companies-NO6L2V6M.js.map +1 -0
- package/dist/translate-QCE5ZB7M.js +600 -0
- package/dist/translate-QCE5ZB7M.js.map +1 -0
- package/dist/triggers-KXUDMDSA.js +141 -0
- package/dist/triggers-KXUDMDSA.js.map +1 -0
- package/dist/tweets-ZUKQAAUQ.js +123 -0
- package/dist/tweets-ZUKQAAUQ.js.map +1 -0
- package/dist/unfollow-A4JVCJBF.js +46 -0
- package/dist/unfollow-A4JVCJBF.js.map +1 -0
- package/dist/unlink-E3N36NYQ.js +67 -0
- package/dist/unlink-E3N36NYQ.js.map +1 -0
- package/dist/unstage-TRMHSHED.js +84 -0
- package/dist/unstage-TRMHSHED.js.map +1 -0
- package/dist/unstage-ZRLLCSQF.js +95 -0
- package/dist/unstage-ZRLLCSQF.js.map +1 -0
- package/dist/update-EWGWAXAQ.js +142 -0
- package/dist/update-EWGWAXAQ.js.map +1 -0
- package/dist/update-OKOQE7U2.js +155 -0
- package/dist/update-OKOQE7U2.js.map +1 -0
- package/dist/update-VSFHID2D.js +63 -0
- package/dist/update-VSFHID2D.js.map +1 -0
- package/dist/update-XGCGQDJ4.js +98 -0
- package/dist/update-XGCGQDJ4.js.map +1 -0
- package/dist/upload-BOYMDDEQ.js +126 -0
- package/dist/upload-BOYMDDEQ.js.map +1 -0
- package/dist/upload-XEHWYMJG.js +150 -0
- package/dist/upload-XEHWYMJG.js.map +1 -0
- package/dist/upscale-I5P2OHTN.js +109 -0
- package/dist/upscale-I5P2OHTN.js.map +1 -0
- package/dist/url-options-PCZEQE66.js +130 -0
- package/dist/url-options-PCZEQE66.js.map +1 -0
- package/dist/url-params-DV37GEQF.js +98 -0
- package/dist/url-params-DV37GEQF.js.map +1 -0
- package/dist/use-U4HG2NF3.js +95 -0
- package/dist/use-U4HG2NF3.js.map +1 -0
- package/dist/validate-5AV4FJZ5.js +91 -0
- package/dist/validate-5AV4FJZ5.js.map +1 -0
- package/dist/variant-FOVE6URJ.js +338 -0
- package/dist/variant-FOVE6URJ.js.map +1 -0
- package/dist/videos-IJ67PPJV.js +39 -0
- package/dist/videos-IJ67PPJV.js.map +1 -0
- package/dist/view-HRI3FHCH.js +121 -0
- package/dist/view-HRI3FHCH.js.map +1 -0
- package/dist/viewer-check-JYUE24M6.js +68 -0
- package/dist/viewer-check-JYUE24M6.js.map +1 -0
- package/dist/web-LJ36FRWD.js +140 -0
- package/dist/web-LJ36FRWD.js.map +1 -0
- package/dist/winners-SMMDN6LW.js +113 -0
- package/dist/winners-SMMDN6LW.js.map +1 -0
- package/dist/winning-ads-JIG2MQHJ.js +84 -0
- package/dist/winning-ads-JIG2MQHJ.js.map +1 -0
- package/dist/write-commands-7Z34WG2J.js +206 -0
- package/dist/write-commands-7Z34WG2J.js.map +1 -0
- package/dist/write-commands-BLT2SEC4.js +713 -0
- package/dist/write-commands-BLT2SEC4.js.map +1 -0
- package/dist/write-commands-GOZU6ENR.js +1015 -0
- package/dist/write-commands-GOZU6ENR.js.map +1 -0
- package/dist/write-commands-KA3QXVSF.js +737 -0
- package/dist/write-commands-KA3QXVSF.js.map +1 -0
- package/dist/x-6HBVXIKH.js +47 -0
- package/dist/x-6HBVXIKH.js.map +1 -0
- package/package.json +9 -2
- package/dist/chunk-CHJOTJTZ.js +0 -9989
- package/dist/chunk-CHJOTJTZ.js.map +0 -1
- package/dist/chunk-HJEMOSPH.js +0 -1292
- package/dist/chunk-HJEMOSPH.js.map +0 -1
- package/dist/chunk-MF7YA62W.js.map +0 -1
- package/dist/chunk-VLUGGVJL.js.map +0 -1
- package/dist/chunk-VZEDAFAR.js.map +0 -1
- package/dist/chunk-XHC4LMK4.js.map +0 -1
- package/dist/client-GR6YL3YX.js +0 -17
- package/dist/output-NMQXZF3Z.js +0 -18
- /package/dist/{client-GR6YL3YX.js.map → chunk-YQSBHWOI.js.map} +0 -0
- /package/dist/{env-4P5HOGNA.js.map → client-26SAJ46D.js.map} +0 -0
- /package/dist/{output-NMQXZF3Z.js.map → connect-WYUYS5V4.js.map} +0 -0
- /package/dist/{shared-J7DQZ2ED.js.map → customers-HYE7N2H5.js.map} +0 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import {
|
|
2
|
+
hintLines,
|
|
3
|
+
splitHints
|
|
4
|
+
} from "./chunk-D5FY4FAK.js";
|
|
5
|
+
import {
|
|
6
|
+
isNotConnectedError,
|
|
7
|
+
writeJsonEnvelope
|
|
8
|
+
} from "./chunk-BVM5IRZW.js";
|
|
9
|
+
import {
|
|
10
|
+
ApiError,
|
|
11
|
+
apiPost
|
|
12
|
+
} from "./chunk-HREWXNTO.js";
|
|
13
|
+
import {
|
|
14
|
+
requireChatId,
|
|
15
|
+
resolveChatId
|
|
16
|
+
} from "./chunk-O6QKCJE4.js";
|
|
17
|
+
|
|
18
|
+
// src/commands/ga4/shared.ts
|
|
19
|
+
import { readFileSync } from "fs";
|
|
20
|
+
function failValidation(message) {
|
|
21
|
+
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
function requireTarget(args, entity) {
|
|
25
|
+
const positional = Array.isArray(args._) ? args._[0] : void 0;
|
|
26
|
+
const target = args.id ?? args.target ?? positional;
|
|
27
|
+
if (typeof target !== "string" || target.length === 0) {
|
|
28
|
+
failValidation(`pass the ${entity} id as the positional argument`);
|
|
29
|
+
}
|
|
30
|
+
return target;
|
|
31
|
+
}
|
|
32
|
+
function readJsonSource(args, flag) {
|
|
33
|
+
const inline = args[flag];
|
|
34
|
+
const file = args.file;
|
|
35
|
+
const raw = typeof file === "string" && file.length > 0 ? readFileSync(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
|
|
36
|
+
if (raw === void 0) {
|
|
37
|
+
failValidation(`pass --${flag} with inline JSON or --file with a path to a JSON file`);
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
return JSON.parse(raw);
|
|
41
|
+
} catch {
|
|
42
|
+
return failValidation(`--${flag} is not valid JSON`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
function asObject(value, flag, index) {
|
|
46
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
47
|
+
failValidation(
|
|
48
|
+
index === void 0 ? `--${flag} must be a JSON object` : `--${flag}[${index}] must be a JSON object`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
return value;
|
|
52
|
+
}
|
|
53
|
+
function loadJsonArg(args, flag = "json") {
|
|
54
|
+
return asObject(readJsonSource(args, flag), flag);
|
|
55
|
+
}
|
|
56
|
+
function loadJsonPayloads(args) {
|
|
57
|
+
const parsed = readJsonSource(args, "json");
|
|
58
|
+
if (!Array.isArray(parsed)) {
|
|
59
|
+
return [asObject(parsed, "json")];
|
|
60
|
+
}
|
|
61
|
+
if (parsed.length === 0) {
|
|
62
|
+
failValidation("--json is an empty list \u2014 pass at least one definition");
|
|
63
|
+
}
|
|
64
|
+
return parsed.map((entry, index) => asObject(entry, "json", index));
|
|
65
|
+
}
|
|
66
|
+
var RETRYABLE_CODES = /* @__PURE__ */ new Set(["RATE_LIMITED", "UNAVAILABLE", "INTERNAL_ERROR", "NETWORK_ERROR", "TIMEOUT"]);
|
|
67
|
+
function handleError(err) {
|
|
68
|
+
if (err instanceof ApiError) {
|
|
69
|
+
const readOnly = err.code === "FORBIDDEN" && /read the property but not change it/i.test(err.message);
|
|
70
|
+
writeJsonEnvelope({
|
|
71
|
+
ok: false,
|
|
72
|
+
error: {
|
|
73
|
+
code: err.code,
|
|
74
|
+
message: err.message,
|
|
75
|
+
...readOnly ? {
|
|
76
|
+
fix: {
|
|
77
|
+
action: "reconnect",
|
|
78
|
+
explanation: "The Google Analytics connection is read-only. Ask the user to reconnect Google Analytics \u2014 in the dashboard, Brain \u2192 Integrations \u2192 Platforms \u2192 Google Analytics \u2014 which grants the permission to change the property. Reporting (`baker ga4 query`, `baker ga4 audit`) keeps working meanwhile, so carry on with the rest of the job and tell them what you will set up once they have reconnected. Don't claim anything was configured."
|
|
79
|
+
}
|
|
80
|
+
} : err.code === "UNAUTHORIZED" || err.code === "FORBIDDEN" && isNotConnectedError(err.code, err.message) ? {
|
|
81
|
+
fix: {
|
|
82
|
+
action: "request_connection",
|
|
83
|
+
explanation: 'Google Analytics is not connected for this company yet, or no property has been picked. Don\'t send the user to Settings \u2014 call the `request_connection` tool with { platform: "google-analytics", reason } and they connect and pick their property from inside the chat. If the `request_connection` call fails, say so plainly and give the exact route: dashboard \u2192 Brain \u2192 Integrations \u2192 Platforms \u2192 Google Analytics. Then carry on with the rest of the task.'
|
|
84
|
+
}
|
|
85
|
+
} : {},
|
|
86
|
+
retryable: RETRYABLE_CODES.has(err.code)
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
writeJsonEnvelope({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error", retryable: true } });
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
var STAGE_HINTS = [
|
|
95
|
+
"Staged only \u2014 nothing has changed in Google Analytics yet. These apply when the chat completes, and an applied change takes effect on the property immediately: there is no version to publish afterwards and no undo. Say the changes are ready and take effect when the user completes the chat \u2014 not that they are done already."
|
|
96
|
+
];
|
|
97
|
+
var WARNING_HINT = "Read the warnings above before telling the user this is ready.";
|
|
98
|
+
async function stageOp(op) {
|
|
99
|
+
const chatId = requireChatId();
|
|
100
|
+
try {
|
|
101
|
+
const { data, hints } = splitHints(await apiPost("/api/ga4/draft/stage", { chatId, op }));
|
|
102
|
+
writeJsonEnvelope({
|
|
103
|
+
ok: true,
|
|
104
|
+
data,
|
|
105
|
+
hints: [...hints, ...STAGE_HINTS, ...data.warnings.length > 0 ? [WARNING_HINT] : []]
|
|
106
|
+
});
|
|
107
|
+
} catch (err) {
|
|
108
|
+
handleError(err);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
async function stageOps(ops) {
|
|
112
|
+
const [only] = ops;
|
|
113
|
+
if (ops.length === 1 && only) {
|
|
114
|
+
await stageOp(only);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const chatId = requireChatId();
|
|
118
|
+
try {
|
|
119
|
+
const { data, hints } = splitHints(
|
|
120
|
+
await apiPost("/api/ga4/draft/stage-batch", { chatId, ops })
|
|
121
|
+
);
|
|
122
|
+
writeJsonEnvelope({
|
|
123
|
+
ok: true,
|
|
124
|
+
data,
|
|
125
|
+
hints: [...hints, ...STAGE_HINTS, ...data.ops.some((op) => op.warnings.length > 0) ? [WARNING_HINT] : []]
|
|
126
|
+
});
|
|
127
|
+
} catch (err) {
|
|
128
|
+
handleError(err);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async function draftAction(path, body, chat) {
|
|
132
|
+
const chatId = resolveChatId(chat);
|
|
133
|
+
try {
|
|
134
|
+
const { data, hints } = splitHints(await apiPost(path, { chatId, ...body }));
|
|
135
|
+
writeJsonEnvelope({ ok: true, data, ...hints.length > 0 ? { hints } : {} });
|
|
136
|
+
return data;
|
|
137
|
+
} catch (err) {
|
|
138
|
+
handleError(err);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function renderDraft(response) {
|
|
142
|
+
if (response.count === 0) {
|
|
143
|
+
return "No Google Analytics changes staged on this chat.";
|
|
144
|
+
}
|
|
145
|
+
const lines = [
|
|
146
|
+
response.status === "discarded" ? `${response.count} Google Analytics change(s) discarded with their chat \u2014 none will apply` : `${response.count} staged Google Analytics change(s)`,
|
|
147
|
+
...response.ops.map((op) => {
|
|
148
|
+
const status = op.result ? ` [${op.result.status}]` : "";
|
|
149
|
+
return ` ${op.ref} ${op.summary}${status}`;
|
|
150
|
+
})
|
|
151
|
+
];
|
|
152
|
+
if (response.status === "applied") {
|
|
153
|
+
const failed = response.ops.filter((op) => op.result?.status !== "applied");
|
|
154
|
+
lines.push(
|
|
155
|
+
"",
|
|
156
|
+
failed.length === 0 ? "All applied \u2014 these are in effect on the property now." : `${failed.length} of ${response.count} did not apply. The rest are in effect on the property.`
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
if (response.publishError) {
|
|
160
|
+
lines.push("", response.publishError);
|
|
161
|
+
}
|
|
162
|
+
return lines.join("\n");
|
|
163
|
+
}
|
|
164
|
+
async function draftList(json, chat) {
|
|
165
|
+
const chatId = resolveChatId(chat);
|
|
166
|
+
try {
|
|
167
|
+
const response = await apiPost("/api/ga4/draft", { chatId });
|
|
168
|
+
const { data, hints } = splitHints(response);
|
|
169
|
+
if (json) {
|
|
170
|
+
writeJsonEnvelope({ ok: true, data, ...hints.length > 0 ? { hints } : {} });
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
process.stdout.write(`${renderDraft(data)}${hintLines(response)}
|
|
174
|
+
`);
|
|
175
|
+
} catch (err) {
|
|
176
|
+
handleError(err);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export {
|
|
181
|
+
failValidation,
|
|
182
|
+
requireTarget,
|
|
183
|
+
loadJsonArg,
|
|
184
|
+
loadJsonPayloads,
|
|
185
|
+
handleError,
|
|
186
|
+
stageOp,
|
|
187
|
+
stageOps,
|
|
188
|
+
draftAction,
|
|
189
|
+
draftList
|
|
190
|
+
};
|
|
191
|
+
//# sourceMappingURL=chunk-W4W4ZRBP.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/ga4/shared.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport type { Ga4DraftListResponse, Ga4DraftStageBatchResponse, Ga4DraftStageResponse } from \"@baker/api/ga4\";\nimport { ApiError, apiPost } from \"../../client.ts\";\nimport { requireChatId, resolveChatId } from \"../../env.ts\";\nimport { isNotConnectedError } from \"../../error-handler.ts\";\nimport { hintLines, splitHints } from \"../ads/hints.ts\";\nimport { writeJsonEnvelope } from \"../ads/output.ts\";\n\n/**\n * Shared plumbing for the staged Google Analytics write commands. These NEVER\n * change the property directly: each stages a change onto this chat's draft, the\n * user reviews the whole set in the Analytics tab, and it applies when the chat\n * completes.\n */\n\nexport function failValidation(message: string): never {\n writeJsonEnvelope({ ok: false, error: { code: \"VALIDATION_ERROR\", message } });\n process.exit(1);\n}\n\nexport function requireTarget(args: Record<string, unknown>, entity: string): string {\n const positional = Array.isArray(args._) ? args._[0] : undefined;\n const target = args.id ?? args.target ?? positional;\n if (typeof target !== \"string\" || target.length === 0) {\n failValidation(`pass the ${entity} id as the positional argument`);\n }\n return target;\n}\n\nfunction readJsonSource(args: Record<string, unknown>, flag: \"patch\" | \"json\"): unknown {\n const inline = args[flag];\n const file = args.file;\n const raw =\n typeof file === \"string\" && file.length > 0\n ? readFileSync(file, \"utf8\")\n : typeof inline === \"string\" && inline.length > 0\n ? inline\n : undefined;\n if (raw === undefined) {\n failValidation(`pass --${flag} with inline JSON or --file with a path to a JSON file`);\n }\n try {\n return JSON.parse(raw) as unknown;\n } catch {\n return failValidation(`--${flag} is not valid JSON`);\n }\n}\n\nfunction asObject(value: unknown, flag: string, index?: number): Record<string, unknown> {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) {\n failValidation(\n index === undefined ? `--${flag} must be a JSON object` : `--${flag}[${index}] must be a JSON object`,\n );\n }\n return value as Record<string, unknown>;\n}\n\n/** `--json '<inline>'` or `--file <path>` → a parsed object. */\nexport function loadJsonArg(args: Record<string, unknown>, flag: \"patch\" | \"json\" = \"json\"): Record<string, unknown> {\n return asObject(readJsonSource(args, flag), flag);\n}\n\n/**\n * The same, but a JSON **array** is allowed and means \"stage all of these\n * together\".\n *\n * This is the only way to keep a bulk job cheap. Every stage call reads the\n * whole property first — the property, its data streams, its key events, its\n * custom definitions and its retention window — because that read is what the\n * duplicate and immutability refusals are derived from. One call per definition\n * therefore multiplies a routine \"make these eight parameters reportable\" into\n * roughly fifty Admin API reads against a quota Google counts per project.\n */\nexport function loadJsonPayloads(args: Record<string, unknown>): Record<string, unknown>[] {\n const parsed = readJsonSource(args, \"json\");\n if (!Array.isArray(parsed)) {\n return [asObject(parsed, \"json\")];\n }\n if (parsed.length === 0) {\n failValidation(\"--json is an empty list — pass at least one definition\");\n }\n return parsed.map((entry, index) => asObject(entry, \"json\", index));\n}\n\nconst RETRYABLE_CODES = new Set([\"RATE_LIMITED\", \"UNAVAILABLE\", \"INTERNAL_ERROR\", \"NETWORK_ERROR\", \"TIMEOUT\"]);\n\n/**\n * The one error shape for the whole family.\n *\n * Two different 403s reach here and they need opposite responses, which is why\n * the fix is keyed to the message and not just the status:\n * - \"no Google Analytics connection / no property picked\" → the in-chat connect\n * form, same as every other family.\n * - \"this connection can read but not change the property\" → a RECONNECT, which\n * is what every connection made before Baker could configure GA4 needs. The\n * backend's message already says so, so it is passed through as the fix\n * explanation rather than being replaced with the connect-form wording, which\n * would send the user to set up a connection they already have.\n */\nexport function handleError(err: unknown): never {\n if (err instanceof ApiError) {\n const readOnly = err.code === \"FORBIDDEN\" && /read the property but not change it/i.test(err.message);\n writeJsonEnvelope({\n ok: false,\n error: {\n code: err.code,\n message: err.message,\n ...(readOnly\n ? {\n fix: {\n action: \"reconnect\",\n explanation:\n \"The Google Analytics connection is read-only. Ask the user to reconnect Google Analytics — in the \" +\n \"dashboard, Brain → Integrations → Platforms → Google Analytics — which grants the permission to change \" +\n \"the property. Reporting (`baker ga4 query`, `baker ga4 audit`) keeps working meanwhile, so carry \" +\n \"on with the rest of the job and tell them what you will set up once they have reconnected. Don't \" +\n \"claim anything was configured.\",\n },\n }\n : err.code === \"UNAUTHORIZED\" || (err.code === \"FORBIDDEN\" && isNotConnectedError(err.code, err.message))\n ? {\n fix: {\n action: \"request_connection\",\n explanation:\n \"Google Analytics is not connected for this company yet, or no property has been picked. Don't \" +\n 'send the user to Settings — call the `request_connection` tool with { platform: \"google-analytics\", ' +\n \"reason } and they connect and pick their property from inside the chat. If the \" +\n \"`request_connection` call fails, say so plainly and give the exact route: dashboard → Brain → \" +\n \"Integrations → Platforms → Google Analytics. Then carry on with the rest of the task.\",\n },\n }\n : {}),\n retryable: RETRYABLE_CODES.has(err.code),\n },\n });\n process.exit(1);\n }\n writeJsonEnvelope({ ok: false, error: { code: \"NETWORK_ERROR\", message: \"Unexpected error\", retryable: true } });\n process.exit(1);\n}\n\n/** Nudges returned after a stage so the agent's next step is obvious. */\nconst STAGE_HINTS = [\n \"Staged only — nothing has changed in Google Analytics yet. These apply when the chat completes, and an applied \" +\n \"change takes effect on the property immediately: there is no version to publish afterwards and no undo. Say \" +\n \"the changes are ready and take effect when the user completes the chat — not that they are done already.\",\n];\n\nconst WARNING_HINT = \"Read the warnings above before telling the user this is ready.\";\n\nexport async function stageOp(op: Record<string, unknown>): Promise<void> {\n const chatId = requireChatId();\n try {\n const { data, hints } = splitHints(await apiPost<Ga4DraftStageResponse>(\"/api/ga4/draft/stage\", { chatId, op }));\n writeJsonEnvelope({\n ok: true,\n data,\n hints: [...hints, ...STAGE_HINTS, ...(data.warnings.length > 0 ? [WARNING_HINT] : [])],\n });\n } catch (err) {\n handleError(err);\n }\n}\n\n/**\n * Stage several changes as ONE request against ONE read of the property.\n *\n * All-or-nothing: if any one of them is refused, none of them stage — which is\n * the honest outcome, since the refusals are things like \"two of these claim the\n * same parameter name\" that only mean anything about the set as a whole. A\n * single op falls through to the plain path so its envelope is unchanged.\n */\nexport async function stageOps(ops: Record<string, unknown>[]): Promise<void> {\n const [only] = ops;\n if (ops.length === 1 && only) {\n await stageOp(only);\n return;\n }\n const chatId = requireChatId();\n try {\n const { data, hints } = splitHints(\n await apiPost<Ga4DraftStageBatchResponse>(\"/api/ga4/draft/stage-batch\", { chatId, ops }),\n );\n writeJsonEnvelope({\n ok: true,\n data,\n hints: [...hints, ...STAGE_HINTS, ...(data.ops.some((op) => op.warnings.length > 0) ? [WARNING_HINT] : [])],\n });\n } catch (err) {\n handleError(err);\n }\n}\n\nexport async function draftAction(\n path: string,\n body: Record<string, unknown>,\n chat?: unknown,\n): Promise<Record<string, unknown>> {\n const chatId = resolveChatId(chat);\n try {\n const { data, hints } = splitHints(await apiPost<Record<string, unknown>>(path, { chatId, ...body }));\n writeJsonEnvelope({ ok: true, data, ...(hints.length > 0 ? { hints } : {}) });\n return data;\n } catch (err) {\n handleError(err);\n }\n}\n\n/** A compact, readable view of everything staged on this chat. */\nexport function renderDraft(response: Ga4DraftListResponse): string {\n if (response.count === 0) {\n return \"No Google Analytics changes staged on this chat.\";\n }\n const lines = [\n response.status === \"discarded\"\n ? `${response.count} Google Analytics change(s) discarded with their chat — none will apply`\n : `${response.count} staged Google Analytics change(s)`,\n ...response.ops.map((op) => {\n const status = op.result ? ` [${op.result.status}]` : \"\";\n return ` ${op.ref} ${op.summary}${status}`;\n }),\n ];\n if (response.status === \"applied\") {\n const failed = response.ops.filter((op) => op.result?.status !== \"applied\");\n lines.push(\n \"\",\n failed.length === 0\n ? \"All applied — these are in effect on the property now.\"\n : `${failed.length} of ${response.count} did not apply. The rest are in effect on the property.`,\n );\n }\n if (response.publishError) {\n lines.push(\"\", response.publishError);\n }\n return lines.join(\"\\n\");\n}\n\nexport async function draftList(json: boolean, chat?: unknown): Promise<void> {\n const chatId = resolveChatId(chat);\n try {\n const response = await apiPost<Ga4DraftListResponse>(\"/api/ga4/draft\", { chatId });\n const { data, hints } = splitHints(response);\n if (json) {\n writeJsonEnvelope({ ok: true, data, ...(hints.length > 0 ? { hints } : {}) });\n return;\n }\n process.stdout.write(`${renderDraft(data)}${hintLines(response)}\\n`);\n } catch (err) {\n handleError(err);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA,SAAS,oBAAoB;AAetB,SAAS,eAAe,SAAwB;AACrD,oBAAkB,EAAE,IAAI,OAAO,OAAO,EAAE,MAAM,oBAAoB,QAAQ,EAAE,CAAC;AAC7E,UAAQ,KAAK,CAAC;AAChB;AAEO,SAAS,cAAc,MAA+B,QAAwB;AACnF,QAAM,aAAa,MAAM,QAAQ,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC,IAAI;AACvD,QAAM,SAAS,KAAK,MAAM,KAAK,UAAU;AACzC,MAAI,OAAO,WAAW,YAAY,OAAO,WAAW,GAAG;AACrD,mBAAe,YAAY,MAAM,gCAAgC;AAAA,EACnE;AACA,SAAO;AACT;AAEA,SAAS,eAAe,MAA+B,MAAiC;AACtF,QAAM,SAAS,KAAK,IAAI;AACxB,QAAM,OAAO,KAAK;AAClB,QAAM,MACJ,OAAO,SAAS,YAAY,KAAK,SAAS,IACtC,aAAa,MAAM,MAAM,IACzB,OAAO,WAAW,YAAY,OAAO,SAAS,IAC5C,SACA;AACR,MAAI,QAAQ,QAAW;AACrB,mBAAe,UAAU,IAAI,wDAAwD;AAAA,EACvF;AACA,MAAI;AACF,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,QAAQ;AACN,WAAO,eAAe,KAAK,IAAI,oBAAoB;AAAA,EACrD;AACF;AAEA,SAAS,SAAS,OAAgB,MAAc,OAAyC;AACvF,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D;AAAA,MACE,UAAU,SAAY,KAAK,IAAI,2BAA2B,KAAK,IAAI,IAAI,KAAK;AAAA,IAC9E;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,YAAY,MAA+B,OAAyB,QAAiC;AACnH,SAAO,SAAS,eAAe,MAAM,IAAI,GAAG,IAAI;AAClD;AAaO,SAAS,iBAAiB,MAA0D;AACzF,QAAM,SAAS,eAAe,MAAM,MAAM;AAC1C,MAAI,CAAC,MAAM,QAAQ,MAAM,GAAG;AAC1B,WAAO,CAAC,SAAS,QAAQ,MAAM,CAAC;AAAA,EAClC;AACA,MAAI,OAAO,WAAW,GAAG;AACvB,mBAAe,6DAAwD;AAAA,EACzE;AACA,SAAO,OAAO,IAAI,CAAC,OAAO,UAAU,SAAS,OAAO,QAAQ,KAAK,CAAC;AACpE;AAEA,IAAM,kBAAkB,oBAAI,IAAI,CAAC,gBAAgB,eAAe,kBAAkB,iBAAiB,SAAS,CAAC;AAetG,SAAS,YAAY,KAAqB;AAC/C,MAAI,eAAe,UAAU;AAC3B,UAAM,WAAW,IAAI,SAAS,eAAe,uCAAuC,KAAK,IAAI,OAAO;AACpG,sBAAkB;AAAA,MAChB,IAAI;AAAA,MACJ,OAAO;AAAA,QACL,MAAM,IAAI;AAAA,QACV,SAAS,IAAI;AAAA,QACb,GAAI,WACA;AAAA,UACE,KAAK;AAAA,YACH,QAAQ;AAAA,YACR,aACE;AAAA,UAKJ;AAAA,QACF,IACA,IAAI,SAAS,kBAAmB,IAAI,SAAS,eAAe,oBAAoB,IAAI,MAAM,IAAI,OAAO,IACnG;AAAA,UACE,KAAK;AAAA,YACH,QAAQ;AAAA,YACR,aACE;AAAA,UAKJ;AAAA,QACF,IACA,CAAC;AAAA,QACP,WAAW,gBAAgB,IAAI,IAAI,IAAI;AAAA,MACzC;AAAA,IACF,CAAC;AACD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,oBAAkB,EAAE,IAAI,OAAO,OAAO,EAAE,MAAM,iBAAiB,SAAS,oBAAoB,WAAW,KAAK,EAAE,CAAC;AAC/G,UAAQ,KAAK,CAAC;AAChB;AAGA,IAAM,cAAc;AAAA,EAClB;AAGF;AAEA,IAAM,eAAe;AAErB,eAAsB,QAAQ,IAA4C;AACxE,QAAM,SAAS,cAAc;AAC7B,MAAI;AACF,UAAM,EAAE,MAAM,MAAM,IAAI,WAAW,MAAM,QAA+B,wBAAwB,EAAE,QAAQ,GAAG,CAAC,CAAC;AAC/G,sBAAkB;AAAA,MAChB,IAAI;AAAA,MACJ;AAAA,MACA,OAAO,CAAC,GAAG,OAAO,GAAG,aAAa,GAAI,KAAK,SAAS,SAAS,IAAI,CAAC,YAAY,IAAI,CAAC,CAAE;AAAA,IACvF,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,gBAAY,GAAG;AAAA,EACjB;AACF;AAUA,eAAsB,SAAS,KAA+C;AAC5E,QAAM,CAAC,IAAI,IAAI;AACf,MAAI,IAAI,WAAW,KAAK,MAAM;AAC5B,UAAM,QAAQ,IAAI;AAClB;AAAA,EACF;AACA,QAAM,SAAS,cAAc;AAC7B,MAAI;AACF,UAAM,EAAE,MAAM,MAAM,IAAI;AAAA,MACtB,MAAM,QAAoC,8BAA8B,EAAE,QAAQ,IAAI,CAAC;AAAA,IACzF;AACA,sBAAkB;AAAA,MAChB,IAAI;AAAA,MACJ;AAAA,MACA,OAAO,CAAC,GAAG,OAAO,GAAG,aAAa,GAAI,KAAK,IAAI,KAAK,CAAC,OAAO,GAAG,SAAS,SAAS,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,CAAE;AAAA,IAC5G,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,gBAAY,GAAG;AAAA,EACjB;AACF;AAEA,eAAsB,YACpB,MACA,MACA,MACkC;AAClC,QAAM,SAAS,cAAc,IAAI;AACjC,MAAI;AACF,UAAM,EAAE,MAAM,MAAM,IAAI,WAAW,MAAM,QAAiC,MAAM,EAAE,QAAQ,GAAG,KAAK,CAAC,CAAC;AACpG,sBAAkB,EAAE,IAAI,MAAM,MAAM,GAAI,MAAM,SAAS,IAAI,EAAE,MAAM,IAAI,CAAC,EAAG,CAAC;AAC5E,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,gBAAY,GAAG;AAAA,EACjB;AACF;AAGO,SAAS,YAAY,UAAwC;AAClE,MAAI,SAAS,UAAU,GAAG;AACxB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ;AAAA,IACZ,SAAS,WAAW,cAChB,GAAG,SAAS,KAAK,iFACjB,GAAG,SAAS,KAAK;AAAA,IACrB,GAAG,SAAS,IAAI,IAAI,CAAC,OAAO;AAC1B,YAAM,SAAS,GAAG,SAAS,KAAK,GAAG,OAAO,MAAM,MAAM;AACtD,aAAO,KAAK,GAAG,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM;AAAA,IAC5C,CAAC;AAAA,EACH;AACA,MAAI,SAAS,WAAW,WAAW;AACjC,UAAM,SAAS,SAAS,IAAI,OAAO,CAAC,OAAO,GAAG,QAAQ,WAAW,SAAS;AAC1E,UAAM;AAAA,MACJ;AAAA,MACA,OAAO,WAAW,IACd,gEACA,GAAG,OAAO,MAAM,OAAO,SAAS,KAAK;AAAA,IAC3C;AAAA,EACF;AACA,MAAI,SAAS,cAAc;AACzB,UAAM,KAAK,IAAI,SAAS,YAAY;AAAA,EACtC;AACA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,eAAsB,UAAU,MAAe,MAA+B;AAC5E,QAAM,SAAS,cAAc,IAAI;AACjC,MAAI;AACF,UAAM,WAAW,MAAM,QAA8B,kBAAkB,EAAE,OAAO,CAAC;AACjF,UAAM,EAAE,MAAM,MAAM,IAAI,WAAW,QAAQ;AAC3C,QAAI,MAAM;AACR,wBAAkB,EAAE,IAAI,MAAM,MAAM,GAAI,MAAM,SAAS,IAAI,EAAE,MAAM,IAAI,CAAC,EAAG,CAAC;AAC5E;AAAA,IACF;AACA,YAAQ,OAAO,MAAM,GAAG,YAAY,IAAI,CAAC,GAAG,UAAU,QAAQ,CAAC;AAAA,CAAI;AAAA,EACrE,SAAS,KAAK;AACZ,gBAAY,GAAG;AAAA,EACjB;AACF;","names":[]}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import {
|
|
2
|
+
NUMERIC_ID_REGEX
|
|
3
|
+
} from "./chunk-JAYT43KX.js";
|
|
4
|
+
|
|
5
|
+
// ../api/src/ads-google/change-history.ts
|
|
6
|
+
var CHANGE_SCOPES = ["detail", "summary"];
|
|
7
|
+
var CHANGE_SCOPE_MAX_DAYS = {
|
|
8
|
+
detail: 30,
|
|
9
|
+
summary: 90
|
|
10
|
+
};
|
|
11
|
+
var DEFAULT_CHANGE_DAYS = 7;
|
|
12
|
+
var MAX_CHANGE_DAYS = CHANGE_SCOPE_MAX_DAYS.summary;
|
|
13
|
+
function isChangeLookbackWithinReach(days, scope) {
|
|
14
|
+
return days <= CHANGE_SCOPE_MAX_DAYS[scope];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ../api/src/ads-google/keyword-planning.ts
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
var ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
|
20
|
+
var micros = z.number().int().positive();
|
|
21
|
+
var FORECAST_MATCH_TYPES = ["EXACT", "PHRASE", "BROAD"];
|
|
22
|
+
var googleForecastBiddingSchema = z.discriminatedUnion("strategy", [
|
|
23
|
+
z.object({ strategy: z.literal("MANUAL_CPC"), maxCpcBidMicros: micros, dailyBudgetMicros: micros.optional() }),
|
|
24
|
+
z.object({
|
|
25
|
+
strategy: z.literal("MAXIMIZE_CLICKS"),
|
|
26
|
+
dailyTargetSpendMicros: micros,
|
|
27
|
+
maxCpcBidCeilingMicros: micros.optional()
|
|
28
|
+
}),
|
|
29
|
+
z.object({ strategy: z.literal("MAXIMIZE_CONVERSIONS"), dailyTargetSpendMicros: micros })
|
|
30
|
+
]);
|
|
31
|
+
var googleKeywordForecastRequestSchema = z.object({
|
|
32
|
+
customerId: z.string().regex(NUMERIC_ID_REGEX, "customerId must be the bare numeric customer id"),
|
|
33
|
+
managerId: z.string().optional(),
|
|
34
|
+
/** One forecast ad group per entry; most forecasts are a single group. */
|
|
35
|
+
adGroups: z.array(
|
|
36
|
+
z.object({
|
|
37
|
+
keywords: z.array(z.object({ text: z.string().trim().min(1).max(80), matchType: z.enum(FORECAST_MATCH_TYPES) })).min(1)
|
|
38
|
+
})
|
|
39
|
+
).min(1),
|
|
40
|
+
locationIds: z.array(z.string().regex(NUMERIC_ID_REGEX)).optional(),
|
|
41
|
+
languageId: z.string().regex(NUMERIC_ID_REGEX).optional(),
|
|
42
|
+
bidding: googleForecastBiddingSchema,
|
|
43
|
+
/** Must start in the future and end within a year. Without them Baker forecasts the 30 days from tomorrow. */
|
|
44
|
+
startDate: z.string().regex(ISO_DATE).optional(),
|
|
45
|
+
endDate: z.string().regex(ISO_DATE).optional(),
|
|
46
|
+
currencyCode: z.string().length(3).optional()
|
|
47
|
+
}).refine((body) => body.startDate === void 0 === (body.endDate === void 0), {
|
|
48
|
+
message: "Give both --start and --end, or neither (the forecast then covers the 30 days from tomorrow)",
|
|
49
|
+
path: ["endDate"]
|
|
50
|
+
});
|
|
51
|
+
var KEYWORD_FORECAST_SOURCE = "keyword_planner_forecast";
|
|
52
|
+
var googleKeywordForecastResponseSchema = z.object({
|
|
53
|
+
source: z.literal(KEYWORD_FORECAST_SOURCE),
|
|
54
|
+
period: z.object({ startDate: z.string(), endDate: z.string() }),
|
|
55
|
+
forecast_clicks: z.number().nullable(),
|
|
56
|
+
forecast_cost_micros: z.number().nullable(),
|
|
57
|
+
forecast_conversions: z.number().nullable(),
|
|
58
|
+
forecast_average_cpc_micros: z.number().nullable(),
|
|
59
|
+
forecast_average_cpa_micros: z.number().nullable()
|
|
60
|
+
});
|
|
61
|
+
var googleAdGroupThemesRequestSchema = z.object({
|
|
62
|
+
customerId: z.string().regex(NUMERIC_ID_REGEX, "customerId must be the bare numeric customer id"),
|
|
63
|
+
managerId: z.string().optional(),
|
|
64
|
+
keywords: z.array(z.string().trim().min(1)).min(1),
|
|
65
|
+
/** Existing ad groups to sort the keywords into: numeric ids or `customers/{cid}/adGroups/{id}`. */
|
|
66
|
+
adGroups: z.array(z.string().min(1)).min(1)
|
|
67
|
+
});
|
|
68
|
+
var googleAdGroupThemesResponseSchema = z.object({
|
|
69
|
+
suggestions: z.array(
|
|
70
|
+
z.object({
|
|
71
|
+
keyword: z.string(),
|
|
72
|
+
suggested_keyword: z.string(),
|
|
73
|
+
match_type: z.string(),
|
|
74
|
+
ad_group: z.string(),
|
|
75
|
+
campaign: z.string()
|
|
76
|
+
})
|
|
77
|
+
),
|
|
78
|
+
unusable_ad_groups: z.array(z.object({ ad_group: z.string(), campaign: z.string() }))
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// ../api/src/ads-google/url-options.ts
|
|
82
|
+
import { z as z2 } from "zod";
|
|
83
|
+
var URL_OPTION_LEVELS = ["account", "campaign", "ad_group", "ad"];
|
|
84
|
+
var googleUrlOptionValueSchema = z2.discriminatedUnion("state", [
|
|
85
|
+
z2.object({ state: z2.literal("set"), value: z2.string() }),
|
|
86
|
+
z2.object({ state: z2.literal("not_set") }),
|
|
87
|
+
z2.object({ state: z2.literal("not_read"), reason: z2.string() })
|
|
88
|
+
]);
|
|
89
|
+
var googleUrlOptionsRequestSchema = z2.object({
|
|
90
|
+
customerId: z2.string().regex(NUMERIC_ID_REGEX, "customerId must be the bare numeric customer id"),
|
|
91
|
+
managerId: z2.string().optional(),
|
|
92
|
+
/** Compact by default: only campaigns that actually override the account. `full` lists every campaign. */
|
|
93
|
+
full: z2.boolean().optional(),
|
|
94
|
+
skipCache: z2.boolean().optional()
|
|
95
|
+
});
|
|
96
|
+
var googleUrlOptionsCampaignSchema = z2.object({
|
|
97
|
+
id: z2.string(),
|
|
98
|
+
name: z2.string(),
|
|
99
|
+
status: z2.string(),
|
|
100
|
+
final_url_suffix: googleUrlOptionValueSchema,
|
|
101
|
+
tracking_url_template: googleUrlOptionValueSchema
|
|
102
|
+
});
|
|
103
|
+
var googleUrlOptionsAdGroupSchema = z2.object({
|
|
104
|
+
id: z2.string(),
|
|
105
|
+
name: z2.string(),
|
|
106
|
+
status: z2.string(),
|
|
107
|
+
campaign_id: z2.string(),
|
|
108
|
+
final_url_suffix: googleUrlOptionValueSchema,
|
|
109
|
+
tracking_url_template: googleUrlOptionValueSchema
|
|
110
|
+
});
|
|
111
|
+
var googleUrlOptionsAdSchema = z2.object({
|
|
112
|
+
id: z2.string(),
|
|
113
|
+
status: z2.string(),
|
|
114
|
+
ad_group_id: z2.string(),
|
|
115
|
+
campaign_id: z2.string(),
|
|
116
|
+
final_url_suffix: googleUrlOptionValueSchema,
|
|
117
|
+
tracking_url_template: googleUrlOptionValueSchema
|
|
118
|
+
});
|
|
119
|
+
var googleUrlOptionsResponseSchema = z2.object({
|
|
120
|
+
customer_id: z2.string(),
|
|
121
|
+
account: z2.object({
|
|
122
|
+
level: z2.literal("account"),
|
|
123
|
+
read: z2.boolean(),
|
|
124
|
+
final_url_suffix: googleUrlOptionValueSchema,
|
|
125
|
+
tracking_url_template: googleUrlOptionValueSchema
|
|
126
|
+
}),
|
|
127
|
+
campaigns: z2.object({
|
|
128
|
+
level: z2.literal("campaign"),
|
|
129
|
+
read: z2.boolean(),
|
|
130
|
+
/** Campaigns actually observed. 0 with `read: true` means the account has no non-removed campaigns. */
|
|
131
|
+
campaigns_read: z2.number().int().nonnegative(),
|
|
132
|
+
/** Campaigns observed to carry no override of their own — an explicit finding, not an omission. */
|
|
133
|
+
campaigns_without_override: z2.number().int().nonnegative(),
|
|
134
|
+
overrides: z2.array(googleUrlOptionsCampaignSchema),
|
|
135
|
+
/** Compact mode only: campaigns read but not listed because they carry no override. */
|
|
136
|
+
omitted: z2.number().int().nonnegative()
|
|
137
|
+
}),
|
|
138
|
+
/**
|
|
139
|
+
* Ad groups and ads that carry an override of their own — read by asking Google only for the
|
|
140
|
+
* entities whose suffix or template IS NOT NULL, so an account of thousands of ads costs one page.
|
|
141
|
+
* `read: true` with no overrides is a finding: nothing at this level overrides the levels above.
|
|
142
|
+
* `truncated` means more overriding entities exist than one page listed.
|
|
143
|
+
*/
|
|
144
|
+
ad_groups: z2.object({
|
|
145
|
+
level: z2.literal("ad_group"),
|
|
146
|
+
read: z2.boolean(),
|
|
147
|
+
overrides: z2.array(googleUrlOptionsAdGroupSchema),
|
|
148
|
+
truncated: z2.boolean()
|
|
149
|
+
}),
|
|
150
|
+
ads: z2.object({
|
|
151
|
+
level: z2.literal("ad"),
|
|
152
|
+
read: z2.boolean(),
|
|
153
|
+
overrides: z2.array(googleUrlOptionsAdSchema),
|
|
154
|
+
truncated: z2.boolean()
|
|
155
|
+
}),
|
|
156
|
+
/** Levels this command could not read. Nothing here may be reported as "not configured". */
|
|
157
|
+
levels_not_read: z2.array(z2.object({ level: z2.enum(URL_OPTION_LEVELS), reason: z2.string() }))
|
|
158
|
+
});
|
|
159
|
+
var ACCOUNT_URL_OPTIONS_LOCATION = "Google Ads UI \u2192 Admin \u2192 Account settings \u2192 Tracking (account-level tracking template and final URL suffix)";
|
|
160
|
+
var ACCOUNT_URL_OPTIONS_STAGE_COMMAND = 'baker ads google account update --customer-id <id> --final-url-suffix "utm_agency=baker"';
|
|
161
|
+
function isSet(value) {
|
|
162
|
+
return value.state === "set";
|
|
163
|
+
}
|
|
164
|
+
function entityOverrideHints(label, plural, field, level) {
|
|
165
|
+
if (!level.read) return [];
|
|
166
|
+
const hints = [];
|
|
167
|
+
const overriding = level.overrides.filter((entity) => isSet(entity.final_url_suffix));
|
|
168
|
+
if (overriding.length > 0) {
|
|
169
|
+
const named = overriding.slice(0, 5).map((entity) => entity.name || entity.id).join(", ");
|
|
170
|
+
hints.push(
|
|
171
|
+
`${overriding.length} ${label}(s) set their own final URL suffix (${named}${overriding.length > 5 ? ", \u2026" : ""}). It REPLACES the campaign and account suffix for every click through it, so an account-wide parameter must be added to theirs too.`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
if (level.truncated) {
|
|
175
|
+
hints.push(
|
|
176
|
+
`More ${plural} override the URL options than one page lists \u2014 read them all with \`baker ads google query\` on ${field}.final_url_suffix IS NOT NULL --all before saying which ones do.`
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
return hints;
|
|
180
|
+
}
|
|
181
|
+
function urlOptionsHints(report) {
|
|
182
|
+
const hints = [];
|
|
183
|
+
const { account, campaigns } = report;
|
|
184
|
+
if (!account.read) {
|
|
185
|
+
hints.push(
|
|
186
|
+
"The account level did NOT read \u2014 its URL options are unknown, not empty. Re-run before telling the user anything about account-wide tagging."
|
|
187
|
+
);
|
|
188
|
+
} else if (account.final_url_suffix.state === "not_set") {
|
|
189
|
+
hints.push(
|
|
190
|
+
`No account-level final URL suffix is set. An account-wide parameter (agency/partner tagging such as utm_agency=\u2026) belongs at the account level so it reaches every ad \u2014 stage it with \`${ACCOUNT_URL_OPTIONS_STAGE_COMMAND}\` (applies at Publish; the user sees it under ${ACCOUNT_URL_OPTIONS_LOCATION}).`
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
if (!campaigns.read) {
|
|
194
|
+
hints.push(
|
|
195
|
+
"Campaign-level URL options did NOT read \u2014 do not report that no campaign overrides exist. Re-run before concluding."
|
|
196
|
+
);
|
|
197
|
+
} else {
|
|
198
|
+
const overriding = campaigns.overrides.filter((c) => isSet(c.final_url_suffix));
|
|
199
|
+
if (overriding.length > 0) {
|
|
200
|
+
const named = overriding.slice(0, 5).map((c) => c.name || c.id).join(", ");
|
|
201
|
+
hints.push(
|
|
202
|
+
`A campaign's final URL suffix REPLACES the account-level one for that campaign \u2014 it does not merge. ${overriding.length} campaign(s) set their own (${named}${overriding.length > 5 ? ", \u2026" : ""}) and will not pick up an account-wide parameter until their own suffix carries it too. Every other campaign read here inherits the account level normally.`
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
hints.push(...entityOverrideHints("ad group", "ad groups", "ad_group", report.ad_groups));
|
|
207
|
+
hints.push(...entityOverrideHints("ad", "ads", "ad_group_ad.ad", report.ads));
|
|
208
|
+
const overridingLevelsNotRead = report.levels_not_read.filter((level) => level.level !== "account");
|
|
209
|
+
if (overridingLevelsNotRead.length > 0) {
|
|
210
|
+
hints.push(
|
|
211
|
+
`Not read at this level: ${overridingLevelsNotRead.map((l) => l.level).join(", ")}. A suffix set there still wins over the levels above it.`
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
if (campaigns.omitted > 0) {
|
|
215
|
+
hints.push(`${campaigns.omitted} campaign(s) read with no override of their own are not listed \u2014 pass --full.`);
|
|
216
|
+
}
|
|
217
|
+
return hints;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export {
|
|
221
|
+
CHANGE_SCOPES,
|
|
222
|
+
CHANGE_SCOPE_MAX_DAYS,
|
|
223
|
+
DEFAULT_CHANGE_DAYS,
|
|
224
|
+
isChangeLookbackWithinReach,
|
|
225
|
+
googleKeywordForecastRequestSchema,
|
|
226
|
+
urlOptionsHints
|
|
227
|
+
};
|
|
228
|
+
//# sourceMappingURL=chunk-WIRBRCTJ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../api/src/ads-google/change-history.ts","../../api/src/ads-google/keyword-planning.ts","../../api/src/ads-google/url-options.ts"],"sourcesContent":["/**\n * How far back Google's account history actually reaches, shared by the CLI and the\n * backend so the two layers cannot disagree about the limit.\n *\n * `change_event` carries field-level detail — old → new value and the user who made the\n * change — for the last 30 days. `change_status` reaches 90 days but only reports which\n * resources were added, changed or removed. Past 90 days there is no API at all; the\n * change has to be inferred from performance, or read from the Google Ads web UI.\n */\n\nexport const CHANGE_SCOPES = [\"detail\", \"summary\"] as const;\n\nexport type ChangeScope = (typeof CHANGE_SCOPES)[number];\n\nexport const CHANGE_SCOPE_MAX_DAYS: Record<ChangeScope, number> = {\n detail: 30,\n summary: 90,\n};\n\nexport const DEFAULT_CHANGE_DAYS = 7;\n\n/** Longest lookback any history resource can serve. */\nexport const MAX_CHANGE_DAYS = CHANGE_SCOPE_MAX_DAYS.summary;\n\nexport function isChangeLookbackWithinReach(days: number, scope: ChangeScope): boolean {\n return days <= CHANGE_SCOPE_MAX_DAYS[scope];\n}\n\n/** The cheapest scope that can serve `days`, or null when nothing reaches that far. */\nexport function changeScopeForDays(days: number): ChangeScope | null {\n return CHANGE_SCOPES.find((scope) => isChangeLookbackWithinReach(days, scope)) ?? null;\n}\n\n/**\n * Why a lookback was refused, and what to do instead. Callers that bypass the CLI get\n * this straight from the API, so it has to carry the way out of the window rather than\n * just the limit that was breached.\n */\nexport function changeLookbackMessage(days: number, scope: ChangeScope): string {\n const reachable = changeScopeForDays(days);\n if (reachable && reachable !== scope) {\n return `Google keeps field-level change detail for ${CHANGE_SCOPE_MAX_DAYS.detail} days only, and ${days} days is outside that window. Use scope \"${reachable}\" to reach back ${CHANGE_SCOPE_MAX_DAYS[reachable]} days — it reports which resources changed, without the old and new values.`;\n }\n return `Google's account history reaches back ${MAX_CHANGE_DAYS} days at most, and ${days} days is outside that window. Infer the change from monthly spend per campaign instead; anything older with attribution exists only in the Google Ads web interface, which has no API.`;\n}\n","/**\n * Keyword Planner reads beyond ideas and historical volume: a forecast for a set of keywords\n * (`GenerateKeywordForecastMetrics`, v25 shape) and ad-group themes (`GenerateAdGroupThemes`,\n * which existing ad group each keyword belongs in).\n *\n * The v25 forecast takes a campaign to forecast — languages, locations, ONE bidding strategy and\n * ad groups of keywords — and answers with one set of campaign-level estimates. It has no network\n * choice, no per-keyword bids and no negatives; those were the pre-v18 keyword-plan shape.\n */\nimport { z } from \"zod\";\nimport { NUMERIC_ID_REGEX } from \"./limits\";\n\nconst ISO_DATE = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst micros = z.number().int().positive();\n\nexport const FORECAST_MATCH_TYPES = [\"EXACT\", \"PHRASE\", \"BROAD\"] as const;\n\nexport const googleForecastBiddingSchema = z.discriminatedUnion(\"strategy\", [\n z.object({ strategy: z.literal(\"MANUAL_CPC\"), maxCpcBidMicros: micros, dailyBudgetMicros: micros.optional() }),\n z.object({\n strategy: z.literal(\"MAXIMIZE_CLICKS\"),\n dailyTargetSpendMicros: micros,\n maxCpcBidCeilingMicros: micros.optional(),\n }),\n z.object({ strategy: z.literal(\"MAXIMIZE_CONVERSIONS\"), dailyTargetSpendMicros: micros }),\n]);\nexport type GoogleForecastBidding = z.infer<typeof googleForecastBiddingSchema>;\n\nexport const googleKeywordForecastRequestSchema = z\n .object({\n customerId: z.string().regex(NUMERIC_ID_REGEX, \"customerId must be the bare numeric customer id\"),\n managerId: z.string().optional(),\n /** One forecast ad group per entry; most forecasts are a single group. */\n adGroups: z\n .array(\n z.object({\n keywords: z\n .array(z.object({ text: z.string().trim().min(1).max(80), matchType: z.enum(FORECAST_MATCH_TYPES) }))\n .min(1),\n }),\n )\n .min(1),\n locationIds: z.array(z.string().regex(NUMERIC_ID_REGEX)).optional(),\n languageId: z.string().regex(NUMERIC_ID_REGEX).optional(),\n bidding: googleForecastBiddingSchema,\n /** Must start in the future and end within a year. Without them Baker forecasts the 30 days from tomorrow. */\n startDate: z.string().regex(ISO_DATE).optional(),\n endDate: z.string().regex(ISO_DATE).optional(),\n currencyCode: z.string().length(3).optional(),\n })\n .refine((body) => (body.startDate === undefined) === (body.endDate === undefined), {\n message: \"Give both --start and --end, or neither (the forecast then covers the 30 days from tomorrow)\",\n path: [\"endDate\"],\n });\nexport type GoogleKeywordForecastRequest = z.infer<typeof googleKeywordForecastRequestSchema>;\n\nexport const KEYWORD_FORECAST_SOURCE = \"keyword_planner_forecast\" as const;\n\n/** Every number is Google's prediction for the whole forecast period — never an account result. */\nexport const googleKeywordForecastResponseSchema = z.object({\n source: z.literal(KEYWORD_FORECAST_SOURCE),\n period: z.object({ startDate: z.string(), endDate: z.string() }),\n forecast_clicks: z.number().nullable(),\n forecast_cost_micros: z.number().nullable(),\n forecast_conversions: z.number().nullable(),\n forecast_average_cpc_micros: z.number().nullable(),\n forecast_average_cpa_micros: z.number().nullable(),\n});\nexport type GoogleKeywordForecastResponse = z.infer<typeof googleKeywordForecastResponseSchema>;\n\nexport const googleAdGroupThemesRequestSchema = z.object({\n customerId: z.string().regex(NUMERIC_ID_REGEX, \"customerId must be the bare numeric customer id\"),\n managerId: z.string().optional(),\n keywords: z.array(z.string().trim().min(1)).min(1),\n /** Existing ad groups to sort the keywords into: numeric ids or `customers/{cid}/adGroups/{id}`. */\n adGroups: z.array(z.string().min(1)).min(1),\n});\nexport type GoogleAdGroupThemesRequest = z.infer<typeof googleAdGroupThemesRequestSchema>;\n\nexport const googleAdGroupThemesResponseSchema = z.object({\n suggestions: z.array(\n z.object({\n keyword: z.string(),\n suggested_keyword: z.string(),\n match_type: z.string(),\n ad_group: z.string(),\n campaign: z.string(),\n }),\n ),\n unusable_ad_groups: z.array(z.object({ ad_group: z.string(), campaign: z.string() })),\n});\nexport type GoogleAdGroupThemesResponse = z.infer<typeof googleAdGroupThemesResponseSchema>;\n","/**\n * `ads.google.url-options` — the URL/tracking options in force on an account.\n *\n * Google returns a field ONLY when it holds a value: an unset `final_url_suffix`\n * is not `\"\"`, it is a key that never appears in the row. Reported naively, that\n * is indistinguishable from a read that never happened — and a false \"no suffix\n * is configured\" has already been written into a client's knowledge base from\n * exactly that ambiguity.\n *\n * So every value here is a tagged union, never a bare string:\n *\n * - `{ state: \"set\", value }` — observed, holds this value\n * - `{ state: \"not_set\" }` — observed, Google carries no value at this level\n * - `{ state: \"not_read\", reason }` — never observed; says nothing about the account\n *\n * and every level Baker did NOT read is listed explicitly in `levels_not_read`\n * rather than silently omitted. Absence is only a finding when it is `not_set`.\n */\nimport { z } from \"zod\";\nimport { NUMERIC_ID_REGEX } from \"./limits\";\n\n/** Google resolves URL options most-specific-first; these are the levels that can carry one. */\nexport const URL_OPTION_LEVELS = [\"account\", \"campaign\", \"ad_group\", \"ad\"] as const;\nexport type GoogleUrlOptionLevel = (typeof URL_OPTION_LEVELS)[number];\n\nexport const googleUrlOptionValueSchema = z.discriminatedUnion(\"state\", [\n z.object({ state: z.literal(\"set\"), value: z.string() }),\n z.object({ state: z.literal(\"not_set\") }),\n z.object({ state: z.literal(\"not_read\"), reason: z.string() }),\n]);\nexport type GoogleUrlOptionValue = z.infer<typeof googleUrlOptionValueSchema>;\n\nexport const googleUrlOptionsRequestSchema = z.object({\n customerId: z.string().regex(NUMERIC_ID_REGEX, \"customerId must be the bare numeric customer id\"),\n managerId: z.string().optional(),\n /** Compact by default: only campaigns that actually override the account. `full` lists every campaign. */\n full: z.boolean().optional(),\n skipCache: z.boolean().optional(),\n});\nexport type GoogleUrlOptionsRequest = z.infer<typeof googleUrlOptionsRequestSchema>;\n\nexport const googleUrlOptionsCampaignSchema = z.object({\n id: z.string(),\n name: z.string(),\n status: z.string(),\n final_url_suffix: googleUrlOptionValueSchema,\n tracking_url_template: googleUrlOptionValueSchema,\n});\nexport type GoogleUrlOptionsCampaign = z.infer<typeof googleUrlOptionsCampaignSchema>;\n\nexport const googleUrlOptionsAdGroupSchema = z.object({\n id: z.string(),\n name: z.string(),\n status: z.string(),\n campaign_id: z.string(),\n final_url_suffix: googleUrlOptionValueSchema,\n tracking_url_template: googleUrlOptionValueSchema,\n});\nexport type GoogleUrlOptionsAdGroup = z.infer<typeof googleUrlOptionsAdGroupSchema>;\n\nexport const googleUrlOptionsAdSchema = z.object({\n id: z.string(),\n status: z.string(),\n ad_group_id: z.string(),\n campaign_id: z.string(),\n final_url_suffix: googleUrlOptionValueSchema,\n tracking_url_template: googleUrlOptionValueSchema,\n});\nexport type GoogleUrlOptionsAd = z.infer<typeof googleUrlOptionsAdSchema>;\n\nexport const googleUrlOptionsResponseSchema = z.object({\n customer_id: z.string(),\n account: z.object({\n level: z.literal(\"account\"),\n read: z.boolean(),\n final_url_suffix: googleUrlOptionValueSchema,\n tracking_url_template: googleUrlOptionValueSchema,\n }),\n campaigns: z.object({\n level: z.literal(\"campaign\"),\n read: z.boolean(),\n /** Campaigns actually observed. 0 with `read: true` means the account has no non-removed campaigns. */\n campaigns_read: z.number().int().nonnegative(),\n /** Campaigns observed to carry no override of their own — an explicit finding, not an omission. */\n campaigns_without_override: z.number().int().nonnegative(),\n overrides: z.array(googleUrlOptionsCampaignSchema),\n /** Compact mode only: campaigns read but not listed because they carry no override. */\n omitted: z.number().int().nonnegative(),\n }),\n /**\n * Ad groups and ads that carry an override of their own — read by asking Google only for the\n * entities whose suffix or template IS NOT NULL, so an account of thousands of ads costs one page.\n * `read: true` with no overrides is a finding: nothing at this level overrides the levels above.\n * `truncated` means more overriding entities exist than one page listed.\n */\n ad_groups: z.object({\n level: z.literal(\"ad_group\"),\n read: z.boolean(),\n overrides: z.array(googleUrlOptionsAdGroupSchema),\n truncated: z.boolean(),\n }),\n ads: z.object({\n level: z.literal(\"ad\"),\n read: z.boolean(),\n overrides: z.array(googleUrlOptionsAdSchema),\n truncated: z.boolean(),\n }),\n /** Levels this command could not read. Nothing here may be reported as \"not configured\". */\n levels_not_read: z.array(z.object({ level: z.enum(URL_OPTION_LEVELS), reason: z.string() })),\n});\nexport type GoogleUrlOptionsResponse = z.infer<typeof googleUrlOptionsResponseSchema>;\n\n/** Where Google keeps the account-level fields, verbatim, for an agent relaying it to a marketer. */\nexport const ACCOUNT_URL_OPTIONS_LOCATION =\n \"Google Ads UI → Admin → Account settings → Tracking (account-level tracking template and final URL suffix)\";\n\n/**\n * How the account-level value is staged: `google.customer.update` rides the same `GoogleAdsService.Mutate`\n * batch as every other staged op (`customerOperation`), so it applies at Publish like the rest.\n */\nexport const ACCOUNT_URL_OPTIONS_STAGE_COMMAND =\n 'baker ads google account update --customer-id <id> --final-url-suffix \"utm_agency=baker\"';\n\nfunction isSet(value: GoogleUrlOptionValue): value is { state: \"set\"; value: string } {\n return value.state === \"set\";\n}\n\n/** What an ad-group or ad level's overrides mean for an account-wide parameter. */\nfunction entityOverrideHints(\n label: string,\n plural: string,\n field: string,\n level: GoogleUrlOptionsResponse[\"ad_groups\"] | GoogleUrlOptionsResponse[\"ads\"],\n): string[] {\n if (!level.read) return [];\n const hints: string[] = [];\n const overriding: Array<{ id: string; name?: string; final_url_suffix: GoogleUrlOptionValue }> =\n level.overrides.filter((entity) => isSet(entity.final_url_suffix));\n if (overriding.length > 0) {\n const named = overriding\n .slice(0, 5)\n .map((entity) => entity.name || entity.id)\n .join(\", \");\n hints.push(\n `${overriding.length} ${label}(s) set their own final URL suffix (${named}${overriding.length > 5 ? \", …\" : \"\"}). It REPLACES the campaign and account suffix for every click through it, so an account-wide parameter must be added to theirs too.`,\n );\n }\n if (level.truncated) {\n hints.push(\n `More ${plural} override the URL options than one page lists — read them all with \\`baker ads google query\\` on ${field}.final_url_suffix IS NOT NULL --all before saying which ones do.`,\n );\n }\n return hints;\n}\n\n/**\n * Post-read nudges. The account level is the right home for an account-wide parameter\n * (agency/partner tagging), so a missing account suffix is the finding worth surfacing —\n * and a level that failed to read must never be reported as unset.\n */\nexport function urlOptionsHints(report: GoogleUrlOptionsResponse): string[] {\n const hints: string[] = [];\n const { account, campaigns } = report;\n\n if (!account.read) {\n hints.push(\n \"The account level did NOT read — its URL options are unknown, not empty. Re-run before telling the user anything about account-wide tagging.\",\n );\n } else if (account.final_url_suffix.state === \"not_set\") {\n hints.push(\n `No account-level final URL suffix is set. An account-wide parameter (agency/partner tagging such as utm_agency=…) belongs at the account level so it reaches every ad — stage it with \\`${ACCOUNT_URL_OPTIONS_STAGE_COMMAND}\\` (applies at Publish; the user sees it under ${ACCOUNT_URL_OPTIONS_LOCATION}).`,\n );\n }\n\n if (!campaigns.read) {\n hints.push(\n \"Campaign-level URL options did NOT read — do not report that no campaign overrides exist. Re-run before concluding.\",\n );\n } else {\n // `overrides` carries every campaign under --full, not just the overriding ones,\n // so name the ones that actually set a suffix. Saying \"campaigns listed under\n // `overrides`\" would tell the agent that campaigns inheriting fine are broken.\n const overriding = campaigns.overrides.filter((c) => isSet(c.final_url_suffix));\n if (overriding.length > 0) {\n const named = overriding\n .slice(0, 5)\n .map((c) => c.name || c.id)\n .join(\", \");\n hints.push(\n `A campaign's final URL suffix REPLACES the account-level one for that campaign — it does not merge. ${overriding.length} campaign(s) set their own (${named}${overriding.length > 5 ? \", …\" : \"\"}) and will not pick up an account-wide parameter until their own suffix carries it too. Every other campaign read here inherits the account level normally.`,\n );\n }\n }\n\n hints.push(...entityOverrideHints(\"ad group\", \"ad groups\", \"ad_group\", report.ad_groups));\n hints.push(...entityOverrideHints(\"ad\", \"ads\", \"ad_group_ad.ad\", report.ads));\n\n // Precedence is account → campaign → ad group → ad, most specific winning, so\n // \"a suffix set there still wins\" only holds for levels BELOW the ones that read.\n // `account` is the least specific — a campaign, ad-group or ad suffix overrides it —\n // and it joins `levels_not_read` whenever the customer read fails, which would hand\n // the agent the precedence backwards. Its own \"did NOT read\" hint above covers it.\n const overridingLevelsNotRead = report.levels_not_read.filter((level) => level.level !== \"account\");\n if (overridingLevelsNotRead.length > 0) {\n hints.push(\n `Not read at this level: ${overridingLevelsNotRead.map((l) => l.level).join(\", \")}. A suffix set there still wins over the levels above it.`,\n );\n }\n\n if (campaigns.omitted > 0) {\n hints.push(`${campaigns.omitted} campaign(s) read with no override of their own are not listed — pass --full.`);\n }\n\n return hints;\n}\n"],"mappings":"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","names":["z","z"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/commands/avatars/wait.ts
|
|
2
|
+
var WAIT_TIMEOUT_MS = 9e4;
|
|
3
|
+
var WAIT_INTERVAL_MS = 3e3;
|
|
4
|
+
function shouldKeepWaiting(avatar, elapsedMs) {
|
|
5
|
+
if (avatar.status === "ready") return { done: true, reason: "ready" };
|
|
6
|
+
if (avatar.status === "error" || avatar.status === "archived") return { done: true, reason: "settled" };
|
|
7
|
+
if (avatar.needsFace) return { done: true, reason: "needs-face" };
|
|
8
|
+
if (elapsedMs >= WAIT_TIMEOUT_MS) return { done: false, reason: "expired" };
|
|
9
|
+
return { done: false, reason: "building" };
|
|
10
|
+
}
|
|
11
|
+
async function waitForSheet(first, read, sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms))) {
|
|
12
|
+
const startedAt = Date.now();
|
|
13
|
+
let latest = first;
|
|
14
|
+
while (!shouldKeepWaiting(latest, Date.now() - startedAt).done) {
|
|
15
|
+
if (shouldKeepWaiting(latest, Date.now() - startedAt).reason === "expired") return latest;
|
|
16
|
+
await sleep(WAIT_INTERVAL_MS);
|
|
17
|
+
latest = await read();
|
|
18
|
+
}
|
|
19
|
+
return latest;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
waitForSheet
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=chunk-WN4KX7GE.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/avatars/wait.ts"],"sourcesContent":["import type { AvatarStatus } from \"@baker/api\";\n\n/**\n * Waiting for an avatar's identity sheet, inside the command rather than in the agent.\n *\n * The sheet is a ~30s render, and the agent is told never to sleep on it — right, because\n * a turn spent standing still is a turn the user watches do nothing. But when the only\n * work left DEPENDS on that avatar, \"do the next piece of work\" names work that does not\n * exist, and the observed turn simply ended: the user had to come back and say \"ya está\n * lista\" for the clip to be made.\n *\n * A command that blocks internally is the sanctioned shape for this — it has its own\n * deadline and returns the moment the thing is ready, which a polling loop written by the\n * agent does neither of.\n */\n\n/** How long to keep asking before giving up. Twice the sheet's usual render. */\nexport const WAIT_TIMEOUT_MS = 90_000;\n/** Gap between reads. Short enough to return promptly, long enough not to hammer. */\nexport const WAIT_INTERVAL_MS = 3_000;\n\nexport type WaitDecision =\n | { done: true; reason: \"ready\" | \"settled\" | \"needs-face\" }\n | { done: false; reason: \"building\" | \"expired\" };\n\n/** Just enough of an avatar to know whether waiting on it can ever end. */\nexport interface WaitSubject {\n status: AvatarStatus;\n /**\n * The build is parked on a face the user has not picked yet.\n *\n * `generating` normally means a render is running. This is the one case where it\n * does not: the casting portraits are in front of the user and nothing starts until\n * they answer.\n */\n needsFace?: boolean;\n}\n\n/**\n * Whether to stop waiting on this avatar, given how long we have waited.\n *\n * `error` and `archived` stop it too: both are settled states, and waiting out the\n * deadline for one of them would burn 90 seconds to learn what the first read said.\n *\n * So does an avatar waiting on its face. Nothing is rendering, so the only thing that\n * can happen here is the deadline expiring — and it is the user's own turn to act, not\n * the agent's. Observed: an agent blocked the full 90 seconds twice, concluded the\n * avatar was broken, and deleted the one the user was at that moment picking a face for.\n */\nexport function shouldKeepWaiting(avatar: WaitSubject, elapsedMs: number): WaitDecision {\n if (avatar.status === \"ready\") return { done: true, reason: \"ready\" };\n if (avatar.status === \"error\" || avatar.status === \"archived\") return { done: true, reason: \"settled\" };\n if (avatar.needsFace) return { done: true, reason: \"needs-face\" };\n if (elapsedMs >= WAIT_TIMEOUT_MS) return { done: false, reason: \"expired\" };\n return { done: false, reason: \"building\" };\n}\n\n/**\n * Re-reads the avatar until its sheet settles, or the deadline passes.\n *\n * Returns whatever the last read said either way — an expired wait is not a failure, it\n * is a slow render, and the caller's own hints already say what a still-building avatar\n * can and cannot be used for.\n */\nexport async function waitForSheet<T extends WaitSubject>(\n first: T,\n read: () => Promise<T>,\n sleep: (ms: number) => Promise<void> = (ms) => new Promise((resolve) => setTimeout(resolve, ms)),\n): Promise<T> {\n const startedAt = Date.now();\n let latest = first;\n while (!shouldKeepWaiting(latest, Date.now() - startedAt).done) {\n if (shouldKeepWaiting(latest, Date.now() - startedAt).reason === \"expired\") return latest;\n await sleep(WAIT_INTERVAL_MS);\n latest = await read();\n }\n return latest;\n}\n"],"mappings":";AAiBO,IAAM,kBAAkB;AAExB,IAAM,mBAAmB;AA8BzB,SAAS,kBAAkB,QAAqB,WAAiC;AACtF,MAAI,OAAO,WAAW,QAAS,QAAO,EAAE,MAAM,MAAM,QAAQ,QAAQ;AACpE,MAAI,OAAO,WAAW,WAAW,OAAO,WAAW,WAAY,QAAO,EAAE,MAAM,MAAM,QAAQ,UAAU;AACtG,MAAI,OAAO,UAAW,QAAO,EAAE,MAAM,MAAM,QAAQ,aAAa;AAChE,MAAI,aAAa,gBAAiB,QAAO,EAAE,MAAM,OAAO,QAAQ,UAAU;AAC1E,SAAO,EAAE,MAAM,OAAO,QAAQ,WAAW;AAC3C;AASA,eAAsB,aACpB,OACA,MACA,QAAuC,CAAC,OAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC,GACnF;AACZ,QAAM,YAAY,KAAK,IAAI;AAC3B,MAAI,SAAS;AACb,SAAO,CAAC,kBAAkB,QAAQ,KAAK,IAAI,IAAI,SAAS,EAAE,MAAM;AAC9D,QAAI,kBAAkB,QAAQ,KAAK,IAAI,IAAI,SAAS,EAAE,WAAW,UAAW,QAAO;AACnF,UAAM,MAAM,gBAAgB;AAC5B,aAAS,MAAM,KAAK;AAAA,EACtB;AACA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import {
|
|
2
|
+
reportError,
|
|
3
|
+
splitList
|
|
4
|
+
} from "./chunk-752S7JF6.js";
|
|
5
|
+
import {
|
|
6
|
+
apiGet
|
|
7
|
+
} from "./chunk-HREWXNTO.js";
|
|
8
|
+
import {
|
|
9
|
+
registerSchema,
|
|
10
|
+
writeJson
|
|
11
|
+
} from "./chunk-WOTDHRNF.js";
|
|
12
|
+
|
|
13
|
+
// src/commands/winning-ads/launches.ts
|
|
14
|
+
import { defineCommand } from "citty";
|
|
15
|
+
registerSchema({
|
|
16
|
+
command: "winning-ads.launches",
|
|
17
|
+
description: 'What the brands you follow (or the ones named) launched in the last N days and which of those ads still run, each with its stage (new, testing, killed_early\u2026), and the tests each brand decided in that window (the version kept, what differed). The "what did competitors launch last week" report. Compact by default; --full lists every launch.',
|
|
18
|
+
args: {
|
|
19
|
+
since: { type: "number", description: "Days to look back, 1-90 (default 7)", required: false, default: 7 },
|
|
20
|
+
advertiser: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "Comma list of advertiser ids instead of every followed brand",
|
|
23
|
+
required: false
|
|
24
|
+
},
|
|
25
|
+
platform: { type: "string", description: "Only this platform: meta|linkedin|tiktok|google", required: false },
|
|
26
|
+
full: { type: "boolean", description: "List every launch", required: false, default: false }
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
var COMPACT_LAUNCHES = 10;
|
|
30
|
+
function compactLaunches(report, full) {
|
|
31
|
+
return {
|
|
32
|
+
since_days: report.since_days,
|
|
33
|
+
advertisers: report.advertisers.map((b) => ({
|
|
34
|
+
advertiser_id: b.advertiser_id,
|
|
35
|
+
label: b.label,
|
|
36
|
+
launched: b.launched,
|
|
37
|
+
still_running: b.still_running,
|
|
38
|
+
launches: (full ? b.launches : b.launches.slice(0, COMPACT_LAUNCHES)).map((l) => ({
|
|
39
|
+
ad_id: l.ad_id,
|
|
40
|
+
platform: l.platform,
|
|
41
|
+
format: l.format,
|
|
42
|
+
headline: l.headline,
|
|
43
|
+
first_seen_at: l.first_seen_at,
|
|
44
|
+
stage: l.stage,
|
|
45
|
+
idea: l.idea ?? null,
|
|
46
|
+
...full ? { media_url: l.media_url } : {}
|
|
47
|
+
})),
|
|
48
|
+
tests_decided: (b.tests_decided ?? []).map((t) => ({
|
|
49
|
+
concept: t.concept,
|
|
50
|
+
versions: t.versions,
|
|
51
|
+
kept_ad_id: t.winner_ad_id,
|
|
52
|
+
decided_at: t.decided_at ?? null,
|
|
53
|
+
what_differed: t.what_differed
|
|
54
|
+
}))
|
|
55
|
+
}))
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
var IDEA_HINT = "Idea: whether each launch was a `new` idea (the first day of its concept), another version of one the brand was still `testing`, or a version built on a `winner` it had already kept. Many launches and no new idea means the brand is iterating on what works, not testing new directions: say so.";
|
|
59
|
+
function launchesHints(report, named) {
|
|
60
|
+
if (!named && report.following_count === 0) {
|
|
61
|
+
return ["You follow no brands yet: `baker winning-ads follow <domain>` adds one, or pass --advertiser <id>."];
|
|
62
|
+
}
|
|
63
|
+
if (report.advertisers.length === 0) {
|
|
64
|
+
return [`No launches in the last ${report.since_days} days. Widen the window with --since 30.`];
|
|
65
|
+
}
|
|
66
|
+
const withIdeas = report.advertisers.some((b) => b.launches.some((l) => l.idea));
|
|
67
|
+
return [
|
|
68
|
+
...withIdeas ? [IDEA_HINT] : [],
|
|
69
|
+
"Stages: new \u22647 days, testing \u226421 days, proven \u226460 days, evergreen beyond, killed_early = stopped within 2 weeks (a lost test). tests_decided is what each brand learned in the window: the version it kept (kept_ad_id) and what differed. `baker winning-ads search --survived-test` finds the versions brands kept across the library."
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
var launchesCommand = defineCommand({
|
|
73
|
+
meta: {
|
|
74
|
+
name: "launches",
|
|
75
|
+
description: "What competitors launched lately and what still runs. Start here: baker winning-ads launches --since 7 (every followed brand), or --advertiser adv_1,adv_2"
|
|
76
|
+
},
|
|
77
|
+
args: {
|
|
78
|
+
since: { type: "string", description: "Days to look back, 1-90 (default 7)", required: false },
|
|
79
|
+
advertiser: { type: "string", description: "Comma list of advertiser ids", required: false },
|
|
80
|
+
platform: { type: "string", description: "Only this platform: meta|linkedin|tiktok|google", required: false },
|
|
81
|
+
full: { type: "boolean", description: "List every launch", required: false, default: false }
|
|
82
|
+
},
|
|
83
|
+
run: async ({ args }) => {
|
|
84
|
+
try {
|
|
85
|
+
const named = splitList(args.advertiser);
|
|
86
|
+
const params = { since_days: String(args.since ?? 7) };
|
|
87
|
+
if (named.length > 0) {
|
|
88
|
+
params.advertiser = named.join(",");
|
|
89
|
+
}
|
|
90
|
+
if (args.platform) {
|
|
91
|
+
params.platform = String(args.platform);
|
|
92
|
+
}
|
|
93
|
+
const report = await apiGet("/api/ad-library/launches", params);
|
|
94
|
+
writeJson({
|
|
95
|
+
ok: true,
|
|
96
|
+
data: compactLaunches(report, Boolean(args.full)),
|
|
97
|
+
hints: launchesHints(report, named.length > 0)
|
|
98
|
+
});
|
|
99
|
+
} catch (err) {
|
|
100
|
+
reportError(err);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
export {
|
|
106
|
+
compactLaunches,
|
|
107
|
+
IDEA_HINT,
|
|
108
|
+
launchesHints,
|
|
109
|
+
launchesCommand
|
|
110
|
+
};
|
|
111
|
+
//# sourceMappingURL=chunk-WNFTXSGR.js.map
|