@reactionary/commercetools 0.6.9 → 0.7.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.
@@ -11,6 +11,7 @@ var __decorateClass = (decorators, target, key, kind) => {
11
11
  };
12
12
  import {
13
13
  error,
14
+ ProductListCapability,
14
15
  ProductListItemMutationCreateSchema,
15
16
  ProductListItemMutationDeleteSchema,
16
17
  ProductListItemMutationUpdateSchema,
@@ -21,7 +22,6 @@ import {
21
22
  ProductListMutationDeleteSchema,
22
23
  ProductListMutationUpdateSchema,
23
24
  ProductListPaginatedResultsSchema,
24
- ProductListCapability,
25
25
  ProductListQueryByIdSchema,
26
26
  ProductListQuerySchema,
27
27
  ProductListSchema,
@@ -38,15 +38,62 @@ class CommercetoolsProductListCapability extends ProductListCapability {
38
38
  this.commercetools = commercetools;
39
39
  this.factory = factory;
40
40
  }
41
- async getClient() {
42
- const client = await this.commercetools.getClient();
43
- return client.withProjectKey({ projectKey: this.config.projectKey }).me();
41
+ /**
42
+ * Creates a new Commercetools client, optionally upgrading it from Anonymous mode to Guest mode.
43
+ * For now, any Query or Mutation will require an upgrade to Guest mode.
44
+ * In the future, maybe we can delay this upgrade until we actually need it.
45
+ */
46
+ async getClient(companyIdentifier) {
47
+ let client;
48
+ if (companyIdentifier) {
49
+ client = await this.commercetools.getClientForCompany(companyIdentifier);
50
+ } else {
51
+ client = (await this.commercetools.getClient()).withProjectKey({ projectKey: this.config.projectKey }).me();
52
+ }
53
+ return client;
54
+ }
55
+ async isMine(listIdentifier) {
56
+ if (this.context.session.identityContext?.identity.type !== "Registered") {
57
+ return false;
58
+ }
59
+ if (this.context.session.identityContext?.identity.id.userId === listIdentifier.user?.userId) {
60
+ return true;
61
+ }
62
+ return false;
63
+ }
64
+ async getCompanyForList(listIdentifier) {
65
+ if ("version" in listIdentifier && "company" in listIdentifier) {
66
+ return listIdentifier.company;
67
+ }
68
+ const client = await this.getClient();
69
+ try {
70
+ const listResponse = await client.shoppingLists().withId({ ID: listIdentifier.key }).get().execute();
71
+ if (listResponse.body.businessUnit) {
72
+ return {
73
+ taxIdentifier: listResponse.body.businessUnit.key
74
+ };
75
+ }
76
+ return void 0;
77
+ } catch (e) {
78
+ console.error("Error fetching list for company information:", e);
79
+ return void 0;
80
+ }
44
81
  }
45
82
  async getById(payload) {
46
83
  try {
47
- const client = await this.getClient();
84
+ const companyIdentifier = await this.getCompanyForList(payload.identifier);
85
+ const client = await this.getClient(companyIdentifier);
48
86
  const response = await client.shoppingLists().withId({ ID: payload.identifier.key }).get().execute();
49
- return success(this.factory.parseProductList(this.context, this.parseSingle(response.body)));
87
+ const payloadResult = this.factory.parseProductList(this.context, response.body);
88
+ if (!await this.isMine(payloadResult.identifier)) {
89
+ if (!payloadResult.published) {
90
+ return error({
91
+ type: "NotFound",
92
+ identifier: payload.identifier
93
+ });
94
+ }
95
+ }
96
+ return success(payloadResult);
50
97
  } catch (err) {
51
98
  if (err.statusCode === 404) {
52
99
  return error({
@@ -61,65 +108,101 @@ class CommercetoolsProductListCapability extends ProductListCapability {
61
108
  async queryLists(payload) {
62
109
  if (this.context.session.identityContext?.identity?.type !== "Registered") {
63
110
  return success(this.factory.parseProductListPaginatedResult(this.context, {
64
- items: [],
65
- pageNumber: 1,
66
- pageSize: payload.search.paginationOptions.pageSize,
67
- totalCount: 0,
68
- totalPages: 0,
69
- identifier: payload.search
70
- }));
111
+ limit: payload.search.paginationOptions.pageSize,
112
+ offset: (payload.search.paginationOptions.pageNumber - 1) * payload.search.paginationOptions.pageSize,
113
+ count: payload.search.paginationOptions.pageSize,
114
+ results: [],
115
+ total: 0
116
+ }, payload));
71
117
  }
72
- const client = await this.getClient();
118
+ const client = await this.getClient(payload.search.company);
119
+ let where = ``;
120
+ const listTypeFilter = `custom(fields(listType=:listType))`;
121
+ const allOfMineFilter = `(customer(id=:customerId))`;
122
+ const othersFilter = `(customer(id != :customerId) and custom(fields(published=true)))`;
123
+ let companyFilter = `businessUnit is not defined`;
124
+ if (payload.search.company) {
125
+ companyFilter = `businessUnit(key=:companyKey)`;
126
+ }
127
+ where = `((${listTypeFilter}) and (${companyFilter})) and (${allOfMineFilter} or ${othersFilter})`;
128
+ const customerId = this.context.session.identityContext?.identity.type === "Registered" ? this.context.session.identityContext?.identity.id.userId : "anonymous";
129
+ const companyKey = payload.search.company?.taxIdentifier || void 0;
73
130
  const response = await client.shoppingLists().get({
74
131
  queryArgs: {
75
- where: `custom(fields(listType=:listType))`,
132
+ where,
76
133
  sort: "createdAt desc",
77
134
  "var.listType": payload.search.listType,
135
+ "var.published": true,
136
+ "var.customerId": customerId,
137
+ "var.companyKey": companyKey,
78
138
  limit: payload.search.paginationOptions.pageSize,
79
139
  offset: (payload.search.paginationOptions.pageNumber - 1) * payload.search.paginationOptions.pageSize
80
140
  }
81
141
  }).execute();
82
- return success(this.factory.parseProductListPaginatedResult(this.context, {
83
- items: response.body.results.map((list) => this.parseSingle(list)),
84
- pageNumber: payload.search.paginationOptions.pageNumber,
85
- pageSize: payload.search.paginationOptions.pageSize,
86
- totalCount: response.body.total || 0,
87
- totalPages: Math.ceil((response.body.total || 0) / payload.search.paginationOptions.pageSize),
88
- identifier: payload.search
89
- }));
142
+ return success(this.factory.parseProductListPaginatedResult(this.context, response.body, payload));
90
143
  }
91
- async addList(mutation) {
92
- const client = await this.getClient();
144
+ addListPayload(payload) {
93
145
  const localeString = this.getLocaleString();
146
+ let businessUnitReference = void 0;
147
+ let customerReference = void 0;
148
+ if (payload.company) {
149
+ businessUnitReference = {
150
+ typeId: "business-unit",
151
+ key: payload.company.taxIdentifier
152
+ };
153
+ if (this.context.session.identityContext?.identity.type === "Registered" && this.context.session.identityContext?.identity.id) {
154
+ customerReference = {
155
+ typeId: "customer",
156
+ id: this.context.session.identityContext?.identity.id.userId
157
+ };
158
+ }
159
+ }
160
+ const customFields = {
161
+ type: {
162
+ typeId: "type",
163
+ key: "reactionaryShoppingList"
164
+ },
165
+ fields: {
166
+ listType: payload.list.type,
167
+ imageUrl: payload.list.image ? payload.list.image.sourceUrl : void 0,
168
+ publishedDate: payload.list.publishDate ? new Date(payload.list.publishDate) : void 0,
169
+ published: payload.list.published && true
170
+ }
171
+ };
172
+ const draft = {
173
+ name: { [localeString]: payload.list.name },
174
+ businessUnit: businessUnitReference,
175
+ customer: customerReference,
176
+ description: payload.list.description ? { [localeString]: payload.list.description } : void 0,
177
+ custom: customFields
178
+ };
179
+ return draft;
180
+ }
181
+ async addList(mutation) {
182
+ const client = await this.getClient(mutation.company);
94
183
  if (this.context.session.identityContext?.identity?.type !== "Registered") {
95
184
  return error({
96
185
  type: "InvalidInput",
97
186
  error: "Only registered users can have product lists"
98
187
  });
99
188
  }
100
- const draft = {
101
- name: { [localeString]: mutation.list.name },
102
- description: mutation.list.description ? { [localeString]: mutation.list.description } : void 0,
103
- custom: {
104
- type: {
105
- key: "reactionaryShoppingList",
106
- typeId: "type"
107
- },
108
- fields: {
109
- listType: mutation.list.type,
110
- imageUrl: mutation.list.image ? mutation.list.image.sourceUrl : void 0,
111
- publishedDate: mutation.list.publishDate ? new Date(mutation.list.publishDate) : void 0,
112
- published: mutation.list.published || true
113
- }
114
- }
115
- };
189
+ const list = this.addListPayload(mutation);
116
190
  const response = await client.shoppingLists().post({
117
- body: draft
191
+ body: list
118
192
  }).execute();
119
- return success(this.factory.parseProductList(this.context, this.parseSingle(response.body)));
193
+ return success(this.factory.parseProductList(this.context, response.body));
120
194
  }
121
195
  async updateList(mutation) {
122
- const client = await this.getClient();
196
+ const companyIdentifier = await this.getCompanyForList(mutation.list);
197
+ const client = await this.getClient(companyIdentifier);
198
+ if (!await this.isMine(mutation.list)) {
199
+ if (await this.isUnpublished(mutation.list, client)) {
200
+ return error({
201
+ type: "InvalidInput",
202
+ error: "Cannot update a list that is not yours, unless it is published"
203
+ });
204
+ }
205
+ }
123
206
  const actions = [];
124
207
  const localeString = this.getLocaleString();
125
208
  if (mutation.name) {
@@ -161,10 +244,19 @@ class CommercetoolsProductListCapability extends ProductListCapability {
161
244
  actions
162
245
  };
163
246
  const response = await client.shoppingLists().withId({ ID: mutation.list.key }).post({ body: update }).execute();
164
- return success(this.factory.parseProductList(this.context, this.parseSingle(response.body)));
247
+ return success(this.factory.parseProductList(this.context, response.body));
165
248
  }
166
249
  async deleteList(mutation) {
167
- const client = await this.getClient();
250
+ const companyIdentifier = await this.getCompanyForList(mutation.list);
251
+ const client = await this.getClient(companyIdentifier);
252
+ if (!await this.isMine(mutation.list)) {
253
+ if (await this.isUnpublished(mutation.list, client)) {
254
+ return error({
255
+ type: "InvalidInput",
256
+ error: "Cannot delete from a list that is not yours, unless it is published"
257
+ });
258
+ }
259
+ }
168
260
  const newestVersion = await client.shoppingLists().withId({ ID: mutation.list.key }).get().execute().then((response) => response.body.version);
169
261
  await client.shoppingLists().withId({ ID: mutation.list.key }).delete({
170
262
  queryArgs: {
@@ -174,22 +266,25 @@ class CommercetoolsProductListCapability extends ProductListCapability {
174
266
  return success(void 0);
175
267
  }
176
268
  async queryListItems(query) {
177
- const client = await this.getClient();
269
+ const companyIdentifier = await this.getCompanyForList(query.search.list);
270
+ const client = await this.getClient(companyIdentifier);
178
271
  const response = await client.shoppingLists().withId({ ID: query.search.list.key }).get({
179
272
  queryArgs: { expand: "lineItems[*].variant" }
180
273
  }).execute();
181
- const items = response.body.lineItems.map((lineItem) => this.parseProductListItem(query.search.list, lineItem));
182
- return success(this.factory.parseProductListItemPaginatedResult(this.context, {
183
- items: items.slice((query.search.paginationOptions.pageNumber - 1) * query.search.paginationOptions.pageSize, query.search.paginationOptions.pageNumber * query.search.paginationOptions.pageSize),
184
- identifier: query.search,
185
- pageNumber: query.search.paginationOptions.pageNumber,
186
- pageSize: query.search.paginationOptions.pageSize,
187
- totalCount: items.length,
188
- totalPages: Math.ceil(items.length / query.search.paginationOptions.pageSize)
189
- }));
274
+ return success(this.factory.parseProductListItemPaginatedResult(this.context, response.body, query));
190
275
  }
191
276
  async addItem(mutation) {
192
- const client = await this.getClient();
277
+ const companyIdentifier = await this.getCompanyForList(mutation.list);
278
+ const client = await this.getClient(companyIdentifier);
279
+ const myList = await this.isMine(mutation.list);
280
+ if (!myList) {
281
+ if (await this.isUnpublished(mutation.list, client)) {
282
+ return error({
283
+ type: "InvalidInput",
284
+ error: "Cannot add items to a list that is not yours, unless it is published"
285
+ });
286
+ }
287
+ }
193
288
  const lineItemDraft = {
194
289
  action: "addLineItem",
195
290
  sku: mutation.listItem.variant.sku,
@@ -215,10 +310,24 @@ class CommercetoolsProductListCapability extends ProductListCapability {
215
310
  if (lastItem.variant?.sku !== mutation.listItem.variant.sku) {
216
311
  throw new Error("The added line item is not the last item in the list, cannot reliably determine the identifier of the added item");
217
312
  }
218
- return success(this.factory.parseProductListItem(this.context, this.parseProductListItem(mutation.list, lastItem)));
313
+ return success(this.factory.parseProductListItem(this.context, { listIdentifier: mutation.list, lineItem: lastItem }));
314
+ }
315
+ async isUnpublished(list, client) {
316
+ const response = await client.shoppingLists().withId({ ID: list.key }).get().execute();
317
+ const isPublished = response.body.custom?.fields["published"] && true;
318
+ return !isPublished;
219
319
  }
220
320
  async deleteItem(mutation) {
221
- const client = await this.getClient();
321
+ const companyIdentifier = await this.getCompanyForList(mutation.listItem.list);
322
+ const client = await this.getClient(companyIdentifier);
323
+ if (!await this.isMine(mutation.listItem.list)) {
324
+ if (await this.isUnpublished(mutation.listItem.list, client)) {
325
+ return error({
326
+ type: "InvalidInput",
327
+ error: "Cannot delete items to a list that is not yours, unless it is published"
328
+ });
329
+ }
330
+ }
222
331
  const update = {
223
332
  version: 0,
224
333
  // The auto-correcting middleware will deal with the version
@@ -231,7 +340,16 @@ class CommercetoolsProductListCapability extends ProductListCapability {
231
340
  return success(void 0);
232
341
  }
233
342
  async updateItem(mutation) {
234
- const client = await this.getClient();
343
+ const companyIdentifier = await this.getCompanyForList(mutation.listItem.list);
344
+ const client = await this.getClient(companyIdentifier);
345
+ if (!await this.isMine(mutation.listItem.list)) {
346
+ if (await this.isUnpublished(mutation.listItem.list, client)) {
347
+ return error({
348
+ type: "InvalidInput",
349
+ error: "Cannot update items in a list that is not yours, unless it is published"
350
+ });
351
+ }
352
+ }
235
353
  const actions = [];
236
354
  if (mutation.quantity !== void 0) {
237
355
  actions.push({
@@ -265,7 +383,7 @@ class CommercetoolsProductListCapability extends ProductListCapability {
265
383
  if (!updatedLineItem) {
266
384
  throw new Error("Failed to find the updated line item in response");
267
385
  }
268
- return success(this.factory.parseProductListItem(this.context, this.parseProductListItem(mutation.listItem.list, updatedLineItem)));
386
+ return success(this.factory.parseProductListItem(this.context, { listIdentifier: mutation.listItem.list, lineItem: updatedLineItem }));
269
387
  }
270
388
  /**
271
389
  * It is not clear to me, why i'd want my CUSTOMER defined resources to be localized, since that means, if he changes visual language,
@@ -274,48 +392,6 @@ class CommercetoolsProductListCapability extends ProductListCapability {
274
392
  getLocaleString() {
275
393
  return "en";
276
394
  }
277
- parseSingle(list) {
278
- const localeString = this.getLocaleString();
279
- const listType = list.custom?.fields["listType"] || "favorite";
280
- const image = list.custom?.fields["imageUrl"];
281
- const published = list.custom?.fields["published"] && true;
282
- const publishDateDate = list.custom?.fields["publishedDate"];
283
- let publishedDate;
284
- if (publishDateDate) {
285
- publishedDate = new Date(publishDateDate).toISOString();
286
- }
287
- return {
288
- identifier: {
289
- listType,
290
- key: list.id
291
- },
292
- type: listType,
293
- name: list.name[localeString] || "Unnamed List",
294
- description: list.description?.[localeString] || "",
295
- published,
296
- publishDate: publishedDate,
297
- image: {
298
- sourceUrl: image || "",
299
- altText: list.name[localeString] || "List Image"
300
- }
301
- };
302
- }
303
- parseProductListItem(listIdentifier, lineItem) {
304
- const localeString = this.getLocaleString();
305
- return {
306
- identifier: {
307
- list: listIdentifier,
308
- key: lineItem.id
309
- },
310
- variant: {
311
- sku: lineItem.variant?.sku || ""
312
- },
313
- quantity: lineItem.quantity,
314
- notes: lineItem.custom?.fields["notes"] || "",
315
- order: lineItem.custom?.fields["order"] || 1
316
- // Commercetools doesn't have explicit ordering
317
- };
318
- }
319
395
  }
320
396
  __decorateClass([
321
397
  Reactionary({
@@ -26,7 +26,8 @@ import {
26
26
  ProfileSchema,
27
27
  PriceSchema,
28
28
  ShippingMethodSchema,
29
- StoreSchema
29
+ StoreSchema,
30
+ CartPaginatedSearchResultSchema
30
31
  } from "@reactionary/core";
31
32
  import {
32
33
  } from "../schema/capabilities.schema.js";
@@ -186,7 +187,7 @@ const capabilityDescriptors = {
186
187
  cart: {
187
188
  isEnabled: (caps) => caps.cart?.enabled,
188
189
  getOverride: (caps) => caps.cart,
189
- createDefaultFactory: () => new CommercetoolsCartFactory(CartSchema, CartIdentifierSchema),
190
+ createDefaultFactory: () => new CommercetoolsCartFactory(CartSchema, CartIdentifierSchema, CartPaginatedSearchResultSchema),
190
191
  createDefaultCapability: (args) => new CommercetoolsCartCapability(
191
192
  args.config,
192
193
  args.cache,
package/core/client.js CHANGED
@@ -10,7 +10,9 @@ import {
10
10
  import * as crypto from "crypto";
11
11
  import createDebug from "debug";
12
12
  import { RequestContextTokenCache } from "./token-cache.js";
13
- import { CommercetoolsSessionSchema } from "../schema/session.schema.js";
13
+ import {
14
+ CommercetoolsSessionSchema
15
+ } from "../schema/session.schema.js";
14
16
  const debug = createDebug("reactionary:commercetools");
15
17
  const PROVIDER_SESSION_KEY = "COMMERCETOOLS_PROVIDER";
16
18
  class CommercetoolsAPI {
@@ -22,7 +24,10 @@ class CommercetoolsAPI {
22
24
  constructor(config, context) {
23
25
  this.config = config;
24
26
  this.context = context;
25
- this.tokenCache = new RequestContextTokenCache(this.context, PROVIDER_SESSION_KEY);
27
+ this.tokenCache = new RequestContextTokenCache(
28
+ this.context,
29
+ PROVIDER_SESSION_KEY
30
+ );
26
31
  }
27
32
  async getClient() {
28
33
  if (!this.client) {
@@ -30,6 +35,17 @@ class CommercetoolsAPI {
30
35
  }
31
36
  return this.client;
32
37
  }
38
+ async getClientForCompany(company) {
39
+ if (this.context.session.identityContext.identity.type !== "Registered") {
40
+ throw new Error("Only registered identities can have company clients");
41
+ }
42
+ const companyClient = (await this.getAdminClient()).withProjectKey({ projectKey: this.config.projectKey }).asAssociate().withAssociateIdValue({
43
+ associateId: this.context.session.identityContext.identity.id.userId
44
+ }).inBusinessUnitKeyWithBusinessUnitKeyValue({
45
+ businessUnitKey: company.taxIdentifier
46
+ });
47
+ return companyClient;
48
+ }
33
49
  async getAdminClient() {
34
50
  if (!this.adminClient) {
35
51
  this.adminClient = this.createAdminClient();
@@ -189,7 +205,11 @@ class CommercetoolsAPI {
189
205
  });
190
206
  }
191
207
  async logout() {
192
- await this.tokenCache.set({ token: "", refreshToken: "", expirationTime: 0 });
208
+ await this.tokenCache.set({
209
+ token: "",
210
+ refreshToken: "",
211
+ expirationTime: 0
212
+ });
193
213
  const identity = {
194
214
  type: "Anonymous"
195
215
  };
@@ -4,21 +4,64 @@ import {
4
4
  class CommercetoolsCartFactory {
5
5
  cartSchema;
6
6
  cartIdentifierSchema;
7
- constructor(cartSchema, cartIdentifierSchema) {
7
+ cartPaginatedSearchResultSchema;
8
+ constructor(cartSchema, cartIdentifierSchema, cartPaginatedSearchResultSchema) {
8
9
  this.cartSchema = cartSchema;
9
10
  this.cartIdentifierSchema = cartIdentifierSchema;
11
+ this.cartPaginatedSearchResultSchema = cartPaginatedSearchResultSchema;
12
+ }
13
+ parseCartPaginatedSearchResult(_context, data, _query) {
14
+ const result = {
15
+ pageNumber: _query.search.paginationOptions.pageNumber,
16
+ pageSize: _query.search.paginationOptions.pageSize,
17
+ totalCount: data.total || 0,
18
+ totalPages: Math.ceil(
19
+ (data.total || 0) / _query.search.paginationOptions.pageSize
20
+ ),
21
+ items: data.results.map(
22
+ (cart) => this.parseCartSearchResultItem(_context, cart)
23
+ ),
24
+ identifier: _query.search
25
+ };
26
+ return this.cartPaginatedSearchResultSchema.parse(result);
10
27
  }
11
28
  parseCartIdentifier(_context, data) {
12
29
  return this.cartIdentifierSchema.parse({
13
- key: data.key || "",
14
- version: data.version || 0
30
+ key: data.id || "",
31
+ version: data.version || 0,
32
+ company: data.businessUnit ? { taxIdentifier: data.businessUnit.key } : void 0
15
33
  });
16
34
  }
35
+ parseCartSearchResultItem(context, data) {
36
+ const identifier = this.parseCartIdentifier(context, data);
37
+ const numItems = data.lineItems.length;
38
+ const lastModifiedDate = data.lastModifiedAt;
39
+ let company;
40
+ if (data.businessUnit) {
41
+ company = {
42
+ taxIdentifier: data.businessUnit.key
43
+ };
44
+ }
45
+ const result = {
46
+ identifier,
47
+ user: {
48
+ userId: data.customerId || data.anonymousId || "???"
49
+ },
50
+ company,
51
+ name: data.custom?.fields["name"] || "",
52
+ numItems,
53
+ lastModifiedDate
54
+ };
55
+ return result;
56
+ }
17
57
  parseCart(context, data) {
18
- const identifier = this.parseCartIdentifier(context, {
19
- key: data.id,
20
- version: data.version
21
- });
58
+ const identifier = this.parseCartIdentifier(context, data);
59
+ let company;
60
+ if (data.businessUnit) {
61
+ company = {
62
+ taxIdentifier: data.businessUnit.key
63
+ };
64
+ }
22
65
  const items = [];
23
66
  for (const lineItem of data.lineItems) {
24
67
  items.push(this.parseCartItem(lineItem));
@@ -73,9 +116,10 @@ class CommercetoolsCartFactory {
73
116
  }
74
117
  const result = {
75
118
  identifier,
76
- userId: {
77
- userId: "???"
119
+ user: {
120
+ userId: data.customerId || data.anonymousId || "???"
78
121
  },
122
+ company,
79
123
  name: data.custom?.fields["name"] || "",
80
124
  description: data.custom?.fields["description"] || "",
81
125
  price,
@@ -104,7 +148,13 @@ class CommercetoolsCartFactory {
104
148
  const currency = lineItem.price.value.currencyCode.toUpperCase();
105
149
  return CartItemSchema.parse({
106
150
  identifier: {
107
- key: lineItem.id
151
+ key: lineItem.id,
152
+ ...lineItem.priceMode === "ExternalPrice" && {
153
+ originalPrice: {
154
+ value: lineItem.price.value.centAmount / 100,
155
+ currency
156
+ }
157
+ }
108
158
  },
109
159
  product: {
110
160
  key: lineItem.productId
@@ -11,53 +11,88 @@ class CommercetoolsProductListFactory {
11
11
  this.productListPaginatedSchema = productListPaginatedSchema;
12
12
  this.productListItemPaginatedSchema = productListItemPaginatedSchema;
13
13
  }
14
- parseProductList(_context, data) {
15
- return this.productListSchema.parse(data);
16
- }
17
- parseProductListItem(_context, data) {
18
- return this.productListItemSchema.parse(data);
19
- }
20
- parseProductListPaginatedResult(_context, data) {
21
- return this.productListPaginatedSchema.parse(data);
22
- }
23
- parseProductListItemPaginatedResult(_context, data) {
24
- return this.productListItemPaginatedSchema.parse(data);
14
+ /**
15
+ * This is a customer owned resource, so we just use english as otherwise it will fail if he changes the visual language settings.
16
+ * @returns
17
+ */
18
+ getLocaleString() {
19
+ return "en";
25
20
  }
26
- parseListFromCommercetools(list) {
27
- const listType = list.custom?.fields["listType"] || "favorite";
28
- const image = list.custom?.fields["imageUrl"];
29
- const published = list.custom?.fields["published"] && true;
30
- const publishDateValue = list.custom?.fields["publishedDate"];
31
- const publishDate = publishDateValue ? new Date(publishDateValue).toISOString() : void 0;
32
- return this.productListSchema.parse({
21
+ parseProductList(_context, data) {
22
+ const localeString = this.getLocaleString();
23
+ const listType = data.custom?.fields["listType"] || "favorite";
24
+ const image = data.custom?.fields["imageUrl"];
25
+ const published = data.custom?.fields["published"] && true;
26
+ const publishDateDate = data.custom?.fields["publishedDate"];
27
+ let publishedDate;
28
+ if (publishDateDate) {
29
+ publishedDate = new Date(publishDateDate).toISOString();
30
+ }
31
+ const result = {
33
32
  identifier: {
34
33
  listType,
35
- key: list.id
34
+ key: data.id,
35
+ user: data.customer ? {
36
+ userId: data.customer.id
37
+ } : void 0,
38
+ version: Number(data.version),
39
+ company: data.businessUnit ? { taxIdentifier: data.businessUnit.key } : void 0
36
40
  },
37
41
  type: listType,
38
- name: list.name["en"] || "Unnamed List",
39
- description: list.description?.["en"] || "",
42
+ name: data.name[localeString] || "Unnamed List",
43
+ description: data.description?.[localeString] || "",
40
44
  published,
41
- publishDate,
45
+ publishDate: publishedDate,
42
46
  image: {
43
47
  sourceUrl: image || "",
44
- altText: list.name["en"] || "List Image"
48
+ altText: data.name[localeString] || "List Image"
45
49
  }
46
- });
50
+ };
51
+ return this.productListSchema.parse(result);
47
52
  }
48
- parseListItemFromCommercetools(listIdentifier, lineItem) {
49
- return this.productListItemSchema.parse({
53
+ parseProductListItem(_context, data) {
54
+ const localeString = this.getLocaleString();
55
+ const result = {
50
56
  identifier: {
51
- list: listIdentifier,
52
- key: lineItem.id
57
+ list: data.listIdentifier,
58
+ key: data.lineItem.id
53
59
  },
54
60
  variant: {
55
- sku: lineItem.variant?.sku || ""
61
+ sku: data.lineItem.variant?.sku || ""
56
62
  },
57
- quantity: lineItem.quantity,
58
- notes: lineItem.custom?.fields["notes"] || "",
59
- order: lineItem.custom?.fields["order"] || 1
60
- });
63
+ quantity: data.lineItem.quantity,
64
+ notes: data.lineItem.custom?.fields["notes"] || "",
65
+ order: data.lineItem.custom?.fields["order"] || 1
66
+ // Commercetools doesn't have explicit ordering
67
+ };
68
+ return this.productListItemSchema.parse(result);
69
+ }
70
+ parseProductListPaginatedResult(context, data, query) {
71
+ const result = {
72
+ items: (data.results || []).map((list) => this.parseProductList(context, list)),
73
+ pageNumber: query.search.paginationOptions.pageNumber,
74
+ pageSize: query.search.paginationOptions.pageSize,
75
+ totalCount: data.total || 0,
76
+ totalPages: Math.ceil((data.total || 0) / query.search.paginationOptions.pageSize),
77
+ identifier: query.search
78
+ };
79
+ return this.productListPaginatedSchema.parse(result);
80
+ }
81
+ parseProductListItemPaginatedResult(context, data, query) {
82
+ const originalItemCount = data.lineItems.length;
83
+ const items = (data.lineItems || []).slice((query.search.paginationOptions.pageNumber - 1) * query.search.paginationOptions.pageSize, query.search.paginationOptions.pageNumber * query.search.paginationOptions.pageSize);
84
+ const result = {
85
+ items: items.map((x) => this.parseProductListItem(context, {
86
+ listIdentifier: query.search.list,
87
+ lineItem: x
88
+ })),
89
+ identifier: query.search,
90
+ pageNumber: query.search.paginationOptions.pageNumber,
91
+ pageSize: query.search.paginationOptions.pageSize,
92
+ totalCount: originalItemCount,
93
+ totalPages: Math.ceil(originalItemCount / query.search.paginationOptions.pageSize)
94
+ };
95
+ return this.productListItemPaginatedSchema.parse(result);
61
96
  }
62
97
  }
63
98
  export {