@koda-sl/baker-cli 0.489.0 → 0.490.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +169 -7
- package/dist/{account-Z65CPOWE.js → account-3H6BZO5H.js} +2 -2
- package/dist/account-IKFDY52P.js +138 -0
- package/dist/account-IKFDY52P.js.map +1 -0
- package/dist/account-assets-LKZVWZAR.js +289 -0
- package/dist/account-assets-LKZVWZAR.js.map +1 -0
- package/dist/account-level-UJOZDVXY.js +608 -0
- package/dist/account-level-UJOZDVXY.js.map +1 -0
- package/dist/{account-writes-4N2MA2ZR.js → account-writes-AE5IJGGW.js} +2 -2
- package/dist/{accounts-UA2ZWRN4.js → accounts-K4INATCW.js} +2 -2
- package/dist/{activities-IQPJPP4B.js → activities-T253KK4Q.js} +4 -4
- package/dist/{ad-group-writes-EUTMPBMK.js → ad-group-writes-VRSBI2Z2.js} +2 -2
- package/dist/{ad-groups-OVPAI5RM.js → ad-groups-IEBVEAMS.js} +6 -6
- package/dist/{ad-writes-DACTYFEO.js → ad-writes-ALV4KFPZ.js} +2 -2
- package/dist/{ads-L65JIKCD.js → ads-CQZHD7FC.js} +7 -7
- package/dist/{ads-G6AS5L7G.js → ads-QIKZ6O2N.js} +5 -5
- package/dist/{ads-HXX2IAFF.js → ads-ZEY72UBN.js} +14 -13
- package/dist/ads-ZEY72UBN.js.map +1 -0
- package/dist/{adsets-LPN6WFGF.js → adsets-5H3MOT3D.js} +15 -14
- package/dist/{adsets-LPN6WFGF.js.map → adsets-5H3MOT3D.js.map} +1 -1
- package/dist/{analytics-QKP3A5F3.js → analytics-ALOZ7ZZ4.js} +1 -1
- package/dist/asset-writes-L5TMKIZC.js +47 -0
- package/dist/audience-writes-X52VG35Y.js +324 -0
- package/dist/audience-writes-X52VG35Y.js.map +1 -0
- package/dist/{audiences-RPLVMO4H.js → audiences-AAZH56WD.js} +2 -2
- package/dist/{audiences-XEZHACKH.js → audiences-X3RLGOVM.js} +12 -6
- package/dist/audiences-X3RLGOVM.js.map +1 -0
- package/dist/{avatars-MXTI74VC.js → avatars-YSFFRHDK.js} +1 -1
- package/dist/{brief-BN4UGUXF.js → brief-7S6XCJIA.js} +15 -15
- package/dist/{businesses-PRRYPR7H.js → businesses-H3HIDQX6.js} +2 -2
- package/dist/{campaign-writes-BAFB5E7A.js → campaign-writes-7ZF57KLH.js} +3 -3
- package/dist/campaign-writes-7ZF57KLH.js.map +1 -0
- package/dist/{campaign-writes-U5LTDTYK.js → campaign-writes-U5PUVSMT.js} +2 -2
- package/dist/{campaigns-4SOLY7OR.js → campaigns-AV6G3AUU.js} +32 -15
- package/dist/campaigns-AV6G3AUU.js.map +1 -0
- package/dist/{campaigns-TFEQTSO3.js → campaigns-JEIKY2M4.js} +6 -6
- package/dist/{campaigns-NR6TNQFN.js → campaigns-VTRMKSAT.js} +5 -5
- package/dist/{canvas-GJAQAVS6.js → canvas-SVJEQO4V.js} +13 -13
- package/dist/{catalog-USZL4SGX.js → catalog-S32MX453.js} +5 -5
- package/dist/{catalogs-A7XMEEEP.js → catalogs-OCVXZLIF.js} +2 -2
- package/dist/catalogs-RXJTZTVX.js +778 -0
- package/dist/catalogs-RXJTZTVX.js.map +1 -0
- package/dist/{chatgpt-4PEWDJKP.js → chatgpt-QVF2FD3E.js} +12 -12
- package/dist/{chats-INN2OHSH.js → chats-QG72JB6Y.js} +22 -8
- package/dist/chats-QG72JB6Y.js.map +1 -0
- package/dist/{check-MMJGFFZS.js → check-SLNHVYGS.js} +4 -4
- package/dist/{chunk-7RBJ2Z7Z.js → chunk-2C7AHPM4.js} +25 -6
- package/dist/chunk-2C7AHPM4.js.map +1 -0
- package/dist/{chunk-KPYDTIAI.js → chunk-2WZI36D3.js} +2 -2
- package/dist/{chunk-FUKDI2UK.js → chunk-3W6G6ARX.js} +2 -2
- package/dist/{chunk-JWSEPW7F.js → chunk-46GWHUKN.js} +2 -2
- package/dist/{chunk-3TZVZXM6.js → chunk-4KJMLYCD.js} +6 -6
- package/dist/{chunk-6JWEGFM5.js → chunk-5C35OW7L.js} +38 -7
- package/dist/chunk-5C35OW7L.js.map +1 -0
- package/dist/chunk-5GQCN2QZ.js +391 -0
- package/dist/chunk-5GQCN2QZ.js.map +1 -0
- package/dist/{chunk-KIGGMKAE.js → chunk-65Y3RCWP.js} +4 -2
- package/dist/chunk-65Y3RCWP.js.map +1 -0
- package/dist/{chunk-R3EKM2P2.js → chunk-6NCJGU6I.js} +5 -5
- package/dist/chunk-A4MVVPJ2.js +4204 -0
- package/dist/chunk-A4MVVPJ2.js.map +1 -0
- package/dist/{chunk-LPXSM2DI.js → chunk-AO45BX6Q.js} +3 -3
- package/dist/{chunk-3UXMQ3K2.js → chunk-AQM4JH62.js} +2 -2
- package/dist/chunk-AQM4JH62.js.map +1 -0
- package/dist/{chunk-NPMAATZG.js → chunk-C7NWUCLQ.js} +2 -2
- package/dist/chunk-CP4P6YKM.js +287 -0
- package/dist/chunk-CP4P6YKM.js.map +1 -0
- package/dist/{chunk-OWA7ZLC4.js → chunk-D4CKCNGW.js} +4 -4
- package/dist/{chunk-H5HDZ7IC.js → chunk-DCBZ5CHZ.js} +4 -4
- package/dist/{chunk-C6EYCD5J.js → chunk-FVHJCERJ.js} +5 -5
- package/dist/{chunk-BITS62MF.js → chunk-G6XKD7QE.js} +2 -2
- package/dist/{chunk-QE3JEJXF.js → chunk-GSZZLW5Q.js} +4 -4
- package/dist/chunk-HLVRHBKL.js +1078 -0
- package/dist/chunk-HLVRHBKL.js.map +1 -0
- package/dist/{chunk-TPANP5A2.js → chunk-JKJQWRLO.js} +2 -2
- package/dist/{chunk-62JQQUAU.js → chunk-JQH5VG6F.js} +2 -2
- package/dist/{chunk-6WXV5GTA.js → chunk-JVH5A3XC.js} +2 -2
- package/dist/{chunk-AVNSH2JE.js → chunk-KOXDXSKN.js} +7 -7
- package/dist/{chunk-2XRMPSEV.js → chunk-LXQB4ZGE.js} +2 -2
- package/dist/{chunk-ZL23HA4N.js → chunk-M6PN3VH6.js} +2 -2
- package/dist/{chunk-TZEVD4Q6.js → chunk-P5FRWPG7.js} +2 -2
- package/dist/{chunk-CSZFZKVX.js → chunk-PQJXIY64.js} +5 -5
- package/dist/{chunk-OP7DNHD2.js → chunk-QTOZ32SU.js} +27 -1
- package/dist/chunk-QTOZ32SU.js.map +1 -0
- package/dist/chunk-SVAB6KV5.js +219 -0
- package/dist/chunk-SVAB6KV5.js.map +1 -0
- package/dist/{chunk-LBO2YAZY.js → chunk-UNX6BS4U.js} +15 -15
- package/dist/{chunk-UWXDNVS5.js → chunk-ZJSGGJ5R.js} +2 -2
- package/dist/cli.js +20 -20
- package/dist/{connect-WBGCBBFJ.js → connect-S54TJ6OV.js} +3 -3
- package/dist/{conversion-writes-JU7Q2MUO.js → conversion-writes-ECZBVY7D.js} +2 -2
- package/dist/{conversions-3ISBR3TS.js → conversions-5QCSCRLI.js} +3 -3
- package/dist/copy-writes-D2RTHAL6.js +167 -0
- package/dist/copy-writes-D2RTHAL6.js.map +1 -0
- package/dist/{creatives-VQO2TKE3.js → creatives-5I3G5YP3.js} +2 -2
- package/dist/{creatives-YJ3CXZQC.js → creatives-MZ6ICNSY.js} +5 -4
- package/dist/{creatives-YJ3CXZQC.js.map → creatives-MZ6ICNSY.js.map} +1 -1
- package/dist/{creatives-S5QUWUL6.js → creatives-PCAGWPW3.js} +10 -10
- package/dist/{critique-5LCG5TYF.js → critique-NRHUPIWF.js} +7 -7
- package/dist/{custom-conversions-YRYE65PU.js → custom-conversions-FIP6ZS34.js} +5 -3
- package/dist/{custom-conversions-YRYE65PU.js.map → custom-conversions-FIP6ZS34.js.map} +1 -1
- package/dist/{draft-Y2QJE2NM.js → draft-34CGWUVA.js} +2 -2
- package/dist/{draft-GPN3HOAG.js → draft-4P3YO67N.js} +9 -5
- package/dist/draft-4P3YO67N.js.map +1 -0
- package/dist/{draft-EWDOIXSH.js → draft-L45PGCYZ.js} +7 -3
- package/dist/draft-L45PGCYZ.js.map +1 -0
- package/dist/engine/index.js +4 -4
- package/dist/{experiment-G3FQVAJU.js → experiment-7N4QFRWV.js} +4 -4
- package/dist/{feedback-CAOZPGTT.js → feedback-O3H42V4I.js} +10 -10
- package/dist/{feedback-record-EXV5H6OS.js → feedback-record-FAPN2GBS.js} +12 -12
- package/dist/{find-EVY4XEIQ.js → find-FSQAEGGF.js} +4 -4
- package/dist/{flows-Z7355RMD.js → flows-T22B77J3.js} +3 -3
- package/dist/{funnel-2B3JXJPX.js → funnel-7OA33VRP.js} +5 -5
- package/dist/{ga4-2BL5YAYN.js → ga4-LPDIBNYP.js} +1 -1
- package/dist/{google-7STODZQR.js → google-5ESVO76E.js} +5 -5
- package/dist/{gsc-UU3T2C6B.js → gsc-FIZTQX3N.js} +1 -1
- package/dist/{history-IQ33J5PB.js → history-QKDYBSYM.js} +2 -2
- package/dist/{icon-GB7UH5RF.js → icon-CSVAZ7NE.js} +4 -4
- package/dist/{ideas-F6CIGTVU.js → ideas-JQT422P7.js} +4 -4
- package/dist/{images-WCKTD6Z2.js → images-WBNWK2ZH.js} +6 -6
- package/dist/{insights-4HT2NAYP.js → insights-YWVJMATY.js} +4 -3
- package/dist/{insights-4HT2NAYP.js.map → insights-YWVJMATY.js.map} +1 -1
- package/dist/{inspiration-XQYHBJY2.js → inspiration-IX5N724J.js} +1 -1
- package/dist/instant-experiences-NQ2GWIWL.js +257 -0
- package/dist/instant-experiences-NQ2GWIWL.js.map +1 -0
- package/dist/{landing-WUILAWDS.js → landing-Y6QCTXCZ.js} +2 -2
- package/dist/leads-THI37ZMD.js +537 -0
- package/dist/leads-THI37ZMD.js.map +1 -0
- package/dist/{learn-CC6Q5IK2.js → learn-3BDZUWDT.js} +5 -5
- package/dist/{linkedin-XKVPSCLV.js → linkedin-UGMAFSGO.js} +2 -2
- package/dist/{locations-YA7NZY44.js → locations-HM56X2MK.js} +2 -2
- package/dist/locations-HM56X2MK.js.map +1 -0
- package/dist/{logo-YSNUUT33.js → logo-VHXH4J6A.js} +3 -3
- package/dist/{make-ED7HBLH3.js → make-W2PYZXYF.js} +39 -39
- package/dist/media-H6B7VDON.js +18 -0
- package/dist/media-H6B7VDON.js.map +1 -0
- package/dist/{media-sources-PEHUMH7C.js → media-sources-EZKAJNVD.js} +1 -1
- package/dist/meta-YHDTGJQ6.js +122 -0
- package/dist/meta-YHDTGJQ6.js.map +1 -0
- package/dist/{options-6FCNFWUF.js → options-NSCZSQ5P.js} +3 -3
- package/dist/page-photos-CXRG4AXV.js +115 -0
- package/dist/page-photos-CXRG4AXV.js.map +1 -0
- package/dist/{pages-FTI44OSH.js → pages-PTWRXAZT.js} +2 -2
- package/dist/{pixels-6IUB3Y3H.js → pixels-MYT3TCHZ.js} +2 -2
- package/dist/{pixels-MBKR4XPX.js → pixels-ZZCQUS3J.js} +2 -2
- package/dist/{preview-V4YBD45S.js → preview-XOXAAPMQ.js} +73 -27
- package/dist/preview-XOXAAPMQ.js.map +1 -0
- package/dist/{rerun-A2XHGFZS.js → rerun-5THJLQQJ.js} +18 -18
- package/dist/{research-BLDY5UWH.js → research-JHDWWFL7.js} +1 -1
- package/dist/rule-writes-6ZCAJDYZ.js +522 -0
- package/dist/rule-writes-6ZCAJDYZ.js.map +1 -0
- package/dist/rules-BMYOY2BM.js +216 -0
- package/dist/rules-BMYOY2BM.js.map +1 -0
- package/dist/{rules-SK5DFFPY.js → rules-YLLFDZEM.js} +3 -3
- package/dist/{rules-add-YQNYSME7.js → rules-add-U2GU4AGP.js} +4 -4
- package/dist/{run-KBN5K7LE.js → run-V5YQB6TH.js} +18 -18
- package/dist/{scaffold-ad-6BN5LWQH.js → scaffold-ad-H4GJOKAW.js} +12 -12
- package/dist/{scaffold-static-ad-VVZRAWBR.js → scaffold-static-ad-2YIFHCTL.js} +25 -25
- package/dist/{scaffold-video-LFIYI4GP.js → scaffold-video-3EJLKR2O.js} +14 -14
- package/dist/{select-QBU6ED4K.js → select-I22NPSIW.js} +9 -9
- package/dist/{set-prompt-TL64CRBQ.js → set-prompt-S75OMQ7L.js} +8 -8
- package/dist/{shared-NDRFKAH7.js → shared-3IBNDEFL.js} +2 -2
- package/dist/{sources-RMNFV4CA.js → sources-VA23PDND.js} +1 -1
- package/dist/{stale-ITFCPOER.js → stale-MHTU2NQJ.js} +8 -8
- package/dist/{stats-RCLQE4HJ.js → stats-ZAGJH4AD.js} +1 -1
- package/dist/{stock-ECRBD7RP.js → stock-6SHHLSKG.js} +5 -5
- package/dist/studies-4NIV4D5Y.js +249 -0
- package/dist/studies-4NIV4D5Y.js.map +1 -0
- package/dist/{studio-MARZ22J2.js → studio-ZLCGXFAN.js} +1 -1
- package/dist/study-writes-L2AA2PGL.js +467 -0
- package/dist/study-writes-L2AA2PGL.js.map +1 -0
- package/dist/{sync-definition-C6ROLKJ4.js → sync-definition-2EBSQA6A.js} +11 -11
- package/dist/{tag-manager-G3LBQZUL.js → tag-manager-3CJ66GKJ.js} +1 -1
- package/dist/targeting-LNDQV4EK.js +759 -0
- package/dist/targeting-LNDQV4EK.js.map +1 -0
- package/dist/{testimonials-YMMA5YWL.js → testimonials-GR6TIS5S.js} +2 -2
- package/dist/{translate-OXVIMYHE.js → translate-GEFUP6KQ.js} +18 -18
- package/dist/{validate-ZS2M5Q3V.js → validate-NOWIOAHE.js} +11 -11
- package/dist/{videos-I6YXFBFT.js → videos-XMTDEHEJ.js} +1 -1
- package/dist/{viewer-check-7ZG7KHEN.js → viewer-check-U4XZMMS7.js} +6 -6
- package/dist/viewer-check-U4XZMMS7.js.map +1 -0
- package/dist/{winning-ads-ABN5OULS.js → winning-ads-QOAYIR5U.js} +1 -1
- package/dist/{write-commands-HCQI4Y27.js → write-commands-PEJBTME6.js} +485 -57
- package/dist/write-commands-PEJBTME6.js.map +1 -0
- package/dist/{x-WK2VQDPF.js → x-VCSMV7T5.js} +4 -4
- package/package.json +1 -1
- package/dist/account-7LUQWY6Q.js +0 -49
- package/dist/account-7LUQWY6Q.js.map +0 -1
- package/dist/ads-HXX2IAFF.js.map +0 -1
- package/dist/audiences-XEZHACKH.js.map +0 -1
- package/dist/campaign-writes-BAFB5E7A.js.map +0 -1
- package/dist/campaigns-4SOLY7OR.js.map +0 -1
- package/dist/chats-INN2OHSH.js.map +0 -1
- package/dist/chunk-3UXMQ3K2.js.map +0 -1
- package/dist/chunk-6JWEGFM5.js.map +0 -1
- package/dist/chunk-7RBJ2Z7Z.js.map +0 -1
- package/dist/chunk-GOJXKIFQ.js +0 -1605
- package/dist/chunk-GOJXKIFQ.js.map +0 -1
- package/dist/chunk-KIGGMKAE.js.map +0 -1
- package/dist/chunk-OP7DNHD2.js.map +0 -1
- package/dist/draft-EWDOIXSH.js.map +0 -1
- package/dist/draft-GPN3HOAG.js.map +0 -1
- package/dist/leads-2XOSAYP4.js +0 -293
- package/dist/leads-2XOSAYP4.js.map +0 -1
- package/dist/locations-YA7NZY44.js.map +0 -1
- package/dist/media-ES2UBGYW.js +0 -15
- package/dist/media-ES2UBGYW.js.map +0 -1
- package/dist/meta-AOIPEDV5.js +0 -69
- package/dist/meta-AOIPEDV5.js.map +0 -1
- package/dist/preview-V4YBD45S.js.map +0 -1
- package/dist/write-commands-HCQI4Y27.js.map +0 -1
- /package/dist/{account-Z65CPOWE.js.map → account-3H6BZO5H.js.map} +0 -0
- /package/dist/{account-writes-4N2MA2ZR.js.map → account-writes-AE5IJGGW.js.map} +0 -0
- /package/dist/{accounts-UA2ZWRN4.js.map → accounts-K4INATCW.js.map} +0 -0
- /package/dist/{activities-IQPJPP4B.js.map → activities-T253KK4Q.js.map} +0 -0
- /package/dist/{ad-group-writes-EUTMPBMK.js.map → ad-group-writes-VRSBI2Z2.js.map} +0 -0
- /package/dist/{ad-groups-OVPAI5RM.js.map → ad-groups-IEBVEAMS.js.map} +0 -0
- /package/dist/{ad-writes-DACTYFEO.js.map → ad-writes-ALV4KFPZ.js.map} +0 -0
- /package/dist/{ads-L65JIKCD.js.map → ads-CQZHD7FC.js.map} +0 -0
- /package/dist/{ads-G6AS5L7G.js.map → ads-QIKZ6O2N.js.map} +0 -0
- /package/dist/{analytics-QKP3A5F3.js.map → analytics-ALOZ7ZZ4.js.map} +0 -0
- /package/dist/{connect-WBGCBBFJ.js.map → asset-writes-L5TMKIZC.js.map} +0 -0
- /package/dist/{audiences-RPLVMO4H.js.map → audiences-AAZH56WD.js.map} +0 -0
- /package/dist/{avatars-MXTI74VC.js.map → avatars-YSFFRHDK.js.map} +0 -0
- /package/dist/{brief-BN4UGUXF.js.map → brief-7S6XCJIA.js.map} +0 -0
- /package/dist/{businesses-PRRYPR7H.js.map → businesses-H3HIDQX6.js.map} +0 -0
- /package/dist/{campaign-writes-U5LTDTYK.js.map → campaign-writes-U5PUVSMT.js.map} +0 -0
- /package/dist/{campaigns-TFEQTSO3.js.map → campaigns-JEIKY2M4.js.map} +0 -0
- /package/dist/{campaigns-NR6TNQFN.js.map → campaigns-VTRMKSAT.js.map} +0 -0
- /package/dist/{canvas-GJAQAVS6.js.map → canvas-SVJEQO4V.js.map} +0 -0
- /package/dist/{catalog-USZL4SGX.js.map → catalog-S32MX453.js.map} +0 -0
- /package/dist/{catalogs-A7XMEEEP.js.map → catalogs-OCVXZLIF.js.map} +0 -0
- /package/dist/{chatgpt-4PEWDJKP.js.map → chatgpt-QVF2FD3E.js.map} +0 -0
- /package/dist/{check-MMJGFFZS.js.map → check-SLNHVYGS.js.map} +0 -0
- /package/dist/{chunk-KPYDTIAI.js.map → chunk-2WZI36D3.js.map} +0 -0
- /package/dist/{chunk-FUKDI2UK.js.map → chunk-3W6G6ARX.js.map} +0 -0
- /package/dist/{chunk-JWSEPW7F.js.map → chunk-46GWHUKN.js.map} +0 -0
- /package/dist/{chunk-3TZVZXM6.js.map → chunk-4KJMLYCD.js.map} +0 -0
- /package/dist/{chunk-R3EKM2P2.js.map → chunk-6NCJGU6I.js.map} +0 -0
- /package/dist/{chunk-LPXSM2DI.js.map → chunk-AO45BX6Q.js.map} +0 -0
- /package/dist/{chunk-NPMAATZG.js.map → chunk-C7NWUCLQ.js.map} +0 -0
- /package/dist/{chunk-OWA7ZLC4.js.map → chunk-D4CKCNGW.js.map} +0 -0
- /package/dist/{chunk-H5HDZ7IC.js.map → chunk-DCBZ5CHZ.js.map} +0 -0
- /package/dist/{chunk-C6EYCD5J.js.map → chunk-FVHJCERJ.js.map} +0 -0
- /package/dist/{chunk-BITS62MF.js.map → chunk-G6XKD7QE.js.map} +0 -0
- /package/dist/{chunk-QE3JEJXF.js.map → chunk-GSZZLW5Q.js.map} +0 -0
- /package/dist/{chunk-TPANP5A2.js.map → chunk-JKJQWRLO.js.map} +0 -0
- /package/dist/{chunk-62JQQUAU.js.map → chunk-JQH5VG6F.js.map} +0 -0
- /package/dist/{chunk-6WXV5GTA.js.map → chunk-JVH5A3XC.js.map} +0 -0
- /package/dist/{chunk-AVNSH2JE.js.map → chunk-KOXDXSKN.js.map} +0 -0
- /package/dist/{chunk-2XRMPSEV.js.map → chunk-LXQB4ZGE.js.map} +0 -0
- /package/dist/{chunk-ZL23HA4N.js.map → chunk-M6PN3VH6.js.map} +0 -0
- /package/dist/{chunk-TZEVD4Q6.js.map → chunk-P5FRWPG7.js.map} +0 -0
- /package/dist/{chunk-CSZFZKVX.js.map → chunk-PQJXIY64.js.map} +0 -0
- /package/dist/{chunk-LBO2YAZY.js.map → chunk-UNX6BS4U.js.map} +0 -0
- /package/dist/{chunk-UWXDNVS5.js.map → chunk-ZJSGGJ5R.js.map} +0 -0
- /package/dist/{ideas-F6CIGTVU.js.map → connect-S54TJ6OV.js.map} +0 -0
- /package/dist/{conversion-writes-JU7Q2MUO.js.map → conversion-writes-ECZBVY7D.js.map} +0 -0
- /package/dist/{conversions-3ISBR3TS.js.map → conversions-5QCSCRLI.js.map} +0 -0
- /package/dist/{creatives-VQO2TKE3.js.map → creatives-5I3G5YP3.js.map} +0 -0
- /package/dist/{creatives-S5QUWUL6.js.map → creatives-PCAGWPW3.js.map} +0 -0
- /package/dist/{critique-5LCG5TYF.js.map → critique-NRHUPIWF.js.map} +0 -0
- /package/dist/{draft-Y2QJE2NM.js.map → draft-34CGWUVA.js.map} +0 -0
- /package/dist/{experiment-G3FQVAJU.js.map → experiment-7N4QFRWV.js.map} +0 -0
- /package/dist/{feedback-CAOZPGTT.js.map → feedback-O3H42V4I.js.map} +0 -0
- /package/dist/{feedback-record-EXV5H6OS.js.map → feedback-record-FAPN2GBS.js.map} +0 -0
- /package/dist/{find-EVY4XEIQ.js.map → find-FSQAEGGF.js.map} +0 -0
- /package/dist/{flows-Z7355RMD.js.map → flows-T22B77J3.js.map} +0 -0
- /package/dist/{funnel-2B3JXJPX.js.map → funnel-7OA33VRP.js.map} +0 -0
- /package/dist/{ga4-2BL5YAYN.js.map → ga4-LPDIBNYP.js.map} +0 -0
- /package/dist/{google-7STODZQR.js.map → google-5ESVO76E.js.map} +0 -0
- /package/dist/{gsc-UU3T2C6B.js.map → gsc-FIZTQX3N.js.map} +0 -0
- /package/dist/{history-IQ33J5PB.js.map → history-QKDYBSYM.js.map} +0 -0
- /package/dist/{icon-GB7UH5RF.js.map → icon-CSVAZ7NE.js.map} +0 -0
- /package/dist/{logo-YSNUUT33.js.map → ideas-JQT422P7.js.map} +0 -0
- /package/dist/{images-WCKTD6Z2.js.map → images-WBNWK2ZH.js.map} +0 -0
- /package/dist/{inspiration-XQYHBJY2.js.map → inspiration-IX5N724J.js.map} +0 -0
- /package/dist/{landing-WUILAWDS.js.map → landing-Y6QCTXCZ.js.map} +0 -0
- /package/dist/{learn-CC6Q5IK2.js.map → learn-3BDZUWDT.js.map} +0 -0
- /package/dist/{linkedin-XKVPSCLV.js.map → linkedin-UGMAFSGO.js.map} +0 -0
- /package/dist/{run-KBN5K7LE.js.map → logo-VHXH4J6A.js.map} +0 -0
- /package/dist/{make-ED7HBLH3.js.map → make-W2PYZXYF.js.map} +0 -0
- /package/dist/{media-sources-PEHUMH7C.js.map → media-sources-EZKAJNVD.js.map} +0 -0
- /package/dist/{options-6FCNFWUF.js.map → options-NSCZSQ5P.js.map} +0 -0
- /package/dist/{pages-FTI44OSH.js.map → pages-PTWRXAZT.js.map} +0 -0
- /package/dist/{pixels-6IUB3Y3H.js.map → pixels-MYT3TCHZ.js.map} +0 -0
- /package/dist/{pixels-MBKR4XPX.js.map → pixels-ZZCQUS3J.js.map} +0 -0
- /package/dist/{rerun-A2XHGFZS.js.map → rerun-5THJLQQJ.js.map} +0 -0
- /package/dist/{research-BLDY5UWH.js.map → research-JHDWWFL7.js.map} +0 -0
- /package/dist/{rules-SK5DFFPY.js.map → rules-YLLFDZEM.js.map} +0 -0
- /package/dist/{rules-add-YQNYSME7.js.map → rules-add-U2GU4AGP.js.map} +0 -0
- /package/dist/{shared-NDRFKAH7.js.map → run-V5YQB6TH.js.map} +0 -0
- /package/dist/{scaffold-ad-6BN5LWQH.js.map → scaffold-ad-H4GJOKAW.js.map} +0 -0
- /package/dist/{scaffold-static-ad-VVZRAWBR.js.map → scaffold-static-ad-2YIFHCTL.js.map} +0 -0
- /package/dist/{scaffold-video-LFIYI4GP.js.map → scaffold-video-3EJLKR2O.js.map} +0 -0
- /package/dist/{select-QBU6ED4K.js.map → select-I22NPSIW.js.map} +0 -0
- /package/dist/{set-prompt-TL64CRBQ.js.map → set-prompt-S75OMQ7L.js.map} +0 -0
- /package/dist/{sync-definition-C6ROLKJ4.js.map → shared-3IBNDEFL.js.map} +0 -0
- /package/dist/{sources-RMNFV4CA.js.map → sources-VA23PDND.js.map} +0 -0
- /package/dist/{stale-ITFCPOER.js.map → stale-MHTU2NQJ.js.map} +0 -0
- /package/dist/{stats-RCLQE4HJ.js.map → stats-ZAGJH4AD.js.map} +0 -0
- /package/dist/{stock-ECRBD7RP.js.map → stock-6SHHLSKG.js.map} +0 -0
- /package/dist/{studio-MARZ22J2.js.map → studio-ZLCGXFAN.js.map} +0 -0
- /package/dist/{viewer-check-7ZG7KHEN.js.map → sync-definition-2EBSQA6A.js.map} +0 -0
- /package/dist/{tag-manager-G3LBQZUL.js.map → tag-manager-3CJ66GKJ.js.map} +0 -0
- /package/dist/{testimonials-YMMA5YWL.js.map → testimonials-GR6TIS5S.js.map} +0 -0
- /package/dist/{translate-OXVIMYHE.js.map → translate-GEFUP6KQ.js.map} +0 -0
- /package/dist/{validate-ZS2M5Q3V.js.map → validate-NOWIOAHE.js.map} +0 -0
- /package/dist/{videos-I6YXFBFT.js.map → videos-XMTDEHEJ.js.map} +0 -0
- /package/dist/{winning-ads-ABN5OULS.js.map → winning-ads-QOAYIR5U.js.map} +0 -0
- /package/dist/{x-WK2VQDPF.js.map → x-VCSMV7T5.js.map} +0 -0
|
@@ -0,0 +1,1078 @@
|
|
|
1
|
+
// ../api/src/ads-meta/adStudies.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
// ../api/src/ads-meta/limits.ts
|
|
5
|
+
var META_LIMITS = {
|
|
6
|
+
/** Meta caps the labels on one object at 50 (`adlabels`, "max 50"); it documents no name length, so 255. */
|
|
7
|
+
adLabel: {
|
|
8
|
+
nameMax: 255,
|
|
9
|
+
perObjectMax: 50
|
|
10
|
+
},
|
|
11
|
+
campaign: {
|
|
12
|
+
nameMax: 400
|
|
13
|
+
},
|
|
14
|
+
adSet: {
|
|
15
|
+
nameMax: 400,
|
|
16
|
+
/**
|
|
17
|
+
* Meta's own bounds for a minimum ROAS, as a multiple of spend (2 = 200%):
|
|
18
|
+
* "roas_average_floor … should be larger than or equal to 0.001 and smaller
|
|
19
|
+
* than or equal to 1000" (subcode 1815888, live on v25.0, 2026-10-14).
|
|
20
|
+
*/
|
|
21
|
+
minRoasMin: 1e-3,
|
|
22
|
+
minRoasMax: 1e3,
|
|
23
|
+
/** Frequency caps: `interval_days` and `max_frequency` are each 1–90 (Meta's #100 refusal, live v25.0). */
|
|
24
|
+
frequencyIntervalDaysMax: 90,
|
|
25
|
+
frequencyMaxImpressionsMax: 90,
|
|
26
|
+
/** "You can set up a maximum of 50 high demand periods per campaign or ad set" (High Demand Period reference). */
|
|
27
|
+
budgetSchedulesMax: 50
|
|
28
|
+
},
|
|
29
|
+
ad: {
|
|
30
|
+
nameMax: 400
|
|
31
|
+
},
|
|
32
|
+
creative: {
|
|
33
|
+
nameMax: 400,
|
|
34
|
+
/** Feed truncates the primary text past this with "… See more". */
|
|
35
|
+
messageSoftMax: 125,
|
|
36
|
+
messageHardMax: 5e3,
|
|
37
|
+
/** Below this, primary text reads as too thin to carry a hook + value + reason to act. */
|
|
38
|
+
messageGoodMin: 40,
|
|
39
|
+
headlineMax: 255,
|
|
40
|
+
descriptionMax: 300,
|
|
41
|
+
carouselCardsMin: 2,
|
|
42
|
+
carouselCardsMax: 10,
|
|
43
|
+
/** Carousels tell a fuller story and give Meta more to optimize at this many cards. */
|
|
44
|
+
carouselCardsGoodMin: 3,
|
|
45
|
+
dynamicTextsMin: 1,
|
|
46
|
+
dynamicTextsMax: 5,
|
|
47
|
+
/** Dynamic ads mix and match best with at least this many media assets. */
|
|
48
|
+
dynamicAssetsGoodMin: 3,
|
|
49
|
+
/**
|
|
50
|
+
* `asset_feed_spec` limits (Meta's Asset Feed Spec Options, "restrictions"):
|
|
51
|
+
* body text 1024 characters, titles and descriptions 255, at most 10
|
|
52
|
+
* images and 10 videos, 30 assets in all (the ad format counts as one).
|
|
53
|
+
*/
|
|
54
|
+
assetFeedBodyMax: 1024,
|
|
55
|
+
assetFeedTitleMax: 255,
|
|
56
|
+
assetFeedImagesMax: 10,
|
|
57
|
+
assetFeedVideosMax: 10,
|
|
58
|
+
assetFeedAssetsMax: 30
|
|
59
|
+
},
|
|
60
|
+
audience: {
|
|
61
|
+
nameMax: 100,
|
|
62
|
+
/** Website/engagement audiences below this rarely serve. */
|
|
63
|
+
minLookalikeSourceRows: 100,
|
|
64
|
+
retentionDaysMax: 180
|
|
65
|
+
},
|
|
66
|
+
customConversion: {
|
|
67
|
+
nameMax: 100,
|
|
68
|
+
descriptionMax: 500,
|
|
69
|
+
/**
|
|
70
|
+
* Meta's hard cap per ad account. It matters because deleting a custom
|
|
71
|
+
* conversion archives it rather than removing it, so a chat that creates
|
|
72
|
+
* one per campaign spends slots that only a person, in Events Manager, can
|
|
73
|
+
* think about reclaiming.
|
|
74
|
+
*/
|
|
75
|
+
perAccountMax: 100
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
var OBJECTIVES = [
|
|
79
|
+
"OUTCOME_TRAFFIC",
|
|
80
|
+
"OUTCOME_ENGAGEMENT",
|
|
81
|
+
"OUTCOME_LEADS",
|
|
82
|
+
"OUTCOME_SALES",
|
|
83
|
+
"OUTCOME_AWARENESS",
|
|
84
|
+
"OUTCOME_APP_PROMOTION"
|
|
85
|
+
];
|
|
86
|
+
var SPECIAL_AD_CATEGORIES = [
|
|
87
|
+
"NONE",
|
|
88
|
+
"HOUSING",
|
|
89
|
+
"EMPLOYMENT",
|
|
90
|
+
/** Deprecated by Meta on 2025-01-14 — replaced by FINANCIAL_PRODUCTS_SERVICES. Still accepted as input and mapped on the wire. */
|
|
91
|
+
"CREDIT",
|
|
92
|
+
"ISSUES_ELECTIONS_POLITICS",
|
|
93
|
+
"FINANCIAL_PRODUCTS_SERVICES",
|
|
94
|
+
"ONLINE_GAMBLING_AND_GAMING"
|
|
95
|
+
];
|
|
96
|
+
var SPECIAL_CATEGORIES_REQUIRING_COUNTRY = ["ISSUES_ELECTIONS_POLITICS"];
|
|
97
|
+
var BUYING_TYPES = ["AUCTION", "RESERVED"];
|
|
98
|
+
var BID_STRATEGIES = [
|
|
99
|
+
"LOWEST_COST_WITHOUT_CAP",
|
|
100
|
+
"LOWEST_COST_WITH_BID_CAP",
|
|
101
|
+
"COST_CAP",
|
|
102
|
+
"LOWEST_COST_WITH_MIN_ROAS"
|
|
103
|
+
];
|
|
104
|
+
var BID_STRATEGIES_REQUIRING_AMOUNT = ["LOWEST_COST_WITH_BID_CAP", "COST_CAP"];
|
|
105
|
+
var ROAS_FLOOR_SCALE = 1e4;
|
|
106
|
+
var BID_STRATEGIES_FORBIDDING_AMOUNT = [
|
|
107
|
+
"LOWEST_COST_WITHOUT_CAP",
|
|
108
|
+
"LOWEST_COST_WITH_MIN_ROAS"
|
|
109
|
+
];
|
|
110
|
+
var BILLING_EVENTS = [
|
|
111
|
+
"APP_INSTALLS",
|
|
112
|
+
"CLICKS",
|
|
113
|
+
"IMPRESSIONS",
|
|
114
|
+
"LINK_CLICKS",
|
|
115
|
+
"NONE",
|
|
116
|
+
"OFFER_CLAIMS",
|
|
117
|
+
"PAGE_LIKES",
|
|
118
|
+
"POST_ENGAGEMENT",
|
|
119
|
+
"THRUPLAY",
|
|
120
|
+
"PURCHASE",
|
|
121
|
+
"LISTING_INTERACTION"
|
|
122
|
+
];
|
|
123
|
+
var OPTIMIZATION_GOALS = [
|
|
124
|
+
"NONE",
|
|
125
|
+
"APP_INSTALLS",
|
|
126
|
+
"AD_RECALL_LIFT",
|
|
127
|
+
"ENGAGED_USERS",
|
|
128
|
+
"EVENT_RESPONSES",
|
|
129
|
+
"IMPRESSIONS",
|
|
130
|
+
"LEAD_GENERATION",
|
|
131
|
+
"QUALITY_LEAD",
|
|
132
|
+
"QUALITY_CALL",
|
|
133
|
+
"LINK_CLICKS",
|
|
134
|
+
"OFFSITE_CONVERSIONS",
|
|
135
|
+
"LANDING_PAGE_VIEWS",
|
|
136
|
+
"PAGE_LIKES",
|
|
137
|
+
"POST_ENGAGEMENT",
|
|
138
|
+
"REACH",
|
|
139
|
+
"THRUPLAY",
|
|
140
|
+
"VALUE",
|
|
141
|
+
"CONVERSATIONS",
|
|
142
|
+
"DERIVED_EVENTS",
|
|
143
|
+
// Added 2026-09-18 from Meta's own generated enum spec
|
|
144
|
+
// (facebook-business-sdk-codegen › AdSet_optimization_goal). Every one of these
|
|
145
|
+
// is a goal Meta accepts and Baker used to refuse at stage time — the messaging
|
|
146
|
+
// and Instagram-profile goals are the ones that cost real campaigns, because a
|
|
147
|
+
// click-to-WhatsApp ad set cannot be expressed without them.
|
|
148
|
+
"ADVERTISER_SILOED_VALUE",
|
|
149
|
+
"APP_INSTALLS_AND_OFFSITE_CONVERSIONS",
|
|
150
|
+
"AUTOMATIC_OBJECTIVE",
|
|
151
|
+
"ENGAGED_PAGE_VIEWS",
|
|
152
|
+
"IN_APP_VALUE",
|
|
153
|
+
"MEANINGFUL_CALL_ATTEMPT",
|
|
154
|
+
"MESSAGING_APPOINTMENT_CONVERSION",
|
|
155
|
+
"MESSAGING_DEEP_CONVERSATION_AND_FOLLOW",
|
|
156
|
+
"MESSAGING_PURCHASE_CONVERSION",
|
|
157
|
+
"PROFILE_AND_PAGE_ENGAGEMENT",
|
|
158
|
+
"PROFILE_VISIT",
|
|
159
|
+
"REMINDERS_SET",
|
|
160
|
+
"SUBSCRIBERS",
|
|
161
|
+
"VISIT_INSTAGRAM_PROFILE"
|
|
162
|
+
];
|
|
163
|
+
var OPTIMIZATION_GOALS_REQUIRING_PAGE = [
|
|
164
|
+
"LEAD_GENERATION",
|
|
165
|
+
"QUALITY_LEAD",
|
|
166
|
+
"PAGE_LIKES"
|
|
167
|
+
];
|
|
168
|
+
var OPTIMIZATION_GOALS_REQUIRING_PIXEL = ["OFFSITE_CONVERSIONS"];
|
|
169
|
+
var OPTIMIZATION_GOALS_REQUIRING_CONVERSION_SOURCE = ["VALUE"];
|
|
170
|
+
var OPTIMIZATION_GOALS_REQUIRING_APP = ["APP_INSTALLS"];
|
|
171
|
+
var DESTINATION_TYPES = [
|
|
172
|
+
"WEBSITE",
|
|
173
|
+
"APP",
|
|
174
|
+
"MESSENGER",
|
|
175
|
+
"INSTAGRAM_DIRECT",
|
|
176
|
+
"ON_AD",
|
|
177
|
+
"ON_PAGE",
|
|
178
|
+
"ON_POST",
|
|
179
|
+
"ON_VIDEO",
|
|
180
|
+
"WHATSAPP",
|
|
181
|
+
"PHONE_CALL",
|
|
182
|
+
"INSTAGRAM_PROFILE",
|
|
183
|
+
"SHOP_AUTOMATIC",
|
|
184
|
+
// Added 2026-09-18 from adcampaign_destination_type. The four MESSAGING_* values
|
|
185
|
+
// are the click-to-message destinations (Messenger / Instagram Direct / WhatsApp
|
|
186
|
+
// in every combination Meta ships); without them Baker could not stage a
|
|
187
|
+
// click-to-WhatsApp ad set at all.
|
|
188
|
+
"APPLINKS_AUTOMATIC",
|
|
189
|
+
"FACEBOOK",
|
|
190
|
+
"FACEBOOK_LIVE",
|
|
191
|
+
"FACEBOOK_PAGE",
|
|
192
|
+
"IMAGINE",
|
|
193
|
+
"INSTAGRAM_LIVE",
|
|
194
|
+
"INSTAGRAM_PROFILE_AND_FACEBOOK_PAGE",
|
|
195
|
+
"MESSAGING_INSTAGRAM_DIRECT_MESSENGER",
|
|
196
|
+
"MESSAGING_INSTAGRAM_DIRECT_MESSENGER_WHATSAPP",
|
|
197
|
+
"MESSAGING_INSTAGRAM_DIRECT_WHATSAPP",
|
|
198
|
+
"MESSAGING_MESSENGER_WHATSAPP",
|
|
199
|
+
"ON_EVENT"
|
|
200
|
+
];
|
|
201
|
+
var CUSTOM_EVENT_TYPES = [
|
|
202
|
+
"PURCHASE",
|
|
203
|
+
"LEAD",
|
|
204
|
+
"COMPLETE_REGISTRATION",
|
|
205
|
+
"ADD_TO_CART",
|
|
206
|
+
"ADD_PAYMENT_INFO",
|
|
207
|
+
"INITIATED_CHECKOUT",
|
|
208
|
+
"CONTENT_VIEW",
|
|
209
|
+
"SEARCH",
|
|
210
|
+
"SUBSCRIBE",
|
|
211
|
+
"START_TRIAL",
|
|
212
|
+
"CONTACT",
|
|
213
|
+
"OTHER",
|
|
214
|
+
// Added 2026-09-18 from AdPromotedObject_custom_event_type. SCHEDULE,
|
|
215
|
+
// SUBMIT_APPLICATION, SERVICE_BOOKING_REQUEST and
|
|
216
|
+
// MESSAGING_CONVERSATION_STARTED_7D are the conversions service businesses and
|
|
217
|
+
// click-to-message campaigns actually optimize toward.
|
|
218
|
+
"ACHIEVEMENT_UNLOCKED",
|
|
219
|
+
"ADD_TO_WISHLIST",
|
|
220
|
+
"AD_IMPRESSION",
|
|
221
|
+
"CUSTOMIZE_PRODUCT",
|
|
222
|
+
"D2_RETENTION",
|
|
223
|
+
"D7_RETENTION",
|
|
224
|
+
"DONATE",
|
|
225
|
+
"FIND_LOCATION",
|
|
226
|
+
"LEVEL_ACHIEVED",
|
|
227
|
+
"LISTING_INTERACTION",
|
|
228
|
+
"MESSAGING_CONVERSATION_STARTED_7D",
|
|
229
|
+
"RATE",
|
|
230
|
+
"SCHEDULE",
|
|
231
|
+
"SERVICE_BOOKING_REQUEST",
|
|
232
|
+
"SPENT_CREDITS",
|
|
233
|
+
"SUBMIT_APPLICATION",
|
|
234
|
+
"TUTORIAL_COMPLETION"
|
|
235
|
+
];
|
|
236
|
+
var OPTIMIZATION_GOALS_WITH_FREQUENCY_CAP = ["REACH", "THRUPLAY"];
|
|
237
|
+
var FREQUENCY_CAP_EVENTS = [
|
|
238
|
+
"IMPRESSIONS",
|
|
239
|
+
"VIDEO_VIEWS",
|
|
240
|
+
"VIDEO_VIEWS_2S",
|
|
241
|
+
"VIDEO_VIEWS_15S",
|
|
242
|
+
"VIDEO_VIEWS_6S"
|
|
243
|
+
];
|
|
244
|
+
var FREQUENCY_CAP_TYPES = ["CAP", "TARGET"];
|
|
245
|
+
var PACING_TYPES = ["standard", "no_pacing", "day_parting"];
|
|
246
|
+
var SCHEDULE_TIMEZONE_TYPES = ["USER", "ADVERTISER"];
|
|
247
|
+
var ATTRIBUTION_EVENT_TYPES = ["CLICK_THROUGH", "VIEW_THROUGH", "ENGAGED_VIDEO_VIEW"];
|
|
248
|
+
var ATTRIBUTION_MAX_WINDOW_DAYS = {
|
|
249
|
+
CLICK_THROUGH: 7,
|
|
250
|
+
VIEW_THROUGH: 1,
|
|
251
|
+
ENGAGED_VIDEO_VIEW: 1
|
|
252
|
+
};
|
|
253
|
+
var ADVANTAGE_AUDIENCE_OPEN_AGE_MAX = 65;
|
|
254
|
+
var ADVANTAGE_AUDIENCE_MAX_HARD_AGE_MIN = 25;
|
|
255
|
+
var EU_DSA_COUNTRIES = /* @__PURE__ */ new Set([
|
|
256
|
+
"AT",
|
|
257
|
+
"BE",
|
|
258
|
+
"BG",
|
|
259
|
+
"HR",
|
|
260
|
+
"CY",
|
|
261
|
+
"CZ",
|
|
262
|
+
"DK",
|
|
263
|
+
"EE",
|
|
264
|
+
"FI",
|
|
265
|
+
"FR",
|
|
266
|
+
"DE",
|
|
267
|
+
"GR",
|
|
268
|
+
"HU",
|
|
269
|
+
"IE",
|
|
270
|
+
"IT",
|
|
271
|
+
"LV",
|
|
272
|
+
"LT",
|
|
273
|
+
"LU",
|
|
274
|
+
"MT",
|
|
275
|
+
"NL",
|
|
276
|
+
"PL",
|
|
277
|
+
"PT",
|
|
278
|
+
"RO",
|
|
279
|
+
"SK",
|
|
280
|
+
"SI",
|
|
281
|
+
"ES",
|
|
282
|
+
"SE"
|
|
283
|
+
]);
|
|
284
|
+
var CTA_TYPES = [
|
|
285
|
+
"BOOK_TRAVEL",
|
|
286
|
+
"CONTACT_US",
|
|
287
|
+
"DONATE",
|
|
288
|
+
"DONATE_NOW",
|
|
289
|
+
"DOWNLOAD",
|
|
290
|
+
"GET_DIRECTIONS",
|
|
291
|
+
"GO_LIVE",
|
|
292
|
+
"INTERESTED",
|
|
293
|
+
"LEARN_MORE",
|
|
294
|
+
"SEE_DETAILS",
|
|
295
|
+
"LIKE_PAGE",
|
|
296
|
+
"MESSAGE_PAGE",
|
|
297
|
+
"RAISE_MONEY",
|
|
298
|
+
"SAVE",
|
|
299
|
+
"SEND_TIP",
|
|
300
|
+
"SHOP_NOW",
|
|
301
|
+
"SIGN_UP",
|
|
302
|
+
"VIEW_INSTAGRAM_PROFILE",
|
|
303
|
+
"INSTAGRAM_MESSAGE",
|
|
304
|
+
"LOYALTY_LEARN_MORE",
|
|
305
|
+
"PURCHASE_GIFT_CARDS",
|
|
306
|
+
"PAY_TO_ACCESS",
|
|
307
|
+
"SEE_MORE",
|
|
308
|
+
"TRY_IN_CAMERA",
|
|
309
|
+
"WHATSAPP_LINK",
|
|
310
|
+
"GET_IN_TOUCH",
|
|
311
|
+
"TRY_NOW",
|
|
312
|
+
"ASK_A_QUESTION",
|
|
313
|
+
"START_A_CHAT",
|
|
314
|
+
"CHAT_NOW",
|
|
315
|
+
"ASK_US",
|
|
316
|
+
"CHAT_WITH_US",
|
|
317
|
+
"BOOK_NOW",
|
|
318
|
+
"CHECK_AVAILABILITY",
|
|
319
|
+
"ORDER_NOW",
|
|
320
|
+
"WHATSAPP_MESSAGE",
|
|
321
|
+
"GET_MOBILE_APP",
|
|
322
|
+
"INSTALL_MOBILE_APP",
|
|
323
|
+
"USE_MOBILE_APP",
|
|
324
|
+
"INSTALL_APP",
|
|
325
|
+
"USE_APP",
|
|
326
|
+
"PLAY_GAME",
|
|
327
|
+
"TRY_DEMO",
|
|
328
|
+
"WATCH_VIDEO",
|
|
329
|
+
"WATCH_MORE",
|
|
330
|
+
"OPEN_LINK",
|
|
331
|
+
"NO_BUTTON",
|
|
332
|
+
"LISTEN_MUSIC",
|
|
333
|
+
"MOBILE_DOWNLOAD",
|
|
334
|
+
"GET_OFFER",
|
|
335
|
+
"GET_OFFER_VIEW",
|
|
336
|
+
"BUY_NOW",
|
|
337
|
+
"BUY_TICKETS",
|
|
338
|
+
"UPDATE_APP",
|
|
339
|
+
"BET_NOW",
|
|
340
|
+
"ADD_TO_CART",
|
|
341
|
+
"SELL_NOW",
|
|
342
|
+
"GET_SHOWTIMES",
|
|
343
|
+
"LISTEN_NOW",
|
|
344
|
+
"GET_EVENT_TICKETS",
|
|
345
|
+
"REMIND_ME",
|
|
346
|
+
"SEARCH_MORE",
|
|
347
|
+
"PRE_REGISTER",
|
|
348
|
+
"SWIPE_UP_PRODUCT",
|
|
349
|
+
"SWIPE_UP_SHOP",
|
|
350
|
+
"PLAY_GAME_ON_FACEBOOK",
|
|
351
|
+
"VISIT_WORLD",
|
|
352
|
+
"OPEN_INSTANT_APP",
|
|
353
|
+
"JOIN_GROUP",
|
|
354
|
+
"GET_PROMOTIONS",
|
|
355
|
+
"SEND_UPDATES",
|
|
356
|
+
"INQUIRE_NOW",
|
|
357
|
+
"VISIT_PROFILE",
|
|
358
|
+
"CHAT_ON_WHATSAPP",
|
|
359
|
+
"EXPLORE_MORE",
|
|
360
|
+
"CONFIRM",
|
|
361
|
+
"JOIN_CHANNEL",
|
|
362
|
+
"MAKE_AN_APPOINTMENT",
|
|
363
|
+
"ASK_ABOUT_SERVICES",
|
|
364
|
+
"BOOK_A_CONSULTATION",
|
|
365
|
+
"GET_A_QUOTE",
|
|
366
|
+
"BUY_VIA_MESSAGE",
|
|
367
|
+
"ASK_FOR_MORE_INFO",
|
|
368
|
+
"VIEW_PRODUCT",
|
|
369
|
+
"VIEW_CHANNEL",
|
|
370
|
+
"WATCH_LIVE_VIDEO",
|
|
371
|
+
"JOIN_LIVE_VIDEO",
|
|
372
|
+
"IMAGINE",
|
|
373
|
+
"CALL",
|
|
374
|
+
"MISSED_CALL",
|
|
375
|
+
"CALL_NOW",
|
|
376
|
+
"CALL_ME",
|
|
377
|
+
"APPLY_NOW",
|
|
378
|
+
"BUY",
|
|
379
|
+
"GET_QUOTE",
|
|
380
|
+
"SUBSCRIBE",
|
|
381
|
+
"RECORD_NOW",
|
|
382
|
+
"VOTE_NOW",
|
|
383
|
+
"GIVE_FREE_RIDES",
|
|
384
|
+
"REGISTER_NOW",
|
|
385
|
+
"OPEN_MESSENGER_EXT",
|
|
386
|
+
"EVENT_RSVP",
|
|
387
|
+
"CIVIC_ACTION",
|
|
388
|
+
"SEND_INVITES",
|
|
389
|
+
"REFER_FRIENDS",
|
|
390
|
+
"REQUEST_TIME",
|
|
391
|
+
"SEE_MENU",
|
|
392
|
+
"SEARCH",
|
|
393
|
+
"TRY_IT",
|
|
394
|
+
"TRY_ON",
|
|
395
|
+
"LINK_CARD",
|
|
396
|
+
"DIAL_CODE",
|
|
397
|
+
"FIND_YOUR_GROUPS",
|
|
398
|
+
"START_ORDER",
|
|
399
|
+
// Added 2026-09-18 from Meta's generated enum spec
|
|
400
|
+
// (AdCreative_call_to_action_type). Additive on purpose: 37 of the values above
|
|
401
|
+
// are absent from that spec and present in the live 400, which is the
|
|
402
|
+
// disagreement the note above is about — so the spec widens this list and never
|
|
403
|
+
// prunes it.
|
|
404
|
+
"AUDIO_CALL",
|
|
405
|
+
"BROWSE_SHOP",
|
|
406
|
+
"CONTACT",
|
|
407
|
+
"FIND_A_GROUP",
|
|
408
|
+
"FIND_OUT_MORE",
|
|
409
|
+
"FOLLOW_NEWS_STORYLINE",
|
|
410
|
+
"FOLLOW_PAGE",
|
|
411
|
+
"FOLLOW_USER",
|
|
412
|
+
"GET_DETAILS",
|
|
413
|
+
"GET_STARTED",
|
|
414
|
+
"SAY_THANKS",
|
|
415
|
+
"SEE_SHOP",
|
|
416
|
+
"SEND_A_GIFT",
|
|
417
|
+
"SEND_GIFT_MONEY",
|
|
418
|
+
"SHARE",
|
|
419
|
+
"SHOP_WITH_AI",
|
|
420
|
+
"SOTTO_SUBSCRIBE",
|
|
421
|
+
"TRY_ON_WITH_AI",
|
|
422
|
+
"VIDEO_ANNOTATION",
|
|
423
|
+
"VIDEO_CALL",
|
|
424
|
+
"VIEW_CART",
|
|
425
|
+
"VIEW_IN_CART",
|
|
426
|
+
"VISIT_PAGES_FEED",
|
|
427
|
+
"VISIT_WEBSITE",
|
|
428
|
+
"WOODHENGE_SUPPORT"
|
|
429
|
+
];
|
|
430
|
+
var ASSET_FEED_CTA_TYPES = [
|
|
431
|
+
"OPEN_LINK",
|
|
432
|
+
"LIKE_PAGE",
|
|
433
|
+
"SHOP_NOW",
|
|
434
|
+
"PLAY_GAME",
|
|
435
|
+
"INSTALL_APP",
|
|
436
|
+
"USE_APP",
|
|
437
|
+
"CALL",
|
|
438
|
+
"CALL_ME",
|
|
439
|
+
"VIDEO_CALL",
|
|
440
|
+
"INSTALL_MOBILE_APP",
|
|
441
|
+
"USE_MOBILE_APP",
|
|
442
|
+
"MOBILE_DOWNLOAD",
|
|
443
|
+
"BOOK_TRAVEL",
|
|
444
|
+
"LISTEN_MUSIC",
|
|
445
|
+
"WATCH_VIDEO",
|
|
446
|
+
"LEARN_MORE",
|
|
447
|
+
"SIGN_UP",
|
|
448
|
+
"DOWNLOAD",
|
|
449
|
+
"WATCH_MORE",
|
|
450
|
+
"NO_BUTTON",
|
|
451
|
+
"VISIT_PAGES_FEED",
|
|
452
|
+
"CALL_NOW",
|
|
453
|
+
"APPLY_NOW",
|
|
454
|
+
"CONTACT",
|
|
455
|
+
"BUY_NOW",
|
|
456
|
+
"GET_OFFER",
|
|
457
|
+
"GET_OFFER_VIEW",
|
|
458
|
+
"BUY_TICKETS",
|
|
459
|
+
"UPDATE_APP",
|
|
460
|
+
"GET_DIRECTIONS",
|
|
461
|
+
"BUY",
|
|
462
|
+
"SEND_UPDATES",
|
|
463
|
+
"MESSAGE_PAGE",
|
|
464
|
+
"DONATE",
|
|
465
|
+
"SUBSCRIBE",
|
|
466
|
+
"SAY_THANKS",
|
|
467
|
+
"SELL_NOW",
|
|
468
|
+
"SHARE",
|
|
469
|
+
"DONATE_NOW",
|
|
470
|
+
"GET_QUOTE",
|
|
471
|
+
"CONTACT_US",
|
|
472
|
+
"ORDER_NOW",
|
|
473
|
+
"START_ORDER",
|
|
474
|
+
"ADD_TO_CART",
|
|
475
|
+
"VIEW_CART",
|
|
476
|
+
"VIEW_IN_CART",
|
|
477
|
+
"VIDEO_ANNOTATION",
|
|
478
|
+
"RECORD_NOW",
|
|
479
|
+
"INQUIRE_NOW",
|
|
480
|
+
"CONFIRM",
|
|
481
|
+
"REFER_FRIENDS",
|
|
482
|
+
"REQUEST_TIME",
|
|
483
|
+
"GET_SHOWTIMES",
|
|
484
|
+
"LISTEN_NOW",
|
|
485
|
+
"TRY_DEMO",
|
|
486
|
+
"WOODHENGE_SUPPORT",
|
|
487
|
+
"SOTTO_SUBSCRIBE",
|
|
488
|
+
"FOLLOW_USER",
|
|
489
|
+
"RAISE_MONEY",
|
|
490
|
+
"SEE_SHOP",
|
|
491
|
+
"GET_DETAILS",
|
|
492
|
+
"FIND_OUT_MORE",
|
|
493
|
+
"VISIT_WEBSITE",
|
|
494
|
+
"BROWSE_SHOP",
|
|
495
|
+
"EVENT_RSVP",
|
|
496
|
+
"WHATSAPP_MESSAGE",
|
|
497
|
+
"FOLLOW_NEWS_STORYLINE",
|
|
498
|
+
"SEE_MORE",
|
|
499
|
+
"BOOK_NOW",
|
|
500
|
+
"FIND_A_GROUP",
|
|
501
|
+
"FIND_YOUR_GROUPS",
|
|
502
|
+
"PAY_TO_ACCESS",
|
|
503
|
+
"PURCHASE_GIFT_CARDS",
|
|
504
|
+
"FOLLOW_PAGE",
|
|
505
|
+
"SEND_A_GIFT",
|
|
506
|
+
"SWIPE_UP_SHOP",
|
|
507
|
+
"SWIPE_UP_PRODUCT",
|
|
508
|
+
"SEND_GIFT_MONEY",
|
|
509
|
+
"PLAY_GAME_ON_FACEBOOK",
|
|
510
|
+
"GET_STARTED",
|
|
511
|
+
"OPEN_INSTANT_APP",
|
|
512
|
+
"AUDIO_CALL",
|
|
513
|
+
"GET_PROMOTIONS",
|
|
514
|
+
"JOIN_CHANNEL",
|
|
515
|
+
"MAKE_AN_APPOINTMENT",
|
|
516
|
+
"ASK_ABOUT_SERVICES",
|
|
517
|
+
"BOOK_A_CONSULTATION",
|
|
518
|
+
"GET_A_QUOTE",
|
|
519
|
+
"BUY_VIA_MESSAGE",
|
|
520
|
+
"ASK_FOR_MORE_INFO",
|
|
521
|
+
"CHAT_WITH_US",
|
|
522
|
+
"VIEW_PRODUCT",
|
|
523
|
+
"VIEW_CHANNEL",
|
|
524
|
+
"GET_IN_TOUCH",
|
|
525
|
+
"ASK_A_QUESTION",
|
|
526
|
+
"START_A_CHAT",
|
|
527
|
+
"CHAT_NOW",
|
|
528
|
+
"ASK_US",
|
|
529
|
+
"WATCH_LIVE_VIDEO",
|
|
530
|
+
"JOIN_LIVE_VIDEO",
|
|
531
|
+
"SHOP_WITH_AI",
|
|
532
|
+
"TRY_ON_WITH_AI"
|
|
533
|
+
];
|
|
534
|
+
var LEAD_FORM_CTA_TYPES = [
|
|
535
|
+
"APPLY_NOW",
|
|
536
|
+
"DOWNLOAD",
|
|
537
|
+
"GET_QUOTE",
|
|
538
|
+
"LEARN_MORE",
|
|
539
|
+
"SIGN_UP",
|
|
540
|
+
"SUBSCRIBE"
|
|
541
|
+
];
|
|
542
|
+
var AD_FORMATS = ["SINGLE_IMAGE", "CAROUSEL", "SINGLE_VIDEO", "AUTOMATIC_FORMAT"];
|
|
543
|
+
var ENROLL_STATUSES = ["OPT_IN", "OPT_OUT"];
|
|
544
|
+
var VISUAL_ENHANCEMENT_FEATURES = {
|
|
545
|
+
adapt_to_placement: "Adapt the picture to each placement",
|
|
546
|
+
add_text_overlay: "Add text on top of the media",
|
|
547
|
+
audio: "Add audio",
|
|
548
|
+
carousel_to_video: "Turn the carousel into a video",
|
|
549
|
+
creative_stickers: "Add stickers",
|
|
550
|
+
cv_transformation: "Visual transformations",
|
|
551
|
+
image_animation: "Animate the picture",
|
|
552
|
+
image_auto_crop: "Crop the picture automatically",
|
|
553
|
+
image_background_gen: "Generate a new background",
|
|
554
|
+
image_banner: "Add a banner",
|
|
555
|
+
image_brightness_and_contrast: "Adjust brightness and contrast",
|
|
556
|
+
image_end_card: "Add an end card",
|
|
557
|
+
image_enhancement: "Enhance the picture",
|
|
558
|
+
image_templates: "Put the picture in a template frame",
|
|
559
|
+
image_text_translation: "Translate text in the picture",
|
|
560
|
+
image_touchups: "Touch up the picture",
|
|
561
|
+
image_uncrop: "Expand the picture with AI",
|
|
562
|
+
media_liquidity_animated_image: "Animate the picture",
|
|
563
|
+
media_type_automation: "Turn the picture into a video",
|
|
564
|
+
multi_photo_to_video: "Turn several pictures into a video",
|
|
565
|
+
music_generation: "Generate music",
|
|
566
|
+
pac_genai_recomposition: "Recompose the media with AI per placement",
|
|
567
|
+
pac_recomposition: "Recompose the media per placement",
|
|
568
|
+
replace_media_text: "Replace text in the media",
|
|
569
|
+
reveal_details_over_time: "Reveal details over time",
|
|
570
|
+
text_overlay_translation: "Translate text overlays",
|
|
571
|
+
translate_voiceover: "Translate the voiceover",
|
|
572
|
+
video_auto_crop: "Crop the video automatically",
|
|
573
|
+
video_filtering: "Filter the video",
|
|
574
|
+
video_highlight: "Cut a highlight from the video",
|
|
575
|
+
video_highlights: "Cut highlights from the video",
|
|
576
|
+
video_to_image: "Turn the video into a picture",
|
|
577
|
+
video_uncrop: "Expand the video with AI",
|
|
578
|
+
video_uncrop_9x16_to_9x18: "Expand a vertical video",
|
|
579
|
+
ig_video_native_subtitle: "Add subtitles to the video"
|
|
580
|
+
};
|
|
581
|
+
var STAGEABLE_CREATE_STATUSES = ["ACTIVE", "PAUSED"];
|
|
582
|
+
var UPDATE_STATUSES = ["ACTIVE", "PAUSED", "ARCHIVED", "DELETED"];
|
|
583
|
+
var CREATIVE_UPDATE_STATUSES = ["ACTIVE", "PAUSED", "ARCHIVED", "DELETED"];
|
|
584
|
+
var CUSTOM_AUDIENCE_SUBTYPES = ["CUSTOM", "WEBSITE", "ENGAGEMENT", "LOOKALIKE"];
|
|
585
|
+
var CUSTOMER_FILE_SOURCES = [
|
|
586
|
+
"USER_PROVIDED_ONLY",
|
|
587
|
+
"PARTNER_PROVIDED_ONLY",
|
|
588
|
+
"BOTH_USER_AND_PARTNER_PROVIDED"
|
|
589
|
+
];
|
|
590
|
+
var MEDIA_KINDS = ["image", "video"];
|
|
591
|
+
var CURRENCY_MINIMUMS = {
|
|
592
|
+
USD: { dailyBudgetMin: 1 },
|
|
593
|
+
EUR: { dailyBudgetMin: 1 },
|
|
594
|
+
GBP: { dailyBudgetMin: 1 }
|
|
595
|
+
};
|
|
596
|
+
var DEFAULT_CURRENCY_MINIMUM = { dailyBudgetMin: 1 };
|
|
597
|
+
var TEMP_REF_REGEX = /^meta_temp_[A-Za-z0-9_-]{4,}$/;
|
|
598
|
+
var NUMERIC_ID_REGEX = /^\d+$/;
|
|
599
|
+
var IMAGE_HASH_REGEX = /^[A-Fa-f0-9]{16,}$/;
|
|
600
|
+
|
|
601
|
+
// ../api/src/ads-meta/adStudies.ts
|
|
602
|
+
var DAY_SECONDS = 86400;
|
|
603
|
+
var entityRefSchema = z.string().refine((value) => NUMERIC_ID_REGEX.test(value) || TEMP_REF_REGEX.test(value), {
|
|
604
|
+
message: "expected a numeric Meta id or a meta_temp_* reference from this chat"
|
|
605
|
+
});
|
|
606
|
+
var adStudyCellSchema = z.strictObject({
|
|
607
|
+
name: z.string().min(1).max(100),
|
|
608
|
+
/** Share of the audience that sees this version, in percent. */
|
|
609
|
+
treatment_percentage: z.number().positive().max(100),
|
|
610
|
+
/** A lift study: the share of the audience held out from the ads, so what they do is the baseline. */
|
|
611
|
+
control_percentage: z.number().positive().max(100).optional(),
|
|
612
|
+
adsets: z.array(entityRefSchema).min(1).max(100).optional(),
|
|
613
|
+
campaigns: z.array(entityRefSchema).min(1).max(100).optional(),
|
|
614
|
+
/** A creative test: the one ad this version runs. */
|
|
615
|
+
ads: z.array(entityRefSchema).min(1).max(100).optional()
|
|
616
|
+
});
|
|
617
|
+
var AD_STUDY_CONFIDENCE_LEVELS = [0.8, 0.9, 0.95];
|
|
618
|
+
var confidenceLevelSchema = z.number().refine((value) => AD_STUDY_CONFIDENCE_LEVELS.includes(value), {
|
|
619
|
+
message: "confidence_level must be 0.8, 0.9 or 0.95 (80%, 90% or 95%)"
|
|
620
|
+
});
|
|
621
|
+
var eventSourceSchema = z.strictObject({
|
|
622
|
+
id: z.string().regex(NUMERIC_ID_REGEX),
|
|
623
|
+
/** Pixel or app events counted, e.g. Lead, Purchase. Meta stores pixel events by their standard name. */
|
|
624
|
+
event_names: z.array(z.string().min(1)).min(1).optional()
|
|
625
|
+
});
|
|
626
|
+
var AD_STUDY_OBJECTIVE_TYPES = [
|
|
627
|
+
"CONVERSIONS",
|
|
628
|
+
"SALES",
|
|
629
|
+
"NONSALES",
|
|
630
|
+
"BRAND",
|
|
631
|
+
"BRANDLIFT",
|
|
632
|
+
"MAE",
|
|
633
|
+
"MAI"
|
|
634
|
+
];
|
|
635
|
+
var adStudyObjectiveSchema = z.strictObject({
|
|
636
|
+
name: z.string().min(1).max(100),
|
|
637
|
+
/** A split test is decided on CONVERSIONS; a lift study may measure sales, brand, app events (Meta's types). */
|
|
638
|
+
type: z.enum(AD_STUDY_OBJECTIVE_TYPES).default("CONVERSIONS"),
|
|
639
|
+
is_primary: z.boolean().optional(),
|
|
640
|
+
adspixels: z.array(eventSourceSchema).min(1).optional(),
|
|
641
|
+
customconversions: z.array(eventSourceSchema).min(1).optional(),
|
|
642
|
+
applications: z.array(eventSourceSchema).min(1).optional(),
|
|
643
|
+
offsite_datasets: z.array(eventSourceSchema).min(1).optional()
|
|
644
|
+
});
|
|
645
|
+
var OBJECTIVE_SOURCES = ["adspixels", "customconversions", "applications", "offsite_datasets"];
|
|
646
|
+
var AD_STUDY_MIN_CELLS = 2;
|
|
647
|
+
var AD_STUDY_MAX_CELLS = 150;
|
|
648
|
+
function cellObjects(cell) {
|
|
649
|
+
return [...cell.adsets ?? [], ...cell.campaigns ?? [], ...cell.ads ?? []];
|
|
650
|
+
}
|
|
651
|
+
function adStudyLevel(cells) {
|
|
652
|
+
const levels = new Set(
|
|
653
|
+
cells.flatMap(
|
|
654
|
+
(cell) => [cell.adsets ? "adsets" : [], cell.campaigns ? "campaigns" : [], cell.ads ? "ads" : []].flat()
|
|
655
|
+
)
|
|
656
|
+
);
|
|
657
|
+
return levels.size === 1 ? [...levels][0] : void 0;
|
|
658
|
+
}
|
|
659
|
+
function levelIssues(cells) {
|
|
660
|
+
const issues = [];
|
|
661
|
+
cells.forEach((cell, index) => {
|
|
662
|
+
if (cellObjects(cell).length === 0) {
|
|
663
|
+
issues.push({
|
|
664
|
+
path: ["cells", index],
|
|
665
|
+
message: `version "${cell.name}" runs nothing \u2014 give it the ad sets (adsets) or campaigns (campaigns) it shows`
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
if (cells.some((cell) => cell.ads)) {
|
|
670
|
+
issues.push({
|
|
671
|
+
path: ["cells"],
|
|
672
|
+
message: 'an A/B test compares ad sets or campaigns \u2014 to compare single ads of one ad set, stage a creative test (type "SPLIT_TEST_V2", `--type creative`)'
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
const named = cells.filter((cell) => cellObjects(cell).length > 0);
|
|
676
|
+
if (named.length > 0 && adStudyLevel(named) === void 0) {
|
|
677
|
+
issues.push({
|
|
678
|
+
path: ["cells"],
|
|
679
|
+
message: "the versions must be all ad sets or all campaigns \u2014 comparing an ad set with a campaign compares two different things"
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
return issues;
|
|
683
|
+
}
|
|
684
|
+
function duplicateObjectIssues(cells) {
|
|
685
|
+
const seen = /* @__PURE__ */ new Map();
|
|
686
|
+
const issues = [];
|
|
687
|
+
cells.forEach((cell, index) => {
|
|
688
|
+
for (const id of cellObjects(cell)) {
|
|
689
|
+
const first = seen.get(id);
|
|
690
|
+
if (first !== void 0 && first !== index) {
|
|
691
|
+
issues.push({
|
|
692
|
+
path: ["cells", index],
|
|
693
|
+
message: `${id} is in more than one version \u2014 each version must run its own ad sets or campaigns, or it is compared with itself`
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
seen.set(id, first ?? index);
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
return issues;
|
|
700
|
+
}
|
|
701
|
+
function shareIssues(cells) {
|
|
702
|
+
const total = Math.round(cells.reduce((sum, cell) => sum + cell.treatment_percentage, 0) * 100) / 100;
|
|
703
|
+
if (total === 100) {
|
|
704
|
+
return [];
|
|
705
|
+
}
|
|
706
|
+
return [
|
|
707
|
+
{
|
|
708
|
+
path: ["cells"],
|
|
709
|
+
message: `the versions' shares must add up to 100% (now ${total}%) \u2014 every person in the test sees exactly one version`
|
|
710
|
+
}
|
|
711
|
+
];
|
|
712
|
+
}
|
|
713
|
+
function cellIssues(cells) {
|
|
714
|
+
if (cells.length < AD_STUDY_MIN_CELLS) {
|
|
715
|
+
return [
|
|
716
|
+
{
|
|
717
|
+
path: ["cells"],
|
|
718
|
+
message: `an A/B test needs at least 2 versions (cells) \u2014 with ${cells.length} there is nothing to compare`
|
|
719
|
+
}
|
|
720
|
+
];
|
|
721
|
+
}
|
|
722
|
+
const issues = [...shareIssues(cells)];
|
|
723
|
+
issues.push(...levelIssues(cells), ...duplicateObjectIssues(cells));
|
|
724
|
+
return issues;
|
|
725
|
+
}
|
|
726
|
+
var AD_STUDY_MIN_DAYS = 1;
|
|
727
|
+
var AD_STUDY_MAX_DAYS = 30;
|
|
728
|
+
function adStudyDays(startTime, endTime) {
|
|
729
|
+
return Math.round((endTime - startTime) / DAY_SECONDS * 10) / 10;
|
|
730
|
+
}
|
|
731
|
+
function scheduleIssues(startTime, endTime) {
|
|
732
|
+
if (endTime <= startTime) {
|
|
733
|
+
return [{ path: ["end_time"], message: "the test ends before it starts \u2014 end_time must be after start_time" }];
|
|
734
|
+
}
|
|
735
|
+
const days = adStudyDays(startTime, endTime);
|
|
736
|
+
if (endTime - startTime < AD_STUDY_MIN_DAYS * DAY_SECONDS) {
|
|
737
|
+
return [{ path: ["end_time"], message: `an A/B test runs for at least 1 day (this one: ${days} days)` }];
|
|
738
|
+
}
|
|
739
|
+
if (endTime - startTime > AD_STUDY_MAX_DAYS * DAY_SECONDS) {
|
|
740
|
+
return [
|
|
741
|
+
{
|
|
742
|
+
path: ["end_time"],
|
|
743
|
+
message: `an A/B test runs for at most 30 days, as in Ads Manager (this one: ${days} days) \u2014 split a longer question into two tests`
|
|
744
|
+
}
|
|
745
|
+
];
|
|
746
|
+
}
|
|
747
|
+
return [];
|
|
748
|
+
}
|
|
749
|
+
function objectiveIssues(objectives) {
|
|
750
|
+
if (!objectives || objectives.length === 0) {
|
|
751
|
+
return [];
|
|
752
|
+
}
|
|
753
|
+
const issues = [];
|
|
754
|
+
objectives.forEach((objective, index) => {
|
|
755
|
+
if (!OBJECTIVE_SOURCES.some((source) => objective[source] !== void 0)) {
|
|
756
|
+
issues.push({
|
|
757
|
+
path: ["objectives", index],
|
|
758
|
+
message: `measure "${objective.name}" counts nothing \u2014 give it a pixel event (adspixels), a custom conversion (customconversions) or an app event (applications)`
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
const primaries = objectives.filter((objective) => objective.is_primary === true).length;
|
|
763
|
+
const implicitPrimary = objectives.length === 1 && objectives[0]?.is_primary === void 0;
|
|
764
|
+
if (primaries !== 1 && !implicitPrimary) {
|
|
765
|
+
issues.push({
|
|
766
|
+
path: ["objectives"],
|
|
767
|
+
message: `a test is decided on exactly one primary measure (is_primary: true) \u2014 ${primaries} are marked`
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
return issues;
|
|
771
|
+
}
|
|
772
|
+
var LIFT_MAX_DAYS = 90;
|
|
773
|
+
function observationEndIssues(study) {
|
|
774
|
+
if (study.observation_end_time === void 0 || study.observation_end_time >= study.end_time) return [];
|
|
775
|
+
return [
|
|
776
|
+
{
|
|
777
|
+
path: ["observation_end_time"],
|
|
778
|
+
message: "observation_end_time must run at least until the study ends (end_time) \u2014 Meta reads results until then"
|
|
779
|
+
}
|
|
780
|
+
];
|
|
781
|
+
}
|
|
782
|
+
function liftIssues(study) {
|
|
783
|
+
const issues = [];
|
|
784
|
+
if (study.cells.length === 0) issues.push({ path: ["cells"], message: "a lift study needs at least one cell" });
|
|
785
|
+
study.cells.forEach((cell, index) => {
|
|
786
|
+
const total = cell.treatment_percentage + (cell.control_percentage ?? 0);
|
|
787
|
+
if (cell.control_percentage === void 0) {
|
|
788
|
+
issues.push({
|
|
789
|
+
path: ["cells", index, "control_percentage"],
|
|
790
|
+
message: `cell "${cell.name}" holds nobody out \u2014 give it a control_percentage (the people who do not see the ads)`
|
|
791
|
+
});
|
|
792
|
+
} else if (total > 100) {
|
|
793
|
+
issues.push({
|
|
794
|
+
path: ["cells", index],
|
|
795
|
+
message: `cell "${cell.name}" splits ${total}% of its audience \u2014 at most 100%`
|
|
796
|
+
});
|
|
797
|
+
}
|
|
798
|
+
if (cell.ads)
|
|
799
|
+
issues.push({
|
|
800
|
+
path: ["cells", index, "ads"],
|
|
801
|
+
message: "a lift study measures campaigns or ad sets, not single ads"
|
|
802
|
+
});
|
|
803
|
+
else if (!cell.campaigns && !cell.adsets)
|
|
804
|
+
issues.push({
|
|
805
|
+
path: ["cells", index],
|
|
806
|
+
message: `cell "${cell.name}" runs nothing \u2014 give it the campaigns (campaigns) or ad sets (adsets) whose lift it measures`
|
|
807
|
+
});
|
|
808
|
+
});
|
|
809
|
+
issues.push(...observationEndIssues(study));
|
|
810
|
+
if (!study.objectives || study.objectives.length === 0) {
|
|
811
|
+
issues.push({
|
|
812
|
+
path: ["objectives"],
|
|
813
|
+
message: "a lift study needs a measure \u2014 the pixel event or conversion whose lift it reads"
|
|
814
|
+
});
|
|
815
|
+
}
|
|
816
|
+
if (study.end_time <= study.start_time) {
|
|
817
|
+
issues.push({ path: ["end_time"], message: "the study ends before it starts" });
|
|
818
|
+
} else if (study.end_time - study.start_time > LIFT_MAX_DAYS * DAY_SECONDS) {
|
|
819
|
+
issues.push({ path: ["end_time"], message: "a lift study runs for at most 90 days" });
|
|
820
|
+
}
|
|
821
|
+
return [...issues, ...duplicateObjectIssues(study.cells), ...objectiveIssues(study.objectives)].filter(
|
|
822
|
+
(issue, index, all) => all.findIndex((other) => other.message === issue.message) === index
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
var CREATIVE_TEST_MIN_CELLS = 2;
|
|
826
|
+
var CREATIVE_TEST_MAX_CELLS = 5;
|
|
827
|
+
function creativeTestIssues(study) {
|
|
828
|
+
const issues = [];
|
|
829
|
+
if (study.cells.length < CREATIVE_TEST_MIN_CELLS || study.cells.length > CREATIVE_TEST_MAX_CELLS) {
|
|
830
|
+
issues.push({ path: ["cells"], message: `a creative test compares 2 to 5 ads (now ${study.cells.length})` });
|
|
831
|
+
}
|
|
832
|
+
study.cells.forEach((cell, index) => {
|
|
833
|
+
if (cell.ads?.length !== 1 || cell.adsets || cell.campaigns) {
|
|
834
|
+
issues.push({ path: ["cells", index], message: `version "${cell.name}" runs exactly one ad (ads: [<ad id>])` });
|
|
835
|
+
}
|
|
836
|
+
});
|
|
837
|
+
if (!study.testDailyBudget) {
|
|
838
|
+
issues.push({
|
|
839
|
+
path: ["testDailyBudget"],
|
|
840
|
+
message: "a creative test needs testDailyBudget \u2014 the part of the ad set's daily budget the test spends"
|
|
841
|
+
});
|
|
842
|
+
}
|
|
843
|
+
return [
|
|
844
|
+
...issues,
|
|
845
|
+
...shareIssues(study.cells),
|
|
846
|
+
...duplicateObjectIssues(study.cells),
|
|
847
|
+
...scheduleIssues(study.start_time, study.end_time),
|
|
848
|
+
...observationEndIssues(study)
|
|
849
|
+
];
|
|
850
|
+
}
|
|
851
|
+
function adStudyIssues(study) {
|
|
852
|
+
if (study.type === "LIFT") return liftIssues(study);
|
|
853
|
+
if (study.type === "SPLIT_TEST_V2") return creativeTestIssues(study);
|
|
854
|
+
return [
|
|
855
|
+
...cellIssues(study.cells),
|
|
856
|
+
...scheduleIssues(study.start_time, study.end_time),
|
|
857
|
+
...objectiveIssues(study.objectives)
|
|
858
|
+
];
|
|
859
|
+
}
|
|
860
|
+
function addIssues(issues, ctx) {
|
|
861
|
+
for (const issue of issues) {
|
|
862
|
+
ctx.addIssue({ code: "custom", path: issue.path, message: issue.message });
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
var AD_STUDY_TYPES = ["SPLIT_TEST", "LIFT", "SPLIT_TEST_V2"];
|
|
866
|
+
var adStudyCreateBaseSchema = z.strictObject({
|
|
867
|
+
name: z.string().min(1).max(255),
|
|
868
|
+
description: z.string().max(1e3).optional(),
|
|
869
|
+
type: z.enum(AD_STUDY_TYPES).default("SPLIT_TEST"),
|
|
870
|
+
start_time: z.number().int().positive(),
|
|
871
|
+
end_time: z.number().int().positive(),
|
|
872
|
+
/** A lift study or creative test: when Meta stops counting results (≥ the end). Defaults to the end. */
|
|
873
|
+
observation_end_time: z.number().int().positive().optional(),
|
|
874
|
+
/** A creative test: the part of the ad set's daily budget it spends, major units. */
|
|
875
|
+
testDailyBudget: z.strictObject({
|
|
876
|
+
amount: z.string().regex(/^\d+(\.\d{1,2})?$/, "expected a decimal amount like 2 or 2.50"),
|
|
877
|
+
currencyCode: z.string().length(3).optional()
|
|
878
|
+
}).optional(),
|
|
879
|
+
cells: z.array(adStudyCellSchema).max(AD_STUDY_MAX_CELLS),
|
|
880
|
+
/** How sure Meta must be before it names a winner; Meta applies its own when none is sent. */
|
|
881
|
+
confidence_level: confidenceLevelSchema.optional(),
|
|
882
|
+
/** What the test is decided on. Without one, Meta compares cost per result on the campaigns' objective. */
|
|
883
|
+
objectives: z.array(adStudyObjectiveSchema).max(10).optional(),
|
|
884
|
+
/** The Business that owns the test — Meta creates studies on a Business. Filled by the backend from the ad account. */
|
|
885
|
+
business_id: z.string().regex(NUMERIC_ID_REGEX).optional()
|
|
886
|
+
});
|
|
887
|
+
var adStudyCreateSchema = adStudyCreateBaseSchema.superRefine(
|
|
888
|
+
(study, ctx) => addIssues(adStudyIssues(study), ctx)
|
|
889
|
+
);
|
|
890
|
+
var START_SOON_SECONDS = 6 * 3600;
|
|
891
|
+
var adStudyCellShareSchema = z.strictObject({
|
|
892
|
+
id: z.string().regex(NUMERIC_ID_REGEX),
|
|
893
|
+
treatment_percentage: z.number().positive().max(100)
|
|
894
|
+
});
|
|
895
|
+
var adStudyUpdateBaseSchema = z.strictObject({
|
|
896
|
+
name: z.string().min(1).max(255).optional(),
|
|
897
|
+
description: z.string().max(1e3).optional(),
|
|
898
|
+
start_time: z.number().int().positive().optional(),
|
|
899
|
+
end_time: z.number().int().positive().optional(),
|
|
900
|
+
/** A lift study or creative test: when Meta stops counting results (≥ the end). Moved out with a later end on its own (`carryObservationEnd`). */
|
|
901
|
+
observation_end_time: z.number().int().positive().optional(),
|
|
902
|
+
/** End the test at publish: the end is set a few minutes after the change applies (Meta refuses an end in the past). */
|
|
903
|
+
end_now: z.literal(true).optional(),
|
|
904
|
+
confidence_level: confidenceLevelSchema.optional(),
|
|
905
|
+
/** Every version's new share — Meta re-splits the whole audience at once, so name every cell. */
|
|
906
|
+
cells: z.array(adStudyCellShareSchema).min(AD_STUDY_MIN_CELLS).optional(),
|
|
907
|
+
/** Delete the test. Meta removes it, results and all; ending it keeps them. */
|
|
908
|
+
status: z.literal("DELETED").optional()
|
|
909
|
+
});
|
|
910
|
+
function updateShapeIssues(p) {
|
|
911
|
+
const set = Object.entries(p).filter(([, value]) => value !== void 0);
|
|
912
|
+
if (set.length === 0) {
|
|
913
|
+
return [{ path: [], message: "update needs at least one field" }];
|
|
914
|
+
}
|
|
915
|
+
if (p.status === "DELETED" && set.length > 1) {
|
|
916
|
+
return [{ path: ["status"], message: "delete alone \u2014 a deleted test takes no other change" }];
|
|
917
|
+
}
|
|
918
|
+
const issues = [];
|
|
919
|
+
if (p.end_now && p.end_time !== void 0) {
|
|
920
|
+
issues.push({ path: ["end_now"], message: "end now or set end_time, not both" });
|
|
921
|
+
}
|
|
922
|
+
if (p.observation_end_time !== void 0 && p.end_time !== void 0 && p.observation_end_time < p.end_time) {
|
|
923
|
+
issues.push({
|
|
924
|
+
path: ["observation_end_time"],
|
|
925
|
+
message: "observation_end_time must run at least until the study ends (end_time) \u2014 Meta reads results until then"
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
if (p.cells) {
|
|
929
|
+
issues.push(...shareIssues(p.cells));
|
|
930
|
+
const ids = p.cells.map((cell) => cell.id);
|
|
931
|
+
if (new Set(ids).size !== ids.length) {
|
|
932
|
+
issues.push({ path: ["cells"], message: "each version's share is given once" });
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
return issues;
|
|
936
|
+
}
|
|
937
|
+
var adStudyUpdateSchema = adStudyUpdateBaseSchema.superRefine(
|
|
938
|
+
(p, ctx) => addIssues(updateShapeIssues(p), ctx)
|
|
939
|
+
);
|
|
940
|
+
function unixSeconds(value) {
|
|
941
|
+
if (typeof value === "number") {
|
|
942
|
+
return value > 1e12 ? Math.floor(value / 1e3) : value;
|
|
943
|
+
}
|
|
944
|
+
if (typeof value !== "string" || value === "") {
|
|
945
|
+
return void 0;
|
|
946
|
+
}
|
|
947
|
+
const iso = value.replace(/([+-]\d{2})(\d{2})$/, "$1:$2");
|
|
948
|
+
const ms = Date.parse(iso);
|
|
949
|
+
return Number.isNaN(ms) ? void 0 : Math.floor(ms / 1e3);
|
|
950
|
+
}
|
|
951
|
+
function wireIds(edge, names) {
|
|
952
|
+
const rows = edge?.data;
|
|
953
|
+
if (!rows || rows.length === 0) {
|
|
954
|
+
return void 0;
|
|
955
|
+
}
|
|
956
|
+
return rows.flatMap((row) => {
|
|
957
|
+
if (typeof row.id !== "string") return [];
|
|
958
|
+
if (typeof row.name === "string") names[row.id] = row.name;
|
|
959
|
+
return [row.id];
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
function text(value) {
|
|
963
|
+
return typeof value === "string" && value !== "" ? value : void 0;
|
|
964
|
+
}
|
|
965
|
+
function wireSources(edge) {
|
|
966
|
+
const rows = edge?.data;
|
|
967
|
+
if (!rows || rows.length === 0) {
|
|
968
|
+
return void 0;
|
|
969
|
+
}
|
|
970
|
+
return rows.map((row) => ({
|
|
971
|
+
id: String(row.id ?? ""),
|
|
972
|
+
...Array.isArray(row.event_names) && row.event_names.length > 0 ? { event_names: row.event_names.map(String) } : {}
|
|
973
|
+
}));
|
|
974
|
+
}
|
|
975
|
+
function objectivesFromWire(edge) {
|
|
976
|
+
const rows = edge?.data;
|
|
977
|
+
if (!rows || rows.length === 0) {
|
|
978
|
+
return void 0;
|
|
979
|
+
}
|
|
980
|
+
return rows.map((row) => {
|
|
981
|
+
const objective = {
|
|
982
|
+
name: String(row.name ?? ""),
|
|
983
|
+
type: "CONVERSIONS",
|
|
984
|
+
...typeof row.is_primary === "boolean" ? { is_primary: row.is_primary } : {}
|
|
985
|
+
};
|
|
986
|
+
for (const source of OBJECTIVE_SOURCES) {
|
|
987
|
+
const sources = wireSources(row[source]);
|
|
988
|
+
if (sources) objective[source] = sources;
|
|
989
|
+
}
|
|
990
|
+
return objective;
|
|
991
|
+
});
|
|
992
|
+
}
|
|
993
|
+
function adStudyFromWire(node) {
|
|
994
|
+
const names = {};
|
|
995
|
+
const cellRows = node.cells?.data ?? [];
|
|
996
|
+
const cells = cellRows.map((cell) => {
|
|
997
|
+
const adsets = wireIds(cell.adsets, names);
|
|
998
|
+
const campaigns = wireIds(cell.campaigns, names);
|
|
999
|
+
const ads = wireIds(cell.ads, names);
|
|
1000
|
+
return {
|
|
1001
|
+
id: String(cell.id ?? ""),
|
|
1002
|
+
name: String(cell.name ?? ""),
|
|
1003
|
+
treatment_percentage: Number(cell.treatment_percentage ?? 0),
|
|
1004
|
+
...typeof cell.control_percentage === "number" ? { control_percentage: cell.control_percentage } : {},
|
|
1005
|
+
...adsets ? { adsets } : {},
|
|
1006
|
+
...campaigns ? { campaigns } : {},
|
|
1007
|
+
...ads ? { ads } : {}
|
|
1008
|
+
};
|
|
1009
|
+
});
|
|
1010
|
+
const out = { id: String(node.id ?? ""), cells, names };
|
|
1011
|
+
const fields = [
|
|
1012
|
+
["name", text(node.name)],
|
|
1013
|
+
["description", text(node.description)],
|
|
1014
|
+
["type", text(node.type)],
|
|
1015
|
+
["start_time", unixSeconds(node.start_time)],
|
|
1016
|
+
["end_time", unixSeconds(node.end_time)],
|
|
1017
|
+
["observation_end_time", unixSeconds(node.observation_end_time)],
|
|
1018
|
+
["business_id", text(node.business?.id)],
|
|
1019
|
+
["objectives", objectivesFromWire(node.objectives)]
|
|
1020
|
+
];
|
|
1021
|
+
for (const [key, value] of fields) {
|
|
1022
|
+
if (value !== void 0) out[key] = value;
|
|
1023
|
+
}
|
|
1024
|
+
return out;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
export {
|
|
1028
|
+
META_LIMITS,
|
|
1029
|
+
OBJECTIVES,
|
|
1030
|
+
SPECIAL_AD_CATEGORIES,
|
|
1031
|
+
SPECIAL_CATEGORIES_REQUIRING_COUNTRY,
|
|
1032
|
+
BUYING_TYPES,
|
|
1033
|
+
BID_STRATEGIES,
|
|
1034
|
+
BID_STRATEGIES_REQUIRING_AMOUNT,
|
|
1035
|
+
ROAS_FLOOR_SCALE,
|
|
1036
|
+
BID_STRATEGIES_FORBIDDING_AMOUNT,
|
|
1037
|
+
BILLING_EVENTS,
|
|
1038
|
+
OPTIMIZATION_GOALS,
|
|
1039
|
+
OPTIMIZATION_GOALS_REQUIRING_PAGE,
|
|
1040
|
+
OPTIMIZATION_GOALS_REQUIRING_PIXEL,
|
|
1041
|
+
OPTIMIZATION_GOALS_REQUIRING_CONVERSION_SOURCE,
|
|
1042
|
+
OPTIMIZATION_GOALS_REQUIRING_APP,
|
|
1043
|
+
DESTINATION_TYPES,
|
|
1044
|
+
CUSTOM_EVENT_TYPES,
|
|
1045
|
+
OPTIMIZATION_GOALS_WITH_FREQUENCY_CAP,
|
|
1046
|
+
FREQUENCY_CAP_EVENTS,
|
|
1047
|
+
FREQUENCY_CAP_TYPES,
|
|
1048
|
+
PACING_TYPES,
|
|
1049
|
+
SCHEDULE_TIMEZONE_TYPES,
|
|
1050
|
+
ATTRIBUTION_EVENT_TYPES,
|
|
1051
|
+
ATTRIBUTION_MAX_WINDOW_DAYS,
|
|
1052
|
+
ADVANTAGE_AUDIENCE_OPEN_AGE_MAX,
|
|
1053
|
+
ADVANTAGE_AUDIENCE_MAX_HARD_AGE_MIN,
|
|
1054
|
+
EU_DSA_COUNTRIES,
|
|
1055
|
+
CTA_TYPES,
|
|
1056
|
+
ASSET_FEED_CTA_TYPES,
|
|
1057
|
+
LEAD_FORM_CTA_TYPES,
|
|
1058
|
+
AD_FORMATS,
|
|
1059
|
+
ENROLL_STATUSES,
|
|
1060
|
+
VISUAL_ENHANCEMENT_FEATURES,
|
|
1061
|
+
STAGEABLE_CREATE_STATUSES,
|
|
1062
|
+
UPDATE_STATUSES,
|
|
1063
|
+
CREATIVE_UPDATE_STATUSES,
|
|
1064
|
+
CUSTOM_AUDIENCE_SUBTYPES,
|
|
1065
|
+
CUSTOMER_FILE_SOURCES,
|
|
1066
|
+
MEDIA_KINDS,
|
|
1067
|
+
CURRENCY_MINIMUMS,
|
|
1068
|
+
DEFAULT_CURRENCY_MINIMUM,
|
|
1069
|
+
TEMP_REF_REGEX,
|
|
1070
|
+
NUMERIC_ID_REGEX,
|
|
1071
|
+
IMAGE_HASH_REGEX,
|
|
1072
|
+
cellObjects,
|
|
1073
|
+
adStudyCreateSchema,
|
|
1074
|
+
adStudyUpdateSchema,
|
|
1075
|
+
unixSeconds,
|
|
1076
|
+
adStudyFromWire
|
|
1077
|
+
};
|
|
1078
|
+
//# sourceMappingURL=chunk-HLVRHBKL.js.map
|