@labdigital/commercetools-mock 2.65.1 → 3.0.0-beta.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.
Files changed (281) hide show
  1. package/README.md +31 -8
  2. package/dist/abstract-BKFcva6S.mjs +1044 -0
  3. package/dist/abstract-BKFcva6S.mjs.map +1 -0
  4. package/dist/config-BcNSzPZz.d.mts +1718 -0
  5. package/dist/index.d.mts +50 -1633
  6. package/dist/index.mjs +3771 -2654
  7. package/dist/index.mjs.map +1 -1
  8. package/dist/storage/sqlite.d.mts +59 -0
  9. package/dist/storage/sqlite.mjs +234 -0
  10. package/dist/storage/sqlite.mjs.map +1 -0
  11. package/package.json +26 -29
  12. package/src/ctMock.ts +125 -136
  13. package/src/helpers.ts +14 -6
  14. package/src/index.ts +5 -0
  15. package/src/lib/masking.ts +4 -5
  16. package/src/lib/product-review-statistics.test.ts +257 -294
  17. package/src/lib/review-statistics.ts +17 -4
  18. package/src/oauth/helpers.ts +7 -4
  19. package/src/oauth/server.test.ts +102 -62
  20. package/src/oauth/server.ts +215 -213
  21. package/src/oauth/store.ts +20 -6
  22. package/src/orderSearch.ts +3 -3
  23. package/src/product-projection-search.ts +38 -20
  24. package/src/product-search-availability.test.ts +31 -52
  25. package/src/product-search.ts +19 -10
  26. package/src/projectAPI.ts +6 -22
  27. package/src/repositories/abstract.ts +182 -48
  28. package/src/repositories/as-associate.test.ts +19 -19
  29. package/src/repositories/associate-role.ts +12 -23
  30. package/src/repositories/attribute-group.test.ts +23 -23
  31. package/src/repositories/attribute-group.ts +6 -4
  32. package/src/repositories/business-unit.test.ts +63 -57
  33. package/src/repositories/business-unit.ts +107 -55
  34. package/src/repositories/cart/actions.ts +96 -65
  35. package/src/repositories/cart/helpers.ts +15 -11
  36. package/src/repositories/cart/index.test.ts +136 -30
  37. package/src/repositories/cart/index.ts +76 -59
  38. package/src/repositories/cart-discount/actions.ts +12 -44
  39. package/src/repositories/cart-discount/index.ts +20 -8
  40. package/src/repositories/category/actions.ts +27 -27
  41. package/src/repositories/category/index.test.ts +13 -9
  42. package/src/repositories/category/index.ts +40 -23
  43. package/src/repositories/channel.test.ts +53 -51
  44. package/src/repositories/channel.ts +12 -22
  45. package/src/repositories/custom-object.ts +34 -25
  46. package/src/repositories/customer/actions.ts +47 -25
  47. package/src/repositories/customer/index.test.ts +11 -11
  48. package/src/repositories/customer/index.ts +65 -35
  49. package/src/repositories/customer-group.test.ts +44 -42
  50. package/src/repositories/customer-group.ts +12 -22
  51. package/src/repositories/discount-code/actions.ts +3 -19
  52. package/src/repositories/discount-code/index.ts +9 -4
  53. package/src/repositories/discount-group/index.ts +8 -3
  54. package/src/repositories/extension.test.ts +27 -27
  55. package/src/repositories/extension.ts +10 -5
  56. package/src/repositories/helpers.ts +126 -47
  57. package/src/repositories/inventory-entry/actions.ts +3 -24
  58. package/src/repositories/inventory-entry/index.ts +19 -11
  59. package/src/repositories/my-customer.ts +13 -12
  60. package/src/repositories/my-order.ts +5 -2
  61. package/src/repositories/order/actions.ts +89 -56
  62. package/src/repositories/order/index.test.ts +36 -31
  63. package/src/repositories/order/index.ts +83 -49
  64. package/src/repositories/order-edit.ts +8 -3
  65. package/src/repositories/payment/actions.ts +64 -44
  66. package/src/repositories/payment/helpers.ts +3 -3
  67. package/src/repositories/payment/index.ts +28 -12
  68. package/src/repositories/product/actions.ts +133 -98
  69. package/src/repositories/product/helpers.ts +29 -16
  70. package/src/repositories/product/index.ts +42 -25
  71. package/src/repositories/product-discount.ts +6 -4
  72. package/src/repositories/product-projection.ts +41 -21
  73. package/src/repositories/product-selection.ts +8 -15
  74. package/src/repositories/product-tailoring.ts +22 -3
  75. package/src/repositories/product-type.ts +45 -4
  76. package/src/repositories/project.ts +57 -13
  77. package/src/repositories/quote/actions.ts +5 -28
  78. package/src/repositories/quote/index.ts +29 -6
  79. package/src/repositories/quote-request/actions.ts +5 -28
  80. package/src/repositories/quote-request/index.test.ts +3 -3
  81. package/src/repositories/quote-request/index.ts +31 -11
  82. package/src/repositories/quote-staged/actions.ts +5 -28
  83. package/src/repositories/quote-staged/index.ts +22 -8
  84. package/src/repositories/recurrence-policy/index.ts +6 -4
  85. package/src/repositories/recurring-order/actions.ts +7 -32
  86. package/src/repositories/recurring-order/index.ts +8 -6
  87. package/src/repositories/review.test.ts +147 -142
  88. package/src/repositories/review.ts +31 -37
  89. package/src/repositories/shipping-method/actions.ts +11 -28
  90. package/src/repositories/shipping-method/index.ts +26 -15
  91. package/src/repositories/shopping-list/actions.ts +21 -31
  92. package/src/repositories/shopping-list/index.ts +44 -22
  93. package/src/repositories/standalone-price.ts +6 -4
  94. package/src/repositories/state.ts +15 -9
  95. package/src/repositories/store.ts +21 -32
  96. package/src/repositories/subscription.test.ts +22 -22
  97. package/src/repositories/subscription.ts +8 -3
  98. package/src/repositories/tax-category/index.ts +8 -3
  99. package/src/repositories/type/actions.ts +21 -3
  100. package/src/repositories/type/index.ts +5 -3
  101. package/src/repositories/zone.test.ts +112 -77
  102. package/src/repositories/zone.ts +5 -3
  103. package/src/schemas/generated/associate-role.ts +13 -0
  104. package/src/schemas/generated/attribute-group.ts +12 -0
  105. package/src/schemas/generated/business-unit.ts +38 -0
  106. package/src/schemas/generated/cart-discount.ts +33 -0
  107. package/src/schemas/generated/cart.ts +61 -0
  108. package/src/schemas/generated/category.ts +25 -0
  109. package/src/schemas/generated/channel.ts +21 -0
  110. package/src/schemas/generated/common.ts +1372 -0
  111. package/src/schemas/generated/custom-object.ts +11 -0
  112. package/src/schemas/generated/customer-group.ts +11 -0
  113. package/src/schemas/generated/customer.ts +47 -0
  114. package/src/schemas/generated/discount-code.ts +25 -0
  115. package/src/schemas/generated/discount-group.ts +13 -0
  116. package/src/schemas/generated/extension.ts +15 -0
  117. package/src/schemas/generated/index.ts +42 -0
  118. package/src/schemas/generated/inventory-entry.ts +20 -0
  119. package/src/schemas/generated/my-quote-request.ts +10 -0
  120. package/src/schemas/generated/order-edit.ts +18 -0
  121. package/src/schemas/generated/order-from-cart.ts +25 -0
  122. package/src/schemas/generated/payment.ts +30 -0
  123. package/src/schemas/generated/product-discount.ts +20 -0
  124. package/src/schemas/generated/product-selection.ts +18 -0
  125. package/src/schemas/generated/product-tailoring.ts +26 -0
  126. package/src/schemas/generated/product-type.ts +12 -0
  127. package/src/schemas/generated/product.ts +37 -0
  128. package/src/schemas/generated/quote-request.ts +19 -0
  129. package/src/schemas/generated/quote.ts +18 -0
  130. package/src/schemas/generated/recurrence-policy.ts +15 -0
  131. package/src/schemas/generated/recurring-order.ts +19 -0
  132. package/src/schemas/generated/review.ts +24 -0
  133. package/src/schemas/generated/shipping-method.ts +24 -0
  134. package/src/schemas/generated/shopping-list.ts +28 -0
  135. package/src/schemas/generated/staged-quote.ts +18 -0
  136. package/src/schemas/generated/standalone-price.ts +32 -0
  137. package/src/schemas/generated/state.ts +20 -0
  138. package/src/schemas/generated/store.ts +23 -0
  139. package/src/schemas/generated/subscription.ts +20 -0
  140. package/src/schemas/generated/tax-category.ts +12 -0
  141. package/src/schemas/generated/type.ts +17 -0
  142. package/src/schemas/generated/zone.ts +12 -0
  143. package/src/schemas/update-request.ts +3 -5
  144. package/src/server.ts +32 -4
  145. package/src/services/abstract.ts +207 -101
  146. package/src/services/as-associate-cart.test.ts +28 -36
  147. package/src/services/as-associate-cart.ts +15 -12
  148. package/src/services/as-associate-order.test.ts +33 -40
  149. package/src/services/as-associate-order.ts +15 -12
  150. package/src/services/as-associate-quote-request.ts +15 -12
  151. package/src/services/as-associate-shopping-list.test.ts +25 -35
  152. package/src/services/as-associate-shopping-list.ts +15 -12
  153. package/src/services/as-associate.test.ts +21 -15
  154. package/src/services/as-associate.ts +23 -22
  155. package/src/services/associate-roles.test.ts +16 -22
  156. package/src/services/associate-roles.ts +2 -2
  157. package/src/services/attribute-group.test.ts +40 -44
  158. package/src/services/attribute-group.ts +2 -2
  159. package/src/services/business-units.test.ts +227 -163
  160. package/src/services/business-units.ts +2 -2
  161. package/src/services/cart-discount.test.ts +253 -187
  162. package/src/services/cart-discount.ts +2 -2
  163. package/src/services/cart.test.ts +833 -832
  164. package/src/services/cart.ts +31 -12
  165. package/src/services/category.test.ts +208 -130
  166. package/src/services/category.ts +2 -2
  167. package/src/services/channel.test.ts +39 -44
  168. package/src/services/channel.ts +2 -2
  169. package/src/services/custom-object.test.ts +103 -79
  170. package/src/services/custom-object.ts +106 -38
  171. package/src/services/customer-group.test.ts +39 -44
  172. package/src/services/customer-group.ts +2 -2
  173. package/src/services/customer.test.ts +357 -292
  174. package/src/services/customer.ts +70 -23
  175. package/src/services/discount-code.test.ts +57 -68
  176. package/src/services/discount-code.ts +2 -2
  177. package/src/services/discount-group.test.ts +111 -134
  178. package/src/services/discount-group.ts +2 -2
  179. package/src/services/draft-validation.test.ts +255 -0
  180. package/src/services/extension.test.ts +39 -44
  181. package/src/services/extension.ts +2 -2
  182. package/src/services/inventory-entry.test.ts +106 -87
  183. package/src/services/inventory-entry.ts +2 -2
  184. package/src/services/my-business-unit.test.ts +82 -112
  185. package/src/services/my-business-unit.ts +25 -19
  186. package/src/services/my-cart.test.ts +46 -41
  187. package/src/services/my-cart.ts +32 -28
  188. package/src/services/my-customer.test.ts +153 -88
  189. package/src/services/my-customer.ts +130 -61
  190. package/src/services/my-order.ts +15 -12
  191. package/src/services/my-payment.test.ts +30 -24
  192. package/src/services/my-payment.ts +2 -2
  193. package/src/services/my-shopping-list.ts +2 -2
  194. package/src/services/order.test.ts +332 -276
  195. package/src/services/order.ts +45 -27
  196. package/src/services/payment.test.ts +31 -29
  197. package/src/services/payment.ts +2 -2
  198. package/src/services/product-discount.test.ts +39 -46
  199. package/src/services/product-discount.ts +2 -2
  200. package/src/services/product-projection.test.ts +176 -166
  201. package/src/services/product-projection.ts +31 -15
  202. package/src/services/product-selection.test.ts +17 -9
  203. package/src/services/product-selection.ts +2 -2
  204. package/src/services/product-type.test.ts +80 -21
  205. package/src/services/product-type.ts +2 -2
  206. package/src/services/product.test.ts +569 -534
  207. package/src/services/product.ts +14 -7
  208. package/src/services/project.test.ts +22 -12
  209. package/src/services/project.ts +28 -13
  210. package/src/services/quote-request.test.ts +36 -39
  211. package/src/services/quote-request.ts +2 -2
  212. package/src/services/quote-staged.ts +2 -2
  213. package/src/services/quote.ts +2 -2
  214. package/src/services/recurrence-policy.test.ts +114 -139
  215. package/src/services/recurrence-policy.ts +2 -2
  216. package/src/services/recurring-order.test.ts +149 -194
  217. package/src/services/recurring-order.ts +2 -2
  218. package/src/services/reviews.test.ts +127 -106
  219. package/src/services/reviews.ts +2 -2
  220. package/src/services/shipping-method.test.ts +96 -125
  221. package/src/services/shipping-method.ts +24 -12
  222. package/src/services/shopping-list.test.ts +183 -141
  223. package/src/services/shopping-list.ts +2 -2
  224. package/src/services/standalone-price.test.ts +60 -46
  225. package/src/services/standalone-price.ts +2 -2
  226. package/src/services/state.test.ts +20 -25
  227. package/src/services/state.ts +2 -2
  228. package/src/services/store.test.ts +26 -45
  229. package/src/services/store.ts +2 -2
  230. package/src/services/subscription.test.ts +39 -44
  231. package/src/services/subscription.ts +2 -2
  232. package/src/services/tax-category.test.ts +33 -36
  233. package/src/services/tax-category.ts +2 -2
  234. package/src/services/type.test.ts +45 -44
  235. package/src/services/type.ts +2 -2
  236. package/src/services/zone.test.ts +40 -44
  237. package/src/services/zone.ts +2 -2
  238. package/src/shipping.ts +41 -11
  239. package/src/storage/abstract.ts +248 -17
  240. package/src/storage/in-memory.ts +147 -290
  241. package/src/storage/sqlite.ts +429 -0
  242. package/src/storage/storage-map.ts +75 -0
  243. package/src/storage/storage.test-helpers.ts +97 -0
  244. package/src/storage/storage.test.ts +802 -0
  245. package/src/testing/associate-role.ts +28 -0
  246. package/src/testing/attribute-group.ts +27 -0
  247. package/src/testing/business-unit.ts +9 -8
  248. package/src/testing/cart-discount.ts +34 -0
  249. package/src/testing/cart.ts +20 -0
  250. package/src/testing/category.ts +25 -0
  251. package/src/testing/channel.ts +23 -0
  252. package/src/testing/custom-object.ts +27 -0
  253. package/src/testing/customer-group.ts +26 -0
  254. package/src/testing/customer.ts +36 -33
  255. package/src/testing/discount-code.ts +29 -0
  256. package/src/testing/discount-group.ts +27 -0
  257. package/src/testing/extension.ts +32 -0
  258. package/src/testing/index.ts +33 -0
  259. package/src/testing/inventory-entry.ts +26 -0
  260. package/src/testing/order.ts +27 -0
  261. package/src/testing/payment.ts +23 -0
  262. package/src/testing/product-discount.ts +33 -0
  263. package/src/testing/product-selection.ts +28 -0
  264. package/src/testing/product-type.ts +27 -0
  265. package/src/testing/product.ts +38 -0
  266. package/src/testing/quote-request.ts +29 -0
  267. package/src/testing/recurrence-policy.ts +33 -0
  268. package/src/testing/recurring-order.ts +32 -0
  269. package/src/testing/review.ts +24 -0
  270. package/src/testing/shipping-method.ts +31 -0
  271. package/src/testing/shopping-list.ts +25 -0
  272. package/src/testing/standalone-price.ts +31 -0
  273. package/src/testing/state.ts +21 -0
  274. package/src/testing/store.ts +26 -0
  275. package/src/testing/subscription.ts +38 -0
  276. package/src/testing/tax-category.ts +27 -0
  277. package/src/testing/type.ts +9 -6
  278. package/src/testing/zone.ts +22 -0
  279. package/src/validate.test.ts +122 -0
  280. package/src/validate.ts +78 -7
  281. package/src/.env +0 -0
