@reactionary/commercetools 0.6.9 → 0.6.10

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.
@@ -10,24 +10,26 @@ var __decorateClass = (decorators, target, key, kind) => {
10
10
  return result;
11
11
  };
12
12
  import {
13
+ assertSuccess,
14
+ CartCapability,
13
15
  CartIdentifierSchema,
14
16
  CartMutationApplyCouponSchema,
15
17
  CartMutationChangeCurrencySchema,
18
+ CartMutationCreateCartSchema,
16
19
  CartMutationDeleteCartSchema,
17
20
  CartMutationItemAddSchema,
18
21
  CartMutationItemQuantityChangeSchema,
19
22
  CartMutationItemRemoveSchema,
20
23
  CartMutationRemoveCouponSchema,
21
- CartCapability,
24
+ CartMutationRenameCartSchema,
25
+ CartPaginatedSearchResultSchema,
22
26
  CartQueryByIdSchema,
27
+ CartQueryListSchema,
23
28
  CartSchema,
24
- Reactionary,
25
- success,
26
29
  error,
27
- unwrapValue,
28
- assertSuccess
30
+ Reactionary,
31
+ success
29
32
  } from "@reactionary/core";
30
- import { CommercetoolsCartIdentifierSchema } from "../schema/commercetools.schema.js";
31
33
  class CommercetoolsCartCapability extends CartCapability {
32
34
  config;
33
35
  commercetools;
@@ -39,8 +41,80 @@ class CommercetoolsCartCapability extends CartCapability {
39
41
  this.commercetools = commercetools;
40
42
  this.factory = factory;
41
43
  }
44
+ async listCarts(payload) {
45
+ const cartsClient = (await this.getClient(payload.search.company)).carts;
46
+ let companyFilter = `businessUnit is not defined`;
47
+ if (payload.search.company) {
48
+ companyFilter = `businessUnit(key=:companyKey)`;
49
+ }
50
+ const where = `(${companyFilter})`;
51
+ const response = await cartsClient.get({
52
+ queryArgs: {
53
+ where,
54
+ limit: payload.search.paginationOptions.pageSize,
55
+ offset: (payload.search.paginationOptions.pageNumber - 1) * payload.search.paginationOptions.pageSize,
56
+ "var.companyKey": payload.search.company?.taxIdentifier
57
+ }
58
+ }).execute();
59
+ return success(this.factory.parseCartPaginatedSearchResult(this.context, response.body, payload));
60
+ }
61
+ async renameCart(payload) {
62
+ const actionResult = await this.applyActions(payload.cart, [
63
+ {
64
+ action: "setCustomField",
65
+ name: "name",
66
+ value: payload.newName
67
+ }
68
+ ]);
69
+ return success(actionResult);
70
+ }
71
+ createCartPayload(payload) {
72
+ let businessUnitReference = void 0;
73
+ let customerReference = void 0;
74
+ if (payload.company) {
75
+ businessUnitReference = {
76
+ typeId: "business-unit",
77
+ key: payload.company.taxIdentifier
78
+ };
79
+ if (this.context.session.identityContext?.identity.type === "Registered" && this.context.session.identityContext?.identity.id) {
80
+ customerReference = {
81
+ typeId: "customer",
82
+ id: this.context.session.identityContext?.identity.id.userId
83
+ };
84
+ }
85
+ }
86
+ const customFields = {
87
+ type: {
88
+ typeId: "type",
89
+ key: "reactionaryCart"
90
+ },
91
+ fields: {
92
+ name: payload.name
93
+ }
94
+ };
95
+ const body = {
96
+ currency: this.context.languageContext.currencyCode || "EUR",
97
+ country: this.context.taxJurisdiction.countryCode || "DK",
98
+ locale: this.context.languageContext.locale,
99
+ businessUnit: businessUnitReference,
100
+ ...customerReference ? { customerId: customerReference.id } : {},
101
+ custom: customFields
102
+ };
103
+ return body;
104
+ }
105
+ async createCart(payload) {
106
+ const cartsClient = (await this.getClient(payload.company)).carts;
107
+ const response = await cartsClient.post({
108
+ body: this.createCartPayload(payload),
109
+ queryArgs: {
110
+ expand: this.expandedCartFields
111
+ }
112
+ }).execute();
113
+ return success(this.factory.parseCart(this.context, response.body));
114
+ }
42
115
  async getById(payload) {
43
- const client = await this.getClient();
116
+ const company = await this.getCompanyForCart(payload.cart);
117
+ const client = await this.getClient(company);
44
118
  const ctId = payload.cart;
45
119
  try {
46
120
  const remote = await client.carts.withId({ ID: ctId.key }).get({
@@ -57,22 +131,27 @@ class CommercetoolsCartCapability extends CartCapability {
57
131
  }
58
132
  }
59
133
  async add(payload) {
60
- let cartIdentifier = payload.cart;
134
+ const cartIdentifier = payload.cart;
61
135
  if (!cartIdentifier) {
62
- cartIdentifier = await this.createCart();
136
+ return error({
137
+ type: "InvalidInput",
138
+ error: "Cart identifier is required to add item to cart. If you want to create a new cart, you can call the createCart mutation first."
139
+ });
63
140
  }
64
141
  const channelId = await this.commercetools.resolveChannelIdByRole("Primary");
142
+ const actions = [];
143
+ actions.push({
144
+ action: "addLineItem",
145
+ quantity: payload.quantity,
146
+ sku: payload.variant.sku,
147
+ // FIXME: This should be dynamic, probably as part of the context...
148
+ distributionChannel: {
149
+ typeId: "channel",
150
+ id: channelId
151
+ }
152
+ });
65
153
  const result = await this.applyActions(cartIdentifier, [
66
- {
67
- action: "addLineItem",
68
- quantity: payload.quantity,
69
- sku: payload.variant.sku,
70
- // FIXME: This should be dynamic, probably as part of the context...
71
- distributionChannel: {
72
- typeId: "channel",
73
- id: channelId
74
- }
75
- },
154
+ ...actions,
76
155
  {
77
156
  action: "recalculate"
78
157
  }
@@ -92,16 +171,18 @@ class CommercetoolsCartCapability extends CartCapability {
92
171
  return success(result);
93
172
  }
94
173
  async changeQuantity(payload) {
95
- if (payload.quantity === 0) {
96
- const existing = await this.getById({ cart: payload.cart });
97
- assertSuccess(existing);
98
- return existing;
99
- }
174
+ const lineIdentifier = payload.item;
100
175
  const result = await this.applyActions(payload.cart, [
101
176
  {
102
177
  action: "changeLineItemQuantity",
103
- lineItemId: payload.item.key,
104
- quantity: payload.quantity
178
+ lineItemId: lineIdentifier.key,
179
+ quantity: payload.quantity,
180
+ ...lineIdentifier.originalPrice && {
181
+ externalPrice: {
182
+ currencyCode: lineIdentifier.originalPrice.currency,
183
+ centAmount: Math.floor(lineIdentifier.originalPrice.value * 100)
184
+ }
185
+ }
105
186
  },
106
187
  {
107
188
  action: "recalculate"
@@ -112,11 +193,17 @@ class CommercetoolsCartCapability extends CartCapability {
112
193
  async getActiveCartId() {
113
194
  const client = await this.getClient();
114
195
  try {
115
- const carts = await client.activeCart.get().execute();
116
- const result = this.factory.parseCartIdentifier(this.context, {
117
- key: carts.body.id,
118
- version: carts.body.version || 0
119
- });
196
+ const carts = await client.carts.get({ queryArgs: {
197
+ sort: "lastModifiedAt desc",
198
+ limit: 1
199
+ } }).execute();
200
+ if (carts.body.results.length === 0) {
201
+ return error({
202
+ type: "NotFound",
203
+ identifier: {}
204
+ });
205
+ }
206
+ const result = this.factory.parseCartIdentifier(this.context, carts.body.results[0]);
120
207
  return success(result);
121
208
  } catch (e) {
122
209
  return error({
@@ -126,7 +213,8 @@ class CommercetoolsCartCapability extends CartCapability {
126
213
  }
127
214
  }
128
215
  async deleteCart(payload) {
129
- const client = await this.getClient();
216
+ const company = await this.getCompanyForCart(payload.cart);
217
+ const client = await this.getClient(company);
130
218
  if (payload.cart.key) {
131
219
  const ctId = payload.cart;
132
220
  await client.carts.withId({ ID: ctId.key }).delete({
@@ -151,7 +239,8 @@ class CommercetoolsCartCapability extends CartCapability {
151
239
  return success(result);
152
240
  }
153
241
  async removeCouponCode(payload) {
154
- const client = await this.getClient();
242
+ const company = await this.getCompanyForCart(payload.cart);
243
+ const client = await this.getClient(company);
155
244
  const currentCart = await client.carts.withId({ ID: payload.cart.key }).get({
156
245
  queryArgs: {
157
246
  expand: this.expandedCartFields
@@ -178,23 +267,29 @@ class CommercetoolsCartCapability extends CartCapability {
178
267
  return success(result);
179
268
  }
180
269
  async changeCurrency(payload) {
181
- const client = await this.getClient();
270
+ const company = await this.getCompanyForCart(payload.cart);
271
+ const client = await this.getClient(company);
182
272
  const currentCart = await client.carts.withId({ ID: payload.cart.key }).get().execute();
183
273
  const newCart = await client.carts.post({
184
274
  body: {
185
275
  currency: payload.newCurrency,
186
- locale: this.context.languageContext.locale
276
+ locale: this.context.languageContext.locale,
277
+ country: currentCart.body.country,
278
+ ...company && {
279
+ businessUnit: {
280
+ typeId: "business-unit",
281
+ key: company.taxIdentifier
282
+ }
283
+ }
187
284
  }
188
285
  }).execute();
189
- const newCartId = CommercetoolsCartIdentifierSchema.parse({
190
- key: newCart.body.id,
191
- version: newCart.body.version || 0
192
- });
286
+ const newCartId = this.factory.parseCartIdentifier(this.context, newCart.body);
193
287
  const cartItemAdds = currentCart.body.lineItems.map(
194
288
  (item) => ({
195
289
  action: "addLineItem",
196
290
  sku: item.variant.sku || "",
197
- quantity: item.quantity
291
+ quantity: item.quantity,
292
+ custom: item.custom
198
293
  })
199
294
  );
200
295
  const response = await this.applyActions(newCartId, [
@@ -211,25 +306,27 @@ class CommercetoolsCartCapability extends CartCapability {
211
306
  }).execute();
212
307
  return success(response);
213
308
  }
214
- async createCart() {
309
+ async getCompanyForCart(cart) {
310
+ if ("version" in cart && "company" in cart) {
311
+ return cart.company;
312
+ }
215
313
  const client = await this.getClient();
216
- const response = await client.carts.post({
217
- body: {
218
- currency: this.context.languageContext.currencyCode || "USD",
219
- country: this.context.taxJurisdiction.countryCode || "US",
220
- locale: this.context.languageContext.locale
221
- },
222
- queryArgs: {
223
- expand: this.expandedCartFields
314
+ try {
315
+ const cartResponse = await client.carts.withId({ ID: cart.key }).get().execute();
316
+ if (cartResponse.body.businessUnit) {
317
+ return {
318
+ taxIdentifier: cartResponse.body.businessUnit.key
319
+ };
224
320
  }
225
- }).execute();
226
- return this.factory.parseCartIdentifier(this.context, {
227
- key: response.body.id,
228
- version: response.body.version || 0
229
- });
321
+ return void 0;
322
+ } catch (e) {
323
+ console.error("Error fetching cart for company information:", e);
324
+ return void 0;
325
+ }
230
326
  }
231
327
  async applyActions(cart, actions) {
232
- const client = await this.getClient();
328
+ const company = await this.getCompanyForCart(cart);
329
+ const client = await this.getClient(company);
233
330
  const ctId = cart;
234
331
  try {
235
332
  const response = await client.carts.withId({ ID: ctId.key }).post({
@@ -255,18 +352,38 @@ class CommercetoolsCartCapability extends CartCapability {
255
352
  * For now, any Query or Mutation will require an upgrade to Guest mode.
256
353
  * In the future, maybe we can delay this upgrade until we actually need it.
257
354
  */
258
- async getClient() {
259
- const client = await this.commercetools.getClient();
260
- const clientWithProject = client.withProjectKey({
261
- projectKey: this.config.projectKey
262
- });
355
+ async getClient(companyIdentifier) {
356
+ let client;
357
+ if (companyIdentifier) {
358
+ client = await this.commercetools.getClientForCompany(companyIdentifier);
359
+ } else {
360
+ client = (await this.commercetools.getClient()).withProjectKey({ projectKey: this.config.projectKey }).me();
361
+ }
263
362
  return {
264
- carts: clientWithProject.me().carts(),
265
- activeCart: clientWithProject.me().activeCart(),
266
- orders: clientWithProject.me().orders()
363
+ carts: client.carts(),
364
+ orders: client.orders()
267
365
  };
268
366
  }
269
367
  }
368
+ __decorateClass([
369
+ Reactionary({
370
+ inputSchema: CartQueryListSchema,
371
+ outputSchema: CartPaginatedSearchResultSchema,
372
+ cache: false
373
+ })
374
+ ], CommercetoolsCartCapability.prototype, "listCarts", 1);
375
+ __decorateClass([
376
+ Reactionary({
377
+ inputSchema: CartMutationRenameCartSchema,
378
+ outputSchema: CartSchema
379
+ })
380
+ ], CommercetoolsCartCapability.prototype, "renameCart", 1);
381
+ __decorateClass([
382
+ Reactionary({
383
+ inputSchema: CartMutationCreateCartSchema,
384
+ outputSchema: CartSchema
385
+ })
386
+ ], CommercetoolsCartCapability.prototype, "createCart", 1);
270
387
  __decorateClass([
271
388
  Reactionary({
272
389
  inputSchema: CartQueryByIdSchema,
@@ -73,7 +73,7 @@ class CommercetoolsEmployeeInvitationCapability extends EmployeeInvitationCapabi
73
73
  return "org-" + Buffer.from(companyIdentifier.taxIdentifier).toString("base64");
74
74
  }
75
75
  makeKeyFromEmail(email) {
76
- return `email-` + Buffer.from(email).toString("base64");
76
+ return `email-` + Buffer.from(email).toString("base64").replace(/=+$/, "");
77
77
  }
78
78
  async fetchInvitationIdsByKey(adminClient, key) {
79
79
  const response = await adminClient.customObjects().withContainerAndKey({