@koda-sl/baker-cli 0.387.0 → 0.389.0-dev.8065ad8f0
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 +1090 -211
- package/canvas/tiktok-captions-composition/index.html +5 -6
- package/canvas/tiktok-captions-composition/meta.json +5 -0
- package/dist/account-CLOKMTTC.js +49 -0
- package/dist/account-CLOKMTTC.js.map +1 -0
- package/dist/account-V5Y2QHAK.js +79 -0
- package/dist/account-V5Y2QHAK.js.map +1 -0
- package/dist/account-XFK6VX2R.js +80 -0
- package/dist/account-XFK6VX2R.js.map +1 -0
- package/dist/account-reads-S5VXX2QU.js +218 -0
- package/dist/account-reads-S5VXX2QU.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-LOJ4WLIX.js +77 -0
- package/dist/accounts-LOJ4WLIX.js.map +1 -0
- package/dist/accounts-RYBDLQ6H.js +75 -0
- package/dist/accounts-RYBDLQ6H.js.map +1 -0
- package/dist/accounts-UO4XBWM2.js +611 -0
- package/dist/accounts-UO4XBWM2.js.map +1 -0
- package/dist/actions-3AW3R63U.js +55 -0
- package/dist/actions-3AW3R63U.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-43DUOVNR.js +104 -0
- package/dist/add-43DUOVNR.js.map +1 -0
- package/dist/add-IE5WDELB.js +302 -0
- package/dist/add-IE5WDELB.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-MALHYD2D.js +40 -0
- package/dist/ads-MALHYD2D.js.map +1 -0
- package/dist/ads-XZCMSPM5.js +113 -0
- package/dist/ads-XZCMSPM5.js.map +1 -0
- package/dist/adsets-AKR75THA.js +176 -0
- package/dist/adsets-AKR75THA.js.map +1 -0
- package/dist/advertisers-52FMMBTQ.js +120 -0
- package/dist/advertisers-52FMMBTQ.js.map +1 -0
- package/dist/advertisers-BCGKUMEH.js +125 -0
- package/dist/advertisers-BCGKUMEH.js.map +1 -0
- package/dist/analytics-JPDBKETM.js +1980 -0
- package/dist/analytics-JPDBKETM.js.map +1 -0
- package/dist/analytics-YVQ6H4BG.js +433 -0
- package/dist/analytics-YVQ6H4BG.js.map +1 -0
- package/dist/animate-JXIT77Y5.js +480 -0
- package/dist/animate-JXIT77Y5.js.map +1 -0
- package/dist/assign-66NTWTR2.js +77 -0
- package/dist/assign-66NTWTR2.js.map +1 -0
- package/dist/audience-size-LVQJWQAS.js +94 -0
- package/dist/audience-size-LVQJWQAS.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-NYGMBGQ3.js +79 -0
- package/dist/audiences-NYGMBGQ3.js.map +1 -0
- package/dist/audit-UIPMTI5C.js +88 -0
- package/dist/audit-UIPMTI5C.js.map +1 -0
- package/dist/audit-XGN2OFLN.js +151 -0
- package/dist/audit-XGN2OFLN.js.map +1 -0
- package/dist/autocomplete-LVPDV3JE.js +111 -0
- package/dist/autocomplete-LVPDV3JE.js.map +1 -0
- package/dist/avatars-S6NSLMJK.js +38 -0
- package/dist/avatars-S6NSLMJK.js.map +1 -0
- package/dist/bid-pricing-2LYULXU2.js +99 -0
- package/dist/bid-pricing-2LYULXU2.js.map +1 -0
- package/dist/brand-WWHUZ72R.js +22 -0
- package/dist/brand-WWHUZ72R.js.map +1 -0
- package/dist/brief-XY3TFWBC.js +492 -0
- package/dist/brief-XY3TFWBC.js.map +1 -0
- package/dist/businesses-J7OP7MSK.js +53 -0
- package/dist/businesses-J7OP7MSK.js.map +1 -0
- package/dist/campaign-groups-N4TZ2F3L.js +95 -0
- package/dist/campaign-groups-N4TZ2F3L.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-7YFRQIQT.js +165 -0
- package/dist/campaign-writes-7YFRQIQT.js.map +1 -0
- package/dist/campaigns-JPYNVFQI.js +76 -0
- package/dist/campaigns-JPYNVFQI.js.map +1 -0
- package/dist/campaigns-L43ZUKAI.js +107 -0
- package/dist/campaigns-L43ZUKAI.js.map +1 -0
- package/dist/campaigns-OD7Z332M.js +109 -0
- package/dist/campaigns-OD7Z332M.js.map +1 -0
- package/dist/campaigns-R4DXIR2Q.js +110 -0
- package/dist/campaigns-R4DXIR2Q.js.map +1 -0
- package/dist/canvas-J7SLIVL7.js +46 -0
- package/dist/canvas-J7SLIVL7.js.map +1 -0
- package/dist/capabilities-FVTZAFPV.js +144 -0
- package/dist/capabilities-FVTZAFPV.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-7ZIGNUW6.js +135 -0
- package/dist/changes-7ZIGNUW6.js.map +1 -0
- package/dist/chatgpt-B3NHRJUE.js +47 -0
- package/dist/chatgpt-B3NHRJUE.js.map +1 -0
- package/dist/chats-E7DBRHBF.js +262 -0
- package/dist/chats-E7DBRHBF.js.map +1 -0
- package/dist/chunk-2CV7LX23.js +474 -0
- package/dist/chunk-2CV7LX23.js.map +1 -0
- package/dist/chunk-2HCI5BXB.js +479 -0
- package/dist/chunk-2HCI5BXB.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-3ACMDRSE.js +39 -0
- package/dist/chunk-3ACMDRSE.js.map +1 -0
- package/dist/chunk-3CIXGQJS.js +150 -0
- package/dist/chunk-3CIXGQJS.js.map +1 -0
- package/dist/chunk-3U7TDBIB.js +275 -0
- package/dist/chunk-3U7TDBIB.js.map +1 -0
- package/dist/chunk-3UDSYYND.js +42 -0
- package/dist/chunk-3UDSYYND.js.map +1 -0
- package/dist/chunk-3ZWWXAQZ.js +150 -0
- package/dist/chunk-3ZWWXAQZ.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-564AEU2Q.js +541 -0
- package/dist/chunk-564AEU2Q.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-77DN7R35.js +228 -0
- package/dist/chunk-77DN7R35.js.map +1 -0
- package/dist/chunk-7F7MFMLI.js +175 -0
- package/dist/chunk-7F7MFMLI.js.map +1 -0
- package/dist/chunk-7THBBTJJ.js +183 -0
- package/dist/chunk-7THBBTJJ.js.map +1 -0
- package/dist/chunk-7XU3HKMX.js +1599 -0
- package/dist/chunk-7XU3HKMX.js.map +1 -0
- package/dist/chunk-A2CBZLQ6.js +111 -0
- package/dist/chunk-A2CBZLQ6.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-AUSKKFVH.js +84 -0
- package/dist/chunk-AUSKKFVH.js.map +1 -0
- package/dist/chunk-B52DCYL2.js +159 -0
- package/dist/chunk-B52DCYL2.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-CYBLKMXQ.js +310 -0
- package/dist/chunk-CYBLKMXQ.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-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-EDLZGTGN.js +216 -0
- package/dist/chunk-EDLZGTGN.js.map +1 -0
- package/dist/chunk-EDNKALM6.js +304 -0
- package/dist/chunk-EDNKALM6.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-ERSX3MKH.js +34 -0
- package/dist/chunk-ERSX3MKH.js.map +1 -0
- package/dist/chunk-F3IJSR7O.js +346 -0
- package/dist/chunk-F3IJSR7O.js.map +1 -0
- package/dist/chunk-FKOECEVC.js +126 -0
- package/dist/chunk-FKOECEVC.js.map +1 -0
- package/dist/chunk-FWT55B3O.js +509 -0
- package/dist/chunk-FWT55B3O.js.map +1 -0
- package/dist/chunk-FYWWTMXP.js +2902 -0
- package/dist/chunk-FYWWTMXP.js.map +1 -0
- package/dist/chunk-FZGCAW46.js +64 -0
- package/dist/chunk-FZGCAW46.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-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-GYABNLWW.js +629 -0
- package/dist/chunk-GYABNLWW.js.map +1 -0
- package/dist/chunk-H7MLHG2I.js +94 -0
- package/dist/chunk-H7MLHG2I.js.map +1 -0
- package/dist/chunk-H7XVKLIY.js +206 -0
- package/dist/chunk-H7XVKLIY.js.map +1 -0
- package/dist/chunk-HAE4WWFQ.js +455 -0
- package/dist/chunk-HAE4WWFQ.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-HYXKRNRV.js +176 -0
- package/dist/chunk-HYXKRNRV.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-IOCSDFF2.js +23992 -0
- package/dist/chunk-IOCSDFF2.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-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-JUAIGJ2A.js +76 -0
- package/dist/chunk-JUAIGJ2A.js.map +1 -0
- package/dist/chunk-K5OQES4V.js +58 -0
- package/dist/chunk-K5OQES4V.js.map +1 -0
- package/dist/chunk-KBS5GH4T.js +1626 -0
- package/dist/chunk-KBS5GH4T.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-KXGG6EQM.js +382 -0
- package/dist/chunk-KXGG6EQM.js.map +1 -0
- package/dist/chunk-KXRKPZZY.js +169 -0
- package/dist/chunk-KXRKPZZY.js.map +1 -0
- package/dist/chunk-KZUHRZ2C.js +5187 -0
- package/dist/chunk-KZUHRZ2C.js.map +1 -0
- package/dist/chunk-L45A3IYV.js +1079 -0
- package/dist/chunk-L45A3IYV.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-LERWCRY5.js +297 -0
- package/dist/chunk-LERWCRY5.js.map +1 -0
- package/dist/chunk-LLPFY3NI.js +207 -0
- package/dist/chunk-LLPFY3NI.js.map +1 -0
- package/dist/chunk-M6UNISGO.js +66 -0
- package/dist/chunk-M6UNISGO.js.map +1 -0
- package/dist/chunk-MDATIJPM.js +92 -0
- package/dist/chunk-MDATIJPM.js.map +1 -0
- package/dist/chunk-MGKHFGLV.js +75 -0
- package/dist/chunk-MGKHFGLV.js.map +1 -0
- package/dist/chunk-MZWC6HHA.js +455 -0
- package/dist/chunk-MZWC6HHA.js.map +1 -0
- package/dist/chunk-N3XJ434P.js +197 -0
- package/dist/chunk-N3XJ434P.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-NJEZM4OB.js +51 -0
- package/dist/chunk-NJEZM4OB.js.map +1 -0
- package/dist/chunk-O6QKCJE4.js +455 -0
- package/dist/chunk-O6QKCJE4.js.map +1 -0
- package/dist/chunk-OFFAMC5H.js +225 -0
- package/dist/chunk-OFFAMC5H.js.map +1 -0
- package/dist/chunk-OHGTCFFE.js +57 -0
- package/dist/chunk-OHGTCFFE.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-PFBQERWX.js +10 -0
- package/dist/chunk-PFBQERWX.js.map +1 -0
- package/dist/chunk-PUPEGICD.js +103 -0
- package/dist/chunk-PUPEGICD.js.map +1 -0
- package/dist/chunk-Q6ULQMWG.js +41 -0
- package/dist/chunk-Q6ULQMWG.js.map +1 -0
- package/dist/chunk-QO23YHLK.js +84 -0
- package/dist/chunk-QO23YHLK.js.map +1 -0
- package/dist/chunk-QSGIWV4P.js +337 -0
- package/dist/chunk-QSGIWV4P.js.map +1 -0
- package/dist/chunk-R4Y5P3PB.js +19 -0
- package/dist/chunk-R4Y5P3PB.js.map +1 -0
- package/dist/chunk-R5OQM7FF.js +179 -0
- package/dist/chunk-R5OQM7FF.js.map +1 -0
- package/dist/chunk-RODLBWIR.js +592 -0
- package/dist/chunk-RODLBWIR.js.map +1 -0
- package/dist/chunk-RY7TYEIX.js +504 -0
- package/dist/chunk-RY7TYEIX.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-SJH4EOZH.js +23 -0
- package/dist/chunk-SJH4EOZH.js.map +1 -0
- package/dist/chunk-SMIENBNX.js +6212 -0
- package/dist/chunk-SMIENBNX.js.map +1 -0
- package/dist/chunk-T7GT22KA.js +494 -0
- package/dist/chunk-T7GT22KA.js.map +1 -0
- package/dist/chunk-T7M4WFNV.js +172 -0
- package/dist/chunk-T7M4WFNV.js.map +1 -0
- package/dist/chunk-TIFVHGQL.js +6683 -0
- package/dist/chunk-TIFVHGQL.js.map +1 -0
- package/dist/chunk-TMIDUSOR.js +665 -0
- package/dist/chunk-TMIDUSOR.js.map +1 -0
- package/dist/{chunk-WLDM2TRF.js → chunk-TPXI2GCW.js} +4 -4
- 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-UOI5S62H.js +846 -0
- package/dist/chunk-UOI5S62H.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-VNKVBY54.js +363 -0
- package/dist/chunk-VNKVBY54.js.map +1 -0
- package/dist/chunk-VS4C7VAR.js +533 -0
- package/dist/chunk-VS4C7VAR.js.map +1 -0
- package/dist/chunk-VZMDYVNS.js +3151 -0
- package/dist/chunk-VZMDYVNS.js.map +1 -0
- package/dist/chunk-W4W4ZRBP.js +191 -0
- package/dist/chunk-W4W4ZRBP.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-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-XX6ZMCY5.js +4227 -0
- package/dist/chunk-XX6ZMCY5.js.map +1 -0
- package/dist/chunk-Y362QH54.js +98 -0
- package/dist/chunk-Y362QH54.js.map +1 -0
- package/dist/chunk-Y4T6ATDQ.js +74 -0
- package/dist/chunk-Y4T6ATDQ.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-Z3ENMCFE.js +94 -0
- package/dist/chunk-Z3ENMCFE.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-LF6VQ7OR.js +197 -0
- package/dist/claim-LF6VQ7OR.js.map +1 -0
- package/dist/cli.js +104 -70041
- 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-6HSK5BLK.js +195 -0
- package/dist/companies-6HSK5BLK.js.map +1 -0
- package/dist/complete-2PUAFQEC.js +81 -0
- package/dist/complete-2PUAFQEC.js.map +1 -0
- package/dist/config-X6GKOVQ6.js +88 -0
- package/dist/config-X6GKOVQ6.js.map +1 -0
- package/dist/connect-RXPMAJQI.js +42 -0
- package/dist/content-UYZC4AKN.js +85 -0
- package/dist/content-UYZC4AKN.js.map +1 -0
- package/dist/conversation-Y3NB2VDI.js +93 -0
- package/dist/conversation-Y3NB2VDI.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-YP4DGTPP.js +438 -0
- package/dist/conversion-upload-command-YP4DGTPP.js.map +1 -0
- package/dist/conversion-writes-WHFFUWWL.js +120 -0
- package/dist/conversion-writes-WHFFUWWL.js.map +1 -0
- package/dist/conversions-K7C32DPW.js +135 -0
- package/dist/conversions-K7C32DPW.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-AJ4KPSJ4.js +59 -0
- package/dist/create-AJ4KPSJ4.js.map +1 -0
- package/dist/create-ALKOAD5J.js +138 -0
- package/dist/create-ALKOAD5J.js.map +1 -0
- package/dist/create-HTKZMXKB.js +207 -0
- package/dist/create-HTKZMXKB.js.map +1 -0
- package/dist/create-TZMAOFBR.js +236 -0
- package/dist/create-TZMAOFBR.js.map +1 -0
- package/dist/creatives-MBTZTIAA.js +51 -0
- package/dist/creatives-MBTZTIAA.js.map +1 -0
- package/dist/creatives-OZHVU4WB.js +182 -0
- package/dist/creatives-OZHVU4WB.js.map +1 -0
- package/dist/creatives-VMGY5SU4.js +87 -0
- package/dist/creatives-VMGY5SU4.js.map +1 -0
- package/dist/credentials-FY4UH6TF.js +287 -0
- package/dist/credentials-FY4UH6TF.js.map +1 -0
- package/dist/critique-2UTP4DR3.js +216 -0
- package/dist/critique-2UTP4DR3.js.map +1 -0
- package/dist/critique-B3H7QFM2.js +1449 -0
- package/dist/critique-B3H7QFM2.js.map +1 -0
- package/dist/crm-2IBLUHDB.js +318 -0
- package/dist/crm-2IBLUHDB.js.map +1 -0
- package/dist/crm-YMYO4U53.js +224 -0
- package/dist/crm-YMYO4U53.js.map +1 -0
- package/dist/crop-U3AD4DDR.js +113 -0
- package/dist/crop-U3AD4DDR.js.map +1 -0
- package/dist/currency-S6KWZSZ6.js +88 -0
- package/dist/currency-S6KWZSZ6.js.map +1 -0
- package/dist/custom-conversions-FABS6YVT.js +125 -0
- package/dist/custom-conversions-FABS6YVT.js.map +1 -0
- package/dist/customers-P6LLLJHK.js +56 -0
- package/dist/decide-YTHCBKM6.js +199 -0
- package/dist/decide-YTHCBKM6.js.map +1 -0
- package/dist/delete-B2TDEW7H.js +63 -0
- package/dist/delete-B2TDEW7H.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-SDOZNDWQ.js +54 -0
- package/dist/delete-SDOZNDWQ.js.map +1 -0
- package/dist/delete-VQMU56OH.js +71 -0
- package/dist/delete-VQMU56OH.js.map +1 -0
- package/dist/delete-WKQPMVAM.js +66 -0
- package/dist/delete-WKQPMVAM.js.map +1 -0
- package/dist/demographics-Q3DCXULY.js +138 -0
- package/dist/demographics-Q3DCXULY.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-NEZM5CHF.js +66 -0
- package/dist/discard-NEZM5CHF.js.map +1 -0
- package/dist/discover-4GD7QSF5.js +93 -0
- package/dist/discover-4GD7QSF5.js.map +1 -0
- package/dist/discover-6K3IOYXR.js +172 -0
- package/dist/discover-6K3IOYXR.js.map +1 -0
- package/dist/domain-7Y256IDR.js +98 -0
- package/dist/domain-7Y256IDR.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-F6TUGXAY.js +307 -0
- package/dist/draft-F6TUGXAY.js.map +1 -0
- package/dist/draft-KLULNBWP.js +233 -0
- package/dist/draft-KLULNBWP.js.map +1 -0
- package/dist/draft-LY5ZPF73.js +217 -0
- package/dist/draft-LY5ZPF73.js.map +1 -0
- package/dist/draft-M4ZHDQ46.js +306 -0
- package/dist/draft-M4ZHDQ46.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-QQMCVDDS.js +328 -0
- package/dist/draft-QQMCVDDS.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-7MBSM7BP.js +114 -0
- package/dist/facets-7MBSM7BP.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-PLMFRAQW.js +66 -0
- package/dist/feedback-PLMFRAQW.js.map +1 -0
- package/dist/feedback-record-QEHHGVYC.js +177 -0
- package/dist/feedback-record-QEHHGVYC.js.map +1 -0
- package/dist/fetch-QE3EB756.js +176 -0
- package/dist/fetch-QE3EB756.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-C67KEMDU.js +247 -0
- package/dist/flows-C67KEMDU.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-UR7XZ5XZ.js +34 -0
- package/dist/fonts-UR7XZ5XZ.js.map +1 -0
- package/dist/forecast-3F4SZNAK.js +104 -0
- package/dist/forecast-3F4SZNAK.js.map +1 -0
- package/dist/forecast-K5E7CTKX.js +168 -0
- package/dist/forecast-K5E7CTKX.js.map +1 -0
- package/dist/funding-H5YO37OW.js +85 -0
- package/dist/funding-H5YO37OW.js.map +1 -0
- package/dist/funnel-2PPEPAMY.js +394 -0
- package/dist/funnel-2PPEPAMY.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-AZARFR6O.js +61 -0
- package/dist/get-AZARFR6O.js.map +1 -0
- package/dist/get-BPMEHRUG.js +56 -0
- package/dist/get-BPMEHRUG.js.map +1 -0
- package/dist/get-MQ6MMIZ7.js +78 -0
- package/dist/get-MQ6MMIZ7.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-X2AQR3RB.js +3190 -0
- package/dist/google-X2AQR3RB.js.map +1 -0
- package/dist/google-ads-PWX7OF5Z.js +195 -0
- package/dist/google-ads-PWX7OF5Z.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-XI5ABCFO.js +133 -0
- package/dist/history-XI5ABCFO.js.map +1 -0
- package/dist/hubspot-AVUOILRE.js +779 -0
- package/dist/hubspot-AVUOILRE.js.map +1 -0
- package/dist/icon-K75KI6BV.js +137 -0
- package/dist/icon-K75KI6BV.js.map +1 -0
- package/dist/ideas-L3SZSIZP.js +35 -0
- package/dist/ideas-L3SZSIZP.js.map +1 -0
- package/dist/images-CD53I2W5.js +90 -0
- package/dist/images-CD53I2W5.js.map +1 -0
- package/dist/improve-L3BW4EQG.js +86 -0
- package/dist/improve-L3BW4EQG.js.map +1 -0
- package/dist/ingest-KRJOYTCQ.js +107 -0
- package/dist/ingest-KRJOYTCQ.js.map +1 -0
- package/dist/ingest-WE3SPPND.js +23 -0
- package/dist/ingest-WE3SPPND.js.map +1 -0
- package/dist/insights-PELVD4RY.js +122 -0
- package/dist/insights-PELVD4RY.js.map +1 -0
- package/dist/insights-XCA4BUJW.js +423 -0
- package/dist/insights-XCA4BUJW.js.map +1 -0
- package/dist/inspect-QKETG5UJ.js +189 -0
- package/dist/inspect-QKETG5UJ.js.map +1 -0
- package/dist/inspiration-Y2J2PUPC.js +53 -0
- package/dist/inspiration-Y2J2PUPC.js.map +1 -0
- package/dist/intent-YJOJGNVJ.js +95 -0
- package/dist/intent-YJOJGNVJ.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-QU7O7UKC.js +130 -0
- package/dist/keyword-gap-QU7O7UKC.js.map +1 -0
- package/dist/keyword-metrics-HLCM3QU7.js +197 -0
- package/dist/keyword-metrics-HLCM3QU7.js.map +1 -0
- package/dist/keywords-for-site-BDKPQKWB.js +128 -0
- package/dist/keywords-for-site-BDKPQKWB.js.map +1 -0
- package/dist/landing-4K6XYNFM.js +28 -0
- package/dist/landing-4K6XYNFM.js.map +1 -0
- package/dist/landings-F7LOAEJE.js +151 -0
- package/dist/landings-F7LOAEJE.js.map +1 -0
- package/dist/languages-P3ZM6R2A.js +40 -0
- package/dist/languages-P3ZM6R2A.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-GDF4S2AM.js +90 -0
- package/dist/leads-GDF4S2AM.js.map +1 -0
- package/dist/leads-TPB5OFSQ.js +293 -0
- package/dist/leads-TPB5OFSQ.js.map +1 -0
- package/dist/learn-NMFEA5H5.js +203 -0
- package/dist/learn-NMFEA5H5.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-O6SSS5NQ.js +208 -0
- package/dist/line-item-writes-O6SSS5NQ.js.map +1 -0
- package/dist/line-items-ZZAKH3YZ.js +103 -0
- package/dist/line-items-ZZAKH3YZ.js.map +1 -0
- package/dist/link-CRY57R3E.js +64 -0
- package/dist/link-CRY57R3E.js.map +1 -0
- package/dist/linkedin-WC7LGYPP.js +1008 -0
- package/dist/linkedin-WC7LGYPP.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-CWAKX5TH.js +63 -0
- package/dist/list-CWAKX5TH.js.map +1 -0
- package/dist/list-FJ5FSVL6.js +151 -0
- package/dist/list-FJ5FSVL6.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-NH4ZRZTL.js +303 -0
- package/dist/list-NH4ZRZTL.js.map +1 -0
- package/dist/locations-2BYWKIYA.js +67 -0
- package/dist/locations-2BYWKIYA.js.map +1 -0
- package/dist/locations-LVVDOSXO.js +40 -0
- package/dist/locations-LVVDOSXO.js.map +1 -0
- package/dist/log-6JOWOY5G.js +92 -0
- package/dist/log-6JOWOY5G.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-N3WZ6OSS.js +640 -0
- package/dist/make-N3WZ6OSS.js.map +1 -0
- package/dist/map-4KOYFHAN.js +404 -0
- package/dist/map-4KOYFHAN.js.map +1 -0
- package/dist/mcp-LSS2DHYL.js +463 -0
- package/dist/mcp-LSS2DHYL.js.map +1 -0
- package/dist/media-JBCN6V4X.js +15 -0
- package/dist/media-JBCN6V4X.js.map +1 -0
- package/dist/media-RAGEJTZX.js +89 -0
- package/dist/media-RAGEJTZX.js.map +1 -0
- package/dist/media-sources-GSPAV7HT.js +32 -0
- package/dist/media-sources-GSPAV7HT.js.map +1 -0
- package/dist/members-GUUVEK2Y.js +44 -0
- package/dist/members-GUUVEK2Y.js.map +1 -0
- package/dist/meta-Z37ZR3PJ.js +69 -0
- package/dist/meta-Z37ZR3PJ.js.map +1 -0
- package/dist/metrics-KW6SDULI.js +152 -0
- package/dist/metrics-KW6SDULI.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-EUDI5HEM.js +141 -0
- package/dist/normalize-EUDI5HEM.js.map +1 -0
- package/dist/options-P4PPJQH4.js +121 -0
- package/dist/options-P4PPJQH4.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-A66LYIZX.js +24 -0
- package/dist/performance-A66LYIZX.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-5ROBOQG7.js +169 -0
- package/dist/preview-5ROBOQG7.js.map +1 -0
- package/dist/profile-Q3PHR6FU.js +159 -0
- package/dist/profile-Q3PHR6FU.js.map +1 -0
- package/dist/promoted-tweet-writes-AEOUK2LK.js +180 -0
- package/dist/promoted-tweet-writes-AEOUK2LK.js.map +1 -0
- package/dist/promoted-tweets-L2CEC2BJ.js +119 -0
- package/dist/promoted-tweets-L2CEC2BJ.js.map +1 -0
- package/dist/properties-WLL6M2P6.js +101 -0
- package/dist/properties-WLL6M2P6.js.map +1 -0
- package/dist/publish-KHNR5ARF.js +322 -0
- package/dist/publish-KHNR5ARF.js.map +1 -0
- package/dist/query-A34J7BGX.js +61 -0
- package/dist/query-A34J7BGX.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-5NPFULGD.js +26 -0
- package/dist/reddit-5NPFULGD.js.map +1 -0
- package/dist/refresh-FGXW4Y4X.js +94 -0
- package/dist/refresh-FGXW4Y4X.js.map +1 -0
- package/dist/release-OKZMC73N.js +60 -0
- package/dist/release-OKZMC73N.js.map +1 -0
- package/dist/relevant-pages-J76ZKNKF.js +99 -0
- package/dist/relevant-pages-J76ZKNKF.js.map +1 -0
- package/dist/remove-CA2J6ACH.js +50 -0
- package/dist/remove-CA2J6ACH.js.map +1 -0
- package/dist/remove-GOYW2G4R.js +48 -0
- package/dist/remove-GOYW2G4R.js.map +1 -0
- package/dist/reopen-XPKSOE6O.js +63 -0
- package/dist/reopen-XPKSOE6O.js.map +1 -0
- package/dist/rerun-QA6ISKVO.js +86 -0
- package/dist/rerun-QA6ISKVO.js.map +1 -0
- package/dist/research-FZ63UZTE.js +62 -0
- package/dist/research-FZ63UZTE.js.map +1 -0
- package/dist/research-YGQQ6CNG.js +262 -0
- package/dist/research-YGQQ6CNG.js.map +1 -0
- package/dist/reset-BGPZ4HMA.js +54 -0
- package/dist/reset-BGPZ4HMA.js.map +1 -0
- package/dist/reset-HTD6LCIT.js +54 -0
- package/dist/reset-HTD6LCIT.js.map +1 -0
- package/dist/resolve-NRDZ6N2B.js +121 -0
- package/dist/resolve-NRDZ6N2B.js.map +1 -0
- package/dist/retry-PF4BGKJV.js +60 -0
- package/dist/retry-PF4BGKJV.js.map +1 -0
- package/dist/retry-XL26JDAV.js +62 -0
- package/dist/retry-XL26JDAV.js.map +1 -0
- package/dist/retry-failed-BEFWRV4Z.js +45 -0
- package/dist/retry-failed-BEFWRV4Z.js.map +1 -0
- package/dist/run-3ZDGCCTH.js +61 -0
- package/dist/run-3ZDGCCTH.js.map +1 -0
- package/dist/run-EMJLI7LR.js +65 -0
- package/dist/run-EMJLI7LR.js.map +1 -0
- package/dist/scaffold-ad-QW75LLYR.js +1550 -0
- package/dist/scaffold-ad-QW75LLYR.js.map +1 -0
- package/dist/scaffold-static-ad-S3UOKLJ3.js +973 -0
- package/dist/scaffold-static-ad-S3UOKLJ3.js.map +1 -0
- package/dist/scaffold-video-3BJQOUAA.js +874 -0
- package/dist/scaffold-video-3BJQOUAA.js.map +1 -0
- package/dist/schedule-KQ7UIR3N.js +66 -0
- package/dist/schedule-KQ7UIR3N.js.map +1 -0
- package/dist/schedule-PKPNSISL.js +61 -0
- package/dist/schedule-PKPNSISL.js.map +1 -0
- package/dist/scheduled-agents-LP5LITA3.js +49 -0
- package/dist/scheduled-agents-LP5LITA3.js.map +1 -0
- package/dist/schema-B6J6VPTO.js +132 -0
- package/dist/schema-B6J6VPTO.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-6WNUKCMP.js +174 -0
- package/dist/search-6WNUKCMP.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-2V6CHATD.js +96 -0
- package/dist/select-2V6CHATD.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-XGZXW63I.js +188 -0
- package/dist/set-prompt-XGZXW63I.js.map +1 -0
- package/dist/setup-links-6H5ONDCQ.js +141 -0
- package/dist/setup-links-6H5ONDCQ.js.map +1 -0
- package/dist/{shared-6762QE6R.js → shared-QAMP7FZV.js} +8 -6
- package/dist/shared-QAMP7FZV.js.map +1 -0
- package/dist/shopify-D3GNV5O6.js +3715 -0
- package/dist/shopify-D3GNV5O6.js.map +1 -0
- package/dist/site-TBPERLY3.js +177 -0
- package/dist/site-TBPERLY3.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-JFQKTK2L.js +421 -0
- package/dist/sources-JFQKTK2L.js.map +1 -0
- package/dist/sources-Q3I6DDV7.js +30 -0
- package/dist/sources-Q3I6DDV7.js.map +1 -0
- package/dist/stale-4SERZW2D.js +66 -0
- package/dist/stale-4SERZW2D.js.map +1 -0
- package/dist/stats-GNILHSKK.js +34 -0
- package/dist/stats-GNILHSKK.js.map +1 -0
- package/dist/status-LIZWJYS4.js +62 -0
- package/dist/status-LIZWJYS4.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-ULKWDFXM.js +54 -0
- package/dist/sync-ULKWDFXM.js.map +1 -0
- package/dist/sync-definition-YTBLMLX2.js +55 -0
- package/dist/sync-definition-YTBLMLX2.js.map +1 -0
- package/dist/tag-manager-E7QTXBWQ.js +43 -0
- package/dist/tag-manager-E7QTXBWQ.js.map +1 -0
- package/dist/tags-4Q4I5GQJ.js +20 -0
- package/dist/tags-4Q4I5GQJ.js.map +1 -0
- package/dist/tags-AMEVAQZ4.js +26 -0
- package/dist/tags-AMEVAQZ4.js.map +1 -0
- package/dist/tags-DPLOLH3E.js +20 -0
- package/dist/tags-DPLOLH3E.js.map +1 -0
- package/dist/tags-LDHXONR3.js +224 -0
- package/dist/tags-LDHXONR3.js.map +1 -0
- package/dist/tags-UW3WJTAQ.js +20 -0
- package/dist/tags-UW3WJTAQ.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-BP6VJA7X.js +113 -0
- package/dist/targeting-criteria-BP6VJA7X.js.map +1 -0
- package/dist/targets-CQWO2UXD.js +102 -0
- package/dist/targets-CQWO2UXD.js.map +1 -0
- package/dist/templates-WZSTNRNZ.js +178 -0
- package/dist/templates-WZSTNRNZ.js.map +1 -0
- package/dist/testimonials-ETHSNWUH.js +32 -0
- package/dist/testimonials-ETHSNWUH.js.map +1 -0
- package/dist/themes-YU663LQH.js +94 -0
- package/dist/themes-YU663LQH.js.map +1 -0
- package/dist/top-companies-KTXHS472.js +108 -0
- package/dist/top-companies-KTXHS472.js.map +1 -0
- package/dist/translate-6QAJ5ZUU.js +600 -0
- package/dist/translate-6QAJ5ZUU.js.map +1 -0
- package/dist/triggers-4EDFLNGH.js +141 -0
- package/dist/triggers-4EDFLNGH.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-KY2OEKMD.js +67 -0
- package/dist/unlink-KY2OEKMD.js.map +1 -0
- package/dist/unstage-FHUG67RI.js +84 -0
- package/dist/unstage-FHUG67RI.js.map +1 -0
- package/dist/unstage-ZRLLCSQF.js +95 -0
- package/dist/unstage-ZRLLCSQF.js.map +1 -0
- package/dist/update-27LGM65V.js +63 -0
- package/dist/update-27LGM65V.js.map +1 -0
- package/dist/update-AIY46I2Q.js +155 -0
- package/dist/update-AIY46I2Q.js.map +1 -0
- package/dist/update-QYD2XZFM.js +142 -0
- package/dist/update-QYD2XZFM.js.map +1 -0
- package/dist/update-W2OSRNFO.js +98 -0
- package/dist/update-W2OSRNFO.js.map +1 -0
- package/dist/upload-JGBTSKGH.js +126 -0
- package/dist/upload-JGBTSKGH.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-QHGA42RP.js +130 -0
- package/dist/url-options-QHGA42RP.js.map +1 -0
- package/dist/url-params-NWSUHWRE.js +98 -0
- package/dist/url-params-NWSUHWRE.js.map +1 -0
- package/dist/use-U4HG2NF3.js +95 -0
- package/dist/use-U4HG2NF3.js.map +1 -0
- package/dist/validate-DOQ6AI62.js +91 -0
- package/dist/validate-DOQ6AI62.js.map +1 -0
- package/dist/variant-FOVE6URJ.js +338 -0
- package/dist/variant-FOVE6URJ.js.map +1 -0
- package/dist/videos-DP3VCSYG.js +39 -0
- package/dist/videos-DP3VCSYG.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-AFUIWPFU.js +140 -0
- package/dist/web-AFUIWPFU.js.map +1 -0
- package/dist/winners-SMMDN6LW.js +113 -0
- package/dist/winners-SMMDN6LW.js.map +1 -0
- package/dist/winning-ads-PCIJUYVA.js +84 -0
- package/dist/winning-ads-PCIJUYVA.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-N4FSGRVQ.js +743 -0
- package/dist/write-commands-N4FSGRVQ.js.map +1 -0
- package/dist/write-commands-Q4MQ3BGM.js +1015 -0
- package/dist/write-commands-Q4MQ3BGM.js.map +1 -0
- package/dist/x-AUOZJNWE.js +47 -0
- package/dist/x-AUOZJNWE.js.map +1 -0
- package/package.json +9 -2
- package/dist/chunk-FGHMWBUD.js +0 -9989
- package/dist/chunk-FGHMWBUD.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-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/{chunk-WLDM2TRF.js.map → chunk-TPXI2GCW.js.map} +0 -0
- /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-RXPMAJQI.js.map} +0 -0
- /package/dist/{shared-6762QE6R.js.map → customers-P6LLLJHK.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/cache-flag.ts"],"sourcesContent":["/**\n * One way to ask for a fresh read.\n *\n * Cached reads used to be bypassed by two different flags: `--no-cache` on the\n * Google, GA4, GSC, research and X families, `--skip-cache` on LinkedIn and\n * Meta. They named the two cache layers — `--no-cache` the CLI's own disk cache,\n * `--skip-cache` the server's — which is a distinction no caller has ever wanted\n * to make: a caller asking for fresh data wants fresh data, and the layer that\n * would have answered instead is an implementation detail of ours.\n *\n * The split was not survivable once an unrecognised flag started failing the\n * call instead of being dropped. The reports runtime appends `--no-cache` for\n * `?fresh=true` and cannot know which family a report reads, so every report row\n * backed by `ads linkedin analytics` or `ads meta insights` failed on refresh —\n * silently, as an empty row. So `--no-cache` is the name, on every command that\n * caches anything, and it bypasses both layers.\n */\n\nimport { declaredArg } from \"./output-flag.ts\";\nimport { commandFor, type IntrospectableCommand } from \"./unknown-flags.ts\";\n\n/**\n * The declaration LinkedIn and Meta share, so `baker schema` reads the same on\n * every command in the families this rename covers. The older families still\n * carry their own wording for the same flag.\n */\nexport const NO_CACHE_ARG = {\n type: \"boolean\",\n description: \"Skip cached results and read live from the platform (slower)\",\n required: false,\n} as const;\n\nconst LEGACY = \"--skip-cache\";\nconst CANONICAL = \"--no-cache\";\n/**\n * The spelling handed to the parser, and the reason this module exists twice\n * over. citty resolves a bare `--no-cache` to `cache: false` rather than filling\n * the `no-cache` arg the command declared, so every `args[\"no-cache\"]` read in\n * the CLI sees `undefined` and the flag does nothing at all — the same trap\n * `wantsAsync` in `ads/meta/insights.ts` records for `--no-async`. citty\n * registers `camelCase(name)` as an alias of every declared arg, and mri leaves\n * `--noCache` alone, so this spelling lands in `args[\"no-cache\"]` as intended.\n */\nconst PARSEABLE = \"--noCache\";\n\n/**\n * One token, respelled — and collapsed to the bare flag when it carried a value.\n *\n * `--no-cache=true` is not the same option with a value: mri's `--no-` branch\n * never splits on `=`, so the whole `cache=true` becomes the key and the flag is\n * dropped without a word. The bare flag says the same thing and survives, and\n * the one value mri read as off drops the flag rather than mis-stating it.\n */\nfunction respell(token: string, from: string, to: string): string[] {\n if (token === from) {\n return [to];\n }\n if (!token.startsWith(`${from}=`)) {\n return [token];\n }\n return token.slice(from.length + 1) === \"false\" ? [] : [to];\n}\n\n/**\n * The legacy spelling, translated before anything parses it.\n *\n * Sandboxes already running carry the old tool docs until their next sync, and\n * an agent that reads `--skip-cache` there would now have its call refused —\n * turning a rename into exactly the failure the rename exists to fix. Kept for\n * one release; the guard in `cache-flag-coverage.test.ts` is what stops the\n * second spelling coming back into the commands themselves.\n */\nexport function normalizeCacheFlag(argv: string[]): string[] {\n return rewriteBeforeDoubleDash(argv, (token) => respell(token, LEGACY, CANONICAL));\n}\n\n/**\n * `--no-cache` dropped where the command it addresses caches nothing.\n *\n * The reports runtime appends it to every read on `?fresh=true` and cannot know\n * which commands cache, so a report reading `winning-ads winners` failed on\n * every Refresh with \"not an option\" — and the same report answered fine\n * without it. A command with no cache already reads fresh, which is all the\n * flag asks for. Applied before `refuseUnknownFlags`, like `--output json`.\n */\nexport function cacheFlagForCommand(root: IntrospectableCommand, argv: string[]): string[] {\n if (!argv.includes(CANONICAL)) {\n return argv;\n }\n const command = commandFor(root, argv);\n if (!command || declaredArg(command, \"no-cache\")) {\n return argv;\n }\n return rewriteBeforeDoubleDash(argv, (token) => (token === CANONICAL ? [] : [token]));\n}\n\n/**\n * The canonical spelling in the form citty can actually parse.\n *\n * Deliberately applied after `refuseUnknownFlags`, not with the rewrite above:\n * that guard quotes the token back to the caller, and a command that does not\n * take this flag should be refused in the spelling the caller typed.\n */\nexport function cacheFlagForParser(argv: string[]): string[] {\n return rewriteBeforeDoubleDash(argv, (token) => respell(token, CANONICAL, PARSEABLE));\n}\n\n/**\n * Everything after `--` is the caller's own payload, not ours to rewrite — the\n * same boundary `unknown-flags.ts` refuses to read past.\n */\nfunction rewriteBeforeDoubleDash(argv: string[], rewrite: (token: string) => string[]): string[] {\n const end = argv.indexOf(\"--\");\n const limit = end === -1 ? argv.length : end;\n return argv.flatMap((token, index) => (index >= limit ? [token] : rewrite(token)));\n}\n"],"mappings":";;;;;;AA0BO,IAAM,eAAe;AAAA,EAC1B,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AACZ;AAEA,IAAM,SAAS;AACf,IAAM,YAAY;AAUlB,IAAM,YAAY;AAUlB,SAAS,QAAQ,OAAe,MAAc,IAAsB;AAClE,MAAI,UAAU,MAAM;AAClB,WAAO,CAAC,EAAE;AAAA,EACZ;AACA,MAAI,CAAC,MAAM,WAAW,GAAG,IAAI,GAAG,GAAG;AACjC,WAAO,CAAC,KAAK;AAAA,EACf;AACA,SAAO,MAAM,MAAM,KAAK,SAAS,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,EAAE;AAC5D;AAWO,SAAS,mBAAmB,MAA0B;AAC3D,SAAO,wBAAwB,MAAM,CAAC,UAAU,QAAQ,OAAO,QAAQ,SAAS,CAAC;AACnF;AAWO,SAAS,oBAAoB,MAA6B,MAA0B;AACzF,MAAI,CAAC,KAAK,SAAS,SAAS,GAAG;AAC7B,WAAO;AAAA,EACT;AACA,QAAM,UAAU,WAAW,MAAM,IAAI;AACrC,MAAI,CAAC,WAAW,YAAY,SAAS,UAAU,GAAG;AAChD,WAAO;AAAA,EACT;AACA,SAAO,wBAAwB,MAAM,CAAC,UAAW,UAAU,YAAY,CAAC,IAAI,CAAC,KAAK,CAAE;AACtF;AASO,SAAS,mBAAmB,MAA0B;AAC3D,SAAO,wBAAwB,MAAM,CAAC,UAAU,QAAQ,OAAO,WAAW,SAAS,CAAC;AACtF;AAMA,SAAS,wBAAwB,MAAgB,SAAgD;AAC/F,QAAM,MAAM,KAAK,QAAQ,IAAI;AAC7B,QAAM,QAAQ,QAAQ,KAAK,KAAK,SAAS;AACzC,SAAO,KAAK,QAAQ,CAAC,OAAO,UAAW,SAAS,QAAQ,CAAC,KAAK,IAAI,QAAQ,KAAK,CAAE;AACnF;","names":[]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// src/lib/repeatedFlags.ts
|
|
2
|
+
function repeatedFlagValues(rawArgs, flag) {
|
|
3
|
+
const long = `--${flag}`;
|
|
4
|
+
const inline = `${long}=`;
|
|
5
|
+
const values = [];
|
|
6
|
+
for (let i = 0; i < rawArgs.length; i++) {
|
|
7
|
+
const arg = rawArgs[i];
|
|
8
|
+
if (arg === "--") break;
|
|
9
|
+
if (arg === long) {
|
|
10
|
+
const value = rawArgs[i + 1];
|
|
11
|
+
if (value !== void 0 && !value.startsWith("-")) {
|
|
12
|
+
values.push(value);
|
|
13
|
+
i++;
|
|
14
|
+
}
|
|
15
|
+
} else if (arg?.startsWith(inline)) {
|
|
16
|
+
values.push(arg.slice(inline.length));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return values;
|
|
20
|
+
}
|
|
21
|
+
function repeatedValues(rawArgs, flag, parsed) {
|
|
22
|
+
if (rawArgs !== void 0) {
|
|
23
|
+
const fromLine = repeatedFlagValues(rawArgs, flag);
|
|
24
|
+
if (fromLine.length > 0) return fromLine;
|
|
25
|
+
}
|
|
26
|
+
if (Array.isArray(parsed)) return parsed.filter((v) => typeof v === "string");
|
|
27
|
+
return typeof parsed === "string" && parsed.length > 0 ? [parsed] : [];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export {
|
|
31
|
+
repeatedFlagValues,
|
|
32
|
+
repeatedValues
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=chunk-ERSX3MKH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/repeatedFlags.ts"],"sourcesContent":["/**\n * Every value a flag was given on the command line.\n *\n * citty declares no array arg type: it hands `util.parseArgs` its options\n * without `multiple: true`, so a repeated flag collapses to its LAST value.\n * `--param utm_source=linkedin --param utm_medium=paid` reaches `run` as the\n * single string `\"utm_medium=paid\"`, and code shaped like\n * `Array.isArray(raw) ? raw : [raw]` never takes its array branch.\n *\n * That is silent, and on a wholesale-replace write it is destructive: the\n * command reports success having staged one pair of the three it was given,\n * and publish then replaces the entity's whole parameter set with that one.\n * So every repeatable flag reads its values from `ctx.rawArgs` instead.\n *\n * Accepts both spellings (`--flag value` and `--flag=value`), stops at a bare\n * `--`, and ignores a trailing flag with no value — that is a malformed line,\n * not an empty value.\n */\nexport function repeatedFlagValues(rawArgs: readonly string[], flag: string): string[] {\n const long = `--${flag}`;\n const inline = `${long}=`;\n const values: string[] = [];\n for (let i = 0; i < rawArgs.length; i++) {\n const arg = rawArgs[i];\n if (arg === \"--\") break;\n if (arg === long) {\n const value = rawArgs[i + 1];\n if (value !== undefined && !value.startsWith(\"-\")) {\n values.push(value);\n i++;\n }\n } else if (arg?.startsWith(inline)) {\n values.push(arg.slice(inline.length));\n }\n }\n return values;\n}\n\n/**\n * The values of a repeatable flag, preferring the command line over the parsed\n * arg. `rawArgs` is absent in unit tests that call a payload builder directly\n * with an already-collected array, so the parsed value stays the fallback.\n */\nexport function repeatedValues(rawArgs: readonly string[] | undefined, flag: string, parsed: unknown): string[] {\n if (rawArgs !== undefined) {\n const fromLine = repeatedFlagValues(rawArgs, flag);\n if (fromLine.length > 0) return fromLine;\n }\n if (Array.isArray(parsed)) return parsed.filter((v): v is string => typeof v === \"string\");\n return typeof parsed === \"string\" && parsed.length > 0 ? [parsed] : [];\n}\n"],"mappings":";AAkBO,SAAS,mBAAmB,SAA4B,MAAwB;AACrF,QAAM,OAAO,KAAK,IAAI;AACtB,QAAM,SAAS,GAAG,IAAI;AACtB,QAAM,SAAmB,CAAC;AAC1B,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,MAAM,QAAQ,CAAC;AACrB,QAAI,QAAQ,KAAM;AAClB,QAAI,QAAQ,MAAM;AAChB,YAAM,QAAQ,QAAQ,IAAI,CAAC;AAC3B,UAAI,UAAU,UAAa,CAAC,MAAM,WAAW,GAAG,GAAG;AACjD,eAAO,KAAK,KAAK;AACjB;AAAA,MACF;AAAA,IACF,WAAW,KAAK,WAAW,MAAM,GAAG;AAClC,aAAO,KAAK,IAAI,MAAM,OAAO,MAAM,CAAC;AAAA,IACtC;AAAA,EACF;AACA,SAAO;AACT;AAOO,SAAS,eAAe,SAAwC,MAAc,QAA2B;AAC9G,MAAI,YAAY,QAAW;AACzB,UAAM,WAAW,mBAAmB,SAAS,IAAI;AACjD,QAAI,SAAS,SAAS,EAAG,QAAO;AAAA,EAClC;AACA,MAAI,MAAM,QAAQ,MAAM,EAAG,QAAO,OAAO,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AACzF,SAAO,OAAO,WAAW,YAAY,OAAO,SAAS,IAAI,CAAC,MAAM,IAAI,CAAC;AACvE;","names":[]}
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import {
|
|
2
|
+
handleLinkedinError,
|
|
3
|
+
resolveAccountIdArg
|
|
4
|
+
} from "./chunk-7F7MFMLI.js";
|
|
5
|
+
import {
|
|
6
|
+
adCopyHints,
|
|
7
|
+
booleanWordPositionalError,
|
|
8
|
+
capabilityFix
|
|
9
|
+
} from "./chunk-6I7SYEYN.js";
|
|
10
|
+
import {
|
|
11
|
+
withHints
|
|
12
|
+
} from "./chunk-D5FY4FAK.js";
|
|
13
|
+
import {
|
|
14
|
+
writeJsonEnvelope
|
|
15
|
+
} from "./chunk-BVM5IRZW.js";
|
|
16
|
+
import {
|
|
17
|
+
LINKEDIN_DRAFT_BATCH_MAX,
|
|
18
|
+
linkedinDraftOpInputSchema
|
|
19
|
+
} from "./chunk-SMIENBNX.js";
|
|
20
|
+
import {
|
|
21
|
+
apiPost
|
|
22
|
+
} from "./chunk-HREWXNTO.js";
|
|
23
|
+
import {
|
|
24
|
+
requireChatId
|
|
25
|
+
} from "./chunk-O6QKCJE4.js";
|
|
26
|
+
|
|
27
|
+
// src/commands/ads/linkedin/write-shared.ts
|
|
28
|
+
import { createHash } from "crypto";
|
|
29
|
+
import { readFileSync } from "fs";
|
|
30
|
+
var TOTAL_BUDGET_HELP = "Lifetime budget \u2014 on something already running it must exceed spend to date, or LinkedIn rejects it";
|
|
31
|
+
function bareAccountId(args) {
|
|
32
|
+
const raw = resolveAccountIdArg(args);
|
|
33
|
+
return raw.replace(/^urn:li:sponsoredAccount:/, "").replace(/^sponsoredAccount:/, "");
|
|
34
|
+
}
|
|
35
|
+
function failWriteValidation(message) {
|
|
36
|
+
writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
function loadJsonFileArg(path) {
|
|
40
|
+
if (typeof path !== "string" || path.length === 0) {
|
|
41
|
+
return {};
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
45
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
46
|
+
failWriteValidation(`${path} must contain a JSON object`);
|
|
47
|
+
}
|
|
48
|
+
return parsed;
|
|
49
|
+
} catch (err) {
|
|
50
|
+
if (err instanceof SyntaxError) {
|
|
51
|
+
failWriteValidation(`${path} is not valid JSON: ${err.message}`);
|
|
52
|
+
}
|
|
53
|
+
throw err;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function mergePayload(file, flags) {
|
|
57
|
+
const merged = { ...file };
|
|
58
|
+
for (const [key, value] of Object.entries(flags)) {
|
|
59
|
+
if (value !== void 0) {
|
|
60
|
+
merged[key] = value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return merged;
|
|
64
|
+
}
|
|
65
|
+
function loadPatchArg(args) {
|
|
66
|
+
const file = typeof args.file === "string" && args.file.length > 0 ? args.file : void 0;
|
|
67
|
+
const inline = typeof args.patch === "string" && args.patch.length > 0 ? args.patch : void 0;
|
|
68
|
+
if (Boolean(file) === Boolean(inline)) {
|
|
69
|
+
failWriteValidation("pass exactly one of --file <patch.json> or --patch '<json>'");
|
|
70
|
+
}
|
|
71
|
+
if (file) {
|
|
72
|
+
return loadJsonFileArg(file);
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
const parsed = JSON.parse(inline);
|
|
76
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
77
|
+
failWriteValidation("--patch must be a JSON object");
|
|
78
|
+
}
|
|
79
|
+
return parsed;
|
|
80
|
+
} catch (err) {
|
|
81
|
+
if (err instanceof SyntaxError) {
|
|
82
|
+
failWriteValidation(`--patch is not valid JSON: ${err.message}`);
|
|
83
|
+
}
|
|
84
|
+
throw err;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
function parseMoneyFlag(amount, currency, flag) {
|
|
88
|
+
if (amount === void 0 || amount === null || amount === "") {
|
|
89
|
+
return void 0;
|
|
90
|
+
}
|
|
91
|
+
if (currency === void 0 || currency === null || currency === "") {
|
|
92
|
+
return { amount: String(amount) };
|
|
93
|
+
}
|
|
94
|
+
if (typeof currency !== "string" || currency.length !== 3) {
|
|
95
|
+
failWriteValidation(`${flag} got an invalid --currency (expected a 3-letter code like EUR)`);
|
|
96
|
+
}
|
|
97
|
+
return { amount: String(amount), currencyCode: currency.toUpperCase() };
|
|
98
|
+
}
|
|
99
|
+
function parseDateFlag(value, flag) {
|
|
100
|
+
if (value === void 0 || value === null || value === "") {
|
|
101
|
+
return void 0;
|
|
102
|
+
}
|
|
103
|
+
const raw = String(value);
|
|
104
|
+
if (/^\d{10,}$/.test(raw)) {
|
|
105
|
+
return Number(raw);
|
|
106
|
+
}
|
|
107
|
+
const parsed = Date.parse(raw);
|
|
108
|
+
if (Number.isNaN(parsed)) {
|
|
109
|
+
failWriteValidation(`${flag} must be an ISO date (2026-07-10) or epoch milliseconds`);
|
|
110
|
+
}
|
|
111
|
+
return parsed;
|
|
112
|
+
}
|
|
113
|
+
function parseOnOffFlag(value, flag) {
|
|
114
|
+
if (value === void 0 || value === null || value === "") {
|
|
115
|
+
return void 0;
|
|
116
|
+
}
|
|
117
|
+
const raw = String(value).toLowerCase();
|
|
118
|
+
if (raw === "on" || raw === "true") {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
if (raw === "off" || raw === "false") {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
failWriteValidation(`${flag} must be on|off`);
|
|
125
|
+
}
|
|
126
|
+
function parseLocaleFlag(value) {
|
|
127
|
+
if (value === void 0 || value === null || value === "") {
|
|
128
|
+
return void 0;
|
|
129
|
+
}
|
|
130
|
+
const match = /^([a-z]{2})[_-]([A-Za-z]{2})$/.exec(String(value));
|
|
131
|
+
if (!match) {
|
|
132
|
+
failWriteValidation("--locale must look like en_US (language_COUNTRY)");
|
|
133
|
+
}
|
|
134
|
+
return { language: match[1], country: match[2].toUpperCase() };
|
|
135
|
+
}
|
|
136
|
+
function loadTargetingFileArg(path) {
|
|
137
|
+
if (typeof path !== "string" || path.length === 0) {
|
|
138
|
+
return void 0;
|
|
139
|
+
}
|
|
140
|
+
const parsed = loadJsonFileArg(path);
|
|
141
|
+
const criteria = parsed.targetingCriteria ?? parsed;
|
|
142
|
+
if (!criteria.include) {
|
|
143
|
+
failWriteValidation(
|
|
144
|
+
`${path} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return criteria;
|
|
148
|
+
}
|
|
149
|
+
function sha256Lower(value) {
|
|
150
|
+
return createHash("sha256").update(value.trim().toLowerCase()).digest("hex");
|
|
151
|
+
}
|
|
152
|
+
function parseCsvLine(line) {
|
|
153
|
+
const cells = [];
|
|
154
|
+
let current = "";
|
|
155
|
+
let inQuotes = false;
|
|
156
|
+
for (let i = 0; i < line.length; i++) {
|
|
157
|
+
const char = line[i];
|
|
158
|
+
if (inQuotes) {
|
|
159
|
+
if (char === '"' && line[i + 1] === '"') {
|
|
160
|
+
current += '"';
|
|
161
|
+
i++;
|
|
162
|
+
} else if (char === '"') {
|
|
163
|
+
inQuotes = false;
|
|
164
|
+
} else {
|
|
165
|
+
current += char;
|
|
166
|
+
}
|
|
167
|
+
} else if (char === '"') {
|
|
168
|
+
inQuotes = true;
|
|
169
|
+
} else if (char === ",") {
|
|
170
|
+
cells.push(current);
|
|
171
|
+
current = "";
|
|
172
|
+
} else {
|
|
173
|
+
current += char;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
cells.push(current);
|
|
177
|
+
return cells.map((cell) => cell.trim());
|
|
178
|
+
}
|
|
179
|
+
function parseListFileArg(path, maxRows) {
|
|
180
|
+
if (typeof path !== "string" || path.length === 0) {
|
|
181
|
+
return void 0;
|
|
182
|
+
}
|
|
183
|
+
const raw = readFileSync(path, "utf8");
|
|
184
|
+
const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
185
|
+
if (lines.length < 2) {
|
|
186
|
+
failWriteValidation(`${path} needs a header row and at least one data row`);
|
|
187
|
+
}
|
|
188
|
+
const columns = parseCsvLine(lines[0]).map((column) => column.trim());
|
|
189
|
+
const rows = [];
|
|
190
|
+
for (const line of lines.slice(1)) {
|
|
191
|
+
const cells = parseCsvLine(line);
|
|
192
|
+
const row = {};
|
|
193
|
+
columns.forEach((column, index) => {
|
|
194
|
+
const value = cells[index] ?? "";
|
|
195
|
+
if (!value) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
row[column] = column.toLowerCase() === "email" ? sha256Lower(value) : value;
|
|
199
|
+
});
|
|
200
|
+
if (Object.keys(row).length > 0) {
|
|
201
|
+
rows.push(row);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (rows.length > maxRows) {
|
|
205
|
+
failWriteValidation(`${path} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
|
|
206
|
+
}
|
|
207
|
+
return { columns, rows };
|
|
208
|
+
}
|
|
209
|
+
function failPreflight(fields) {
|
|
210
|
+
writeJsonEnvelope({
|
|
211
|
+
ok: false,
|
|
212
|
+
error: {
|
|
213
|
+
code: "VALIDATION_ERROR",
|
|
214
|
+
message: fields.map((field) => field.path ? `${field.path}: ${field.message}` : field.message).join("; "),
|
|
215
|
+
fields,
|
|
216
|
+
fix: capabilityFix("linkedin-ads")
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
process.exit(1);
|
|
220
|
+
}
|
|
221
|
+
var BATCH_NUDGE = "This command takes several ids at once \u2014 pass them comma-separated or with --ids-file instead of one call per id.";
|
|
222
|
+
function batchNudge(data) {
|
|
223
|
+
return data.sameKindStaged === void 0 ? [] : [BATCH_NUDGE];
|
|
224
|
+
}
|
|
225
|
+
async function stageOp(raw, hints) {
|
|
226
|
+
const preflight = linkedinDraftOpInputSchema.safeParse(raw);
|
|
227
|
+
if (!preflight.success) {
|
|
228
|
+
failPreflight(preflight.error.issues.map((issue) => ({ path: issue.path.join("."), message: issue.message })));
|
|
229
|
+
}
|
|
230
|
+
try {
|
|
231
|
+
const chatId = requireChatId();
|
|
232
|
+
const response = await apiPost("/api/ads/linkedin/draft/stage", {
|
|
233
|
+
chatId,
|
|
234
|
+
op: preflight.data
|
|
235
|
+
});
|
|
236
|
+
const allHints = [...batchNudge(response.data), ...hints ?? [], ...await adCopyHints(preflight.data)];
|
|
237
|
+
writeJsonEnvelope(withHints(response, allHints));
|
|
238
|
+
} catch (err) {
|
|
239
|
+
handleLinkedinError(err);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
async function stageLinkedinOps(rawOps, hints) {
|
|
243
|
+
if (rawOps.length === 1 && rawOps[0]) {
|
|
244
|
+
await stageOp(rawOps[0], hints);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const ops = [];
|
|
248
|
+
for (const [index, raw] of rawOps.entries()) {
|
|
249
|
+
const preflight = linkedinDraftOpInputSchema.safeParse(raw);
|
|
250
|
+
if (!preflight.success) {
|
|
251
|
+
failPreflight(
|
|
252
|
+
preflight.error.issues.map((issue) => ({
|
|
253
|
+
path: `ops[${index}]${issue.path.length > 0 ? `.${issue.path.join(".")}` : ""}`,
|
|
254
|
+
message: issue.message
|
|
255
|
+
}))
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
ops.push(preflight.data);
|
|
259
|
+
}
|
|
260
|
+
try {
|
|
261
|
+
const chatId = requireChatId();
|
|
262
|
+
const response = await apiPost("/api/ads/linkedin/draft/stage-batch", { chatId, ops });
|
|
263
|
+
const allHints = [...hints ?? [], ...await adCopyHints(ops)];
|
|
264
|
+
writeJsonEnvelope(withHints(response, allHints));
|
|
265
|
+
} catch (err) {
|
|
266
|
+
handleLinkedinError(err);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
async function stageStatusChange(input) {
|
|
270
|
+
const payload = input.kind === "creative.update" ? { intendedStatus: input.status } : { status: input.status };
|
|
271
|
+
await stageLinkedinOps(
|
|
272
|
+
input.targets.map((target) => ({ kind: input.kind, accountId: input.accountId, target, payload }))
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
function requireTarget(args, entity) {
|
|
276
|
+
const inverted = booleanWordPositionalError(args, entity);
|
|
277
|
+
if (inverted !== void 0) {
|
|
278
|
+
failWriteValidation(inverted);
|
|
279
|
+
}
|
|
280
|
+
const positionals = readPositionals(args);
|
|
281
|
+
const target = args.id ?? args.target ?? args.ref ?? positionals[0];
|
|
282
|
+
if (typeof target !== "string" || target.length === 0) {
|
|
283
|
+
failWriteValidation(`pass the ${entity} id or URN as the positional argument`);
|
|
284
|
+
}
|
|
285
|
+
if (positionals.length > 1 || splitIdList(target).length > 1) {
|
|
286
|
+
failWriteValidation(
|
|
287
|
+
`this command takes one ${entity} id \u2014 run it once per id. Only pause/resume/archive and 'creatives update' accept several ids in one call.`
|
|
288
|
+
);
|
|
289
|
+
}
|
|
290
|
+
return target;
|
|
291
|
+
}
|
|
292
|
+
function readPositionals(args) {
|
|
293
|
+
if (!Array.isArray(args._)) {
|
|
294
|
+
return [];
|
|
295
|
+
}
|
|
296
|
+
return args._.filter((value) => typeof value === "string" && value.length > 0);
|
|
297
|
+
}
|
|
298
|
+
function splitIdList(raw) {
|
|
299
|
+
return raw.split(",").map((id) => id.trim()).filter(Boolean);
|
|
300
|
+
}
|
|
301
|
+
function idsFileEntries(path) {
|
|
302
|
+
if (typeof path !== "string" || path.length === 0) {
|
|
303
|
+
return [];
|
|
304
|
+
}
|
|
305
|
+
return readFileSync(path, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0 && !line.startsWith("#")).flatMap(splitIdList);
|
|
306
|
+
}
|
|
307
|
+
function requireTargets(args, entity) {
|
|
308
|
+
const positionals = readPositionals(args);
|
|
309
|
+
const named = [args.id, args.target, args.ref].filter(
|
|
310
|
+
(value) => typeof value === "string" && value.length > 0
|
|
311
|
+
);
|
|
312
|
+
const fromArgs = positionals.length > 0 ? positionals : named;
|
|
313
|
+
const targets = [.../* @__PURE__ */ new Set([...fromArgs.flatMap(splitIdList), ...idsFileEntries(args["ids-file"])])];
|
|
314
|
+
if (targets.length === 0) {
|
|
315
|
+
failWriteValidation(
|
|
316
|
+
`pass the ${entity} id or URN as the positional argument (comma-separated for several), or --ids-file <path>`
|
|
317
|
+
);
|
|
318
|
+
}
|
|
319
|
+
if (targets.length > LINKEDIN_DRAFT_BATCH_MAX) {
|
|
320
|
+
failWriteValidation(
|
|
321
|
+
`${targets.length} ids exceeds the batch limit of ${LINKEDIN_DRAFT_BATCH_MAX} \u2014 split the list`
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
return targets;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export {
|
|
328
|
+
TOTAL_BUDGET_HELP,
|
|
329
|
+
bareAccountId,
|
|
330
|
+
failWriteValidation,
|
|
331
|
+
loadJsonFileArg,
|
|
332
|
+
mergePayload,
|
|
333
|
+
loadPatchArg,
|
|
334
|
+
parseMoneyFlag,
|
|
335
|
+
parseDateFlag,
|
|
336
|
+
parseOnOffFlag,
|
|
337
|
+
parseLocaleFlag,
|
|
338
|
+
loadTargetingFileArg,
|
|
339
|
+
parseListFileArg,
|
|
340
|
+
stageOp,
|
|
341
|
+
stageLinkedinOps,
|
|
342
|
+
stageStatusChange,
|
|
343
|
+
requireTarget,
|
|
344
|
+
requireTargets
|
|
345
|
+
};
|
|
346
|
+
//# sourceMappingURL=chunk-F3IJSR7O.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/ads/linkedin/write-shared.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\nimport { readFileSync } from \"node:fs\";\nimport {\n LINKEDIN_DRAFT_BATCH_MAX,\n type LinkedinDraftStageBatchResponse,\n type LinkedinDraftStageResponse,\n linkedinDraftOpInputSchema,\n} from \"@baker/api\";\nimport { apiPost } from \"../../../client.ts\";\nimport { requireChatId } from \"../../../env.ts\";\nimport { capabilityFix } from \"../../capabilities/fix.ts\";\nimport { booleanWordPositionalError } from \"../boolean-word-positional.ts\";\nimport { adCopyHints } from \"../copy-hints.ts\";\nimport { withHints } from \"../hints.ts\";\nimport { writeJsonEnvelope } from \"../output.ts\";\nimport { handleLinkedinError, resolveAccountIdArg } from \"./shared.ts\";\n\n/**\n * Shared plumbing for the staged write commands. Writes NEVER hit LinkedIn\n * directly: every command stages an op against this chat's draft\n * (`/api/ads/linkedin/draft/stage`), the dashboard shows it as a pending\n * LinkedIn change, and it applies when the chat is published.\n */\n\n/**\n * LinkedIn rejects a lifetime budget at or below what the entity has already\n * spent, so the flag needs the constraint wherever it is offered — the same\n * text on every surface (`--help` and `baker schema`) so the two can't drift.\n */\nexport const TOTAL_BUDGET_HELP =\n \"Lifetime budget — on something already running it must exceed spend to date, or LinkedIn rejects it\";\n\nexport function bareAccountId(args: Record<string, unknown>): string {\n const raw = resolveAccountIdArg(args);\n return raw.replace(/^urn:li:sponsoredAccount:/, \"\").replace(/^sponsoredAccount:/, \"\");\n}\n\nexport function failWriteValidation(message: string): never {\n writeJsonEnvelope({ ok: false, error: { code: \"VALIDATION_ERROR\", message } });\n process.exit(1);\n}\n\nexport function loadJsonFileArg(path: unknown): Record<string, unknown> {\n if (typeof path !== \"string\" || path.length === 0) {\n return {};\n }\n try {\n const parsed = JSON.parse(readFileSync(path, \"utf8\")) as unknown;\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n failWriteValidation(`${path} must contain a JSON object`);\n }\n return parsed as Record<string, unknown>;\n } catch (err) {\n if (err instanceof SyntaxError) {\n failWriteValidation(`${path} is not valid JSON: ${err.message}`);\n }\n throw err;\n }\n}\n\n/** Flags override file keys — the file is the base, flags are the overrides. */\nexport function mergePayload(file: Record<string, unknown>, flags: Record<string, unknown>): Record<string, unknown> {\n const merged: Record<string, unknown> = { ...file };\n for (const [key, value] of Object.entries(flags)) {\n if (value !== undefined) {\n merged[key] = value;\n }\n }\n return merged;\n}\n\n/**\n * The `draft amend` patch: exactly one of `--file <path>` (JSON file) or `--patch '<json>'`\n * (inline string), and it must parse to a JSON object — RFC-7386 merge-patch needs an object to\n * merge, and a stray array/scalar would silently no-op or replace the whole payload.\n */\nexport function loadPatchArg(args: Record<string, unknown>): Record<string, unknown> {\n const file = typeof args.file === \"string\" && args.file.length > 0 ? args.file : undefined;\n const inline = typeof args.patch === \"string\" && args.patch.length > 0 ? args.patch : undefined;\n if (Boolean(file) === Boolean(inline)) {\n failWriteValidation(\"pass exactly one of --file <patch.json> or --patch '<json>'\");\n }\n if (file) {\n return loadJsonFileArg(file);\n }\n try {\n const parsed = JSON.parse(inline as string) as unknown;\n if (parsed === null || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n failWriteValidation(\"--patch must be a JSON object\");\n }\n return parsed as Record<string, unknown>;\n } catch (err) {\n if (err instanceof SyntaxError) {\n failWriteValidation(`--patch is not valid JSON: ${err.message}`);\n }\n throw err;\n }\n}\n\nexport function parseMoneyFlag(\n amount: unknown,\n currency: unknown,\n flag: string,\n): { amount: string; currencyCode?: string } | undefined {\n if (amount === undefined || amount === null || amount === \"\") {\n return undefined;\n }\n if (currency === undefined || currency === null || currency === \"\") {\n // LinkedIn ad accounts are single-currency — the backend fills it in.\n return { amount: String(amount) };\n }\n if (typeof currency !== \"string\" || currency.length !== 3) {\n failWriteValidation(`${flag} got an invalid --currency (expected a 3-letter code like EUR)`);\n }\n return { amount: String(amount), currencyCode: currency.toUpperCase() };\n}\n\n/** Accepts ISO dates (2026-07-10), ISO datetimes, or epoch millis. */\nexport function parseDateFlag(value: unknown, flag: string): number | undefined {\n if (value === undefined || value === null || value === \"\") {\n return undefined;\n }\n const raw = String(value);\n if (/^\\d{10,}$/.test(raw)) {\n return Number(raw);\n }\n const parsed = Date.parse(raw);\n if (Number.isNaN(parsed)) {\n failWriteValidation(`${flag} must be an ISO date (2026-07-10) or epoch milliseconds`);\n }\n return parsed;\n}\n\nexport function parseOnOffFlag(value: unknown, flag: string): boolean | undefined {\n if (value === undefined || value === null || value === \"\") {\n return undefined;\n }\n const raw = String(value).toLowerCase();\n if (raw === \"on\" || raw === \"true\") {\n return true;\n }\n if (raw === \"off\" || raw === \"false\") {\n return false;\n }\n failWriteValidation(`${flag} must be on|off`);\n}\n\nexport function parseLocaleFlag(value: unknown): { country: string; language: string } | undefined {\n if (value === undefined || value === null || value === \"\") {\n return undefined;\n }\n const match = /^([a-z]{2})[_-]([A-Za-z]{2})$/.exec(String(value));\n if (!match) {\n failWriteValidation(\"--locale must look like en_US (language_COUNTRY)\");\n }\n return { language: match[1] as string, country: (match[2] as string).toUpperCase() };\n}\n\nexport function loadTargetingFileArg(path: unknown): Record<string, unknown> | undefined {\n if (typeof path !== \"string\" || path.length === 0) {\n return undefined;\n }\n const parsed = loadJsonFileArg(path);\n // Accept either the bare criteria object or a { targetingCriteria } wrapper.\n const criteria = (parsed.targetingCriteria as Record<string, unknown> | undefined) ?? parsed;\n if (!criteria.include) {\n failWriteValidation(\n `${path} must contain targeting criteria with an \"include\" block (see baker schema ads.linkedin.campaigns.create)`,\n );\n }\n return criteria;\n}\n\nfunction sha256Lower(value: string): string {\n return createHash(\"sha256\").update(value.trim().toLowerCase()).digest(\"hex\");\n}\n\nfunction parseCsvLine(line: string): string[] {\n const cells: string[] = [];\n let current = \"\";\n let inQuotes = false;\n for (let i = 0; i < line.length; i++) {\n const char = line[i];\n if (inQuotes) {\n if (char === '\"' && line[i + 1] === '\"') {\n current += '\"';\n i++;\n } else if (char === '\"') {\n inQuotes = false;\n } else {\n current += char;\n }\n } else if (char === '\"') {\n inQuotes = true;\n } else if (char === \",\") {\n cells.push(current);\n current = \"\";\n } else {\n current += char;\n }\n }\n cells.push(current);\n return cells.map((cell) => cell.trim());\n}\n\nexport interface ParsedList {\n columns: string[];\n rows: Array<Record<string, string>>;\n}\n\n/**\n * Parses a header-first CSV into row objects. Email columns are SHA-256\n * hashed here so raw addresses never leave the machine or sit in the draft.\n */\nexport function parseListFileArg(path: unknown, maxRows: number): ParsedList | undefined {\n if (typeof path !== \"string\" || path.length === 0) {\n return undefined;\n }\n const raw = readFileSync(path, \"utf8\");\n const lines = raw.split(/\\r?\\n/).filter((line) => line.trim().length > 0);\n if (lines.length < 2) {\n failWriteValidation(`${path} needs a header row and at least one data row`);\n }\n const columns = parseCsvLine(lines[0] as string).map((column) => column.trim());\n const rows: Array<Record<string, string>> = [];\n for (const line of lines.slice(1)) {\n const cells = parseCsvLine(line);\n const row: Record<string, string> = {};\n columns.forEach((column, index) => {\n const value = cells[index] ?? \"\";\n if (!value) {\n return;\n }\n row[column] = column.toLowerCase() === \"email\" ? sha256Lower(value) : value;\n });\n if (Object.keys(row).length > 0) {\n rows.push(row);\n }\n }\n if (rows.length > maxRows) {\n failWriteValidation(`${path} has ${rows.length} rows — the inline limit is ${maxRows}. Split the list.`);\n }\n return { columns, rows };\n}\n\ninterface StageEnvelope extends Record<string, unknown> {\n ok: true;\n data: LinkedinDraftStageResponse;\n}\n\n/** Structured preflight failure — the agent learns WHICH field (and, in a batch, which op) is wrong. */\nfunction failPreflight(fields: Array<{ path: string; message: string }>): never {\n writeJsonEnvelope({\n ok: false,\n error: {\n code: \"VALIDATION_ERROR\",\n message: fields.map((field) => (field.path ? `${field.path}: ${field.message}` : field.message)).join(\"; \"),\n fields,\n fix: capabilityFix(\"linkedin-ads\"),\n },\n });\n process.exit(1);\n}\n\n/**\n * The agent is staging one id per call for a kind it has already staged in this\n * draft — the exact loop these commands' id lists exist to replace.\n */\nconst BATCH_NUDGE =\n \"This command takes several ids at once — pass them comma-separated or with --ids-file instead of one call per id.\";\n\nfunction batchNudge(data: LinkedinDraftStageResponse): string[] {\n return data.sameKindStaged === undefined ? [] : [BATCH_NUDGE];\n}\n\n/**\n * Preflight-validates the op against the shared `@baker/api` contract (same\n * schema the backend enforces), then stages it. Prints the staged envelope —\n * ref, mode (always `live`: publishing reaches the real ad account), summary,\n * warnings.\n */\nexport async function stageOp(raw: Record<string, unknown>, hints?: string[]): Promise<void> {\n const preflight = linkedinDraftOpInputSchema.safeParse(raw);\n if (!preflight.success) {\n failPreflight(preflight.error.issues.map((issue) => ({ path: issue.path.join(\".\"), message: issue.message })));\n }\n try {\n const chatId = requireChatId();\n const response = await apiPost<StageEnvelope>(\"/api/ads/linkedin/draft/stage\", {\n chatId,\n op: preflight.data,\n });\n const allHints = [...batchNudge(response.data), ...(hints ?? []), ...(await adCopyHints(preflight.data))];\n writeJsonEnvelope(withHints(response, allHints));\n } catch (err) {\n handleLinkedinError(err);\n }\n}\n\ninterface StageBatchEnvelope extends Record<string, unknown> {\n ok: true;\n data: LinkedinDraftStageBatchResponse;\n}\n\n/**\n * Stage several ops as ONE request (`/stage-batch`) — all-or-nothing on the\n * backend, one rate-limit hit instead of one per id. A single op falls through to\n * the plain stage path so its envelope, its amend behaviour and its hints stay\n * exactly as before.\n */\nexport async function stageLinkedinOps(rawOps: Array<Record<string, unknown>>, hints?: string[]): Promise<void> {\n if (rawOps.length === 1 && rawOps[0]) {\n await stageOp(rawOps[0], hints);\n return;\n }\n const ops: unknown[] = [];\n for (const [index, raw] of rawOps.entries()) {\n const preflight = linkedinDraftOpInputSchema.safeParse(raw);\n if (!preflight.success) {\n failPreflight(\n preflight.error.issues.map((issue) => ({\n path: `ops[${index}]${issue.path.length > 0 ? `.${issue.path.join(\".\")}` : \"\"}`,\n message: issue.message,\n })),\n );\n }\n ops.push(preflight.data);\n }\n try {\n const chatId = requireChatId();\n const response = await apiPost<StageBatchEnvelope>(\"/api/ads/linkedin/draft/stage-batch\", { chatId, ops });\n const allHints = [...(hints ?? []), ...(await adCopyHints(ops))];\n writeJsonEnvelope(withHints(response, allHints));\n } catch (err) {\n handleLinkedinError(err);\n }\n}\n\nexport async function stageStatusChange(input: {\n kind: \"campaignGroup.update\" | \"campaign.update\" | \"creative.update\";\n accountId: string;\n targets: string[];\n status: \"ACTIVE\" | \"PAUSED\" | \"ARCHIVED\";\n}): Promise<void> {\n const payload = input.kind === \"creative.update\" ? { intendedStatus: input.status } : { status: input.status };\n await stageLinkedinOps(\n input.targets.map((target) => ({ kind: input.kind, accountId: input.accountId, target, payload })),\n );\n}\n\n/**\n * Reads the target from whichever positional the command declared. Commands\n * name it `id` (entity writes) or `ref` (draft show/amend), and citty also\n * leaves every positional in `args._` — so we accept all three rather than\n * making the receipt depend on one command's arg name.\n *\n * `--flag false` is refused BEFORE the one-id check below, which would otherwise\n * blame the stray word on a second id: on `campaigns url-params 123456 --clear\n * false` that sends the agent back with `--clear` alone, which is TRUE again and\n * wipes every tracking parameter on a live ad set.\n */\nexport function requireTarget(args: Record<string, unknown>, entity: string): string {\n const inverted = booleanWordPositionalError(args, entity);\n if (inverted !== undefined) {\n failWriteValidation(inverted);\n }\n const positionals = readPositionals(args);\n const target = args.id ?? args.target ?? args.ref ?? positionals[0];\n if (typeof target !== \"string\" || target.length === 0) {\n failWriteValidation(`pass the ${entity} id or URN as the positional argument`);\n }\n // This command applies one payload to one id. Accepting the first of several and\n // dropping the rest would report success for work it never staged, so say so.\n if (positionals.length > 1 || splitIdList(target).length > 1) {\n failWriteValidation(\n `this command takes one ${entity} id — run it once per id. Only pause/resume/archive and 'creatives update' accept several ids in one call.`,\n );\n }\n return target;\n}\n\n/** Every positional citty left in `_`, as strings. Numeric ids arrive as strings via `node:util parseArgs`. */\nfunction readPositionals(args: Record<string, unknown>): string[] {\n if (!Array.isArray(args._)) {\n return [];\n }\n return args._.filter((value): value is string => typeof value === \"string\" && value.length > 0);\n}\n\n/** Ids in the positional: `123,456` or `urn:li:sponsoredCreative:1, urn:…:2` (URNs never contain commas). */\nfunction splitIdList(raw: string): string[] {\n return raw\n .split(\",\")\n .map((id) => id.trim())\n .filter(Boolean);\n}\n\n/**\n * `--ids-file` lines: one id per line, or comma-separated on a line — the agent\n * writes whichever is convenient. Blank lines and `#` comments are skipped.\n */\nfunction idsFileEntries(path: unknown): string[] {\n if (typeof path !== \"string\" || path.length === 0) {\n return [];\n }\n return readFileSync(path, \"utf8\")\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter((line) => line.length > 0 && !line.startsWith(\"#\"))\n .flatMap(splitIdList);\n}\n\n/**\n * Every id a write command was invoked with: **all** positionals (each of which may\n * itself be comma-separated) plus `--ids-file` lines, deduped in first-seen order.\n * One id stages exactly as before; several stage as one batch.\n *\n * All positionals, not just the first: an agent writing `creatives pause 111 222 333`\n * — space-separated, as most CLIs accept — used to stage one op and be told `ok: true`,\n * so it believed three ads were paused.\n */\nexport function requireTargets(args: Record<string, unknown>, entity: string): string[] {\n // `args._` is the superset: citty copies the FIRST positional into the declared\n // arg (`id`/`ref`) but leaves every positional in `_`. Reading the named arg alone\n // is what dropped ids 2..n. The named arg is the fallback for a command that ever\n // declares its id as a flag instead, where `_` would be empty.\n const positionals = readPositionals(args);\n const named = [args.id, args.target, args.ref].filter(\n (value): value is string => typeof value === \"string\" && value.length > 0,\n );\n const fromArgs = positionals.length > 0 ? positionals : named;\n const targets = [...new Set([...fromArgs.flatMap(splitIdList), ...idsFileEntries(args[\"ids-file\"])])];\n if (targets.length === 0) {\n failWriteValidation(\n `pass the ${entity} id or URN as the positional argument (comma-separated for several), or --ids-file <path>`,\n );\n }\n if (targets.length > LINKEDIN_DRAFT_BATCH_MAX) {\n failWriteValidation(\n `${targets.length} ids exceeds the batch limit of ${LINKEDIN_DRAFT_BATCH_MAX} — split the list`,\n );\n }\n return targets;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
// src/commands/videos/videoPlatforms.ts
|
|
2
|
+
var PLATFORM_DOMAINS = {
|
|
3
|
+
youtube: ["youtube.com", "youtu.be"],
|
|
4
|
+
instagram: ["instagram.com", "ddinstagram.com"],
|
|
5
|
+
tiktok: ["tiktok.com"],
|
|
6
|
+
twitter: ["twitter.com", "x.com", "vxtwitter.com", "fixvx.com"],
|
|
7
|
+
facebook: ["facebook.com", "fb.watch", "fb.com"],
|
|
8
|
+
linkedin: ["linkedin.com", "lnkd.in"],
|
|
9
|
+
reddit: ["reddit.com", "redd.it"],
|
|
10
|
+
vimeo: ["vimeo.com"],
|
|
11
|
+
dailymotion: ["dailymotion.com", "dai.ly"],
|
|
12
|
+
twitch: ["twitch.tv"],
|
|
13
|
+
bluesky: ["bsky.app"],
|
|
14
|
+
bilibili: ["bilibili.com", "bilibili.tv", "b23.tv"],
|
|
15
|
+
vk: ["vk.com", "vk.ru", "vkvideo.ru"],
|
|
16
|
+
ok: ["ok.ru"],
|
|
17
|
+
pinterest: ["pinterest.com", "pin.it"],
|
|
18
|
+
tumblr: ["tumblr.com"],
|
|
19
|
+
snapchat: ["snapchat.com"],
|
|
20
|
+
loom: ["loom.com"],
|
|
21
|
+
streamable: ["streamable.com"],
|
|
22
|
+
newgrounds: ["newgrounds.com"],
|
|
23
|
+
rutube: ["rutube.ru"]
|
|
24
|
+
};
|
|
25
|
+
var VIDEO_PLATFORMS = Object.keys(PLATFORM_DOMAINS);
|
|
26
|
+
function platformFromUrl(rawUrl) {
|
|
27
|
+
let host;
|
|
28
|
+
try {
|
|
29
|
+
host = new URL(rawUrl).hostname.toLowerCase();
|
|
30
|
+
} catch {
|
|
31
|
+
return "url";
|
|
32
|
+
}
|
|
33
|
+
for (const [platform, domains] of Object.entries(PLATFORM_DOMAINS)) {
|
|
34
|
+
if (domains.some((domain) => host === domain || host.endsWith(`.${domain}`))) {
|
|
35
|
+
return platform;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return "url";
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// src/commands/videos/ingestUrl.ts
|
|
42
|
+
var MAX_VIDEO_INGEST_BYTES = 16 * 1024 * 1024 * 1024;
|
|
43
|
+
var MAX_VIDEO_INGEST_SECONDS = 3 * 60 * 60;
|
|
44
|
+
function refuseByDuration(seconds, maxSeconds) {
|
|
45
|
+
if (seconds === void 0 || seconds <= maxSeconds) return null;
|
|
46
|
+
return `That video is ${(seconds / 3600).toFixed(1)} hours long \u2014 the limit is ${Math.round(maxSeconds / 3600)} hours.`;
|
|
47
|
+
}
|
|
48
|
+
var DOWNLOAD_TIMEOUT_FLOOR_MS = 10 * 60 * 1e3;
|
|
49
|
+
var DOWNLOAD_TIMEOUT_CEILING_MS = 15 * 60 * 1e3;
|
|
50
|
+
function downloadTimeoutMs(seconds) {
|
|
51
|
+
if (seconds === void 0) return DOWNLOAD_TIMEOUT_FLOOR_MS;
|
|
52
|
+
const scaled = seconds * 2 * 1e3;
|
|
53
|
+
return Math.min(Math.max(scaled, DOWNLOAD_TIMEOUT_FLOOR_MS), DOWNLOAD_TIMEOUT_CEILING_MS);
|
|
54
|
+
}
|
|
55
|
+
var DIRECT_MEDIA_EXTENSIONS = [".mp4", ".mov", ".webm", ".m4v", ".mkv", ".avi"];
|
|
56
|
+
function isDirectMediaUrl(rawUrl) {
|
|
57
|
+
const pathname = safePathname(rawUrl);
|
|
58
|
+
return DIRECT_MEDIA_EXTENSIONS.some((ext) => pathname.endsWith(ext));
|
|
59
|
+
}
|
|
60
|
+
function resolveIngestSource(explicit, rawUrl) {
|
|
61
|
+
if (explicit) return explicit;
|
|
62
|
+
return platformFromUrl(rawUrl);
|
|
63
|
+
}
|
|
64
|
+
var TOOLING_OR_BLOCK_SIGNATURES = [
|
|
65
|
+
"requested format is not available",
|
|
66
|
+
"only images are available",
|
|
67
|
+
"nsig",
|
|
68
|
+
"sign in to confirm",
|
|
69
|
+
// bot check — distinct from "Private video. Sign in if…"
|
|
70
|
+
"unable to download api page",
|
|
71
|
+
"http error 403",
|
|
72
|
+
// yt-dlp's own "the site changed under me" signature. It prints a GitHub issue
|
|
73
|
+
// link whenever a page parsed nothing like the shape the extractor expects —
|
|
74
|
+
// which is precisely a downloader that has aged out, not a bad link. Observed
|
|
75
|
+
// live on TikTok, which probed fine and then broke ninety minutes later from
|
|
76
|
+
// the same machine, identically through direct, datacenter and residential
|
|
77
|
+
// exits. Without this it fell through to "check the link is public", sending
|
|
78
|
+
// the reader to inspect a video that was never the problem.
|
|
79
|
+
"please report this issue"
|
|
80
|
+
];
|
|
81
|
+
function isToolingOrBlockFailure(detail) {
|
|
82
|
+
const haystack = detail.toLowerCase();
|
|
83
|
+
return TOOLING_OR_BLOCK_SIGNATURES.some((signature) => haystack.includes(signature));
|
|
84
|
+
}
|
|
85
|
+
var REGION_BLOCK_SIGNATURES = [
|
|
86
|
+
"in your country",
|
|
87
|
+
"geo-restricted",
|
|
88
|
+
"geo restricted",
|
|
89
|
+
"not available from your location",
|
|
90
|
+
"blocked in your country"
|
|
91
|
+
];
|
|
92
|
+
function isDrmProtected(detail) {
|
|
93
|
+
return detail.toLowerCase().includes("drm protected");
|
|
94
|
+
}
|
|
95
|
+
function isRegionBlocked(detail) {
|
|
96
|
+
const haystack = detail.toLowerCase();
|
|
97
|
+
return REGION_BLOCK_SIGNATURES.some((signature) => haystack.includes(signature));
|
|
98
|
+
}
|
|
99
|
+
function worthDownloadingInstead(errorCode) {
|
|
100
|
+
return errorCode === "VALIDATION_ERROR";
|
|
101
|
+
}
|
|
102
|
+
function directDedupeKey(source, rawUrl) {
|
|
103
|
+
return `${source}:${rawUrl}`;
|
|
104
|
+
}
|
|
105
|
+
function safePathname(rawUrl) {
|
|
106
|
+
try {
|
|
107
|
+
return new URL(rawUrl).pathname.toLowerCase();
|
|
108
|
+
} catch {
|
|
109
|
+
return "";
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export {
|
|
114
|
+
MAX_VIDEO_INGEST_BYTES,
|
|
115
|
+
MAX_VIDEO_INGEST_SECONDS,
|
|
116
|
+
refuseByDuration,
|
|
117
|
+
downloadTimeoutMs,
|
|
118
|
+
isDirectMediaUrl,
|
|
119
|
+
resolveIngestSource,
|
|
120
|
+
isToolingOrBlockFailure,
|
|
121
|
+
isDrmProtected,
|
|
122
|
+
isRegionBlocked,
|
|
123
|
+
worthDownloadingInstead,
|
|
124
|
+
directDedupeKey
|
|
125
|
+
};
|
|
126
|
+
//# sourceMappingURL=chunk-FKOECEVC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/commands/videos/videoPlatforms.ts","../src/commands/videos/ingestUrl.ts"],"sourcesContent":["/**\n * Which platform a video link came from.\n *\n * This exists for provenance, not for capability. The downloader already reaches\n * far more sites than are named here, so a platform missing from this table\n * still ingests — it is simply recorded as `url`. What the table buys is the\n * ability to answer \"where did this clip come from\" later: a competitor's TikTok,\n * a supplier's Vimeo and the client's own YouTube are different things to a\n * marketer, and collapsing all three into \"url\" throws that away at the only\n * moment it is knowable.\n *\n * Kept deliberately small. Naming every site the downloader supports would be a\n * list nobody can maintain and would still be missing the next one; these are the\n * platforms whose provenance actually changes how a clip gets used.\n */\n\n/** Registrable domains per platform. Subdomains match; lookalikes must not. */\nconst PLATFORM_DOMAINS = {\n youtube: [\"youtube.com\", \"youtu.be\"],\n instagram: [\"instagram.com\", \"ddinstagram.com\"],\n tiktok: [\"tiktok.com\"],\n twitter: [\"twitter.com\", \"x.com\", \"vxtwitter.com\", \"fixvx.com\"],\n facebook: [\"facebook.com\", \"fb.watch\", \"fb.com\"],\n linkedin: [\"linkedin.com\", \"lnkd.in\"],\n reddit: [\"reddit.com\", \"redd.it\"],\n vimeo: [\"vimeo.com\"],\n dailymotion: [\"dailymotion.com\", \"dai.ly\"],\n twitch: [\"twitch.tv\"],\n bluesky: [\"bsky.app\"],\n bilibili: [\"bilibili.com\", \"bilibili.tv\", \"b23.tv\"],\n vk: [\"vk.com\", \"vk.ru\", \"vkvideo.ru\"],\n ok: [\"ok.ru\"],\n pinterest: [\"pinterest.com\", \"pin.it\"],\n tumblr: [\"tumblr.com\"],\n snapchat: [\"snapchat.com\"],\n loom: [\"loom.com\"],\n streamable: [\"streamable.com\"],\n newgrounds: [\"newgrounds.com\"],\n rutube: [\"rutube.ru\"],\n} as const satisfies Record<string, readonly string[]>;\n\nexport type VideoPlatform = keyof typeof PLATFORM_DOMAINS;\n\n/** Every platform this can name; `platformFromUrl` returns one of these or `url`. */\nexport const VIDEO_PLATFORMS = Object.keys(PLATFORM_DOMAINS) as readonly VideoPlatform[];\n\n/**\n * The platform a URL belongs to, or `url` when it is not one we name.\n *\n * Matching is on the host, anchored at a dot boundary — never `includes`. That\n * is the whole security property of this function: `youtube.com.evil.test` and\n * `notyoutube.com` are attacker-controlled hosts that would otherwise inherit\n * YouTube's identity, and provenance that can be spoofed is worse than none,\n * because it is trusted.\n *\n * Pinterest is a deliberate omission from the country-mirror handling: cobalt\n * collapses `pinterest.co.uk` and friends, and doing the same here would mean\n * carrying a list of every ccTLD a platform has ever used. Those links resolve\n * as `url` and still ingest.\n */\nexport function platformFromUrl(rawUrl: string): VideoPlatform | \"url\" {\n let host: string;\n try {\n host = new URL(rawUrl).hostname.toLowerCase();\n } catch {\n return \"url\";\n }\n\n for (const [platform, domains] of Object.entries(PLATFORM_DOMAINS)) {\n if (domains.some((domain) => host === domain || host.endsWith(`.${domain}`))) {\n return platform as VideoPlatform;\n }\n }\n return \"url\";\n}\n","import { platformFromUrl } from \"./videoPlatforms.ts\";\n/**\n * URL classification for `baker videos ingest`. Pure so the routing decision —\n * hand the URL to Baker, or download it here first — is testable without a\n * network, a sandbox, or yt-dlp installed.\n */\n\n/**\n * Ceiling on the download path only. The direct path has no equivalent: Mux\n * fetches the file itself, so nothing is held in the Runtime's memory or disk.\n *\n * This was 2 GB, and it was never really a policy — it was a memory limit\n * wearing a policy's clothes. The upload read the whole file into a Buffer and\n * then copied it again into a `Uint8Array` (measured: that constructor does not\n * alias), so peak RAM was twice the file and an 8 GB Runtime would be OOM-killed\n * before the check ever fired. The file now streams from disk\n * (`lib/streamUpload.ts`), peak memory is one chunk regardless of length, and\n * this bounds the Runtime's *disk* — the last resource a download still spends\n * in proportion to how long the video is.\n *\n * The gate that does the real work is `refuseByDuration`, below: it turns away a\n * too-long video from its metadata, before a single byte is fetched.\n */\nexport const MAX_VIDEO_INGEST_BYTES = 16 * 1024 * 1024 * 1024;\n\n/** The longest video we will pull down, in seconds. */\nexport const MAX_VIDEO_INGEST_SECONDS = 3 * 60 * 60;\n\n/**\n * Whether a video is too long to ingest, phrased for whoever pasted the link.\n *\n * Duration rather than bytes, because duration is knowable *before* downloading\n * and a byte count is not: a watch page carries no `content-length`, an adaptive\n * stream has one per segment, and the merged file does not exist until it has\n * been muxed. So a byte cap can only be enforced after paying for the very\n * download it was supposed to avoid, while a duration cap costs one metadata\n * probe.\n *\n * An unknown duration is accepted, not refused. A live stream, or a site that\n * publishes no metadata, reports nothing — and treating silence as \"too long\"\n * would turn a missing field into a blocked ingest. The byte ceiling still\n * catches those on the way out.\n */\nexport function refuseByDuration(seconds: number | undefined, maxSeconds: number): string | null {\n if (seconds === undefined || seconds <= maxSeconds) return null;\n return `That video is ${(seconds / 3600).toFixed(1)} hours long — the limit is ${Math.round(maxSeconds / 3600)} hours.`;\n}\n\n/** Floor, and what an unknown duration gets: enough for any ordinary clip. */\nconst DOWNLOAD_TIMEOUT_FLOOR_MS = 10 * 60 * 1000;\n/**\n * Ceiling, and the binding constraint in practice.\n *\n * Set by what a person waiting in a chat will tolerate, not by what a download\n * might need: the turn is blocked for this whole time, and a chat that appears\n * frozen for three quarters of an hour is a worse outcome than a clip that did\n * not import. Fifteen minutes covers any ordinary clip even from a slow CDN,\n * and a video that cannot make it says so and points at `upload`.\n */\nconst DOWNLOAD_TIMEOUT_CEILING_MS = 15 * 60 * 1000;\n\n/**\n * How long a download may take, derived from how long the video is.\n *\n * These two numbers have to be related or they quietly contradict each other,\n * which is exactly what happened: the duration gate accepted up to three hours\n * while every download got a flat ten-minute window, so a 33-minute VK video —\n * served slowly, still transferring at 137 MB when the clock ran out — was\n * accepted by one rule and made impossible by another. It surfaced as\n * \"Unexpected error\", because a timeout throws a plain `Error` that the caller\n * discarded.\n *\n * Twice real-time is the budget: generous for a CDN serving faster than\n * playback, and still finite for one that is not. The ceiling matters more than\n * the ratio — without it a three-hour video would license a six-hour download.\n */\nexport function downloadTimeoutMs(seconds: number | undefined): number {\n if (seconds === undefined) return DOWNLOAD_TIMEOUT_FLOOR_MS;\n const scaled = seconds * 2 * 1000;\n return Math.min(Math.max(scaled, DOWNLOAD_TIMEOUT_FLOOR_MS), DOWNLOAD_TIMEOUT_CEILING_MS);\n}\n\nconst DIRECT_MEDIA_EXTENSIONS = [\".mp4\", \".mov\", \".webm\", \".m4v\", \".mkv\", \".avi\"] as const;\n\n/**\n * True when the URL's path ends in a media extension, which is the signal that\n * Mux can pull it directly. Deliberately conservative: a false negative only\n * costs an unnecessary download, while a false positive hands Mux a web page.\n */\nexport function isDirectMediaUrl(rawUrl: string): boolean {\n const pathname = safePathname(rawUrl);\n return DIRECT_MEDIA_EXTENSIONS.some((ext) => pathname.endsWith(ext));\n}\n\n/** Explicit `--source` always wins; otherwise infer provenance from the host. */\nexport function resolveIngestSource(explicit: string | undefined, rawUrl: string): string {\n if (explicit) return explicit;\n return platformFromUrl(rawUrl);\n}\n\n/**\n * Signatures of \"the site wouldn't hand over the video\", as opposed to \"this\n * link is private or gone\".\n *\n * They matter because the remediation is opposite. These all mean the downloader\n * could not read the page — nearly always because it has aged out against a site\n * that changed (YouTube rewrites its player every few weeks) or because the\n * request was blocked. Retrying is useless and the user's link is fine, so\n * telling them to check whether their public video is \"private\" sends them after\n * a problem that isn't theirs.\n */\nconst TOOLING_OR_BLOCK_SIGNATURES = [\n \"requested format is not available\",\n \"only images are available\",\n \"nsig\",\n \"sign in to confirm\", // bot check — distinct from \"Private video. Sign in if…\"\n \"unable to download api page\",\n \"http error 403\",\n // yt-dlp's own \"the site changed under me\" signature. It prints a GitHub issue\n // link whenever a page parsed nothing like the shape the extractor expects —\n // which is precisely a downloader that has aged out, not a bad link. Observed\n // live on TikTok, which probed fine and then broke ninety minutes later from\n // the same machine, identically through direct, datacenter and residential\n // exits. Without this it fell through to \"check the link is public\", sending\n // the reader to inspect a video that was never the problem.\n \"please report this issue\",\n] as const;\n\nexport function isToolingOrBlockFailure(detail: string): boolean {\n const haystack = detail.toLowerCase();\n return TOOLING_OR_BLOCK_SIGNATURES.some((signature) => haystack.includes(signature));\n}\n\n/**\n * Failures a *different country* could plausibly open — the only ones where\n * retrying with `--country` is worth suggesting.\n *\n * Deliberately narrow, and it is the narrowness that matters. Every rung of the\n * ladder already tries a different IP, so \"we were refused\" is not evidence that\n * geography was the reason; it is only evidence that geography *might* be. These\n * phrases are the ones where the site itself named the country.\n *\n * TikTok is the worked counter-example and the reason this is not a loose match\n * on \"blocked\": it answers with \"Your IP address is blocked from accessing this\n * post\", which reads exactly like a geo problem. Measured across six exits in\n * four countries — Spain direct, Spain datacenter, US, DE, SG, BR — that post\n * failed identically from all of them, while a different post succeeded from the\n * plain direct IP. Treating that string as regional would sell the agent a retry\n * that cannot work, once per country it thinks to try.\n */\nconst REGION_BLOCK_SIGNATURES = [\n \"in your country\",\n \"geo-restricted\",\n \"geo restricted\",\n \"not available from your location\",\n \"blocked in your country\",\n] as const;\n\n/**\n * The video's own encryption refusing us — a hard stop, not a hurdle.\n *\n * Kept separate from every other failure because it is the only one where the\n * honest answer is \"no, and no amount of retrying, signing in or changing\n * country will alter that\". Removing DRM is a different act from downloading\n * something published openly, so this never suggests a workaround.\n *\n * Checked *before* the tooling signatures, because a DRM video also emits\n * \"Requested format is not available\" as its second line — and that phrase is\n * read as a stale downloader, which would file a permanent property of the video\n * as a bug in our tooling. Measured: `--check-formats`, the remedy yt-dlp's own\n * message suggests, does not help when the audio track is the encrypted part.\n */\nexport function isDrmProtected(detail: string): boolean {\n return detail.toLowerCase().includes(\"drm protected\");\n}\n\nexport function isRegionBlocked(detail: string): boolean {\n const haystack = detail.toLowerCase();\n return REGION_BLOCK_SIGNATURES.some((signature) => haystack.includes(signature));\n}\n\n/**\n * Whether a failed direct ingest is worth retrying by downloading the file\n * ourselves.\n *\n * The subtlety that makes this necessary: the download route finishes by posting\n * to the *same* endpoint, with the same API key and the same `source`. So a\n * failure about the request rather than about the URL is guaranteed to fail\n * again identically, except now after pulling the whole video down first.\n *\n * An allow-list of one, and it has to be, because the codes here are the CLI's\n * (`mapHttpError`), not the backend's. That distinction was previously missed:\n * this listed backend names, so `apiError(\"BAD_REQUEST\")` — the code the route\n * raises when Mux refuses the source, and the only case this exists for —\n * arrived as `VALIDATION_ERROR` and was refused, while a backend 500 arrived as\n * `INTERNAL_ERROR`, matched nothing, and downloaded a whole video to replay the\n * identical failing request. Naming the outcome we want, rather than the ones we\n * don't, means a code nobody anticipated costs a missed retry instead of a\n * wasted download.\n *\n * `VALIDATION_ERROR` is unambiguous *here* only because the request body is zod\n * validated client-side before it is ever sent, so a 400 from this route is not\n * a malformed request — it is Baker saying it could not fetch that URL.\n */\nexport function worthDownloadingInstead(errorCode: string): boolean {\n return errorCode === \"VALIDATION_ERROR\";\n}\n\n/**\n * The dedupe key for a URL handed straight to Baker.\n *\n * The direct path never probes — that is the whole point of it — so there is no\n * provider id to key on and the URL is the only identifier available. That is\n * the same position the download path's *generic* extractor branch is in, and it\n * resolves it the same way, so a link filed directly and the same link filed via\n * the download fallback agree on one row instead of producing two.\n *\n * Keyed on the full URL rather than the filename: two unrelated clips are very\n * often both called `demo.mp4`, and a collision silently returns the wrong video\n * under a successful-looking response, which is far worse than a missed dedupe.\n * A signed URL carrying an expiring token simply never dedupes, which is the\n * harmless direction to fail in.\n */\nexport function directDedupeKey(source: string, rawUrl: string): string {\n return `${source}:${rawUrl}`;\n}\n\nfunction safePathname(rawUrl: string): string {\n try {\n return new URL(rawUrl).pathname.toLowerCase();\n } catch {\n return \"\";\n }\n}\n"],"mappings":"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","names":[]}
|