@reactionary/feeds 0.10.46 → 0.10.48

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 +175 -65
  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}`
@@ -113145,8 +113204,9 @@ var init_checkout_factory2 = __esm({
113145
113204
  if (!shippingInstruction) return false;
113146
113205
  if (!shippingAddress && !shippingInstruction.pickupPoint) return false;
113147
113206
  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;
113207
+ const toCents = (value) => Math.round(value * 100);
113208
+ const authorizedPayments = paymentInstructions.filter((paymentInstruction) => paymentInstruction.status === "authorized").map((paymentInstruction) => toCents(paymentInstruction.amount.value)).reduce((sum, value) => sum + value, 0);
113209
+ if (toCents(price.grandTotal.value) !== authorizedPayments) return false;
113150
113210
  return true;
113151
113211
  }
113152
113212
  parsePaymentInstruction(context2, data) {
@@ -113269,11 +113329,31 @@ var init_inventory_factory2 = __esm({
113269
113329
  }
113270
113330
  });
113271
113331
 
113332
+ // packages/commercetools/src/core/order-status.ts
113333
+ function getOrderStatusFromOrderState(orderState) {
113334
+ switch (orderState) {
113335
+ case "Cancelled":
113336
+ return "Cancelled";
113337
+ case "Complete":
113338
+ return "Shipped";
113339
+ case "Confirmed":
113340
+ return "ReleasedToFulfillment";
113341
+ default:
113342
+ return "AwaitingPayment";
113343
+ }
113344
+ }
113345
+ var init_order_status = __esm({
113346
+ "packages/commercetools/src/core/order-status.ts"() {
113347
+ "use strict";
113348
+ }
113349
+ });
113350
+
113272
113351
  // packages/commercetools/src/factories/order/order.factory.ts
113273
113352
  var CommercetoolsOrderFactory;
113274
113353
  var init_order_factory2 = __esm({
113275
113354
  "packages/commercetools/src/factories/order/order.factory.ts"() {
113276
113355
  "use strict";
113356
+ init_order_status();
113277
113357
  CommercetoolsOrderFactory = class {
113278
113358
  orderSchema;
113279
113359
  constructor(orderSchema) {
@@ -113308,7 +113388,7 @@ var init_order_factory2 = __esm({
113308
113388
  },
113309
113389
  totalShipping: {
113310
113390
  value: shippingTotal / 100,
113311
- currency: data.shippingInfo?.price.currencyCode
113391
+ currency
113312
113392
  },
113313
113393
  totalProductPrice: {
113314
113394
  value: productTotal / 100,
@@ -113319,16 +113399,7 @@ var init_order_factory2 = __esm({
113319
113399
  currency
113320
113400
  }
113321
113401
  };
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
- }
113402
+ const orderStatus = getOrderStatusFromOrderState(data.orderState);
113332
113403
  const items = [];
113333
113404
  for (const remoteItem of data.lineItems) {
113334
113405
  const lineIdentifier = {
@@ -113391,6 +113462,7 @@ var CommercetoolsOrderSearchFactory;
113391
113462
  var init_order_search_factory2 = __esm({
113392
113463
  "packages/commercetools/src/factories/order-search/order-search.factory.ts"() {
113393
113464
  "use strict";
113465
+ init_order_status();
113394
113466
  CommercetoolsOrderSearchFactory = class {
113395
113467
  orderSearchResultSchema;
113396
113468
  constructor(orderSearchResultSchema) {
@@ -113428,16 +113500,7 @@ var init_order_search_factory2 = __esm({
113428
113500
  const userId = {
113429
113501
  userId: data.customerId || data.anonymousId || ""
113430
113502
  };
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
- }
113503
+ const orderStatus = getOrderStatusFromOrderState(data.orderState);
113441
113504
  const totalAmount = {
113442
113505
  currency: data.totalPrice ? data.totalPrice.currencyCode : context2.languageContext.currencyCode,
113443
113506
  value: data.totalPrice ? data.totalPrice.centAmount / 100 : 0
@@ -113512,12 +113575,52 @@ var init_price_factory2 = __esm({
113512
113575
  }
113513
113576
  });
113514
113577
 
113578
+ // packages/commercetools/src/core/attribute-utils.ts
113579
+ function isRecord(value) {
113580
+ return typeof value === "object" && value !== null && !Array.isArray(value);
113581
+ }
113582
+ function getAttributeValueKeyAndLabel(value, language) {
113583
+ if (Array.isArray(value)) {
113584
+ return getAttributeValueKeyAndLabel(value[0], language);
113585
+ }
113586
+ if (isRecord(value)) {
113587
+ if ("key" in value && "label" in value) {
113588
+ const key = String(value["key"]);
113589
+ const label = getAttributeValueKeyAndLabel(value["label"], language).label;
113590
+ return { key, label: label || key };
113591
+ }
113592
+ const localized = value[language] ?? Object.values(value).find((text4) => typeof text4 === "string");
113593
+ const text3 = typeof localized === "string" ? localized : "";
113594
+ return { key: text3, label: text3 };
113595
+ }
113596
+ const text2 = value === void 0 || value === null ? "" : String(value);
113597
+ return { key: text2, label: text2 };
113598
+ }
113599
+ function parseVariantOptionFromAttribute(attribute, language) {
113600
+ const option = { key: attribute.name };
113601
+ const { key, label } = getAttributeValueKeyAndLabel(attribute.value, language);
113602
+ return {
113603
+ identifier: option,
113604
+ name: attribute.name,
113605
+ value: {
113606
+ identifier: { option, key },
113607
+ label
113608
+ }
113609
+ };
113610
+ }
113611
+ var init_attribute_utils = __esm({
113612
+ "packages/commercetools/src/core/attribute-utils.ts"() {
113613
+ "use strict";
113614
+ }
113615
+ });
113616
+
113515
113617
  // packages/commercetools/src/factories/product-associations/product-associations.factory.ts
113516
113618
  var CommercetoolsProductAssociationsFactory;
113517
113619
  var init_product_associations_factory2 = __esm({
113518
113620
  "packages/commercetools/src/factories/product-associations/product-associations.factory.ts"() {
113519
113621
  "use strict";
113520
113622
  init_src();
113623
+ init_attribute_utils();
113521
113624
  init_locale_utils();
113522
113625
  CommercetoolsProductAssociationsFactory = class {
113523
113626
  productAssociationSchema;
@@ -113557,12 +113660,7 @@ var init_product_associations_factory2 = __esm({
113557
113660
  altText: sourceImage?.label || product.name[getLanguageCodeFromLocale(context2.languageContext.locale)] || void 0
113558
113661
  });
113559
113662
  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
- })
113663
+ (option) => ProductVariantOptionSchema.parse(parseVariantOptionFromAttribute(option, getLanguageCodeFromLocale(context2.languageContext.locale)))
113566
113664
  ) || [];
113567
113665
  const mappedOption = mappedOptions?.[0];
113568
113666
  return ProductSearchResultItemVariantSchema.parse({
@@ -113892,6 +113990,7 @@ var init_product_search_factory3 = __esm({
113892
113990
  "packages/commercetools/src/factories/product-search/product-search.factory.ts"() {
113893
113991
  "use strict";
113894
113992
  init_src();
113993
+ init_attribute_utils();
113895
113994
  init_locale_utils();
113896
113995
  CommercetoolsProductSearchFactory = class {
113897
113996
  productSearchResultSchema;
@@ -113982,12 +114081,7 @@ var init_product_search_factory3 = __esm({
113982
114081
  altText: sourceImage?.label || product.name[localeStr] || void 0
113983
114082
  });
113984
114083
  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
- })
114084
+ (option) => ProductVariantOptionSchema.parse(parseVariantOptionFromAttribute(option, localeStr))
113991
114085
  ) || [];
113992
114086
  const mappedOption = mappedOptions?.[0];
113993
114087
  return ProductSearchResultItemVariantSchema.parse({
@@ -114295,7 +114389,7 @@ var init_cart_capability2 = __esm({
114295
114389
  ...lineIdentifier.originalPrice && {
114296
114390
  externalPrice: {
114297
114391
  currencyCode: lineIdentifier.originalPrice.currency,
114298
- centAmount: Math.floor(lineIdentifier.originalPrice.value * 100)
114392
+ centAmount: Math.round(lineIdentifier.originalPrice.value * 100)
114299
114393
  }
114300
114394
  }
114301
114395
  },
@@ -116036,7 +116130,7 @@ var init_product_list_capability2 = __esm({
116036
116130
  };
116037
116131
  __decorateClass([
116038
116132
  Reactionary({
116039
- cache: true,
116133
+ cache: false,
116040
116134
  cacheTimeToLiveInSeconds: 300,
116041
116135
  currencyDependentCaching: false,
116042
116136
  localeDependentCaching: false,
@@ -116046,7 +116140,7 @@ var init_product_list_capability2 = __esm({
116046
116140
  ], CommercetoolsProductListCapability.prototype, "getById", 1);
116047
116141
  __decorateClass([
116048
116142
  Reactionary({
116049
- cache: true,
116143
+ cache: false,
116050
116144
  cacheTimeToLiveInSeconds: 300,
116051
116145
  currencyDependentCaching: false,
116052
116146
  localeDependentCaching: false,
@@ -116077,7 +116171,7 @@ var init_product_list_capability2 = __esm({
116077
116171
  ], CommercetoolsProductListCapability.prototype, "deleteList", 1);
116078
116172
  __decorateClass([
116079
116173
  Reactionary({
116080
- cache: true,
116174
+ cache: false,
116081
116175
  cacheTimeToLiveInSeconds: 300,
116082
116176
  currencyDependentCaching: false,
116083
116177
  localeDependentCaching: false,
@@ -116322,7 +116416,7 @@ var init_product_reviews_capability2 = __esm({
116322
116416
  },
116323
116417
  target: {
116324
116418
  typeId: "product",
116325
- id: mutation.product.key
116419
+ key: mutation.product.key
116326
116420
  },
116327
116421
  locale: getLanguageCodeFromLocale(this.context.languageContext.locale)
116328
116422
  }
@@ -116333,7 +116427,7 @@ var init_product_reviews_capability2 = __esm({
116333
116427
  parseSingle(review, productKey) {
116334
116428
  return {
116335
116429
  identifier: {
116336
- key: review.key || ""
116430
+ key: review.key ?? review.id
116337
116431
  },
116338
116432
  product: {
116339
116433
  key: productKey
@@ -125916,20 +126010,20 @@ function parseDamImages(raw, fallbackAltText) {
125916
126010
  debug17("original_dam_reference is not valid JSON: %s", trimmed);
125917
126011
  return [];
125918
126012
  }
125919
- if (!isRecord(parsed) || !Array.isArray(parsed["images"])) {
126013
+ if (!isRecord2(parsed) || !Array.isArray(parsed["images"])) {
125920
126014
  debug17('original_dam_reference has no "images" array: %s', trimmed);
125921
126015
  return [];
125922
126016
  }
125923
126017
  return parsed["images"].map((entry) => parseDamImage(entry, fallbackAltText)).filter((image) => image !== null);
125924
126018
  }
125925
- function isRecord(value) {
126019
+ function isRecord2(value) {
125926
126020
  return typeof value === "object" && value !== null && !Array.isArray(value);
125927
126021
  }
125928
126022
  function toPixelSize(value) {
125929
126023
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
125930
126024
  }
125931
126025
  function parseDamImage(entry, fallbackAltText) {
125932
- if (!isRecord(entry)) {
126026
+ if (!isRecord2(entry)) {
125933
126027
  return null;
125934
126028
  }
125935
126029
  const url2 = entry["url"];
@@ -125937,7 +126031,7 @@ function parseDamImage(entry, fallbackAltText) {
125937
126031
  return null;
125938
126032
  }
125939
126033
  const altText = entry["altText"];
125940
- const dimensions = isRecord(entry["dimensions"]) ? entry["dimensions"] : void 0;
126034
+ const dimensions = isRecord2(entry["dimensions"]) ? entry["dimensions"] : void 0;
125941
126035
  return ImageSchema.parse({
125942
126036
  sourceUrl: url2.trim(),
125943
126037
  altText: typeof altText === "string" && altText.trim().length > 0 ? altText.trim() : fallbackAltText,
@@ -138469,6 +138563,22 @@ var init_checkout_capability5 = __esm({
138469
138563
  cart_id: payload.checkout.key
138470
138564
  };
138471
138565
  }
138566
+ /**
138567
+ * Whether a Medusa shipping option's calculated price is usable, i.e. has an
138568
+ * actual amount (which may be `0` for valid free shipping) rather than no
138569
+ * price data at all. `calculated_amount`/`original_amount` are `number | null`;
138570
+ * checking them with a plain falsy check would incorrectly treat a `0` amount
138571
+ * (free shipping) the same as a missing price and drop the option.
138572
+ *
138573
+ * Override this if a project needs different rules for which shipping
138574
+ * options are considered usable.
138575
+ */
138576
+ hasUsableShippingPrice(calculatedPrice) {
138577
+ if (!calculatedPrice) {
138578
+ return false;
138579
+ }
138580
+ return calculatedPrice.calculated_amount != null || calculatedPrice.original_amount != null;
138581
+ }
138472
138582
  async getAvailableShippingMethods(payload) {
138473
138583
  const client = await this.medusaApi.getClient();
138474
138584
  if (debug23.enabled) {
@@ -138503,7 +138613,7 @@ var init_checkout_capability5 = __esm({
138503
138613
  }
138504
138614
  }
138505
138615
  for (const sm of shippingMethodResponse.shipping_options) {
138506
- if (!sm.calculated_price || !sm.calculated_price.calculated_amount && !sm.calculated_price.original_amount) {
138616
+ if (!this.hasUsableShippingPrice(sm.calculated_price)) {
138507
138617
  console.warn(`Skipping shipping method ${sm.name}/${sm.provider.id} because it has no calculated price for checkout ${payload.checkout.key}`);
138508
138618
  continue;
138509
138619
  }
@@ -162274,7 +162384,7 @@ var init_order_search_factory5 = __esm({
162274
162384
  pageNumber: (Math.ceil(data.offset / data.limit) || 0) + 1,
162275
162385
  pageSize: data.limit,
162276
162386
  totalCount: data.count,
162277
- totalPages: Math.ceil(data.count / data.limit || 0) + 1,
162387
+ totalPages: Math.ceil(data.count / data.limit || 0),
162278
162388
  items: orders
162279
162389
  };
162280
162390
  return this.orderSearchResultSchema.parse(result);
@@ -162616,7 +162726,7 @@ var init_product_search_factory6 = __esm({
162616
162726
  pageNumber: (Math.ceil(remote.offset / remote.limit) || 0) + 1,
162617
162727
  pageSize: remote.limit,
162618
162728
  totalCount: remote.count,
162619
- totalPages: Math.ceil(remote.count / remote.limit || 0) + 1,
162729
+ totalPages: Math.ceil(remote.count / remote.limit || 0),
162620
162730
  items: products,
162621
162731
  facets: []
162622
162732
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reactionary/feeds",
3
- "version": "0.10.46",
3
+ "version": "0.10.48",
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.46",
16
- "@reactionary/commercetools": "0.10.46",
17
- "@reactionary/core": "0.10.46",
18
- "@reactionary/fake": "0.10.46",
19
- "@reactionary/magento": "0.10.46",
20
- "@reactionary/medusa": "0.10.46",
21
- "@reactionary/meilisearch": "0.10.46",
22
- "@reactionary/unomi": "0.10.46",
15
+ "@reactionary/algolia": "0.10.48",
16
+ "@reactionary/commercetools": "0.10.48",
17
+ "@reactionary/core": "0.10.48",
18
+ "@reactionary/fake": "0.10.48",
19
+ "@reactionary/magento": "0.10.48",
20
+ "@reactionary/medusa": "0.10.48",
21
+ "@reactionary/meilisearch": "0.10.48",
22
+ "@reactionary/unomi": "0.10.48",
23
23
  "commander": "^15.0.0",
24
24
  "dotenv": "^17.2.2",
25
25
  "sitemap": "^9.0.1",