@reactionary/commercetools 0.7.5 → 0.8.0

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.
@@ -30,6 +30,7 @@ import {
30
30
  Reactionary,
31
31
  success
32
32
  } from "@reactionary/core";
33
+ import { getLanguageCodeFromLocale } from "../core/locale-utils.js";
33
34
  class CommercetoolsCartCapability extends CartCapability {
34
35
  config;
35
36
  commercetools;
@@ -95,7 +96,7 @@ class CommercetoolsCartCapability extends CartCapability {
95
96
  const body = {
96
97
  currency: this.context.languageContext.currencyCode || "EUR",
97
98
  country: this.context.taxJurisdiction.countryCode || "DK",
98
- locale: this.context.languageContext.locale,
99
+ locale: getLanguageCodeFromLocale(this.context.languageContext.locale),
99
100
  businessUnit: businessUnitReference,
100
101
  ...customerReference ? { customerId: customerReference.id } : {},
101
102
  custom: customFields
@@ -273,7 +274,7 @@ class CommercetoolsCartCapability extends CartCapability {
273
274
  const newCart = await client.carts.post({
274
275
  body: {
275
276
  currency: payload.newCurrency,
276
- locale: this.context.languageContext.locale,
277
+ locale: getLanguageCodeFromLocale(this.context.languageContext.locale),
277
278
  country: currentCart.body.country,
278
279
  ...company && {
279
280
  businessUnit: {
@@ -23,6 +23,7 @@ import {
23
23
  error
24
24
  } from "@reactionary/core";
25
25
  import * as z from "zod";
26
+ import { getLanguageCodeFromLocale } from "../core/locale-utils.js";
26
27
  class CommercetoolsCategoryCapability extends CategoryCapability {
27
28
  config;
28
29
  commercetools;
@@ -54,7 +55,7 @@ class CommercetoolsCategoryCapability extends CategoryCapability {
54
55
  try {
55
56
  const response = await client.get({
56
57
  queryArgs: {
57
- where: `slug(${this.context.languageContext.locale}=:slug)`,
58
+ where: `slug(${getLanguageCodeFromLocale(this.context.languageContext.locale)}=:slug)`,
58
59
  "var.slug": payload.slug,
59
60
  storeProjection: this.context.storeIdentifier.key,
60
61
  limit: 1,
@@ -30,6 +30,7 @@ import {
30
30
  } from "@reactionary/core";
31
31
  import * as z from "zod";
32
32
  import {} from "../schema/commercetools.schema.js";
33
+ import { getLanguageCodeFromLocale } from "../core/locale-utils.js";
33
34
  class CheckoutNotReadyForFinalizationError extends Error {
34
35
  constructor(checkoutIdentifier) {
35
36
  super(
@@ -194,7 +195,7 @@ class CommercetoolsCheckoutCapability extends CheckoutCapability {
194
195
  paymentMethodInfo: {
195
196
  method: payload.paymentInstruction.paymentMethod.method,
196
197
  name: {
197
- [this.context.languageContext.locale]: payload.paymentInstruction.paymentMethod.name
198
+ [getLanguageCodeFromLocale(this.context.languageContext.locale)]: payload.paymentInstruction.paymentMethod.name
198
199
  },
199
200
  paymentInterface: payload.paymentInstruction.paymentMethod.paymentProcessor
200
201
  },
@@ -18,6 +18,7 @@ import {
18
18
  ProductRatingSummarySchema,
19
19
  ProductReviewPaginatedResultSchema
20
20
  } from "@reactionary/core";
21
+ import { getLanguageCodeFromLocale } from "../core/locale-utils.js";
21
22
  class CommercetoolsProductReviewsCapability extends ProductReviewsCapability {
22
23
  config;
23
24
  commercetools;
@@ -135,7 +136,7 @@ class CommercetoolsProductReviewsCapability extends ProductReviewsCapability {
135
136
  typeId: "product",
136
137
  id: mutation.product.key
137
138
  },
138
- locale: this.context.languageContext.locale
139
+ locale: getLanguageCodeFromLocale(this.context.languageContext.locale)
139
140
  }
140
141
  }).execute();
141
142
  const review = this.parseSingle(response.body, mutation.product.key);
@@ -20,11 +20,16 @@ import {
20
20
  } from "@reactionary/core";
21
21
  import createDebug from "debug";
22
22
  import { CommercetoolsCategoryLookupSchema, CommercetoolsResolveCategoryQueryByKeySchema } from "../schema/commercetools.schema.js";
23
+ import { getLanguageCodeFromLocale } from "../core/locale-utils.js";
23
24
  const debug = createDebug("reactionary:commercetools:search");
24
25
  class CommercetoolsProductSearchCapability extends ProductSearchCapability {
25
26
  config;
26
27
  commercetools;
27
28
  factory;
29
+ /**
30
+ * We assume all commercetools data is indexed on the language level, not the country subdivision
31
+ */
32
+ languageCode = getLanguageCodeFromLocale(this.context.languageContext.locale);
28
33
  constructor(config, cache, context, commercetools, factory) {
29
34
  super(cache, context);
30
35
  this.config = config;
@@ -48,7 +53,8 @@ class CommercetoolsProductSearchCapability extends ProductSearchCapability {
48
53
  return {
49
54
  exact: {
50
55
  field: selectedFacetValue.facet.key,
51
- fieldType: "text",
56
+ fieldType: "ltext",
57
+ language: `${this.languageCode}`,
52
58
  value: selectedFacetValue.key
53
59
  }
54
60
  };
@@ -117,21 +123,21 @@ class CommercetoolsProductSearchCapability extends ProductSearchCapability {
117
123
  {
118
124
  fullText: {
119
125
  field: "name",
120
- language: `${this.context.languageContext.locale}`,
126
+ language: `${this.languageCode}`,
121
127
  value: payload.search.term
122
128
  }
123
129
  },
124
130
  {
125
131
  fullText: {
126
132
  field: "description",
127
- language: `${this.context.languageContext.locale}`,
133
+ language: `${this.languageCode}`,
128
134
  value: payload.search.term
129
135
  }
130
136
  },
131
137
  {
132
138
  fullText: {
133
139
  field: "searchKeywords",
134
- language: `${this.context.languageContext.locale}`,
140
+ language: `${this.languageCode}`,
135
141
  value: payload.search.term
136
142
  }
137
143
  }
@@ -163,7 +169,8 @@ class CommercetoolsProductSearchCapability extends ProductSearchCapability {
163
169
  distinct: {
164
170
  name: facet,
165
171
  field: facet,
166
- fieldType: "text",
172
+ fieldType: "ltext",
173
+ language: `${this.languageCode}`,
167
174
  limit: 50
168
175
  }
169
176
  });
@@ -261,7 +268,7 @@ class CommercetoolsProductSearchCapability extends ProductSearchCapability {
261
268
  if (!category) {
262
269
  continue;
263
270
  }
264
- facetValue.name = category.name[this.context.languageContext.locale] || category.id;
271
+ facetValue.name = category.name[this.languageCode] || category.id;
265
272
  } catch (error) {
266
273
  if (debug.enabled) {
267
274
  debug(`Error resolving category key for id ${facetValue.identifier.key}:`, error);
@@ -0,0 +1,6 @@
1
+ function getLanguageCodeFromLocale(locale) {
2
+ return locale.split("-")[0];
3
+ }
4
+ export {
5
+ getLanguageCodeFromLocale
6
+ };
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  CartItemSchema
3
3
  } from "@reactionary/core";
4
+ import { getLanguageCodeFromLocale } from "../../core/locale-utils.js";
4
5
  class CommercetoolsCartFactory {
5
6
  cartSchema;
6
7
  cartIdentifierSchema;
@@ -102,7 +103,7 @@ class CommercetoolsCartFactory {
102
103
  currency
103
104
  }
104
105
  };
105
- const localeString = context.languageContext.locale || "en";
106
+ const localeString = getLanguageCodeFromLocale(context.languageContext.locale) || "en";
106
107
  const appliedPromotions = [];
107
108
  if (data.discountCodes) {
108
109
  for (const promo of data.discountCodes) {
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  } from "@reactionary/core";
3
+ import { getLanguageCodeFromLocale } from "../../core/locale-utils.js";
3
4
  class CommercetoolsCategoryFactory {
4
5
  categorySchema;
5
6
  categoryPaginatedResultSchema;
@@ -9,15 +10,16 @@ class CommercetoolsCategoryFactory {
9
10
  }
10
11
  parseCategory(context, data) {
11
12
  const identifier = { key: data.key || "" };
13
+ const localeStr = getLanguageCodeFromLocale(context.languageContext.locale) || "en";
12
14
  const result = {
13
15
  identifier,
14
- name: data.name[context.languageContext.locale] || "No Name",
15
- slug: data.slug ? data.slug[context.languageContext.locale] || "" : "",
16
- text: data.description ? data.description[context.languageContext.locale] || "" : "",
16
+ name: data.name[localeStr] || "No Name",
17
+ slug: data.slug ? data.slug[localeStr] || "" : "",
18
+ text: data.description ? data.description[localeStr] || "" : "",
17
19
  parentCategory: data.parent && data.parent.obj && data.parent.obj?.key ? { key: data.parent.obj.key } : void 0,
18
20
  images: (data.assets || []).filter((asset) => asset.sources.length > 0).filter((asset) => asset.sources[0].contentType?.startsWith("image/")).map((asset) => ({
19
21
  sourceUrl: asset.sources[0].uri,
20
- altText: asset.description?.[context.languageContext.locale] || asset.name[context.languageContext.locale] || "",
22
+ altText: asset.description?.[localeStr] || asset.name[localeStr] || "",
21
23
  height: asset.sources[0].dimensions?.h || 0,
22
24
  width: asset.sources[0].dimensions?.w || 0
23
25
  }))
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  CheckoutItemSchema
3
3
  } from "@reactionary/core";
4
+ import { getLanguageCodeFromLocale } from "../../core/locale-utils.js";
4
5
  class CommercetoolsCheckoutFactory {
5
6
  checkoutSchema;
6
7
  shippingMethodSchema;
@@ -104,7 +105,7 @@ class CommercetoolsCheckoutFactory {
104
105
  };
105
106
  const result = {
106
107
  deliveryTime: "",
107
- description: data.localizedDescription?.[context.languageContext.locale] || "",
108
+ description: data.localizedDescription?.[getLanguageCodeFromLocale(context.languageContext.locale)] || "",
108
109
  identifier,
109
110
  name: data.name,
110
111
  price: data.zoneRates[0].shippingRates[0].price ? {
@@ -176,7 +177,7 @@ class CommercetoolsCheckoutFactory {
176
177
  };
177
178
  const method = data.paymentMethodInfo?.method || "unknown";
178
179
  const paymentProcessor = data.paymentMethodInfo?.paymentInterface || method;
179
- const paymentName = data.paymentMethodInfo.name?.[context.languageContext.locale];
180
+ const paymentName = data.paymentMethodInfo.name?.[getLanguageCodeFromLocale(context.languageContext.locale)];
180
181
  const paymentMethod = {
181
182
  method,
182
183
  paymentProcessor,
@@ -5,6 +5,7 @@ import {
5
5
  ProductAttributeValueIdentifierSchema,
6
6
  ProductAttributeValueSchema
7
7
  } from "@reactionary/core";
8
+ import { getLanguageCodeFromLocale } from "../../core/locale-utils.js";
8
9
  class CommercetoolsProductFactory {
9
10
  productSchema;
10
11
  // PAIN: not being able to assign a default for productSchema (productSchema: TProductSchema = ProductSchema)
@@ -15,11 +16,12 @@ class CommercetoolsProductFactory {
15
16
  }
16
17
  parseProduct(context, data) {
17
18
  const identifier = { key: data.key || data.id };
18
- const name = data.name[context.languageContext.locale];
19
- const slug = data.slug[context.languageContext.locale];
19
+ const localeStr = getLanguageCodeFromLocale(context.languageContext.locale) || "en";
20
+ const name = data.name[localeStr];
21
+ const slug = data.slug[localeStr];
20
22
  let description = "";
21
23
  if (data.description) {
22
- description = data.description[context.languageContext.locale];
24
+ description = data.description[localeStr];
23
25
  }
24
26
  const variantLevelAttributes = data.masterVariant.attributes?.map(
25
27
  (x) => this.parseAttribute(context, x)
@@ -70,6 +72,7 @@ class CommercetoolsProductFactory {
70
72
  const identifier = {
71
73
  sku: variant.sku
72
74
  };
75
+ const localeStr = getLanguageCodeFromLocale(context.languageContext.locale) || "en";
73
76
  const images = [
74
77
  ...(variant.images || []).map(
75
78
  (img) => ImageSchema.parse({
@@ -104,7 +107,7 @@ class CommercetoolsProductFactory {
104
107
  barcode: "",
105
108
  ean: "",
106
109
  gtin: "",
107
- name: product.name[context.languageContext.locale],
110
+ name: product.name[localeStr],
108
111
  options,
109
112
  upc: ""
110
113
  };
@@ -126,9 +129,10 @@ class CommercetoolsProductFactory {
126
129
  if (attr.value && Array.isArray(attr.value)) {
127
130
  attrValue = attr.value[0];
128
131
  }
132
+ const localeStr = getLanguageCodeFromLocale(context.languageContext.locale) || "en";
129
133
  if (attr.value && typeof attr.value === "object") {
130
- if (context.languageContext.locale in attr.value) {
131
- attrValue = attr.value[context.languageContext.locale];
134
+ if (localeStr in attr.value) {
135
+ attrValue = attr.value[localeStr];
132
136
  } else {
133
137
  attrValue = "-";
134
138
  }
@@ -5,6 +5,7 @@ import {
5
5
  ProductVariantIdentifierSchema,
6
6
  ProductVariantOptionSchema
7
7
  } from "@reactionary/core";
8
+ import { getLanguageCodeFromLocale } from "../../core/locale-utils.js";
8
9
  class CommercetoolsProductAssociationsFactory {
9
10
  productAssociationSchema;
10
11
  constructor(productAssociationSchema) {
@@ -25,10 +26,11 @@ class CommercetoolsProductAssociationsFactory {
25
26
  const variants = [data.masterVariant, ...data.variants].map(
26
27
  (variant) => this.parseVariant(context, variant, data)
27
28
  );
29
+ const localeStr = getLanguageCodeFromLocale(context.languageContext.locale) || "en";
28
30
  return {
29
31
  identifier: { key: data.id },
30
- name: data.name[context.languageContext.locale] || data.id,
31
- slug: data.slug?.[context.languageContext.locale] || data.id,
32
+ name: data.name[localeStr] || data.id,
33
+ slug: data.slug?.[localeStr] || data.id,
32
34
  variants
33
35
  };
34
36
  }
@@ -38,7 +40,7 @@ class CommercetoolsProductAssociationsFactory {
38
40
  sourceUrl: sourceImage?.url || "",
39
41
  height: sourceImage?.dimensions.h || void 0,
40
42
  width: sourceImage?.dimensions.w || void 0,
41
- altText: sourceImage?.label || product.name[context.languageContext.locale] || void 0
43
+ altText: sourceImage?.label || product.name[getLanguageCodeFromLocale(context.languageContext.locale)] || void 0
42
44
  });
43
45
  const mappedOptions = variant.attributes?.filter((attribute) => attribute.name === "Color").map(
44
46
  (option) => ProductVariantOptionSchema.parse({
@@ -9,6 +9,7 @@ import {
9
9
  ProductVariantIdentifierSchema,
10
10
  ProductVariantOptionSchema
11
11
  } from "@reactionary/core";
12
+ import { getLanguageCodeFromLocale } from "../../core/locale-utils.js";
12
13
  class CommercetoolsProductSearchFactory {
13
14
  productSearchResultSchema;
14
15
  constructor(productSearchResultSchema) {
@@ -43,9 +44,10 @@ class CommercetoolsProductSearchFactory {
43
44
  return this.productSearchResultSchema.parse(result);
44
45
  }
45
46
  parseSingle(context, data) {
47
+ const localeStr = getLanguageCodeFromLocale(context.languageContext.locale) || "en";
46
48
  const identifier = { key: data.key || data.id };
47
- const name = data.name[context.languageContext.locale] || data.id;
48
- const slug = data.slug?.[context.languageContext.locale] || data.id;
49
+ const name = data.name[localeStr] || data.id;
50
+ const slug = data.slug?.[localeStr] || data.id;
49
51
  const variants = [data.masterVariant, ...data.variants].map(
50
52
  (variant) => this.parseVariant(context, variant, data)
51
53
  );
@@ -84,12 +86,13 @@ class CommercetoolsProductSearchFactory {
84
86
  });
85
87
  }
86
88
  parseVariant(context, variant, product) {
89
+ const localeStr = getLanguageCodeFromLocale(context.languageContext.locale);
87
90
  const sourceImage = variant.images?.[0];
88
91
  const image = ImageSchema.parse({
89
92
  sourceUrl: sourceImage?.url || "",
90
93
  height: sourceImage?.dimensions.h || void 0,
91
94
  width: sourceImage?.dimensions.w || void 0,
92
- altText: sourceImage?.label || product.name[context.languageContext.locale] || void 0
95
+ altText: sourceImage?.label || product.name[localeStr] || void 0
93
96
  });
94
97
  const mappedOptions = variant.attributes?.filter((attribute) => attribute.name === "Color").map(
95
98
  (option) => ProductVariantOptionSchema.parse({
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@reactionary/commercetools",
3
- "version": "0.7.5",
3
+ "version": "0.8.0",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "types": "./src/index.d.ts",
7
7
  "dependencies": {
8
8
  "vitest": "^4.0.9",
9
9
  "@nx/vite": "22.4.5",
10
- "@reactionary/core": "0.7.5",
10
+ "@reactionary/core": "0.8.0",
11
11
  "zod": "4.1.9",
12
12
  "@commercetools/ts-client": "^4.9.1",
13
13
  "@commercetools/platform-sdk": "^8.25.0",
@@ -9,6 +9,10 @@ export declare class CommercetoolsProductSearchCapability<TFactory extends Produ
9
9
  protected config: CommercetoolsConfiguration;
10
10
  protected commercetools: CommercetoolsAPI;
11
11
  protected factory: ProductSearchFactoryWithOutput<TFactory>;
12
+ /**
13
+ * We assume all commercetools data is indexed on the language level, not the country subdivision
14
+ */
15
+ protected languageCode: string;
12
16
  constructor(config: CommercetoolsConfiguration, cache: Cache, context: RequestContext, commercetools: CommercetoolsAPI, factory: ProductSearchFactoryWithOutput<TFactory>);
13
17
  protected getClient(): Promise<import("@commercetools/platform-sdk").ByProjectKeyProductsRequestBuilder>;
14
18
  protected getFacetQuery(payload: ProductSearchQueryByTerm, selectedFacetValue: FacetValueIdentifier): Promise<{
@@ -16,12 +20,14 @@ export declare class CommercetoolsProductSearchCapability<TFactory extends Produ
16
20
  field: string;
17
21
  values: string[];
18
22
  fieldType: string;
23
+ language?: undefined;
19
24
  value?: undefined;
20
25
  };
21
26
  } | {
22
27
  exact: {
23
28
  field: string;
24
29
  fieldType: string;
30
+ language: string;
25
31
  value: string;
26
32
  values?: undefined;
27
33
  };
@@ -49,12 +55,14 @@ export declare class CommercetoolsProductSearchCapability<TFactory extends Produ
49
55
  field: string;
50
56
  values: string[];
51
57
  fieldType: string;
58
+ language?: undefined;
52
59
  value?: undefined;
53
60
  };
54
61
  } | {
55
62
  exact: {
56
63
  field: string;
57
64
  fieldType: string;
65
+ language: string;
58
66
  value: string;
59
67
  values?: undefined;
60
68
  };
@@ -64,12 +72,14 @@ export declare class CommercetoolsProductSearchCapability<TFactory extends Produ
64
72
  field: string;
65
73
  values: string[];
66
74
  fieldType: string;
75
+ language?: undefined;
67
76
  value?: undefined;
68
77
  };
69
78
  } | {
70
79
  exact: {
71
80
  field: string;
72
81
  fieldType: string;
82
+ language: string;
73
83
  value: string;
74
84
  values?: undefined;
75
85
  };
@@ -0,0 +1 @@
1
+ export declare function getLanguageCodeFromLocale(locale: string): string;