@salla.sa/twilight-components 2.14.507 → 2.14.509

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. package/dist/cjs/catalog-recommendations-dtK9Dlfw.js +97 -0
  2. package/dist/cjs/{filepond-CvJ5cEog.js → filepond-Dn8WkI9_.js} +1 -1
  3. package/dist/cjs/{filepond-plugin-file-poster-BaTGVcva.js → filepond-plugin-file-poster-mufjzLbD.js} +1 -1
  4. package/dist/cjs/{filepond-plugin-file-validate-size-DLrFHUWL.js → filepond-plugin-file-validate-size-BC6t5UPj.js} +1 -1
  5. package/dist/cjs/{filepond-plugin-file-validate-type-BU1HIA61.js → filepond-plugin-file-validate-type-CaQ5Kqok.js} +1 -1
  6. package/dist/cjs/{filepond-plugin-image-edit-CF5DJ9dM.js → filepond-plugin-image-edit-DvSmfnUl.js} +1 -1
  7. package/dist/cjs/{filepond-plugin-image-exif-orientation-DLrU2VJ-.js → filepond-plugin-image-exif-orientation-Br5ovpCW.js} +1 -1
  8. package/dist/cjs/{filepond-plugin-image-preview-D_3BTg6j.js → filepond-plugin-image-preview-C71ogaak.js} +1 -1
  9. package/dist/cjs/{functions-Chjqknfu.js → functions-DgFPxTJv.js} +1 -1
  10. package/dist/cjs/{index-DDEOCBF1.js → index-CeEhEVDJ.js} +6 -6
  11. package/dist/cjs/{index-D4085yXe.js → index-DHuZTkix.js} +1 -1
  12. package/dist/cjs/loader.cjs.js +2 -2
  13. package/dist/cjs/salla-accordion-body_2.cjs.entry.js +1 -1
  14. package/dist/cjs/salla-accordion_6.cjs.entry.js +1 -1
  15. package/dist/cjs/salla-add-product-button_5.cjs.entry.js +2 -2
  16. package/dist/cjs/salla-advertisement.cjs.entry.js +1 -1
  17. package/dist/cjs/salla-alert_2.cjs.entry.js +1 -1
  18. package/dist/cjs/salla-app-install-alert.cjs.entry.js +1 -1
  19. package/dist/cjs/salla-apps-icons.cjs.entry.js +1 -1
  20. package/dist/cjs/salla-badge.cjs.entry.js +1 -1
  21. package/dist/cjs/salla-basket-gap.cjs.entry.js +2 -2
  22. package/dist/cjs/salla-booking-field_7.cjs.entry.js +10 -10
  23. package/dist/cjs/salla-bullet-delivery_2.cjs.entry.js +1 -1
  24. package/dist/cjs/salla-cart-coupons.cjs.entry.js +1 -1
  25. package/dist/cjs/salla-cart-item-offers_2.cjs.entry.js +1 -1
  26. package/dist/cjs/salla-cart-summary-card.cjs.entry.js +1 -1
  27. package/dist/cjs/salla-cashback-banner.cjs.entry.js +1 -1
  28. package/dist/cjs/salla-comment-factors.cjs.entry.js +2 -2
  29. package/dist/cjs/salla-comment-form_8.cjs.entry.js +12 -17
  30. package/dist/cjs/salla-conditional-offer.cjs.entry.js +1 -1
  31. package/dist/cjs/salla-contacts.cjs.entry.js +1 -1
  32. package/dist/cjs/salla-cookies-bar.cjs.entry.js +1 -1
  33. package/dist/cjs/salla-count-down_2.cjs.entry.js +1 -1
  34. package/dist/cjs/salla-custom-fields.cjs.entry.js +1 -1
  35. package/dist/cjs/salla-delivery-promise.cjs.entry.js +1 -1
  36. package/dist/cjs/salla-edit-order-button.cjs.entry.js +1 -1
  37. package/dist/cjs/salla-filters-widget.cjs.entry.js +1 -1
  38. package/dist/cjs/salla-filters.cjs.entry.js +1 -1
  39. package/dist/cjs/salla-fulfillment-methods.cjs.entry.js +1 -1
  40. package/dist/cjs/salla-gifting.cjs.entry.js +1 -1
  41. package/dist/cjs/salla-hook.cjs.entry.js +1 -1
  42. package/dist/cjs/salla-infinite-scroll.cjs.entry.js +1 -1
  43. package/dist/cjs/salla-installment.cjs.entry.js +1 -1
  44. package/dist/cjs/salla-list-tile.cjs.entry.js +1 -1
  45. package/dist/cjs/salla-localization-modal.cjs.entry.js +1 -1
  46. package/dist/cjs/salla-login-modal.cjs.entry.js +1 -1
  47. package/dist/cjs/salla-loyalty-banner.cjs.entry.js +2 -2
  48. package/dist/cjs/salla-loyalty-exchange-product-card_5.cjs.entry.js +3 -3
  49. package/dist/cjs/salla-loyalty-hero_2.cjs.entry.js +2 -2
  50. package/dist/cjs/salla-loyalty-panel.cjs.entry.js +3 -3
  51. package/dist/cjs/salla-loyalty-points-banner.cjs.entry.js +1 -1
  52. package/dist/cjs/salla-loyalty-points-history.cjs.entry.js +1 -1
  53. package/dist/cjs/salla-loyalty-prize-item.cjs.entry.js +1 -1
  54. package/dist/cjs/salla-loyalty-program.cjs.entry.js +3 -3
  55. package/dist/cjs/salla-loyalty-reward.cjs.entry.js +2 -2
  56. package/dist/cjs/salla-loyalty.cjs.entry.js +1 -1
  57. package/dist/cjs/salla-maintenance-alert.cjs.entry.js +1 -1
  58. package/dist/cjs/salla-map_2.cjs.entry.js +1 -1
  59. package/dist/cjs/salla-menu.cjs.entry.js +1 -1
  60. package/dist/cjs/salla-metadata.cjs.entry.js +1 -1
  61. package/dist/cjs/salla-multiple-bundle-product-cart_2.cjs.entry.js +1 -1
  62. package/dist/cjs/salla-multiple-bundle-product-options-modal_2.cjs.entry.js +1 -1
  63. package/dist/cjs/salla-multiple-bundle-product.cjs.entry.js +1 -1
  64. package/dist/cjs/salla-next-order-coupon.cjs.entry.js +1 -1
  65. package/dist/cjs/salla-notification-item.cjs.entry.js +1 -1
  66. package/dist/cjs/salla-notifications.cjs.entry.js +1 -1
  67. package/dist/cjs/salla-offer-modal.cjs.entry.js +1 -1
  68. package/dist/cjs/salla-offer.cjs.entry.js +1 -1
  69. package/dist/cjs/salla-order-branch.cjs.entry.js +1 -1
  70. package/dist/cjs/salla-order-cancel.cjs.entry.js +1 -1
  71. package/dist/cjs/salla-order-details-multiple-bundle-product.cjs.entry.js +1 -1
  72. package/dist/cjs/salla-order-details-options.cjs.entry.js +1 -1
  73. package/dist/cjs/salla-order-details.cjs.entry.js +1 -1
  74. package/dist/cjs/salla-order-edit-item.cjs.entry.js +1 -1
  75. package/dist/cjs/salla-order-edit-product-card.cjs.entry.js +1 -1
  76. package/dist/cjs/salla-order-edit.cjs.entry.js +1 -1
  77. package/dist/cjs/salla-order-summary.cjs.entry.js +1 -1
  78. package/dist/cjs/salla-order-totals-card.cjs.entry.js +1 -1
  79. package/dist/cjs/salla-orders.cjs.entry.js +1 -1
  80. package/dist/cjs/salla-payments.cjs.entry.js +1 -1
  81. package/dist/cjs/salla-placeholder.cjs.entry.js +1 -1
  82. package/dist/cjs/salla-price-range.cjs.entry.js +1 -1
  83. package/dist/cjs/salla-product-card-embed.cjs.entry.js +1 -1
  84. package/dist/cjs/salla-product-card_2.cjs.entry.js +1 -1
  85. package/dist/cjs/salla-product-size-guide.cjs.entry.js +1 -1
  86. package/dist/cjs/salla-products-list.cjs.entry.js +1 -1
  87. package/dist/cjs/salla-quick-order.cjs.entry.js +1 -1
  88. package/dist/cjs/salla-rating-modal-v2.cjs.entry.js +1 -1
  89. package/dist/cjs/salla-rating-modal.cjs.entry.js +1 -1
  90. package/dist/cjs/salla-review-factors-tags.cjs.entry.js +28 -8
  91. package/dist/cjs/salla-scopes.cjs.entry.js +1 -1
  92. package/dist/cjs/salla-search.cjs.entry.js +1 -1
  93. package/dist/cjs/salla-skeleton.cjs.entry.js +1 -1
  94. package/dist/cjs/salla-slider.cjs.entry.js +1 -1
  95. package/dist/cjs/salla-social-share.cjs.entry.js +10 -3
  96. package/dist/cjs/salla-social.cjs.entry.js +1 -1
  97. package/dist/cjs/salla-tab-content_3.cjs.entry.js +1 -1
  98. package/dist/cjs/salla-tiered-offer.cjs.entry.js +1 -1
  99. package/dist/cjs/salla-tooltip.cjs.entry.js +1 -1
  100. package/dist/cjs/salla-trust-badges.cjs.entry.js +1 -1
  101. package/dist/cjs/salla-user-menu.cjs.entry.js +1 -1
  102. package/dist/cjs/salla-user-profile.cjs.entry.js +1 -1
  103. package/dist/cjs/salla-user-settings.cjs.entry.js +1 -1
  104. package/dist/cjs/salla-verify.cjs.entry.js +1 -1
  105. package/dist/cjs/salla-wallet.cjs.entry.js +1 -1
  106. package/dist/cjs/salla-wishlist-actions.cjs.entry.js +1 -1
  107. package/dist/cjs/{tracked-promise-C69FwhCX.js → tracked-promise-DDnavSzb.js} +1 -1
  108. package/dist/cjs/twilight.cjs.js +2 -2
  109. package/dist/cjs/{vanilla-picker-BDDWkkNu.js → vanilla-picker-CyrLIKBL.js} +1 -1
  110. package/dist/collection/components/salla-comments/salla-comments.css +2 -5
  111. package/dist/collection/components/salla-comments/salla-comments.js +6 -3
  112. package/dist/collection/components/salla-review-factors-tags/salla-review-factors-tags.css +7 -3
  113. package/dist/collection/components/salla-review-factors-tags/salla-review-factors-tags.js +64 -9
  114. package/dist/collection/components/salla-reviews-summary/salla-reviews-summary.css +15 -31
  115. package/dist/collection/components/salla-reviews-summary/salla-reviews-summary.js +2 -11
  116. package/dist/collection/components/salla-social-share/salla-social-share.js +9 -2
  117. package/dist/collection/shared/catalog-recommendations.js +47 -41
  118. package/dist/components/catalog-recommendations.js +47 -41
  119. package/dist/components/index.js +2 -2
  120. package/dist/components/salla-comment-factors2.js +1 -1
  121. package/dist/components/salla-comment-item2.js +1 -1
  122. package/dist/components/salla-comments.js +29 -20
  123. package/dist/components/salla-review-factors-tags.js +1 -141
  124. package/dist/components/salla-review-factors-tags2.js +173 -0
  125. package/dist/components/salla-reviews-summary2.js +13 -16
  126. package/dist/components/salla-social-share2.js +9 -2
  127. package/dist/esm/catalog-recommendations-CL7OPpYS.js +94 -0
  128. package/dist/esm/{filepond-BfxOWgeR.js → filepond-Cu0hGP46.js} +1 -1
  129. package/dist/esm/{filepond-plugin-file-poster-Dt5Vnuk4.js → filepond-plugin-file-poster-DBfLrjkx.js} +1 -1
  130. package/dist/esm/{filepond-plugin-file-validate-size-D5WrsM0T.js → filepond-plugin-file-validate-size-Cq0e60aE.js} +1 -1
  131. package/dist/esm/{filepond-plugin-file-validate-type-CjaeW32q.js → filepond-plugin-file-validate-type-CpRmNAFC.js} +1 -1
  132. package/dist/esm/{filepond-plugin-image-edit-BTzFile_.js → filepond-plugin-image-edit-C-7yhkPK.js} +1 -1
  133. package/dist/esm/{filepond-plugin-image-exif-orientation-DSNjqS_v.js → filepond-plugin-image-exif-orientation-CTn5LeXC.js} +1 -1
  134. package/dist/esm/{filepond-plugin-image-preview-CCGiOVLr.js → filepond-plugin-image-preview-BsETbqVf.js} +1 -1
  135. package/dist/esm/{functions-D05iBLQe.js → functions-DtC2lEvS.js} +1 -1
  136. package/dist/esm/{index-DpTbeb50.js → index-BEjZOd--.js} +6 -6
  137. package/dist/esm/{index-BTUirq4N.js → index-DskkoO4T.js} +1 -1
  138. package/dist/esm/loader.js +3 -3
  139. package/dist/esm/salla-accordion-body_2.entry.js +1 -1
  140. package/dist/esm/salla-accordion_6.entry.js +1 -1
  141. package/dist/esm/salla-add-product-button_5.entry.js +2 -2
  142. package/dist/esm/salla-advertisement.entry.js +1 -1
  143. package/dist/esm/salla-alert_2.entry.js +1 -1
  144. package/dist/esm/salla-app-install-alert.entry.js +1 -1
  145. package/dist/esm/salla-apps-icons.entry.js +1 -1
  146. package/dist/esm/salla-badge.entry.js +1 -1
  147. package/dist/esm/salla-basket-gap.entry.js +2 -2
  148. package/dist/esm/salla-booking-field_7.entry.js +10 -10
  149. package/dist/esm/salla-bullet-delivery_2.entry.js +1 -1
  150. package/dist/esm/salla-cart-coupons.entry.js +1 -1
  151. package/dist/esm/salla-cart-item-offers_2.entry.js +1 -1
  152. package/dist/esm/salla-cart-summary-card.entry.js +1 -1
  153. package/dist/esm/salla-cashback-banner.entry.js +1 -1
  154. package/dist/esm/salla-comment-factors.entry.js +2 -2
  155. package/dist/esm/salla-comment-form_8.entry.js +12 -17
  156. package/dist/esm/salla-conditional-offer.entry.js +1 -1
  157. package/dist/esm/salla-contacts.entry.js +1 -1
  158. package/dist/esm/salla-cookies-bar.entry.js +1 -1
  159. package/dist/esm/salla-count-down_2.entry.js +1 -1
  160. package/dist/esm/salla-custom-fields.entry.js +1 -1
  161. package/dist/esm/salla-delivery-promise.entry.js +1 -1
  162. package/dist/esm/salla-edit-order-button.entry.js +1 -1
  163. package/dist/esm/salla-filters-widget.entry.js +1 -1
  164. package/dist/esm/salla-filters.entry.js +1 -1
  165. package/dist/esm/salla-fulfillment-methods.entry.js +1 -1
  166. package/dist/esm/salla-gifting.entry.js +1 -1
  167. package/dist/esm/salla-hook.entry.js +1 -1
  168. package/dist/esm/salla-infinite-scroll.entry.js +1 -1
  169. package/dist/esm/salla-installment.entry.js +1 -1
  170. package/dist/esm/salla-list-tile.entry.js +1 -1
  171. package/dist/esm/salla-localization-modal.entry.js +1 -1
  172. package/dist/esm/salla-login-modal.entry.js +1 -1
  173. package/dist/esm/salla-loyalty-banner.entry.js +2 -2
  174. package/dist/esm/salla-loyalty-exchange-product-card_5.entry.js +3 -3
  175. package/dist/esm/salla-loyalty-hero_2.entry.js +2 -2
  176. package/dist/esm/salla-loyalty-panel.entry.js +3 -3
  177. package/dist/esm/salla-loyalty-points-banner.entry.js +1 -1
  178. package/dist/esm/salla-loyalty-points-history.entry.js +1 -1
  179. package/dist/esm/salla-loyalty-prize-item.entry.js +1 -1
  180. package/dist/esm/salla-loyalty-program.entry.js +3 -3
  181. package/dist/esm/salla-loyalty-reward.entry.js +2 -2
  182. package/dist/esm/salla-loyalty.entry.js +1 -1
  183. package/dist/esm/salla-maintenance-alert.entry.js +1 -1
  184. package/dist/esm/salla-map_2.entry.js +1 -1
  185. package/dist/esm/salla-menu.entry.js +1 -1
  186. package/dist/esm/salla-metadata.entry.js +1 -1
  187. package/dist/esm/salla-multiple-bundle-product-cart_2.entry.js +1 -1
  188. package/dist/esm/salla-multiple-bundle-product-options-modal_2.entry.js +1 -1
  189. package/dist/esm/salla-multiple-bundle-product.entry.js +1 -1
  190. package/dist/esm/salla-next-order-coupon.entry.js +1 -1
  191. package/dist/esm/salla-notification-item.entry.js +1 -1
  192. package/dist/esm/salla-notifications.entry.js +1 -1
  193. package/dist/esm/salla-offer-modal.entry.js +1 -1
  194. package/dist/esm/salla-offer.entry.js +1 -1
  195. package/dist/esm/salla-order-branch.entry.js +1 -1
  196. package/dist/esm/salla-order-cancel.entry.js +1 -1
  197. package/dist/esm/salla-order-details-multiple-bundle-product.entry.js +1 -1
  198. package/dist/esm/salla-order-details-options.entry.js +1 -1
  199. package/dist/esm/salla-order-details.entry.js +1 -1
  200. package/dist/esm/salla-order-edit-item.entry.js +1 -1
  201. package/dist/esm/salla-order-edit-product-card.entry.js +1 -1
  202. package/dist/esm/salla-order-edit.entry.js +1 -1
  203. package/dist/esm/salla-order-summary.entry.js +1 -1
  204. package/dist/esm/salla-order-totals-card.entry.js +1 -1
  205. package/dist/esm/salla-orders.entry.js +1 -1
  206. package/dist/esm/salla-payments.entry.js +1 -1
  207. package/dist/esm/salla-placeholder.entry.js +1 -1
  208. package/dist/esm/salla-price-range.entry.js +1 -1
  209. package/dist/esm/salla-product-card-embed.entry.js +1 -1
  210. package/dist/esm/salla-product-card_2.entry.js +1 -1
  211. package/dist/esm/salla-product-size-guide.entry.js +1 -1
  212. package/dist/esm/salla-products-list.entry.js +1 -1
  213. package/dist/esm/salla-quick-order.entry.js +1 -1
  214. package/dist/esm/salla-rating-modal-v2.entry.js +1 -1
  215. package/dist/esm/salla-rating-modal.entry.js +1 -1
  216. package/dist/esm/salla-review-factors-tags.entry.js +28 -8
  217. package/dist/esm/salla-scopes.entry.js +1 -1
  218. package/dist/esm/salla-search.entry.js +1 -1
  219. package/dist/esm/salla-skeleton.entry.js +1 -1
  220. package/dist/esm/salla-slider.entry.js +1 -1
  221. package/dist/esm/salla-social-share.entry.js +10 -3
  222. package/dist/esm/salla-social.entry.js +1 -1
  223. package/dist/esm/salla-tab-content_3.entry.js +1 -1
  224. package/dist/esm/salla-tiered-offer.entry.js +1 -1
  225. package/dist/esm/salla-tooltip.entry.js +1 -1
  226. package/dist/esm/salla-trust-badges.entry.js +1 -1
  227. package/dist/esm/salla-user-menu.entry.js +1 -1
  228. package/dist/esm/salla-user-profile.entry.js +1 -1
  229. package/dist/esm/salla-user-settings.entry.js +1 -1
  230. package/dist/esm/salla-verify.entry.js +1 -1
  231. package/dist/esm/salla-wallet.entry.js +1 -1
  232. package/dist/esm/salla-wishlist-actions.entry.js +1 -1
  233. package/dist/esm/{tracked-promise-DBueMSK5.js → tracked-promise-DzdT8znx.js} +1 -1
  234. package/dist/esm/twilight.js +3 -3
  235. package/dist/esm/{vanilla-picker-CWFpeA2O.js → vanilla-picker-DzKX2qA5.js} +1 -1
  236. package/dist/twilight/{p-C3eic20c.js → p--UKCKF-7.js} +1 -1
  237. package/dist/twilight/{p-a877a3df.entry.js → p-017a1a77.entry.js} +1 -1
  238. package/dist/twilight/p-03505fdd.entry.js +4 -0
  239. package/dist/twilight/{p-4448d43a.entry.js → p-05f01920.entry.js} +1 -1
  240. package/dist/twilight/{p-bf15f029.entry.js → p-0950cbbb.entry.js} +1 -1
  241. package/dist/twilight/{p-ed7de02d.entry.js → p-0959b41c.entry.js} +1 -1
  242. package/dist/twilight/{p-a00bc904.entry.js → p-09cd7f70.entry.js} +1 -1
  243. package/dist/twilight/{p-163f862d.entry.js → p-0a3e9f94.entry.js} +1 -1
  244. package/dist/twilight/{p-d5811dab.entry.js → p-113e7032.entry.js} +1 -1
  245. package/dist/twilight/{p-17682453.entry.js → p-12c571d7.entry.js} +1 -1
  246. package/dist/twilight/p-19388aef.entry.js +4 -0
  247. package/dist/twilight/{p-059447b5.entry.js → p-193cccd3.entry.js} +1 -1
  248. package/dist/twilight/{p-a67f9586.entry.js → p-1bec8b0a.entry.js} +1 -1
  249. package/dist/twilight/{p-2e16cb11.entry.js → p-1c03607d.entry.js} +1 -1
  250. package/dist/twilight/{p-4e82cbd2.entry.js → p-1df6827d.entry.js} +1 -1
  251. package/dist/twilight/p-21870458.entry.js +4 -0
  252. package/dist/twilight/{p-5adb2573.entry.js → p-25f8d253.entry.js} +1 -1
  253. package/dist/twilight/{p-374bbf0c.entry.js → p-2643952e.entry.js} +1 -1
  254. package/dist/twilight/{p-537127ba.entry.js → p-27252d50.entry.js} +1 -1
  255. package/dist/twilight/{p-7272b850.entry.js → p-27acb426.entry.js} +1 -1
  256. package/dist/twilight/{p-92f654cd.entry.js → p-296df4c6.entry.js} +1 -1
  257. package/dist/twilight/{p-4a367dba.entry.js → p-2c7e18c5.entry.js} +1 -1
  258. package/dist/twilight/{p-7c286ef2.entry.js → p-30d6436e.entry.js} +1 -1
  259. package/dist/twilight/{p-abc06135.entry.js → p-3350c805.entry.js} +1 -1
  260. package/dist/twilight/{p-629ce572.entry.js → p-33756c72.entry.js} +1 -1
  261. package/dist/twilight/{p-6e88b2ee.entry.js → p-37310557.entry.js} +1 -1
  262. package/dist/twilight/{p-61cac25a.entry.js → p-3791a8d0.entry.js} +1 -1
  263. package/dist/twilight/{p-a7f2a74c.entry.js → p-384febda.entry.js} +1 -1
  264. package/dist/twilight/{p-8dd123f2.entry.js → p-3ccbdb7a.entry.js} +1 -1
  265. package/dist/twilight/{p-818c83b3.entry.js → p-3d44e1e9.entry.js} +1 -1
  266. package/dist/twilight/{p-21fe599c.entry.js → p-41ac2dc0.entry.js} +1 -1
  267. package/dist/twilight/{p-9c2c481e.entry.js → p-42c57314.entry.js} +1 -1
  268. package/dist/twilight/{p-9f8b8f9b.entry.js → p-4317eeb9.entry.js} +1 -1
  269. package/dist/twilight/{p-e94e2b10.entry.js → p-47a7f1a5.entry.js} +1 -1
  270. package/dist/twilight/{p-ae778949.entry.js → p-48cf6b68.entry.js} +1 -1
  271. package/dist/twilight/{p-b25dc971.entry.js → p-4d76cd8f.entry.js} +1 -1
  272. package/dist/twilight/{p-5d8a987d.entry.js → p-516e9179.entry.js} +1 -1
  273. package/dist/twilight/{p-950cd62e.entry.js → p-518b6032.entry.js} +1 -1
  274. package/dist/twilight/{p-a9259c2c.entry.js → p-5201eb4f.entry.js} +1 -1
  275. package/dist/twilight/{p-f624f871.entry.js → p-52c0a1b5.entry.js} +1 -1
  276. package/dist/twilight/{p-2426ecc1.entry.js → p-557609aa.entry.js} +1 -1
  277. package/dist/twilight/{p-61c2bd59.entry.js → p-5958986c.entry.js} +1 -1
  278. package/dist/twilight/{p-5fa56bf3.entry.js → p-62a86556.entry.js} +1 -1
  279. package/dist/twilight/{p-1208db60.entry.js → p-62abd25a.entry.js} +1 -1
  280. package/dist/twilight/{p-9fed2cae.entry.js → p-6681db6a.entry.js} +1 -1
  281. package/dist/twilight/{p-4402fa6e.entry.js → p-69758093.entry.js} +1 -1
  282. package/dist/twilight/{p-c88bacf7.entry.js → p-6ba99048.entry.js} +1 -1
  283. package/dist/twilight/{p-7a4c9484.entry.js → p-6c3b50e2.entry.js} +1 -1
  284. package/dist/twilight/{p-43a205c5.entry.js → p-6d970be9.entry.js} +1 -1
  285. package/dist/twilight/{p-d5d143f8.entry.js → p-725eeeed.entry.js} +1 -1
  286. package/dist/twilight/{p-036bacea.entry.js → p-734dfd28.entry.js} +1 -1
  287. package/dist/twilight/{p-5b2a71b6.entry.js → p-74c84c67.entry.js} +1 -1
  288. package/dist/twilight/{p-2edbc237.entry.js → p-758894b7.entry.js} +1 -1
  289. package/dist/twilight/{p-609e9adc.entry.js → p-7e4fea4b.entry.js} +1 -1
  290. package/dist/twilight/{p-9029c370.entry.js → p-7edc5c88.entry.js} +1 -1
  291. package/dist/twilight/{p-789b3fd9.entry.js → p-804cfed5.entry.js} +1 -1
  292. package/dist/twilight/{p-3a18c5f0.entry.js → p-858f485b.entry.js} +1 -1
  293. package/dist/twilight/{p-1cb73a8f.entry.js → p-86df9649.entry.js} +1 -1
  294. package/dist/twilight/{p-d2698f9a.entry.js → p-8b9c8776.entry.js} +1 -1
  295. package/dist/twilight/{p-4bf27bdf.entry.js → p-8c03c0d2.entry.js} +1 -1
  296. package/dist/twilight/{p-4f78e05a.entry.js → p-8c6730a9.entry.js} +1 -1
  297. package/dist/twilight/{p-0d391a95.entry.js → p-8d199be5.entry.js} +1 -1
  298. package/dist/twilight/{p-d4338ca5.entry.js → p-8ddfe69e.entry.js} +1 -1
  299. package/dist/twilight/{p-c7dd7c0b.entry.js → p-8f982a91.entry.js} +1 -1
  300. package/dist/twilight/{p-948fb25a.entry.js → p-8fcc4bb0.entry.js} +1 -1
  301. package/dist/twilight/{p-7c0ffbd5.entry.js → p-925af19b.entry.js} +1 -1
  302. package/dist/twilight/{p-ee32d269.entry.js → p-9807935d.entry.js} +1 -1
  303. package/dist/twilight/{p-85df37ed.entry.js → p-9eade28d.entry.js} +1 -1
  304. package/dist/twilight/{p-Bo_bRDhK.js → p-BDLhoSt2.js} +1 -1
  305. package/dist/twilight/{p-DpTbeb50.js → p-BEjZOd--.js} +1 -1
  306. package/dist/twilight/{p-CnfHXyEu.js → p-BTVc7r-Z.js} +1 -1
  307. package/dist/twilight/{p-DjsKwETU.js → p-CCH8joDb.js} +1 -1
  308. package/dist/twilight/{p-yMm9FfsL.js → p-CGahPnsw.js} +1 -1
  309. package/dist/twilight/p-CL7OPpYS.js +4 -0
  310. package/dist/twilight/{p-RkvdV-0f.js → p-COwpiJQt.js} +1 -1
  311. package/dist/twilight/{p-M4ZqgDjz.js → p-CxQVHI3A.js} +1 -1
  312. package/dist/twilight/{p-COmDVrcC.js → p-D2_JplO8.js} +1 -1
  313. package/dist/twilight/{p-ucgX82B7.js → p-Da0xrmo3.js} +1 -1
  314. package/dist/twilight/{p-b3EkK54S.js → p-Dv2SelMn.js} +1 -1
  315. package/dist/twilight/p-Dw58JgkP.js +9 -0
  316. package/dist/twilight/{p-d243c5c6.entry.js → p-a476f7b2.entry.js} +1 -1
  317. package/dist/twilight/{p-65c395b2.entry.js → p-abd00b41.entry.js} +1 -1
  318. package/dist/twilight/{p-dced08eb.entry.js → p-ad8eda9d.entry.js} +1 -1
  319. package/dist/twilight/{p-69df3f0f.entry.js → p-b25fd5f0.entry.js} +1 -1
  320. package/dist/twilight/{p-249db53c.entry.js → p-b2789ab4.entry.js} +1 -1
  321. package/dist/twilight/{p-77e452bb.entry.js → p-b6322bba.entry.js} +1 -1
  322. package/dist/twilight/{p-c7a42493.entry.js → p-b847e008.entry.js} +1 -1
  323. package/dist/twilight/{p-1c0a22fc.entry.js → p-bbb48f58.entry.js} +1 -1
  324. package/dist/twilight/{p-fd208d08.entry.js → p-bec996fb.entry.js} +1 -1
  325. package/dist/twilight/{p-d9cb76fa.entry.js → p-c4f379a8.entry.js} +1 -1
  326. package/dist/twilight/{p-af2f5e14.entry.js → p-d53f9574.entry.js} +1 -1
  327. package/dist/twilight/{p-ac4fffc8.entry.js → p-d66af968.entry.js} +1 -1
  328. package/dist/twilight/{p-429fc3c7.entry.js → p-d6d8d12e.entry.js} +1 -1
  329. package/dist/twilight/{p-604317c4.entry.js → p-d6fbb91c.entry.js} +1 -1
  330. package/dist/twilight/{p-69850e8b.entry.js → p-d76f186c.entry.js} +1 -1
  331. package/dist/twilight/{p-a882a9df.entry.js → p-da441555.entry.js} +1 -1
  332. package/dist/twilight/p-de07b85c.entry.js +4 -0
  333. package/dist/twilight/{p-24c84285.entry.js → p-e1842675.entry.js} +1 -1
  334. package/dist/twilight/{p-518a0343.entry.js → p-e69c2c35.entry.js} +1 -1
  335. package/dist/twilight/{p-3a41ac1c.entry.js → p-e78fe137.entry.js} +1 -1
  336. package/dist/twilight/{p-70bad7c7.entry.js → p-e7b03751.entry.js} +1 -1
  337. package/dist/twilight/{p-1cac053d.entry.js → p-ed698e64.entry.js} +1 -1
  338. package/dist/twilight/{p-8e820727.entry.js → p-effae25c.entry.js} +1 -1
  339. package/dist/twilight/{p-59377e23.entry.js → p-f3f0ee9b.entry.js} +1 -1
  340. package/dist/twilight/{p-9d4f612c.entry.js → p-fa7c213b.entry.js} +1 -1
  341. package/dist/twilight/{p-743c3869.entry.js → p-fc18bd83.entry.js} +1 -1
  342. package/dist/twilight/{p-3c8e7fa5.entry.js → p-fef39c48.entry.js} +1 -1
  343. package/dist/twilight/twilight.esm.js +1 -1
  344. package/dist/types/components/salla-comments/salla-comments.d.ts +1 -1
  345. package/dist/types/components/salla-review-factors-tags/salla-review-factors-tags.d.ts +8 -2
  346. package/dist/types/components/salla-reviews-summary/salla-reviews-summary.d.ts +0 -2
  347. package/dist/types/components/salla-social-share/salla-social-share.d.ts +1 -0
  348. package/dist/types/components.d.ts +12 -2
  349. package/dist/types/shared/catalog-recommendations.d.ts +12 -0
  350. package/package.json +5 -5
  351. package/dist/cjs/catalog-recommendations-B_DRy6NT.js +0 -91
  352. package/dist/esm/catalog-recommendations-CehbSKTM.js +0 -88
  353. package/dist/twilight/p-5e85ab72.entry.js +0 -4
  354. package/dist/twilight/p-6d6faf9e.entry.js +0 -4
  355. package/dist/twilight/p-6f74c650.entry.js +0 -4
  356. package/dist/twilight/p-91969734.entry.js +0 -4
  357. package/dist/twilight/p-C4y1c3K3.js +0 -9
  358. package/dist/twilight/p-CehbSKTM.js +0 -4
