@reactionary/feeds 0.10.47 → 0.10.49

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 (2) hide show
  1. package/cli.cjs +261 -71
  2. package/package.json +9 -9
package/cli.cjs CHANGED
@@ -112287,6 +112287,23 @@ var init_token_cache = __esm({
112287
112287
  }
112288
112288
  });
112289
112289
 
112290
+ // packages/commercetools/src/schema/oauth.schema.ts
112291
+ var CommercetoolsTokenIntrospectionSchema, CommercetoolsAccessTokenSchema;
112292
+ var init_oauth_schema = __esm({
112293
+ "packages/commercetools/src/schema/oauth.schema.ts"() {
112294
+ "use strict";
112295
+ init_zod();
112296
+ CommercetoolsTokenIntrospectionSchema = looseObject({
112297
+ active: boolean2(),
112298
+ scope: string2().optional()
112299
+ });
112300
+ CommercetoolsAccessTokenSchema = looseObject({
112301
+ access_token: string2(),
112302
+ expires_in: number2()
112303
+ });
112304
+ }
112305
+ });
112306
+
112290
112307
  // packages/commercetools/src/core/client.ts
112291
112308
  var import_ts_client, import_platform_sdk, import_crypto2, crypto2, import_debug, debug, PROVIDER_SESSION_KEY, CommercetoolsAPI;