@@ -53,7 +53,7 @@ type ProductUpdateHandlerMethod<T> = (
53
53
  context: RepositoryContext,
54
54
  resource: Writable<Product>,
55
55
  action: T,
56
- ) => void;
56
+ ) => void | Promise<void>;
57
57
 
58
58
  type ProductUpdateActions = Partial<{
59
59
  [P in ProductUpdateAction as P["action"]]: ProductUpdateHandlerMethod<P>;
@@ -75,8 +75,12 @@ export class ProductUpdateHandler
75
75
  sku,
76
76
  );
77
77
  if (!variant) {
78
- throw new Error(
79
- `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,
78
+ throw new CommercetoolsError<InvalidOperationError>(
79
+ {
80
+ code: "InvalidOperation",
81
+ message: `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,
82
+ },
83
+ 400,
80
84
  );
81
85
  }
82
86
 
@@ -85,8 +89,12 @@ export class ProductUpdateHandler
85
89
  } else {
86
90
  const existingImage = variant.images.find((x) => x.url === image.url);
87
91
  if (existingImage) {
88
- throw new Error(
89
- `Cannot add image '${image.url}' because product '${resource.id}' already has that image.`,
92
+ throw new CommercetoolsError<InvalidOperationError>(
93
+ {
94
+ code: "InvalidOperation",
95
+ message: `Cannot add image '${image.url}' because product '${resource.id}' already has that image.`,
96
+ },
97
+ 400,
90
98
  );
91
99
  }
92
100
  }
@@ -115,11 +123,9 @@ export class ProductUpdateHandler
115
123
  addImg(resource.masterData.current);
116
124
  }