@@ -38,7 +38,6 @@ export class SallaReviewsSummary {
38
38
  });
39
39
  this.basedOnLabel = salla.lang.get('blocks.comments.based_on');
40
40
  this.recommendedLabel = salla.lang.get('blocks.comments.recommended');
41
- this.overallRatingLabel = salla.lang.get('blocks.comments.overall_rating');
42
41
  });
43
42
  }
44
43
  async loadSummary() {
@@ -62,13 +61,6 @@ export class SallaReviewsSummary {
62
61
  console.error('Error loading reviews summary:', error);
63
62
  }
64
63
  }
65
- renderFactorTags() {
66
- const factors = this.data?.factors || [];
67
- if (!factors.length) {
68
- return null;
69
- }
70
- return (h("div", { class: "s-reviews-summary-factors" }, factors.map(factor => (h("div", { class: "s-reviews-summary-factor-tag" }, h("span", { class: "s-reviews-summary-factor-name" }, factor.name), h("span", { class: "s-reviews-summary-factor-star", innerHTML: Star2 }), h("span", { class: "s-reviews-summary-factor-rating" }, factor.rating || ''))))));
71
- }
72
64
  renderRecommendation() {
73
65
  if (!this.showRecommendation || !this.data?.recommendation) {
74
66
  return null;
@@ -94,9 +86,9 @@ export class SallaReviewsSummary {
94
86
  };
95
87
  const reviewElements = Object.keys(ratings).reverse().map((rating) => {
96
88
  const percentage = ratings[rating];
97
- return (h("div", { key: rating, class: "s-reviews-summary-row" }, h("div", { class: "s-reviews-summary-row-rate" }, rating, " ", h("span", { innerHTML: Star2 })), h("salla-progress-bar", { class: "s-reviews-summary-progress", value: percentage, target: 100, hideUnits: true, height: '16px' }), h("span", { class: "s-reviews-summary-percentage" }, percentage, "%")));
89
+ return (h("div", { key: rating, class: "s-reviews-summary-row" }, h("div", { class: "s-reviews-summary-row-rate" }, rating, " ", h("span", { innerHTML: Star2 })), h("salla-progress-bar", { class: "s-reviews-summary-progress", value: percentage, target: 100, hideUnits: true, height: '20px' }), h("span", { class: "s-reviews-summary-percentage" }, percentage, "%")));
98
90
  });
99
- return (h(Host, { class: "s-reviews-summary-wrapper" }, h("div", { class: "s-reviews-summary-header" }, h("div", { class: "s-reviews-summary-overall-section items-start" }, h("p", { class: "s-reviews-summary-overall-label" }, this.overallRatingLabel), h("div", { class: "s-reviews-summary-overall-row" }, h("h3", { class: "s-reviews-summary-average" }, this.data.rating), h("div", null, h("salla-rating-stars", { size: 'large', value: this.data.rating }), h("p", { class: "s-reviews-summary-count" }, this.basedOnLabel, " ", salla.helpers.number(salla.lang.choice('pages.rating.reviews', this.data.count)))))), this.renderFactorTags(), this.renderRecommendation()), h("div", { class: "s-reviews-summary-rows" }, reviewElements)));
91
+ return (h(Host, { class: "s-reviews-summary-wrapper s-reviews-summary-main-container" }, h("div", { class: "s-reviews-summary-header" }, h("div", { class: "s-reviews-summary-overall-section items-start" }, h("div", { class: "s-reviews-summary-overall-row" }, h("h3", { class: "s-reviews-summary-average" }, this.data.rating), h("div", null, h("salla-rating-stars", { size: 'large', value: this.data.rating }), h("p", { class: "s-reviews-summary-count" }, this.basedOnLabel, " ", salla.helpers.number(salla.lang.choice('pages.rating.reviews', this.data.count)))))), !!this.data?.factors?.length && (h("div", { class: "s-reviews-summary-factors" }, h("salla-review-factors-tags", { factors: this.data.factors }))), this.renderRecommendation()), h("div", { class: "s-reviews-summary-rows" }, reviewElements)));
100
92
  }
101
93
  static get is() { return "salla-reviews-summary"; }
102
94
  static get originalStyleUrls() {
@@ -138,7 +130,6 @@ export class SallaReviewsSummary {
138
130
  "canRender": {},
139
131
  "basedOnLabel": {},
140
132
  "recommendedLabel": {},
141
- "overallRatingLabel": {},
142
133
  "showRatingSummary": {},
143
134
  "recommendationOnly": {},
144
135
  "showRecommendation": {}
@@ -82,7 +82,7 @@ export class SallaSocialShare {
82
82
  if (this.host.hasAttribute('aria-label')) {
83
83
  this.host.removeAttribute('aria-label');
84
84
  }
85
- if (document.getElementById('a2a-script')) {
85
+ if (salla.mobile?.isEnabled?.() || document.getElementById('a2a-script')) {
86
86
  return;
87
87
  }
88
88
  const script = document.createElement('script');
@@ -211,6 +211,13 @@ export class SallaSocialShare {
211
211
  this.deferOutsideClickGuard();
212
212
  return this.open();
213
213
  }
214
+ handleShareClick() {
215
+ if (salla.mobile?.isEnabled?.()) {
216
+ salla.event.dispatch('mobile::share.open', { url: this.getShareUrl() });
217
+ return;
218
+ }
219
+ void this.toggle();
220
+ }
214
221
  /**
215
222
  * Asynchronously initializes the "AddToAny" (a2a) social sharing tool on the current page.
216
223
  * If the global object `window.a2a` is available, it initializes the tool with the 'page' mode.
@@ -345,7 +352,7 @@ export class SallaSocialShare {
345
352
  })));
346
353
  }
347
354
  render() {
348
- return (h("div", { key: 'e934ffb94fea491d445e62f26fcf98914ff0a399', class: "s-social-share-wrapper" }, h("slot", { key: '8dbf4a0c3fb6fb17a0a7c32ace57b357708c0678', name: "widget" }, h("salla-button", { key: 'eb6459bc99d4587bbfc6c0399003a2860d6992b0', "aria-label": "Share", onClick: () => this.toggle(), class: "s-social-share-btn", shape: "icon", fill: "outline", color: "light" }, h("span", { key: '3394f64755bd0bc07839b1a513f5459c8258f096', innerHTML: this.opened ? Cancel : ShareAlt }))), this.mode === 'modal' ? this.renderModal() : this.renderPopupList()));
355
+ return (h("div", { key: 'a96314583de0fd531a9cbc1298efd3c367dae23d', class: "s-social-share-wrapper" }, h("slot", { key: '9f8a1789871e46f02e06cf29a52404a5f01b1e5f', name: "widget" }, h("salla-button", { key: '22c00cfa4d3ca197d4016efcb6e1c49e54b923cf', "aria-label": "Share", onClick: () => this.handleShareClick(), class: "s-social-share-btn", shape: "icon", fill: "outline", color: "light" }, h("span", { key: '4e030b48ba5e673e66ac135f90e6b395c28df403', innerHTML: this.opened ? Cancel : ShareAlt }))), this.mode === 'modal' ? this.renderModal() : this.renderPopupList()));
349
356
  }
350
357
  static get is() { return "salla-social-share"; }
351
358
  static get originalStyleUrls() {
@@ -13,62 +13,67 @@ function getRecommendationsBaseUrl() {
13
13
  function getRecommendationsUrl(path) {
14
14
  return `${getRecommendationsBaseUrl()}${RECOMMENDATIONS_BASE_PATH}${path}`;
15
15
  }
16
- function parseHostname(value) {
17
- if (!value) {
18
- return null;
19
- }
20
- try {
21
- const normalized = value.startsWith('http') ? value : `https://${value}`;
22
- return new URL(normalized).hostname || null;
23
- }
24
- catch {
25
- const hostname = String(value).replace(/^https?:\/\//i, '').split('/')[0];
26
- return hostname || null;
27
- }
28
- }
29
- function getStoreOriginHostname() {
30
- const trackUrl = salla.config.get('jitsu.track_url');
31
- const trackHostname = trackUrl ? parseHostname(String(trackUrl)) : null;
32
- if (trackHostname) {
33
- return trackHostname;
34
- }
35
- for (const candidate of [salla.config.get('store.domain'), salla.config.get('store.url')]) {
36
- const hostname = candidate ? parseHostname(String(candidate)) : null;
37
- if (hostname && !hostname.includes('beta.salla.group')) {
38
- return hostname;
39
- }
40
- }
41
- return window.location.hostname;
42
- }
43
- function getRecommendationsRequestConfig(params) {
16
+ /**
17
+ * Minimal, CORS-allow-listed header set for the recommendations host.
18
+ *
19
+ * We deliberately do NOT go through `salla.api` here: axios injects default
20
+ * common headers (Authorization, UTM params, s-affiliate-code, allocation, …)
21
+ * that are not in the recommendations CORS allow-list and fail the preflight.
22
+ * Sending an explicit set via `fetch` avoids that whole class of failures.
23
+ * Store resolution uses the browser-set `Origin` header plus `s-store-id`.
24
+ *
25
+ * @internal exported for unit tests
26
+ */
27
+ export function getRecommendationsHeaders() {
44
28
  const headers = {
45
29
  's-store-id': String(salla.config.get('store.id')),
46
- origin: getStoreOriginHostname(),
47
30
  's-source': 'store',
48
31
  lang: salla.lang.getLocale(),
49
32
  };
50
- const scopeId = salla.api.getHeader('s-scope-id');
33
+ // Only `s-scope-id` is on the recommendations CORS allow-list — `s-scope-type`
34
+ // is NOT, and requesting it makes the browser reject the preflight.
35
+ const scopeId = salla.api.getHeader?.('s-scope-id');
51
36
  if (scopeId) {
52
37
  headers['s-scope-id'] = String(scopeId);
53
38
  }
54
- return { params, headers };
39
+ return headers;
55
40
  }
56
41
  function extractRecommendationIds(response) {
57
42
  return (response?.data ?? [])
58
43
  .map(item => item?.id)
59
44
  .filter((id) => Boolean(id));
60
45
  }
46
+ /** Salla product ids are always numeric; reject anything else before it reaches the URL. */
47
+ function toNumericId(value) {
48
+ const id = String(value);
49
+ return /^\d+$/.test(id) ? id : null;
50
+ }
61
51
  function fetchRecommendations(path, params) {
62
- const url = getRecommendationsUrl(path);
63
- const config = getRecommendationsRequestConfig(params);
64
- // Recommendations are a non-critical, best-effort feature; suppress the global
65
- // API error notifier so transient failures stay invisible and the consuming
66
- // component can silently hide its section via its own .catch().
67
- return salla.api.withoutNotifier(() => salla.api.request(url, config, 'get'))
68
- .then((response) => extractRecommendationIds(response));
52
+ const url = new URL(getRecommendationsUrl(path));
53
+ Object.entries(params).forEach(([key, value]) => url.searchParams.set(key, value));
54
+ // Native fetch (not salla.api) so only the explicit allow-listed headers are
55
+ // sent no axios default headers to trip the recommendations CORS preflight.
56
+ // Best-effort feature: callers hide their section via .catch(), so no notifier.
57
+ // The host is the hardcoded constant CATALOG_RECOMMENDATIONS_API and only
58
+ // validated numeric ids reach the query string, so there is no SSRF surface.
59
+ // nosemgrep
60
+ return fetch(url.toString(), {
61
+ method: 'GET',
62
+ headers: getRecommendationsHeaders(),
63
+ })
64
+ .then((response) => {
65
+ if (!response.ok) {
66
+ throw new Error(`Recommendations request failed: ${response.status}`);
67
+ }
68
+ return response.json();
69
+ })
70
+ .then((payload) => extractRecommendationIds(payload));
69
71
  }
70
72
  export function fetchCartBoughtTogether(productIds) {
71
- const ids = productIds.slice(0, CART_BOUGHT_TOGETHER_MAX_PRODUCT_IDS);
73
+ const ids = productIds
74
+ .map(toNumericId)
75
+ .filter((id) => id !== null)
76
+ .slice(0, CART_BOUGHT_TOGETHER_MAX_PRODUCT_IDS);
72
77
  if (!ids.length) {
73
78
  return Promise.resolve([]);
74
79
  }
@@ -77,10 +82,11 @@ export function fetchCartBoughtTogether(productIds) {
77
82
  });
78
83
  }
79
84
  export function fetchProductCustomersAlsoBought(productId) {
80
- if (!productId) {
85
+ const id = toNumericId(productId);
86
+ if (!id) {
81
87
  return Promise.resolve([]);
82
88
  }
83
89
  return fetchRecommendations('/products/customers-also-bought', {
84
- product_id: productId,
90
+ product_id: id,
85
91
  });
86
92
  }
@@ -13,62 +13,67 @@ function getRecommendationsBaseUrl() {
13
13
  function getRecommendationsUrl(path) {
14
14
  return `${getRecommendationsBaseUrl()}${RECOMMENDATIONS_BASE_PATH}${path}`;
15
15
  }
16
- function parseHostname(value) {
17
- if (!value) {
18
- return null;
19
- }
20
- try {
21
- const normalized = value.startsWith('http') ? value : `https://${value}`;
22
- return new URL(normalized).hostname || null;
23
- }
24
- catch {
25
- const hostname = String(value).replace(/^https?:\/\//i, '').split('/')[0];
26
- return hostname || null;
27
- }
28
- }
29
- function getStoreOriginHostname() {
30
- const trackUrl = salla.config.get('jitsu.track_url');
31
- const trackHostname = trackUrl ? parseHostname(String(trackUrl)) : null;
32
- if (trackHostname) {
33
- return trackHostname;
34
- }
35
- for (const candidate of [salla.config.get('store.domain'), salla.config.get('store.url')]) {
36
- const hostname = candidate ? parseHostname(String(candidate)) : null;
37
- if (hostname && !hostname.includes('beta.salla.group')) {
38
- return hostname;
39
- }
40
- }
41
- return window.location.hostname;
42
- }
43
- function getRecommendationsRequestConfig(params) {
16
+ /**
17
+ * Minimal, CORS-allow-listed header set for the recommendations host.
18
+ *
19
+ * We deliberately do NOT go through `salla.api` here: axios injects default
20
+ * common headers (Authorization, UTM params, s-affiliate-code, allocation, …)
21
+ * that are not in the recommendations CORS allow-list and fail the preflight.
22
+ * Sending an explicit set via `fetch` avoids that whole class of failures.
23
+ * Store resolution uses the browser-set `Origin` header plus `s-store-id`.
24
+ *
25
+ * @internal exported for unit tests
26
+ */
27
+ function getRecommendationsHeaders() {
44
28
  const headers = {
45
29
  's-store-id': String(salla.config.get('store.id')),
46
- origin: getStoreOriginHostname(),
47
30
  's-source': 'store',
48
31
  lang: salla.lang.getLocale(),
49
32
  };
50
- const scopeId = salla.api.getHeader('s-scope-id');
33
+ // Only `s-scope-id` is on the recommendations CORS allow-list — `s-scope-type`
34
+ // is NOT, and requesting it makes the browser reject the preflight.
35
+ const scopeId = salla.api.getHeader?.('s-scope-id');
51
36
  if (scopeId) {
52
37
  headers['s-scope-id'] = String(scopeId);
53
38
  }
54
- return { params, headers };
39
+ return headers;
55
40
  }
56
41
  function extractRecommendationIds(response) {
57
42
  return (response?.data ?? [])
58
43
  .map(item => item?.id)
59
44
  .filter((id) => Boolean(id));
60
45
  }
46
+ /** Salla product ids are always numeric; reject anything else before it reaches the URL. */
47
+ function toNumericId(value) {
48
+ const id = String(value);
49
+ return /^\d+$/.test(id) ? id : null;
50
+ }
61
51
  function fetchRecommendations(path, params) {
62
- const url = getRecommendationsUrl(path);
63
- const config = getRecommendationsRequestConfig(params);
64
- // Recommendations are a non-critical, best-effort feature; suppress the global
65
- // API error notifier so transient failures stay invisible and the consuming
66
- // component can silently hide its section via its own .catch().
67
- return salla.api.withoutNotifier(() => salla.api.request(url, config, 'get'))
68
- .then((response) => extractRecommendationIds(response));
52
+ const url = new URL(getRecommendationsUrl(path));
53
+ Object.entries(params).forEach(([key, value]) => url.searchParams.set(key, value));
54
+ // Native fetch (not salla.api) so only the explicit allow-listed headers are
55
+ // sent no axios default headers to trip the recommendations CORS preflight.
56
+ // Best-effort feature: callers hide their section via .catch(), so no notifier.
57
+ // The host is the hardcoded constant CATALOG_RECOMMENDATIONS_API and only
58
+ // validated numeric ids reach the query string, so there is no SSRF surface.
59
+ // nosemgrep
60
+ return fetch(url.toString(), {
61
+ method: 'GET',
62
+ headers: getRecommendationsHeaders(),
63
+ })
64
+ .then((response) => {
65
+ if (!response.ok) {
66
+ throw new Error(`Recommendations request failed: ${response.status}`);
67
+ }
68
+ return response.json();
69
+ })
70
+ .then((payload) => extractRecommendationIds(payload));
69
71
  }
70
72
  function fetchCartBoughtTogether(productIds) {
71
- const ids = productIds.slice(0, CART_BOUGHT_TOGETHER_MAX_PRODUCT_IDS);
73
+ const ids = productIds
74
+ .map(toNumericId)
75
+ .filter((id) => id !== null)
76
+ .slice(0, CART_BOUGHT_TOGETHER_MAX_PRODUCT_IDS);
72
77
  if (!ids.length) {
73
78
  return Promise.resolve([]);
74
79
  }
@@ -77,11 +82,12 @@ function fetchCartBoughtTogether(productIds) {
77
82
  });
78
83
  }
79
84
  function fetchProductCustomersAlsoBought(productId) {
80
- if (!productId) {
85
+ const id = toNumericId(productId);
86
+ if (!id) {
81
87
  return Promise.resolve([]);
82
88
  }
83
89
  return fetchRecommendations('/products/customers-also-bought', {
84
- product_id: productId,
90
+ product_id: id,
85
91
  });
86
92
  }
87
93