112292
112309
  var init_client3 = __esm({
@@ -112300,6 +112317,7 @@ var init_client3 = __esm({
112300
112317
  import_debug = __toESM(require_src(), 1);
112301
112318
  init_token_cache();
112302
112319
  init_session_schema2();
112320
+ init_oauth_schema();
112303
112321
  debug = (0, import_debug.default)("reactionary:commercetools");
112304
112322
  PROVIDER_SESSION_KEY = "COMMERCETOOLS_PROVIDER";
112305
112323
  CommercetoolsAPI = class {
@@ -112368,7 +112386,7 @@ var init_client3 = __esm({
112368
112386
  const response = await client.withProjectKey({ projectKey: this.config.projectKey }).channels().withKey({ key }).get().execute();
112369
112387
  const channel = response.body;
112370
112388
  this.setSessionData({
112371
- cacheKey: channel.id
112389
+ [cacheKey]: channel.id
112372
112390
  });
112373
112391
  if (debug.enabled) {
112374
112392
  debug(`Resolved channel ${key} from API and cached it`);
@@ -112502,7 +112520,6 @@ var init_client3 = __esm({
112502
112520
  };
112503
112521
  return identity;
112504
112522
  }
112505
- // FIXME: This can fail if the short-lived access token has expired. In other words, probably missing a token refresh.
112506
112523
  async introspect() {
112507
112524
  const session = await this.tokenCache.get();
112508
112525
  if (!session || !session.token) {
@@ -112511,21 +112528,13 @@ var init_client3 = __esm({
112511
112528
  };
112512
112529
  return identity;
112513
112530
  }
112514
- const authHeader = "Basic " + Buffer.from(
112515
- `${this.config.clientId}:${this.config.clientSecret}`
112516
- ).toString("base64");
112517
- const introspectionUrl = `${this.config.authUrl}/oauth/introspect`;
112518
- const response = await fetch(introspectionUrl, {
112519
- method: "POST",
112520
- headers: {
112521
- Authorization: authHeader,
112522
- "Content-Type": "application/x-www-form-urlencoded"
112523
- },
112524
- body: new URLSearchParams({
112525
- token: session.token
112526
- })
112527
- });
112528
- const body = await response.json();
112531
+ let body = await this.introspectToken(session.token);
112532
+ if (body && !body.active && session.refreshToken) {
112533
+ const refreshedToken = await this.refreshAccessToken(session.refreshToken);
112534
+ if (refreshedToken) {
112535
+ body = await this.introspectToken(refreshedToken);
112536
+ }
112537
+ }
112529
112538
  if (!body) {
112530
112539
  return AnonymousIdentitySchema.parse({});
112531
112540
  }
@@ -112558,6 +112567,56 @@ var init_client3 = __esm({
112558
112567
  type: "Anonymous"
112559
112568
  };
112560
112569
  }
112570
+ getBasicAuthHeader() {
112571
+ return "Basic " + Buffer.from(
112572
+ `${this.config.clientId}:${this.config.clientSecret}`
112573
+ ).toString("base64");
112574
+ }
112575
+ async introspectToken(token) {
112576
+ const response = await fetch(`${this.config.authUrl}/oauth/introspect`, {
112577
+ method: "POST",
112578
+ headers: {
112579
+ Authorization: this.getBasicAuthHeader(),
112580
+ "Content-Type": "application/x-www-form-urlencoded"
112581
+ },
112582
+ body: new URLSearchParams({
112583
+ token
112584
+ })
112585
+ });
112586
+ const result = CommercetoolsTokenIntrospectionSchema.safeParse(await response.json());
112587
+ return result.success ? result.data : void 0;
112588
+ }
112589
+ /**
112590
+ * Exchanges the refresh token for a new access token and stores it in the token cache.
112591
+ * Returns the new access token, or undefined if the refresh token is no longer valid.
112592
+ */
112593
+ async refreshAccessToken(refreshToken) {
112594
+ const response = await fetch(`${this.config.authUrl}/oauth/token`, {
112595
+ method: "POST",
112596
+ headers: {
112597
+ Authorization: this.getBasicAuthHeader(),
112598
+ "Content-Type": "application/x-www-form-urlencoded"
112599
+ },
112600
+ body: new URLSearchParams({
112601
+ grant_type: "refresh_token",
112602
+ refresh_token: refreshToken
112603
+ })
112604
+ });
112605
+ if (!response.ok) {
112606
+ return void 0;
112607
+ }
112608
+ const parsed = CommercetoolsAccessTokenSchema.safeParse(await response.json());
112609
+ if (!parsed.success) {
112610
+ return void 0;
112611
+ }
112612
+ const result = parsed.data;
112613
+ await this.tokenCache.set({
112614
+ expirationTime: Date.now() + result.expires_in * 1e3 - 5 * 60 * 1e3,
112615
+ token: result.access_token,
112616
+ refreshToken
112617
+ });
112618
+ return result.access_token;
112619
+ }
112561
112620
  async becomeGuest() {
112562
112621
  const credentials = Buffer.from(
112563
112622
  `${this.config.clientId}:${this.config.clientSecret}`
@@ -112822,17 +112881,38 @@ var init_cart_factory2 = __esm({
112822
112881
  }
112823
112882
  };
112824
112883
  const localeString = getLanguageCodeFromLocale(context2.languageContext.locale) || "en";
112884
+ const discountedAmountByCartDiscountId = this.groupDiscountedAmountsByCartDiscountId(data);
112825
112885
  const appliedPromotions = [];
112886
+ const codeClaimedCartDiscountIds = /* @__PURE__ */ new Set();
112826
112887
  if (data.discountCodes) {
112827
112888
  for (const promo of data.discountCodes) {
112889
+ const cartDiscountIds = promo.discountCode.obj?.cartDiscounts.map((ref) => ref.id) || [];
112890
+ cartDiscountIds.forEach((id) => codeClaimedCartDiscountIds.add(id));
112891
+ const discountedCentAmount = cartDiscountIds.reduce(
112892
+ (sum, id) => sum + (discountedAmountByCartDiscountId.get(id)?.centAmount || 0),
112893
+ 0
112894
+ );
112828
112895
  appliedPromotions.push({
112829
112896
  code: promo.discountCode.obj?.code || "",
112830
112897
  isCouponCode: true,
112831
112898
  name: promo.discountCode.obj?.name?.[localeString] || "",
112832
- description: promo.discountCode.obj?.description?.[localeString] || ""
112899
+ description: promo.discountCode.obj?.description?.[localeString] || "",
112900
+ ...discountedCentAmount > 0 ? { amount: { value: discountedCentAmount / 100, currency } } : {}
112833
112901
  });
112834
112902
  }
112835
112903
  }
112904
+ for (const [cartDiscountId, applied] of discountedAmountByCartDiscountId) {
112905
+ if (codeClaimedCartDiscountIds.has(cartDiscountId)) {
112906
+ continue;
112907
+ }
112908
+ appliedPromotions.push({
112909
+ code: "",
112910
+ isCouponCode: false,
112911
+ name: applied.cartDiscount?.name?.[localeString] || "",
112912
+ description: applied.cartDiscount?.description?.[localeString] || "",
112913
+ ...applied.centAmount > 0 ? { amount: { value: applied.centAmount / 100, currency } } : {}
112914
+ });
112915
+ }
112836
112916
  const result = {
112837
112917
  identifier,
112838
112918
  user: {
@@ -112847,6 +112927,46 @@ var init_cart_factory2 = __esm({
112847
112927
  };
112848
112928
  return this.cartSchema.parse(result);
112849
112929
  }
112930
+ /**
112931
+ * commercetools links a discount code to the amount it discounted only
112932
+ * indirectly: `discountCode.obj.cartDiscounts` gives the CartDiscount ids a
112933
+ * code triggers, while the actual discounted amounts are reported per line
112934
+ * item (`discountedPricePerQuantity[].discountedPrice.includedDiscounts`)
112935
+ * and on the cart total (`discountOnTotalPrice.includedDiscounts`), each
112936
+ * keyed by that same CartDiscount id. Sum both sources by CartDiscount id
112937
+ * so a discount code's total can be looked up by joining on its ids, and
112938
+ * keep the expanded CartDiscount (when available) so automatically applied
112939
+ * discounts — those not claimed by any code — can be surfaced by name.
112940
+ */
112941
+ groupDiscountedAmountsByCartDiscountId(data) {
112942
+ const totals = /* @__PURE__ */ new Map();
112943
+ const add = (cartDiscountId, centAmount, cartDiscount) => {
112944
+ const entry = totals.get(cartDiscountId) || { centAmount: 0 };
112945
+ entry.centAmount += centAmount;
112946
+ entry.cartDiscount = entry.cartDiscount || cartDiscount;
112947
+ totals.set(cartDiscountId, entry);
112948
+ };
112949
+ const expandedCartDiscount = (reference) => reference.typeId === "cart-discount" ? reference.obj : void 0;
112950
+ for (const lineItem of data.lineItems) {
112951
+ for (const discPrQty of lineItem.discountedPricePerQuantity || []) {
112952
+ for (const included of discPrQty.discountedPrice?.includedDiscounts || []) {
112953
+ add(
112954
+ included.discount.id,
112955
+ included.discountedAmount.centAmount * discPrQty.quantity,
112956
+ expandedCartDiscount(included.discount)
112957
+ );
112958
+ }
112959
+ }
112960
+ }
112961
+ for (const included of data.discountOnTotalPrice?.includedDiscounts || []) {
112962
+ add(
112963
+ included.discount.id,
112964
+ included.discountedAmount.centAmount,
112965
+ expandedCartDiscount(included.discount)
112966
+ );
112967
+ }
112968
+ return totals;
112969
+ }
112850
112970
  parseCartItem(lineItem) {
112851
112971
  const unitPrice = lineItem.price.value.centAmount;
112852
112972
  const totalPrice = lineItem.totalPrice.centAmount || 0;
@@ -113145,8 +113265,9 @@ var init_checkout_factory2 = __esm({
113145
113265
  if (!shippingInstruction) return false;
113146
113266
  if (!shippingAddress && !shippingInstruction.pickupPoint) return false;
113147
113267
  if (paymentInstructions.length === 0) return false;
113148
- const authorizedPayments = paymentInstructions.filter((paymentInstruction) => paymentInstruction.status === "authorized").map((paymentInstruction) => paymentInstruction.amount.value).reduce((sum, value) => sum + value, 0);
113149
- if (price.grandTotal.value !== authorizedPayments) return false;
113268
+ const toCents = (value) => Math.round(value * 100);
113269
+ const authorizedPayments = paymentInstructions.filter((paymentInstruction) => paymentInstruction.status === "authorized").map((paymentInstruction) => toCents(paymentInstruction.amount.value)).reduce((sum, value) => sum + value, 0);
113270
+ if (toCents(price.grandTotal.value) !== authorizedPayments) return false;
113150
113271
  return true;
113151
113272
  }
113152
113273
  parsePaymentInstruction(context2, data) {
@@ -113269,11 +113390,31 @@ var init_inventory_factory2 = __esm({
113269
113390
  }
113270
113391
  });
113271
113392
 
113393
+ // packages/commercetools/src/core/order-status.ts
113394
+ function getOrderStatusFromOrderState(orderState) {
113395
+ switch (orderState) {
113396
+ case "Cancelled":
113397
+ return "Cancelled";
113398
+ case "Complete":
113399
+ return "Shipped";
113400
+ case "Confirmed":
113401
+ return "ReleasedToFulfillment";
113402
+ default:
113403
+ return "AwaitingPayment";
113404
+ }
113405
+ }
113406
+ var init_order_status = __esm({
113407
+ "packages/commercetools/src/core/order-status.ts"() {
113408
+ "use strict";
113409
+ }
113410
+ });
113411
+
113272
113412
  // packages/commercetools/src/factories/order/order.factory.ts
113273
113413
  var CommercetoolsOrderFactory;
113274
113414
  var init_order_factory2 = __esm({
113275
113415
  "packages/commercetools/src/factories/order/order.factory.ts"() {
113276
113416
  "use strict";
113417
+ init_order_status();
113277
113418
  CommercetoolsOrderFactory = class {
113278
113419
  orderSchema;
113279
113420
  constructor(orderSchema) {
@@ -113308,7 +113449,7 @@ var init_order_factory2 = __esm({
113308
113449
  },
113309
113450
  totalShipping: {
113310
113451
  value: shippingTotal / 100,
113311
- currency: data.shippingInfo?.price.currencyCode
113452
+ currency
113312
113453
  },
113313
113454
  totalProductPrice: {
113314
113455
  value: productTotal / 100,
@@ -113319,16 +113460,7 @@ var init_order_factory2 = __esm({
113319
113460
  currency
113320
113461
  }
113321
113462
  };
113322
- let orderStatus = "AwaitingPayment";
113323
- if (data.paymentState === "Paid" && data.orderState === "Confirmed") {
113324
- orderStatus = "ReleasedToFulfillment";
113325
- }
113326
- if (data.shipmentState === "Ready" && data.orderState === "Confirmed") {
113327
- orderStatus = "ReleasedToFulfillment";
113328
- }
113329
- if ((data.shipmentState === "Shipped" || data.shipmentState === "Delivered") && data.orderState === "Completed") {
113330
- orderStatus = "Shipped";
113331
- }
113463
+ const orderStatus = getOrderStatusFromOrderState(data.orderState);
113332
113464
  const items = [];
113333
113465
  for (const remoteItem of data.lineItems) {
113334
113466
  const lineIdentifier = {
@@ -113391,6 +113523,7 @@ var CommercetoolsOrderSearchFactory;
113391
113523
  var init_order_search_factory2 = __esm({
113392
113524
  "packages/commercetools/src/factories/order-search/order-search.factory.ts"() {
113393
113525
  "use strict";
113526
+ init_order_status();
113394
113527
  CommercetoolsOrderSearchFactory = class {
113395
113528
  orderSearchResultSchema;
113396
113529
  constructor(orderSearchResultSchema) {
@@ -113428,16 +113561,7 @@ var init_order_search_factory2 = __esm({
113428
113561
  const userId = {
113429
113562
  userId: data.customerId || data.anonymousId || ""
113430
113563
  };
113431
- let orderStatus = "AwaitingPayment";
113432
- if (data.paymentState === "Paid" && data.orderState === "Confirmed") {
113433
- orderStatus = "ReleasedToFulfillment";
113434
- }
113435
- if (data.shipmentState === "Ready" && data.orderState === "Confirmed") {
113436
- orderStatus = "ReleasedToFulfillment";
113437
- }
113438
- if ((data.shipmentState === "Shipped" || data.shipmentState === "Delivered") && data.orderState === "Completed") {
113439
- orderStatus = "Shipped";
113440
- }
113564
+ const orderStatus = getOrderStatusFromOrderState(data.orderState);
113441
113565
  const totalAmount = {
113442
113566
  currency: data.totalPrice ? data.totalPrice.currencyCode : context2.languageContext.currencyCode,
113443
113567
  value: data.totalPrice ? data.totalPrice.centAmount / 100 : 0
@@ -113512,12 +113636,52 @@ var init_price_factory2 = __esm({
113512
113636
  }
113513
113637
  });
113514
113638
 
113639
+ // packages/commercetools/src/core/attribute-utils.ts
113640
+ function isRecord(value) {
113641
+ return typeof value === "object" && value !== null && !Array.isArray(value);
113642
+ }
113643
+ function getAttributeValueKeyAndLabel(value, language) {
113644
+ if (Array.isArray(value)) {
113645
+ return getAttributeValueKeyAndLabel(value[0], language);
113646
+ }
113647
+ if (isRecord(value)) {
113648
+ if ("key" in value && "label" in value) {
113649
+ const key = String(value["key"]);
113650
+ const label = getAttributeValueKeyAndLabel(value["label"], language).label;
113651
+ return { key, label: label || key };
113652
+ }
113653
+ const localized = value[language] ?? Object.values(value).find((text4) => typeof text4 === "string");
113654
+ const text3 = typeof localized === "string" ? localized : "";
113655
+ return { key: text3, label: text3 };
113656
+ }
113657
+ const text2 = value === void 0 || value === null ? "" : String(value);
113658
+ return { key: text2, label: text2 };
113659
+ }
113660
+ function parseVariantOptionFromAttribute(attribute, language) {
113661
+ const option = { key: attribute.name };
113662
+ const { key, label } = getAttributeValueKeyAndLabel(attribute.value, language);
113663
+ return {
113664
+ identifier: option,
113665
+ name: attribute.name,
113666
+ value: {
113667
+ identifier: { option, key },
113668
+ label
113669
+ }
113670
+ };
113671
+ }
113672
+ var init_attribute_utils = __esm({
113673
+ "packages/commercetools/src/core/attribute-utils.ts"() {
113674
+ "use strict";
113675
+ }
113676
+ });
113677
+
113515
113678
  // packages/commercetools/src/factories/product-associations/product-associations.factory.ts
113516
113679
  var CommercetoolsProductAssociationsFactory;
113517
113680
  var init_product_associations_factory2 = __esm({
113518
113681
  "packages/commercetools/src/factories/product-associations/product-associations.factory.ts"() {
113519
113682
  "use strict";
113520
113683
  init_src();
113684
+ init_attribute_utils();
113521
113685
  init_locale_utils();
113522
113686
  CommercetoolsProductAssociationsFactory = class {
113523
113687
  productAssociationSchema;
@@ -113557,12 +113721,7 @@ var init_product_associations_factory2 = __esm({
113557
113721
  altText: sourceImage?.label || product.name[getLanguageCodeFromLocale(context2.languageContext.locale)] || void 0
113558
113722
  });
113559
113723
  const mappedOptions = variant.attributes?.filter((attribute) => attribute.name === "Color").map(
113560
- (option) => ProductVariantOptionSchema.parse({
113561
- identifier: ProductOptionIdentifierSchema.parse({
113562
- key: option.name
113563
- }),
113564
- name: option.value || ""
113565
- })
113724
+ (option) => ProductVariantOptionSchema.parse(parseVariantOptionFromAttribute(option, getLanguageCodeFromLocale(context2.languageContext.locale)))
113566
113725
  ) || [];
113567
113726
  const mappedOption = mappedOptions?.[0];
113568
113727
  return ProductSearchResultItemVariantSchema.parse({
@@ -113892,6 +114051,7 @@ var init_product_search_factory3 = __esm({
113892
114051
  "packages/commercetools/src/factories/product-search/product-search.factory.ts"() {
113893
114052
  "use strict";
113894
114053
  init_src();
114054
+ init_attribute_utils();
113895
114055
  init_locale_utils();
113896
114056
  CommercetoolsProductSearchFactory = class {
113897
114057
  productSearchResultSchema;
@@ -113982,12 +114142,7 @@ var init_product_search_factory3 = __esm({
113982
114142
  altText: sourceImage?.label || product.name[localeStr] || void 0
113983
114143
  });
113984
114144
  const mappedOptions = variant.attributes?.filter((attribute) => attribute.name === "Color").map(
113985
- (option) => ProductVariantOptionSchema.parse({
113986
- identifier: ProductOptionIdentifierSchema.parse({
113987
- key: option.name
113988
- }),
113989
- name: option.value || ""
113990
- })
114145
+ (option) => ProductVariantOptionSchema.parse(parseVariantOptionFromAttribute(option, localeStr))
113991
114146
  ) || [];
113992
114147
  const mappedOption = mappedOptions?.[0];
113993
114148
  return ProductSearchResultItemVariantSchema.parse({
@@ -114148,7 +114303,11 @@ var init_cart_capability2 = __esm({
114148
114303
  CommercetoolsCartCapability = class extends CartCapability {
114149
114304
  config;
114150
114305
  commercetools;
114151
- expandedCartFields = ["discountCodes[*].discountCode"];
114306
+ expandedCartFields = [
114307
+ "discountCodes[*].discountCode",
114308
+ "lineItems[*].discountedPricePerQuantity[*].discountedPrice.includedDiscounts[*].discount",
114309
+ "discountOnTotalPrice.includedDiscounts[*].discount"
114310
+ ];
114152
114311
  factory;
114153
114312
  constructor(config3, cache, context2, commercetools, factory) {
114154
114313
  super(cache, context2);
@@ -114295,7 +114454,7 @@ var init_cart_capability2 = __esm({
114295
114454
  ...lineIdentifier.originalPrice && {
114296
114455
  externalPrice: {
114297
114456
  currencyCode: lineIdentifier.originalPrice.currency,
114298
- centAmount: Math.floor(lineIdentifier.originalPrice.value * 100)
114457
+ centAmount: Math.round(lineIdentifier.originalPrice.value * 100)
114299
114458
  }
114300
114459
  }
114301
114460
  },
@@ -116036,7 +116195,7 @@ var init_product_list_capability2 = __esm({
116036
116195
  };
116037
116196
  __decorateClass([
116038
116197
  Reactionary({
116039
- cache: true,
116198
+ cache: false,
116040
116199
  cacheTimeToLiveInSeconds: 300,
116041
116200
  currencyDependentCaching: false,
116042
116201
  localeDependentCaching: false,
@@ -116046,7 +116205,7 @@ var init_product_list_capability2 = __esm({
116046
116205
  ], CommercetoolsProductListCapability.prototype, "getById", 1);
116047
116206
  __decorateClass([
116048
116207
  Reactionary({
116049
- cache: true,
116208
+ cache: false,
116050
116209
  cacheTimeToLiveInSeconds: 300,
116051
116210
  currencyDependentCaching: false,
116052
116211
  localeDependentCaching: false,
@@ -116077,7 +116236,7 @@ var init_product_list_capability2 = __esm({
116077
116236
  ], CommercetoolsProductListCapability.prototype, "deleteList", 1);
116078
116237
  __decorateClass([
116079
116238
  Reactionary({
116080
- cache: true,
116239
+ cache: false,
116081
116240
  cacheTimeToLiveInSeconds: 300,
116082
116241
  currencyDependentCaching: false,
116083
116242
  localeDependentCaching: false,
@@ -116322,7 +116481,7 @@ var init_product_reviews_capability2 = __esm({
116322
116481
  },
116323
116482
  target: {
116324
116483
  typeId: "product",
116325
- id: mutation.product.key
116484
+ key: mutation.product.key
116326
116485
  },
116327
116486
  locale: getLanguageCodeFromLocale(this.context.languageContext.locale)
116328
116487
  }
@@ -116333,7 +116492,7 @@ var init_product_reviews_capability2 = __esm({
116333
116492
  parseSingle(review, productKey) {
116334
116493
  return {
116335
116494
  identifier: {
116336
- key: review.key || ""
116495
+ key: review.key ?? review.id
116337
116496
  },
116338
116497
  product: {
116339
116498
  key: productKey
@@ -121592,7 +121751,9 @@ var init_cart_capability3 = __esm({
121592
121751
  code: payload.couponCode,
121593
121752
  isCouponCode: true,
121594
121753
  name: `Promotion for ${payload.couponCode}`,
121595
- description: `Description for promotion with code ${payload.couponCode}`
121754
+ description: `Description for promotion with code ${payload.couponCode}`,
121755
+ amount: { value: 10, currency: cart.price.grandTotal.currency }
121756
+ // For simplicity, every coupon gives a $10 discount
121596
121757
  });
121597
121758
  cart.price.totalDiscount.value += 10;
121598
121759
  cart.price.grandTotal.value -= 10;
@@ -125916,20 +126077,20 @@ function parseDamImages(raw, fallbackAltText) {
125916
126077
  debug17("original_dam_reference is not valid JSON: %s", trimmed);
125917
126078
  return [];
125918
126079
  }
125919
- if (!isRecord(parsed) || !Array.isArray(parsed["images"])) {
126080
+ if (!isRecord2(parsed) || !Array.isArray(parsed["images"])) {
125920
126081
  debug17('original_dam_reference has no "images" array: %s', trimmed);
125921
126082
  return [];
125922
126083
  }
125923
126084
  return parsed["images"].map((entry) => parseDamImage(entry, fallbackAltText)).filter((image) => image !== null);
125924
126085
  }
125925
- function isRecord(value) {
126086
+ function isRecord2(value) {
125926
126087
  return typeof value === "object" && value !== null && !Array.isArray(value);
125927
126088
  }
125928
126089
  function toPixelSize(value) {
125929
126090
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
125930
126091
  }
125931
126092
  function parseDamImage(entry, fallbackAltText) {
125932
- if (!isRecord(entry)) {
126093
+ if (!isRecord2(entry)) {
125933
126094
  return null;
125934
126095
  }
125935
126096
  const url2 = entry["url"];
@@ -125937,7 +126098,7 @@ function parseDamImage(entry, fallbackAltText) {
125937
126098
  return null;
125938
126099
  }
125939
126100
  const altText = entry["altText"];
125940
- const dimensions = isRecord(entry["dimensions"]) ? entry["dimensions"] : void 0;
126101
+ const dimensions = isRecord2(entry["dimensions"]) ? entry["dimensions"] : void 0;
125941
126102
  return ImageSchema.parse({
125942
126103
  sourceUrl: url2.trim(),
125943
126104
  altText: typeof altText === "string" && altText.trim().length > 0 ? altText.trim() : fallbackAltText,
@@ -137706,7 +137867,7 @@ var init_cart_capability5 = __esm({
137706
137867
  *
137707
137868
  * example: this.includedFields = [includedFields, '+discounts.*'].join(',');
137708
137869
  */
137709
- includedFields = ["+items.*"].join(",");
137870
+ includedFields = ["+items.*", "+items.adjustments.*", "+shipping_methods.adjustments.*"].join(",");
137710
137871
  async listCarts(payload) {
137711
137872
  const client = await this.getClient();
137712
137873
  const sessionData = this.medusaApi.getSessionData();
@@ -161427,6 +161588,7 @@ var init_cart_factory5 = __esm({
161427
161588
  for (const remoteItem of allItems) {
161428
161589
  items.push(this.parseCartItem(context2, remoteItem, price.grandTotal.currency));
161429
161590
  }
161591
+ const adjustmentsByPromotionId = this.groupAdjustmentsByPromotionId(data);
161430
161592
  const appliedPromotions = [];
161431
161593
  if (data.promotions) {
161432
161594
  for (const promo of data.promotions) {
@@ -161438,11 +161600,13 @@ var init_cart_factory5 = __esm({
161438
161600
  if (promo.application_method?.type === "fixed") {
161439
161601
  promoDescription = `-${promo.application_method.value} ${price.grandTotal.currency}`;
161440
161602
  }
161603
+ const discountedAmount = adjustmentsByPromotionId.get(promo.id);
161441
161604
  appliedPromotions.push({
161442
161605
  code: promo.code || "",
161443
161606
  isCouponCode: promo.is_automatic ? false : true,
161444
161607
  name: promotionName || promoDescription,
161445
- description: promoDescription
161608
+ description: promoDescription,
161609
+ ...discountedAmount !== void 0 ? { amount: { value: Math.abs(discountedAmount), currency: price.grandTotal.currency } } : {}
161446
161610
  });
161447
161611
  }
161448
161612
  }
@@ -161467,11 +161631,37 @@ var init_cart_factory5 = __esm({
161467
161631
  return this.cartIdentifierSchema.parse(result);
161468
161632
  }
161469
161633
  /**
161470
- * Extension point to control the parsing of a single cart item price
161471
- * @param remoteItem
161472
- * @param currency
161473
- * @returns
161634
+ * Sums each line item's and shipping method's adjustments by the promotion
161635
+ * that caused them, so the resulting amount is the actual monetary total
161636
+ * discounted by that promotion on this cart.
161474
161637
  */
161638
+ groupAdjustmentsByPromotionId(data) {
161639
+ const totals = /* @__PURE__ */ new Map();
161640
+ const addAdjustments = (adjustments) => {
161641
+ for (const adjustment of adjustments || []) {
161642
+ if (!adjustment.promotion_id) {
161643
+ continue;
161644
+ }
161645
+ totals.set(
161646
+ adjustment.promotion_id,
161647
+ (totals.get(adjustment.promotion_id) || 0) + adjustment.amount
161648
+ );
161649
+ }
161650
+ };
161651
+ for (const item of data.items || []) {
161652
+ addAdjustments(item.adjustments);
161653
+ }
161654
+ for (const shippingMethod of data.shipping_methods || []) {
161655
+ addAdjustments(shippingMethod.adjustments);
161656
+ }
161657
+ return totals;
161658
+ }
161659
+ /**
161660
+ * Extension point to control the parsing of a single cart item price
161661
+ * @param remoteItem
161662
+ * @param currency
161663
+ * @returns
161664
+ */
161475
161665
  parseItemPrice(_context, remoteItem, currency) {
161476
161666
  return parseMedusaItemPrice(remoteItem, currency);
161477
161667
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactionary/feeds",
3
- "version": "0.10.47",
3
+ "version": "0.10.49",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "types": "./src/index.d.ts",
@@ -12,14 +12,14 @@
12
12
  "url": "git+https://github.com/Solteq/reactionary.git"
13
13
  },
14
14
  "dependencies": {
15
- "@reactionary/algolia": "0.10.47",
16
- "@reactionary/commercetools": "0.10.47",
17
- "@reactionary/core": "0.10.47",
18
- "@reactionary/fake": "0.10.47",
19
- "@reactionary/magento": "0.10.47",
20
- "@reactionary/medusa": "0.10.47",
21
- "@reactionary/meilisearch": "0.10.47",
22
- "@reactionary/unomi": "0.10.47",
15
+ "@reactionary/algolia": "0.10.49",
16
+ "@reactionary/commercetools": "0.10.49",
17
+ "@reactionary/core": "0.10.49",
18
+ "@reactionary/fake": "0.10.49",
19
+ "@reactionary/magento": "0.10.49",
20
+ "@reactionary/medusa": "0.10.49",
21
+ "@reactionary/meilisearch": "0.10.49",
22
+ "@reactionary/unomi": "0.10.49",
23
23
  "commander": "^15.0.0",
24
24
  "dotenv": "^17.2.2",
25
25
  "sitemap": "^9.0.1",