@cimplify/sdk 0.108.0 → 0.110.2
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/LICENSE +21 -0
- package/dist/advanced.d.mts +4 -3
- package/dist/advanced.d.ts +4 -3
- package/dist/advanced.js +24 -24
- package/dist/advanced.mjs +5 -5
- package/dist/animation-4EXBXRVX.js +27 -0
- package/dist/animation-6DICNWUP.mjs +6 -0
- package/dist/audio-DhvyjqdA.d.mts +249 -0
- package/dist/audio-m0w8cnxq.d.ts +249 -0
- package/dist/avatars.d.mts +110 -0
- package/dist/avatars.d.ts +110 -0
- package/dist/avatars.js +82 -0
- package/dist/avatars.mjs +5 -0
- package/dist/backend-gUCzs5Kg.d.mts +3866 -0
- package/dist/backend-gUCzs5Kg.d.ts +3866 -0
- package/dist/{catalogue-B4eLL8Mi.d.ts → catalogue-CPTMyBUz.d.mts} +109 -221
- package/dist/catalogue-DzrTXP3v.d.mts +541 -0
- package/dist/catalogue-DzrTXP3v.d.ts +541 -0
- package/dist/{catalogue-OT89_Ifs.d.mts → catalogue-OTuS5zp-.d.ts} +109 -221
- package/dist/chunk-22BD3RHN.mjs +1809 -0
- package/dist/chunk-25T4JHEA.mjs +21 -0
- package/dist/chunk-2AQ237Y4.js +508 -0
- package/dist/chunk-2IC4H6OV.mjs +48 -0
- package/dist/chunk-2LHLG4OB.mjs +71 -0
- package/dist/chunk-2O2CG465.js +1709 -0
- package/dist/chunk-2Q4DTHXK.js +316 -0
- package/dist/chunk-2QTQ6BUH.mjs +46 -0
- package/dist/chunk-2UN4SFLR.mjs +100 -0
- package/dist/chunk-2V75I7K3.js +454 -0
- package/dist/chunk-2V7IL4HC.js +10 -0
- package/dist/chunk-34XBXUMW.js +296 -0
- package/dist/chunk-3C4C654I.js +71 -0
- package/dist/chunk-3DAD2LDF.mjs +72 -0
- package/dist/chunk-3GXH2NFD.mjs +4 -0
- package/dist/chunk-3O47ZFW3.js +961 -0
- package/dist/chunk-3OY3VYNF.mjs +11 -0
- package/dist/chunk-3S6WPBZL.js +2936 -0
- package/dist/chunk-3TUOUP5T.js +399 -0
- package/dist/chunk-3VEH23I5.mjs +1380 -0
- package/dist/chunk-3ZYSAW2T.mjs +263 -0
- package/dist/chunk-4ANVF274.js +103 -0
- package/dist/chunk-4C7I3ELN.js +388 -0
- package/dist/chunk-4DYKAYFO.mjs +8 -0
- package/dist/chunk-4ZDR72SG.js +329 -0
- package/dist/chunk-52YS45RR.js +1066 -0
- package/dist/chunk-5325XSCH.js +107 -0
- package/dist/chunk-5AD5X6AV.js +13 -0
- package/dist/chunk-5BYDGGWO.mjs +197 -0
- package/dist/chunk-5C3C7VDM.mjs +55 -0
- package/dist/chunk-5HFMY3D7.js +660 -0
- package/dist/chunk-5LH2QN3T.js +1862 -0
- package/dist/chunk-5PJEXSOW.js +44 -0
- package/dist/chunk-5SXDH3Y7.js +90 -0
- package/dist/chunk-5YFBGGCK.mjs +502 -0
- package/dist/chunk-5YWN6H5Q.mjs +133 -0
- package/dist/chunk-66QP3SMN.js +402 -0
- package/dist/chunk-6DAEZKIG.mjs +385 -0
- package/dist/chunk-6DATW7TB.mjs +420 -0
- package/dist/{chunk-JRGK3NXR.mjs → chunk-6ETDAU62.mjs} +72 -212
- package/dist/chunk-6H254EVP.mjs +178 -0
- package/dist/chunk-6PFNJPBJ.mjs +820 -0
- package/dist/chunk-6PJWXIFX.mjs +357 -0
- package/dist/chunk-6SWKWCMS.js +80 -0
- package/dist/chunk-6VVXXX7S.js +808 -0
- package/dist/chunk-6WUBSMTX.js +1403 -0
- package/dist/chunk-73SGZLAQ.mjs +35 -0
- package/dist/chunk-76L2V6KD.mjs +4 -0
- package/dist/chunk-7AAIAVAA.js +1531 -0
- package/dist/chunk-7ARSJPV3.mjs +93 -0
- package/dist/chunk-7BHW5GTC.mjs +1234 -0
- package/dist/chunk-7DQSDKDU.js +6 -0
- package/dist/chunk-7IQQQENP.mjs +401 -0
- package/dist/chunk-7KFTYENS.js +11357 -0
- package/dist/chunk-7SM6XSPZ.js +3171 -0
- package/dist/chunk-7SXOHAIR.mjs +28 -0
- package/dist/chunk-A2MAX6S4.js +90 -0
- package/dist/chunk-A33OORT7.mjs +1530 -0
- package/dist/{chunk-U6ACF76H.mjs → chunk-A36JRXXH.mjs} +1075 -1845
- package/dist/chunk-A7BU3BK4.js +52 -0
- package/dist/chunk-A7MQSN2V.mjs +77 -0
- package/dist/chunk-A7V4L2IT.mjs +416 -0
- package/dist/chunk-AABEK6XU.js +226 -0
- package/dist/chunk-AGV33FWC.mjs +5005 -0
- package/dist/chunk-AHNR3BXI.js +108 -0
- package/dist/chunk-AQ5RLBU2.mjs +286 -0
- package/dist/chunk-AQOE6WCG.js +1270 -0
- package/dist/chunk-ATAWRACV.mjs +62 -0
- package/dist/chunk-ATCURNUV.js +14 -0
- package/dist/chunk-AWPV33OO.js +6 -0
- package/dist/chunk-AYJPHKYV.js +337 -0
- package/dist/chunk-AZ5BGWHB.js +162 -0
- package/dist/chunk-AZAXD44P.js +1373 -0
- package/dist/chunk-BBGKQIJJ.mjs +406 -0
- package/dist/chunk-BP4JLSUA.js +1453 -0
- package/dist/{chunk-SUCE7FWA.mjs → chunk-BTUSVHIE.mjs} +539 -978
- package/dist/chunk-BU6OK542.mjs +818 -0
- package/dist/chunk-CVSRWM6W.js +418 -0
- package/dist/chunk-CYBMFMJD.mjs +247 -0
- package/dist/chunk-DDJLDOUX.mjs +217 -0
- package/dist/{chunk-V32BCG7M.js → chunk-DFZWHNRG.js} +75 -215
- package/dist/chunk-DJ2C7AVG.js +644 -0
- package/dist/chunk-DS2VU4WW.mjs +102 -0
- package/dist/chunk-DSAG7T5P.js +7290 -0
- package/dist/chunk-E2QPPH7I.js +327 -0
- package/dist/chunk-E65WCTIG.mjs +1187 -0
- package/dist/{chunk-33VCYWVL.mjs → chunk-E6QQKDNE.mjs} +30 -42
- package/dist/chunk-ECDK6QBF.mjs +981 -0
- package/dist/chunk-EIB4OWVQ.mjs +620 -0
- package/dist/chunk-EQUZYCGO.js +250 -0
- package/dist/chunk-F3UJ6ZRM.mjs +313 -0
- package/dist/chunk-F63N2ZTQ.js +7023 -0
- package/dist/chunk-F6XRYEM3.mjs +26 -0
- package/dist/chunk-FE6VCE4K.js +5030 -0
- package/dist/chunk-FLWD6GRR.js +1372 -0
- package/dist/chunk-FQBFWJBS.mjs +110 -0
- package/dist/chunk-FXVJ2HFU.js +26 -0
- package/dist/chunk-FZMQMQBW.js +312 -0
- package/dist/chunk-G3EEC44R.js +53 -0
- package/dist/{chunk-KG3WT4PR.mjs → chunk-GCKWKLZF.mjs} +73 -104
- package/dist/chunk-GCX7TY4D.mjs +6826 -0
- package/dist/chunk-GDB6TCSD.js +450 -0
- package/dist/chunk-GDCV4IWO.mjs +21 -0
- package/dist/chunk-GDZT5LZ5.js +170 -0
- package/dist/chunk-GHPUYD4I.mjs +213 -0
- package/dist/chunk-GHS6MIL6.mjs +1432 -0
- package/dist/chunk-GPS2THCL.mjs +11 -0
- package/dist/{chunk-EV2EVOYS.js → chunk-GTJWQAGU.js} +31 -42
- package/dist/chunk-GVTI6UJQ.mjs +130 -0
- package/dist/chunk-GXKI64OT.mjs +1138 -0
- package/dist/chunk-GYDYF2WX.js +275 -0
- package/dist/chunk-GYLP6UG4.mjs +705 -0
- package/dist/chunk-H3OQKK6X.js +1158 -0
- package/dist/chunk-H5DFSCJ6.js +40 -0
- package/dist/chunk-HAGEIC2L.mjs +186 -0
- package/dist/chunk-HAJ4JRFO.js +293 -0
- package/dist/chunk-HDR72GB6.js +188 -0
- package/dist/chunk-HF5HPS4T.mjs +40 -0
- package/dist/chunk-HK6LOFDS.js +218 -0
- package/dist/chunk-HMWYTXCY.mjs +143 -0
- package/dist/chunk-HPCSRCMA.js +89 -0
- package/dist/chunk-HSEO6TPU.js +247 -0
- package/dist/chunk-I5FOHCLH.js +132 -0
- package/dist/chunk-IDLW4NWA.mjs +85 -0
- package/dist/chunk-IIDZ5WUX.js +61 -0
- package/dist/chunk-IR74FJHU.js +2332 -0
- package/dist/chunk-IRVFYAKP.mjs +100 -0
- package/dist/{chunk-XBL3TMPC.mjs → chunk-IZDWAL53.mjs} +1795 -3287
- package/dist/chunk-J2KZXIU3.js +51 -0
- package/dist/chunk-J2U6PJSO.js +91 -0
- package/dist/chunk-J5AJNY2N.js +283 -0
- package/dist/chunk-J6KQZ4FO.mjs +821 -0
- package/dist/{chunk-OWW5GUSB.js → chunk-JGBCIKJV.js} +7 -6
- package/dist/chunk-JKGTBMU7.mjs +25 -0
- package/dist/chunk-JR3TNEQC.js +422 -0
- package/dist/chunk-JURRXY2J.mjs +29 -0
- package/dist/chunk-K3HW5I2A.mjs +317 -0
- package/dist/chunk-K46SMZ66.mjs +103 -0
- package/dist/chunk-K4UDGE3Z.mjs +6 -0
- package/dist/chunk-KDQOR4QQ.mjs +350 -0
- package/dist/chunk-KDTVOLHI.mjs +288 -0
- package/dist/chunk-KGHJH5KJ.mjs +35 -0
- package/dist/chunk-KIZOA5LX.mjs +140 -0
- package/dist/chunk-KK6HYVBI.mjs +242 -0
- package/dist/chunk-KMKWGXMK.js +856 -0
- package/dist/chunk-KPA6K5IB.js +80 -0
- package/dist/chunk-KU7O4IXU.mjs +260 -0
- package/dist/chunk-KVFNRJOR.mjs +11142 -0
- package/dist/chunk-KZJRSXHK.js +2432 -0
- package/dist/chunk-LHWPRUJL.js +79 -0
- package/dist/chunk-LIV3KXJG.mjs +369 -0
- package/dist/chunk-LKV4LACG.js +21 -0
- package/dist/chunk-LUY45X3U.mjs +263 -0
- package/dist/chunk-LYEZZEEF.mjs +17 -0
- package/dist/chunk-M5EXQZYY.mjs +1519 -0
- package/dist/chunk-ME6HGG4I.mjs +1338 -0
- package/dist/chunk-MEXP6DA6.js +31 -0
- package/dist/chunk-MG52AW3H.js +902 -0
- package/dist/chunk-MIPO6F72.js +334 -0
- package/dist/{chunk-5QW7CQBA.js → chunk-MKIJQL5Q.js} +211 -321
- package/dist/chunk-MN3YETVN.mjs +17 -0
- package/dist/chunk-MOBSBXVE.mjs +2391 -0
- package/dist/chunk-MOMOZEUM.mjs +88 -0
- package/dist/chunk-MRFUNRAP.js +62 -0
- package/dist/chunk-MTIHEW2M.js +433 -0
- package/dist/chunk-N4RGGDEL.mjs +73 -0
- package/dist/chunk-NH654HAT.js +10 -0
- package/dist/chunk-NHJUGZUR.mjs +253 -0
- package/dist/chunk-NMQT4HG3.mjs +757 -0
- package/dist/chunk-NPSYB6DC.mjs +906 -0
- package/dist/chunk-NW2GPMSO.js +857 -0
- package/dist/chunk-NXKQOQ6L.js +76 -0
- package/dist/chunk-NXLAZIJZ.js +309 -0
- package/dist/chunk-NYWNA5CF.js +148 -0
- package/dist/chunk-NZTKLY2W.js +1442 -0
- package/dist/chunk-O2ICABUD.js +36 -0
- package/dist/chunk-OIVVQQ22.js +862 -0
- package/dist/chunk-OKC2B4O3.mjs +312 -0
- package/dist/chunk-OLWFPDBK.js +2220 -0
- package/dist/chunk-OMTVH334.js +3779 -0
- package/dist/chunk-OQRVEM56.mjs +362 -0
- package/dist/chunk-OXMIBOD4.js +337 -0
- package/dist/chunk-PBL6YL5L.mjs +288 -0
- package/dist/chunk-PDOELNNQ.js +97 -0
- package/dist/chunk-PDQJY2GZ.js +136 -0
- package/dist/chunk-PKOZXD2Q.js +1274 -0
- package/dist/chunk-PPF2BYFL.mjs +2191 -0
- package/dist/chunk-PQTQKNKD.js +539 -0
- package/dist/chunk-PRSR4FAV.mjs +81 -0
- package/dist/chunk-PTRNO5UD.js +95 -0
- package/dist/chunk-Q2Y3VMKH.js +2000 -0
- package/dist/chunk-QCZOE65N.js +96 -0
- package/dist/chunk-QDYFLATW.mjs +52 -0
- package/dist/chunk-QQABGCMM.js +22 -0
- package/dist/chunk-QS6TRHMR.js +345 -0
- package/dist/chunk-R56P64LB.mjs +208 -0
- package/dist/chunk-RCQ2MPBV.js +428 -0
- package/dist/chunk-RFVRPYR2.mjs +856 -0
- package/dist/chunk-RKBLPGPV.js +11521 -0
- package/dist/chunk-RM2V4IND.mjs +327 -0
- package/dist/chunk-RQXN5A34.mjs +613 -0
- package/dist/chunk-RUVGVNOF.mjs +2687 -0
- package/dist/chunk-SAFJIGYB.mjs +165 -0
- package/dist/chunk-SKQFLBDD.js +263 -0
- package/dist/chunk-SMK6JU2F.mjs +2092 -0
- package/dist/{chunk-UVRPC2P7.js → chunk-SNNEOS5Z.js} +1984 -3476
- package/dist/chunk-SPCRQ6NO.mjs +1246 -0
- package/dist/chunk-SWX4SALA.mjs +19 -0
- package/dist/{chunk-JVODCGFP.mjs → chunk-SYEO2WV4.mjs} +128 -238
- package/dist/chunk-T2QQMX2N.js +10 -0
- package/dist/chunk-T3AFF3L7.mjs +57 -0
- package/dist/chunk-T6Z2EXYL.js +712 -0
- package/dist/chunk-T7LOXGYX.js +118 -0
- package/dist/chunk-TJCAE7RC.mjs +1315 -0
- package/dist/chunk-TJI3K6RP.js +137 -0
- package/dist/chunk-TL2SVO4P.mjs +55 -0
- package/dist/chunk-TM63CYGN.mjs +399 -0
- package/dist/chunk-TU5RYTYU.mjs +13 -0
- package/dist/chunk-TVJZ4GPS.js +1553 -0
- package/dist/chunk-TWM6DLYF.js +371 -0
- package/dist/chunk-U63OC4TQ.js +30 -0
- package/dist/{chunk-L5GKVQVJ.js → chunk-U6BVSJZ6.js} +25 -57
- package/dist/chunk-U6UVWEAK.mjs +792 -0
- package/dist/chunk-UCEPNO6N.mjs +11048 -0
- package/dist/{chunk-ANT574FD.js → chunk-UCR5HRYM.js} +74 -105
- package/dist/chunk-UG5BTOTF.mjs +334 -0
- package/dist/chunk-UGH37BQW.mjs +157 -0
- package/dist/chunk-V7ZRH3PY.mjs +271 -0
- package/dist/chunk-VBGHBL3E.mjs +1394 -0
- package/dist/chunk-VRBDAS5I.js +920 -0
- package/dist/chunk-VVE3Y76O.js +230 -0
- package/dist/chunk-W65JIRI4.mjs +1182 -0
- package/dist/chunk-WHYKAT7G.js +62 -0
- package/dist/{chunk-YOIVZ6OA.mjs → chunk-WIZRUIZB.mjs} +25 -57
- package/dist/chunk-WKWTDZS7.js +385 -0
- package/dist/chunk-WLMINRC4.mjs +78 -0
- package/dist/chunk-WOF3AD3J.js +22 -0
- package/dist/chunk-WWKMOA76.js +1262 -0
- package/dist/chunk-X5A5FOWW.js +615 -0
- package/dist/chunk-X6CN6KQF.mjs +192 -0
- package/dist/chunk-XD2PMH46.mjs +517 -0
- package/dist/chunk-XJA2NGTI.mjs +88 -0
- package/dist/chunk-XJIHN3BY.mjs +8 -0
- package/dist/chunk-XK6UDWJS.js +203 -0
- package/dist/chunk-XPG3N5CF.mjs +415 -0
- package/dist/chunk-XVZ2NKSU.mjs +74 -0
- package/dist/chunk-XYP45OLE.js +117 -0
- package/dist/chunk-XZSDGZX6.mjs +301 -0
- package/dist/chunk-Y2EMGN4T.mjs +120 -0
- package/dist/chunk-Y3XWP5XW.mjs +298 -0
- package/dist/chunk-Y4K22JL6.js +228 -0
- package/dist/chunk-Y65LXQGA.mjs +3164 -0
- package/dist/chunk-Y66WVMO5.mjs +87 -0
- package/dist/chunk-Y7JWLB25.mjs +7280 -0
- package/dist/chunk-YCDXAJKU.js +175 -0
- package/dist/chunk-YRDQCCIS.js +152 -0
- package/dist/chunk-YV52DGSA.js +111 -0
- package/dist/chunk-YXGZQPUD.js +94 -0
- package/dist/chunk-Z3A3AFVU.mjs +102 -0
- package/dist/chunk-ZCY6YKKP.mjs +475 -0
- package/dist/chunk-ZEQHXVU5.js +215 -0
- package/dist/chunk-ZF7JCXCI.js +284 -0
- package/dist/chunk-ZJBRUH6V.js +29 -0
- package/dist/chunk-ZMIL4ZOA.js +365 -0
- package/dist/chunk-ZR5ULMN2.mjs +337 -0
- package/dist/chunk-ZXREOYOW.js +87 -0
- package/dist/{client-BSP9U1O1.d.mts → client-CX_WR0-J.d.mts} +2 -2
- package/dist/client-Dytx_ZTC.d.ts +230 -0
- package/dist/{client-B878xeAP.d.ts → client-dqOhP9Nc.d.ts} +2 -2
- package/dist/client-hTKbCuhG.d.mts +230 -0
- package/dist/clock-B-UAjkKa.d.mts +5 -0
- package/dist/clock-B-UAjkKa.d.ts +5 -0
- package/dist/config-BlXQluJR.d.mts +36 -0
- package/dist/config-BlXQluJR.d.ts +36 -0
- package/dist/courier-Cnn-edJ4.d.ts +95 -0
- package/dist/courier-FmGfkvIN.d.mts +95 -0
- package/dist/crowd-DdHFbqKK.d.ts +186 -0
- package/dist/crowd-hOVSAmA3.d.mts +186 -0
- package/dist/danfo-BEBapFlX.d.mts +146 -0
- package/dist/danfo-UQ_PTIIx.d.ts +146 -0
- package/dist/{elements-Bty6Qs_N.d.mts → elements-DdsRig-2.d.mts} +1548 -257
- package/dist/{elements-Bty6Qs_N.d.ts → elements-DdsRig-2.d.ts} +1548 -257
- package/dist/engines/godot.d.mts +56 -0
- package/dist/engines/godot.d.ts +56 -0
- package/dist/engines/godot.js +28 -0
- package/dist/engines/godot.mjs +3 -0
- package/dist/engines/wasm.d.mts +11 -0
- package/dist/engines/wasm.d.ts +11 -0
- package/dist/engines/wasm.js +178 -0
- package/dist/engines/wasm.mjs +176 -0
- package/dist/fallback-CrG_lTFk.d.mts +270 -0
- package/dist/fallback-CrG_lTFk.d.ts +270 -0
- package/dist/fallback-KDB4Y2CE.mjs +6 -0
- package/dist/fallback-Y26TQENE.js +19 -0
- package/dist/features-CZB4rmcD.d.mts +118 -0
- package/dist/features-CZB4rmcD.d.ts +118 -0
- package/dist/fit-BWiE7rgA.d.mts +44 -0
- package/dist/fit-DK0oT7zO.d.ts +44 -0
- package/dist/five-a-side-Bv1AOUy3.d.mts +115 -0
- package/dist/five-a-side-EC51SJY1.d.ts +115 -0
- package/dist/fluid-ARr0qUIL.d.ts +939 -0
- package/dist/fluid-DLlEj2cs.d.mts +939 -0
- package/dist/game/conformance.d.mts +84 -0
- package/dist/game/conformance.d.ts +84 -0
- package/dist/game/conformance.js +1025 -0
- package/dist/game/conformance.mjs +994 -0
- package/dist/game/heap.d.mts +40 -0
- package/dist/game/heap.d.ts +40 -0
- package/dist/game/heap.js +48 -0
- package/dist/game/heap.mjs +7 -0
- package/dist/game/kit/canvas.d.mts +240 -0
- package/dist/game/kit/canvas.d.ts +240 -0
- package/dist/game/kit/canvas.js +3566 -0
- package/dist/game/kit/canvas.mjs +1039 -0
- package/dist/game/kit/courier.d.mts +17 -0
- package/dist/game/kit/courier.d.ts +17 -0
- package/dist/game/kit/courier.js +66 -0
- package/dist/game/kit/courier.mjs +49 -0
- package/dist/game/kit/danfo.d.mts +11 -0
- package/dist/game/kit/danfo.d.ts +11 -0
- package/dist/game/kit/danfo.js +109 -0
- package/dist/game/kit/danfo.mjs +44 -0
- package/dist/game/kit/engine.d.mts +29 -0
- package/dist/game/kit/engine.d.ts +29 -0
- package/dist/game/kit/engine.js +183 -0
- package/dist/game/kit/engine.mjs +30 -0
- package/dist/game/kit/five-a-side.d.mts +11 -0
- package/dist/game/kit/five-a-side.d.ts +11 -0
- package/dist/game/kit/five-a-side.js +86 -0
- package/dist/game/kit/five-a-side.mjs +41 -0
- package/dist/game/kit/frontier.d.mts +344 -0
- package/dist/game/kit/frontier.d.ts +344 -0
- package/dist/game/kit/frontier.js +435 -0
- package/dist/game/kit/frontier.mjs +14 -0
- package/dist/game/kit/genesis.d.mts +752 -0
- package/dist/game/kit/genesis.d.ts +752 -0
- package/dist/game/kit/genesis.js +380 -0
- package/dist/game/kit/genesis.mjs +15 -0
- package/dist/game/kit/ludo.d.mts +15 -0
- package/dist/game/kit/ludo.d.ts +15 -0
- package/dist/game/kit/ludo.js +87 -0
- package/dist/game/kit/ludo.mjs +42 -0
- package/dist/game/kit/runner.d.mts +12 -0
- package/dist/game/kit/runner.d.ts +12 -0
- package/dist/game/kit/runner.js +83 -0
- package/dist/game/kit/runner.mjs +46 -0
- package/dist/game/kit/shootout.d.mts +13 -0
- package/dist/game/kit/shootout.d.ts +13 -0
- package/dist/game/kit/shootout.js +122 -0
- package/dist/game/kit/shootout.mjs +57 -0
- package/dist/game/kit/slots.d.mts +392 -0
- package/dist/game/kit/slots.d.ts +392 -0
- package/dist/game/kit/slots.js +215 -0
- package/dist/game/kit/slots.mjs +6 -0
- package/dist/game/kit/tycoon.d.mts +16 -0
- package/dist/game/kit/tycoon.d.ts +16 -0
- package/dist/game/kit/tycoon.js +145 -0
- package/dist/game/kit/tycoon.mjs +44 -0
- package/dist/game/kit/word.d.mts +11 -0
- package/dist/game/kit/word.d.ts +11 -0
- package/dist/game/kit/word.js +78 -0
- package/dist/game/kit/word.mjs +41 -0
- package/dist/game/kit/worlds.d.mts +18 -0
- package/dist/game/kit/worlds.d.ts +18 -0
- package/dist/game/kit/worlds.js +74 -0
- package/dist/game/kit/worlds.mjs +49 -0
- package/dist/game/kit.d.mts +53 -0
- package/dist/game/kit.d.ts +53 -0
- package/dist/game/kit.js +2610 -0
- package/dist/game/kit.mjs +101 -0
- package/dist/game/prepared.d.mts +14 -0
- package/dist/game/prepared.d.ts +14 -0
- package/dist/game/prepared.js +81 -0
- package/dist/game/prepared.mjs +32 -0
- package/dist/game-Bx8onkhX.d.mts +1451 -0
- package/dist/game-fgQy2YIm.d.ts +1451 -0
- package/dist/game-theme-CBTw1b_d.d.mts +35 -0
- package/dist/game-theme-Dg-ict5A.d.ts +35 -0
- package/dist/game.d.mts +3546 -0
- package/dist/game.d.ts +3546 -0
- package/dist/game.js +4455 -0
- package/dist/game.mjs +50 -0
- package/dist/graphics-C6YjWYvP.d.ts +5 -0
- package/dist/graphics-Dk2yQnYN.d.mts +5 -0
- package/dist/guest-DrsA00XD.d.mts +732 -0
- package/dist/guest-wIdfoT05.d.ts +732 -0
- package/dist/hit-stop-BKkVwTq7.d.mts +43 -0
- package/dist/hit-stop-D-8pPYnM.d.ts +43 -0
- package/dist/hot-Crn9XpHJ.d.ts +29 -0
- package/dist/hot-DH3nOhQD.d.mts +29 -0
- package/dist/{index-CQStGb3B.d.mts → index-6gkHMGAq.d.mts} +2 -2
- package/dist/index-B8ybCKJI.d.ts +41 -0
- package/dist/{index-DJwXmoaP.d.ts → index-B98Xac8e.d.ts} +2 -2
- package/dist/{index-B7oA_1XI.d.ts → index-B_ByTtIT.d.ts} +2 -2
- package/dist/index-DHjNHb1c.d.mts +41 -0
- package/dist/{index-DhUSTAhT.d.mts → index-DbAN_VQE.d.mts} +2 -2
- package/dist/index.d.mts +134 -24
- package/dist/index.d.ts +134 -24
- package/dist/index.js +407 -248
- package/dist/index.mjs +184 -58
- package/dist/interactives-authoring.d.mts +231 -0
- package/dist/interactives-authoring.d.ts +231 -0
- package/dist/interactives-authoring.js +1743 -0
- package/dist/interactives-authoring.mjs +1704 -0
- package/dist/interactives-canvas.global.js +148 -0
- package/dist/interactives-guest.d.mts +20 -0
- package/dist/interactives-guest.d.ts +20 -0
- package/dist/interactives-guest.js +63 -0
- package/dist/interactives-guest.json +1 -0
- package/dist/interactives-guest.mjs +61 -0
- package/dist/interactives-jsc.global.js +9357 -0
- package/dist/interactives-meters.d.mts +93 -0
- package/dist/interactives-meters.d.ts +93 -0
- package/dist/interactives-meters.js +252 -0
- package/dist/interactives-meters.mjs +68 -0
- package/dist/interactives-production.d.mts +430 -0
- package/dist/interactives-production.d.ts +430 -0
- package/dist/interactives-production.js +1231 -0
- package/dist/interactives-production.mjs +1170 -0
- package/dist/interactives-record.d.mts +112 -0
- package/dist/interactives-record.d.ts +112 -0
- package/dist/interactives-record.js +302 -0
- package/dist/interactives-record.mjs +295 -0
- package/dist/interactives-runtime.d.mts +61 -0
- package/dist/interactives-runtime.d.ts +61 -0
- package/dist/interactives-runtime.js +442 -0
- package/dist/interactives-runtime.mjs +25 -0
- package/dist/interactives-studio-kernel.global.js +1 -0
- package/dist/interactives-studio.d.mts +806 -0
- package/dist/interactives-studio.d.ts +806 -0
- package/dist/interactives-studio.js +5741 -0
- package/dist/interactives-studio.mjs +5651 -0
- package/dist/interactives-tick.d.mts +90 -0
- package/dist/interactives-tick.d.ts +90 -0
- package/dist/interactives-tick.js +203 -0
- package/dist/interactives-tick.mjs +6 -0
- package/dist/interactives-web.d.mts +762 -0
- package/dist/interactives-web.d.ts +762 -0
- package/dist/interactives-web.js +5000 -0
- package/dist/interactives-web.mjs +4628 -0
- package/dist/interactives.d.mts +2430 -0
- package/dist/interactives.d.ts +2430 -0
- package/dist/interactives.js +5723 -0
- package/dist/interactives.mjs +4333 -0
- package/dist/juice-CoHxlpKA.d.ts +42 -0
- package/dist/juice-DQztFS43.d.mts +42 -0
- package/dist/launch-T2f4_Di4.d.mts +151 -0
- package/dist/launch-d6oreMzR.d.ts +151 -0
- package/dist/library-DXYaMFhi.d.mts +69 -0
- package/dist/library-DXYaMFhi.d.ts +69 -0
- package/dist/link-BUTqGmyi.d.mts +38 -0
- package/dist/link-BUTqGmyi.d.ts +38 -0
- package/dist/lint.js +104 -204
- package/dist/lint.mjs +103 -203
- package/dist/local-D8_I6UeL.d.mts +6967 -0
- package/dist/local-VZkqsCzR.d.ts +6967 -0
- package/dist/lockstep-BLf6dglI.d.mts +321 -0
- package/dist/lockstep-D50Ia0JW.d.ts +321 -0
- package/dist/ludo-B8ClkDqr.d.ts +205 -0
- package/dist/ludo-BOuohQ-M.d.mts +205 -0
- package/dist/mock/cli.mjs +200 -56
- package/dist/mock/library.js +200 -56
- package/dist/mock/library.mjs +200 -56
- package/dist/mock/msw.js +200 -56
- package/dist/mock/msw.mjs +200 -56
- package/dist/native-BodxSh03.d.mts +16 -0
- package/dist/native-DUHMT8gA.d.ts +16 -0
- package/dist/network-ZXLD7l1b.d.mts +19 -0
- package/dist/network-ZXLD7l1b.d.ts +19 -0
- package/dist/online-XeymeM9s.d.ts +381 -0
- package/dist/online-d7W_Al9a.d.mts +381 -0
- package/dist/params-DxFb5G_U.d.mts +155 -0
- package/dist/params-DxFb5G_U.d.ts +155 -0
- package/dist/play-BRRlfLhX.d.ts +940 -0
- package/dist/play-ClrMd_e8.d.mts +940 -0
- package/dist/policy-CCw8tXLm.d.mts +3078 -0
- package/dist/policy-CMqOSQIu.d.ts +3078 -0
- package/dist/ports-B_0v_P3A.d.mts +13 -0
- package/dist/ports-CGU_3e_0.d.ts +13 -0
- package/dist/prefetch-BHnicOQj.d.ts +117 -0
- package/dist/prefetch-CBXgYacv.d.mts +117 -0
- package/dist/{price-CSztR02F.d.mts → price-BOzexBww.d.mts} +1 -1
- package/dist/{price-C_vasx9A.d.ts → price-C1h9sPxE.d.ts} +1 -1
- package/dist/protocol-C8qbpUbT.d.mts +242 -0
- package/dist/protocol-C8qbpUbT.d.ts +242 -0
- package/dist/rapier-AZHT4YI7.js +7886 -0
- package/dist/rapier-ODEPCQA6.mjs +7792 -0
- package/dist/react.d.mts +157 -15
- package/dist/react.d.ts +157 -15
- package/dist/react.js +5564 -5904
- package/dist/react.mjs +5451 -5808
- package/dist/runner-CQcLL7By.d.ts +189 -0
- package/dist/runner-D46Yj-wE.d.mts +189 -0
- package/dist/runtime-BRWfkf_q.d.mts +51 -0
- package/dist/runtime-DyuBMkKM.d.ts +51 -0
- package/dist/scheduling-D2ajXpMC.d.ts +224 -0
- package/dist/scheduling-DSRbbaZb.d.mts +224 -0
- package/dist/schema-BrWxzKp6.d.mts +63 -0
- package/dist/schema-BrWxzKp6.d.ts +63 -0
- package/dist/server/evict.js +34 -37
- package/dist/server/evict.mjs +34 -37
- package/dist/server/tanstack.d.mts +49 -3
- package/dist/server/tanstack.d.ts +49 -3
- package/dist/server/tanstack.js +169 -117
- package/dist/server/tanstack.mjs +166 -118
- package/dist/{server-Dckg4Vdr.d.ts → server-D29IIuDV.d.ts} +136 -130
- package/dist/{server-B6dW7-Lj.d.mts → server-DQMWPnc8.d.mts} +136 -130
- package/dist/server.d.mts +45 -5
- package/dist/server.d.ts +45 -5
- package/dist/server.js +171 -227
- package/dist/server.mjs +165 -225
- package/dist/session-grant-CJ27DwrT.d.mts +19 -0
- package/dist/session-grant-CJ27DwrT.d.ts +19 -0
- package/dist/shootout-BJZeX6FG.d.ts +140 -0
- package/dist/shootout-tcZd1Rxt.d.mts +140 -0
- package/dist/state-replica-stMtdkVD.d.mts +42 -0
- package/dist/state-replica-stMtdkVD.d.ts +42 -0
- package/dist/studio-CowqWqez.d.mts +14 -0
- package/dist/studio-CowqWqez.d.ts +14 -0
- package/dist/styles.css +1 -1
- package/dist/template-AhCdB1kW.d.mts +190 -0
- package/dist/template-BkEGVTQj.d.ts +190 -0
- package/dist/terrain-BMxEc6Oc.d.ts +429 -0
- package/dist/terrain-C-XC1Oui.d.mts +429 -0
- package/dist/testing/msw.d.mts +28 -4
- package/dist/testing/msw.d.ts +28 -4
- package/dist/testing/msw.js +15 -21
- package/dist/testing/msw.mjs +15 -21
- package/dist/testing/suite.d.mts +6 -5
- package/dist/testing/suite.d.ts +6 -5
- package/dist/testing/suite.js +89 -124
- package/dist/testing/suite.mjs +81 -116
- package/dist/testing.d.mts +27 -1227
- package/dist/testing.d.ts +27 -1227
- package/dist/testing.js +127 -131
- package/dist/testing.mjs +19 -23
- package/dist/tick-transport-C8QEh8Uw.d.mts +50 -0
- package/dist/tick-transport-UjHY3xK1.d.ts +50 -0
- package/dist/timeline-protocol-hp6e8zFB.d.mts +47 -0
- package/dist/timeline-protocol-hp6e8zFB.d.ts +47 -0
- package/dist/tokens-DhanQRQS.d.mts +21 -0
- package/dist/tokens-K8yxwd6G.d.ts +21 -0
- package/dist/tree-C-Io2Hbx.d.mts +35 -0
- package/dist/tree-CP_qSW4H.d.ts +35 -0
- package/dist/tycoon-B5KHk2Xx.d.mts +255 -0
- package/dist/tycoon-hmHo-3HX.d.ts +255 -0
- package/dist/types-BQkxPwZP.d.mts +219 -0
- package/dist/types-D_f6UUxM.d.ts +219 -0
- package/dist/ui-DwHicuFv.d.mts +563 -0
- package/dist/ui-hi7S2YcH.d.ts +563 -0
- package/dist/{sign-in-DQlIdqsi.d.mts → url-52ndUruG.d.mts} +15 -1
- package/dist/{sign-in-DQlIdqsi.d.ts → url-52ndUruG.d.ts} +15 -1
- package/dist/utils.d.mts +3 -3
- package/dist/utils.d.ts +3 -3
- package/dist/utils.js +37 -37
- package/dist/utils.mjs +4 -4
- package/dist/vars-Dc_PrhBK.d.mts +511 -0
- package/dist/vars-Dc_PrhBK.d.ts +511 -0
- package/dist/vm-IUARFFAI.mjs +63 -0
- package/dist/vm-N7L6MGGH.js +65 -0
- package/dist/weave-delivery-CW-Kstut.d.mts +360 -0
- package/dist/weave-delivery-CW-Kstut.d.ts +360 -0
- package/dist/web-Dss74a7v.d.ts +883 -0
- package/dist/web-f9ZQPoyw.d.mts +883 -0
- package/dist/web-transport-C7MkBL0a.d.ts +19 -0
- package/dist/web-transport-aYEqXMd9.d.mts +19 -0
- package/dist/weight-CPGjsgjV.d.ts +92 -0
- package/dist/weight-tF1ODR1p.d.mts +92 -0
- package/dist/word-BcX9Jcmv.d.mts +70 -0
- package/dist/word-C7sVPLHm.d.ts +70 -0
- package/dist/world-PvILHDR1.d.ts +2285 -0
- package/dist/world-qekkXjJv.d.mts +2285 -0
- package/dist/worlds-Br2Pb0Cs.d.ts +109 -0
- package/dist/worlds-D5ydYr7d.d.mts +109 -0
- package/engines/c/cimplify.h +108 -0
- package/engines/c/cimplify.lib.js +11 -0
- package/engines/godot/addons/cimplify/cimplify.gd +97 -0
- package/engines/rust/interactives-ctx/Cargo.toml +9 -0
- package/engines/rust/interactives-ctx/src/lib.rs +189 -0
- package/package.json +189 -3
- package/vendor/rapier3d-compat/LICENSE +201 -0
- package/vendor/rapier3d-compat/PATCHES.md +61 -0
- package/dist/chunk-2P4KXFB6.js +0 -274
- package/dist/chunk-3G6RQLXK.mjs +0 -21
- package/dist/chunk-3V4DVXV3.mjs +0 -254
- package/dist/chunk-EDK3LNM6.js +0 -2436
- package/dist/chunk-F7J3HK27.js +0 -4549
- package/dist/chunk-U4MW6PYU.mjs +0 -23
- package/dist/chunk-XREIZ56K.js +0 -26
package/dist/chunk-F7J3HK27.js
DELETED
|
@@ -1,4549 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
var chunkEV2EVOYS_js = require('./chunk-EV2EVOYS.js');
|
|
4
|
-
var chunkV32BCG7M_js = require('./chunk-V32BCG7M.js');
|
|
5
|
-
var chunkANT574FD_js = require('./chunk-ANT574FD.js');
|
|
6
|
-
|
|
7
|
-
// src/types/result.ts
|
|
8
|
-
function ok(value) {
|
|
9
|
-
return { ok: true, value };
|
|
10
|
-
}
|
|
11
|
-
function err(error) {
|
|
12
|
-
return { ok: false, error };
|
|
13
|
-
}
|
|
14
|
-
function isOk(result) {
|
|
15
|
-
return result.ok === true;
|
|
16
|
-
}
|
|
17
|
-
function isErr(result) {
|
|
18
|
-
return result.ok === false;
|
|
19
|
-
}
|
|
20
|
-
function mapResult(result, fn) {
|
|
21
|
-
return result.ok ? ok(fn(result.value)) : result;
|
|
22
|
-
}
|
|
23
|
-
function mapError(result, fn) {
|
|
24
|
-
return result.ok ? result : err(fn(result.error));
|
|
25
|
-
}
|
|
26
|
-
function flatMap(result, fn) {
|
|
27
|
-
return result.ok ? fn(result.value) : result;
|
|
28
|
-
}
|
|
29
|
-
function getOrElse(result, defaultFn) {
|
|
30
|
-
return result.ok ? result.value : defaultFn();
|
|
31
|
-
}
|
|
32
|
-
function unwrap(result) {
|
|
33
|
-
if (result.ok) {
|
|
34
|
-
return result.value;
|
|
35
|
-
}
|
|
36
|
-
throw result.error;
|
|
37
|
-
}
|
|
38
|
-
function toNullable(result) {
|
|
39
|
-
return result.ok ? result.value : void 0;
|
|
40
|
-
}
|
|
41
|
-
async function fromPromise(promise, mapError2) {
|
|
42
|
-
try {
|
|
43
|
-
const value = await promise;
|
|
44
|
-
return ok(value);
|
|
45
|
-
} catch (error) {
|
|
46
|
-
return err(mapError2(error));
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
function tryCatch(fn, mapError2) {
|
|
50
|
-
try {
|
|
51
|
-
return ok(fn());
|
|
52
|
-
} catch (error) {
|
|
53
|
-
return err(mapError2(error));
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
function combine(results) {
|
|
57
|
-
const values = [];
|
|
58
|
-
for (const result of results) {
|
|
59
|
-
if (!result.ok) {
|
|
60
|
-
return result;
|
|
61
|
-
}
|
|
62
|
-
values.push(result.value);
|
|
63
|
-
}
|
|
64
|
-
return ok(values);
|
|
65
|
-
}
|
|
66
|
-
function combineObject(results) {
|
|
67
|
-
const values = {};
|
|
68
|
-
for (const [key, result] of Object.entries(results)) {
|
|
69
|
-
if (!result.ok) {
|
|
70
|
-
return result;
|
|
71
|
-
}
|
|
72
|
-
values[key] = result.value;
|
|
73
|
-
}
|
|
74
|
-
return ok(values);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// src/internal/idempotency.ts
|
|
78
|
-
function generateIdempotencyKey(prefix = "idem") {
|
|
79
|
-
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
80
|
-
return `${prefix}_${crypto.randomUUID()}`;
|
|
81
|
-
}
|
|
82
|
-
const timestamp = Date.now().toString(36);
|
|
83
|
-
const random = Math.random().toString(36).substring(2, 15);
|
|
84
|
-
return `${prefix}_${timestamp}_${random}`;
|
|
85
|
-
}
|
|
86
|
-
var INTENT_PREFIX = "cimplify-intent:";
|
|
87
|
-
function sessionStorageOrNull() {
|
|
88
|
-
try {
|
|
89
|
-
return typeof window !== "undefined" ? window.sessionStorage : null;
|
|
90
|
-
} catch {
|
|
91
|
-
return null;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
function intentIdempotencyKey(scope, fingerprint, storage = sessionStorageOrNull()) {
|
|
95
|
-
const slot = INTENT_PREFIX + scope;
|
|
96
|
-
try {
|
|
97
|
-
const raw = storage?.getItem(slot);
|
|
98
|
-
if (raw) {
|
|
99
|
-
const stored = JSON.parse(raw);
|
|
100
|
-
if (stored.fingerprint === fingerprint && typeof stored.key === "string") return stored.key;
|
|
101
|
-
}
|
|
102
|
-
} catch {
|
|
103
|
-
}
|
|
104
|
-
const key = generateIdempotencyKey();
|
|
105
|
-
try {
|
|
106
|
-
storage?.setItem(slot, JSON.stringify({ key, fingerprint }));
|
|
107
|
-
} catch {
|
|
108
|
-
}
|
|
109
|
-
return key;
|
|
110
|
-
}
|
|
111
|
-
function clearIntentIdempotencyKey(scope, storage = sessionStorageOrNull()) {
|
|
112
|
-
try {
|
|
113
|
-
storage?.removeItem(INTENT_PREFIX + scope);
|
|
114
|
-
} catch {
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// src/internal/safe.ts
|
|
119
|
-
function toCimplifyError(error) {
|
|
120
|
-
if (error instanceof chunkANT574FD_js.CimplifyError) return chunkANT574FD_js.enrichError(error);
|
|
121
|
-
if (error instanceof Error) {
|
|
122
|
-
return chunkANT574FD_js.enrichError(new chunkANT574FD_js.CimplifyError(chunkANT574FD_js.ErrorCode.UNKNOWN_ERROR, error.message, false));
|
|
123
|
-
}
|
|
124
|
-
return chunkANT574FD_js.enrichError(new chunkANT574FD_js.CimplifyError(chunkANT574FD_js.ErrorCode.UNKNOWN_ERROR, String(error), false));
|
|
125
|
-
}
|
|
126
|
-
async function safe(promise) {
|
|
127
|
-
try {
|
|
128
|
-
return ok(await promise);
|
|
129
|
-
} catch (error) {
|
|
130
|
-
return err(toCimplifyError(error));
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// src/catalogue.ts
|
|
135
|
-
function withQuery(path, params) {
|
|
136
|
-
const query = new URLSearchParams();
|
|
137
|
-
for (const [key, value] of Object.entries(params)) {
|
|
138
|
-
if (value === void 0) continue;
|
|
139
|
-
query.set(key, String(value));
|
|
140
|
-
}
|
|
141
|
-
const queryString = query.toString();
|
|
142
|
-
return queryString ? `${path}?${queryString}` : path;
|
|
143
|
-
}
|
|
144
|
-
function isRecord(value) {
|
|
145
|
-
return typeof value === "object" && value !== null;
|
|
146
|
-
}
|
|
147
|
-
function readFinalPrice(value) {
|
|
148
|
-
if (!isRecord(value)) return void 0;
|
|
149
|
-
const finalPrice = value.final_price;
|
|
150
|
-
if (typeof finalPrice === "string" || typeof finalPrice === "number") {
|
|
151
|
-
return finalPrice;
|
|
152
|
-
}
|
|
153
|
-
return void 0;
|
|
154
|
-
}
|
|
155
|
-
function needsDefaultPriceNormalization(value) {
|
|
156
|
-
return value === void 0 || value === null || value === "";
|
|
157
|
-
}
|
|
158
|
-
function optionNeedsNormalization(option) {
|
|
159
|
-
return isRecord(option) && needsDefaultPriceNormalization(option["default_price"]);
|
|
160
|
-
}
|
|
161
|
-
function addOnNeedsNormalization(addOn) {
|
|
162
|
-
if (!isRecord(addOn)) return false;
|
|
163
|
-
const options = addOn["options"];
|
|
164
|
-
return Array.isArray(options) && options.some((option) => optionNeedsNormalization(option));
|
|
165
|
-
}
|
|
166
|
-
function normalizeAddOnPayload(addOn) {
|
|
167
|
-
if (!isRecord(addOn)) return addOn;
|
|
168
|
-
const options = addOn["options"];
|
|
169
|
-
if (!Array.isArray(options)) return addOn;
|
|
170
|
-
if (!options.some((option) => optionNeedsNormalization(option))) return addOn;
|
|
171
|
-
const normalizedAddOn = { ...addOn };
|
|
172
|
-
normalizedAddOn["options"] = options.map((option) => {
|
|
173
|
-
if (!isRecord(option)) return option;
|
|
174
|
-
if (!optionNeedsNormalization(option)) return option;
|
|
175
|
-
const normalizedOption = { ...option };
|
|
176
|
-
const optionPrice = normalizedOption["default_price"];
|
|
177
|
-
if (needsDefaultPriceNormalization(optionPrice)) {
|
|
178
|
-
normalizedOption["default_price"] = readFinalPrice(normalizedOption["default_price_info"]) || readFinalPrice(normalizedOption["price_info"]) || "0";
|
|
179
|
-
}
|
|
180
|
-
return normalizedOption;
|
|
181
|
-
});
|
|
182
|
-
return normalizedAddOn;
|
|
183
|
-
}
|
|
184
|
-
function normalizeCatalogueProductPayload(product) {
|
|
185
|
-
const productRecord = product;
|
|
186
|
-
const defaultPrice = productRecord["default_price"];
|
|
187
|
-
const addOns = productRecord["add_ons"];
|
|
188
|
-
const needsPriceFix = needsDefaultPriceNormalization(defaultPrice);
|
|
189
|
-
const needsAddOnFix = Array.isArray(addOns) && addOns.some((addOn) => addOnNeedsNormalization(addOn));
|
|
190
|
-
if (!needsPriceFix && !needsAddOnFix) {
|
|
191
|
-
return product;
|
|
192
|
-
}
|
|
193
|
-
const normalized = { ...productRecord };
|
|
194
|
-
if (needsPriceFix) {
|
|
195
|
-
const derivedDefaultPrice = readFinalPrice(normalized["default_price_info"]) || readFinalPrice(normalized["price_info"]) || (typeof normalized["final_price"] === "string" || typeof normalized["final_price"] === "number" ? normalized["final_price"] : void 0);
|
|
196
|
-
normalized["default_price"] = derivedDefaultPrice ?? "0";
|
|
197
|
-
}
|
|
198
|
-
if (needsAddOnFix && Array.isArray(addOns)) {
|
|
199
|
-
normalized["add_ons"] = addOns.map((addOn) => normalizeAddOnPayload(addOn));
|
|
200
|
-
}
|
|
201
|
-
return normalized;
|
|
202
|
-
}
|
|
203
|
-
function toFiniteNumber(value) {
|
|
204
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
205
|
-
return value;
|
|
206
|
-
}
|
|
207
|
-
if (typeof value === "string" && value.trim().length > 0) {
|
|
208
|
-
const parsed = Number(value);
|
|
209
|
-
if (Number.isFinite(parsed)) {
|
|
210
|
-
return parsed;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return void 0;
|
|
214
|
-
}
|
|
215
|
-
function normalizePagination(value) {
|
|
216
|
-
if (!isRecord(value)) {
|
|
217
|
-
return void 0;
|
|
218
|
-
}
|
|
219
|
-
const totalCount = toFiniteNumber(value.total_count);
|
|
220
|
-
const currentPage = toFiniteNumber(value.current_page);
|
|
221
|
-
const pageSize = toFiniteNumber(value.page_size);
|
|
222
|
-
const totalPages = toFiniteNumber(value.total_pages);
|
|
223
|
-
if (totalCount === void 0 || currentPage === void 0 || pageSize === void 0 || totalPages === void 0) {
|
|
224
|
-
return void 0;
|
|
225
|
-
}
|
|
226
|
-
return {
|
|
227
|
-
total_count: totalCount,
|
|
228
|
-
current_page: currentPage,
|
|
229
|
-
page_size: pageSize,
|
|
230
|
-
total_pages: totalPages,
|
|
231
|
-
has_more: value.has_more === true,
|
|
232
|
-
next_cursor: typeof value.next_cursor === "string" ? value.next_cursor : void 0
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
function normalizeCatalogueResult(payload) {
|
|
236
|
-
if (Array.isArray(payload)) {
|
|
237
|
-
return {
|
|
238
|
-
items: payload.map((product) => normalizeCatalogueProductPayload(product)),
|
|
239
|
-
is_complete: true
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
if (!isRecord(payload)) {
|
|
243
|
-
return {
|
|
244
|
-
items: [],
|
|
245
|
-
is_complete: true
|
|
246
|
-
};
|
|
247
|
-
}
|
|
248
|
-
const rawItems = Array.isArray(payload.products) ? payload.products : Array.isArray(payload.items) ? payload.items : [];
|
|
249
|
-
return {
|
|
250
|
-
items: rawItems.map((product) => normalizeCatalogueProductPayload(product)),
|
|
251
|
-
is_complete: typeof payload.is_complete === "boolean" ? payload.is_complete : true,
|
|
252
|
-
total_available: toFiniteNumber(payload.total_available),
|
|
253
|
-
pagination: normalizePagination(payload.pagination)
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
function normalizeCatalogueSnapshot(payload) {
|
|
257
|
-
if (Array.isArray(payload)) {
|
|
258
|
-
return {
|
|
259
|
-
categories: [],
|
|
260
|
-
products: payload.map((product) => normalizeCatalogueProductPayload(product)),
|
|
261
|
-
add_ons: [],
|
|
262
|
-
is_complete: true
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
if (!isRecord(payload)) {
|
|
266
|
-
return {
|
|
267
|
-
categories: [],
|
|
268
|
-
products: [],
|
|
269
|
-
add_ons: [],
|
|
270
|
-
is_complete: true
|
|
271
|
-
};
|
|
272
|
-
}
|
|
273
|
-
const rawProducts = Array.isArray(payload.products) ? payload.products : Array.isArray(payload.items) ? payload.items : [];
|
|
274
|
-
const rawCategories = Array.isArray(payload.categories) ? payload.categories : [];
|
|
275
|
-
const rawAddOns = Array.isArray(payload.add_ons) ? payload.add_ons : [];
|
|
276
|
-
return {
|
|
277
|
-
categories: rawCategories,
|
|
278
|
-
products: rawProducts.map((product) => normalizeCatalogueProductPayload(product)),
|
|
279
|
-
add_ons: rawAddOns.map((addOn) => normalizeAddOnPayload(addOn)),
|
|
280
|
-
is_complete: typeof payload.is_complete === "boolean" ? payload.is_complete : true,
|
|
281
|
-
total_available: toFiniteNumber(payload.total_available),
|
|
282
|
-
pagination: normalizePagination(payload.pagination)
|
|
283
|
-
};
|
|
284
|
-
}
|
|
285
|
-
var CatalogueQueries = class {
|
|
286
|
-
constructor(client) {
|
|
287
|
-
this.client = client;
|
|
288
|
-
}
|
|
289
|
-
async getCatalogue(opts) {
|
|
290
|
-
const result = await safe(
|
|
291
|
-
this.client.get("/api/v1/catalogue", opts)
|
|
292
|
-
);
|
|
293
|
-
if (!result.ok) return result;
|
|
294
|
-
return ok(normalizeCatalogueSnapshot(result.value));
|
|
295
|
-
}
|
|
296
|
-
async getProducts(options, opts) {
|
|
297
|
-
const path = withQuery("/api/v1/catalogue/products", {
|
|
298
|
-
category_id: options?.category,
|
|
299
|
-
taxonomy_id: options?.taxonomy,
|
|
300
|
-
search: options?.search,
|
|
301
|
-
page: options?.page,
|
|
302
|
-
tags: options?.tags?.join(","),
|
|
303
|
-
featured: options?.featured,
|
|
304
|
-
in_stock: options?.in_stock,
|
|
305
|
-
min_price: options?.min_price,
|
|
306
|
-
max_price: options?.max_price,
|
|
307
|
-
sort_by: options?.sort_by,
|
|
308
|
-
sort_order: options?.sort_order,
|
|
309
|
-
limit: options?.limit,
|
|
310
|
-
offset: options?.offset,
|
|
311
|
-
cursor: options?.cursor,
|
|
312
|
-
properties: options?.properties ? JSON.stringify(options.properties) : void 0
|
|
313
|
-
});
|
|
314
|
-
const result = await safe(this.client.get(path, opts));
|
|
315
|
-
if (!result.ok) return result;
|
|
316
|
-
return ok(normalizeCatalogueResult(result.value));
|
|
317
|
-
}
|
|
318
|
-
async getProduct(id, opts) {
|
|
319
|
-
const encodedId = encodeURIComponent(id);
|
|
320
|
-
const result = await safe(
|
|
321
|
-
this.client.get(`/api/v1/catalogue/products/${encodedId}`, opts)
|
|
322
|
-
);
|
|
323
|
-
if (!result.ok) return result;
|
|
324
|
-
const payload = result.value;
|
|
325
|
-
const rawProduct = isRecord(payload.item) ? payload.item : payload;
|
|
326
|
-
const product = normalizeCatalogueProductPayload(rawProduct);
|
|
327
|
-
if (isRecord(payload.category)) {
|
|
328
|
-
product.category = payload.category;
|
|
329
|
-
}
|
|
330
|
-
const addOnIds = rawProduct.add_on_ids;
|
|
331
|
-
if (Array.isArray(addOnIds) && addOnIds.length > 0) {
|
|
332
|
-
const addOnsResult = await this.getAddOns(product.id, opts);
|
|
333
|
-
if (addOnsResult.ok) {
|
|
334
|
-
product.add_ons = addOnsResult.value;
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
return ok(product);
|
|
338
|
-
}
|
|
339
|
-
async getProductBySlug(slug, opts) {
|
|
340
|
-
return this.getProduct(slug, opts);
|
|
341
|
-
}
|
|
342
|
-
async getVariants(productId) {
|
|
343
|
-
const encodedId = encodeURIComponent(productId);
|
|
344
|
-
return safe(
|
|
345
|
-
this.client.get(`/api/v1/catalogue/products/${encodedId}/variants`)
|
|
346
|
-
);
|
|
347
|
-
}
|
|
348
|
-
async getVariantAxes(productId) {
|
|
349
|
-
const encodedId = encodeURIComponent(productId);
|
|
350
|
-
return safe(
|
|
351
|
-
this.client.get(`/api/v1/catalogue/products/${encodedId}/variant-axes`)
|
|
352
|
-
);
|
|
353
|
-
}
|
|
354
|
-
async getVariantByAxisSelections(productId, selections) {
|
|
355
|
-
const encodedId = encodeURIComponent(productId);
|
|
356
|
-
return safe(
|
|
357
|
-
this.client.post(
|
|
358
|
-
`/api/v1/catalogue/products/${encodedId}/variants/find`,
|
|
359
|
-
{ axis_selections: selections }
|
|
360
|
-
)
|
|
361
|
-
);
|
|
362
|
-
}
|
|
363
|
-
async getVariantById(productId, variantId) {
|
|
364
|
-
const encodedProductId = encodeURIComponent(productId);
|
|
365
|
-
const encodedVariantId = encodeURIComponent(variantId);
|
|
366
|
-
return safe(
|
|
367
|
-
this.client.get(
|
|
368
|
-
`/api/v1/catalogue/products/${encodedProductId}/variants/${encodedVariantId}`
|
|
369
|
-
)
|
|
370
|
-
);
|
|
371
|
-
}
|
|
372
|
-
async getAddOns(productId, opts) {
|
|
373
|
-
const encodedId = encodeURIComponent(productId);
|
|
374
|
-
return safe(this.client.get(`/api/v1/catalogue/products/${encodedId}/add-ons`, opts));
|
|
375
|
-
}
|
|
376
|
-
async getCategories(opts) {
|
|
377
|
-
return safe(this.client.get("/api/v1/catalogue/categories", opts));
|
|
378
|
-
}
|
|
379
|
-
async getCategory(id, opts) {
|
|
380
|
-
const encodedId = encodeURIComponent(id);
|
|
381
|
-
return safe(this.client.get(`/api/v1/catalogue/categories/${encodedId}`, opts));
|
|
382
|
-
}
|
|
383
|
-
async getCategoryBySlug(slug, opts) {
|
|
384
|
-
return this.getCategory(slug, opts);
|
|
385
|
-
}
|
|
386
|
-
async getCategoryProducts(categoryId, options, opts) {
|
|
387
|
-
const encodedId = encodeURIComponent(categoryId);
|
|
388
|
-
const path = withQuery(`/api/v1/catalogue/categories/${encodedId}/products`, {
|
|
389
|
-
limit: options?.limit,
|
|
390
|
-
offset: options?.offset
|
|
391
|
-
});
|
|
392
|
-
return safe(this.client.get(path, opts));
|
|
393
|
-
}
|
|
394
|
-
async getCollections(opts) {
|
|
395
|
-
return safe(this.client.get("/api/v1/catalogue/collections", opts));
|
|
396
|
-
}
|
|
397
|
-
async getCollection(id, opts) {
|
|
398
|
-
const encodedId = encodeURIComponent(id);
|
|
399
|
-
return safe(this.client.get(`/api/v1/catalogue/collections/${encodedId}`, opts));
|
|
400
|
-
}
|
|
401
|
-
async getCollectionBySlug(slug, opts) {
|
|
402
|
-
return this.getCollection(slug, opts);
|
|
403
|
-
}
|
|
404
|
-
async getCollectionProducts(collectionId, options, opts) {
|
|
405
|
-
const encodedId = encodeURIComponent(collectionId);
|
|
406
|
-
const path = withQuery(`/api/v1/catalogue/collections/${encodedId}/products`, {
|
|
407
|
-
limit: options?.limit,
|
|
408
|
-
offset: options?.offset
|
|
409
|
-
});
|
|
410
|
-
return safe(this.client.get(path, opts));
|
|
411
|
-
}
|
|
412
|
-
async searchCollections(query, limit = 20) {
|
|
413
|
-
const path = withQuery("/api/v1/catalogue/collections", { search: query, limit });
|
|
414
|
-
return safe(this.client.get(path));
|
|
415
|
-
}
|
|
416
|
-
async getBundles() {
|
|
417
|
-
return safe(this.client.get("/api/v1/catalogue/bundles"));
|
|
418
|
-
}
|
|
419
|
-
async getBundle(id) {
|
|
420
|
-
const encodedId = encodeURIComponent(id);
|
|
421
|
-
return safe(this.client.get(`/api/v1/catalogue/bundles/${encodedId}`));
|
|
422
|
-
}
|
|
423
|
-
async getBundleBySlug(slug) {
|
|
424
|
-
return this.getBundle(slug);
|
|
425
|
-
}
|
|
426
|
-
async searchBundles(query, limit = 20) {
|
|
427
|
-
const path = withQuery("/api/v1/catalogue/bundles", { search: query, limit });
|
|
428
|
-
return safe(this.client.get(path));
|
|
429
|
-
}
|
|
430
|
-
async getComposites(options) {
|
|
431
|
-
const path = withQuery("/api/v1/catalogue/composites", { limit: options?.limit });
|
|
432
|
-
return safe(this.client.get(path));
|
|
433
|
-
}
|
|
434
|
-
async getComposite(id) {
|
|
435
|
-
const encodedId = encodeURIComponent(id);
|
|
436
|
-
return safe(this.client.get(`/api/v1/catalogue/composites/${encodedId}`));
|
|
437
|
-
}
|
|
438
|
-
async getCompositeByProduct(productId) {
|
|
439
|
-
const encodedId = encodeURIComponent(productId);
|
|
440
|
-
return safe(this.client.get(`/api/v1/catalogue/composites/by-product/${encodedId}`));
|
|
441
|
-
}
|
|
442
|
-
async calculateCompositePrice(compositeId, selections, locationId) {
|
|
443
|
-
const encodedId = encodeURIComponent(compositeId);
|
|
444
|
-
return safe(
|
|
445
|
-
this.client.post(
|
|
446
|
-
`/api/v1/catalogue/composites/${encodedId}/calculate-price`,
|
|
447
|
-
{
|
|
448
|
-
selections,
|
|
449
|
-
location_id: locationId
|
|
450
|
-
}
|
|
451
|
-
)
|
|
452
|
-
);
|
|
453
|
-
}
|
|
454
|
-
async fetchQuote(input, opts) {
|
|
455
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
456
|
-
return safe(
|
|
457
|
-
this.client.post("/api/v1/catalogue/quotes", input, { idempotencyKey })
|
|
458
|
-
);
|
|
459
|
-
}
|
|
460
|
-
async getQuote(quoteId) {
|
|
461
|
-
const encodedQuoteId = encodeURIComponent(quoteId);
|
|
462
|
-
return safe(this.client.get(`/api/v1/catalogue/quotes/${encodedQuoteId}`));
|
|
463
|
-
}
|
|
464
|
-
async refreshQuote(input) {
|
|
465
|
-
const encodedQuoteId = encodeURIComponent(input.quote_id);
|
|
466
|
-
return safe(
|
|
467
|
-
this.client.post(
|
|
468
|
-
`/api/v1/catalogue/quotes/${encodedQuoteId}/refresh`,
|
|
469
|
-
input
|
|
470
|
-
)
|
|
471
|
-
);
|
|
472
|
-
}
|
|
473
|
-
async getTaxonomies(parentId) {
|
|
474
|
-
const path = withQuery("/api/v1/catalogue/taxonomies", { parent_id: parentId });
|
|
475
|
-
return safe(this.client.get(path));
|
|
476
|
-
}
|
|
477
|
-
async getTaxonomy(id) {
|
|
478
|
-
const encodedId = encodeURIComponent(id);
|
|
479
|
-
return safe(this.client.get(`/api/v1/catalogue/taxonomies/${encodedId}`));
|
|
480
|
-
}
|
|
481
|
-
async getTaxonomyPath(id) {
|
|
482
|
-
const encodedId = encodeURIComponent(id);
|
|
483
|
-
return safe(
|
|
484
|
-
this.client.get(`/api/v1/catalogue/taxonomies/${encodedId}/path`)
|
|
485
|
-
);
|
|
486
|
-
}
|
|
487
|
-
async searchTaxonomies(query, limit) {
|
|
488
|
-
const path = withQuery("/api/v1/catalogue/taxonomies/search", { q: query, limit });
|
|
489
|
-
return safe(this.client.get(path));
|
|
490
|
-
}
|
|
491
|
-
async getEligibleBillingPlans(productId, query) {
|
|
492
|
-
const encodedId = encodeURIComponent(productId);
|
|
493
|
-
const path = withQuery(`/api/v1/catalogue/products/${encodedId}/billing-plans/eligible`, {
|
|
494
|
-
customer_id: query?.customer_id,
|
|
495
|
-
quantity: query?.quantity,
|
|
496
|
-
order_value: query?.order_value
|
|
497
|
-
});
|
|
498
|
-
return safe(this.client.get(path));
|
|
499
|
-
}
|
|
500
|
-
async getProductSchedules(productId) {
|
|
501
|
-
const encodedId = encodeURIComponent(productId);
|
|
502
|
-
return safe(
|
|
503
|
-
this.client.get(`/api/v1/catalogue/products/${encodedId}/schedules`)
|
|
504
|
-
);
|
|
505
|
-
}
|
|
506
|
-
async checkProductAvailableNow(productId, locationId) {
|
|
507
|
-
const encodedId = encodeURIComponent(productId);
|
|
508
|
-
const path = withQuery(`/api/v1/catalogue/products/${encodedId}/available-now`, {
|
|
509
|
-
location_id: locationId
|
|
510
|
-
});
|
|
511
|
-
return safe(this.client.get(path));
|
|
512
|
-
}
|
|
513
|
-
async getDeals(locationId) {
|
|
514
|
-
const path = withQuery("/api/v1/catalogue/deals", { location_id: locationId });
|
|
515
|
-
return safe(this.client.get(path));
|
|
516
|
-
}
|
|
517
|
-
async getProductsOnSale() {
|
|
518
|
-
return safe(this.client.get("/api/v1/catalogue/deals/on-sale"));
|
|
519
|
-
}
|
|
520
|
-
async getProductDeals(productId) {
|
|
521
|
-
const encodedId = encodeURIComponent(productId);
|
|
522
|
-
return safe(this.client.get(`/api/v1/catalogue/products/${encodedId}/deals`));
|
|
523
|
-
}
|
|
524
|
-
async getCategoryDeals(categoryId) {
|
|
525
|
-
const encodedId = encodeURIComponent(categoryId);
|
|
526
|
-
return safe(this.client.get(`/api/v1/catalogue/categories/${encodedId}/deals`));
|
|
527
|
-
}
|
|
528
|
-
async getCollectionDeals(collectionId) {
|
|
529
|
-
const encodedId = encodeURIComponent(collectionId);
|
|
530
|
-
return safe(this.client.get(`/api/v1/catalogue/collections/${encodedId}/deals`));
|
|
531
|
-
}
|
|
532
|
-
async validateDiscountCode(code, orderSubtotal, locationId) {
|
|
533
|
-
return safe(
|
|
534
|
-
this.client.post("/api/v1/catalogue/deals/validate", {
|
|
535
|
-
discount_code: code,
|
|
536
|
-
order_subtotal: orderSubtotal,
|
|
537
|
-
location_id: locationId
|
|
538
|
-
})
|
|
539
|
-
);
|
|
540
|
-
}
|
|
541
|
-
async search(query, options, opts) {
|
|
542
|
-
const result = await this.getProducts(
|
|
543
|
-
{
|
|
544
|
-
...options,
|
|
545
|
-
search: query,
|
|
546
|
-
limit: options?.limit ?? 20
|
|
547
|
-
},
|
|
548
|
-
opts
|
|
549
|
-
);
|
|
550
|
-
if (!result.ok) return result;
|
|
551
|
-
return ok(result.value.items);
|
|
552
|
-
}
|
|
553
|
-
async searchProducts(query, options, opts) {
|
|
554
|
-
return this.search(query, options, opts);
|
|
555
|
-
}
|
|
556
|
-
async getMenu(options) {
|
|
557
|
-
const path = withQuery("/api/v1/catalogue/menu", {
|
|
558
|
-
category_id: options?.category,
|
|
559
|
-
limit: options?.limit
|
|
560
|
-
});
|
|
561
|
-
return safe(this.client.get(path));
|
|
562
|
-
}
|
|
563
|
-
async getMenuCategory(categoryId) {
|
|
564
|
-
const encodedId = encodeURIComponent(categoryId);
|
|
565
|
-
return safe(this.client.get(`/api/v1/catalogue/menu/categories/${encodedId}`));
|
|
566
|
-
}
|
|
567
|
-
async getMenuItem(itemId) {
|
|
568
|
-
const encodedId = encodeURIComponent(itemId);
|
|
569
|
-
return safe(this.client.get(`/api/v1/catalogue/menu/items/${encodedId}`));
|
|
570
|
-
}
|
|
571
|
-
async getTags(options) {
|
|
572
|
-
const path = withQuery("/api/v1/catalogue/tags", {
|
|
573
|
-
tag_group: options?.tag_group,
|
|
574
|
-
search: options?.search,
|
|
575
|
-
min_usage: options?.min_usage,
|
|
576
|
-
limit: options?.limit,
|
|
577
|
-
offset: options?.offset
|
|
578
|
-
});
|
|
579
|
-
return safe(this.client.get(path));
|
|
580
|
-
}
|
|
581
|
-
async getAttributeDefinitions(namespace) {
|
|
582
|
-
const params = namespace ? `?namespace=${encodeURIComponent(namespace)}` : "";
|
|
583
|
-
return safe(
|
|
584
|
-
this.client.get(`/api/v1/catalogue/attributes${params}`)
|
|
585
|
-
);
|
|
586
|
-
}
|
|
587
|
-
async getProductAttributes(productId) {
|
|
588
|
-
const encodedId = encodeURIComponent(productId);
|
|
589
|
-
return safe(
|
|
590
|
-
this.client.get(`/api/v1/catalogue/products/${encodedId}/attributes`)
|
|
591
|
-
);
|
|
592
|
-
}
|
|
593
|
-
async getCategoryAttributes(categoryId) {
|
|
594
|
-
const encodedId = encodeURIComponent(categoryId);
|
|
595
|
-
return safe(
|
|
596
|
-
this.client.get(
|
|
597
|
-
`/api/v1/catalogue/categories/${encodedId}/attributes`
|
|
598
|
-
)
|
|
599
|
-
);
|
|
600
|
-
}
|
|
601
|
-
async getCollectionAttributes(collectionId) {
|
|
602
|
-
const encodedId = encodeURIComponent(collectionId);
|
|
603
|
-
return safe(
|
|
604
|
-
this.client.get(
|
|
605
|
-
`/api/v1/catalogue/collections/${encodedId}/attributes`
|
|
606
|
-
)
|
|
607
|
-
);
|
|
608
|
-
}
|
|
609
|
-
async getPropertyFacets(options) {
|
|
610
|
-
const path = withQuery("/api/v1/catalogue/properties/facets", {
|
|
611
|
-
category_id: options?.category_id,
|
|
612
|
-
product_type: options?.product_type
|
|
613
|
-
});
|
|
614
|
-
return safe(this.client.get(path));
|
|
615
|
-
}
|
|
616
|
-
async getTaxonomyAttributes(taxonomyId) {
|
|
617
|
-
const encodedId = encodeURIComponent(taxonomyId);
|
|
618
|
-
return safe(
|
|
619
|
-
this.client.get(
|
|
620
|
-
`/api/v1/catalogue/taxonomies/${encodedId}/attributes`
|
|
621
|
-
)
|
|
622
|
-
);
|
|
623
|
-
}
|
|
624
|
-
async searchKnowledge(query, limit) {
|
|
625
|
-
const path = withQuery("/api/v1/catalogue/knowledge-base/search", {
|
|
626
|
-
q: query,
|
|
627
|
-
limit: limit ?? 5
|
|
628
|
-
});
|
|
629
|
-
return safe(this.client.get(path));
|
|
630
|
-
}
|
|
631
|
-
async getKnowledgeArticles() {
|
|
632
|
-
return safe(this.client.get("/api/v1/catalogue/knowledge-base/articles"));
|
|
633
|
-
}
|
|
634
|
-
};
|
|
635
|
-
|
|
636
|
-
// src/cart.ts
|
|
637
|
-
function lineItemToCartInput(item) {
|
|
638
|
-
const config = item.configuration;
|
|
639
|
-
const input = {
|
|
640
|
-
item_id: item.product_id,
|
|
641
|
-
quantity: item.quantity
|
|
642
|
-
};
|
|
643
|
-
if (config.variant) {
|
|
644
|
-
input.variant_id = config.variant.variant_id;
|
|
645
|
-
}
|
|
646
|
-
if (config.add_ons && config.add_ons.selected_options.length > 0) {
|
|
647
|
-
input.add_on_options = config.add_ons.selected_options.map((o) => o.option_id);
|
|
648
|
-
}
|
|
649
|
-
if (config.type === "bundle") {
|
|
650
|
-
input.bundle_selections = config.input;
|
|
651
|
-
} else if (config.type === "composite") {
|
|
652
|
-
input.composite_selections = config.input;
|
|
653
|
-
}
|
|
654
|
-
return input;
|
|
655
|
-
}
|
|
656
|
-
var CartOperations = class {
|
|
657
|
-
constructor(client) {
|
|
658
|
-
this.client = client;
|
|
659
|
-
}
|
|
660
|
-
async get() {
|
|
661
|
-
return safe(this.client.get("/api/v1/cart"));
|
|
662
|
-
}
|
|
663
|
-
async getItems() {
|
|
664
|
-
return safe(this.client.get("/api/v1/cart/items"));
|
|
665
|
-
}
|
|
666
|
-
async getCount() {
|
|
667
|
-
return safe(this.client.get("/api/v1/cart/count"));
|
|
668
|
-
}
|
|
669
|
-
async getTotal() {
|
|
670
|
-
return safe(this.client.get("/api/v1/cart/total"));
|
|
671
|
-
}
|
|
672
|
-
async quoteDestination(input) {
|
|
673
|
-
return safe(this.client.post("/api/v1/cart/destination-quote", input));
|
|
674
|
-
}
|
|
675
|
-
async getSummary() {
|
|
676
|
-
const cartResult = await this.get();
|
|
677
|
-
if (!cartResult.ok) return cartResult;
|
|
678
|
-
const cart = cartResult.value;
|
|
679
|
-
return ok({
|
|
680
|
-
item_count: cart.items.length,
|
|
681
|
-
total_items: cart.items.reduce((sum, item) => sum + item.quantity, 0),
|
|
682
|
-
subtotal: cart.pricing.subtotal,
|
|
683
|
-
discount_amount: cart.pricing.total_discounts,
|
|
684
|
-
tax_amount: cart.pricing.tax_amount,
|
|
685
|
-
total: cart.pricing.total_price,
|
|
686
|
-
currency: cart.pricing.currency
|
|
687
|
-
});
|
|
688
|
-
}
|
|
689
|
-
async addItem(input, opts) {
|
|
690
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
691
|
-
return safe(
|
|
692
|
-
this.client.post("/api/v1/cart/items", input, { idempotencyKey })
|
|
693
|
-
);
|
|
694
|
-
}
|
|
695
|
-
async updateItem(cartItemId, updates) {
|
|
696
|
-
if (typeof updates.quantity !== "number") {
|
|
697
|
-
return {
|
|
698
|
-
ok: false,
|
|
699
|
-
error: new chunkANT574FD_js.CimplifyError(
|
|
700
|
-
"VALIDATION_ERROR",
|
|
701
|
-
"updateItem requires a quantity; richer mid-cart edits are not supported"
|
|
702
|
-
)
|
|
703
|
-
};
|
|
704
|
-
}
|
|
705
|
-
return this.updateQuantity(cartItemId, updates.quantity);
|
|
706
|
-
}
|
|
707
|
-
async updateQuantity(cartItemId, quantity) {
|
|
708
|
-
const encodedId = encodeURIComponent(cartItemId);
|
|
709
|
-
return safe(
|
|
710
|
-
this.client.patch(`/api/v1/cart/items/${encodedId}`, {
|
|
711
|
-
quantity
|
|
712
|
-
})
|
|
713
|
-
);
|
|
714
|
-
}
|
|
715
|
-
async removeItem(cartItemId) {
|
|
716
|
-
const encodedId = encodeURIComponent(cartItemId);
|
|
717
|
-
return safe(this.client.delete(`/api/v1/cart/items/${encodedId}`));
|
|
718
|
-
}
|
|
719
|
-
async clear() {
|
|
720
|
-
return safe(this.client.delete("/api/v1/cart"));
|
|
721
|
-
}
|
|
722
|
-
async applyCoupon(code, opts) {
|
|
723
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
724
|
-
return safe(
|
|
725
|
-
this.client.post(
|
|
726
|
-
"/api/v1/cart/coupons",
|
|
727
|
-
{ coupon_code: code },
|
|
728
|
-
{ idempotencyKey }
|
|
729
|
-
)
|
|
730
|
-
);
|
|
731
|
-
}
|
|
732
|
-
async removeCoupon() {
|
|
733
|
-
return safe(this.client.delete("/api/v1/cart/coupons/current"));
|
|
734
|
-
}
|
|
735
|
-
async reorderFromOrder(orderId) {
|
|
736
|
-
const orderResult = await this.client.orders.get(orderId);
|
|
737
|
-
if (!orderResult.ok) return orderResult;
|
|
738
|
-
const order = orderResult.value;
|
|
739
|
-
if (!order.items || order.items.length === 0) {
|
|
740
|
-
return ok({ added: [], failed: [] });
|
|
741
|
-
}
|
|
742
|
-
const added = [];
|
|
743
|
-
const failed = [];
|
|
744
|
-
for (const item of order.items) {
|
|
745
|
-
const input = lineItemToCartInput(item);
|
|
746
|
-
const result = await this.addItem(input);
|
|
747
|
-
if (result.ok) {
|
|
748
|
-
added.push({ item_id: input.item_id });
|
|
749
|
-
} else {
|
|
750
|
-
failed.push({ item_id: input.item_id, error: result.error });
|
|
751
|
-
}
|
|
752
|
-
}
|
|
753
|
-
return ok({ added, failed });
|
|
754
|
-
}
|
|
755
|
-
async isEmpty() {
|
|
756
|
-
const countResult = await this.getCount();
|
|
757
|
-
if (!countResult.ok) return countResult;
|
|
758
|
-
return ok(countResult.value === 0);
|
|
759
|
-
}
|
|
760
|
-
async hasItem(productId, variantId) {
|
|
761
|
-
const itemsResult = await this.getItems();
|
|
762
|
-
if (!itemsResult.ok) return itemsResult;
|
|
763
|
-
const found = itemsResult.value.some((item) => {
|
|
764
|
-
const matchesProduct = item.item_id === productId;
|
|
765
|
-
if (!variantId) return matchesProduct;
|
|
766
|
-
const config = item.configuration;
|
|
767
|
-
if ("variant" in config && config.variant) {
|
|
768
|
-
return matchesProduct && config.variant.variant_id === variantId;
|
|
769
|
-
}
|
|
770
|
-
return matchesProduct;
|
|
771
|
-
});
|
|
772
|
-
return ok(found);
|
|
773
|
-
}
|
|
774
|
-
async findItem(productId, variantId) {
|
|
775
|
-
const itemsResult = await this.getItems();
|
|
776
|
-
if (!itemsResult.ok) return itemsResult;
|
|
777
|
-
const found = itemsResult.value.find((item) => {
|
|
778
|
-
const matchesProduct = item.item_id === productId;
|
|
779
|
-
if (!variantId) return matchesProduct;
|
|
780
|
-
const config = item.configuration;
|
|
781
|
-
if ("variant" in config && config.variant) {
|
|
782
|
-
return matchesProduct && config.variant.variant_id === variantId;
|
|
783
|
-
}
|
|
784
|
-
return matchesProduct;
|
|
785
|
-
});
|
|
786
|
-
return ok(found);
|
|
787
|
-
}
|
|
788
|
-
};
|
|
789
|
-
|
|
790
|
-
// src/payment-authorization/types.ts
|
|
791
|
-
var PAYMENT_AUTHORIZATION_OUTCOME_STATUS = {
|
|
792
|
-
SUBMITTED: "submitted",
|
|
793
|
-
CANCELLED: "cancelled",
|
|
794
|
-
FAILED: "failed"
|
|
795
|
-
};
|
|
796
|
-
var PAYMENT_AUTHORIZATION_PROVIDER = {
|
|
797
|
-
PAYSTACK: "paystack",
|
|
798
|
-
STRIPE: "stripe"
|
|
799
|
-
};
|
|
800
|
-
|
|
801
|
-
// src/payment-authorization/providers/paystack.ts
|
|
802
|
-
var PAYSTACK_POPUP_ERROR = {
|
|
803
|
-
PROVIDER_UNAVAILABLE: chunkANT574FD_js.ErrorCode.PROVIDER_UNAVAILABLE,
|
|
804
|
-
SUBMISSION_UNKNOWN: "SUBMISSION_UNKNOWN",
|
|
805
|
-
CANCELLED: "CANCELLED",
|
|
806
|
-
PAYMENT_CANCELLED: chunkANT574FD_js.ErrorCode.PAYMENT_CANCELLED,
|
|
807
|
-
PAYMENT_FAILED: chunkANT574FD_js.ErrorCode.PAYMENT_FAILED,
|
|
808
|
-
POPUP_BLOCKED: chunkANT574FD_js.ErrorCode.POPUP_BLOCKED
|
|
809
|
-
};
|
|
810
|
-
async function openPaystackPopup(options, signal) {
|
|
811
|
-
if (typeof window === "undefined") {
|
|
812
|
-
return { success: false, error: PAYSTACK_POPUP_ERROR.PROVIDER_UNAVAILABLE };
|
|
813
|
-
}
|
|
814
|
-
let PaystackPop;
|
|
815
|
-
try {
|
|
816
|
-
const imported = await import('@paystack/inline-js');
|
|
817
|
-
PaystackPop = imported.default;
|
|
818
|
-
} catch {
|
|
819
|
-
return { success: false, error: PAYSTACK_POPUP_ERROR.PROVIDER_UNAVAILABLE };
|
|
820
|
-
}
|
|
821
|
-
return new Promise((resolve) => {
|
|
822
|
-
let settled = false;
|
|
823
|
-
let providerStarted = false;
|
|
824
|
-
const resolveOnce = (result) => {
|
|
825
|
-
if (settled) {
|
|
826
|
-
return;
|
|
827
|
-
}
|
|
828
|
-
settled = true;
|
|
829
|
-
if (signal) {
|
|
830
|
-
signal.removeEventListener("abort", onAbort);
|
|
831
|
-
}
|
|
832
|
-
resolve(result);
|
|
833
|
-
};
|
|
834
|
-
const onAbort = () => {
|
|
835
|
-
resolveOnce({
|
|
836
|
-
success: false,
|
|
837
|
-
// Once Paystack owns the transaction, cancellation is ambiguous. The
|
|
838
|
-
// adapter converts this into submitted so Cimplify polling decides.
|
|
839
|
-
error: providerStarted ? PAYSTACK_POPUP_ERROR.SUBMISSION_UNKNOWN : PAYSTACK_POPUP_ERROR.CANCELLED
|
|
840
|
-
});
|
|
841
|
-
};
|
|
842
|
-
if (signal?.aborted) {
|
|
843
|
-
resolveOnce({ success: false, error: PAYSTACK_POPUP_ERROR.CANCELLED });
|
|
844
|
-
return;
|
|
845
|
-
}
|
|
846
|
-
if (signal) {
|
|
847
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
848
|
-
}
|
|
849
|
-
try {
|
|
850
|
-
const popup = new PaystackPop();
|
|
851
|
-
popup.newTransaction({
|
|
852
|
-
key: options.key,
|
|
853
|
-
email: options.email,
|
|
854
|
-
amount: options.amount,
|
|
855
|
-
currency: options.currency,
|
|
856
|
-
reference: options.reference,
|
|
857
|
-
accessCode: options.accessCode,
|
|
858
|
-
onSuccess: (transaction) => {
|
|
859
|
-
resolveOnce({
|
|
860
|
-
success: true,
|
|
861
|
-
reference: transaction.reference ?? options.reference
|
|
862
|
-
});
|
|
863
|
-
},
|
|
864
|
-
onCancel: () => {
|
|
865
|
-
resolveOnce({ success: false, error: PAYSTACK_POPUP_ERROR.PAYMENT_CANCELLED });
|
|
866
|
-
},
|
|
867
|
-
onError: (error) => {
|
|
868
|
-
resolveOnce({
|
|
869
|
-
success: false,
|
|
870
|
-
error: error?.message || PAYSTACK_POPUP_ERROR.PAYMENT_FAILED
|
|
871
|
-
});
|
|
872
|
-
}
|
|
873
|
-
});
|
|
874
|
-
providerStarted = true;
|
|
875
|
-
} catch {
|
|
876
|
-
resolveOnce({ success: false, error: PAYSTACK_POPUP_ERROR.POPUP_BLOCKED });
|
|
877
|
-
}
|
|
878
|
-
});
|
|
879
|
-
}
|
|
880
|
-
var PaystackAuthorizationAdapter = class {
|
|
881
|
-
constructor(openPopup = openPaystackPopup) {
|
|
882
|
-
this.openPopup = openPopup;
|
|
883
|
-
this.provider = PAYMENT_AUTHORIZATION_PROVIDER.PAYSTACK;
|
|
884
|
-
}
|
|
885
|
-
async authorize(context) {
|
|
886
|
-
const result = await this.openPopup(
|
|
887
|
-
{
|
|
888
|
-
key: context.action.public_key,
|
|
889
|
-
email: context.email,
|
|
890
|
-
accessCode: context.action.client_secret,
|
|
891
|
-
reference: context.reference || context.action.client_secret,
|
|
892
|
-
currency: context.currency
|
|
893
|
-
},
|
|
894
|
-
context.signal
|
|
895
|
-
);
|
|
896
|
-
if (result.success) {
|
|
897
|
-
return {
|
|
898
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.SUBMITTED,
|
|
899
|
-
reference: result.reference || context.reference
|
|
900
|
-
};
|
|
901
|
-
}
|
|
902
|
-
if (result.error === PAYSTACK_POPUP_ERROR.SUBMISSION_UNKNOWN) {
|
|
903
|
-
return {
|
|
904
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.SUBMITTED,
|
|
905
|
-
reference: context.reference
|
|
906
|
-
};
|
|
907
|
-
}
|
|
908
|
-
if (!result.error || result.error === PAYSTACK_POPUP_ERROR.CANCELLED || result.error === PAYSTACK_POPUP_ERROR.PAYMENT_CANCELLED) {
|
|
909
|
-
return { status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.CANCELLED };
|
|
910
|
-
}
|
|
911
|
-
if (result.error === PAYSTACK_POPUP_ERROR.POPUP_BLOCKED) {
|
|
912
|
-
return {
|
|
913
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
914
|
-
code: chunkANT574FD_js.ErrorCode.POPUP_BLOCKED,
|
|
915
|
-
message: "Unable to open the Paystack payment popup. Please allow popups and try again.",
|
|
916
|
-
recoverable: true
|
|
917
|
-
};
|
|
918
|
-
}
|
|
919
|
-
if (result.error === PAYSTACK_POPUP_ERROR.PROVIDER_UNAVAILABLE) {
|
|
920
|
-
return {
|
|
921
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
922
|
-
code: chunkANT574FD_js.ErrorCode.PROVIDER_UNAVAILABLE,
|
|
923
|
-
message: "Paystack is unavailable in this environment.",
|
|
924
|
-
recoverable: false
|
|
925
|
-
};
|
|
926
|
-
}
|
|
927
|
-
return {
|
|
928
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
929
|
-
code: chunkANT574FD_js.ErrorCode.PAYMENT_FAILED,
|
|
930
|
-
message: result.error || "Paystack payment could not be submitted.",
|
|
931
|
-
recoverable: true
|
|
932
|
-
};
|
|
933
|
-
}
|
|
934
|
-
};
|
|
935
|
-
|
|
936
|
-
// src/payment-authorization/providers/stripe.ts
|
|
937
|
-
var STRIPE_REDIRECT_MODE = "if_required";
|
|
938
|
-
var STRIPE_PAYMENT_ELEMENT_TYPE = "payment";
|
|
939
|
-
async function loadStripeFromPeer(publicKey, options) {
|
|
940
|
-
try {
|
|
941
|
-
const imported = await import('@stripe/stripe-js');
|
|
942
|
-
return imported.loadStripe ? imported.loadStripe(publicKey, options) : null;
|
|
943
|
-
} catch {
|
|
944
|
-
return null;
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
function createStripeModal() {
|
|
948
|
-
if (typeof document === "undefined" || !document.body) return null;
|
|
949
|
-
const previousFocus = document.activeElement instanceof HTMLElement ? document.activeElement : null;
|
|
950
|
-
const root = document.createElement("div");
|
|
951
|
-
root.setAttribute("role", "dialog");
|
|
952
|
-
root.setAttribute("aria-modal", "true");
|
|
953
|
-
root.setAttribute("aria-label", "Secure card payment");
|
|
954
|
-
Object.assign(root.style, {
|
|
955
|
-
position: "fixed",
|
|
956
|
-
inset: "0",
|
|
957
|
-
zIndex: "2147483647",
|
|
958
|
-
display: "grid",
|
|
959
|
-
placeItems: "center",
|
|
960
|
-
padding: "16px",
|
|
961
|
-
background: "rgba(15, 23, 42, 0.58)"
|
|
962
|
-
});
|
|
963
|
-
const form = document.createElement("form");
|
|
964
|
-
Object.assign(form.style, {
|
|
965
|
-
width: "min(100%, 480px)",
|
|
966
|
-
maxHeight: "calc(100vh - 32px)",
|
|
967
|
-
overflow: "auto",
|
|
968
|
-
borderRadius: "12px",
|
|
969
|
-
padding: "24px",
|
|
970
|
-
background: "#fff",
|
|
971
|
-
boxShadow: "0 24px 80px rgba(15, 23, 42, 0.32)"
|
|
972
|
-
});
|
|
973
|
-
const title = document.createElement("h2");
|
|
974
|
-
title.textContent = "Complete card payment";
|
|
975
|
-
Object.assign(title.style, { margin: "0 0 18px", font: "600 18px/1.4 system-ui" });
|
|
976
|
-
const paymentMount = document.createElement("div");
|
|
977
|
-
paymentMount.setAttribute("data-cimplify-stripe-payment-element", "");
|
|
978
|
-
const error = document.createElement("p");
|
|
979
|
-
error.setAttribute("role", "alert");
|
|
980
|
-
Object.assign(error.style, {
|
|
981
|
-
minHeight: "20px",
|
|
982
|
-
margin: "14px 0 0",
|
|
983
|
-
color: "#b91c1c",
|
|
984
|
-
font: "14px/1.4 system-ui"
|
|
985
|
-
});
|
|
986
|
-
const actions = document.createElement("div");
|
|
987
|
-
Object.assign(actions.style, {
|
|
988
|
-
display: "flex",
|
|
989
|
-
justifyContent: "flex-end",
|
|
990
|
-
gap: "10px",
|
|
991
|
-
marginTop: "18px"
|
|
992
|
-
});
|
|
993
|
-
const cancelButton = document.createElement("button");
|
|
994
|
-
cancelButton.type = "button";
|
|
995
|
-
cancelButton.textContent = "Cancel";
|
|
996
|
-
Object.assign(cancelButton.style, {
|
|
997
|
-
border: "1px solid #cbd5e1",
|
|
998
|
-
borderRadius: "8px",
|
|
999
|
-
padding: "10px 16px",
|
|
1000
|
-
background: "#fff",
|
|
1001
|
-
color: "#0f172a",
|
|
1002
|
-
cursor: "pointer"
|
|
1003
|
-
});
|
|
1004
|
-
const submitButton = document.createElement("button");
|
|
1005
|
-
submitButton.type = "submit";
|
|
1006
|
-
submitButton.textContent = "Pay securely";
|
|
1007
|
-
Object.assign(submitButton.style, {
|
|
1008
|
-
border: "0",
|
|
1009
|
-
borderRadius: "8px",
|
|
1010
|
-
padding: "10px 16px",
|
|
1011
|
-
background: "#0f172a",
|
|
1012
|
-
color: "#fff",
|
|
1013
|
-
cursor: "pointer"
|
|
1014
|
-
});
|
|
1015
|
-
actions.append(cancelButton, submitButton);
|
|
1016
|
-
form.append(title, paymentMount, error, actions);
|
|
1017
|
-
root.append(form);
|
|
1018
|
-
document.body.append(root);
|
|
1019
|
-
cancelButton.focus();
|
|
1020
|
-
return { root, form, paymentMount, submitButton, cancelButton, error, previousFocus };
|
|
1021
|
-
}
|
|
1022
|
-
function stripeFailure(error) {
|
|
1023
|
-
const message = error?.message || "Stripe could not authorize this payment.";
|
|
1024
|
-
if (error?.code === "payment_intent_authentication_failure" || error?.type === "invalid_request_error") {
|
|
1025
|
-
return {
|
|
1026
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
1027
|
-
code: chunkANT574FD_js.ErrorCode.AUTHORIZATION_FAILED,
|
|
1028
|
-
message,
|
|
1029
|
-
recoverable: true
|
|
1030
|
-
};
|
|
1031
|
-
}
|
|
1032
|
-
return {
|
|
1033
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
1034
|
-
code: chunkANT574FD_js.ErrorCode.PAYMENT_FAILED,
|
|
1035
|
-
message,
|
|
1036
|
-
recoverable: true
|
|
1037
|
-
};
|
|
1038
|
-
}
|
|
1039
|
-
var StripeAuthorizationAdapter = class {
|
|
1040
|
-
constructor(loadStripe = loadStripeFromPeer) {
|
|
1041
|
-
this.loadStripe = loadStripe;
|
|
1042
|
-
this.provider = PAYMENT_AUTHORIZATION_PROVIDER.STRIPE;
|
|
1043
|
-
}
|
|
1044
|
-
async authorize(context) {
|
|
1045
|
-
if (typeof window === "undefined" || typeof document === "undefined" || context.signal?.aborted) {
|
|
1046
|
-
return context.signal?.aborted ? { status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.CANCELLED } : {
|
|
1047
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
1048
|
-
code: chunkANT574FD_js.ErrorCode.PROVIDER_UNAVAILABLE,
|
|
1049
|
-
message: "Stripe Payment Element is unavailable in this environment.",
|
|
1050
|
-
recoverable: false
|
|
1051
|
-
};
|
|
1052
|
-
}
|
|
1053
|
-
let stripe;
|
|
1054
|
-
try {
|
|
1055
|
-
stripe = await this.loadStripe(
|
|
1056
|
-
context.action.public_key,
|
|
1057
|
-
context.action.provider_account_id ? { stripeAccount: context.action.provider_account_id } : void 0
|
|
1058
|
-
);
|
|
1059
|
-
} catch (error) {
|
|
1060
|
-
return {
|
|
1061
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
1062
|
-
code: chunkANT574FD_js.ErrorCode.PROVIDER_UNAVAILABLE,
|
|
1063
|
-
message: error instanceof Error ? error.message : "Stripe.js could not be loaded.",
|
|
1064
|
-
recoverable: true
|
|
1065
|
-
};
|
|
1066
|
-
}
|
|
1067
|
-
if (context.signal?.aborted) {
|
|
1068
|
-
return { status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.CANCELLED };
|
|
1069
|
-
}
|
|
1070
|
-
if (!stripe) {
|
|
1071
|
-
return {
|
|
1072
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
1073
|
-
code: chunkANT574FD_js.ErrorCode.PROVIDER_UNAVAILABLE,
|
|
1074
|
-
message: "Stripe.js could not be loaded.",
|
|
1075
|
-
recoverable: false
|
|
1076
|
-
};
|
|
1077
|
-
}
|
|
1078
|
-
const modal = createStripeModal();
|
|
1079
|
-
if (!modal) {
|
|
1080
|
-
return {
|
|
1081
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
1082
|
-
code: chunkANT574FD_js.ErrorCode.PROVIDER_UNAVAILABLE,
|
|
1083
|
-
message: "Stripe Payment Element could not be mounted.",
|
|
1084
|
-
recoverable: false
|
|
1085
|
-
};
|
|
1086
|
-
}
|
|
1087
|
-
let paymentElement;
|
|
1088
|
-
let elements;
|
|
1089
|
-
try {
|
|
1090
|
-
elements = stripe.elements({ clientSecret: context.action.client_secret });
|
|
1091
|
-
paymentElement = elements.create(STRIPE_PAYMENT_ELEMENT_TYPE);
|
|
1092
|
-
paymentElement.mount(modal.paymentMount);
|
|
1093
|
-
} catch {
|
|
1094
|
-
modal.root.remove();
|
|
1095
|
-
modal.previousFocus?.focus();
|
|
1096
|
-
return {
|
|
1097
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
1098
|
-
code: chunkANT574FD_js.ErrorCode.PROVIDER_UNAVAILABLE,
|
|
1099
|
-
message: "Stripe Payment Element could not be initialized.",
|
|
1100
|
-
recoverable: false
|
|
1101
|
-
};
|
|
1102
|
-
}
|
|
1103
|
-
if (context.signal?.aborted) {
|
|
1104
|
-
if (paymentElement.destroy) paymentElement.destroy();
|
|
1105
|
-
else paymentElement.unmount?.();
|
|
1106
|
-
modal.root.remove();
|
|
1107
|
-
modal.previousFocus?.focus();
|
|
1108
|
-
return { status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.CANCELLED };
|
|
1109
|
-
}
|
|
1110
|
-
return new Promise((resolve) => {
|
|
1111
|
-
let settled = false;
|
|
1112
|
-
let submitting = false;
|
|
1113
|
-
let confirmationStarted = false;
|
|
1114
|
-
const cleanup = () => {
|
|
1115
|
-
context.signal?.removeEventListener("abort", onAbort);
|
|
1116
|
-
modal.form.removeEventListener("submit", onSubmit);
|
|
1117
|
-
modal.cancelButton.removeEventListener("click", onCancel);
|
|
1118
|
-
if (paymentElement.destroy) paymentElement.destroy();
|
|
1119
|
-
else paymentElement.unmount?.();
|
|
1120
|
-
modal.root.remove();
|
|
1121
|
-
modal.previousFocus?.focus();
|
|
1122
|
-
};
|
|
1123
|
-
const settle = (outcome) => {
|
|
1124
|
-
if (settled) return;
|
|
1125
|
-
settled = true;
|
|
1126
|
-
cleanup();
|
|
1127
|
-
resolve(outcome);
|
|
1128
|
-
};
|
|
1129
|
-
const onAbort = () => {
|
|
1130
|
-
if (confirmationStarted) {
|
|
1131
|
-
settle({
|
|
1132
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.SUBMITTED,
|
|
1133
|
-
reference: context.reference
|
|
1134
|
-
});
|
|
1135
|
-
return;
|
|
1136
|
-
}
|
|
1137
|
-
settle({ status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.CANCELLED });
|
|
1138
|
-
};
|
|
1139
|
-
const onCancel = () => {
|
|
1140
|
-
if (!confirmationStarted) {
|
|
1141
|
-
settle({ status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.CANCELLED });
|
|
1142
|
-
}
|
|
1143
|
-
};
|
|
1144
|
-
const onSubmit = async (event) => {
|
|
1145
|
-
event.preventDefault();
|
|
1146
|
-
if (submitting || settled) return;
|
|
1147
|
-
submitting = true;
|
|
1148
|
-
modal.submitButton.disabled = true;
|
|
1149
|
-
modal.error.textContent = "";
|
|
1150
|
-
try {
|
|
1151
|
-
const validation = elements.submit ? await elements.submit() : {};
|
|
1152
|
-
if (validation.error) {
|
|
1153
|
-
modal.error.textContent = validation.error.message || "Check your payment details.";
|
|
1154
|
-
submitting = false;
|
|
1155
|
-
modal.submitButton.disabled = false;
|
|
1156
|
-
return;
|
|
1157
|
-
}
|
|
1158
|
-
if (settled || context.signal?.aborted) {
|
|
1159
|
-
settle({ status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.CANCELLED });
|
|
1160
|
-
return;
|
|
1161
|
-
}
|
|
1162
|
-
confirmationStarted = true;
|
|
1163
|
-
modal.cancelButton.disabled = true;
|
|
1164
|
-
const confirmation = await stripe.confirmPayment({
|
|
1165
|
-
elements,
|
|
1166
|
-
confirmParams: { return_url: context.returnUrl || window.location.href },
|
|
1167
|
-
redirect: STRIPE_REDIRECT_MODE
|
|
1168
|
-
});
|
|
1169
|
-
if (settled) return;
|
|
1170
|
-
if (confirmation.error) {
|
|
1171
|
-
settle(stripeFailure(confirmation.error));
|
|
1172
|
-
return;
|
|
1173
|
-
}
|
|
1174
|
-
settle({
|
|
1175
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.SUBMITTED,
|
|
1176
|
-
reference: confirmation.paymentIntent?.id || context.reference
|
|
1177
|
-
});
|
|
1178
|
-
} catch (error) {
|
|
1179
|
-
if (confirmationStarted) {
|
|
1180
|
-
settle({
|
|
1181
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.SUBMITTED,
|
|
1182
|
-
reference: context.reference
|
|
1183
|
-
});
|
|
1184
|
-
return;
|
|
1185
|
-
}
|
|
1186
|
-
settle(
|
|
1187
|
-
stripeFailure({
|
|
1188
|
-
message: error instanceof Error ? error.message : "Stripe confirmation failed."
|
|
1189
|
-
})
|
|
1190
|
-
);
|
|
1191
|
-
}
|
|
1192
|
-
};
|
|
1193
|
-
modal.form.addEventListener("submit", onSubmit);
|
|
1194
|
-
modal.cancelButton.addEventListener("click", onCancel);
|
|
1195
|
-
context.signal?.addEventListener("abort", onAbort, { once: true });
|
|
1196
|
-
paymentElement.on?.("escape", onCancel);
|
|
1197
|
-
paymentElement.on?.("loaderror", (event) => {
|
|
1198
|
-
if (confirmationStarted) return;
|
|
1199
|
-
settle({
|
|
1200
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
1201
|
-
code: chunkANT574FD_js.ErrorCode.PROVIDER_UNAVAILABLE,
|
|
1202
|
-
message: event?.error?.message || "Stripe Payment Element failed to load.",
|
|
1203
|
-
recoverable: true
|
|
1204
|
-
});
|
|
1205
|
-
});
|
|
1206
|
-
});
|
|
1207
|
-
}
|
|
1208
|
-
};
|
|
1209
|
-
|
|
1210
|
-
// src/payment-authorization/registry.ts
|
|
1211
|
-
function normalizeProvider(provider) {
|
|
1212
|
-
return typeof provider === "string" ? provider.trim().toLowerCase() : "";
|
|
1213
|
-
}
|
|
1214
|
-
var PaymentAuthorizationAdapterRegistry = class {
|
|
1215
|
-
constructor(adapters = []) {
|
|
1216
|
-
this.adapters = /* @__PURE__ */ new Map();
|
|
1217
|
-
for (const adapter of adapters) {
|
|
1218
|
-
this.register(adapter);
|
|
1219
|
-
}
|
|
1220
|
-
}
|
|
1221
|
-
register(adapter) {
|
|
1222
|
-
const provider = normalizeProvider(adapter.provider);
|
|
1223
|
-
if (!provider) {
|
|
1224
|
-
throw new TypeError("Payment authorization adapter provider cannot be empty.");
|
|
1225
|
-
}
|
|
1226
|
-
this.adapters.set(provider, adapter);
|
|
1227
|
-
return this;
|
|
1228
|
-
}
|
|
1229
|
-
unregister(provider) {
|
|
1230
|
-
return this.adapters.delete(normalizeProvider(provider));
|
|
1231
|
-
}
|
|
1232
|
-
get(provider) {
|
|
1233
|
-
return this.adapters.get(normalizeProvider(provider));
|
|
1234
|
-
}
|
|
1235
|
-
supports(provider) {
|
|
1236
|
-
return this.adapters.has(normalizeProvider(provider));
|
|
1237
|
-
}
|
|
1238
|
-
providers() {
|
|
1239
|
-
return [...this.adapters.keys()];
|
|
1240
|
-
}
|
|
1241
|
-
async authorize(action, options) {
|
|
1242
|
-
const provider = normalizeProvider(action.provider);
|
|
1243
|
-
if (!provider) {
|
|
1244
|
-
return {
|
|
1245
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
1246
|
-
code: chunkANT574FD_js.ErrorCode.PROVIDER_UNAVAILABLE,
|
|
1247
|
-
message: "Card authorization response did not identify a payment provider.",
|
|
1248
|
-
recoverable: false
|
|
1249
|
-
};
|
|
1250
|
-
}
|
|
1251
|
-
const adapter = this.adapters.get(provider);
|
|
1252
|
-
if (!adapter) {
|
|
1253
|
-
return {
|
|
1254
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
1255
|
-
code: chunkANT574FD_js.ErrorCode.PROVIDER_UNAVAILABLE,
|
|
1256
|
-
message: `Card authorization provider '${provider}' is not supported by this SDK client.`,
|
|
1257
|
-
recoverable: false
|
|
1258
|
-
};
|
|
1259
|
-
}
|
|
1260
|
-
try {
|
|
1261
|
-
const normalizedAction = action.provider === provider ? action : { ...action, provider };
|
|
1262
|
-
return await adapter.authorize({ ...options, action: normalizedAction });
|
|
1263
|
-
} catch (error) {
|
|
1264
|
-
return {
|
|
1265
|
-
status: PAYMENT_AUTHORIZATION_OUTCOME_STATUS.FAILED,
|
|
1266
|
-
code: chunkANT574FD_js.ErrorCode.PAYMENT_FAILED,
|
|
1267
|
-
message: error instanceof Error ? error.message : `Card authorization provider '${provider}' failed unexpectedly.`,
|
|
1268
|
-
recoverable: true
|
|
1269
|
-
};
|
|
1270
|
-
}
|
|
1271
|
-
}
|
|
1272
|
-
};
|
|
1273
|
-
function createDefaultPaymentAuthorizationAdapterRegistry() {
|
|
1274
|
-
return new PaymentAuthorizationAdapterRegistry([
|
|
1275
|
-
new PaystackAuthorizationAdapter(),
|
|
1276
|
-
new StripeAuthorizationAdapter()
|
|
1277
|
-
]);
|
|
1278
|
-
}
|
|
1279
|
-
|
|
1280
|
-
// src/utils/purchase-intent-confirmation.ts
|
|
1281
|
-
var EXACT_ZERO_MONEY = /^[+-]?0+(?:\.0+)?(?:[eE][+-]?\d+)?$/;
|
|
1282
|
-
function isExactlyZeroMoney(value) {
|
|
1283
|
-
if (typeof value === "number") return Object.is(value, 0) || Object.is(value, -0);
|
|
1284
|
-
return EXACT_ZERO_MONEY.test(value.trim());
|
|
1285
|
-
}
|
|
1286
|
-
function selectPurchaseIntentPaymentOption(terms, selection) {
|
|
1287
|
-
return terms.payment_options.filter((option) => option.status === chunkANT574FD_js.PAYMENT_OPTION_STATUS.ELIGIBLE).sort((left, right) => left.rank - right.rank).find(
|
|
1288
|
-
(option) => option.method_kind === selection.method_kind && (selection.payment_option_id === void 0 || option.id === selection.payment_option_id)
|
|
1289
|
-
);
|
|
1290
|
-
}
|
|
1291
|
-
function createPurchaseIntentConfirmation(terms, paymentOption, idempotencyKey) {
|
|
1292
|
-
const normalizedKey = idempotencyKey.trim();
|
|
1293
|
-
if (!normalizedKey) throw new TypeError("idempotencyKey must not be empty");
|
|
1294
|
-
const requiresOption = purchaseIntentRequiresPaymentOption(terms);
|
|
1295
|
-
if (!paymentOption && requiresOption) {
|
|
1296
|
-
throw new TypeError("Nonzero rail terms require an eligible payment option");
|
|
1297
|
-
}
|
|
1298
|
-
if (paymentOption && !requiresOption) {
|
|
1299
|
-
throw new TypeError("Zero-rail terms must not name a payment option");
|
|
1300
|
-
}
|
|
1301
|
-
const authoritativeOption = paymentOption ? terms.payment_options.find(
|
|
1302
|
-
(candidate) => candidate.id === paymentOption.id && candidate.status === chunkANT574FD_js.PAYMENT_OPTION_STATUS.ELIGIBLE
|
|
1303
|
-
) : void 0;
|
|
1304
|
-
if (paymentOption && !authoritativeOption) {
|
|
1305
|
-
throw new TypeError("Payment option is not eligible for these checkout terms");
|
|
1306
|
-
}
|
|
1307
|
-
return {
|
|
1308
|
-
accepted_intent_revision: terms.intent_revision,
|
|
1309
|
-
accepted_terms_version: terms.terms_version,
|
|
1310
|
-
accepted_due_now: terms.money.due_now,
|
|
1311
|
-
// Rail fees and routes may differ by option. Consent is to the exact
|
|
1312
|
-
// server-issued buyer debit, never an ambiguous principal/fee aggregate.
|
|
1313
|
-
accepted_customer_debit_amount: authoritativeOption?.customer_debit_amount ?? terms.money.rail_amount,
|
|
1314
|
-
currency: terms.money.currency,
|
|
1315
|
-
payment_option_id: authoritativeOption?.id ?? null,
|
|
1316
|
-
idempotency_key: normalizedKey
|
|
1317
|
-
};
|
|
1318
|
-
}
|
|
1319
|
-
function purchaseIntentRequiresPaymentOption(terms) {
|
|
1320
|
-
return terms.payment_options.length > 0 || !isExactlyZeroMoney(terms.money.rail_amount);
|
|
1321
|
-
}
|
|
1322
|
-
var PLAIN_DECIMAL = /^([+-]?)(\d+)(?:\.(\d+))?$/;
|
|
1323
|
-
function canonicalDecimal(value) {
|
|
1324
|
-
const match = PLAIN_DECIMAL.exec(typeof value === "number" ? String(value) : value.trim());
|
|
1325
|
-
if (!match) return null;
|
|
1326
|
-
const whole = match[2].replace(/^0+(?=\d)/, "");
|
|
1327
|
-
const fraction = (match[3] ?? "").replace(/0+$/, "");
|
|
1328
|
-
const isZero = whole === "0" && fraction === "";
|
|
1329
|
-
return `${match[1] === "-" && !isZero ? "-" : ""}${whole}${fraction ? `.${fraction}` : ""}`;
|
|
1330
|
-
}
|
|
1331
|
-
function isSameAmount(left, right) {
|
|
1332
|
-
const canonicalLeft = canonicalDecimal(left);
|
|
1333
|
-
return canonicalLeft !== null && canonicalLeft === canonicalDecimal(right);
|
|
1334
|
-
}
|
|
1335
|
-
function confirmationForUnchangedReplacement(response, selection, idempotencyKey) {
|
|
1336
|
-
const { replacement, deltas } = response;
|
|
1337
|
-
const paymentDeltas = deltas.filter(
|
|
1338
|
-
(delta2) => delta2.kind === chunkANT574FD_js.CHECKOUT_TERMS_DELTA_KIND.PAYMENT_OPTION
|
|
1339
|
-
);
|
|
1340
|
-
if (paymentDeltas.length !== deltas.length) return null;
|
|
1341
|
-
if (!purchaseIntentRequiresPaymentOption(replacement)) {
|
|
1342
|
-
return paymentDeltas.length === 0 ? createPurchaseIntentConfirmation(replacement, null, idempotencyKey) : null;
|
|
1343
|
-
}
|
|
1344
|
-
if (!selection || paymentDeltas.length !== 1) return null;
|
|
1345
|
-
const option = selectPurchaseIntentPaymentOption(replacement, {
|
|
1346
|
-
method_kind: selection.method_kind
|
|
1347
|
-
});
|
|
1348
|
-
const [delta] = paymentDeltas;
|
|
1349
|
-
if (!option || delta.kind !== chunkANT574FD_js.CHECKOUT_TERMS_DELTA_KIND.PAYMENT_OPTION) return null;
|
|
1350
|
-
if (!isSameAmount(option.customer_debit_amount, delta.accepted_customer_debit_amount)) {
|
|
1351
|
-
return null;
|
|
1352
|
-
}
|
|
1353
|
-
return createPurchaseIntentConfirmation(replacement, option, idempotencyKey);
|
|
1354
|
-
}
|
|
1355
|
-
|
|
1356
|
-
// src/utils/purchase-intent-adapter.ts
|
|
1357
|
-
function tenderPreference(form) {
|
|
1358
|
-
if (form.payment_method === chunkANT574FD_js.PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY) {
|
|
1359
|
-
if (form.link_payment_method_id) {
|
|
1360
|
-
return {
|
|
1361
|
-
method_kind: chunkANT574FD_js.PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY,
|
|
1362
|
-
authority: {
|
|
1363
|
-
authority_kind: chunkANT574FD_js.MOBILE_MONEY_TENDER_AUTHORITY_KIND.SAVED_REFERENCE,
|
|
1364
|
-
stored_instrument_id: form.link_payment_method_id
|
|
1365
|
-
}
|
|
1366
|
-
};
|
|
1367
|
-
}
|
|
1368
|
-
const details = form.mobile_money_details;
|
|
1369
|
-
if (!details?.phone_number || !details.provider) {
|
|
1370
|
-
throw new chunkANT574FD_js.CimplifyError(
|
|
1371
|
-
chunkANT574FD_js.ErrorCode.INVALID_PAYMENT_METHOD,
|
|
1372
|
-
"Mobile money requires a phone number and network.",
|
|
1373
|
-
false
|
|
1374
|
-
);
|
|
1375
|
-
}
|
|
1376
|
-
const network = chunkV32BCG7M_js.purchaseIntentMobileMoneyNetwork(details.provider);
|
|
1377
|
-
if (!network) {
|
|
1378
|
-
throw new chunkANT574FD_js.CimplifyError(
|
|
1379
|
-
chunkANT574FD_js.ErrorCode.INVALID_PAYMENT_METHOD,
|
|
1380
|
-
"That mobile money network is not available for PurchaseIntent checkout.",
|
|
1381
|
-
false
|
|
1382
|
-
);
|
|
1383
|
-
}
|
|
1384
|
-
return {
|
|
1385
|
-
method_kind: chunkANT574FD_js.PURCHASE_INTENT_PAYMENT_METHOD.MOBILE_MONEY,
|
|
1386
|
-
authority: {
|
|
1387
|
-
authority_kind: chunkANT574FD_js.MOBILE_MONEY_TENDER_AUTHORITY_KIND.TRANSIENT,
|
|
1388
|
-
phone_number: details.phone_number,
|
|
1389
|
-
network
|
|
1390
|
-
}
|
|
1391
|
-
};
|
|
1392
|
-
}
|
|
1393
|
-
if (form.payment_method === chunkANT574FD_js.LEGACY_CHECKOUT_PAYMENT_METHOD_ALIAS.CASH || form.payment_method === chunkANT574FD_js.PURCHASE_INTENT_PAYMENT_METHOD.OFFLINE) {
|
|
1394
|
-
throw new chunkANT574FD_js.CimplifyError(
|
|
1395
|
-
chunkANT574FD_js.ErrorCode.INVALID_PAYMENT_METHOD,
|
|
1396
|
-
"Offline tender requires an authenticated staff checkout.",
|
|
1397
|
-
false
|
|
1398
|
-
);
|
|
1399
|
-
}
|
|
1400
|
-
if (form.payment_method === chunkANT574FD_js.PURCHASE_INTENT_PAYMENT_METHOD.CARD) {
|
|
1401
|
-
return {
|
|
1402
|
-
method_kind: chunkANT574FD_js.PURCHASE_INTENT_PAYMENT_METHOD.CARD,
|
|
1403
|
-
stored_instrument_id: form.link_payment_method_id
|
|
1404
|
-
};
|
|
1405
|
-
}
|
|
1406
|
-
if (form.payment_method === chunkANT574FD_js.LEGACY_CHECKOUT_PAYMENT_METHOD_ALIAS.STORE_CREDIT) {
|
|
1407
|
-
return void 0;
|
|
1408
|
-
}
|
|
1409
|
-
throw new chunkANT574FD_js.CimplifyError(
|
|
1410
|
-
chunkANT574FD_js.ErrorCode.INVALID_PAYMENT_METHOD,
|
|
1411
|
-
"Checkout payment method is not supported.",
|
|
1412
|
-
false
|
|
1413
|
-
);
|
|
1414
|
-
}
|
|
1415
|
-
function checkoutFormToIntentRequest(form, clientIntentKey) {
|
|
1416
|
-
return {
|
|
1417
|
-
client_intent_key: clientIntentKey,
|
|
1418
|
-
source: { kind: chunkANT574FD_js.PURCHASE_INTENT_SOURCE_KIND.CART, cart_id: form.cart_id },
|
|
1419
|
-
checkout: {
|
|
1420
|
-
customer: form.customer,
|
|
1421
|
-
order_type: form.order_type,
|
|
1422
|
-
address_info: form.address_info,
|
|
1423
|
-
location_id: form.location_id,
|
|
1424
|
-
delivery_rate_id: form.delivery_rate_id,
|
|
1425
|
-
special_instructions: form.special_instructions,
|
|
1426
|
-
link_address_id: form.link_address_id,
|
|
1427
|
-
metadata: form.metadata,
|
|
1428
|
-
pay_currency: form.pay_currency,
|
|
1429
|
-
fx_quote_id: form.fx_quote_id,
|
|
1430
|
-
use_store_credit: form.use_store_credit || form.payment_method === chunkANT574FD_js.LEGACY_CHECKOUT_PAYMENT_METHOD_ALIAS.STORE_CREDIT,
|
|
1431
|
-
voucher_code: form.voucher_code,
|
|
1432
|
-
pay_deposit: form.pay_deposit,
|
|
1433
|
-
tender_preference: tenderPreference(form)
|
|
1434
|
-
}
|
|
1435
|
-
};
|
|
1436
|
-
}
|
|
1437
|
-
function selectCheckoutPaymentOption(terms, form) {
|
|
1438
|
-
const preference = tenderPreference(form);
|
|
1439
|
-
if (!preference) return void 0;
|
|
1440
|
-
return terms.payment_options.filter((option) => option.status === chunkANT574FD_js.PAYMENT_OPTION_STATUS.ELIGIBLE).sort((left, right) => left.rank - right.rank).find((option) => option.method_kind === preference.method_kind);
|
|
1441
|
-
}
|
|
1442
|
-
function checkoutFormToConfirmation(_form, terms, paymentOption, idempotencyKey) {
|
|
1443
|
-
return createPurchaseIntentConfirmation(terms, paymentOption, idempotencyKey);
|
|
1444
|
-
}
|
|
1445
|
-
function committedBase(response) {
|
|
1446
|
-
return {
|
|
1447
|
-
intent_id: response.intent_id,
|
|
1448
|
-
attempt_id: response.attempt_id,
|
|
1449
|
-
order_id: response.order_id,
|
|
1450
|
-
order_number: response.order_number || response.order_id,
|
|
1451
|
-
payment_id: response.payment_id
|
|
1452
|
-
};
|
|
1453
|
-
}
|
|
1454
|
-
function confirmationToCheckoutResult(response) {
|
|
1455
|
-
switch (response.status) {
|
|
1456
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.ORDER_CREATED:
|
|
1457
|
-
return ok({
|
|
1458
|
-
...committedBase(response),
|
|
1459
|
-
payment_status: chunkANT574FD_js.LEGACY_CHECKOUT_PAYMENT_STATUS.SUCCEEDED,
|
|
1460
|
-
requires_authorization: false,
|
|
1461
|
-
next_action: { type: chunkEV2EVOYS_js.CHECKOUT_NEXT_ACTION.NONE }
|
|
1462
|
-
});
|
|
1463
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.COLLECTION_PROCESSING:
|
|
1464
|
-
return ok({
|
|
1465
|
-
...committedBase(response),
|
|
1466
|
-
payment_status: chunkANT574FD_js.LEGACY_CHECKOUT_PAYMENT_STATUS.PROCESSING,
|
|
1467
|
-
requires_authorization: false,
|
|
1468
|
-
next_action: { type: chunkEV2EVOYS_js.CHECKOUT_NEXT_ACTION.POLL }
|
|
1469
|
-
});
|
|
1470
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.PAYMENT_OUTCOME_UNKNOWN:
|
|
1471
|
-
return ok({
|
|
1472
|
-
...committedBase(response),
|
|
1473
|
-
payment_status: chunkANT574FD_js.LEGACY_CHECKOUT_PAYMENT_STATUS.UNKNOWN,
|
|
1474
|
-
requires_authorization: false,
|
|
1475
|
-
next_action: { type: chunkEV2EVOYS_js.CHECKOUT_NEXT_ACTION.POLL }
|
|
1476
|
-
});
|
|
1477
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.PAYMENT_FAILED:
|
|
1478
|
-
return err(
|
|
1479
|
-
new chunkANT574FD_js.CimplifyError(
|
|
1480
|
-
chunkANT574FD_js.PURCHASE_INTENT_ERROR_CODE.PAYMENT_FAILED,
|
|
1481
|
-
"Payment failed. The order remains recorded, but collection did not succeed.",
|
|
1482
|
-
true
|
|
1483
|
-
)
|
|
1484
|
-
);
|
|
1485
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.REDIRECT_REQUIRED:
|
|
1486
|
-
return ok({
|
|
1487
|
-
...committedBase(response),
|
|
1488
|
-
payment_status: chunkANT574FD_js.LEGACY_CHECKOUT_PAYMENT_STATUS.REQUIRES_ACTION,
|
|
1489
|
-
requires_authorization: false,
|
|
1490
|
-
authorization_url: response.authorization_url,
|
|
1491
|
-
next_action: {
|
|
1492
|
-
type: chunkEV2EVOYS_js.CHECKOUT_NEXT_ACTION.REDIRECT,
|
|
1493
|
-
authorization_url: response.authorization_url
|
|
1494
|
-
}
|
|
1495
|
-
});
|
|
1496
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.CARD_POPUP_REQUIRED:
|
|
1497
|
-
return ok({
|
|
1498
|
-
...committedBase(response),
|
|
1499
|
-
payment_status: chunkANT574FD_js.LEGACY_CHECKOUT_PAYMENT_STATUS.REQUIRES_ACTION,
|
|
1500
|
-
requires_authorization: false,
|
|
1501
|
-
provider: response.provider,
|
|
1502
|
-
client_secret: response.client_secret,
|
|
1503
|
-
public_key: response.public_key,
|
|
1504
|
-
next_action: {
|
|
1505
|
-
type: chunkEV2EVOYS_js.CHECKOUT_NEXT_ACTION.CARD_POPUP,
|
|
1506
|
-
provider: response.provider,
|
|
1507
|
-
client_secret: response.client_secret,
|
|
1508
|
-
public_key: response.public_key,
|
|
1509
|
-
provider_account_id: response.provider_account_id ?? void 0
|
|
1510
|
-
}
|
|
1511
|
-
});
|
|
1512
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.AUTHORIZATION_REQUIRED:
|
|
1513
|
-
return ok({
|
|
1514
|
-
...committedBase(response),
|
|
1515
|
-
payment_status: chunkANT574FD_js.LEGACY_CHECKOUT_PAYMENT_STATUS.REQUIRES_ACTION,
|
|
1516
|
-
requires_authorization: true,
|
|
1517
|
-
authorization_type: response.authorization_type,
|
|
1518
|
-
display_text: response.display_text,
|
|
1519
|
-
next_action: {
|
|
1520
|
-
type: chunkEV2EVOYS_js.CHECKOUT_NEXT_ACTION.AUTHORIZATION,
|
|
1521
|
-
authorization_type: response.authorization_type,
|
|
1522
|
-
display_text: response.display_text
|
|
1523
|
-
}
|
|
1524
|
-
});
|
|
1525
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.TERMS_CHANGED:
|
|
1526
|
-
return err(
|
|
1527
|
-
new chunkANT574FD_js.CimplifyError(
|
|
1528
|
-
chunkANT574FD_js.PURCHASE_INTENT_ERROR_CODE.TERMS_CHANGED,
|
|
1529
|
-
"Checkout terms changed. Review the replacement terms before confirming again.",
|
|
1530
|
-
true
|
|
1531
|
-
)
|
|
1532
|
-
);
|
|
1533
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.SELECTION_UNAVAILABLE:
|
|
1534
|
-
return err(
|
|
1535
|
-
new chunkANT574FD_js.CimplifyError(
|
|
1536
|
-
chunkANT574FD_js.PURCHASE_INTENT_ERROR_CODE.SELECTION_UNAVAILABLE,
|
|
1537
|
-
"One or more checkout selections are no longer available.",
|
|
1538
|
-
true
|
|
1539
|
-
)
|
|
1540
|
-
);
|
|
1541
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.OFFER_ENDED:
|
|
1542
|
-
return err(
|
|
1543
|
-
new chunkANT574FD_js.CimplifyError(
|
|
1544
|
-
chunkANT574FD_js.PURCHASE_INTENT_ERROR_CODE.OFFER_ENDED,
|
|
1545
|
-
"This offer has ended.",
|
|
1546
|
-
false
|
|
1547
|
-
)
|
|
1548
|
-
);
|
|
1549
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.SOURCE_UNAVAILABLE:
|
|
1550
|
-
return err(
|
|
1551
|
-
new chunkANT574FD_js.CimplifyError(
|
|
1552
|
-
chunkANT574FD_js.PURCHASE_INTENT_ERROR_CODE.SOURCE_UNAVAILABLE,
|
|
1553
|
-
"This purchase source is unavailable.",
|
|
1554
|
-
false
|
|
1555
|
-
)
|
|
1556
|
-
);
|
|
1557
|
-
}
|
|
1558
|
-
}
|
|
1559
|
-
|
|
1560
|
-
// src/checkout.ts
|
|
1561
|
-
function checkoutActionAuthority(response) {
|
|
1562
|
-
if (response.status !== chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.CARD_POPUP_REQUIRED && response.status !== chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.AUTHORIZATION_REQUIRED) {
|
|
1563
|
-
return null;
|
|
1564
|
-
}
|
|
1565
|
-
const paymentId = response.payment_id?.trim();
|
|
1566
|
-
return paymentId ? {
|
|
1567
|
-
intentId: response.intent_id,
|
|
1568
|
-
attemptId: response.attempt_id,
|
|
1569
|
-
paymentId
|
|
1570
|
-
} : null;
|
|
1571
|
-
}
|
|
1572
|
-
function isAmbiguousCheckoutError(error) {
|
|
1573
|
-
return error.code === chunkANT574FD_js.ErrorCode.NETWORK_ERROR || error.code === chunkANT574FD_js.ErrorCode.TIMEOUT;
|
|
1574
|
-
}
|
|
1575
|
-
function authorizationKind(value) {
|
|
1576
|
-
if (value && typeof value === "object" && chunkEV2EVOYS_js.AUTHORIZATION_TYPE.ADDRESS in value) {
|
|
1577
|
-
return chunkEV2EVOYS_js.AUTHORIZATION_TYPE.ADDRESS;
|
|
1578
|
-
}
|
|
1579
|
-
if (value === chunkEV2EVOYS_js.AUTHORIZATION_TYPE.OTP || value === chunkEV2EVOYS_js.AUTHORIZATION_TYPE.PIN || value === chunkEV2EVOYS_js.AUTHORIZATION_TYPE.PHONE || value === chunkEV2EVOYS_js.AUTHORIZATION_TYPE.BIRTHDAY) {
|
|
1580
|
-
return value;
|
|
1581
|
-
}
|
|
1582
|
-
return void 0;
|
|
1583
|
-
}
|
|
1584
|
-
function normalizeAuthorizationSubmission(expected, submission) {
|
|
1585
|
-
if (submission.type !== expected) throw new Error(`Expected ${expected} authorization details.`);
|
|
1586
|
-
if (submission.type === chunkEV2EVOYS_js.AUTHORIZATION_TYPE.ADDRESS) {
|
|
1587
|
-
const address = submission.address.trim();
|
|
1588
|
-
const city = submission.city.trim();
|
|
1589
|
-
const state = submission.state.trim();
|
|
1590
|
-
const zipCode = submission.zip_code.trim();
|
|
1591
|
-
if (!address || !city || !state || !zipCode) {
|
|
1592
|
-
throw new Error("Complete all authorization address fields.");
|
|
1593
|
-
}
|
|
1594
|
-
return { type: chunkEV2EVOYS_js.AUTHORIZATION_TYPE.ADDRESS, address, city, state, zip_code: zipCode };
|
|
1595
|
-
}
|
|
1596
|
-
const value = submission.value.trim();
|
|
1597
|
-
if (!value) throw new Error("Authorization value is required.");
|
|
1598
|
-
return { type: submission.type, value };
|
|
1599
|
-
}
|
|
1600
|
-
var DECIMAL_WIRE_VALUE = /^([+-]?)(\d+)(?:\.(\d+))?(?:[eE][+-]?\d+)?$/;
|
|
1601
|
-
function decimalSign(value) {
|
|
1602
|
-
if (typeof value === "number") {
|
|
1603
|
-
if (!Number.isFinite(value)) return null;
|
|
1604
|
-
if (Object.is(value, 0) || Object.is(value, -0)) return 0;
|
|
1605
|
-
return value > 0 ? 1 : -1;
|
|
1606
|
-
}
|
|
1607
|
-
const match = DECIMAL_WIRE_VALUE.exec(value.trim());
|
|
1608
|
-
if (!match) return null;
|
|
1609
|
-
const nonzero = [...match[2], ...match[3] ?? ""].some((digit) => digit !== "0");
|
|
1610
|
-
if (!nonzero) return 0;
|
|
1611
|
-
return match[1] === "-" ? -1 : 1;
|
|
1612
|
-
}
|
|
1613
|
-
function toTerminalFailure(code, message, recoverable) {
|
|
1614
|
-
return {
|
|
1615
|
-
success: false,
|
|
1616
|
-
error: {
|
|
1617
|
-
code,
|
|
1618
|
-
message,
|
|
1619
|
-
recoverable
|
|
1620
|
-
}
|
|
1621
|
-
};
|
|
1622
|
-
}
|
|
1623
|
-
function isValidCustomerName(name) {
|
|
1624
|
-
const trimmed = (name ?? "").trim();
|
|
1625
|
-
return trimmed.length >= 2 && /\p{L}/u.test(trimmed);
|
|
1626
|
-
}
|
|
1627
|
-
function isOfflinePaymentMethod(method) {
|
|
1628
|
-
return method === chunkANT574FD_js.LEGACY_CHECKOUT_PAYMENT_METHOD_ALIAS.CASH || method === chunkANT574FD_js.PURCHASE_INTENT_PAYMENT_METHOD.OFFLINE;
|
|
1629
|
-
}
|
|
1630
|
-
function notifyCheckoutStatus(observer, status, context = {}) {
|
|
1631
|
-
try {
|
|
1632
|
-
observer?.(status, context);
|
|
1633
|
-
} catch {
|
|
1634
|
-
}
|
|
1635
|
-
}
|
|
1636
|
-
function notifyAuthorizationUi(observer, open) {
|
|
1637
|
-
try {
|
|
1638
|
-
observer?.(open);
|
|
1639
|
-
} catch {
|
|
1640
|
-
}
|
|
1641
|
-
}
|
|
1642
|
-
var MAX_STOREFRONT_COLLECTION_OPTIONS = 32;
|
|
1643
|
-
var CHECKOUT_INTENT_SCOPE_PREFIX = "checkout:";
|
|
1644
|
-
var CHECKOUT_CONFIRMATION_SCOPE_PREFIX = "checkout-confirm:";
|
|
1645
|
-
var CHECKOUT_INTENT_RECOVERY_FINGERPRINT = "cart-intent-v1";
|
|
1646
|
-
var ABORT_ERROR_NAME = "AbortError";
|
|
1647
|
-
var AUTHORIZATION_POPUP_NAME = "cimplify-auth";
|
|
1648
|
-
var AUTHORIZATION_POPUP_FEATURES = "width=520,height=760";
|
|
1649
|
-
var ORDER_TOKEN_QUERY_PARAMETER = "token";
|
|
1650
|
-
var CHECKOUT_API_ROUTE = {
|
|
1651
|
-
COLLECTION_OPTIONS: "/api/v1/payments/collection-options",
|
|
1652
|
-
paymentStatus: (orderId) => `/api/v1/orders/${orderId}/payment-status`,
|
|
1653
|
-
updateCustomer: (orderId) => `/api/v1/orders/${orderId}/customer`,
|
|
1654
|
-
verifyPayment: (orderId) => `/api/v1/orders/${orderId}/verify-payment`
|
|
1655
|
-
};
|
|
1656
|
-
var CHECKOUT_STATUS_BY_PURCHASE_INTENT_RESOLVE_STATUS = {
|
|
1657
|
-
[chunkANT574FD_js.PURCHASE_INTENT_RESOLVE_STATUS.CONFIRMING]: chunkEV2EVOYS_js.CHECKOUT_STATUS.PROCESSING,
|
|
1658
|
-
[chunkANT574FD_js.PURCHASE_INTENT_RESOLVE_STATUS.POLLING]: chunkEV2EVOYS_js.CHECKOUT_STATUS.POLLING,
|
|
1659
|
-
[chunkANT574FD_js.PURCHASE_INTENT_RESOLVE_STATUS.AWAITING_ACTION]: chunkEV2EVOYS_js.CHECKOUT_STATUS.AWAITING_AUTHORIZATION,
|
|
1660
|
-
[chunkANT574FD_js.PURCHASE_INTENT_RESOLVE_STATUS.REVIEWING_TERMS]: chunkEV2EVOYS_js.CHECKOUT_STATUS.REVIEWING_TERMS,
|
|
1661
|
-
[chunkANT574FD_js.PURCHASE_INTENT_RESOLVE_STATUS.COMPLETED]: chunkEV2EVOYS_js.CHECKOUT_STATUS.FINALIZING,
|
|
1662
|
-
[chunkANT574FD_js.PURCHASE_INTENT_RESOLVE_STATUS.FAILED]: chunkEV2EVOYS_js.CHECKOUT_STATUS.FAILED,
|
|
1663
|
-
[chunkANT574FD_js.PURCHASE_INTENT_RESOLVE_STATUS.OUTCOME_UNKNOWN]: chunkEV2EVOYS_js.CHECKOUT_STATUS.RECOVERING
|
|
1664
|
-
};
|
|
1665
|
-
function normalizeCollectionOptions(value, expectedCurrency) {
|
|
1666
|
-
if (!value || typeof value !== "object") return null;
|
|
1667
|
-
const response = value;
|
|
1668
|
-
if (response.presentment_currency !== expectedCurrency || !Array.isArray(response.options)) {
|
|
1669
|
-
return null;
|
|
1670
|
-
}
|
|
1671
|
-
if (response.options.length > MAX_STOREFRONT_COLLECTION_OPTIONS) return null;
|
|
1672
|
-
const options = [];
|
|
1673
|
-
const seen = /* @__PURE__ */ new Set();
|
|
1674
|
-
for (const candidate of response.options) {
|
|
1675
|
-
if (!candidate || typeof candidate !== "object") continue;
|
|
1676
|
-
const option = candidate;
|
|
1677
|
-
if (option.method === chunkEV2EVOYS_js.PAYMENT_METHOD.CARD && option.network == null) {
|
|
1678
|
-
if (!seen.has(chunkEV2EVOYS_js.PAYMENT_METHOD.CARD)) {
|
|
1679
|
-
seen.add(chunkEV2EVOYS_js.PAYMENT_METHOD.CARD);
|
|
1680
|
-
options.push({ method: chunkEV2EVOYS_js.PAYMENT_METHOD.CARD, network: null });
|
|
1681
|
-
}
|
|
1682
|
-
continue;
|
|
1683
|
-
}
|
|
1684
|
-
if (option.method !== chunkEV2EVOYS_js.PAYMENT_METHOD.MOBILE_MONEY || typeof option.network !== "string" || !option.network.trim()) {
|
|
1685
|
-
continue;
|
|
1686
|
-
}
|
|
1687
|
-
const network = chunkV32BCG7M_js.purchaseIntentMobileMoneyNetwork(option.network);
|
|
1688
|
-
if (!network) continue;
|
|
1689
|
-
const key = `${chunkEV2EVOYS_js.PAYMENT_METHOD.MOBILE_MONEY}:${network}`;
|
|
1690
|
-
if (seen.has(key)) continue;
|
|
1691
|
-
seen.add(key);
|
|
1692
|
-
options.push({ method: chunkEV2EVOYS_js.PAYMENT_METHOD.MOBILE_MONEY, network });
|
|
1693
|
-
}
|
|
1694
|
-
return { presentment_currency: expectedCurrency, options };
|
|
1695
|
-
}
|
|
1696
|
-
var CheckoutService = class {
|
|
1697
|
-
constructor(client) {
|
|
1698
|
-
this.client = client;
|
|
1699
|
-
/** Raw checkout material is component-lifetime only, never browser storage. */
|
|
1700
|
-
this.intentCommands = /* @__PURE__ */ new Map();
|
|
1701
|
-
/** Opaque owner/attempt authority for deprecated action submission. */
|
|
1702
|
-
this.actionAuthorities = /* @__PURE__ */ new Map();
|
|
1703
|
-
}
|
|
1704
|
-
validateCheckoutData(data) {
|
|
1705
|
-
if (isOfflinePaymentMethod(data.payment_method)) {
|
|
1706
|
-
return new chunkANT574FD_js.CimplifyError(
|
|
1707
|
-
chunkANT574FD_js.ErrorCode.INVALID_PAYMENT_METHOD,
|
|
1708
|
-
"Offline payment isn't available for online checkout. Please pay by card or mobile money.",
|
|
1709
|
-
false
|
|
1710
|
-
);
|
|
1711
|
-
}
|
|
1712
|
-
if (!isValidCustomerName(data.customer?.name)) {
|
|
1713
|
-
return new chunkANT574FD_js.CimplifyError(
|
|
1714
|
-
chunkANT574FD_js.ErrorCode.INVALID_CUSTOMER_NAME,
|
|
1715
|
-
"Enter your name, not a phone number.",
|
|
1716
|
-
false
|
|
1717
|
-
);
|
|
1718
|
-
}
|
|
1719
|
-
return null;
|
|
1720
|
-
}
|
|
1721
|
-
orderTokenParam(orderId) {
|
|
1722
|
-
const token = this.client.getOrderToken(orderId);
|
|
1723
|
-
return token ? `?${ORDER_TOKEN_QUERY_PARAMETER}=${encodeURIComponent(token)}` : "";
|
|
1724
|
-
}
|
|
1725
|
-
/** Available storefront collection methods for one presentment currency. */
|
|
1726
|
-
async collectionOptions(currency) {
|
|
1727
|
-
const normalized = currency.trim().toUpperCase();
|
|
1728
|
-
if (!chunkANT574FD_js.isSupportedCurrency(normalized)) {
|
|
1729
|
-
return err(
|
|
1730
|
-
new chunkANT574FD_js.CimplifyError(
|
|
1731
|
-
chunkANT574FD_js.ErrorCode.UNSUPPORTED_CURRENCY,
|
|
1732
|
-
"No online payment method is available for this currency.",
|
|
1733
|
-
false
|
|
1734
|
-
)
|
|
1735
|
-
);
|
|
1736
|
-
}
|
|
1737
|
-
const response = await safe(
|
|
1738
|
-
this.client.get(
|
|
1739
|
-
`${CHECKOUT_API_ROUTE.COLLECTION_OPTIONS}?currency=${encodeURIComponent(normalized)}`
|
|
1740
|
-
)
|
|
1741
|
-
);
|
|
1742
|
-
if (!response.ok) return response;
|
|
1743
|
-
const options = normalizeCollectionOptions(response.value, normalized);
|
|
1744
|
-
return options ? ok(options) : err(
|
|
1745
|
-
new chunkANT574FD_js.CimplifyError(
|
|
1746
|
-
chunkANT574FD_js.ErrorCode.PAYMENT_CAPABILITY_MISMATCH,
|
|
1747
|
-
"Payment methods could not be verified for this currency.",
|
|
1748
|
-
false
|
|
1749
|
-
)
|
|
1750
|
-
);
|
|
1751
|
-
}
|
|
1752
|
-
/**
|
|
1753
|
-
* Run provider-owned UI for a backend `card_popup` action. A submitted
|
|
1754
|
-
* outcome is not proof of payment; callers must poll/verify with Cimplify.
|
|
1755
|
-
*/
|
|
1756
|
-
authorizeCardPopup(action, options) {
|
|
1757
|
-
return this.client.authorizationAdapters.authorize(action, options);
|
|
1758
|
-
}
|
|
1759
|
-
async startIntentCheckout(data, options) {
|
|
1760
|
-
const invalid = this.validateCheckoutData(data);
|
|
1761
|
-
if (invalid) return err(invalid);
|
|
1762
|
-
const intentScope = `${CHECKOUT_INTENT_SCOPE_PREFIX}${data.cart_id}`;
|
|
1763
|
-
const inMemoryCommand = JSON.stringify(data);
|
|
1764
|
-
const previousCommand = this.intentCommands.get(intentScope);
|
|
1765
|
-
if (previousCommand !== void 0 && previousCommand !== inMemoryCommand) {
|
|
1766
|
-
clearIntentIdempotencyKey(intentScope);
|
|
1767
|
-
}
|
|
1768
|
-
this.intentCommands.set(intentScope, inMemoryCommand);
|
|
1769
|
-
const clientIntentKey = data.idempotency_key || intentIdempotencyKey(intentScope, CHECKOUT_INTENT_RECOVERY_FINGERPRINT);
|
|
1770
|
-
const checkoutData = { ...data, idempotency_key: clientIntentKey };
|
|
1771
|
-
let mintRequest;
|
|
1772
|
-
try {
|
|
1773
|
-
mintRequest = checkoutFormToIntentRequest(checkoutData, clientIntentKey);
|
|
1774
|
-
} catch (error) {
|
|
1775
|
-
clearIntentIdempotencyKey(intentScope);
|
|
1776
|
-
this.intentCommands.delete(intentScope);
|
|
1777
|
-
return err(
|
|
1778
|
-
error instanceof chunkANT574FD_js.CimplifyError ? error : new chunkANT574FD_js.CimplifyError(
|
|
1779
|
-
chunkANT574FD_js.ErrorCode.CHECKOUT_VALIDATION_FAILED,
|
|
1780
|
-
"Checkout details are invalid.",
|
|
1781
|
-
false
|
|
1782
|
-
)
|
|
1783
|
-
);
|
|
1784
|
-
}
|
|
1785
|
-
const minted = await this.client.purchaseIntents.mint(mintRequest, options);
|
|
1786
|
-
if (!minted.ok) {
|
|
1787
|
-
if (!isAmbiguousCheckoutError(minted.error)) {
|
|
1788
|
-
clearIntentIdempotencyKey(intentScope);
|
|
1789
|
-
this.intentCommands.delete(intentScope);
|
|
1790
|
-
}
|
|
1791
|
-
return minted;
|
|
1792
|
-
}
|
|
1793
|
-
const terms = minted.value.current_terms;
|
|
1794
|
-
if (!terms) {
|
|
1795
|
-
clearIntentIdempotencyKey(intentScope);
|
|
1796
|
-
this.intentCommands.delete(intentScope);
|
|
1797
|
-
return err(
|
|
1798
|
-
new chunkANT574FD_js.CimplifyError(
|
|
1799
|
-
chunkANT574FD_js.ErrorCode.CHECKOUT_TERMS_UNAVAILABLE,
|
|
1800
|
-
"Checkout terms are not available for this purchase intent.",
|
|
1801
|
-
true
|
|
1802
|
-
)
|
|
1803
|
-
);
|
|
1804
|
-
}
|
|
1805
|
-
let paymentOption;
|
|
1806
|
-
try {
|
|
1807
|
-
paymentOption = selectCheckoutPaymentOption(terms, checkoutData);
|
|
1808
|
-
} catch (error) {
|
|
1809
|
-
return err(
|
|
1810
|
-
error instanceof chunkANT574FD_js.CimplifyError ? error : new chunkANT574FD_js.CimplifyError(
|
|
1811
|
-
chunkANT574FD_js.ErrorCode.INVALID_PAYMENT_METHOD,
|
|
1812
|
-
"Payment details are invalid.",
|
|
1813
|
-
false
|
|
1814
|
-
)
|
|
1815
|
-
);
|
|
1816
|
-
}
|
|
1817
|
-
if (!paymentOption && purchaseIntentRequiresPaymentOption(terms)) {
|
|
1818
|
-
return err(
|
|
1819
|
-
new chunkANT574FD_js.CimplifyError(
|
|
1820
|
-
chunkANT574FD_js.ErrorCode.PAYMENT_CAPABILITY_MISMATCH,
|
|
1821
|
-
"The selected payment method is not eligible for these checkout terms.",
|
|
1822
|
-
true
|
|
1823
|
-
)
|
|
1824
|
-
);
|
|
1825
|
-
}
|
|
1826
|
-
const confirmationScope = `${CHECKOUT_CONFIRMATION_SCOPE_PREFIX}${minted.value.id}`;
|
|
1827
|
-
const confirmationFingerprint = JSON.stringify([
|
|
1828
|
-
terms.intent_revision,
|
|
1829
|
-
terms.terms_version,
|
|
1830
|
-
terms.terms_digest,
|
|
1831
|
-
paymentOption?.id ?? null,
|
|
1832
|
-
terms.money.due_now,
|
|
1833
|
-
paymentOption?.customer_debit_amount ?? terms.money.rail_amount,
|
|
1834
|
-
terms.money.currency
|
|
1835
|
-
]);
|
|
1836
|
-
const confirmationKey = intentIdempotencyKey(
|
|
1837
|
-
confirmationScope,
|
|
1838
|
-
confirmationFingerprint
|
|
1839
|
-
);
|
|
1840
|
-
const confirmation = checkoutFormToConfirmation(
|
|
1841
|
-
checkoutData,
|
|
1842
|
-
terms,
|
|
1843
|
-
paymentOption,
|
|
1844
|
-
confirmationKey
|
|
1845
|
-
);
|
|
1846
|
-
const confirmed = await this.client.purchaseIntents.confirm(
|
|
1847
|
-
minted.value.id,
|
|
1848
|
-
confirmation,
|
|
1849
|
-
options
|
|
1850
|
-
);
|
|
1851
|
-
if (!confirmed.ok) {
|
|
1852
|
-
if (!isAmbiguousCheckoutError(confirmed.error)) {
|
|
1853
|
-
clearIntentIdempotencyKey(confirmationScope);
|
|
1854
|
-
}
|
|
1855
|
-
return confirmed;
|
|
1856
|
-
}
|
|
1857
|
-
return ok({
|
|
1858
|
-
intentId: minted.value.id,
|
|
1859
|
-
intentScope,
|
|
1860
|
-
confirmationScope,
|
|
1861
|
-
confirmation,
|
|
1862
|
-
initialResponse: confirmed.value,
|
|
1863
|
-
terms
|
|
1864
|
-
});
|
|
1865
|
-
}
|
|
1866
|
-
/** @deprecated Use `client.purchaseIntents.mint()` then `confirm()`. */
|
|
1867
|
-
async process(data, options) {
|
|
1868
|
-
const started = await this.startIntentCheckout(data, options);
|
|
1869
|
-
if (!started.ok) return started;
|
|
1870
|
-
this.reconcileActionAuthority(started.value.initialResponse);
|
|
1871
|
-
const result = confirmationToCheckoutResult(started.value.initialResponse);
|
|
1872
|
-
if (started.value.initialResponse.status === chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.ORDER_CREATED || started.value.initialResponse.status === chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.PAYMENT_FAILED) {
|
|
1873
|
-
clearIntentIdempotencyKey(started.value.intentScope);
|
|
1874
|
-
clearIntentIdempotencyKey(started.value.confirmationScope);
|
|
1875
|
-
this.intentCommands.delete(started.value.intentScope);
|
|
1876
|
-
}
|
|
1877
|
-
return result;
|
|
1878
|
-
}
|
|
1879
|
-
async initializePayment(_orderId, _method) {
|
|
1880
|
-
return err(
|
|
1881
|
-
new chunkANT574FD_js.CimplifyError(
|
|
1882
|
-
chunkANT574FD_js.ErrorCode.NOT_IMPLEMENTED,
|
|
1883
|
-
"initializePayment is not available in REST mode.",
|
|
1884
|
-
false
|
|
1885
|
-
)
|
|
1886
|
-
);
|
|
1887
|
-
}
|
|
1888
|
-
/**
|
|
1889
|
-
* @deprecated Use `client.purchaseIntents.submitAction()`. This adapter works
|
|
1890
|
-
* only while this CheckoutService instance retains the opaque authority
|
|
1891
|
-
* returned by its own `process()` call; it never falls back to a payment-id
|
|
1892
|
-
* mutation.
|
|
1893
|
-
*/
|
|
1894
|
-
async submitAuthorization(input, options) {
|
|
1895
|
-
const paymentId = input.payment_id.trim();
|
|
1896
|
-
const authority = this.actionAuthorities.get(paymentId);
|
|
1897
|
-
if (!authority) {
|
|
1898
|
-
return err(
|
|
1899
|
-
new chunkANT574FD_js.CimplifyError(
|
|
1900
|
-
chunkANT574FD_js.ErrorCode.CHECKOUT_AUTHORITY_REQUIRED,
|
|
1901
|
-
"The purchase-intent action authority is unavailable. Restart checkout before submitting authorization.",
|
|
1902
|
-
false
|
|
1903
|
-
)
|
|
1904
|
-
);
|
|
1905
|
-
}
|
|
1906
|
-
const submitted = await this.client.purchaseIntents.submitAction(
|
|
1907
|
-
authority.intentId,
|
|
1908
|
-
authority.attemptId,
|
|
1909
|
-
{ authorization: input.authorization },
|
|
1910
|
-
{
|
|
1911
|
-
signal: options?.signal,
|
|
1912
|
-
timeoutMs: options?.timeoutMs
|
|
1913
|
-
}
|
|
1914
|
-
);
|
|
1915
|
-
if (!submitted.ok) return submitted;
|
|
1916
|
-
this.reconcileActionAuthority(submitted.value, paymentId);
|
|
1917
|
-
return confirmationToCheckoutResult(submitted.value);
|
|
1918
|
-
}
|
|
1919
|
-
reconcileActionAuthority(response, previousPaymentId) {
|
|
1920
|
-
if (previousPaymentId) this.actionAuthorities.delete(previousPaymentId);
|
|
1921
|
-
if ("payment_id" in response && typeof response.payment_id === "string" && response.payment_id.trim()) {
|
|
1922
|
-
this.actionAuthorities.delete(response.payment_id.trim());
|
|
1923
|
-
}
|
|
1924
|
-
const authority = checkoutActionAuthority(response);
|
|
1925
|
-
if (authority) this.actionAuthorities.set(authority.paymentId, authority);
|
|
1926
|
-
}
|
|
1927
|
-
async pollPaymentStatus(orderId, options) {
|
|
1928
|
-
const encodedId = encodeURIComponent(orderId);
|
|
1929
|
-
const tokenParam = this.orderTokenParam(orderId);
|
|
1930
|
-
return safe(
|
|
1931
|
-
this.client.get(
|
|
1932
|
-
`${CHECKOUT_API_ROUTE.paymentStatus(encodedId)}${tokenParam}`,
|
|
1933
|
-
options
|
|
1934
|
-
)
|
|
1935
|
-
);
|
|
1936
|
-
}
|
|
1937
|
-
async updateOrderCustomer(orderId, customer) {
|
|
1938
|
-
const encodedId = encodeURIComponent(orderId);
|
|
1939
|
-
const tokenParam = this.orderTokenParam(orderId);
|
|
1940
|
-
return safe(
|
|
1941
|
-
this.client.post(`${CHECKOUT_API_ROUTE.updateCustomer(encodedId)}${tokenParam}`, customer)
|
|
1942
|
-
);
|
|
1943
|
-
}
|
|
1944
|
-
async verifyPayment(orderId) {
|
|
1945
|
-
const encodedId = encodeURIComponent(orderId);
|
|
1946
|
-
const tokenParam = this.orderTokenParam(orderId);
|
|
1947
|
-
return safe(
|
|
1948
|
-
this.client.post(`${CHECKOUT_API_ROUTE.verifyPayment(encodedId)}${tokenParam}`)
|
|
1949
|
-
);
|
|
1950
|
-
}
|
|
1951
|
-
async maybeEnrollResolvedOrder(orderId, data) {
|
|
1952
|
-
if (data.enroll_in_link === false) return false;
|
|
1953
|
-
const business = await safe(this.client.resolveBusinessId());
|
|
1954
|
-
if (!business.ok) return false;
|
|
1955
|
-
const address = data.address_info.street_address ? {
|
|
1956
|
-
label: "Default",
|
|
1957
|
-
street_address: data.address_info.street_address,
|
|
1958
|
-
apartment: data.address_info.apartment,
|
|
1959
|
-
city: data.address_info.city ?? "",
|
|
1960
|
-
region: data.address_info.region ?? "",
|
|
1961
|
-
postal_code: data.address_info.postal_code,
|
|
1962
|
-
country: data.address_info.country,
|
|
1963
|
-
delivery_instructions: data.address_info.delivery_instructions,
|
|
1964
|
-
phone_for_delivery: data.address_info.phone_for_delivery,
|
|
1965
|
-
latitude: data.address_info.latitude,
|
|
1966
|
-
longitude: data.address_info.longitude
|
|
1967
|
-
} : void 0;
|
|
1968
|
-
const mobileMoney = data.payment_method === chunkEV2EVOYS_js.PAYMENT_METHOD.MOBILE_MONEY && data.mobile_money_details ? {
|
|
1969
|
-
phone_number: data.mobile_money_details.phone_number,
|
|
1970
|
-
provider: data.mobile_money_details.provider,
|
|
1971
|
-
label: "Mobile Money"
|
|
1972
|
-
} : void 0;
|
|
1973
|
-
try {
|
|
1974
|
-
const enrollment = await this.client.link.enrollAndLinkOrder({
|
|
1975
|
-
order_id: orderId,
|
|
1976
|
-
business_id: business.value,
|
|
1977
|
-
order_type: data.order_type,
|
|
1978
|
-
address,
|
|
1979
|
-
mobile_money: mobileMoney
|
|
1980
|
-
});
|
|
1981
|
-
return enrollment.ok && enrollment.value.success;
|
|
1982
|
-
} catch {
|
|
1983
|
-
return false;
|
|
1984
|
-
}
|
|
1985
|
-
}
|
|
1986
|
-
/** @deprecated Use `client.purchaseIntents.resolve()`. */
|
|
1987
|
-
async processAndResolve(data) {
|
|
1988
|
-
notifyCheckoutStatus(data.on_status_change, chunkEV2EVOYS_js.CHECKOUT_STATUS.PREPARING);
|
|
1989
|
-
if (!data.cart_id) {
|
|
1990
|
-
return ok(
|
|
1991
|
-
toTerminalFailure(
|
|
1992
|
-
chunkANT574FD_js.ErrorCode.INVALID_CART,
|
|
1993
|
-
"A valid cart is required before checkout can start.",
|
|
1994
|
-
false
|
|
1995
|
-
)
|
|
1996
|
-
);
|
|
1997
|
-
}
|
|
1998
|
-
const cartResult = await this.client.cart.get();
|
|
1999
|
-
if (!cartResult.ok || !cartResult.value?.id) {
|
|
2000
|
-
return ok(
|
|
2001
|
-
toTerminalFailure(
|
|
2002
|
-
chunkANT574FD_js.ErrorCode.INVALID_CART,
|
|
2003
|
-
"Unable to load cart for checkout.",
|
|
2004
|
-
false
|
|
2005
|
-
)
|
|
2006
|
-
);
|
|
2007
|
-
}
|
|
2008
|
-
const cart = cartResult.value;
|
|
2009
|
-
if (cart.id !== data.cart_id || cart.items.length === 0) {
|
|
2010
|
-
return ok(
|
|
2011
|
-
toTerminalFailure(
|
|
2012
|
-
chunkANT574FD_js.ErrorCode.INVALID_CART,
|
|
2013
|
-
"Cart is empty or no longer valid. Please refresh and try again.",
|
|
2014
|
-
false
|
|
2015
|
-
)
|
|
2016
|
-
);
|
|
2017
|
-
}
|
|
2018
|
-
const checkoutData = {
|
|
2019
|
-
cart_id: data.cart_id,
|
|
2020
|
-
location_id: data.location_id,
|
|
2021
|
-
customer: data.customer,
|
|
2022
|
-
order_type: data.order_type,
|
|
2023
|
-
address_info: data.address_info,
|
|
2024
|
-
delivery_rate_id: data.delivery_rate_id,
|
|
2025
|
-
payment_method: data.payment_method,
|
|
2026
|
-
mobile_money_details: data.mobile_money_details,
|
|
2027
|
-
special_instructions: data.special_instructions,
|
|
2028
|
-
link_address_id: data.link_address_id,
|
|
2029
|
-
link_payment_method_id: data.link_payment_method_id,
|
|
2030
|
-
idempotency_key: data.idempotency_key,
|
|
2031
|
-
metadata: data.metadata,
|
|
2032
|
-
pay_currency: data.pay_currency,
|
|
2033
|
-
fx_quote_id: data.fx_quote_id,
|
|
2034
|
-
use_store_credit: data.use_store_credit,
|
|
2035
|
-
voucher_code: data.voucher_code,
|
|
2036
|
-
pay_deposit: data.pay_deposit
|
|
2037
|
-
};
|
|
2038
|
-
const rawBaseCurrency = typeof cart.pricing.currency === "string" ? cart.pricing.currency.trim().toUpperCase() : "";
|
|
2039
|
-
if (!chunkANT574FD_js.isSupportedCurrency(rawBaseCurrency)) {
|
|
2040
|
-
return ok(
|
|
2041
|
-
toTerminalFailure(
|
|
2042
|
-
chunkANT574FD_js.ErrorCode.UNSUPPORTED_CURRENCY,
|
|
2043
|
-
"Cart currency is missing or unsupported. Refresh the cart before checkout.",
|
|
2044
|
-
false
|
|
2045
|
-
)
|
|
2046
|
-
);
|
|
2047
|
-
}
|
|
2048
|
-
const baseCurrency = rawBaseCurrency;
|
|
2049
|
-
const payCurrency = data.pay_currency?.trim().toUpperCase();
|
|
2050
|
-
if (payCurrency && !chunkANT574FD_js.isSupportedCurrency(payCurrency)) {
|
|
2051
|
-
return ok(
|
|
2052
|
-
toTerminalFailure(
|
|
2053
|
-
chunkANT574FD_js.ErrorCode.UNSUPPORTED_CURRENCY,
|
|
2054
|
-
"Payment currency is unsupported for checkout.",
|
|
2055
|
-
false
|
|
2056
|
-
)
|
|
2057
|
-
);
|
|
2058
|
-
}
|
|
2059
|
-
const payCurrencyCode = payCurrency && chunkANT574FD_js.isSupportedCurrency(payCurrency) ? payCurrency : void 0;
|
|
2060
|
-
const cartTotalSign = decimalSign(cart.pricing.total_price);
|
|
2061
|
-
if (cartTotalSign === null || cartTotalSign < 0) {
|
|
2062
|
-
return ok(
|
|
2063
|
-
toTerminalFailure(
|
|
2064
|
-
chunkANT574FD_js.ErrorCode.CHECKOUT_VALIDATION_FAILED,
|
|
2065
|
-
"Cart total is not a valid non-negative decimal amount.",
|
|
2066
|
-
false
|
|
2067
|
-
)
|
|
2068
|
-
);
|
|
2069
|
-
}
|
|
2070
|
-
if (payCurrencyCode && payCurrencyCode !== baseCurrency && !checkoutData.fx_quote_id && cartTotalSign > 0) {
|
|
2071
|
-
const fxQuoteResult = await this.client.fx.lockQuote({
|
|
2072
|
-
from: baseCurrency,
|
|
2073
|
-
to: payCurrencyCode,
|
|
2074
|
-
amount: cart.pricing.total_price
|
|
2075
|
-
});
|
|
2076
|
-
if (!fxQuoteResult.ok) {
|
|
2077
|
-
return ok(
|
|
2078
|
-
toTerminalFailure(
|
|
2079
|
-
chunkANT574FD_js.ErrorCode.FX_QUOTE_FAILED,
|
|
2080
|
-
fxQuoteResult.error.message || "Unable to lock FX quote for checkout.",
|
|
2081
|
-
true
|
|
2082
|
-
)
|
|
2083
|
-
);
|
|
2084
|
-
}
|
|
2085
|
-
checkoutData.pay_currency = payCurrencyCode;
|
|
2086
|
-
checkoutData.fx_quote_id = fxQuoteResult.value.id;
|
|
2087
|
-
}
|
|
2088
|
-
notifyCheckoutStatus(data.on_status_change, chunkEV2EVOYS_js.CHECKOUT_STATUS.PROCESSING);
|
|
2089
|
-
const started = await this.startIntentCheckout(checkoutData, { signal: data.signal });
|
|
2090
|
-
if (!started.ok) {
|
|
2091
|
-
return ok(
|
|
2092
|
-
toTerminalFailure(
|
|
2093
|
-
started.error.code || chunkANT574FD_js.ErrorCode.CHECKOUT_FAILED,
|
|
2094
|
-
started.error.message || "Unable to process checkout.",
|
|
2095
|
-
started.error.retryable ?? true
|
|
2096
|
-
)
|
|
2097
|
-
);
|
|
2098
|
-
}
|
|
2099
|
-
let actionFailure;
|
|
2100
|
-
try {
|
|
2101
|
-
const resolved = await this.client.purchaseIntents.resolve(started.value.intentId, {
|
|
2102
|
-
confirmation: started.value.confirmation,
|
|
2103
|
-
initialResponse: started.value.initialResponse,
|
|
2104
|
-
pollIntervalMs: data.poll_interval_ms,
|
|
2105
|
-
maxPollAttempts: data.max_poll_attempts,
|
|
2106
|
-
signal: data.signal,
|
|
2107
|
-
onStatusChange: (status, response) => {
|
|
2108
|
-
const context = {};
|
|
2109
|
-
if (response && "order_id" in response) context.order_id = response.order_id;
|
|
2110
|
-
if (response?.status === chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.TERMS_CHANGED) {
|
|
2111
|
-
context.replacement_terms = response.replacement;
|
|
2112
|
-
context.terms_deltas = response.deltas;
|
|
2113
|
-
}
|
|
2114
|
-
if (response?.status === chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.SELECTION_UNAVAILABLE) {
|
|
2115
|
-
context.unavailable_lines = response.lines;
|
|
2116
|
-
}
|
|
2117
|
-
const checkoutStatus = CHECKOUT_STATUS_BY_PURCHASE_INTENT_RESOLVE_STATUS[status];
|
|
2118
|
-
notifyCheckoutStatus(data.on_status_change, checkoutStatus, context);
|
|
2119
|
-
},
|
|
2120
|
-
onActionRequired: async (action) => {
|
|
2121
|
-
switch (action.status) {
|
|
2122
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.CARD_POPUP_REQUIRED: {
|
|
2123
|
-
const allowPopups = data.allow_popups ?? typeof window !== "undefined";
|
|
2124
|
-
if (!allowPopups) {
|
|
2125
|
-
actionFailure = {
|
|
2126
|
-
code: chunkANT574FD_js.ErrorCode.PROVIDER_UNAVAILABLE,
|
|
2127
|
-
message: "Card authorization UI is unavailable in this environment.",
|
|
2128
|
-
recoverable: false
|
|
2129
|
-
};
|
|
2130
|
-
return chunkANT574FD_js.PURCHASE_INTENT_ACTION_DECISION.STOP;
|
|
2131
|
-
}
|
|
2132
|
-
let outcome;
|
|
2133
|
-
try {
|
|
2134
|
-
notifyAuthorizationUi(data.on_authorization_ui_change, true);
|
|
2135
|
-
outcome = await this.authorizeCardPopup(
|
|
2136
|
-
{
|
|
2137
|
-
type: chunkEV2EVOYS_js.CHECKOUT_NEXT_ACTION.CARD_POPUP,
|
|
2138
|
-
provider: action.provider,
|
|
2139
|
-
client_secret: action.client_secret,
|
|
2140
|
-
public_key: action.public_key,
|
|
2141
|
-
provider_account_id: action.provider_account_id ?? void 0
|
|
2142
|
-
},
|
|
2143
|
-
{
|
|
2144
|
-
email: checkoutData.customer.email,
|
|
2145
|
-
currency: started.value.terms.money.currency,
|
|
2146
|
-
returnUrl: data.return_url,
|
|
2147
|
-
signal: data.signal
|
|
2148
|
-
}
|
|
2149
|
-
);
|
|
2150
|
-
} finally {
|
|
2151
|
-
notifyAuthorizationUi(data.on_authorization_ui_change, false);
|
|
2152
|
-
}
|
|
2153
|
-
if (outcome.status === PAYMENT_AUTHORIZATION_OUTCOME_STATUS.SUBMITTED) {
|
|
2154
|
-
return chunkANT574FD_js.PURCHASE_INTENT_ACTION_DECISION.CONTINUE;
|
|
2155
|
-
}
|
|
2156
|
-
actionFailure = outcome.status === PAYMENT_AUTHORIZATION_OUTCOME_STATUS.CANCELLED ? {
|
|
2157
|
-
code: chunkANT574FD_js.ErrorCode.PAYMENT_CANCELLED,
|
|
2158
|
-
message: "Card payment was cancelled before submission.",
|
|
2159
|
-
recoverable: true
|
|
2160
|
-
} : {
|
|
2161
|
-
code: outcome.code,
|
|
2162
|
-
message: outcome.message,
|
|
2163
|
-
recoverable: outcome.recoverable
|
|
2164
|
-
};
|
|
2165
|
-
return chunkANT574FD_js.PURCHASE_INTENT_ACTION_DECISION.STOP;
|
|
2166
|
-
}
|
|
2167
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.REDIRECT_REQUIRED: {
|
|
2168
|
-
const authorizationUrl = chunkV32BCG7M_js.paymentAuthorizationUrl(action.authorization_url);
|
|
2169
|
-
if (!authorizationUrl) {
|
|
2170
|
-
actionFailure = {
|
|
2171
|
-
code: chunkANT574FD_js.ErrorCode.AUTHORIZATION_FAILED,
|
|
2172
|
-
message: "The provider returned an invalid authorization URL.",
|
|
2173
|
-
recoverable: false
|
|
2174
|
-
};
|
|
2175
|
-
return chunkANT574FD_js.PURCHASE_INTENT_ACTION_DECISION.STOP;
|
|
2176
|
-
}
|
|
2177
|
-
if (typeof window !== "undefined") {
|
|
2178
|
-
if (data.allow_popups === false) {
|
|
2179
|
-
window.location.assign(authorizationUrl);
|
|
2180
|
-
} else {
|
|
2181
|
-
const popup = window.open(
|
|
2182
|
-
"",
|
|
2183
|
-
AUTHORIZATION_POPUP_NAME,
|
|
2184
|
-
AUTHORIZATION_POPUP_FEATURES
|
|
2185
|
-
);
|
|
2186
|
-
if (!popup) {
|
|
2187
|
-
actionFailure = {
|
|
2188
|
-
code: chunkANT574FD_js.ErrorCode.POPUP_BLOCKED,
|
|
2189
|
-
message: "Authorization popup was blocked.",
|
|
2190
|
-
recoverable: true
|
|
2191
|
-
};
|
|
2192
|
-
return chunkANT574FD_js.PURCHASE_INTENT_ACTION_DECISION.STOP;
|
|
2193
|
-
}
|
|
2194
|
-
popup.opener = null;
|
|
2195
|
-
popup.location.replace(authorizationUrl);
|
|
2196
|
-
}
|
|
2197
|
-
}
|
|
2198
|
-
actionFailure = {
|
|
2199
|
-
code: chunkANT574FD_js.ErrorCode.REDIRECT_REQUIRED,
|
|
2200
|
-
message: "Complete authorization at the payment provider, then resume checkout.",
|
|
2201
|
-
recoverable: true
|
|
2202
|
-
};
|
|
2203
|
-
return chunkANT574FD_js.PURCHASE_INTENT_ACTION_DECISION.STOP;
|
|
2204
|
-
}
|
|
2205
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.AUTHORIZATION_REQUIRED: {
|
|
2206
|
-
const expected = authorizationKind(action.authorization_type);
|
|
2207
|
-
if (!expected || !data.on_authorization_required) {
|
|
2208
|
-
actionFailure = {
|
|
2209
|
-
code: chunkANT574FD_js.ErrorCode.AUTHORIZATION_REQUIRED,
|
|
2210
|
-
message: "Additional payment authorization is required.",
|
|
2211
|
-
recoverable: true
|
|
2212
|
-
};
|
|
2213
|
-
return chunkANT574FD_js.PURCHASE_INTENT_ACTION_DECISION.STOP;
|
|
2214
|
-
}
|
|
2215
|
-
let submission;
|
|
2216
|
-
await data.on_authorization_required(expected, async (candidate) => {
|
|
2217
|
-
if (submission) throw new Error("Authorization was already submitted.");
|
|
2218
|
-
submission = normalizeAuthorizationSubmission(expected, candidate);
|
|
2219
|
-
});
|
|
2220
|
-
if (!submission) {
|
|
2221
|
-
actionFailure = {
|
|
2222
|
-
code: chunkANT574FD_js.ErrorCode.AUTHORIZATION_REQUIRED,
|
|
2223
|
-
message: "Payment authorization was not submitted.",
|
|
2224
|
-
recoverable: true
|
|
2225
|
-
};
|
|
2226
|
-
return chunkANT574FD_js.PURCHASE_INTENT_ACTION_DECISION.STOP;
|
|
2227
|
-
}
|
|
2228
|
-
return {
|
|
2229
|
-
kind: chunkANT574FD_js.PURCHASE_INTENT_ACTION_DECISION.SUBMIT,
|
|
2230
|
-
request: { authorization: submission }
|
|
2231
|
-
};
|
|
2232
|
-
}
|
|
2233
|
-
}
|
|
2234
|
-
}
|
|
2235
|
-
});
|
|
2236
|
-
if (!resolved.ok) {
|
|
2237
|
-
return ok(
|
|
2238
|
-
toTerminalFailure(
|
|
2239
|
-
resolved.error.code || chunkANT574FD_js.ErrorCode.CHECKOUT_FAILED,
|
|
2240
|
-
resolved.error.message || "Unable to resolve checkout.",
|
|
2241
|
-
resolved.error.retryable ?? true
|
|
2242
|
-
)
|
|
2243
|
-
);
|
|
2244
|
-
}
|
|
2245
|
-
switch (resolved.value.kind) {
|
|
2246
|
-
case chunkANT574FD_js.PURCHASE_INTENT_RESOLUTION_KIND.COMPLETED: {
|
|
2247
|
-
clearIntentIdempotencyKey(started.value.intentScope);
|
|
2248
|
-
clearIntentIdempotencyKey(started.value.confirmationScope);
|
|
2249
|
-
const response = resolved.value.response;
|
|
2250
|
-
notifyCheckoutStatus(data.on_status_change, chunkEV2EVOYS_js.CHECKOUT_STATUS.FINALIZING, {
|
|
2251
|
-
order_id: response.order_id
|
|
2252
|
-
});
|
|
2253
|
-
const enrolledInLink = await this.maybeEnrollResolvedOrder(response.order_id, data);
|
|
2254
|
-
notifyCheckoutStatus(data.on_status_change, chunkEV2EVOYS_js.CHECKOUT_STATUS.SUCCESS, {
|
|
2255
|
-
order_id: response.order_id
|
|
2256
|
-
});
|
|
2257
|
-
return ok({
|
|
2258
|
-
success: true,
|
|
2259
|
-
order: {
|
|
2260
|
-
id: response.order_id,
|
|
2261
|
-
order_number: response.order_number ?? response.order_id,
|
|
2262
|
-
status: chunkEV2EVOYS_js.CHECKOUT_ORDER_RESULT_STATUS.CONFIRMED,
|
|
2263
|
-
total: String(cart.pricing.total_price),
|
|
2264
|
-
currency: started.value.terms.money.currency
|
|
2265
|
-
},
|
|
2266
|
-
enrolled_in_link: enrolledInLink
|
|
2267
|
-
});
|
|
2268
|
-
}
|
|
2269
|
-
case chunkANT574FD_js.PURCHASE_INTENT_RESOLUTION_KIND.FAILED:
|
|
2270
|
-
clearIntentIdempotencyKey(started.value.confirmationScope);
|
|
2271
|
-
return ok(
|
|
2272
|
-
toTerminalFailure(
|
|
2273
|
-
chunkANT574FD_js.PURCHASE_INTENT_ERROR_CODE.PAYMENT_FAILED,
|
|
2274
|
-
"Payment failed. Choose another method or retry collection.",
|
|
2275
|
-
true
|
|
2276
|
-
)
|
|
2277
|
-
);
|
|
2278
|
-
case chunkANT574FD_js.PURCHASE_INTENT_RESOLUTION_KIND.OUTCOME_UNKNOWN:
|
|
2279
|
-
return ok(
|
|
2280
|
-
toTerminalFailure(
|
|
2281
|
-
chunkANT574FD_js.ErrorCode.PAYMENT_OUTCOME_UNKNOWN,
|
|
2282
|
-
"Payment outcome is still unknown. Resume this intent before retrying.",
|
|
2283
|
-
true
|
|
2284
|
-
)
|
|
2285
|
-
);
|
|
2286
|
-
case chunkANT574FD_js.PURCHASE_INTENT_RESOLUTION_KIND.TIMED_OUT:
|
|
2287
|
-
return ok(
|
|
2288
|
-
toTerminalFailure(
|
|
2289
|
-
chunkANT574FD_js.ErrorCode.TIMEOUT,
|
|
2290
|
-
"Payment is still processing. Resume this intent to continue polling.",
|
|
2291
|
-
true
|
|
2292
|
-
)
|
|
2293
|
-
);
|
|
2294
|
-
case chunkANT574FD_js.PURCHASE_INTENT_RESOLUTION_KIND.ACTION_REQUIRED:
|
|
2295
|
-
return ok(
|
|
2296
|
-
toTerminalFailure(
|
|
2297
|
-
actionFailure?.code ?? chunkANT574FD_js.ErrorCode.AUTHORIZATION_REQUIRED,
|
|
2298
|
-
actionFailure?.message ?? "Checkout requires additional authorization.",
|
|
2299
|
-
actionFailure?.recoverable ?? true
|
|
2300
|
-
)
|
|
2301
|
-
);
|
|
2302
|
-
case chunkANT574FD_js.PURCHASE_INTENT_RESOLUTION_KIND.REVIEW_REQUIRED: {
|
|
2303
|
-
const response = resolved.value.response;
|
|
2304
|
-
switch (response.status) {
|
|
2305
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.TERMS_CHANGED:
|
|
2306
|
-
return ok(
|
|
2307
|
-
toTerminalFailure(
|
|
2308
|
-
chunkANT574FD_js.PURCHASE_INTENT_ERROR_CODE.TERMS_CHANGED,
|
|
2309
|
-
"Checkout terms changed and require explicit review.",
|
|
2310
|
-
true
|
|
2311
|
-
)
|
|
2312
|
-
);
|
|
2313
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.SELECTION_UNAVAILABLE:
|
|
2314
|
-
return ok(
|
|
2315
|
-
toTerminalFailure(
|
|
2316
|
-
chunkANT574FD_js.PURCHASE_INTENT_ERROR_CODE.SELECTION_UNAVAILABLE,
|
|
2317
|
-
"One or more checkout selections are unavailable.",
|
|
2318
|
-
true
|
|
2319
|
-
)
|
|
2320
|
-
);
|
|
2321
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.OFFER_ENDED:
|
|
2322
|
-
return ok(
|
|
2323
|
-
toTerminalFailure(
|
|
2324
|
-
chunkANT574FD_js.PURCHASE_INTENT_ERROR_CODE.OFFER_ENDED,
|
|
2325
|
-
"This offer has ended.",
|
|
2326
|
-
false
|
|
2327
|
-
)
|
|
2328
|
-
);
|
|
2329
|
-
case chunkANT574FD_js.PURCHASE_INTENT_CONFIRM_STATUS.SOURCE_UNAVAILABLE:
|
|
2330
|
-
return ok(
|
|
2331
|
-
toTerminalFailure(
|
|
2332
|
-
chunkANT574FD_js.PURCHASE_INTENT_ERROR_CODE.SOURCE_UNAVAILABLE,
|
|
2333
|
-
"This purchase source is unavailable.",
|
|
2334
|
-
false
|
|
2335
|
-
)
|
|
2336
|
-
);
|
|
2337
|
-
}
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2340
|
-
} catch (error) {
|
|
2341
|
-
const cancelled = data.signal?.aborted || error instanceof Error && error.name === ABORT_ERROR_NAME;
|
|
2342
|
-
return ok(
|
|
2343
|
-
toTerminalFailure(
|
|
2344
|
-
cancelled ? chunkANT574FD_js.ErrorCode.CANCELLED : chunkANT574FD_js.ErrorCode.AUTHORIZATION_FAILED,
|
|
2345
|
-
cancelled ? "Checkout was cancelled." : error instanceof Error ? error.message : "Checkout authorization failed.",
|
|
2346
|
-
true
|
|
2347
|
-
)
|
|
2348
|
-
);
|
|
2349
|
-
}
|
|
2350
|
-
}
|
|
2351
|
-
};
|
|
2352
|
-
|
|
2353
|
-
// src/orders.ts
|
|
2354
|
-
var OrderQueries = class {
|
|
2355
|
-
constructor(client) {
|
|
2356
|
-
this.client = client;
|
|
2357
|
-
}
|
|
2358
|
-
orderTokenParam(orderId) {
|
|
2359
|
-
const token = this.client.getOrderToken(orderId);
|
|
2360
|
-
return token ? `?token=${encodeURIComponent(token)}` : "";
|
|
2361
|
-
}
|
|
2362
|
-
async list(options) {
|
|
2363
|
-
const params = new URLSearchParams();
|
|
2364
|
-
if (options?.status) params.set("status", options.status);
|
|
2365
|
-
if (options?.limit) params.set("limit", String(options.limit));
|
|
2366
|
-
if (options?.offset) params.set("offset", String(options.offset));
|
|
2367
|
-
const path = params.toString() ? `/api/v1/orders?${params.toString()}` : "/api/v1/orders";
|
|
2368
|
-
return safe(this.client.get(path));
|
|
2369
|
-
}
|
|
2370
|
-
async get(orderId) {
|
|
2371
|
-
const encodedId = encodeURIComponent(orderId);
|
|
2372
|
-
const tokenParam = this.orderTokenParam(orderId);
|
|
2373
|
-
return safe(this.client.get(`/api/v1/orders/${encodedId}${tokenParam}`));
|
|
2374
|
-
}
|
|
2375
|
-
/**
|
|
2376
|
-
* Same endpoint as `get`, typed as the enriched display contract
|
|
2377
|
-
* (product names, images, resolved selections, customer inputs, scheduling,
|
|
2378
|
-
* fulfillment). Feed the result through `toAccountOrderView`.
|
|
2379
|
-
*/
|
|
2380
|
-
async getDetail(orderId) {
|
|
2381
|
-
const encodedId = encodeURIComponent(orderId);
|
|
2382
|
-
const tokenParam = this.orderTokenParam(orderId);
|
|
2383
|
-
return safe(this.client.get(`/api/v1/orders/${encodedId}${tokenParam}`));
|
|
2384
|
-
}
|
|
2385
|
-
async getRecent(limit = 5) {
|
|
2386
|
-
return this.list({ limit });
|
|
2387
|
-
}
|
|
2388
|
-
async getByStatus(status) {
|
|
2389
|
-
return this.list({ status });
|
|
2390
|
-
}
|
|
2391
|
-
async cancel(orderId, reason, opts) {
|
|
2392
|
-
const encodedId = encodeURIComponent(orderId);
|
|
2393
|
-
const tokenParam = this.orderTokenParam(orderId);
|
|
2394
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2395
|
-
return safe(
|
|
2396
|
-
this.client.post(
|
|
2397
|
-
`/api/v1/orders/${encodedId}/cancel${tokenParam}`,
|
|
2398
|
-
{ reason },
|
|
2399
|
-
{ idempotencyKey }
|
|
2400
|
-
)
|
|
2401
|
-
);
|
|
2402
|
-
}
|
|
2403
|
-
};
|
|
2404
|
-
|
|
2405
|
-
// src/link.ts
|
|
2406
|
-
function encodePathSegment(value) {
|
|
2407
|
-
return encodeURIComponent(value);
|
|
2408
|
-
}
|
|
2409
|
-
var LinkService = class {
|
|
2410
|
-
constructor(client) {
|
|
2411
|
-
this.client = client;
|
|
2412
|
-
this.activationGeneration = 0;
|
|
2413
|
-
}
|
|
2414
|
-
beginActivation() {
|
|
2415
|
-
return {
|
|
2416
|
-
generation: ++this.activationGeneration,
|
|
2417
|
-
sessionEpoch: this.client.getSessionEpoch(),
|
|
2418
|
-
publicKeyEpoch: this.client.getPublicKeyEpoch()
|
|
2419
|
-
};
|
|
2420
|
-
}
|
|
2421
|
-
isActivationFenceCurrent(fence) {
|
|
2422
|
-
return fence.generation === this.activationGeneration && fence.sessionEpoch === this.client.getSessionEpoch() && fence.publicKeyEpoch === this.client.getPublicKeyEpoch();
|
|
2423
|
-
}
|
|
2424
|
-
supersededActivation() {
|
|
2425
|
-
return {
|
|
2426
|
-
ok: false,
|
|
2427
|
-
error: new chunkANT574FD_js.CimplifyError(
|
|
2428
|
-
"session_superseded",
|
|
2429
|
-
"A newer authentication session replaced this one"
|
|
2430
|
-
)
|
|
2431
|
-
};
|
|
2432
|
-
}
|
|
2433
|
-
async activateAuthenticatedSession(result, fence) {
|
|
2434
|
-
if (!result.ok || !result.value.session_token) return result;
|
|
2435
|
-
if (!this.isActivationFenceCurrent(fence)) return this.supersededActivation();
|
|
2436
|
-
const accessToken = result.value.session_token;
|
|
2437
|
-
this.client.setAccessToken(accessToken);
|
|
2438
|
-
const installedSessionEpoch = this.client.getSessionEpoch();
|
|
2439
|
-
if (!this.client.getPublicKey().trim()) {
|
|
2440
|
-
this.client.activity.refreshIdentity();
|
|
2441
|
-
return result;
|
|
2442
|
-
}
|
|
2443
|
-
const claim = await this.client.session.claim();
|
|
2444
|
-
if (fence.generation !== this.activationGeneration || fence.publicKeyEpoch !== this.client.getPublicKeyEpoch() || this.client.getAccessToken() !== accessToken) {
|
|
2445
|
-
return this.supersededActivation();
|
|
2446
|
-
}
|
|
2447
|
-
if (!claim.ok && claim.error.code !== "already_claimed") {
|
|
2448
|
-
if (this.client.getSessionEpoch() !== installedSessionEpoch) {
|
|
2449
|
-
return this.supersededActivation();
|
|
2450
|
-
}
|
|
2451
|
-
if (this.client.hasClaimedSessionAuthority()) {
|
|
2452
|
-
this.client.clearSession();
|
|
2453
|
-
} else {
|
|
2454
|
-
this.client.setAccessToken(null);
|
|
2455
|
-
}
|
|
2456
|
-
return claim;
|
|
2457
|
-
}
|
|
2458
|
-
this.client.activity.refreshIdentity();
|
|
2459
|
-
return result;
|
|
2460
|
-
}
|
|
2461
|
-
async requestOtp(input, opts) {
|
|
2462
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2463
|
-
return safe(
|
|
2464
|
-
this.client.linkPost("/v1/link/auth/request-otp", input, {
|
|
2465
|
-
idempotencyKey
|
|
2466
|
-
})
|
|
2467
|
-
);
|
|
2468
|
-
}
|
|
2469
|
-
async verifyOtp(input, opts) {
|
|
2470
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2471
|
-
const activationFence = opts?.activateSession === false ? null : this.beginActivation();
|
|
2472
|
-
const { business_id: _ignoredBusinessId, ...body } = input;
|
|
2473
|
-
const result = await safe(
|
|
2474
|
-
this.client.linkPost("/v1/link/auth/verify-otp", body, { idempotencyKey })
|
|
2475
|
-
);
|
|
2476
|
-
return activationFence ? this.activateAuthenticatedSession(result, activationFence) : result;
|
|
2477
|
-
}
|
|
2478
|
-
async refreshSession(sessionToken, opts) {
|
|
2479
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2480
|
-
const activationFence = opts?.activateSession === false ? null : this.beginActivation();
|
|
2481
|
-
const body = sessionToken ? { session_token: sessionToken } : {};
|
|
2482
|
-
const result = await safe(
|
|
2483
|
-
this.client.linkPost("/v1/link/auth/refresh", body, { idempotencyKey })
|
|
2484
|
-
);
|
|
2485
|
-
return activationFence ? this.activateAuthenticatedSession(result, activationFence) : result;
|
|
2486
|
-
}
|
|
2487
|
-
async logout() {
|
|
2488
|
-
this.activationGeneration += 1;
|
|
2489
|
-
const request = safe(this.client.linkPost("/v1/link/auth/logout"));
|
|
2490
|
-
this.client.clearSession();
|
|
2491
|
-
return request;
|
|
2492
|
-
}
|
|
2493
|
-
async checkStatus(contact) {
|
|
2494
|
-
return safe(this.client.linkPost("/v1/link/check-status", { contact }));
|
|
2495
|
-
}
|
|
2496
|
-
async getLinkData() {
|
|
2497
|
-
return safe(this.client.linkGet("/v1/link/data"));
|
|
2498
|
-
}
|
|
2499
|
-
async getAddresses() {
|
|
2500
|
-
return safe(this.client.linkGet("/v1/link/addresses"));
|
|
2501
|
-
}
|
|
2502
|
-
async getMobileMoney() {
|
|
2503
|
-
return safe(this.client.linkGet("/v1/link/mobile-money"));
|
|
2504
|
-
}
|
|
2505
|
-
async getPreferences() {
|
|
2506
|
-
return safe(this.client.linkGet("/v1/link/preferences"));
|
|
2507
|
-
}
|
|
2508
|
-
async updateProfile(input) {
|
|
2509
|
-
return safe(this.client.linkPost("/v1/link/profile", input));
|
|
2510
|
-
}
|
|
2511
|
-
async getOrders(options) {
|
|
2512
|
-
const params = new URLSearchParams();
|
|
2513
|
-
if (options?.status) params.set("status", options.status);
|
|
2514
|
-
if (options?.limit) params.set("limit", String(options.limit));
|
|
2515
|
-
if (options?.offset) params.set("offset", String(options.offset));
|
|
2516
|
-
if (options?.businessId) params.set("business_id", options.businessId);
|
|
2517
|
-
const query = params.toString();
|
|
2518
|
-
const path = query ? `/v1/link/orders?${query}` : "/v1/link/orders";
|
|
2519
|
-
return safe(this.client.linkGet(path));
|
|
2520
|
-
}
|
|
2521
|
-
async getOrder(orderId, options) {
|
|
2522
|
-
const params = new URLSearchParams();
|
|
2523
|
-
if (options?.businessId) params.set("business_id", options.businessId);
|
|
2524
|
-
const query = params.toString();
|
|
2525
|
-
const path = query ? `/v1/link/orders/${encodePathSegment(orderId)}?${query}` : `/v1/link/orders/${encodePathSegment(orderId)}`;
|
|
2526
|
-
return safe(this.client.linkGet(path));
|
|
2527
|
-
}
|
|
2528
|
-
async enroll(data, opts) {
|
|
2529
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2530
|
-
return safe(
|
|
2531
|
-
this.client.linkPost("/v1/link/enroll", data, { idempotencyKey })
|
|
2532
|
-
);
|
|
2533
|
-
}
|
|
2534
|
-
async enrollAndLinkOrder(data, opts) {
|
|
2535
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2536
|
-
return safe(
|
|
2537
|
-
this.client.linkPost("/v1/link/enroll-and-link-order", data, {
|
|
2538
|
-
idempotencyKey
|
|
2539
|
-
})
|
|
2540
|
-
);
|
|
2541
|
-
}
|
|
2542
|
-
async updatePreferences(preferences) {
|
|
2543
|
-
return safe(this.client.linkPost("/v1/link/preferences", preferences));
|
|
2544
|
-
}
|
|
2545
|
-
async createAddress(input, opts) {
|
|
2546
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2547
|
-
return safe(
|
|
2548
|
-
this.client.linkPost("/v1/link/addresses", input, { idempotencyKey })
|
|
2549
|
-
);
|
|
2550
|
-
}
|
|
2551
|
-
async updateAddress(input) {
|
|
2552
|
-
const { address_id, ...patch } = input;
|
|
2553
|
-
return safe(
|
|
2554
|
-
this.client.linkPost(
|
|
2555
|
-
`/v1/link/addresses/${encodePathSegment(address_id)}`,
|
|
2556
|
-
patch
|
|
2557
|
-
)
|
|
2558
|
-
);
|
|
2559
|
-
}
|
|
2560
|
-
async deleteAddress(addressId) {
|
|
2561
|
-
return safe(
|
|
2562
|
-
this.client.linkDelete(`/v1/link/addresses/${encodePathSegment(addressId)}`)
|
|
2563
|
-
);
|
|
2564
|
-
}
|
|
2565
|
-
async setDefaultAddress(addressId) {
|
|
2566
|
-
return safe(
|
|
2567
|
-
this.client.linkPost(
|
|
2568
|
-
`/v1/link/addresses/${encodePathSegment(addressId)}/default`
|
|
2569
|
-
)
|
|
2570
|
-
);
|
|
2571
|
-
}
|
|
2572
|
-
async trackAddressUsage(addressId) {
|
|
2573
|
-
return safe(
|
|
2574
|
-
this.client.linkPost(
|
|
2575
|
-
`/v1/link/addresses/${encodePathSegment(addressId)}/track-usage`
|
|
2576
|
-
)
|
|
2577
|
-
);
|
|
2578
|
-
}
|
|
2579
|
-
async createMobileMoney(input, opts) {
|
|
2580
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2581
|
-
return safe(
|
|
2582
|
-
this.client.linkPost("/v1/link/mobile-money", input, { idempotencyKey })
|
|
2583
|
-
);
|
|
2584
|
-
}
|
|
2585
|
-
async deleteMobileMoney(mobileMoneyId) {
|
|
2586
|
-
return safe(
|
|
2587
|
-
this.client.linkDelete(
|
|
2588
|
-
`/v1/link/mobile-money/${encodePathSegment(mobileMoneyId)}`
|
|
2589
|
-
)
|
|
2590
|
-
);
|
|
2591
|
-
}
|
|
2592
|
-
async setDefaultMobileMoney(mobileMoneyId) {
|
|
2593
|
-
return safe(
|
|
2594
|
-
this.client.linkPost(
|
|
2595
|
-
`/v1/link/mobile-money/${encodePathSegment(mobileMoneyId)}/default`
|
|
2596
|
-
)
|
|
2597
|
-
);
|
|
2598
|
-
}
|
|
2599
|
-
async trackMobileMoneyUsage(mobileMoneyId) {
|
|
2600
|
-
return safe(
|
|
2601
|
-
this.client.linkPost(
|
|
2602
|
-
`/v1/link/mobile-money/${encodePathSegment(mobileMoneyId)}/track-usage`
|
|
2603
|
-
)
|
|
2604
|
-
);
|
|
2605
|
-
}
|
|
2606
|
-
async verifyMobileMoney(mobileMoneyId, opts) {
|
|
2607
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2608
|
-
return safe(
|
|
2609
|
-
this.client.linkPost(
|
|
2610
|
-
`/v1/link/mobile-money/${encodePathSegment(mobileMoneyId)}/verify`,
|
|
2611
|
-
void 0,
|
|
2612
|
-
{ idempotencyKey }
|
|
2613
|
-
)
|
|
2614
|
-
);
|
|
2615
|
-
}
|
|
2616
|
-
async getSessions() {
|
|
2617
|
-
return safe(this.client.linkGet("/v1/link/sessions"));
|
|
2618
|
-
}
|
|
2619
|
-
async revokeSession(sessionId) {
|
|
2620
|
-
return safe(this.client.linkDelete(`/v1/link/sessions/${sessionId}`));
|
|
2621
|
-
}
|
|
2622
|
-
async revokeAllSessions() {
|
|
2623
|
-
return safe(this.client.linkDelete("/v1/link/sessions"));
|
|
2624
|
-
}
|
|
2625
|
-
};
|
|
2626
|
-
|
|
2627
|
-
// src/auth.ts
|
|
2628
|
-
var AuthService = class {
|
|
2629
|
-
constructor(client) {
|
|
2630
|
-
this.client = client;
|
|
2631
|
-
}
|
|
2632
|
-
async getStatus() {
|
|
2633
|
-
return safe(this.client.get("/api/v1/auth/status"));
|
|
2634
|
-
}
|
|
2635
|
-
async getCurrentUser() {
|
|
2636
|
-
const result = await this.getStatus();
|
|
2637
|
-
if (!result.ok) return result;
|
|
2638
|
-
return ok(result.value.customer || null);
|
|
2639
|
-
}
|
|
2640
|
-
async isAuthenticated() {
|
|
2641
|
-
const result = await this.getStatus();
|
|
2642
|
-
if (!result.ok) return result;
|
|
2643
|
-
return ok(result.value.is_authenticated);
|
|
2644
|
-
}
|
|
2645
|
-
async requestOtp(contact, contactType, opts) {
|
|
2646
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2647
|
-
return safe(
|
|
2648
|
-
this.client.post(
|
|
2649
|
-
"/api/v1/auth/request-otp",
|
|
2650
|
-
{ contact, contact_type: contactType },
|
|
2651
|
-
{ idempotencyKey }
|
|
2652
|
-
)
|
|
2653
|
-
);
|
|
2654
|
-
}
|
|
2655
|
-
async verifyOtp(code, contact, opts) {
|
|
2656
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2657
|
-
const result = await safe(
|
|
2658
|
-
this.client.post(
|
|
2659
|
-
"/api/v1/auth/verify-otp",
|
|
2660
|
-
{ otp_code: code, contact },
|
|
2661
|
-
{ idempotencyKey }
|
|
2662
|
-
)
|
|
2663
|
-
);
|
|
2664
|
-
if (result.ok && result.value.session_token) {
|
|
2665
|
-
this.client.setAccessToken(result.value.session_token);
|
|
2666
|
-
this.client.activity.refreshIdentity();
|
|
2667
|
-
this.client.autoClaimSession();
|
|
2668
|
-
}
|
|
2669
|
-
return result;
|
|
2670
|
-
}
|
|
2671
|
-
async logout() {
|
|
2672
|
-
const result = await safe(this.client.post("/api/v1/auth/logout"));
|
|
2673
|
-
this.client.clearSession();
|
|
2674
|
-
return result;
|
|
2675
|
-
}
|
|
2676
|
-
async updateProfile(input) {
|
|
2677
|
-
return safe(this.client.post("/api/v1/auth/profile", input));
|
|
2678
|
-
}
|
|
2679
|
-
};
|
|
2680
|
-
|
|
2681
|
-
// src/business.ts
|
|
2682
|
-
var BusinessService = class {
|
|
2683
|
-
constructor(client) {
|
|
2684
|
-
this.client = client;
|
|
2685
|
-
}
|
|
2686
|
-
async getInfo(opts) {
|
|
2687
|
-
return safe(this.client.get("/api/v1/business", opts));
|
|
2688
|
-
}
|
|
2689
|
-
async getByHandle(handle, opts) {
|
|
2690
|
-
const encodedHandle = encodeURIComponent(handle);
|
|
2691
|
-
return safe(this.client.get(`/api/v1/business/by-handle/${encodedHandle}`, opts));
|
|
2692
|
-
}
|
|
2693
|
-
async getByDomain(domain, opts) {
|
|
2694
|
-
const encodedDomain = encodeURIComponent(domain);
|
|
2695
|
-
return safe(this.client.get(`/api/v1/business/by-domain?domain=${encodedDomain}`, opts));
|
|
2696
|
-
}
|
|
2697
|
-
async getSettings(opts) {
|
|
2698
|
-
return safe(this.client.get("/api/v1/business/settings", opts));
|
|
2699
|
-
}
|
|
2700
|
-
async getLocations(opts) {
|
|
2701
|
-
return safe(this.client.get("/api/v1/business/locations", opts));
|
|
2702
|
-
}
|
|
2703
|
-
async getLocation(locationId, opts) {
|
|
2704
|
-
const result = await this.getLocations(opts);
|
|
2705
|
-
if (!result.ok) return err(result.error);
|
|
2706
|
-
const location = result.value.find((item) => item.id === locationId);
|
|
2707
|
-
if (!location) {
|
|
2708
|
-
return err(new chunkANT574FD_js.CimplifyError(chunkANT574FD_js.ErrorCode.NOT_FOUND, `Location not found: ${locationId}`, false));
|
|
2709
|
-
}
|
|
2710
|
-
return ok(location);
|
|
2711
|
-
}
|
|
2712
|
-
async getHours(opts) {
|
|
2713
|
-
return safe(this.client.get("/api/v1/business/hours", opts));
|
|
2714
|
-
}
|
|
2715
|
-
async getLocationHours(locationId, opts) {
|
|
2716
|
-
const result = await this.getHours(opts);
|
|
2717
|
-
if (!result.ok) return result;
|
|
2718
|
-
return ok(result.value.filter((hour) => hour.location_id === locationId));
|
|
2719
|
-
}
|
|
2720
|
-
async getBootstrap(opts) {
|
|
2721
|
-
return safe(this.client.get("/api/v1/bootstrap", opts));
|
|
2722
|
-
}
|
|
2723
|
-
};
|
|
2724
|
-
|
|
2725
|
-
// src/inventory.ts
|
|
2726
|
-
var InventoryService = class {
|
|
2727
|
-
constructor(client) {
|
|
2728
|
-
this.client = client;
|
|
2729
|
-
}
|
|
2730
|
-
withQuery(path, params) {
|
|
2731
|
-
const searchParams = new URLSearchParams();
|
|
2732
|
-
for (const [key, value] of Object.entries(params)) {
|
|
2733
|
-
if (value === void 0) continue;
|
|
2734
|
-
searchParams.set(key, String(value));
|
|
2735
|
-
}
|
|
2736
|
-
const query = searchParams.toString();
|
|
2737
|
-
return query ? `${path}?${query}` : path;
|
|
2738
|
-
}
|
|
2739
|
-
async getProductStock(productId, locationId) {
|
|
2740
|
-
const encodedId = encodeURIComponent(productId);
|
|
2741
|
-
const path = this.withQuery(`/api/v1/inventory/products/${encodedId}/stock`, {
|
|
2742
|
-
location_id: locationId
|
|
2743
|
-
});
|
|
2744
|
-
return safe(this.client.get(path));
|
|
2745
|
-
}
|
|
2746
|
-
async getVariantStock(variantId, locationId) {
|
|
2747
|
-
const encodedId = encodeURIComponent(variantId);
|
|
2748
|
-
const path = this.withQuery(`/api/v1/inventory/variants/${encodedId}/stock`, {
|
|
2749
|
-
location_id: locationId
|
|
2750
|
-
});
|
|
2751
|
-
return safe(this.client.get(path));
|
|
2752
|
-
}
|
|
2753
|
-
async checkProductAvailability(productId, quantity, locationId) {
|
|
2754
|
-
const encodedId = encodeURIComponent(productId);
|
|
2755
|
-
const path = this.withQuery(`/api/v1/inventory/products/${encodedId}/availability`, {
|
|
2756
|
-
quantity,
|
|
2757
|
-
location_id: locationId
|
|
2758
|
-
});
|
|
2759
|
-
return safe(this.client.get(path));
|
|
2760
|
-
}
|
|
2761
|
-
async checkVariantAvailability(variantId, quantity, locationId) {
|
|
2762
|
-
const encodedId = encodeURIComponent(variantId);
|
|
2763
|
-
const path = this.withQuery(`/api/v1/inventory/variants/${encodedId}/availability`, {
|
|
2764
|
-
quantity,
|
|
2765
|
-
location_id: locationId
|
|
2766
|
-
});
|
|
2767
|
-
return safe(this.client.get(path));
|
|
2768
|
-
}
|
|
2769
|
-
async checkMultipleAvailability(items, locationId) {
|
|
2770
|
-
const results = await Promise.all(
|
|
2771
|
-
items.map(
|
|
2772
|
-
(item) => item.variant_id ? this.checkVariantAvailability(item.variant_id, item.quantity, locationId) : this.checkProductAvailability(item.product_id, item.quantity, locationId)
|
|
2773
|
-
)
|
|
2774
|
-
);
|
|
2775
|
-
for (const result of results) {
|
|
2776
|
-
if (!result.ok) return result;
|
|
2777
|
-
}
|
|
2778
|
-
return ok(results.map((r) => r.value));
|
|
2779
|
-
}
|
|
2780
|
-
async isInStock(productId, locationId) {
|
|
2781
|
-
const result = await this.checkProductAvailability(productId, 1, locationId);
|
|
2782
|
-
if (!result.ok) return result;
|
|
2783
|
-
return ok(result.value.is_available);
|
|
2784
|
-
}
|
|
2785
|
-
async getAvailableQuantity(productId, locationId) {
|
|
2786
|
-
const result = await this.getProductStock(productId, locationId);
|
|
2787
|
-
if (!result.ok) return result;
|
|
2788
|
-
return ok(result.value.available_quantity ?? void 0);
|
|
2789
|
-
}
|
|
2790
|
-
};
|
|
2791
|
-
|
|
2792
|
-
// src/scheduling.ts
|
|
2793
|
-
function withQuery2(path, params) {
|
|
2794
|
-
const searchParams = new URLSearchParams();
|
|
2795
|
-
for (const [key, value] of Object.entries(params)) {
|
|
2796
|
-
if (value === void 0) continue;
|
|
2797
|
-
searchParams.set(key, String(value));
|
|
2798
|
-
}
|
|
2799
|
-
const query = searchParams.toString();
|
|
2800
|
-
return query ? `${path}?${query}` : path;
|
|
2801
|
-
}
|
|
2802
|
-
function firstScheduledTime(booking) {
|
|
2803
|
-
return booking.service_items.find((item) => typeof item.scheduled_start === "string")?.scheduled_start || booking.created_at;
|
|
2804
|
-
}
|
|
2805
|
-
var SchedulingService = class {
|
|
2806
|
-
constructor(client) {
|
|
2807
|
-
this.client = client;
|
|
2808
|
-
}
|
|
2809
|
-
async getServices() {
|
|
2810
|
-
return safe(this.client.get("/api/v1/scheduling/services"));
|
|
2811
|
-
}
|
|
2812
|
-
async getService(serviceId) {
|
|
2813
|
-
const encodedId = encodeURIComponent(serviceId);
|
|
2814
|
-
return safe(this.client.get(`/api/v1/scheduling/services/${encodedId}`));
|
|
2815
|
-
}
|
|
2816
|
-
async getAvailableSlots(input) {
|
|
2817
|
-
const path = withQuery2("/api/v1/scheduling/slots", {
|
|
2818
|
-
service_id: input.service_id,
|
|
2819
|
-
date: input.date,
|
|
2820
|
-
participant_count: input.participant_count,
|
|
2821
|
-
units: input.units,
|
|
2822
|
-
variant_id: input.variant_id
|
|
2823
|
-
});
|
|
2824
|
-
return safe(this.client.get(path));
|
|
2825
|
-
}
|
|
2826
|
-
async checkSlotAvailability(input) {
|
|
2827
|
-
const path = withQuery2("/api/v1/scheduling/slots/check", {
|
|
2828
|
-
service_id: input.service_id,
|
|
2829
|
-
slot_time: input.slot_time,
|
|
2830
|
-
duration_minutes: input.duration_minutes,
|
|
2831
|
-
participant_count: input.participant_count
|
|
2832
|
-
});
|
|
2833
|
-
return safe(this.client.get(path));
|
|
2834
|
-
}
|
|
2835
|
-
async getServiceAvailability(params) {
|
|
2836
|
-
const path = withQuery2("/api/v1/scheduling/availability", {
|
|
2837
|
-
service_id: params.service_id,
|
|
2838
|
-
start_date: params.start_date,
|
|
2839
|
-
end_date: params.end_date,
|
|
2840
|
-
location_id: params.location_id,
|
|
2841
|
-
participant_count: params.participant_count,
|
|
2842
|
-
units: params.units,
|
|
2843
|
-
variant_id: params.variant_id
|
|
2844
|
-
});
|
|
2845
|
-
return safe(this.client.get(path));
|
|
2846
|
-
}
|
|
2847
|
-
async getBooking(bookingId) {
|
|
2848
|
-
const encodedId = encodeURIComponent(bookingId);
|
|
2849
|
-
return safe(this.client.get(`/api/v1/scheduling/bookings/${encodedId}`));
|
|
2850
|
-
}
|
|
2851
|
-
async getCustomerBookings(customerId) {
|
|
2852
|
-
const path = withQuery2("/api/v1/scheduling/bookings", {
|
|
2853
|
-
customer_id: customerId
|
|
2854
|
-
});
|
|
2855
|
-
return safe(this.client.get(path));
|
|
2856
|
-
}
|
|
2857
|
-
async getUpcomingBookings() {
|
|
2858
|
-
const result = await this.getCustomerBookings();
|
|
2859
|
-
if (!result.ok) return result;
|
|
2860
|
-
const upcoming = result.value.filter((booking) => {
|
|
2861
|
-
const status = String(booking.status).toLowerCase();
|
|
2862
|
-
return status !== "completed" && status !== "cancelled";
|
|
2863
|
-
}).sort((a, b) => firstScheduledTime(a).localeCompare(firstScheduledTime(b)));
|
|
2864
|
-
return ok(upcoming);
|
|
2865
|
-
}
|
|
2866
|
-
async getPastBookings(limit = 10) {
|
|
2867
|
-
const result = await this.getCustomerBookings();
|
|
2868
|
-
if (!result.ok) return result;
|
|
2869
|
-
const past = result.value.filter((booking) => String(booking.status).toLowerCase() === "completed").sort((a, b) => firstScheduledTime(b).localeCompare(firstScheduledTime(a))).slice(0, Math.max(0, limit));
|
|
2870
|
-
return ok(past);
|
|
2871
|
-
}
|
|
2872
|
-
async cancelBooking(input, opts) {
|
|
2873
|
-
const encodedId = encodeURIComponent(input.booking_id);
|
|
2874
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2875
|
-
return safe(
|
|
2876
|
-
this.client.post(
|
|
2877
|
-
`/api/v1/scheduling/bookings/${encodedId}/cancel`,
|
|
2878
|
-
{ reason: input.reason },
|
|
2879
|
-
{ idempotencyKey }
|
|
2880
|
-
)
|
|
2881
|
-
);
|
|
2882
|
-
}
|
|
2883
|
-
async rescheduleBooking(input, opts) {
|
|
2884
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2885
|
-
return safe(
|
|
2886
|
-
this.client.post(
|
|
2887
|
-
"/api/v1/scheduling/bookings/reschedule",
|
|
2888
|
-
input,
|
|
2889
|
-
{ idempotencyKey }
|
|
2890
|
-
)
|
|
2891
|
-
);
|
|
2892
|
-
}
|
|
2893
|
-
async getNextAvailableSlot(serviceId, fromDate) {
|
|
2894
|
-
const date = fromDate || (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
2895
|
-
const result = await this.getAvailableSlots({
|
|
2896
|
-
service_id: serviceId,
|
|
2897
|
-
date
|
|
2898
|
-
});
|
|
2899
|
-
if (!result.ok) return result;
|
|
2900
|
-
return ok(result.value[0] ?? null);
|
|
2901
|
-
}
|
|
2902
|
-
async hasAvailabilityOn(serviceId, date) {
|
|
2903
|
-
const result = await this.getAvailableSlots({
|
|
2904
|
-
service_id: serviceId,
|
|
2905
|
-
date
|
|
2906
|
-
});
|
|
2907
|
-
if (!result.ok) return result;
|
|
2908
|
-
return ok(result.value.length > 0);
|
|
2909
|
-
}
|
|
2910
|
-
};
|
|
2911
|
-
|
|
2912
|
-
// src/lite.ts
|
|
2913
|
-
var LiteService = class {
|
|
2914
|
-
constructor(client) {
|
|
2915
|
-
this.client = client;
|
|
2916
|
-
}
|
|
2917
|
-
async getBootstrap() {
|
|
2918
|
-
return safe(this.client.get("/api/v1/lite/bootstrap"));
|
|
2919
|
-
}
|
|
2920
|
-
async getResource(resourceId) {
|
|
2921
|
-
const encodedId = encodeURIComponent(resourceId);
|
|
2922
|
-
return safe(this.client.get(`/api/v1/lite/resources/${encodedId}`));
|
|
2923
|
-
}
|
|
2924
|
-
async getMenu() {
|
|
2925
|
-
return safe(this.client.get("/api/v1/lite/menu"));
|
|
2926
|
-
}
|
|
2927
|
-
async getMenuByCategory(categoryId) {
|
|
2928
|
-
const encodedId = encodeURIComponent(categoryId);
|
|
2929
|
-
return safe(this.client.get(`/api/v1/lite/menu/categories/${encodedId}`));
|
|
2930
|
-
}
|
|
2931
|
-
};
|
|
2932
|
-
|
|
2933
|
-
// src/fx.ts
|
|
2934
|
-
var FxService = class {
|
|
2935
|
-
constructor(client) {
|
|
2936
|
-
this.client = client;
|
|
2937
|
-
}
|
|
2938
|
-
async getRate(from, to) {
|
|
2939
|
-
const path = `/api/v1/fx/rate?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`;
|
|
2940
|
-
return safe(this.client.get(path));
|
|
2941
|
-
}
|
|
2942
|
-
async lockQuote(request, opts) {
|
|
2943
|
-
const idempotencyKey = opts?.idempotencyKey ?? generateIdempotencyKey();
|
|
2944
|
-
return safe(
|
|
2945
|
-
this.client.post("/api/v1/fx/quotes", request, { idempotencyKey })
|
|
2946
|
-
);
|
|
2947
|
-
}
|
|
2948
|
-
};
|
|
2949
|
-
|
|
2950
|
-
// src/types/elements.ts
|
|
2951
|
-
var ELEMENT_TYPES = {
|
|
2952
|
-
AUTH: "auth",
|
|
2953
|
-
ADDRESS: "address",
|
|
2954
|
-
PAYMENT: "payment",
|
|
2955
|
-
CHECKOUT: "checkout",
|
|
2956
|
-
ACCOUNT: "account"
|
|
2957
|
-
};
|
|
2958
|
-
var MESSAGE_TYPES = {
|
|
2959
|
-
INIT: "init",
|
|
2960
|
-
IDENTITY: "identity",
|
|
2961
|
-
SESSION_CLEARED: "session_cleared",
|
|
2962
|
-
SET_CART: "set_cart",
|
|
2963
|
-
GET_DATA: "get_data",
|
|
2964
|
-
LOGOUT: "logout",
|
|
2965
|
-
PROCESS_CHECKOUT: "process_checkout",
|
|
2966
|
-
ABORT_CHECKOUT: "abort_checkout",
|
|
2967
|
-
READY: "ready",
|
|
2968
|
-
HEIGHT_CHANGE: "height_change",
|
|
2969
|
-
ERROR: "error",
|
|
2970
|
-
ADDRESS_CHANGED: "address_changed",
|
|
2971
|
-
ADDRESS_SELECTED: "address_selected",
|
|
2972
|
-
PAYMENT_METHOD_SELECTED: "payment_method_selected",
|
|
2973
|
-
LOGOUT_COMPLETE: "logout_complete",
|
|
2974
|
-
AUTH_REQUESTED: "auth_requested",
|
|
2975
|
-
SESSION_ESTABLISHED: "session_established",
|
|
2976
|
-
CONTINUE_WITHOUT_SAVED_DETAILS: "continue_without_saved_details",
|
|
2977
|
-
CONTACT_PROVIDED: "contact_provided",
|
|
2978
|
-
CHECKOUT_STATUS: "checkout_status",
|
|
2979
|
-
CHECKOUT_COMPLETE: "checkout_complete",
|
|
2980
|
-
TERMS_CHANGED: "terms_changed",
|
|
2981
|
-
SELECTION_UNAVAILABLE: "selection_unavailable",
|
|
2982
|
-
ORDER_TYPE_CHANGED: "order_type_changed",
|
|
2983
|
-
REQUEST_SUBMIT: "request_submit"
|
|
2984
|
-
};
|
|
2985
|
-
var ELEMENTS_AUTH_CONTACT_TYPES = {
|
|
2986
|
-
EMAIL: "email",
|
|
2987
|
-
PHONE: "phone"
|
|
2988
|
-
};
|
|
2989
|
-
var ELEMENTS_AUTH_PROMPTS = {
|
|
2990
|
-
LOGIN: "login"
|
|
2991
|
-
};
|
|
2992
|
-
var ELEMENTS_AUTH_MODES = {
|
|
2993
|
-
CHECKOUT: "checkout",
|
|
2994
|
-
DEFAULT: "default"
|
|
2995
|
-
};
|
|
2996
|
-
var EVENT_TYPES = {
|
|
2997
|
-
READY: "ready",
|
|
2998
|
-
AUTHENTICATED: "authenticated",
|
|
2999
|
-
ERROR: "error",
|
|
3000
|
-
CHANGE: "change",
|
|
3001
|
-
BLUR: "blur",
|
|
3002
|
-
FOCUS: "focus",
|
|
3003
|
-
ORDER_TYPE_CHANGED: "order_type_changed",
|
|
3004
|
-
REQUEST_SUBMIT: "request_submit"
|
|
3005
|
-
};
|
|
3006
|
-
|
|
3007
|
-
// src/internal/pkce.ts
|
|
3008
|
-
var VERIFIER_BYTES = 64;
|
|
3009
|
-
async function generatePkce() {
|
|
3010
|
-
const random = new Uint8Array(VERIFIER_BYTES);
|
|
3011
|
-
crypto.getRandomValues(random);
|
|
3012
|
-
const verifier = base64UrlEncode(random);
|
|
3013
|
-
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(verifier));
|
|
3014
|
-
const challenge = base64UrlEncode(new Uint8Array(digest));
|
|
3015
|
-
return { verifier, challenge, method: "S256" };
|
|
3016
|
-
}
|
|
3017
|
-
function generateState(byteLength = 16) {
|
|
3018
|
-
const buf = new Uint8Array(byteLength);
|
|
3019
|
-
crypto.getRandomValues(buf);
|
|
3020
|
-
return base64UrlEncode(buf);
|
|
3021
|
-
}
|
|
3022
|
-
function base64UrlEncode(bytes) {
|
|
3023
|
-
let str = "";
|
|
3024
|
-
for (const byte of bytes) str += String.fromCharCode(byte);
|
|
3025
|
-
return btoa(str).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
3026
|
-
}
|
|
3027
|
-
|
|
3028
|
-
// src/internal/pkce-cookie.ts
|
|
3029
|
-
var PKCE_COOKIE = "cimplify_pkce";
|
|
3030
|
-
var PKCE_COOKIE_PATH = "/auth";
|
|
3031
|
-
var PKCE_COOKIE_MAX_AGE_SECONDS = 600;
|
|
3032
|
-
function encodePkceState(state) {
|
|
3033
|
-
return encodeURIComponent(JSON.stringify(state));
|
|
3034
|
-
}
|
|
3035
|
-
function decodePkceState(raw) {
|
|
3036
|
-
try {
|
|
3037
|
-
const parsed = JSON.parse(decodeURIComponent(raw));
|
|
3038
|
-
if (typeof parsed?.verifier === "string" && typeof parsed.state === "string" && typeof parsed.returnTo === "string") {
|
|
3039
|
-
return { verifier: parsed.verifier, state: parsed.state, returnTo: parsed.returnTo };
|
|
3040
|
-
}
|
|
3041
|
-
} catch {
|
|
3042
|
-
}
|
|
3043
|
-
return null;
|
|
3044
|
-
}
|
|
3045
|
-
|
|
3046
|
-
// src/internal/discovery.ts
|
|
3047
|
-
var DEFAULT_ISSUER = "https://api.cimplify.io";
|
|
3048
|
-
var DEFAULT_AUTHORIZATION_ENDPOINT = "https://auth.cimplify.io/oauth/authorize";
|
|
3049
|
-
function fallbackAuthorizationEndpoint(issuerBase) {
|
|
3050
|
-
if (issuerBase === DEFAULT_ISSUER) return DEFAULT_AUTHORIZATION_ENDPOINT;
|
|
3051
|
-
throw new Error(
|
|
3052
|
-
`OIDC discovery for "${issuerBase}" is unreachable and no fallback authorize endpoint is known for it. Make discovery reachable (enable CORS) or pass authUrl.`
|
|
3053
|
-
);
|
|
3054
|
-
}
|
|
3055
|
-
var cache = /* @__PURE__ */ new Map();
|
|
3056
|
-
function fetchDiscovery(issuer) {
|
|
3057
|
-
const base = issuer.replace(/\/$/, "");
|
|
3058
|
-
let pending = cache.get(base);
|
|
3059
|
-
if (!pending) {
|
|
3060
|
-
pending = fetch(`${base}/.well-known/openid-configuration`).then((res) => {
|
|
3061
|
-
if (!res.ok) throw new Error(`oidc discovery failed: ${res.status}`);
|
|
3062
|
-
return res.json();
|
|
3063
|
-
});
|
|
3064
|
-
pending.catch(() => cache.delete(base));
|
|
3065
|
-
cache.set(base, pending);
|
|
3066
|
-
}
|
|
3067
|
-
return pending;
|
|
3068
|
-
}
|
|
3069
|
-
async function getAuthorizationEndpoint(issuer) {
|
|
3070
|
-
const base = issuer.replace(/\/$/, "");
|
|
3071
|
-
try {
|
|
3072
|
-
const doc = await fetchDiscovery(base);
|
|
3073
|
-
if (doc.authorization_endpoint) return doc.authorization_endpoint;
|
|
3074
|
-
} catch {
|
|
3075
|
-
}
|
|
3076
|
-
return fallbackAuthorizationEndpoint(base);
|
|
3077
|
-
}
|
|
3078
|
-
|
|
3079
|
-
// src/internal/modal-iframe.ts
|
|
3080
|
-
function openModalIframe(opts) {
|
|
3081
|
-
const overlay = document.createElement("div");
|
|
3082
|
-
overlay.dataset.cimplifyModal = "1";
|
|
3083
|
-
Object.assign(overlay.style, {
|
|
3084
|
-
position: "fixed",
|
|
3085
|
-
inset: "0",
|
|
3086
|
-
background: "rgba(15, 18, 24, 0.55)",
|
|
3087
|
-
zIndex: "2147483647",
|
|
3088
|
-
display: "grid",
|
|
3089
|
-
placeItems: "center",
|
|
3090
|
-
backdropFilter: "blur(2px)"
|
|
3091
|
-
});
|
|
3092
|
-
const card = document.createElement("div");
|
|
3093
|
-
Object.assign(card.style, {
|
|
3094
|
-
width: `${opts.width ?? 480}px`,
|
|
3095
|
-
maxWidth: "calc(100vw - 24px)",
|
|
3096
|
-
height: `${opts.height ?? 720}px`,
|
|
3097
|
-
maxHeight: "calc(100vh - 32px)"
|
|
3098
|
-
});
|
|
3099
|
-
const iframe = document.createElement("iframe");
|
|
3100
|
-
iframe.src = opts.src;
|
|
3101
|
-
iframe.style.width = "100%";
|
|
3102
|
-
iframe.style.height = "100%";
|
|
3103
|
-
iframe.style.border = "none";
|
|
3104
|
-
iframe.style.background = "transparent";
|
|
3105
|
-
iframe.setAttribute(
|
|
3106
|
-
"sandbox",
|
|
3107
|
-
opts.sandbox ?? "allow-scripts allow-same-origin allow-forms allow-popups"
|
|
3108
|
-
);
|
|
3109
|
-
iframe.setAttribute("allow", "publickey-credentials-get; publickey-credentials-create");
|
|
3110
|
-
card.appendChild(iframe);
|
|
3111
|
-
overlay.appendChild(card);
|
|
3112
|
-
document.body.appendChild(overlay);
|
|
3113
|
-
const close = () => {
|
|
3114
|
-
overlay.remove();
|
|
3115
|
-
document.removeEventListener("keydown", onKey);
|
|
3116
|
-
opts.onClose?.();
|
|
3117
|
-
};
|
|
3118
|
-
const onKey = (e) => {
|
|
3119
|
-
if (e.key === "Escape") close();
|
|
3120
|
-
};
|
|
3121
|
-
overlay.addEventListener("click", (e) => {
|
|
3122
|
-
if (e.target === overlay) close();
|
|
3123
|
-
});
|
|
3124
|
-
document.addEventListener("keydown", onKey);
|
|
3125
|
-
return { iframe, close };
|
|
3126
|
-
}
|
|
3127
|
-
|
|
3128
|
-
// src/sign-in.ts
|
|
3129
|
-
var DEFAULT_SCOPE = "openid email phone profile";
|
|
3130
|
-
var DEFAULT_SILENT_TIMEOUT_MS = 900;
|
|
3131
|
-
var RESPONSE_TYPE_CODE = "code";
|
|
3132
|
-
var RESPONSE_MODE_WEB_MESSAGE = "web_message";
|
|
3133
|
-
var RESPONSE_MODE_QUERY = "query";
|
|
3134
|
-
var PROMPT_NONE = "none";
|
|
3135
|
-
var AUTHORIZATION_RESPONSE_MESSAGE_TYPE = "authorization_response";
|
|
3136
|
-
var ERROR_STATE_MISMATCH = "state_mismatch";
|
|
3137
|
-
var ERROR_CALLBACK_FAILED = "callback_failed";
|
|
3138
|
-
var ERROR_CALLBACK_EXCEPTION = "callback_exception";
|
|
3139
|
-
var ERROR_CANCELLED = "cancelled";
|
|
3140
|
-
var ERROR_LOGIN_REQUIRED = "login_required";
|
|
3141
|
-
var ERROR_CONSENT_REQUIRED = "consent_required";
|
|
3142
|
-
var ERROR_INTERACTION_REQUIRED = "interaction_required";
|
|
3143
|
-
var INTERACTIVE_AUTH_ERRORS = /* @__PURE__ */ new Set([
|
|
3144
|
-
ERROR_LOGIN_REQUIRED,
|
|
3145
|
-
ERROR_CONSENT_REQUIRED,
|
|
3146
|
-
ERROR_INTERACTION_REQUIRED
|
|
3147
|
-
]);
|
|
3148
|
-
function buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, urlOpts) {
|
|
3149
|
-
const params = new URLSearchParams({
|
|
3150
|
-
response_type: RESPONSE_TYPE_CODE,
|
|
3151
|
-
response_mode: urlOpts.responseMode,
|
|
3152
|
-
client_id: opts.clientId,
|
|
3153
|
-
redirect_uri: opts.redirectUri,
|
|
3154
|
-
scope: opts.scope ?? DEFAULT_SCOPE,
|
|
3155
|
-
state,
|
|
3156
|
-
code_challenge: pkce.challenge,
|
|
3157
|
-
code_challenge_method: pkce.method
|
|
3158
|
-
});
|
|
3159
|
-
if (opts.loginHint) params.set("login_hint", opts.loginHint);
|
|
3160
|
-
if (urlOpts.prompt) params.set("prompt", urlOpts.prompt);
|
|
3161
|
-
if (opts.uiMode) params.set("ui_mode", opts.uiMode);
|
|
3162
|
-
return `${authorizeEndpoint}?${params.toString()}`;
|
|
3163
|
-
}
|
|
3164
|
-
async function exchangeAuthorizationCode(callbackUri, pkce, state, code) {
|
|
3165
|
-
const res = await fetch(callbackUri, {
|
|
3166
|
-
method: "POST",
|
|
3167
|
-
credentials: "include",
|
|
3168
|
-
headers: { "Content-Type": "application/json" },
|
|
3169
|
-
body: JSON.stringify({ code, codeVerifier: pkce.verifier, state })
|
|
3170
|
-
});
|
|
3171
|
-
if (!res.ok) {
|
|
3172
|
-
const body = await res.text().catch(() => "");
|
|
3173
|
-
throw { error: ERROR_CALLBACK_FAILED, description: body };
|
|
3174
|
-
}
|
|
3175
|
-
const payload = await res.json().catch(() => ({}));
|
|
3176
|
-
return {
|
|
3177
|
-
accessToken: payload.accessToken ?? payload.access_token,
|
|
3178
|
-
expiresIn: payload.expiresIn ?? payload.expires_in,
|
|
3179
|
-
scope: payload.scope
|
|
3180
|
-
};
|
|
3181
|
-
}
|
|
3182
|
-
async function trySilentModalSignIn(opts, authorizeEndpoint, callbackUri, pkce, state) {
|
|
3183
|
-
const expectedOrigin = new URL(authorizeEndpoint).origin;
|
|
3184
|
-
const iframe = document.createElement("iframe");
|
|
3185
|
-
iframe.style.display = "none";
|
|
3186
|
-
iframe.setAttribute("aria-hidden", "true");
|
|
3187
|
-
iframe.setAttribute("sandbox", "allow-scripts allow-same-origin");
|
|
3188
|
-
iframe.src = buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, {
|
|
3189
|
-
responseMode: RESPONSE_MODE_WEB_MESSAGE,
|
|
3190
|
-
prompt: PROMPT_NONE
|
|
3191
|
-
});
|
|
3192
|
-
return new Promise((resolve) => {
|
|
3193
|
-
let settled = false;
|
|
3194
|
-
let handler = () => {
|
|
3195
|
-
};
|
|
3196
|
-
const timeout = setTimeout(() => finish(false), opts.silentTimeoutMs ?? DEFAULT_SILENT_TIMEOUT_MS);
|
|
3197
|
-
const cleanup = () => {
|
|
3198
|
-
window.removeEventListener("message", handler);
|
|
3199
|
-
iframe.remove();
|
|
3200
|
-
clearTimeout(timeout);
|
|
3201
|
-
};
|
|
3202
|
-
const finish = (handled) => {
|
|
3203
|
-
if (settled) return;
|
|
3204
|
-
settled = true;
|
|
3205
|
-
cleanup();
|
|
3206
|
-
resolve(handled);
|
|
3207
|
-
};
|
|
3208
|
-
handler = async (event) => {
|
|
3209
|
-
if (event.origin !== expectedOrigin) return;
|
|
3210
|
-
const data = event.data;
|
|
3211
|
-
if (!data || typeof data !== "object" || data.type !== AUTHORIZATION_RESPONSE_MESSAGE_TYPE) return;
|
|
3212
|
-
const response = data.response;
|
|
3213
|
-
if (response.error) {
|
|
3214
|
-
if (INTERACTIVE_AUTH_ERRORS.has(response.error)) {
|
|
3215
|
-
finish(false);
|
|
3216
|
-
return;
|
|
3217
|
-
}
|
|
3218
|
-
opts.onError?.({ error: response.error, description: response.error_description });
|
|
3219
|
-
finish(true);
|
|
3220
|
-
return;
|
|
3221
|
-
}
|
|
3222
|
-
if (!response.code) return;
|
|
3223
|
-
if (response.state !== state) {
|
|
3224
|
-
opts.onError?.({ error: ERROR_STATE_MISMATCH });
|
|
3225
|
-
finish(true);
|
|
3226
|
-
return;
|
|
3227
|
-
}
|
|
3228
|
-
try {
|
|
3229
|
-
opts.onSuccess?.(await exchangeAuthorizationCode(callbackUri, pkce, state, response.code));
|
|
3230
|
-
} catch (e) {
|
|
3231
|
-
const err2 = e;
|
|
3232
|
-
opts.onError?.({
|
|
3233
|
-
error: err2.error ?? ERROR_CALLBACK_EXCEPTION,
|
|
3234
|
-
description: err2.description ?? String(e)
|
|
3235
|
-
});
|
|
3236
|
-
}
|
|
3237
|
-
finish(true);
|
|
3238
|
-
};
|
|
3239
|
-
window.addEventListener("message", handler);
|
|
3240
|
-
document.body.appendChild(iframe);
|
|
3241
|
-
});
|
|
3242
|
-
}
|
|
3243
|
-
function resolveAuthorizeEndpoint(opts) {
|
|
3244
|
-
if (opts.authUrl) {
|
|
3245
|
-
return Promise.resolve(`${opts.authUrl.replace(/\/$/, "")}/oauth/authorize`);
|
|
3246
|
-
}
|
|
3247
|
-
return getAuthorizationEndpoint(opts.issuer ?? DEFAULT_ISSUER);
|
|
3248
|
-
}
|
|
3249
|
-
async function startSignIn(opts) {
|
|
3250
|
-
const callbackUri = opts.callbackUri ?? "/auth/callback";
|
|
3251
|
-
const pkce = await generatePkce();
|
|
3252
|
-
const state = generateState();
|
|
3253
|
-
const authorizeEndpoint = await resolveAuthorizeEndpoint(opts);
|
|
3254
|
-
if ((opts.mode ?? "redirect") === "redirect") {
|
|
3255
|
-
startRedirectSignIn(opts, authorizeEndpoint, pkce, state);
|
|
3256
|
-
return;
|
|
3257
|
-
}
|
|
3258
|
-
if (opts.silentFirst && !opts.prompt) {
|
|
3259
|
-
const handledSilently = await trySilentModalSignIn(opts, authorizeEndpoint, callbackUri, pkce, state);
|
|
3260
|
-
if (handledSilently) {
|
|
3261
|
-
return;
|
|
3262
|
-
}
|
|
3263
|
-
}
|
|
3264
|
-
const src = buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, {
|
|
3265
|
-
responseMode: RESPONSE_MODE_WEB_MESSAGE,
|
|
3266
|
-
prompt: opts.prompt
|
|
3267
|
-
});
|
|
3268
|
-
const expectedOrigin = new URL(authorizeEndpoint).origin;
|
|
3269
|
-
let completed = false;
|
|
3270
|
-
let handler = () => {
|
|
3271
|
-
};
|
|
3272
|
-
const modal = openModalIframe({
|
|
3273
|
-
src,
|
|
3274
|
-
onClose: () => {
|
|
3275
|
-
window.removeEventListener("message", handler);
|
|
3276
|
-
if (!completed) {
|
|
3277
|
-
opts.onError?.({ error: ERROR_CANCELLED });
|
|
3278
|
-
}
|
|
3279
|
-
}
|
|
3280
|
-
});
|
|
3281
|
-
handler = async (event) => {
|
|
3282
|
-
if (event.origin !== expectedOrigin) return;
|
|
3283
|
-
const data = event.data;
|
|
3284
|
-
if (!data || typeof data !== "object" || data.type !== AUTHORIZATION_RESPONSE_MESSAGE_TYPE) return;
|
|
3285
|
-
const response = data.response;
|
|
3286
|
-
if (response.error) {
|
|
3287
|
-
completed = true;
|
|
3288
|
-
modal.close();
|
|
3289
|
-
opts.onError?.({ error: response.error, description: response.error_description });
|
|
3290
|
-
return;
|
|
3291
|
-
}
|
|
3292
|
-
if (!response.code) return;
|
|
3293
|
-
if (response.state !== state) {
|
|
3294
|
-
completed = true;
|
|
3295
|
-
modal.close();
|
|
3296
|
-
opts.onError?.({ error: ERROR_STATE_MISMATCH });
|
|
3297
|
-
return;
|
|
3298
|
-
}
|
|
3299
|
-
try {
|
|
3300
|
-
const result = await exchangeAuthorizationCode(callbackUri, pkce, state, response.code);
|
|
3301
|
-
completed = true;
|
|
3302
|
-
modal.close();
|
|
3303
|
-
opts.onSuccess?.(result);
|
|
3304
|
-
} catch (e) {
|
|
3305
|
-
const err2 = e;
|
|
3306
|
-
completed = true;
|
|
3307
|
-
opts.onError?.({
|
|
3308
|
-
error: err2.error ?? ERROR_CALLBACK_EXCEPTION,
|
|
3309
|
-
description: err2.description ?? String(e)
|
|
3310
|
-
});
|
|
3311
|
-
modal.close();
|
|
3312
|
-
}
|
|
3313
|
-
};
|
|
3314
|
-
window.addEventListener("message", handler);
|
|
3315
|
-
}
|
|
3316
|
-
function startRedirectSignIn(opts, authorizeEndpoint, pkce, state) {
|
|
3317
|
-
const returnTo = opts.returnTo ?? window.location.pathname + window.location.search;
|
|
3318
|
-
const cookieValue = encodePkceState({ verifier: pkce.verifier, state, returnTo });
|
|
3319
|
-
const secure = window.location.protocol === "https:" ? "; Secure" : "";
|
|
3320
|
-
document.cookie = `${PKCE_COOKIE}=${cookieValue}; Path=${PKCE_COOKIE_PATH}; Max-Age=${PKCE_COOKIE_MAX_AGE_SECONDS}; SameSite=Lax${secure}`;
|
|
3321
|
-
window.location.assign(buildAuthorizeUrl(opts, authorizeEndpoint, pkce, state, {
|
|
3322
|
-
responseMode: RESPONSE_MODE_QUERY,
|
|
3323
|
-
prompt: opts.prompt
|
|
3324
|
-
}));
|
|
3325
|
-
}
|
|
3326
|
-
|
|
3327
|
-
// src/internal/events.ts
|
|
3328
|
-
var MUTATION_ERROR = "mutation:error";
|
|
3329
|
-
var AUTH_TOKEN_CHANGED = "auth:token-changed";
|
|
3330
|
-
var SESSION_CLAIMED = "session:claimed";
|
|
3331
|
-
var SESSION_CLEARED = "session:cleared";
|
|
3332
|
-
function createClientEvents() {
|
|
3333
|
-
const listeners = /* @__PURE__ */ new Map();
|
|
3334
|
-
return {
|
|
3335
|
-
on(name, listener) {
|
|
3336
|
-
let set = listeners.get(name);
|
|
3337
|
-
if (!set) {
|
|
3338
|
-
set = /* @__PURE__ */ new Set();
|
|
3339
|
-
listeners.set(name, set);
|
|
3340
|
-
}
|
|
3341
|
-
set.add(listener);
|
|
3342
|
-
return () => {
|
|
3343
|
-
set?.delete(listener);
|
|
3344
|
-
};
|
|
3345
|
-
},
|
|
3346
|
-
off(name, listener) {
|
|
3347
|
-
listeners.get(name)?.delete(listener);
|
|
3348
|
-
},
|
|
3349
|
-
emit(name, payload) {
|
|
3350
|
-
const set = listeners.get(name);
|
|
3351
|
-
if (!set) return;
|
|
3352
|
-
const snapshot = Array.from(set);
|
|
3353
|
-
for (const listener of snapshot) {
|
|
3354
|
-
try {
|
|
3355
|
-
listener(payload);
|
|
3356
|
-
} catch (err2) {
|
|
3357
|
-
console.error(`[Cimplify] event listener for "${name}" threw:`, err2);
|
|
3358
|
-
}
|
|
3359
|
-
}
|
|
3360
|
-
}
|
|
3361
|
-
};
|
|
3362
|
-
}
|
|
3363
|
-
|
|
3364
|
-
// src/elements.ts
|
|
3365
|
-
function toCheckoutError(code, message, recoverable) {
|
|
3366
|
-
const hint = chunkANT574FD_js.getErrorHint(code);
|
|
3367
|
-
return {
|
|
3368
|
-
success: false,
|
|
3369
|
-
error: {
|
|
3370
|
-
code,
|
|
3371
|
-
message,
|
|
3372
|
-
recoverable,
|
|
3373
|
-
docs_url: hint?.docs_url,
|
|
3374
|
-
suggestion: hint?.suggestion
|
|
3375
|
-
}
|
|
3376
|
-
};
|
|
3377
|
-
}
|
|
3378
|
-
var DEFAULT_LINK_URL = "https://link.cimplify.io";
|
|
3379
|
-
var AUTH_CONTACT_TYPES = new Set(Object.values(ELEMENTS_AUTH_CONTACT_TYPES));
|
|
3380
|
-
var AUTH_MODES = new Set(Object.values(ELEMENTS_AUTH_MODES));
|
|
3381
|
-
var AUTH_PROMPTS = new Set(Object.values(ELEMENTS_AUTH_PROMPTS));
|
|
3382
|
-
function generateNonce() {
|
|
3383
|
-
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
3384
|
-
return crypto.randomUUID().replace(/-/g, "").slice(0, 16);
|
|
3385
|
-
}
|
|
3386
|
-
return Math.random().toString(36).slice(2) + Math.random().toString(36).slice(2);
|
|
3387
|
-
}
|
|
3388
|
-
function readPublicEnv(name) {
|
|
3389
|
-
try {
|
|
3390
|
-
const processLike = globalThis.process;
|
|
3391
|
-
const value = processLike?.env?.[name];
|
|
3392
|
-
return value && value.trim() ? value : void 0;
|
|
3393
|
-
} catch {
|
|
3394
|
-
return void 0;
|
|
3395
|
-
}
|
|
3396
|
-
}
|
|
3397
|
-
function decodeJwtSub(token) {
|
|
3398
|
-
const [, payload] = token.split(".");
|
|
3399
|
-
if (!payload || typeof atob === "undefined") return "";
|
|
3400
|
-
try {
|
|
3401
|
-
const base64 = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
3402
|
-
const padded = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, "=");
|
|
3403
|
-
const parsed = JSON.parse(atob(padded));
|
|
3404
|
-
return typeof parsed.sub === "string" ? parsed.sub : "";
|
|
3405
|
-
} catch {
|
|
3406
|
-
return "";
|
|
3407
|
-
}
|
|
3408
|
-
}
|
|
3409
|
-
function isClaimedCustomer(value) {
|
|
3410
|
-
if (!value || typeof value !== "object") return false;
|
|
3411
|
-
const record = value;
|
|
3412
|
-
return typeof record.id === "string" && typeof record.name === "string" && (record.email === null || typeof record.email === "string") && (record.phone === null || typeof record.phone === "string");
|
|
3413
|
-
}
|
|
3414
|
-
function isAllowedOrigin(origin) {
|
|
3415
|
-
try {
|
|
3416
|
-
const url = new URL(origin);
|
|
3417
|
-
const hostname = url.hostname;
|
|
3418
|
-
if (hostname === "localhost" || hostname === "127.0.0.1") {
|
|
3419
|
-
return true;
|
|
3420
|
-
}
|
|
3421
|
-
if (url.protocol !== "https:") {
|
|
3422
|
-
return false;
|
|
3423
|
-
}
|
|
3424
|
-
return hostname === "cimplify.io" || hostname.endsWith(".cimplify.io");
|
|
3425
|
-
} catch {
|
|
3426
|
-
return false;
|
|
3427
|
-
}
|
|
3428
|
-
}
|
|
3429
|
-
var KNOWN_IFRAME_TYPES = /* @__PURE__ */ new Set([
|
|
3430
|
-
MESSAGE_TYPES.READY,
|
|
3431
|
-
MESSAGE_TYPES.HEIGHT_CHANGE,
|
|
3432
|
-
MESSAGE_TYPES.AUTH_REQUESTED,
|
|
3433
|
-
MESSAGE_TYPES.SESSION_ESTABLISHED,
|
|
3434
|
-
MESSAGE_TYPES.CONTINUE_WITHOUT_SAVED_DETAILS,
|
|
3435
|
-
MESSAGE_TYPES.ERROR,
|
|
3436
|
-
MESSAGE_TYPES.ADDRESS_CHANGED,
|
|
3437
|
-
MESSAGE_TYPES.ADDRESS_SELECTED,
|
|
3438
|
-
MESSAGE_TYPES.PAYMENT_METHOD_SELECTED,
|
|
3439
|
-
MESSAGE_TYPES.CONTACT_PROVIDED,
|
|
3440
|
-
MESSAGE_TYPES.LOGOUT_COMPLETE,
|
|
3441
|
-
MESSAGE_TYPES.CHECKOUT_STATUS,
|
|
3442
|
-
MESSAGE_TYPES.CHECKOUT_COMPLETE,
|
|
3443
|
-
MESSAGE_TYPES.TERMS_CHANGED,
|
|
3444
|
-
MESSAGE_TYPES.SELECTION_UNAVAILABLE,
|
|
3445
|
-
MESSAGE_TYPES.ORDER_TYPE_CHANGED,
|
|
3446
|
-
MESSAGE_TYPES.REQUEST_SUBMIT
|
|
3447
|
-
]);
|
|
3448
|
-
function parseIframeMessage(data) {
|
|
3449
|
-
if (!data || typeof data !== "object") {
|
|
3450
|
-
return null;
|
|
3451
|
-
}
|
|
3452
|
-
const record = data;
|
|
3453
|
-
if (typeof record.type !== "string" || !KNOWN_IFRAME_TYPES.has(record.type)) {
|
|
3454
|
-
return null;
|
|
3455
|
-
}
|
|
3456
|
-
switch (record.type) {
|
|
3457
|
-
case MESSAGE_TYPES.AUTH_REQUESTED:
|
|
3458
|
-
if (record.loginHint !== void 0 && typeof record.loginHint !== "string") return null;
|
|
3459
|
-
if (record.contactType !== void 0 && (typeof record.contactType !== "string" || !AUTH_CONTACT_TYPES.has(record.contactType))) {
|
|
3460
|
-
return null;
|
|
3461
|
-
}
|
|
3462
|
-
if (record.mode !== void 0 && (typeof record.mode !== "string" || !AUTH_MODES.has(record.mode))) {
|
|
3463
|
-
return null;
|
|
3464
|
-
}
|
|
3465
|
-
if (record.prompt !== void 0 && (typeof record.prompt !== "string" || !AUTH_PROMPTS.has(record.prompt))) {
|
|
3466
|
-
return null;
|
|
3467
|
-
}
|
|
3468
|
-
break;
|
|
3469
|
-
case MESSAGE_TYPES.SESSION_ESTABLISHED:
|
|
3470
|
-
if (typeof record.sessionToken !== "string" || !record.sessionToken.trim()) return null;
|
|
3471
|
-
if (typeof record.accessToken !== "string" || !record.accessToken.trim()) return null;
|
|
3472
|
-
if (record.refreshToken !== void 0 && typeof record.refreshToken !== "string") return null;
|
|
3473
|
-
if (!isClaimedCustomer(record.customer)) return null;
|
|
3474
|
-
break;
|
|
3475
|
-
case MESSAGE_TYPES.ADDRESS_CHANGED:
|
|
3476
|
-
case MESSAGE_TYPES.ADDRESS_SELECTED:
|
|
3477
|
-
if (!record.address || typeof record.address !== "object") return null;
|
|
3478
|
-
break;
|
|
3479
|
-
case MESSAGE_TYPES.PAYMENT_METHOD_SELECTED:
|
|
3480
|
-
if (!record.method || typeof record.method !== "object") return null;
|
|
3481
|
-
break;
|
|
3482
|
-
case MESSAGE_TYPES.CONTACT_PROVIDED:
|
|
3483
|
-
case MESSAGE_TYPES.CONTINUE_WITHOUT_SAVED_DETAILS:
|
|
3484
|
-
if (typeof record.contact !== "string" || typeof record.contactType !== "string") return null;
|
|
3485
|
-
break;
|
|
3486
|
-
case MESSAGE_TYPES.ERROR:
|
|
3487
|
-
if (typeof record.code !== "string" || typeof record.message !== "string") return null;
|
|
3488
|
-
break;
|
|
3489
|
-
case MESSAGE_TYPES.CHECKOUT_COMPLETE:
|
|
3490
|
-
if (typeof record.success !== "boolean") return null;
|
|
3491
|
-
break;
|
|
3492
|
-
case MESSAGE_TYPES.CHECKOUT_STATUS:
|
|
3493
|
-
if (typeof record.status !== "string" || !record.context || typeof record.context !== "object")
|
|
3494
|
-
return null;
|
|
3495
|
-
break;
|
|
3496
|
-
case MESSAGE_TYPES.TERMS_CHANGED:
|
|
3497
|
-
if (typeof record.intent_id !== "string" || !record.replacement || typeof record.replacement !== "object" || !Array.isArray(record.deltas))
|
|
3498
|
-
return null;
|
|
3499
|
-
break;
|
|
3500
|
-
case MESSAGE_TYPES.SELECTION_UNAVAILABLE:
|
|
3501
|
-
if (typeof record.intent_id !== "string" || !Array.isArray(record.lines)) return null;
|
|
3502
|
-
break;
|
|
3503
|
-
case MESSAGE_TYPES.READY:
|
|
3504
|
-
case MESSAGE_TYPES.HEIGHT_CHANGE:
|
|
3505
|
-
if (typeof record.height !== "number") return null;
|
|
3506
|
-
break;
|
|
3507
|
-
case MESSAGE_TYPES.ORDER_TYPE_CHANGED:
|
|
3508
|
-
if (typeof record.orderType !== "string") return null;
|
|
3509
|
-
break;
|
|
3510
|
-
}
|
|
3511
|
-
return data;
|
|
3512
|
-
}
|
|
3513
|
-
var CimplifyElements = class {
|
|
3514
|
-
constructor(client, businessId, options = {}) {
|
|
3515
|
-
this.elements = /* @__PURE__ */ new Map();
|
|
3516
|
-
this.accessToken = null;
|
|
3517
|
-
this.accountId = null;
|
|
3518
|
-
this.customerId = null;
|
|
3519
|
-
this.customerData = null;
|
|
3520
|
-
this.addressData = null;
|
|
3521
|
-
this.paymentData = null;
|
|
3522
|
-
this.checkoutInProgress = false;
|
|
3523
|
-
this.authInProgress = false;
|
|
3524
|
-
this.authGeneration = 0;
|
|
3525
|
-
this.activeCheckoutAbort = null;
|
|
3526
|
-
this.businessIdResolvePromise = null;
|
|
3527
|
-
this.stopSessionSync = () => {
|
|
3528
|
-
};
|
|
3529
|
-
this.client = client;
|
|
3530
|
-
this.businessId = businessId ?? null;
|
|
3531
|
-
this.linkUrl = options.linkUrl || DEFAULT_LINK_URL;
|
|
3532
|
-
this.options = options;
|
|
3533
|
-
this.boundHandleMessage = this.handleMessage.bind(this);
|
|
3534
|
-
if (typeof window !== "undefined") {
|
|
3535
|
-
window.addEventListener("message", this.boundHandleMessage);
|
|
3536
|
-
}
|
|
3537
|
-
this.stopSessionSync = client.events.on(SESSION_CLAIMED, () => {
|
|
3538
|
-
if (!this.authInProgress) this._syncHostSession();
|
|
3539
|
-
});
|
|
3540
|
-
void this.restoreSession();
|
|
3541
|
-
}
|
|
3542
|
-
debug(...args) {
|
|
3543
|
-
if (this.client.isTestMode()) {
|
|
3544
|
-
console.debug(...args);
|
|
3545
|
-
}
|
|
3546
|
-
}
|
|
3547
|
-
_syncHostSession(element) {
|
|
3548
|
-
const sessionToken = this.client.getSessionToken();
|
|
3549
|
-
if (!sessionToken) return;
|
|
3550
|
-
const identity = {
|
|
3551
|
-
type: MESSAGE_TYPES.IDENTITY,
|
|
3552
|
-
sessionToken,
|
|
3553
|
-
accessToken: this.client.getAccessToken() ?? this.accessToken,
|
|
3554
|
-
customer: this.identityCustomer()
|
|
3555
|
-
};
|
|
3556
|
-
const targets = element ? [element] : Array.from(this.elements.values());
|
|
3557
|
-
for (const target of targets) {
|
|
3558
|
-
target.sendMessage(identity);
|
|
3559
|
-
}
|
|
3560
|
-
}
|
|
3561
|
-
identityCustomer() {
|
|
3562
|
-
if (!this.accessToken || !this.customerId || !this.customerData) return null;
|
|
3563
|
-
return { id: this.customerId, ...this.customerData };
|
|
3564
|
-
}
|
|
3565
|
-
create(type, options = {}) {
|
|
3566
|
-
const existing = this.elements.get(type);
|
|
3567
|
-
if (existing) return existing;
|
|
3568
|
-
const element = new CimplifyElement(type, this.businessId, this.linkUrl, options, this);
|
|
3569
|
-
this.elements.set(type, element);
|
|
3570
|
-
return element;
|
|
3571
|
-
}
|
|
3572
|
-
getElement(type) {
|
|
3573
|
-
return this.elements.get(type);
|
|
3574
|
-
}
|
|
3575
|
-
_removeElement(type, instance) {
|
|
3576
|
-
const current = this.elements.get(type);
|
|
3577
|
-
if (current === instance) {
|
|
3578
|
-
this.elements.delete(type);
|
|
3579
|
-
}
|
|
3580
|
-
}
|
|
3581
|
-
destroy() {
|
|
3582
|
-
this.authGeneration += 1;
|
|
3583
|
-
this.authInProgress = false;
|
|
3584
|
-
this.stopSessionSync();
|
|
3585
|
-
this.stopSessionSync = () => {
|
|
3586
|
-
};
|
|
3587
|
-
this.elements.forEach((element) => element.destroy());
|
|
3588
|
-
this.elements.clear();
|
|
3589
|
-
if (typeof window !== "undefined") {
|
|
3590
|
-
window.removeEventListener("message", this.boundHandleMessage);
|
|
3591
|
-
}
|
|
3592
|
-
}
|
|
3593
|
-
async submitCheckout(data) {
|
|
3594
|
-
const result = await this.processCheckout({
|
|
3595
|
-
cart_id: data.cart_id,
|
|
3596
|
-
intent_id: data.intent_id,
|
|
3597
|
-
hosted_session_id: data.hosted_session_id,
|
|
3598
|
-
initial_terms: data.initial_terms,
|
|
3599
|
-
order_type: data.order_type ?? chunkEV2EVOYS_js.ORDER_TYPE.DELIVERY,
|
|
3600
|
-
location_id: data.location_id,
|
|
3601
|
-
notes: data.notes,
|
|
3602
|
-
scheduled_time: data.scheduled_time,
|
|
3603
|
-
tip_amount: data.tip_amount,
|
|
3604
|
-
enroll_in_link: true
|
|
3605
|
-
});
|
|
3606
|
-
if (result.success) {
|
|
3607
|
-
return {
|
|
3608
|
-
success: true,
|
|
3609
|
-
order: {
|
|
3610
|
-
id: result.order?.id || "",
|
|
3611
|
-
status: result.order?.status || chunkEV2EVOYS_js.CHECKOUT_ORDER_RESULT_STATUS.UNKNOWN,
|
|
3612
|
-
total: result.order?.total || ""
|
|
3613
|
-
}
|
|
3614
|
-
};
|
|
3615
|
-
}
|
|
3616
|
-
return {
|
|
3617
|
-
success: false,
|
|
3618
|
-
error: {
|
|
3619
|
-
code: result.error?.code || chunkANT574FD_js.ErrorCode.CHECKOUT_FAILED,
|
|
3620
|
-
message: result.error?.message || "Checkout failed"
|
|
3621
|
-
}
|
|
3622
|
-
};
|
|
3623
|
-
}
|
|
3624
|
-
processCheckout(options) {
|
|
3625
|
-
let abortFn = null;
|
|
3626
|
-
const task = (async () => {
|
|
3627
|
-
this.debug("[cimplify:checkout] processCheckout called", {
|
|
3628
|
-
cart_id: options.cart_id,
|
|
3629
|
-
intent_id: options.intent_id,
|
|
3630
|
-
hosted_session_id: options.hosted_session_id,
|
|
3631
|
-
order_type: options.order_type,
|
|
3632
|
-
location_id: options.location_id
|
|
3633
|
-
});
|
|
3634
|
-
if (this.checkoutInProgress) {
|
|
3635
|
-
this.debug("[cimplify:checkout] BLOCKED: already processing");
|
|
3636
|
-
return toCheckoutError(
|
|
3637
|
-
chunkANT574FD_js.ErrorCode.ALREADY_PROCESSING,
|
|
3638
|
-
"Checkout is already in progress.",
|
|
3639
|
-
false
|
|
3640
|
-
);
|
|
3641
|
-
}
|
|
3642
|
-
this.checkoutInProgress = true;
|
|
3643
|
-
if (!options.cart_id && !options.intent_id) {
|
|
3644
|
-
this.debug("[cimplify:checkout] BLOCKED: no cart_id or intent_id");
|
|
3645
|
-
this.checkoutInProgress = false;
|
|
3646
|
-
return toCheckoutError(
|
|
3647
|
-
chunkANT574FD_js.ErrorCode.CHECKOUT_AUTHORITY_REQUIRED,
|
|
3648
|
-
"A cart or existing purchase intent is required before checkout can start.",
|
|
3649
|
-
false
|
|
3650
|
-
);
|
|
3651
|
-
}
|
|
3652
|
-
if (!options.order_type) {
|
|
3653
|
-
this.debug("[cimplify:checkout] BLOCKED: no order_type");
|
|
3654
|
-
this.checkoutInProgress = false;
|
|
3655
|
-
return toCheckoutError(
|
|
3656
|
-
chunkANT574FD_js.ErrorCode.ORDER_TYPE_REQUIRED,
|
|
3657
|
-
"Order type is required before checkout can start.",
|
|
3658
|
-
false
|
|
3659
|
-
);
|
|
3660
|
-
}
|
|
3661
|
-
const checkoutElement = this.elements.get(ELEMENT_TYPES.CHECKOUT) || this.elements.get(ELEMENT_TYPES.PAYMENT);
|
|
3662
|
-
if (!checkoutElement) {
|
|
3663
|
-
this.debug("[cimplify:checkout] BLOCKED: no checkout element");
|
|
3664
|
-
this.checkoutInProgress = false;
|
|
3665
|
-
return toCheckoutError(
|
|
3666
|
-
chunkANT574FD_js.ErrorCode.NO_PAYMENT_ELEMENT,
|
|
3667
|
-
"Checkout element must be mounted before checkout.",
|
|
3668
|
-
false
|
|
3669
|
-
);
|
|
3670
|
-
}
|
|
3671
|
-
if (!checkoutElement.isMounted()) {
|
|
3672
|
-
this.debug("[cimplify:checkout] BLOCKED: checkout element not mounted");
|
|
3673
|
-
this.checkoutInProgress = false;
|
|
3674
|
-
return toCheckoutError(
|
|
3675
|
-
chunkANT574FD_js.ErrorCode.PAYMENT_NOT_MOUNTED,
|
|
3676
|
-
"Checkout element must be mounted before checkout.",
|
|
3677
|
-
false
|
|
3678
|
-
);
|
|
3679
|
-
}
|
|
3680
|
-
const isUnifiedCheckout = this.elements.has(ELEMENT_TYPES.CHECKOUT);
|
|
3681
|
-
if (!isUnifiedCheckout) {
|
|
3682
|
-
const authElement = this.elements.get(ELEMENT_TYPES.AUTH);
|
|
3683
|
-
if (authElement && !this.accessToken) {
|
|
3684
|
-
this.debug("[cimplify:checkout] BLOCKED: auth incomplete");
|
|
3685
|
-
this.checkoutInProgress = false;
|
|
3686
|
-
return toCheckoutError(
|
|
3687
|
-
chunkANT574FD_js.ErrorCode.AUTH_INCOMPLETE,
|
|
3688
|
-
"Authentication must complete before checkout can start.",
|
|
3689
|
-
true
|
|
3690
|
-
);
|
|
3691
|
-
}
|
|
3692
|
-
const addressElement = this.elements.get(ELEMENT_TYPES.ADDRESS);
|
|
3693
|
-
if (addressElement) {
|
|
3694
|
-
this.debug("[cimplify:checkout] getting address data...");
|
|
3695
|
-
await addressElement.getData();
|
|
3696
|
-
this.debug("[cimplify:checkout] address data resolved", this.addressData);
|
|
3697
|
-
}
|
|
3698
|
-
await this.hydrateCustomerData();
|
|
3699
|
-
}
|
|
3700
|
-
this.debug("[cimplify:checkout] customer data hydrated", {
|
|
3701
|
-
customerData: this.customerData,
|
|
3702
|
-
accountId: this.accountId,
|
|
3703
|
-
isUnifiedCheckout
|
|
3704
|
-
});
|
|
3705
|
-
const processMessage = {
|
|
3706
|
-
type: MESSAGE_TYPES.PROCESS_CHECKOUT,
|
|
3707
|
-
// Existing intent authority wins if a compatibility caller supplied
|
|
3708
|
-
// both values; the iframe must never mint a replacement.
|
|
3709
|
-
cart_id: options.intent_id ? void 0 : options.cart_id,
|
|
3710
|
-
intent_id: options.intent_id,
|
|
3711
|
-
hosted_session_id: options.hosted_session_id,
|
|
3712
|
-
initial_terms: options.intent_id ? options.initial_terms : void 0,
|
|
3713
|
-
order_type: options.order_type,
|
|
3714
|
-
location_id: options.location_id,
|
|
3715
|
-
notes: options.notes,
|
|
3716
|
-
scheduled_time: options.scheduled_time,
|
|
3717
|
-
tip_amount: options.tip_amount,
|
|
3718
|
-
pay_currency: options.pay_currency,
|
|
3719
|
-
enroll_in_link: options.enroll_in_link ?? true,
|
|
3720
|
-
address: isUnifiedCheckout ? void 0 : this.addressData ?? void 0,
|
|
3721
|
-
customer: isUnifiedCheckout ? void 0 : this.customerData ? {
|
|
3722
|
-
name: this.customerData.name,
|
|
3723
|
-
email: this.customerData.email,
|
|
3724
|
-
phone: this.customerData.phone
|
|
3725
|
-
} : null,
|
|
3726
|
-
account_id: this.accountId ?? void 0,
|
|
3727
|
-
customer_id: this.customerId ?? void 0
|
|
3728
|
-
};
|
|
3729
|
-
const inactivityTimeoutMs = options.timeout_ms ?? 18e4;
|
|
3730
|
-
const shopperPendingStatuses = /* @__PURE__ */ new Set([
|
|
3731
|
-
chunkEV2EVOYS_js.CHECKOUT_STATUS.REVIEWING_TERMS,
|
|
3732
|
-
chunkEV2EVOYS_js.CHECKOUT_STATUS.AWAITING_AUTHORIZATION
|
|
3733
|
-
]);
|
|
3734
|
-
return new Promise((resolve) => {
|
|
3735
|
-
let settled = false;
|
|
3736
|
-
let timeout;
|
|
3737
|
-
const cleanup = () => {
|
|
3738
|
-
if (typeof window !== "undefined") {
|
|
3739
|
-
window.removeEventListener("message", handleCheckoutMessage);
|
|
3740
|
-
}
|
|
3741
|
-
clearTimeout(timeout);
|
|
3742
|
-
this.checkoutInProgress = false;
|
|
3743
|
-
this.activeCheckoutAbort = null;
|
|
3744
|
-
};
|
|
3745
|
-
const settle = (result) => {
|
|
3746
|
-
if (settled) {
|
|
3747
|
-
return;
|
|
3748
|
-
}
|
|
3749
|
-
settled = true;
|
|
3750
|
-
cleanup();
|
|
3751
|
-
resolve(result);
|
|
3752
|
-
};
|
|
3753
|
-
const armTimeout = () => {
|
|
3754
|
-
clearTimeout(timeout);
|
|
3755
|
-
timeout = setTimeout(() => {
|
|
3756
|
-
settle(
|
|
3757
|
-
toCheckoutError(
|
|
3758
|
-
chunkANT574FD_js.ErrorCode.TIMEOUT,
|
|
3759
|
-
"Checkout timed out before receiving a terminal response.",
|
|
3760
|
-
true
|
|
3761
|
-
)
|
|
3762
|
-
);
|
|
3763
|
-
}, inactivityTimeoutMs);
|
|
3764
|
-
};
|
|
3765
|
-
const suspendTimeout = () => {
|
|
3766
|
-
clearTimeout(timeout);
|
|
3767
|
-
timeout = void 0;
|
|
3768
|
-
};
|
|
3769
|
-
armTimeout();
|
|
3770
|
-
const handleCheckoutMessage = (event) => {
|
|
3771
|
-
if (!isAllowedOrigin(event.origin)) {
|
|
3772
|
-
return;
|
|
3773
|
-
}
|
|
3774
|
-
const message = parseIframeMessage(event.data);
|
|
3775
|
-
if (!message) {
|
|
3776
|
-
return;
|
|
3777
|
-
}
|
|
3778
|
-
if (!checkoutElement._acceptsMessageEvent(event, message)) {
|
|
3779
|
-
return;
|
|
3780
|
-
}
|
|
3781
|
-
if (message.type === MESSAGE_TYPES.CHECKOUT_STATUS) {
|
|
3782
|
-
if (shopperPendingStatuses.has(message.status)) {
|
|
3783
|
-
suspendTimeout();
|
|
3784
|
-
} else {
|
|
3785
|
-
armTimeout();
|
|
3786
|
-
}
|
|
3787
|
-
options.on_status_change?.(message.status, message.context);
|
|
3788
|
-
return;
|
|
3789
|
-
}
|
|
3790
|
-
if (message.type === MESSAGE_TYPES.TERMS_CHANGED) {
|
|
3791
|
-
suspendTimeout();
|
|
3792
|
-
options.on_status_change?.(chunkEV2EVOYS_js.CHECKOUT_STATUS.REVIEWING_TERMS, {
|
|
3793
|
-
intent_id: message.intent_id,
|
|
3794
|
-
replacement_terms: message.replacement,
|
|
3795
|
-
terms_deltas: message.deltas
|
|
3796
|
-
});
|
|
3797
|
-
return;
|
|
3798
|
-
}
|
|
3799
|
-
if (message.type === MESSAGE_TYPES.SELECTION_UNAVAILABLE) {
|
|
3800
|
-
suspendTimeout();
|
|
3801
|
-
options.on_status_change?.(chunkEV2EVOYS_js.CHECKOUT_STATUS.REVIEWING_TERMS, {
|
|
3802
|
-
intent_id: message.intent_id,
|
|
3803
|
-
unavailable_lines: message.lines
|
|
3804
|
-
});
|
|
3805
|
-
return;
|
|
3806
|
-
}
|
|
3807
|
-
if (message.type === MESSAGE_TYPES.CHECKOUT_COMPLETE) {
|
|
3808
|
-
this.debug("[cimplify:checkout] received checkout_complete", {
|
|
3809
|
-
success: message.success,
|
|
3810
|
-
error: message.error
|
|
3811
|
-
});
|
|
3812
|
-
settle({
|
|
3813
|
-
success: message.success,
|
|
3814
|
-
order: message.order,
|
|
3815
|
-
error: message.error,
|
|
3816
|
-
enrolled_in_link: message.enrolled_in_link
|
|
3817
|
-
});
|
|
3818
|
-
}
|
|
3819
|
-
if (message.type === MESSAGE_TYPES.LOGOUT_COMPLETE) {
|
|
3820
|
-
checkoutElement.sendMessage({ type: MESSAGE_TYPES.ABORT_CHECKOUT });
|
|
3821
|
-
settle(
|
|
3822
|
-
toCheckoutError(
|
|
3823
|
-
chunkANT574FD_js.ErrorCode.AUTH_LOST,
|
|
3824
|
-
"Authentication was cleared during checkout.",
|
|
3825
|
-
true
|
|
3826
|
-
)
|
|
3827
|
-
);
|
|
3828
|
-
}
|
|
3829
|
-
};
|
|
3830
|
-
if (typeof window !== "undefined") {
|
|
3831
|
-
window.addEventListener("message", handleCheckoutMessage);
|
|
3832
|
-
}
|
|
3833
|
-
abortFn = () => {
|
|
3834
|
-
checkoutElement.sendMessage({ type: MESSAGE_TYPES.ABORT_CHECKOUT });
|
|
3835
|
-
settle(toCheckoutError(chunkANT574FD_js.ErrorCode.CANCELLED, "Checkout was cancelled.", true));
|
|
3836
|
-
};
|
|
3837
|
-
this.activeCheckoutAbort = abortFn;
|
|
3838
|
-
this.debug("[cimplify:checkout] sending process_checkout to checkout iframe", {
|
|
3839
|
-
cart_id: processMessage.cart_id,
|
|
3840
|
-
intent_id: processMessage.intent_id,
|
|
3841
|
-
hosted_session_id: processMessage.hosted_session_id,
|
|
3842
|
-
order_type: processMessage.order_type,
|
|
3843
|
-
hasCustomer: !!processMessage.customer,
|
|
3844
|
-
hasAddress: !!processMessage.address,
|
|
3845
|
-
isUnifiedCheckout
|
|
3846
|
-
});
|
|
3847
|
-
this._syncHostSession(checkoutElement);
|
|
3848
|
-
checkoutElement.sendMessage(processMessage);
|
|
3849
|
-
this.debug("[cimplify:checkout] postMessage sent, waiting for checkout_complete...");
|
|
3850
|
-
});
|
|
3851
|
-
})();
|
|
3852
|
-
const abortable = task;
|
|
3853
|
-
abortable.abort = () => {
|
|
3854
|
-
if (abortFn) {
|
|
3855
|
-
abortFn();
|
|
3856
|
-
}
|
|
3857
|
-
};
|
|
3858
|
-
return abortable;
|
|
3859
|
-
}
|
|
3860
|
-
isAuthenticated() {
|
|
3861
|
-
return this.accessToken !== null;
|
|
3862
|
-
}
|
|
3863
|
-
getAccessToken() {
|
|
3864
|
-
return this.accessToken;
|
|
3865
|
-
}
|
|
3866
|
-
getPublicKey() {
|
|
3867
|
-
return this.client.getPublicKey();
|
|
3868
|
-
}
|
|
3869
|
-
getSessionToken() {
|
|
3870
|
-
return this.client.getSessionToken();
|
|
3871
|
-
}
|
|
3872
|
-
getBusinessId() {
|
|
3873
|
-
return this.businessId;
|
|
3874
|
-
}
|
|
3875
|
-
async resolveBusinessId() {
|
|
3876
|
-
if (this.businessId) {
|
|
3877
|
-
return this.businessId;
|
|
3878
|
-
}
|
|
3879
|
-
if (this.businessIdResolvePromise) {
|
|
3880
|
-
return this.businessIdResolvePromise;
|
|
3881
|
-
}
|
|
3882
|
-
this.businessIdResolvePromise = this.client.resolveBusinessId().then((resolvedBusinessId) => {
|
|
3883
|
-
this.businessId = resolvedBusinessId;
|
|
3884
|
-
return resolvedBusinessId;
|
|
3885
|
-
}).catch(() => null).finally(() => {
|
|
3886
|
-
this.businessIdResolvePromise = null;
|
|
3887
|
-
});
|
|
3888
|
-
return this.businessIdResolvePromise;
|
|
3889
|
-
}
|
|
3890
|
-
getAppearance() {
|
|
3891
|
-
return this.options.appearance;
|
|
3892
|
-
}
|
|
3893
|
-
isAuthGenerationCurrent(generation, token) {
|
|
3894
|
-
return this.authGeneration === generation && this.client.getAccessToken() === token;
|
|
3895
|
-
}
|
|
3896
|
-
async hydrateCustomerData(generation = this.authGeneration, token = this.accessToken, force = false) {
|
|
3897
|
-
if (!token || !this.isAuthGenerationCurrent(generation, token)) return false;
|
|
3898
|
-
if (this.customerData && !force) return true;
|
|
3899
|
-
const linkDataResult = await this.client.link.getLinkData();
|
|
3900
|
-
if (!this.isAuthGenerationCurrent(generation, token)) return false;
|
|
3901
|
-
if (!linkDataResult.ok || !linkDataResult.value?.customer) {
|
|
3902
|
-
return true;
|
|
3903
|
-
}
|
|
3904
|
-
const customer = linkDataResult.value.customer;
|
|
3905
|
-
this.customerData = {
|
|
3906
|
-
name: customer.name || "",
|
|
3907
|
-
email: customer.email || null,
|
|
3908
|
-
phone: customer.phone || null
|
|
3909
|
-
};
|
|
3910
|
-
this.customerId = customer.id;
|
|
3911
|
-
return true;
|
|
3912
|
-
}
|
|
3913
|
-
sourceElementFor(event, message) {
|
|
3914
|
-
for (const element of this.elements.values()) {
|
|
3915
|
-
if (element._acceptsMessageEvent(event, message)) {
|
|
3916
|
-
return element;
|
|
3917
|
-
}
|
|
3918
|
-
}
|
|
3919
|
-
return null;
|
|
3920
|
-
}
|
|
3921
|
-
// Refresh token kept first-party (keyed by public key) so a signed-in shopper
|
|
3922
|
-
// survives reloads. Standard SPA tradeoff; far safer than the third-party
|
|
3923
|
-
// iframe, whose storage/cookies are partitioned or blocked.
|
|
3924
|
-
sessionStorageKey() {
|
|
3925
|
-
const key = this.client.getPublicKey().trim();
|
|
3926
|
-
return key ? `cimplify.link.rt.${key}` : null;
|
|
3927
|
-
}
|
|
3928
|
-
persistRefreshToken(refreshToken) {
|
|
3929
|
-
if (typeof window === "undefined") return;
|
|
3930
|
-
const storageKey = this.sessionStorageKey();
|
|
3931
|
-
if (!storageKey) return;
|
|
3932
|
-
try {
|
|
3933
|
-
if (refreshToken) {
|
|
3934
|
-
window.localStorage.setItem(storageKey, refreshToken);
|
|
3935
|
-
} else {
|
|
3936
|
-
window.localStorage.removeItem(storageKey);
|
|
3937
|
-
}
|
|
3938
|
-
} catch {
|
|
3939
|
-
}
|
|
3940
|
-
}
|
|
3941
|
-
clearPersistedSession() {
|
|
3942
|
-
if (typeof window === "undefined") return;
|
|
3943
|
-
const storageKey = this.sessionStorageKey();
|
|
3944
|
-
if (!storageKey) return;
|
|
3945
|
-
try {
|
|
3946
|
-
window.localStorage.removeItem(storageKey);
|
|
3947
|
-
} catch {
|
|
3948
|
-
}
|
|
3949
|
-
}
|
|
3950
|
-
clearClaimedAuthorityAfterRestoreFailure() {
|
|
3951
|
-
if (!this.client.getAccessToken() && !this.client.hasClaimedSessionAuthority()) return;
|
|
3952
|
-
this.accessToken = null;
|
|
3953
|
-
this.accountId = null;
|
|
3954
|
-
this.customerId = null;
|
|
3955
|
-
this.customerData = null;
|
|
3956
|
-
this.addressData = null;
|
|
3957
|
-
this.paymentData = null;
|
|
3958
|
-
this.client.clearSession();
|
|
3959
|
-
this.broadcastClearedSession();
|
|
3960
|
-
}
|
|
3961
|
-
async restoreSession() {
|
|
3962
|
-
if (typeof window === "undefined" || this.accessToken) return;
|
|
3963
|
-
const generation = ++this.authGeneration;
|
|
3964
|
-
const storageKey = this.sessionStorageKey();
|
|
3965
|
-
if (!storageKey) return;
|
|
3966
|
-
let refreshToken = null;
|
|
3967
|
-
try {
|
|
3968
|
-
refreshToken = window.localStorage.getItem(storageKey);
|
|
3969
|
-
} catch {
|
|
3970
|
-
this.clearClaimedAuthorityAfterRestoreFailure();
|
|
3971
|
-
return;
|
|
3972
|
-
}
|
|
3973
|
-
if (!refreshToken) {
|
|
3974
|
-
this.clearClaimedAuthorityAfterRestoreFailure();
|
|
3975
|
-
return;
|
|
3976
|
-
}
|
|
3977
|
-
const result = await this.client.link.refreshSession(refreshToken, {
|
|
3978
|
-
activateSession: false
|
|
3979
|
-
});
|
|
3980
|
-
if (this.authGeneration !== generation) return;
|
|
3981
|
-
if (!result.ok || !result.value.session_token) {
|
|
3982
|
-
this.clearPersistedSession();
|
|
3983
|
-
this.clearClaimedAuthorityAfterRestoreFailure();
|
|
3984
|
-
return;
|
|
3985
|
-
}
|
|
3986
|
-
this.persistRefreshToken(result.value.refresh_token ?? void 0);
|
|
3987
|
-
const application = await this.applyAccessToken(result.value.session_token, generation);
|
|
3988
|
-
if (application.kind === "claim_failed") {
|
|
3989
|
-
this.clearPersistedSession();
|
|
3990
|
-
this.broadcastClearedSession();
|
|
3991
|
-
return;
|
|
3992
|
-
}
|
|
3993
|
-
if (application.kind !== "authenticated") return;
|
|
3994
|
-
this._syncHostSession();
|
|
3995
|
-
this.elements.forEach((element) => element._emitAuthenticated(application.data));
|
|
3996
|
-
}
|
|
3997
|
-
async applyAccessToken(token, generation) {
|
|
3998
|
-
if (this.authGeneration !== generation) return { kind: "incomplete" };
|
|
3999
|
-
this.accessToken = null;
|
|
4000
|
-
this.accountId = null;
|
|
4001
|
-
this.customerId = null;
|
|
4002
|
-
this.customerData = null;
|
|
4003
|
-
this.addressData = null;
|
|
4004
|
-
this.paymentData = null;
|
|
4005
|
-
this.client.setAccessToken(token);
|
|
4006
|
-
const claim = await this.client.session.claim();
|
|
4007
|
-
if (!this.isAuthGenerationCurrent(generation, token)) return { kind: "incomplete" };
|
|
4008
|
-
if (!claim.ok && claim.error.code !== "already_claimed") {
|
|
4009
|
-
if (this.client.hasClaimedSessionAuthority()) {
|
|
4010
|
-
this.client.clearSession();
|
|
4011
|
-
} else {
|
|
4012
|
-
this.client.setAccessToken(null);
|
|
4013
|
-
}
|
|
4014
|
-
return {
|
|
4015
|
-
kind: "claim_failed",
|
|
4016
|
-
code: claim.error.code,
|
|
4017
|
-
message: claim.error.userMessage
|
|
4018
|
-
};
|
|
4019
|
-
}
|
|
4020
|
-
this.accessToken = token;
|
|
4021
|
-
this.accountId = decodeJwtSub(token);
|
|
4022
|
-
if (!await this.hydrateCustomerData(generation, token, true)) {
|
|
4023
|
-
return { kind: "incomplete" };
|
|
4024
|
-
}
|
|
4025
|
-
if (!this.isAuthGenerationCurrent(generation, token)) return { kind: "incomplete" };
|
|
4026
|
-
return {
|
|
4027
|
-
kind: "authenticated",
|
|
4028
|
-
data: {
|
|
4029
|
-
accountId: this.accountId ?? "",
|
|
4030
|
-
customerId: this.customerId ?? "",
|
|
4031
|
-
token,
|
|
4032
|
-
customer: this.customerData ?? { name: "", email: null, phone: null }
|
|
4033
|
-
}
|
|
4034
|
-
};
|
|
4035
|
-
}
|
|
4036
|
-
adoptEstablishedSession(sourceElement, session) {
|
|
4037
|
-
this.authGeneration += 1;
|
|
4038
|
-
this.authInProgress = false;
|
|
4039
|
-
const { id, ...customer } = session.customer;
|
|
4040
|
-
this.accessToken = session.accessToken;
|
|
4041
|
-
this.accountId = decodeJwtSub(session.accessToken);
|
|
4042
|
-
this.customerId = id;
|
|
4043
|
-
this.customerData = customer;
|
|
4044
|
-
this.addressData = null;
|
|
4045
|
-
this.paymentData = null;
|
|
4046
|
-
this.client.setAccessToken(session.accessToken);
|
|
4047
|
-
this.persistRefreshToken(session.refreshToken);
|
|
4048
|
-
this.client.session.adopt(session.accessToken, {
|
|
4049
|
-
sessionToken: session.sessionToken,
|
|
4050
|
-
customerName: session.customer.name,
|
|
4051
|
-
customer: session.customer,
|
|
4052
|
-
cart: null
|
|
4053
|
-
});
|
|
4054
|
-
sourceElement._emitAuthenticated({
|
|
4055
|
-
accountId: this.accountId,
|
|
4056
|
-
customerId: id,
|
|
4057
|
-
token: session.accessToken,
|
|
4058
|
-
customer
|
|
4059
|
-
});
|
|
4060
|
-
}
|
|
4061
|
-
broadcastClearedSession() {
|
|
4062
|
-
const sessionToken = this.client.getSessionToken();
|
|
4063
|
-
if (!sessionToken) return null;
|
|
4064
|
-
this.elements.forEach((element) => {
|
|
4065
|
-
element.sendMessage({ type: MESSAGE_TYPES.SESSION_CLEARED, sessionToken });
|
|
4066
|
-
});
|
|
4067
|
-
return sessionToken;
|
|
4068
|
-
}
|
|
4069
|
-
startEmbeddedAuth(sourceElement, request) {
|
|
4070
|
-
if (this.authInProgress) return;
|
|
4071
|
-
const auth = this.options.auth ?? {};
|
|
4072
|
-
const clientId = auth.clientId ?? readPublicEnv("NEXT_PUBLIC_CIMPLIFY_CLIENT_ID");
|
|
4073
|
-
const redirectUri = auth.redirectUri ?? readPublicEnv("NEXT_PUBLIC_CIMPLIFY_REDIRECT_URI");
|
|
4074
|
-
if (!clientId || !redirectUri) {
|
|
4075
|
-
sourceElement._emitError({
|
|
4076
|
-
code: chunkANT574FD_js.ErrorCode.AUTH_CONFIG_REQUIRED,
|
|
4077
|
-
message: "Cimplify OAuth clientId and redirectUri are required."
|
|
4078
|
-
});
|
|
4079
|
-
return;
|
|
4080
|
-
}
|
|
4081
|
-
const generation = ++this.authGeneration;
|
|
4082
|
-
this.authInProgress = true;
|
|
4083
|
-
void startSignIn({
|
|
4084
|
-
clientId,
|
|
4085
|
-
redirectUri,
|
|
4086
|
-
callbackUri: auth.callbackUri,
|
|
4087
|
-
scope: auth.scope,
|
|
4088
|
-
issuer: auth.issuer,
|
|
4089
|
-
authUrl: auth.authUrl,
|
|
4090
|
-
loginHint: request.loginHint,
|
|
4091
|
-
prompt: request.prompt,
|
|
4092
|
-
uiMode: request.mode,
|
|
4093
|
-
mode: "modal",
|
|
4094
|
-
silentFirst: request.mode === ELEMENTS_AUTH_MODES.CHECKOUT && request.prompt !== ELEMENTS_AUTH_PROMPTS.LOGIN,
|
|
4095
|
-
onSuccess: async ({ accessToken }) => {
|
|
4096
|
-
if (this.authGeneration !== generation) return;
|
|
4097
|
-
this.authInProgress = false;
|
|
4098
|
-
if (!accessToken) {
|
|
4099
|
-
sourceElement._emitError({
|
|
4100
|
-
code: chunkANT574FD_js.ErrorCode.AUTH_CALLBACK_MISSING_TOKEN,
|
|
4101
|
-
message: "Sign-in callback did not return an access token."
|
|
4102
|
-
});
|
|
4103
|
-
return;
|
|
4104
|
-
}
|
|
4105
|
-
const application = await this.applyAccessToken(accessToken, generation);
|
|
4106
|
-
if (application.kind === "authenticated") {
|
|
4107
|
-
this._syncHostSession();
|
|
4108
|
-
sourceElement._emitAuthenticated(application.data);
|
|
4109
|
-
} else if (application.kind === "claim_failed") {
|
|
4110
|
-
sourceElement._emitError({
|
|
4111
|
-
code: application.code,
|
|
4112
|
-
message: application.message
|
|
4113
|
-
});
|
|
4114
|
-
}
|
|
4115
|
-
},
|
|
4116
|
-
onError: (err2) => {
|
|
4117
|
-
if (this.authGeneration !== generation) return;
|
|
4118
|
-
this.authInProgress = false;
|
|
4119
|
-
sourceElement._emitError({
|
|
4120
|
-
code: err2.error,
|
|
4121
|
-
message: err2.description ?? err2.error
|
|
4122
|
-
});
|
|
4123
|
-
}
|
|
4124
|
-
}).catch((error) => {
|
|
4125
|
-
if (this.authGeneration !== generation) return;
|
|
4126
|
-
this.authInProgress = false;
|
|
4127
|
-
sourceElement._emitError({
|
|
4128
|
-
code: chunkANT574FD_js.ErrorCode.AUTH_START_FAILED,
|
|
4129
|
-
message: error instanceof Error ? error.message : "Unable to start sign-in."
|
|
4130
|
-
});
|
|
4131
|
-
});
|
|
4132
|
-
}
|
|
4133
|
-
handleMessage(event) {
|
|
4134
|
-
if (!isAllowedOrigin(event.origin)) {
|
|
4135
|
-
return;
|
|
4136
|
-
}
|
|
4137
|
-
const message = parseIframeMessage(event.data);
|
|
4138
|
-
if (!message) return;
|
|
4139
|
-
const sourceElement = this.sourceElementFor(event, message);
|
|
4140
|
-
if (!sourceElement) return;
|
|
4141
|
-
switch (message.type) {
|
|
4142
|
-
case MESSAGE_TYPES.AUTH_REQUESTED:
|
|
4143
|
-
this.startEmbeddedAuth(sourceElement, message);
|
|
4144
|
-
break;
|
|
4145
|
-
case MESSAGE_TYPES.SESSION_ESTABLISHED:
|
|
4146
|
-
this.adoptEstablishedSession(sourceElement, message);
|
|
4147
|
-
break;
|
|
4148
|
-
case MESSAGE_TYPES.ADDRESS_CHANGED:
|
|
4149
|
-
case MESSAGE_TYPES.ADDRESS_SELECTED:
|
|
4150
|
-
this.addressData = message.address;
|
|
4151
|
-
break;
|
|
4152
|
-
case MESSAGE_TYPES.PAYMENT_METHOD_SELECTED:
|
|
4153
|
-
this.paymentData = message.method;
|
|
4154
|
-
break;
|
|
4155
|
-
case MESSAGE_TYPES.CONTACT_PROVIDED:
|
|
4156
|
-
if (!this.customerData) {
|
|
4157
|
-
this.customerData = { name: "", email: null, phone: null };
|
|
4158
|
-
}
|
|
4159
|
-
if (message.contactType === ELEMENTS_AUTH_CONTACT_TYPES.EMAIL) {
|
|
4160
|
-
this.customerData.email = message.contact;
|
|
4161
|
-
} else {
|
|
4162
|
-
this.customerData.phone = message.contact;
|
|
4163
|
-
}
|
|
4164
|
-
break;
|
|
4165
|
-
case MESSAGE_TYPES.CONTINUE_WITHOUT_SAVED_DETAILS: {
|
|
4166
|
-
this.authGeneration += 1;
|
|
4167
|
-
this.authInProgress = false;
|
|
4168
|
-
const carriedIdentityAuthority = Boolean(this.client.getAccessToken()) || this.client.hasClaimedSessionAuthority();
|
|
4169
|
-
this.accessToken = null;
|
|
4170
|
-
this.accountId = null;
|
|
4171
|
-
this.customerId = null;
|
|
4172
|
-
this.customerData = { name: "", email: null, phone: null };
|
|
4173
|
-
this.addressData = null;
|
|
4174
|
-
this.paymentData = null;
|
|
4175
|
-
this.clearPersistedSession();
|
|
4176
|
-
if (carriedIdentityAuthority) {
|
|
4177
|
-
this.client.clearSession();
|
|
4178
|
-
} else {
|
|
4179
|
-
this.client.setAccessToken(null);
|
|
4180
|
-
}
|
|
4181
|
-
this.broadcastClearedSession();
|
|
4182
|
-
if (message.contactType === ELEMENTS_AUTH_CONTACT_TYPES.EMAIL) {
|
|
4183
|
-
this.customerData.email = message.contact;
|
|
4184
|
-
} else {
|
|
4185
|
-
this.customerData.phone = message.contact;
|
|
4186
|
-
}
|
|
4187
|
-
break;
|
|
4188
|
-
}
|
|
4189
|
-
case MESSAGE_TYPES.LOGOUT_COMPLETE:
|
|
4190
|
-
this.authGeneration += 1;
|
|
4191
|
-
this.authInProgress = false;
|
|
4192
|
-
if (this.checkoutInProgress && this.activeCheckoutAbort) {
|
|
4193
|
-
this.activeCheckoutAbort();
|
|
4194
|
-
}
|
|
4195
|
-
this.accessToken = null;
|
|
4196
|
-
this.accountId = null;
|
|
4197
|
-
this.customerId = null;
|
|
4198
|
-
this.customerData = null;
|
|
4199
|
-
this.addressData = null;
|
|
4200
|
-
this.paymentData = null;
|
|
4201
|
-
this.clearPersistedSession();
|
|
4202
|
-
this.client.clearSession();
|
|
4203
|
-
this.broadcastClearedSession();
|
|
4204
|
-
break;
|
|
4205
|
-
}
|
|
4206
|
-
}
|
|
4207
|
-
_setAddressData(data) {
|
|
4208
|
-
this.addressData = data;
|
|
4209
|
-
}
|
|
4210
|
-
_setPaymentData(data) {
|
|
4211
|
-
this.paymentData = data;
|
|
4212
|
-
}
|
|
4213
|
-
_setGuestContact(contact, contactType) {
|
|
4214
|
-
if (!this.customerData) {
|
|
4215
|
-
this.customerData = { name: "", email: null, phone: null };
|
|
4216
|
-
}
|
|
4217
|
-
if (contactType === ELEMENTS_AUTH_CONTACT_TYPES.EMAIL) {
|
|
4218
|
-
this.customerData.email = contact;
|
|
4219
|
-
} else {
|
|
4220
|
-
this.customerData.phone = contact;
|
|
4221
|
-
}
|
|
4222
|
-
}
|
|
4223
|
-
};
|
|
4224
|
-
var CimplifyElement = class {
|
|
4225
|
-
constructor(type, businessId, linkUrl, options, parent) {
|
|
4226
|
-
this.iframe = null;
|
|
4227
|
-
this.container = null;
|
|
4228
|
-
this.mounted = false;
|
|
4229
|
-
this.ready = false;
|
|
4230
|
-
this.pendingMessages = [];
|
|
4231
|
-
this.pendingInit = null;
|
|
4232
|
-
this.eventHandlers = /* @__PURE__ */ new Map();
|
|
4233
|
-
this.resolvers = /* @__PURE__ */ new Map();
|
|
4234
|
-
this.lastReportedHeight = 0;
|
|
4235
|
-
this.listening = false;
|
|
4236
|
-
this.type = type;
|
|
4237
|
-
this.businessId = businessId;
|
|
4238
|
-
this.linkUrl = linkUrl;
|
|
4239
|
-
this.options = options;
|
|
4240
|
-
this.parent = parent;
|
|
4241
|
-
this.nonce = generateNonce();
|
|
4242
|
-
this.boundHandleMessage = this.handleMessage.bind(this);
|
|
4243
|
-
this.boundHandleResize = () => this.applyHeight();
|
|
4244
|
-
if (typeof window !== "undefined") {
|
|
4245
|
-
window.addEventListener("message", this.boundHandleMessage);
|
|
4246
|
-
window.addEventListener("resize", this.boundHandleResize);
|
|
4247
|
-
this.listening = true;
|
|
4248
|
-
}
|
|
4249
|
-
}
|
|
4250
|
-
/**
|
|
4251
|
-
* Size the iframe to the element's reported content height (in pixels). We do
|
|
4252
|
-
* NOT cap checkout at the viewport: capping forced a tall checkout to scroll
|
|
4253
|
-
* *inside* a viewport-height iframe — a nested scroll-within-scroll. Sizing to
|
|
4254
|
-
* content lets the iframe grow and the host page scroll naturally as one
|
|
4255
|
-
* surface, which is the standard embedded-checkout behaviour.
|
|
4256
|
-
*/
|
|
4257
|
-
applyHeight(reportedHeight) {
|
|
4258
|
-
if (!this.iframe) return;
|
|
4259
|
-
if (typeof reportedHeight === "number" && reportedHeight > 0) {
|
|
4260
|
-
this.lastReportedHeight = reportedHeight;
|
|
4261
|
-
}
|
|
4262
|
-
const content = this.lastReportedHeight;
|
|
4263
|
-
if (!content) return;
|
|
4264
|
-
this.iframe.style.height = `${Math.max(320, content)}px`;
|
|
4265
|
-
}
|
|
4266
|
-
mount(container) {
|
|
4267
|
-
if (this.mounted) {
|
|
4268
|
-
console.warn(`Element ${this.type} is already mounted`);
|
|
4269
|
-
return;
|
|
4270
|
-
}
|
|
4271
|
-
const target = typeof container === "string" ? document.querySelector(container) : container;
|
|
4272
|
-
if (!target) {
|
|
4273
|
-
console.error(`Container not found: ${container}`);
|
|
4274
|
-
return;
|
|
4275
|
-
}
|
|
4276
|
-
this.container = target;
|
|
4277
|
-
this.mounted = true;
|
|
4278
|
-
if (!this.listening && typeof window !== "undefined") {
|
|
4279
|
-
window.addEventListener("message", this.boundHandleMessage);
|
|
4280
|
-
this.listening = true;
|
|
4281
|
-
}
|
|
4282
|
-
void this.createIframe();
|
|
4283
|
-
}
|
|
4284
|
-
destroy() {
|
|
4285
|
-
if (this.iframe) {
|
|
4286
|
-
this.iframe.remove();
|
|
4287
|
-
this.iframe = null;
|
|
4288
|
-
}
|
|
4289
|
-
this.container = null;
|
|
4290
|
-
this.mounted = false;
|
|
4291
|
-
this.ready = false;
|
|
4292
|
-
this.pendingMessages = [];
|
|
4293
|
-
this.eventHandlers.clear();
|
|
4294
|
-
this.resolvers.forEach((entry) => clearTimeout(entry.timeoutId));
|
|
4295
|
-
this.resolvers.clear();
|
|
4296
|
-
if (this.listening && typeof window !== "undefined") {
|
|
4297
|
-
window.removeEventListener("message", this.boundHandleMessage);
|
|
4298
|
-
window.removeEventListener("resize", this.boundHandleResize);
|
|
4299
|
-
this.listening = false;
|
|
4300
|
-
}
|
|
4301
|
-
this.parent._removeElement(this.type, this);
|
|
4302
|
-
}
|
|
4303
|
-
on(event, handler) {
|
|
4304
|
-
if (!this.eventHandlers.has(event)) {
|
|
4305
|
-
this.eventHandlers.set(event, /* @__PURE__ */ new Set());
|
|
4306
|
-
}
|
|
4307
|
-
this.eventHandlers.get(event).add(handler);
|
|
4308
|
-
}
|
|
4309
|
-
off(event, handler) {
|
|
4310
|
-
this.eventHandlers.get(event)?.delete(handler);
|
|
4311
|
-
}
|
|
4312
|
-
async getData() {
|
|
4313
|
-
if (!this.isMounted()) {
|
|
4314
|
-
return null;
|
|
4315
|
-
}
|
|
4316
|
-
return new Promise((resolve) => {
|
|
4317
|
-
const id = Math.random().toString(36).slice(2);
|
|
4318
|
-
const timeoutId = setTimeout(() => {
|
|
4319
|
-
const entry = this.resolvers.get(id);
|
|
4320
|
-
if (!entry) {
|
|
4321
|
-
return;
|
|
4322
|
-
}
|
|
4323
|
-
this.resolvers.delete(id);
|
|
4324
|
-
entry.resolve(null);
|
|
4325
|
-
}, 5e3);
|
|
4326
|
-
this.resolvers.set(id, { resolve, timeoutId });
|
|
4327
|
-
this.sendMessage({ type: MESSAGE_TYPES.GET_DATA });
|
|
4328
|
-
});
|
|
4329
|
-
}
|
|
4330
|
-
setCart(cart) {
|
|
4331
|
-
this.sendMessage({ type: MESSAGE_TYPES.SET_CART, cart });
|
|
4332
|
-
}
|
|
4333
|
-
sendMessage(message) {
|
|
4334
|
-
const iframe = this.iframe;
|
|
4335
|
-
if (!iframe || !iframe.isConnected) {
|
|
4336
|
-
if (iframe && !iframe.isConnected) {
|
|
4337
|
-
console.warn("[cimplify:checkout] sendMessage DROPPED \u2014 iframe detached", {
|
|
4338
|
-
type: message.type
|
|
4339
|
-
});
|
|
4340
|
-
}
|
|
4341
|
-
return;
|
|
4342
|
-
}
|
|
4343
|
-
if (!this.ready || !iframe.contentWindow) {
|
|
4344
|
-
this.pendingMessages.push(message);
|
|
4345
|
-
return;
|
|
4346
|
-
}
|
|
4347
|
-
iframe.contentWindow.postMessage(message, this.linkUrl);
|
|
4348
|
-
}
|
|
4349
|
-
flushPending() {
|
|
4350
|
-
if (!this.ready || !this.iframe?.contentWindow) return;
|
|
4351
|
-
const queue = this.pendingMessages;
|
|
4352
|
-
this.pendingMessages = [];
|
|
4353
|
-
for (const message of queue) {
|
|
4354
|
-
this.iframe.contentWindow.postMessage(message, this.linkUrl);
|
|
4355
|
-
}
|
|
4356
|
-
}
|
|
4357
|
-
getContentWindow() {
|
|
4358
|
-
return this.iframe?.contentWindow ?? null;
|
|
4359
|
-
}
|
|
4360
|
-
isMounted() {
|
|
4361
|
-
return this.mounted && Boolean(this.iframe) && this.iframe?.isConnected === true;
|
|
4362
|
-
}
|
|
4363
|
-
_acceptsMessageEvent(event, message) {
|
|
4364
|
-
const iframeWindow = this.iframe?.contentWindow;
|
|
4365
|
-
if (!iframeWindow || event.source !== iframeWindow) return false;
|
|
4366
|
-
return message.nonce === this.nonce;
|
|
4367
|
-
}
|
|
4368
|
-
_emitAuthenticated(data) {
|
|
4369
|
-
this.emit(EVENT_TYPES.AUTHENTICATED, data);
|
|
4370
|
-
}
|
|
4371
|
-
_emitError(error) {
|
|
4372
|
-
this.emit(EVENT_TYPES.ERROR, error);
|
|
4373
|
-
}
|
|
4374
|
-
async createIframe() {
|
|
4375
|
-
if (!this.container) return;
|
|
4376
|
-
const resolvedBusinessId = this.businessId ?? await this.parent.resolveBusinessId();
|
|
4377
|
-
if (!resolvedBusinessId || !this.container || !this.mounted) {
|
|
4378
|
-
console.error("Unable to mount element without a resolved business ID");
|
|
4379
|
-
this.emit(EVENT_TYPES.ERROR, {
|
|
4380
|
-
code: chunkANT574FD_js.ErrorCode.BUSINESS_ID_REQUIRED,
|
|
4381
|
-
message: "Unable to initialize checkout without a business ID."
|
|
4382
|
-
});
|
|
4383
|
-
return;
|
|
4384
|
-
}
|
|
4385
|
-
this.businessId = resolvedBusinessId;
|
|
4386
|
-
const iframe = document.createElement("iframe");
|
|
4387
|
-
const url = new URL(`${this.linkUrl}/elements/${this.type}`);
|
|
4388
|
-
url.searchParams.set("businessId", resolvedBusinessId);
|
|
4389
|
-
url.searchParams.set("nonce", this.nonce);
|
|
4390
|
-
if (this.options.prefillEmail) url.searchParams.set("email", this.options.prefillEmail);
|
|
4391
|
-
if (this.options.mode) url.searchParams.set("mode", this.options.mode);
|
|
4392
|
-
iframe.src = url.toString();
|
|
4393
|
-
iframe.style.border = "none";
|
|
4394
|
-
iframe.style.width = "100%";
|
|
4395
|
-
iframe.style.minHeight = "200px";
|
|
4396
|
-
iframe.style.display = "block";
|
|
4397
|
-
iframe.style.overflow = "hidden";
|
|
4398
|
-
iframe.style.background = "transparent";
|
|
4399
|
-
iframe.setAttribute("allowtransparency", "true");
|
|
4400
|
-
iframe.setAttribute("frameborder", "0");
|
|
4401
|
-
iframe.setAttribute("allow", "geolocation");
|
|
4402
|
-
iframe.setAttribute(
|
|
4403
|
-
"sandbox",
|
|
4404
|
-
"allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox"
|
|
4405
|
-
);
|
|
4406
|
-
this.iframe = iframe;
|
|
4407
|
-
this.container.appendChild(iframe);
|
|
4408
|
-
this.pendingInit = {
|
|
4409
|
-
businessId: resolvedBusinessId,
|
|
4410
|
-
publicKey: this.parent.getPublicKey()
|
|
4411
|
-
};
|
|
4412
|
-
}
|
|
4413
|
-
handleMessage(event) {
|
|
4414
|
-
if (!isAllowedOrigin(event.origin)) {
|
|
4415
|
-
return;
|
|
4416
|
-
}
|
|
4417
|
-
const message = parseIframeMessage(event.data);
|
|
4418
|
-
if (!message) return;
|
|
4419
|
-
if (!this._acceptsMessageEvent(event, message)) return;
|
|
4420
|
-
switch (message.type) {
|
|
4421
|
-
case MESSAGE_TYPES.READY:
|
|
4422
|
-
this.ready = true;
|
|
4423
|
-
if (message.height) this.applyHeight(message.height);
|
|
4424
|
-
if (this.pendingInit) {
|
|
4425
|
-
const { publicKey } = this.pendingInit;
|
|
4426
|
-
this.sendMessage({
|
|
4427
|
-
type: MESSAGE_TYPES.INIT,
|
|
4428
|
-
businessId: this.pendingInit.businessId,
|
|
4429
|
-
publicKey,
|
|
4430
|
-
prefillEmail: this.options.prefillEmail,
|
|
4431
|
-
appearance: this.parent.getAppearance(),
|
|
4432
|
-
orderTypes: this.options.orderTypes,
|
|
4433
|
-
defaultOrderType: this.options.defaultOrderType,
|
|
4434
|
-
renderSubmitButton: true,
|
|
4435
|
-
submitLabel: this.options.submitLabel,
|
|
4436
|
-
intentId: this.options.intentId,
|
|
4437
|
-
hostedSessionId: this.options.hostedSessionId,
|
|
4438
|
-
initialTerms: this.options.initialTerms
|
|
4439
|
-
});
|
|
4440
|
-
this.parent._syncHostSession(this);
|
|
4441
|
-
this.pendingInit = null;
|
|
4442
|
-
}
|
|
4443
|
-
this.flushPending();
|
|
4444
|
-
this.emit(EVENT_TYPES.READY, { height: message.height });
|
|
4445
|
-
break;
|
|
4446
|
-
case MESSAGE_TYPES.HEIGHT_CHANGE:
|
|
4447
|
-
this.applyHeight(message.height);
|
|
4448
|
-
break;
|
|
4449
|
-
case MESSAGE_TYPES.ERROR:
|
|
4450
|
-
this.emit(EVENT_TYPES.ERROR, { code: message.code, message: message.message });
|
|
4451
|
-
break;
|
|
4452
|
-
case MESSAGE_TYPES.ADDRESS_CHANGED:
|
|
4453
|
-
case MESSAGE_TYPES.ADDRESS_SELECTED:
|
|
4454
|
-
this.parent._setAddressData(message.address);
|
|
4455
|
-
this.emit(EVENT_TYPES.CHANGE, { address: message.address });
|
|
4456
|
-
this.resolveData(message.address);
|
|
4457
|
-
break;
|
|
4458
|
-
case MESSAGE_TYPES.PAYMENT_METHOD_SELECTED:
|
|
4459
|
-
this.parent._setPaymentData(message.method);
|
|
4460
|
-
this.emit(EVENT_TYPES.CHANGE, { paymentMethod: message.method });
|
|
4461
|
-
this.resolveData(message.method);
|
|
4462
|
-
break;
|
|
4463
|
-
case MESSAGE_TYPES.CONTACT_PROVIDED:
|
|
4464
|
-
this.parent._setGuestContact(message.contact, message.contactType);
|
|
4465
|
-
break;
|
|
4466
|
-
case MESSAGE_TYPES.ORDER_TYPE_CHANGED:
|
|
4467
|
-
this.emit(EVENT_TYPES.ORDER_TYPE_CHANGED, { orderType: message.orderType });
|
|
4468
|
-
break;
|
|
4469
|
-
case MESSAGE_TYPES.REQUEST_SUBMIT:
|
|
4470
|
-
this.emit(EVENT_TYPES.REQUEST_SUBMIT, {});
|
|
4471
|
-
break;
|
|
4472
|
-
}
|
|
4473
|
-
}
|
|
4474
|
-
emit(event, data) {
|
|
4475
|
-
this.eventHandlers.get(event)?.forEach((handler) => handler(data));
|
|
4476
|
-
}
|
|
4477
|
-
resolveData(data) {
|
|
4478
|
-
this.resolvers.forEach((entry) => {
|
|
4479
|
-
clearTimeout(entry.timeoutId);
|
|
4480
|
-
entry.resolve(data);
|
|
4481
|
-
});
|
|
4482
|
-
this.resolvers.clear();
|
|
4483
|
-
}
|
|
4484
|
-
};
|
|
4485
|
-
function createElements(client, businessId, options) {
|
|
4486
|
-
return new CimplifyElements(client, businessId, options);
|
|
4487
|
-
}
|
|
4488
|
-
|
|
4489
|
-
exports.AUTH_TOKEN_CHANGED = AUTH_TOKEN_CHANGED;
|
|
4490
|
-
exports.AuthService = AuthService;
|
|
4491
|
-
exports.BusinessService = BusinessService;
|
|
4492
|
-
exports.CartOperations = CartOperations;
|
|
4493
|
-
exports.CatalogueQueries = CatalogueQueries;
|
|
4494
|
-
exports.CheckoutService = CheckoutService;
|
|
4495
|
-
exports.CimplifyElement = CimplifyElement;
|
|
4496
|
-
exports.CimplifyElements = CimplifyElements;
|
|
4497
|
-
exports.DEFAULT_ISSUER = DEFAULT_ISSUER;
|
|
4498
|
-
exports.ELEMENTS_AUTH_CONTACT_TYPES = ELEMENTS_AUTH_CONTACT_TYPES;
|
|
4499
|
-
exports.ELEMENTS_AUTH_MODES = ELEMENTS_AUTH_MODES;
|
|
4500
|
-
exports.ELEMENTS_AUTH_PROMPTS = ELEMENTS_AUTH_PROMPTS;
|
|
4501
|
-
exports.ELEMENT_TYPES = ELEMENT_TYPES;
|
|
4502
|
-
exports.EVENT_TYPES = EVENT_TYPES;
|
|
4503
|
-
exports.FxService = FxService;
|
|
4504
|
-
exports.InventoryService = InventoryService;
|
|
4505
|
-
exports.LinkService = LinkService;
|
|
4506
|
-
exports.LiteService = LiteService;
|
|
4507
|
-
exports.MESSAGE_TYPES = MESSAGE_TYPES;
|
|
4508
|
-
exports.MUTATION_ERROR = MUTATION_ERROR;
|
|
4509
|
-
exports.OrderQueries = OrderQueries;
|
|
4510
|
-
exports.PAYMENT_AUTHORIZATION_OUTCOME_STATUS = PAYMENT_AUTHORIZATION_OUTCOME_STATUS;
|
|
4511
|
-
exports.PAYMENT_AUTHORIZATION_PROVIDER = PAYMENT_AUTHORIZATION_PROVIDER;
|
|
4512
|
-
exports.PKCE_COOKIE = PKCE_COOKIE;
|
|
4513
|
-
exports.PKCE_COOKIE_PATH = PKCE_COOKIE_PATH;
|
|
4514
|
-
exports.PaymentAuthorizationAdapterRegistry = PaymentAuthorizationAdapterRegistry;
|
|
4515
|
-
exports.PaystackAuthorizationAdapter = PaystackAuthorizationAdapter;
|
|
4516
|
-
exports.SESSION_CLAIMED = SESSION_CLAIMED;
|
|
4517
|
-
exports.SESSION_CLEARED = SESSION_CLEARED;
|
|
4518
|
-
exports.SchedulingService = SchedulingService;
|
|
4519
|
-
exports.StripeAuthorizationAdapter = StripeAuthorizationAdapter;
|
|
4520
|
-
exports.clearIntentIdempotencyKey = clearIntentIdempotencyKey;
|
|
4521
|
-
exports.combine = combine;
|
|
4522
|
-
exports.combineObject = combineObject;
|
|
4523
|
-
exports.confirmationForUnchangedReplacement = confirmationForUnchangedReplacement;
|
|
4524
|
-
exports.createClientEvents = createClientEvents;
|
|
4525
|
-
exports.createDefaultPaymentAuthorizationAdapterRegistry = createDefaultPaymentAuthorizationAdapterRegistry;
|
|
4526
|
-
exports.createElements = createElements;
|
|
4527
|
-
exports.createPurchaseIntentConfirmation = createPurchaseIntentConfirmation;
|
|
4528
|
-
exports.decodePkceState = decodePkceState;
|
|
4529
|
-
exports.err = err;
|
|
4530
|
-
exports.flatMap = flatMap;
|
|
4531
|
-
exports.fromPromise = fromPromise;
|
|
4532
|
-
exports.generateIdempotencyKey = generateIdempotencyKey;
|
|
4533
|
-
exports.generatePkce = generatePkce;
|
|
4534
|
-
exports.generateState = generateState;
|
|
4535
|
-
exports.getAuthorizationEndpoint = getAuthorizationEndpoint;
|
|
4536
|
-
exports.getOrElse = getOrElse;
|
|
4537
|
-
exports.intentIdempotencyKey = intentIdempotencyKey;
|
|
4538
|
-
exports.isErr = isErr;
|
|
4539
|
-
exports.isOk = isOk;
|
|
4540
|
-
exports.mapError = mapError;
|
|
4541
|
-
exports.mapResult = mapResult;
|
|
4542
|
-
exports.ok = ok;
|
|
4543
|
-
exports.purchaseIntentRequiresPaymentOption = purchaseIntentRequiresPaymentOption;
|
|
4544
|
-
exports.safe = safe;
|
|
4545
|
-
exports.selectPurchaseIntentPaymentOption = selectPurchaseIntentPaymentOption;
|
|
4546
|
-
exports.startSignIn = startSignIn;
|
|
4547
|
-
exports.toNullable = toNullable;
|
|
4548
|
-
exports.tryCatch = tryCatch;
|
|
4549
|
-
exports.unwrap = unwrap;
|