feeef 0.12.4 → 0.12.6

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,37 @@ function shouldSuppressPixelEvents(order) {
3122
3122
  return treatment === "warning" || treatment === "fake";
3123
3123
  }
3124
3124
 
3125
+ // src/core/entities/product_offer_policy.ts
3126
+ function readForceOffer(product) {
3127
+ return product.forceOffer === true || product.force_offer === true;
3128
+ }
3129
+ function readDefaultOfferCode(product) {
3130
+ const code = product.defaultOfferCode ?? product.default_offer_code;
3131
+ if (typeof code !== "string") return null;
3132
+ const trimmed = code.trim();
3133
+ return trimmed.length > 0 ? trimmed : null;
3134
+ }
3135
+ function syncDefaultOfferCode(offers, defaultOfferCode) {
3136
+ if (!defaultOfferCode || !offers?.length) return null;
3137
+ return offers.some((o) => o.code === defaultOfferCode) ? defaultOfferCode : null;
3138
+ }
3139
+ function resolveInitialProductOffer(product) {
3140
+ const code = syncDefaultOfferCode(product.offers, readDefaultOfferCode(product));
3141
+ if (!code || !product.offers?.length) return void 0;
3142
+ return product.offers.find((o) => o.code === code);
3143
+ }
3144
+ function isProductOfferRequired(product) {
3145
+ return readForceOffer(product);
3146
+ }
3147
+ function isProductOfferLocked(product) {
3148
+ if (!readForceOffer(product)) return false;
3149
+ return syncDefaultOfferCode(product.offers, readDefaultOfferCode(product)) !== null;
3150
+ }
3151
+ function resolveForcedProductOffer(product) {
3152
+ if (!isProductOfferLocked(product)) return void 0;
3153
+ return resolveInitialProductOffer(product);
3154
+ }
3155
+
3125
3156
  // src/core/entities/shipping_method.ts