117
125
  checkForStagedChanges(resource);
118
-
119
- return resource;
120
126
  }
121
127
 
122
- addPrice(
128
+ async addPrice(
123
129
  context: RepositoryContext,
124
130
  resource: Writable<Product>,
125
131
  { variantId, sku, price, staged }: ProductAddPriceAction,
@@ -134,8 +140,12 @@ export class ProductUpdateHandler
134
140
  sku,
135
141
  );
136
142
  if (!variant) {
137
- throw new Error(
138
- `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,
143
+ throw new CommercetoolsError<InvalidOperationError>(
144
+ {
145
+ code: "InvalidOperation",
146
+ message: `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,
147
+ },
148
+ 400,
139
149
  );
140
150
  }
141
151
 
@@ -153,7 +163,7 @@ export class ProductUpdateHandler
153
163
  };
154
164
 
155
165
  // Pre-creating the price object ensures consistency between staged and current versions
156
- const priceToAdd = priceFromDraft(context, this._storage, price);
166
+ const priceToAdd = await priceFromDraft(context, this._storage, price);
157
167
 
158
168
  // If true, only the staged Attribute is set. If false, both current and
159
169
  // staged Attribute is set. Default is true
@@ -169,19 +179,17 @@ export class ProductUpdateHandler
169
179
  addVariantPrice(resource.masterData.current, priceToAdd);
