feeef 0.12.4 → 0.12.5

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/build/index.js CHANGED
@@ -3122,6 +3122,28 @@ function shouldSuppressPixelEvents(order) {
3122
3122
  return treatment === "warning" || treatment === "fake";
3123
3123
  }
3124
3124
 
3125
+ // src/core/entities/product_offer_policy.ts
3126
+ function syncDefaultOfferCode(offers, defaultOfferCode) {
3127
+ if (!defaultOfferCode || !offers?.length) return null;
3128
+ return offers.some((o) => o.code === defaultOfferCode) ? defaultOfferCode : null;
3129
+ }
3130
+ function resolveInitialProductOffer(product) {
3131
+ const code = syncDefaultOfferCode(product.offers, product.defaultOfferCode);
3132
+ if (!code || !product.offers?.length) return void 0;
3133
+ return product.offers.find((o) => o.code === code);
3134
+ }
3135
+ function isProductOfferRequired(product) {
3136
+ return product.forceOffer === true;
3137
+ }
3138
+ function isProductOfferLocked(product) {
3139
+ if (product.forceOffer !== true) return false;
3140
+ return syncDefaultOfferCode(product.offers, product.defaultOfferCode) !== null;
3141
+ }
3142
+ function resolveForcedProductOffer(product) {
3143
+ if (!isProductOfferLocked(product)) return void 0;
3144
+ return resolveInitialProductOffer(product);
3145
+ }
3146
+
3125
3147
  // src/core/entities/shipping_method.ts
3126
3148
  var ShippingMethodStatus = /* @__PURE__ */ ((ShippingMethodStatus2) => {
3127
3149
  ShippingMethodStatus2["draft"] = "draft";
@@ -3287,10 +3309,12 @@ var CartService = class extends NotifiableService {
3287
3309
  }
3288
3310
  /**
3289
3311
  * Sets the current item to be managed in the cart.
3312
+ * Applies product [defaultOfferCode] when the item has no offer yet, and
3313
+ * re-applies a forced offer when [forceOffer] locks selection.
3290
3314
  * @param item - The item to be set as current.
3291
3315
  */
3292
3316
  setCurrentItem(item, notify = true) {
3293
- this.currentItem = item;
3317
+ this.currentItem = this.applyProductOfferPolicy(item);
3294
3318
  const existingItemIndex = this.findItemIndex(this.currentItem);
3295
3319
  if (existingItemIndex !== -1) {
3296
3320
  this.items[existingItemIndex] = this.currentItem;
@@ -3300,6 +3324,26 @@ var CartService = class extends NotifiableService {
3300
3324
  this.notify();
3301
3325
  }
3302
3326
  }
3327
+ /**
3328
+ * Hydrates / locks offer from product policy without mutating unrelated fields.
3329
+ * - Default: preselect when item has no offer
3330
+ * - Forced+default: always keep the forced offer
3331
+ */
3332
+ applyProductOfferPolicy(item) {
3333
+ const forced = resolveForcedProductOffer(item.product);
3334
+ if (forced) {
3335
+ const quantity = this.clampQuantityToOfferLimits(forced, item.quantity);
3336
+ return { ...item, offer: forced, quantity };
3337
+ }
3338
+ if (!item.offer) {
3339
+ const initial = resolveInitialProductOffer(item.product);
3340
+ if (initial) {
3341
+ const quantity = this.clampQuantityToOfferLimits(initial, item.quantity);
3342
+ return { ...item, offer: initial, quantity };
3343
+ }
3344
+ }
3345
+ return item;
3346
+ }
3303
3347
  /**
3304
3348
  * Clamps the quantity to be within the offer's min/max range
3305
3349
  * @param offer - The offer containing quantity constraints
@@ -3566,9 +3610,11 @@ var CartService = class extends NotifiableService {
3566
3610
  updateItemOffer(item, offer) {
3567
3611
  const existingItem = this.findItem(item);
3568
3612
  if (!existingItem) return;
3569
- const updatedItem = { ...existingItem, offer };
3570
- if (offer) {
3571
- updatedItem.quantity = this.clampQuantityToOfferLimits(offer, existingItem.quantity);
3613
+ const next = this.resolveOfferUpdate(existingItem.product, existingItem.offer, offer);
3614
+ if (next === "blocked") return;
3615
+ const updatedItem = { ...existingItem, offer: next };
3616
+ if (next) {
3617
+ updatedItem.quantity = this.clampQuantityToOfferLimits(next, existingItem.quantity);
3572
3618
  }
3573
3619
  this.updateItem(item, updatedItem);
3574
3620
  this.cachedSubtotal = null;
@@ -3580,14 +3626,29 @@ var CartService = class extends NotifiableService {
3580
3626
  */
3581
3627
  updateCurrentItemOffer(offer) {
3582
3628
  if (!this.currentItem) return;
3583
- const updatedItem = { ...this.currentItem, offer };
3584
- if (offer) {
3585
- updatedItem.quantity = this.clampQuantityToOfferLimits(offer, this.currentItem.quantity);
3629
+ const next = this.resolveOfferUpdate(this.currentItem.product, this.currentItem.offer, offer);
3630
+ if (next === "blocked") return;
3631
+ const updatedItem = { ...this.currentItem, offer: next };
3632
+ if (next) {
3633
+ updatedItem.quantity = this.clampQuantityToOfferLimits(next, this.currentItem.quantity);
3586
3634
  }
3587
3635
  this.updateCurrentItem(updatedItem, true);
3588
3636
  this.cachedSubtotal = null;
3589
3637
  this.notify();
3590
3638
  }
3639
+ /**
3640
+ * Enforces product offer policy for a requested offer change.
3641
+ * Returns `'blocked'` when the change is not allowed.
3642
+ */
3643
+ resolveOfferUpdate(product, _current, offer) {
3644
+ const forced = resolveForcedProductOffer(product);
3645
+ if (forced) {
3646
+ if (!offer || offer.code !== forced.code) return "blocked";
3647
+ return forced;
3648
+ }
3649
+ if (!offer && isProductOfferRequired(product)) return "blocked";
3650
+ return offer;
3651
+ }
3591
3652
  /**
3592
3653
  * Sets the shipping method.
3593
3654
  * @param method - Either a store or a shipping method.
@@ -5938,6 +5999,8 @@ export {
5938
5999
  isAttachmentType,
5939
6000
  isFakeOrder,
5940
6001
  isFakeOrderId,
6002
+ isProductOfferLocked,
6003
+ isProductOfferRequired,
5941
6004
  isShippingAvailable,
5942
6005
  isWarningOrder,
5943
6006
  mergeAiModelsBilling,
@@ -5949,11 +6012,14 @@ export {
5949
6012
  parseBatchResult,
5950
6013
  parseBatchRpcStatus,
5951
6014
  parseBatchSummary,
6015
+ resolveForcedProductOffer,
6016
+ resolveInitialProductOffer,
5952
6017
  serializeAttachmentPayload,
5953
6018
  serializeAttachmentPayloads,
5954
6019
  serializeImagePromptTemplateCreate,
5955
6020
  serializeImagePromptTemplateUpdate,
5956
6021
  shouldSuppressPixelEvents,
6022
+ syncDefaultOfferCode,
5957
6023
  transmitRootFromApiBaseUrl,
5958
6024
  tryFixPhoneNumber,
5959
6025
  validatePhoneNumber