3126
3157
  var ShippingMethodStatus = /* @__PURE__ */ ((ShippingMethodStatus2) => {
3127
3158
  ShippingMethodStatus2["draft"] = "draft";
@@ -3287,10 +3318,12 @@ var CartService = class extends NotifiableService {
3287
3318
  }
3288
3319
  /**
3289
3320
  * Sets the current item to be managed in the cart.
3321
+ * Applies product [defaultOfferCode] when the item has no offer yet, and
3322
+ * re-applies a forced offer when [forceOffer] locks selection.
3290
3323
  * @param item - The item to be set as current.
3291
3324
  */
3292
3325
  setCurrentItem(item, notify = true) {
3293
- this.currentItem = item;
3326
+ this.currentItem = this.applyProductOfferPolicy(item);
3294
3327
  const existingItemIndex = this.findItemIndex(this.currentItem);
3295
3328
  if (existingItemIndex !== -1) {
3296
3329
  this.items[existingItemIndex] = this.currentItem;
@@ -3300,6 +3333,26 @@ var CartService = class extends NotifiableService {
3300
3333
  this.notify();
3301
3334
  }
3302
3335
  }
3336
+ /**
3337
+ * Hydrates / locks offer from product policy without mutating unrelated fields.
3338
+ * - Default: preselect when item has no offer
3339
+ * - Forced+default: always keep the forced offer
3340
+ */
3341
+ applyProductOfferPolicy(item) {
3342
+ const forced = resolveForcedProductOffer(item.product);
3343
+ if (forced) {
3344
+ const quantity = this.clampQuantityToOfferLimits(forced, item.quantity);
3345
+ return { ...item, offer: forced, quantity };
3346
+ }
3347
+ if (!item.offer) {
3348
+ const initial = resolveInitialProductOffer(item.product);
3349
+ if (initial) {
3350
+ const quantity = this.clampQuantityToOfferLimits(initial, item.quantity);
3351
+ return { ...item, offer: initial, quantity };
3352
+ }
3353
+ }
3354
+ return item;
3355
+ }
3303
3356
  /**
3304
3357
  * Clamps the quantity to be within the offer's min/max range
3305
3358
  * @param offer - The offer containing quantity constraints
@@ -3566,9 +3619,11 @@ var CartService = class extends NotifiableService {
3566
3619
  updateItemOffer(item, offer) {
3567
3620
  const existingItem = this.findItem(item);
3568
3621
  if (!existingItem) return;
3569
- const updatedItem = { ...existingItem, offer };
3570
- if (offer) {
3571
- updatedItem.quantity = this.clampQuantityToOfferLimits(offer, existingItem.quantity);
3622
+ const next = this.resolveOfferUpdate(existingItem.product, existingItem.offer, offer);
3623
+ if (next === "blocked") return;
3624
+ const updatedItem = { ...existingItem, offer: next };
3625
+ if (next) {
3626
+ updatedItem.quantity = this.clampQuantityToOfferLimits(next, existingItem.quantity);
3572
3627
  }
3573
3628
  this.updateItem(item, updatedItem);
3574
3629
  this.cachedSubtotal = null;
@@ -3580,14 +3635,29 @@ var CartService = class extends NotifiableService {
3580
3635
  */
3581
3636
  updateCurrentItemOffer(offer) {
3582
3637
  if (!this.currentItem) return;
3583
- const updatedItem = { ...this.currentItem, offer };
3584
- if (offer) {
3585
- updatedItem.quantity = this.clampQuantityToOfferLimits(offer, this.currentItem.quantity);
3638
+ const next = this.resolveOfferUpdate(this.currentItem.product, this.currentItem.offer, offer);
3639
+ if (next === "blocked") return;
3640
+ const updatedItem = { ...this.currentItem, offer: next };
3641
+ if (next) {
3642
+ updatedItem.quantity = this.clampQuantityToOfferLimits(next, this.currentItem.quantity);
3586
3643
  }
3587
3644
  this.updateCurrentItem(updatedItem, true);
3588
3645
  this.cachedSubtotal = null;
3589
3646
  this.notify();
3590
3647
  }
3648
+ /**
3649
+ * Enforces product offer policy for a requested offer change.
3650
+ * Returns `'blocked'` when the change is not allowed.
3651
+ */
3652
+ resolveOfferUpdate(product, _current, offer) {
3653
+ const forced = resolveForcedProductOffer(product);
3654
+ if (forced) {
3655
+ if (!offer || offer.code !== forced.code) return "blocked";
3656
+ return forced;
3657
+ }
3658
+ if (!offer && isProductOfferRequired(product)) return "blocked";
3659
+ return offer;
3660
+ }
3591
3661
  /**
3592
3662
  * Sets the shipping method.
3593
3663
  * @param method - Either a store or a shipping method.
@@ -5938,6 +6008,8 @@ export {
5938
6008
  isAttachmentType,
5939
6009
  isFakeOrder,
5940
6010
  isFakeOrderId,
6011
+ isProductOfferLocked,
6012
+ isProductOfferRequired,
5941
6013
  isShippingAvailable,
5942
6014
  isWarningOrder,
5943
6015
  mergeAiModelsBilling,
@@ -5949,11 +6021,14 @@ export {
5949
6021
  parseBatchResult,
5950
6022
  parseBatchRpcStatus,
5951
6023
  parseBatchSummary,
6024
+ resolveForcedProductOffer,
6025
+ resolveInitialProductOffer,
5952
6026
  serializeAttachmentPayload,
5953
6027
  serializeAttachmentPayloads,
5954
6028
  serializeImagePromptTemplateCreate,
5955
6029
  serializeImagePromptTemplateUpdate,
5956
6030
  shouldSuppressPixelEvents,
6031
+ syncDefaultOfferCode,
5957
6032
  transmitRootFromApiBaseUrl,
5958
6033
  tryFixPhoneNumber,
5959
6034
  validatePhoneNumber