170
180
  }
171
181
  checkForStagedChanges(resource);
172
-
173
- return resource;
174
182
  }
175
183
 
176
- addToCategory(
184
+ async addToCategory(
177
185
  context: RepositoryContext,
178
186
  resource: Writable<Product>,
179
187
  { category, staged, orderHint }: ProductAddToCategoryAction,
180
188
  ) {
181
- const addCategory = (data: Writable<ProductData>) => {
189
+ const addCategory = async (data: Writable<ProductData>) => {
182
190
  if (category) {
183
191
  data.categories.push(
184
- getReferenceFromResourceIdentifier<CategoryReference>(
192
+ await getReferenceFromResourceIdentifier<CategoryReference>(
185
193
  category,
186
194
  context.projectKey,
187
195
  this._storage,
@@ -201,17 +209,15 @@ export class ProductUpdateHandler
201
209
 
202
210
  const onlyStaged = staged !== undefined ? staged : true;
203
211
 
204
- addCategory(resource.masterData.staged);
212
+ await addCategory(resource.masterData.staged);
205
213
 
206
214
  if (!onlyStaged) {
207
- addCategory(resource.masterData.current);
215
+ await addCategory(resource.masterData.current);
208
216
  }
209
217
  checkForStagedChanges(resource);
210
-
211
- return resource;
212
218
  }
213
219
 
214
- addVariant(
220
+ async addVariant(
215
221
  context: RepositoryContext,
216
222
  resource: Writable<Product>,
217
223
  {
@@ -242,7 +248,7 @@ export class ProductUpdateHandler
242
248
  (max, element) => (element.id > max ? element.id : max),
243
249
  0,
244
250
  );
245
- const variant = variantFromDraft(
251
+ const variant = await variantFromDraft(
246
252
  context,
247
253
  this._storage,
248
254
  maxId + 1,
@@ -256,8 +262,6 @@ export class ProductUpdateHandler
256
262
  resource.masterData.current.variants.push(variant);
257
263
  }
258
264
  checkForStagedChanges(resource);
259
-
260
- return resource;
261
265
  }
262
266
 
263
267
  changeMasterVariant(
@@ -272,8 +276,12 @@ export class ProductUpdateHandler
272
276
  sku,
273
277
  );
274
278
  if (!variant) {
275
- throw new Error(
276
- `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,
279
+ throw new CommercetoolsError<InvalidOperationError>(
280
+ {
281
+ code: "InvalidOperation",
282
+ message: `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,
283
+ },
284
+ 400,
277
285
  );
278
286
  }
279
287
 
@@ -296,8 +304,6 @@ export class ProductUpdateHandler
296
304
  setMaster(resource.masterData.current);
297
305
  }
298
306
  checkForStagedChanges(resource);
299
-
300
- return resource;
301
307
  }
302
308
 
303
309
  changeName(
@@ -311,7 +317,6 @@ export class ProductUpdateHandler
311
317
  resource.masterData.current.name = name;
312
318
  }
313
319
  checkForStagedChanges(resource);
314
- return resource;
315
320
  }
316
321
 
317
322
  changePrice(
@@ -325,8 +330,12 @@ export class ProductUpdateHandler
325
330
  variant.prices?.some((x) => x.id === priceId),
326
331
  );
327
332
  if (!priceVariant) {
328
- throw new Error(
329
- `Price with id ${priceId} not found on product ${resource.id}`,
333
+ throw new CommercetoolsError<InvalidOperationError>(
334
+ {
335
+ code: "InvalidOperation",
336
+ message: `Price with id ${priceId} not found on product ${resource.id}`,
337
+ },
338
+ 400,
330
339
  );
331
340
  }
332
341
 
@@ -336,8 +345,12 @@ export class ProductUpdateHandler
336
345
  priceVariant.sku,
337
346
  );
338
347
  if (!variant) {
339
- throw new Error(
340
- `Variant with id ${priceVariant.id} or sku ${priceVariant.sku} not found on product ${resource.id}`,
348
+ throw new CommercetoolsError<InvalidOperationError>(
349
+ {
350
+ code: "InvalidOperation",
351
+ message: `Variant with id ${priceVariant.id} or sku ${priceVariant.sku} not found on product ${resource.id}`,
352
+ },
353
+ 400,
341
354
  );
342
355
  }
343
356
 
@@ -369,8 +382,6 @@ export class ProductUpdateHandler
369
382
  changeVariantPrice(resource.masterData.current);
370
383
  }
371
384
  checkForStagedChanges(resource);
372
-
373
- return resource;
374
385
  }
375
386
 
376
387
  changeSlug(
@@ -384,7 +395,6 @@ export class ProductUpdateHandler
384
395
  resource.masterData.current.slug = slug;
385
396
  }
386
397
  checkForStagedChanges(resource);
387
- return resource;
388
398
  }
389
399
 
390
400
  moveImageToPosition(
@@ -405,22 +415,35 @@ export class ProductUpdateHandler
405
415
  sku,
406
416
  );
407
417
  if (!variant) {
408
- throw new Error(
409
- `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,
418
+ throw new CommercetoolsError<InvalidOperationError>(
419
+ {
420
+ code: "InvalidOperation",
421
+ message: `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,
422
+ },
423
+ 400,
410
424
  );
411
425
  }
412
426
 
413
427
  const variantImages = variant.images ?? [];
414
428
  const existingImage = variantImages.find((x) => x.url === imageUrl);
415
429
  if (!existingImage) {
416
- throw new Error(
417
- `Cannot move image '${imageUrl}' because product '${resource.id}' does not have that image.`,
430
+ throw new CommercetoolsError<InvalidOperationError>(
431
+ {
432
+ code: "InvalidOperation",
433
+ message: `Cannot move image '${imageUrl}' because product '${resource.id}' does not have that image.`,
434
+ },
435
+ 400,
418
436
  );
419
437
  }
420
438
 
421
439
  if (position >= variantImages.length) {
422
- throw new Error(
423
- "Invalid position given. Position in images where the image should be moved. Must be between 0 and the total number of images minus 1.",
440
+ throw new CommercetoolsError<InvalidOperationError>(
441
+ {
442
+ code: "InvalidOperation",
443
+ message:
444
+ "Invalid position given. Position in images where the image should be moved. Must be between 0 and the total number of images minus 1.",
445
+ },
446
+ 400,
424
447
  );
425
448
  }
426
449
 
@@ -451,8 +474,6 @@ export class ProductUpdateHandler
451
474
  moveImg(resource.masterData.current);
452
475
  }
453
476
  checkForStagedChanges(resource);
454
-
455
- return resource;
456
477
  }
457
478
 
458
479
  publish(
@@ -465,15 +486,15 @@ export class ProductUpdateHandler
465
486
  checkForStagedChanges(resource);
466
487
  }
467
488
 
468
- removeFromCategory(
489
+ async removeFromCategory(
469
490
  context: RepositoryContext,
470
491
  resource: Writable<Product>,
471
492
  { category, staged }: ProductRemoveFromCategoryAction,
472
493
  ) {
473
- const removeCategory = (data: Writable<ProductData>) => {
494
+ const removeCategory = async (data: Writable<ProductData>) => {
474
495
  if (category) {
475
496
  const resolvedCategory =
476
- getReferenceFromResourceIdentifier<CategoryReference>(
497
+ await getReferenceFromResourceIdentifier<CategoryReference>(
477
498
  category,
478
499
  context.projectKey,
479
500
  this._storage,
@@ -521,14 +542,12 @@ export class ProductUpdateHandler
521
542
  };
522
543
 
523
544
  const onlyStaged = staged !== undefined ? staged : true;
524
- removeCategory(resource.masterData.staged);
545
+ await removeCategory(resource.masterData.staged);
525
546
 
526
547
  if (!onlyStaged) {
527
- removeCategory(resource.masterData.current);
548
+ await removeCategory(resource.masterData.current);
528
549
  }
529
550
  checkForStagedChanges(resource);
530
-
531
- return resource;
532
551
  }
533
552
 
534
553
  removeImage(
@@ -543,16 +562,24 @@ export class ProductUpdateHandler
543
562
  sku,
544
563
  );
545
564
  if (!variant) {
546
- throw new Error(
547
- `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,
565
+ throw new CommercetoolsError<InvalidOperationError>(
566
+ {
567
+ code: "InvalidOperation",
568
+ message: `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,
569
+ },
570
+ 400,
548
571
  );
549
572
  }
550
573
 
551
574
  const variantImages = variant.images ?? [];
552
575
  const existingImage = variantImages.find((x) => x.url === imageUrl);
553
576
  if (!existingImage) {
554
- throw new Error(
555
- `Cannot remove image '${imageUrl}' because product '${resource.id}' does not have that image.`,
577
+ throw new CommercetoolsError<InvalidOperationError>(
578
+ {
579
+ code: "InvalidOperation",
580
+ message: `Cannot remove image '${imageUrl}' because product '${resource.id}' does not have that image.`,
581
+ },
582
+ 400,
556
583
  );
557
584
  }
558
585
 
@@ -580,8 +607,6 @@ export class ProductUpdateHandler
580
607
  removeImg(resource.masterData.current);
581
608
  }
582
609
  checkForStagedChanges(resource);
583
-
584
- return resource;
585
610
  }
586
611
 
587
612
  removePrice(
@@ -595,8 +620,12 @@ export class ProductUpdateHandler
595
620
  variant.prices?.some((x) => x.id === priceId),
596
621
  );
597
622
  if (!priceVariant) {
598
- throw new Error(
599
- `Price with id ${priceId} not found on product ${resource.id}`,
623
+ throw new CommercetoolsError<InvalidOperationError>(
624
+ {
625
+ code: "InvalidOperation",
626
+ message: `Price with id ${priceId} not found on product ${resource.id}`,
627
+ },
628
+ 400,
600
629
  );
601
630
  }
602
631
 
@@ -606,8 +635,12 @@ export class ProductUpdateHandler
606
635
  priceVariant.sku,
607
636
  );
608
637
  if (!variant) {
609
- throw new Error(
610
- `Variant with id ${priceVariant.id} or sku ${priceVariant.sku} not found on product ${resource.id}`,
638
+ throw new CommercetoolsError<InvalidOperationError>(
639
+ {
640
+ code: "InvalidOperation",
641
+ message: `Variant with id ${priceVariant.id} or sku ${priceVariant.sku} not found on product ${resource.id}`,
642
+ },
643
+ 400,
611
644
  );
612
645
  }
613
646
 
@@ -634,8 +667,6 @@ export class ProductUpdateHandler
634
667
  removeVariantPrice(resource.masterData.current);
635
668
  }
636
669
  checkForStagedChanges(resource);
637
-
638
- return resource;
639
670
  }
640
671
 
641
672
  removeVariant(
@@ -650,13 +681,21 @@ export class ProductUpdateHandler
650
681
  sku,
651
682
  );
652
683
  if (!variant) {
653
- throw new Error(
654
- `Variant with id ${id} or sku ${sku} not found on product ${resource.id}`,
684
+ throw new CommercetoolsError<InvalidOperationError>(
685
+ {
686
+ code: "InvalidOperation",
687
+ message: `Variant with id ${id} or sku ${sku} not found on product ${resource.id}`,
688
+ },
689
+ 400,
655
690
  );
656
691
  }
657
692
  if (isMasterVariant) {
658
- throw new Error(
659
- `Can not remove the variant [ID:${id}] for [Product:${resource.id}] since it's the master variant`,
693
+ throw new CommercetoolsError<InvalidOperationError>(
694
+ {
695
+ code: "InvalidOperation",
696
+ message: `Can not remove the variant [ID:${id}] for [Product:${resource.id}] since it's the master variant`,
697
+ },
698
+ 400,
660
699
  );
661
700
  }
662
701
 
@@ -671,8 +710,6 @@ export class ProductUpdateHandler
671
710
  removeVariant(resource.masterData.current);
672
711
  }
673
712
  checkForStagedChanges(resource);
674
-
675
- return resource;
676
713
  }
677
714
 
678
715
  setAttribute(
@@ -687,8 +724,12 @@ export class ProductUpdateHandler
687
724
  sku,
688
725
  );
689
726
  if (!variant) {
690
- throw new Error(
691
- `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,
727
+ throw new CommercetoolsError<InvalidOperationError>(
728
+ {
729
+ code: "InvalidOperation",
730
+ message: `Variant with id ${variantId} or sku ${sku} not found on product ${resource.id}`,
731
+ },
732
+ 400,
692
733
  );
693
734
  }
694
735
 
@@ -728,8 +769,6 @@ export class ProductUpdateHandler
728
769
  setAttr(resource.masterData.current);
729
770
  }
730
771
  checkForStagedChanges(resource);
731
-
732
- return resource;
733
772
  }
734
773
 
735
774
  setAttributeInAllVariants(
@@ -788,8 +827,6 @@ export class ProductUpdateHandler
788
827
  setAttrInAllVariants(resource.masterData.current);
789
828
  }
790
829
  checkForStagedChanges(resource);
791
-
792
- return resource;
793
830
  }
794
831
 
795
832
  setDescription(
@@ -804,7 +841,6 @@ export class ProductUpdateHandler
804
841
  resource.masterData.current.description = description;
805
842
  }
806
843
  checkForStagedChanges(resource);
807
- return resource;
808
844
  }
809
845
 
810
846
  setKey(
@@ -813,7 +849,6 @@ export class ProductUpdateHandler
813
849
  { key }: ProductSetKeyAction,
814
850
  ) {
815
851
  resource.key = key;
816
- return resource;
817
852
  }
818
853
 
819
854
  setMetaDescription(
@@ -827,7 +862,6 @@ export class ProductUpdateHandler
827
862
  resource.masterData.current.metaDescription = metaDescription;
828
863
  }
829
864
  checkForStagedChanges(resource);
830
- return resource;
831
865
  }
832
866
 
833
867
  setMetaKeywords(
@@ -841,7 +875,6 @@ export class ProductUpdateHandler
841
875
  resource.masterData.current.metaKeywords = metaKeywords;
842
876
  }
843
877
  checkForStagedChanges(resource);
844
- return resource;
845
878
  }
846
879
 
847
880
  setMetaTitle(
@@ -855,7 +888,6 @@ export class ProductUpdateHandler
855
888
  resource.masterData.current.metaTitle = metaTitle;
856
889
  }
857
890
  checkForStagedChanges(resource);
858
- return resource;
859
891
  }
860
892
 
861
893
  setProductPriceCustomField(
@@ -869,8 +901,12 @@ export class ProductUpdateHandler
869
901
  .find((price) => price.id === priceId);
870
902
 
871
903
  if (!price) {
872
- throw new Error(
873
- `Price with id ${priceId} not found on product ${resource.id}`,
904
+ throw new CommercetoolsError<InvalidOperationError>(
905
+ {
906
+ code: "InvalidOperation",
907
+ message: `Price with id ${priceId} not found on product ${resource.id}`,
908
+ },
909
+ 400,
874
910
  );
875
911
  }
876
912
  if (price.custom) {
@@ -894,22 +930,21 @@ export class ProductUpdateHandler
894
930
  );
895
931
  }
896
932
  checkForStagedChanges(resource);
897
- return resource;
898
933
  }
899
934
 
900
- setProductPriceCustomType(
935
+ async setProductPriceCustomType(
901
936
  context: RepositoryContext,
902
937
  resource: Writable<Product>,
903
938
  { type, fields, staged, priceId }: ProductSetProductPriceCustomTypeAction,
904
939
  ) {
905
- const updatePriceCustomType = (data: Writable<ProductData>) => {
940
+ const updatePriceCustomType = async (data: Writable<ProductData>) => {
906
941
  const price = [data.masterVariant, ...(data.variants ?? [])]
907
942
  .flatMap((variant) => variant.prices ?? [])
908
943
  .find((price) => price.id === priceId);
909
944
 
910
945
  if (price) {
911
946
  if (type) {
912
- price.custom = createCustomFields(
947
+ price.custom = await createCustomFields(
913
948
  { type, fields },
914
949
  context.projectKey,
915
950
  this._storage,
@@ -918,28 +953,31 @@ export class ProductUpdateHandler
918
953
  price.custom = undefined;
919
954
  }
920
955
  } else {
921
- throw new Error(
922
- `Price with id ${priceId} not found on product ${resource.id}`,
956
+ throw new CommercetoolsError<InvalidOperationError>(
957
+ {
958
+ code: "InvalidOperation",
959
+ message: `Price with id ${priceId} not found on product ${resource.id}`,
960
+ },
961
+ 400,
923
962
  );
924
963
  }
925
964
  return data;
926
965
  };
927
966
 
928
- resource.masterData.staged = updatePriceCustomType(
967
+ resource.masterData.staged = await updatePriceCustomType(
929
968
  resource.masterData.staged,
930
969
  );
931
970
 
932
971
  const onlyStaged = staged !== undefined ? staged : true;
933
972
  if (!onlyStaged) {
934
- resource.masterData.current = updatePriceCustomType(
973
+ resource.masterData.current = await updatePriceCustomType(
935
974
  resource.masterData.current,
936
975
  );
937
976
  }
938
977
  checkForStagedChanges(resource);
939
- return resource;
940
978
  }
941
979
 
942
- setTaxCategory(
980
+ async setTaxCategory(
943
981
  context: RepositoryContext,
944
982
  resource: Writable<Product>,
945
983
  { taxCategory }: ProductSetTaxCategoryAction,
@@ -947,7 +985,7 @@ export class ProductUpdateHandler
947
985
  let taxCategoryReference: TaxCategoryReference | undefined;
948
986
  if (taxCategory) {
949
987
  taxCategoryReference =
950
- getReferenceFromResourceIdentifier<TaxCategoryReference>(
988
+ await getReferenceFromResourceIdentifier<TaxCategoryReference>(
951
989
  taxCategory,
952
990
  context.projectKey,
953
991
  this._storage,
@@ -964,10 +1002,9 @@ export class ProductUpdateHandler
964
1002
  );
965
1003
  }
966
1004
  resource.taxCategory = taxCategoryReference;
967
- return resource;
968
1005
  }
969
1006
 
970
- transitionState(
1007
+ async transitionState(
971
1008
  context: RepositoryContext,
972
1009
  resource: Writable<Product>,
973
1010
  { state, force }: ProductTransitionStateAction,
@@ -975,7 +1012,7 @@ export class ProductUpdateHandler
975
1012
  let productStateReference: StateReference | undefined;
976
1013
  if (state) {
977
1014
  productStateReference =
978
- getReferenceFromResourceIdentifier<StateReference>(
1015
+ await getReferenceFromResourceIdentifier<StateReference>(
979
1016
  state,
980
1017
  context.projectKey,
981
1018
  this._storage,
@@ -991,8 +1028,6 @@ export class ProductUpdateHandler
991
1028
  400,
992
1029
  );
993
1030
  }
994
-
995
- return resource;
996
1031
  }
997
1032
 
998
1033
  unpublish(
@@ -69,45 +69,58 @@ export const checkForStagedChanges = (product: Writable<Product>) => {
69
69
  }
70
70
  };
71
71
 
72
- export const variantFromDraft = (
72
+ export const variantFromDraft = async (
73
73
  context: RepositoryContext,
74
74
  storage: AbstractStorage,
75
75
  variantId: number,
76
76
  variant: ProductVariantDraft,
77
- ): ProductVariant => ({
78
- id: variantId,
79
- sku: variant?.sku,
80
- key: variant?.key,
81
- attributes: variant?.attributes ?? [],
82
- prices: variant?.prices?.map((p) => priceFromDraft(context, storage, p)),
83
- assets: variant.assets?.map((a) => assetFromDraft(context, storage, a)) ?? [],
84
- images: variant.images ?? [],
85
- });
77
+ ): Promise<ProductVariant> => {
78
+ const prices = variant?.prices
79
+ ? await Promise.all(
80
+ variant.prices.map((p) => priceFromDraft(context, storage, p)),
81
+ )
82
+ : undefined;
83
+ const assets = variant.assets
84
+ ? await Promise.all(
85
+ variant.assets.map((a) => assetFromDraft(context, storage, a)),
86
+ )
87
+ : [];
88
+
89
+ return {
90
+ id: variantId,
91
+ sku: variant?.sku,
92
+ key: variant?.key,
93
+ attributes: variant?.attributes ?? [],
94
+ prices,
95
+ assets,
96
+ images: variant.images ?? [],
97
+ };
98
+ };
86
99
 
87
- export const assetFromDraft = (
100
+ export const assetFromDraft = async (
88
101
  context: RepositoryContext,
89
102
  storage: AbstractStorage,
90
103
  draft: AssetDraft,
91
- ): Asset => {
104
+ ): Promise<Asset> => {
92
105
  const asset: Asset = {
93
106
  ...draft,
94
107
  id: uuidv4(),
95
- custom: createCustomFields(draft.custom, context.projectKey, storage),
108
+ custom: await createCustomFields(draft.custom, context.projectKey, storage),
96
109
  };
97
110
  return asset;
98
111
  };
99
112
 
100
- export const priceFromDraft = (
113
+ export const priceFromDraft = async (
101
114
  context: RepositoryContext,
102
115
  storage: AbstractStorage,
103
116
  draft: PriceDraft,
104
- ): Price => ({
117
+ ): Promise<Price> => ({
105
118
  id: uuidv4(),
106
119
  key: draft.key,
107
120
  country: draft.country,
108
121
  value: createTypedMoney(draft.value),
109
122
  channel: draft.channel
110
- ? getReferenceFromResourceIdentifier<ChannelReference>(
123
+ ? await getReferenceFromResourceIdentifier<ChannelReference>(
111
124
  draft.channel,
112
125
  context.projectKey,
113
126
  storage,