@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
@@ -7,6 +7,7 @@ import type {
7
7
  ProductPagedSearchResponse,
8
8
  ProductSearchRequest,
9
9
  ProductTypeReference,
10
+ RequiredFieldError,
10
11
  StateReference,
11
12
  TaxCategoryReference,
12
13
  } from "@commercetools/platform-sdk";
@@ -15,6 +16,7 @@ import { CommercetoolsError } from "#src/exceptions.ts";
15
16
  import { getBaseResourceProperties } from "#src/helpers.ts";
16
17
  import { ReviewStatisticsService } from "#src/lib/review-statistics.ts";
17
18
  import { ProductSearch } from "#src/product-search.ts";
19
+ import { ProductDraftSchema } from "#src/schemas/generated/product.ts";
18
20
  import type { GetParams, RepositoryContext } from "../abstract.ts";
19
21
  import { AbstractResourceRepository } from "../abstract.ts";
20
22
  import { getReferenceFromResourceIdentifier } from "../helpers.ts";
@@ -30,20 +32,32 @@ export class ProductRepository extends AbstractResourceRepository<"product"> {
30
32
  this.actions = new ProductUpdateHandler(config.storage);
31
33
  this._searchService = new ProductSearch(config);
32
34
  this._reviewStatisticsService = new ReviewStatisticsService(config.storage);
35
+ this.draftSchema = ProductDraftSchema;
33
36
  }
34
37
 
35
- create(context: RepositoryContext, draft: ProductDraft): Product {
38
+ async create(
39
+ context: RepositoryContext,
40
+ draft: ProductDraft,
41
+ ): Promise<Product> {
36
42
  if (!draft.masterVariant) {
37
- throw new Error("Missing master variant");
43
+ throw new CommercetoolsError<RequiredFieldError>(
44
+ {
45
+ code: "RequiredField",
46
+ message: "Missing master variant",
47
+ field: "masterVariant",
48
+ },
49
+ 400,
50
+ );
38
51
  }
39
52
 
40
53
  let productType: ProductTypeReference | undefined;
41
54
  try {
42
- productType = getReferenceFromResourceIdentifier<ProductTypeReference>(
43
- draft.productType,
44
- context.projectKey,
45
- this._storage,
46
- );
55
+ productType =
56
+ await getReferenceFromResourceIdentifier<ProductTypeReference>(
57
+ draft.productType,
58
+ context.projectKey,
59
+ this._storage,
60
+ );
47
61
  } catch (err) {
48
62
  if (this.config.strict) {
49
63
  throw err;
@@ -51,7 +65,7 @@ export class ProductRepository extends AbstractResourceRepository<"product"> {
51
65
 
52
66
  // For now accept missing product types (but warn)
53
67
  process.emitWarning(
54
- `Error resolving product-type '${draft.productType.id}'. This will be throw an error in later releases.`,
68
+ `Error resolving product-type '${draft.productType.id}'. This will throw an error in later releases.`,
55
69
  );
56
70
  productType = {
57
71
  typeId: "product-type",
@@ -61,10 +75,10 @@ export class ProductRepository extends AbstractResourceRepository<"product"> {
61
75
 
62
76
  // Resolve Product categories
63
77
  const categoryReferences: CategoryReference[] = [];
64
- draft.categories?.forEach((category) => {
78
+ for (const category of draft.categories ?? []) {
65
79
  if (category) {
66
80
  categoryReferences.push(
67
- getReferenceFromResourceIdentifier<CategoryReference>(
81
+ await getReferenceFromResourceIdentifier<CategoryReference>(
68
82
  category,
69
83
  context.projectKey,
70
84
  this._storage,
@@ -80,13 +94,13 @@ export class ProductRepository extends AbstractResourceRepository<"product"> {
80
94
  400,
81
95
  );
82
96
  }
83
- });
97
+ }
84
98
 
85
99
  // Resolve Tax category
86
100
  let taxCategoryReference: TaxCategoryReference | undefined;
87
101
  if (draft.taxCategory) {
88
102
  taxCategoryReference =
89
- getReferenceFromResourceIdentifier<TaxCategoryReference>(
103
+ await getReferenceFromResourceIdentifier<TaxCategoryReference>(
90
104
  draft.taxCategory,
91
105
  context.projectKey,
92
106
  this._storage,
@@ -97,29 +111,32 @@ export class ProductRepository extends AbstractResourceRepository<"product"> {
97
111
  let productStateReference: StateReference | undefined;
98
112
  if (draft.state) {
99
113
  productStateReference =
100
- getReferenceFromResourceIdentifier<StateReference>(
114
+ await getReferenceFromResourceIdentifier<StateReference>(
101
115
  draft.state,
102
116
  context.projectKey,
103
117
  this._storage,
104
118
  );
105
119
  }
106
120
 
121
+ const variants = await Promise.all(
122
+ draft.variants?.map((variant, index) =>
123
+ variantFromDraft(context, this._storage, index + 2, variant),
124
+ ) ?? [],
125
+ );
126
+
107
127
  const productData: ProductData = {
108
128
  name: draft.name,
109
129
  slug: draft.slug,
110
130
  description: draft.description,
111
131
  attributes: draft.attributes ?? [],
112
132
  categories: categoryReferences,
113
- masterVariant: variantFromDraft(
133
+ masterVariant: await variantFromDraft(
114
134
  context,
115
135
  this._storage,
116
136
  1,
117
137
  draft.masterVariant,
118
138
  ),
119
- variants:
120
- draft.variants?.map((variant, index) =>
121
- variantFromDraft(context, this._storage, index + 2, variant),
122
- ) ?? [],
139
+ variants,
123
140
  metaTitle: draft.metaTitle,
124
141
  metaDescription: draft.metaDescription,
125
142
  metaKeywords: draft.metaKeywords,
@@ -127,7 +144,7 @@ export class ProductRepository extends AbstractResourceRepository<"product"> {
127
144
  };
128
145
 
129
146
  const resource: Product = {
130
- ...getBaseResourceProperties(),
147
+ ...getBaseResourceProperties(context.clientId),
131
148
  key: draft.key,
132
149
  productType: productType,
133
150
  taxCategory: taxCategoryReference,
@@ -140,17 +157,17 @@ export class ProductRepository extends AbstractResourceRepository<"product"> {
140
157
  },
141
158
  };
142
159
 
143
- return this.saveNew(context, resource);
160
+ return await this.saveNew(context, resource);
144
161
  }
145
162
 
146
- postProcessResource(
163
+ async postProcessResource(
147
164
  context: RepositoryContext,
148
165
  resource: Product,
149
166
  params?: GetParams,
150
- ): Product {
167
+ ): Promise<Product> {
151
168
  // Add review statistics to the product
152
169
  const reviewStatistics =
153
- this._reviewStatisticsService.calculateProductReviewStatistics(
170
+ await this._reviewStatisticsService.calculateProductReviewStatistics(
154
171
  context.projectKey,
155
172
  resource.id,
156
173
  );
@@ -161,10 +178,10 @@ export class ProductRepository extends AbstractResourceRepository<"product"> {
161
178
  };
162
179
  }
163
180
 
164
- search(
181
+ async search(
165
182
  context: RepositoryContext,
166
183
  searchRequest: ProductSearchRequest,
167
- ): ProductPagedSearchResponse {
184
+ ): Promise<ProductPagedSearchResponse> {
168
185
  return this._searchService.search(context.projectKey, searchRequest);
169
186
  }
170
187
  }
@@ -19,6 +19,7 @@ import type {
19
19
  ProductDiscountValueRelative,
20
20
  } from "@commercetools/platform-sdk";
21
21
  import type { Config } from "#src/config.ts";
22
+ import { ProductDiscountDraftSchema } from "#src/schemas/generated/product-discount.ts";
22
23
  import { getBaseResourceProperties } from "../helpers.ts";
23
24
  import type { Writable } from "../types.ts";
24
25
  import type { RepositoryContext, UpdateHandlerInterface } from "./abstract.ts";
@@ -32,14 +33,15 @@ export class ProductDiscountRepository extends AbstractResourceRepository<"produ
32
33
  constructor(config: Config) {
33
34
  super("product-discount", config);
34
35
  this.actions = new ProductDiscountUpdateHandler(this._storage);
36
+ this.draftSchema = ProductDiscountDraftSchema;
35
37
  }
36
38
 
37
- create(
39
+ async create(
38
40
  context: RepositoryContext,
39
41
  draft: ProductDiscountDraft,
40
- ): ProductDiscount {
42
+ ): Promise<ProductDiscount> {
41
43
  const resource: ProductDiscount = {
42
- ...getBaseResourceProperties(),
44
+ ...getBaseResourceProperties(context.clientId),
43
45
  key: draft.key,
44
46
  name: draft.name,
45
47
  description: draft.description,
@@ -51,7 +53,7 @@ export class ProductDiscountRepository extends AbstractResourceRepository<"produ
51
53
  validUntil: draft.validUntil,
52
54
  references: [],
53
55
  };
54
- return this.saveNew(context, resource);
56
+ return await this.saveNew(context, resource);
55
57
  }
56
58
  }
57
59
 
@@ -1,5 +1,6 @@
1
1
  import type {
2
2
  InvalidInputError,
3
+ InvalidOperationError,
3
4
  ProductDraft,
4
5
  ProductProjection,
5
6
  QueryParam,
@@ -37,43 +38,60 @@ export class ProductProjectionRepository extends AbstractResourceRepository<"pro
37
38
  this._searchService = new ProductProjectionSearch(config);
38
39
  }
39
40
 
40
- create(context: RepositoryContext, draft: ProductDraft): ProductProjection {
41
- throw new Error("No valid action");
41
+ async create(
42
+ context: RepositoryContext,
43
+ draft: ProductDraft,
44
+ ): Promise<ProductProjection> {
45
+ throw new CommercetoolsError<InvalidOperationError>(
46
+ {
47
+ code: "InvalidOperation",
48
+ message: "No valid action",
49
+ },
50
+ 400,
51
+ );
42
52
  }
43
53
 
44
- get(
54
+ async get(
45
55
  context: RepositoryContext,
46
56
  id: string,
47
57
  params: GetParams = {},
48
- ): ProductProjection | null {
49
- const resource = this._storage.get(
58
+ ): Promise<ProductProjection | null> {
59
+ const resource = await this._storage.get(
50
60
  context.projectKey,
51
61
  "product",
52
62
  id,
53
63
  params,
54
64
  );
55
65
  if (resource) {
56
- return this._searchService.transform(resource, false, context.projectKey);
66
+ return await this._searchService.transform(
67
+ resource,
68
+ false,
69
+ context.projectKey,
70
+ );
57
71
  }
58
72
  return null;
59
73
  }
60
74
 
61
- query(context: RepositoryContext, params: ProductProjectionQueryParams = {}) {
62
- let resources = this._storage
63
- .all(context.projectKey, "product")
64
- .map((r) =>
75
+ async query(
76
+ context: RepositoryContext,
77
+ params: ProductProjectionQueryParams = {},
78
+ ) {
79
+ const allProducts = await this._storage.all(context.projectKey, "product");
80
+ let resources = await Promise.all(
81
+ allProducts.map((r) =>
65
82
  this._searchService.transform(
66
83
  r,
67
84
  params.staged ?? false,
68
85
  context.projectKey,
69
86
  ),
70
- )
71
- .filter((p) => {
72
- if (!(params.staged ?? false)) {
73
- return p.published;
74
- }
75
- return true;
76
- });
87
+ ),
88
+ );
89
+ resources = resources.filter((p) => {
90
+ if (!(params.staged ?? false)) {
91
+ return p.published;
92
+ }
93
+ return true;
94
+ });
77
95
 
78
96
  // Apply predicates
79
97
  if (params.where) {
@@ -116,8 +134,10 @@ export class ProductProjectionRepository extends AbstractResourceRepository<"pro
116
134
 
117
135
  // Expand the resources
118
136
  if (params.expand !== undefined) {
119
- resources = resources.map((resource) =>
120
- this._storage.expand(context.projectKey, resource, params.expand),
137
+ resources = await Promise.all(
138
+ resources.map((resource) =>
139
+ this._storage.expand(context.projectKey, resource, params.expand),
140
+ ),
121
141
  );
122
142
  }
123
143
 
@@ -130,8 +150,8 @@ export class ProductProjectionRepository extends AbstractResourceRepository<"pro
130
150
  const results = resources.slice(offset, offset + limit);
131
151
 
132
152
  return {
133
- count: totalResults,
134
- total: results.length,
153
+ count: results.length,
154
+ total: totalResults,
135
155
  offset: offset,
136
156
  limit: limit,
137
157
  results: results,
@@ -6,7 +6,7 @@ import type {
6
6
  ProductSelectionUpdateAction,
7
7
  } from "@commercetools/platform-sdk";
8
8
  import type { Config } from "#src/config.ts";
9
- import { createCustomFields } from "#src/repositories/helpers.ts";
9
+ import { ProductSelectionDraftSchema } from "#src/schemas/generated/product-selection.ts";
10
10
  import { getBaseResourceProperties } from "../helpers.ts";
11
11
  import type { Writable } from "../types.ts";
12
12
  import type { RepositoryContext, UpdateHandlerInterface } from "./abstract.ts";
@@ -19,20 +19,21 @@ export class ProductSelectionRepository extends AbstractResourceRepository<"prod
19
19
  constructor(config: Config) {
20
20
  super("product-selection", config);
21
21
  this.actions = new ProductSelectionUpdateHandler(this._storage);
22
+ this.draftSchema = ProductSelectionDraftSchema;
22
23
  }
23
24
 
24
- create(
25
+ async create(
25
26
  context: RepositoryContext,
26
27
  draft: ProductSelectionDraft,
27
- ): ProductSelection {
28
+ ): Promise<ProductSelection> {
28
29
  const resource: ProductSelection = {
29
- ...getBaseResourceProperties(),
30
+ ...getBaseResourceProperties(context.clientId),
30
31
  productCount: 0,
31
32
  key: draft.key,
32
33
  name: draft.name,
33
34
  mode: "Individual",
34
35
  };
35
- return this.saveNew(context, resource);
36
+ return await this.saveNew(context, resource);
36
37
  }
37
38
  }
38
39
 
@@ -51,19 +52,11 @@ class ProductSelectionUpdateHandler
51
52
  resource.name = name;
52
53
  }
53
54
 
54
- setCustomType(
55
+ async setCustomType(
55
56
  context: RepositoryContext,
56
57
  resource: Writable<ProductSelection>,
57
58
  { type, fields }: ProductSelectionSetCustomTypeAction,
58
59
  ) {
59
- if (type) {
60
- resource.custom = createCustomFields(
61
- { type, fields },
62
- context.projectKey,
63
- this._storage,
64
- );
65
- } else {
66
- resource.custom = undefined;
67
- }
60
+ await this._setCustomType(context, resource, { type, fields });
68
61
  }
69
62
  }
@@ -1,8 +1,11 @@
1
1
  import type {
2
+ InvalidOperationError,
2
3
  ProductTailoring,
3
4
  ProductTailoringUpdateAction,
4
5
  } from "@commercetools/platform-sdk";
5
6
  import type { Config } from "#src/config.ts";
7
+ import { CommercetoolsError } from "#src/exceptions.ts";
8
+ import { ProductTailoringDraftSchema } from "#src/schemas/generated/product-tailoring.ts";
6
9
  import type { RepositoryContext, UpdateHandlerInterface } from "./abstract.ts";
7
10
  import {
8
11
  AbstractResourceRepository,
@@ -13,10 +16,20 @@ export class ProductTailoringRepository extends AbstractResourceRepository<"prod
13
16
  constructor(config: Config) {
14
17
  super("product-tailoring", config);
15
18
  this.actions = new ProductTailoringUpdateHandler(this._storage);
19
+ this.draftSchema = ProductTailoringDraftSchema;
16
20
  }
17
21
 
18
- create(context: RepositoryContext, draft: any): ProductTailoring {
19
- throw new Error("Create method for product-tailoring not implemented.");
22
+ async create(
23
+ context: RepositoryContext,
24
+ draft: any,
25
+ ): Promise<ProductTailoring> {
26
+ throw new CommercetoolsError<InvalidOperationError>(
27
+ {
28
+ code: "InvalidOperation",
29
+ message: "Create method for product-tailoring not implemented.",
30
+ },
31
+ 400,
32
+ );
20
33
  }
21
34
  }
22
35
 
@@ -28,6 +41,12 @@ class ProductTailoringUpdateHandler
28
41
  >
29
42
  {
30
43
  setSlug() {
31
- throw new Error("SetSlug method for product-tailoring not implemented.");
44
+ throw new CommercetoolsError<InvalidOperationError>(
45
+ {
46
+ code: "InvalidOperation",
47
+ message: "SetSlug method for product-tailoring not implemented.",
48
+ },
49
+ 400,
50
+ );
32
51
  }
33
52
  }
@@ -2,17 +2,23 @@ import type {
2
2
  AttributeDefinition,
3
3
  AttributeDefinitionDraft,
4
4
  AttributeType,
5
+ InvalidOperationError,
5
6
  ProductType,
6
7
  ProductTypeAddAttributeDefinitionAction,
7
8
  ProductTypeChangeAttributeOrderByNameAction,
9
+ ProductTypeChangeDescriptionAction,
8
10
  ProductTypeChangeLabelAction,
9
11
  ProductTypeChangeLocalizedEnumValueLabelAction,
12
+ ProductTypeChangeNameAction,
10
13
  ProductTypeDraft,
11
14
  ProductTypeRemoveAttributeDefinitionAction,
12
15
  ProductTypeRemoveEnumValuesAction,
16
+ ProductTypeSetKeyAction,
13
17
  ProductTypeUpdateAction,
14
18
  } from "@commercetools/platform-sdk";
15
19
  import type { Config } from "#src/config.ts";
20
+ import { CommercetoolsError } from "#src/exceptions.ts";
21
+ import { ProductTypeDraftSchema } from "#src/schemas/generated/product-type.ts";
16
22
  import { getBaseResourceProperties } from "../helpers.ts";
17
23
  import type { Writable } from "../types.ts";
18
24
  import type { RepositoryContext, UpdateHandlerInterface } from "./abstract.ts";
@@ -25,11 +31,15 @@ export class ProductTypeRepository extends AbstractResourceRepository<"product-t
25
31
  constructor(config: Config) {
26
32
  super("product-type", config);
27
33
  this.actions = new ProductTypeUpdateHandler(config.storage);
34
+ this.draftSchema = ProductTypeDraftSchema;
28
35
  }
29
36
 
30
- create(context: RepositoryContext, draft: ProductTypeDraft): ProductType {
37
+ async create(
38
+ context: RepositoryContext,
39
+ draft: ProductTypeDraft,
40
+ ): Promise<ProductType> {
31
41
  const resource: ProductType = {
32
- ...getBaseResourceProperties(),
42
+ ...getBaseResourceProperties(context.clientId),
33
43
  key: draft.key,
34
44
  name: draft.name,
35
45
  description: draft.description,
@@ -38,7 +48,7 @@ export class ProductTypeRepository extends AbstractResourceRepository<"product-t
38
48
  ),
39
49
  };
40
50
 
41
- return this.saveNew(context, resource);
51
+ return await this.saveNew(context, resource);
42
52
  }
43
53
  }
44
54
 
@@ -86,7 +96,14 @@ class ProductTypeUpdateHandler
86
96
  attributeNames.forEach((attrName) => {
87
97
  const attr = attrs.get(attrName);
88
98
  if (attr === undefined) {
89
- throw new Error("New attr");
99
+ throw new CommercetoolsError<InvalidOperationError>(
100
+ {
101
+ code: "InvalidOperation",
102
+ message:
103
+ "Adding new attribute definitions is not fully supported yet",
104
+ },
105
+ 400,
106
+ );
90
107
  }
91
108
  result.push(attr);
92
109
 
@@ -172,4 +189,28 @@ class ProductTypeUpdateHandler
172
189
  }
173
190
  });
174
191
  }
192
+
193
+ setKey(
194
+ _context: RepositoryContext,
195
+ resource: Writable<ProductType>,
196
+ { key }: ProductTypeSetKeyAction,
197
+ ) {
198
+ resource.key = key;
199
+ }
200
+
201
+ changeName(
202
+ _context: RepositoryContext,
203
+ resource: Writable<ProductType>,
204
+ { name }: ProductTypeChangeNameAction,
205
+ ) {
206
+ resource.name = name;
207
+ }
208
+
209
+ changeDescription(
210
+ _context: RepositoryContext,
211
+ resource: Writable<ProductType>,
212
+ { description }: ProductTypeChangeDescriptionAction,
213
+ ) {
214
+ resource.description = description;
215
+ }
175
216
  }
@@ -1,4 +1,5 @@
1
1
  import type {
2
+ InvalidOperationError,
2
3
  Project,
3
4
  ProjectChangeBusinessUnitSearchStatusAction,
4
5
  ProjectChangeBusinessUnitStatusOnCreationAction,
@@ -21,6 +22,7 @@ import type {
21
22
  } from "@commercetools/platform-sdk";
22
23
  import type { ProjectSetBusinessUnitAssociateRoleOnCreationAction } from "@commercetools/platform-sdk/dist/declarations/src/generated/models/project";
23
24
  import type { Config } from "#src/config.ts";
25
+ import { CommercetoolsError } from "#src/exceptions.ts";
24
26
  import { maskSecretValue } from "../lib/masking.ts";
25
27
  import type { Writable } from "../types.ts";
26
28
  import type { RepositoryContext, UpdateHandlerInterface } from "./abstract.ts";
@@ -32,25 +34,37 @@ export class ProjectRepository extends AbstractRepository<Project> {
32
34
  this.actions = new ProjectUpdateHandler(config.storage);
33
35
  }
34
36
 
35
- get(context: RepositoryContext): Project | null {
36
- const resource = this._storage.getProject(context.projectKey);
37
- return this.postProcessResource(context, resource);
37
+ async get(context: RepositoryContext): Promise<Project | null> {
38
+ const resource = await this._storage.getProject(context.projectKey);
39
+ return await this.postProcessResource(context, resource);
38
40
  }
39
41
 
40
- postProcessResource(context: RepositoryContext, resource: Project): Project {
42
+ async postProcessResource(
43
+ context: RepositoryContext,
44
+ resource: Project | null,
45
+ ): Promise<Project | null> {
41
46
  if (resource) {
42
47
  return maskSecretValue(resource, "externalOAuth.authorizationHeader");
43
48
  }
44
49
  return resource;
45
50
  }
46
51
 
47
- saveNew(context: RepositoryContext, resource: Writable<Project>) {
52
+ async saveNew(
53
+ context: RepositoryContext,
54
+ resource: Writable<Project>,
55
+ ): Promise<Project> {
48
56
  resource.version = 1;
49
- this._storage.saveProject(resource);
57
+ await this._storage.saveProject(resource);
58
+ return resource;
50
59
  }
51
60
 
52
- saveUpdate(context: RepositoryContext, version: number, resource: Project) {
53
- this._storage.saveProject(resource);
61
+ async saveUpdate(
62
+ context: RepositoryContext,
63
+ version: number,
64
+ resource: Project,
65
+ ): Promise<Project> {
66
+ await this._storage.saveProject(resource);
67
+ return resource;
54
68
  }
55
69
  }
56
70
 
@@ -132,7 +146,13 @@ class ProjectUpdateHandler
132
146
  { status }: ProjectChangeCustomerSearchStatusAction,
133
147
  ) {
134
148
  if (!resource.searchIndexing?.customers) {
135
- throw new Error("Invalid project state");
149
+ throw new CommercetoolsError<InvalidOperationError>(
150
+ {
151
+ code: "InvalidOperation",
152
+ message: "Invalid project state",
153
+ },
154
+ 400,
155
+ );
136
156
  }
137
157
  resource.searchIndexing.customers.status = status;
138
158
  resource.searchIndexing.customers.lastModifiedAt = new Date().toISOString();
@@ -144,7 +164,13 @@ class ProjectUpdateHandler
144
164
  { status }: ProjectChangeBusinessUnitSearchStatusAction,
145
165
  ) {
146
166
  if (!resource.searchIndexing?.businessUnits) {
147
- throw new Error("Invalid project state");
167
+ throw new CommercetoolsError<InvalidOperationError>(
168
+ {
169
+ code: "InvalidOperation",
170
+ message: "Invalid project state",
171
+ },
172
+ 400,
173
+ );
148
174
  }
149
175
  resource.searchIndexing.businessUnits.status = status;
150
176
  resource.searchIndexing.businessUnits.lastModifiedAt =
@@ -197,7 +223,13 @@ class ProjectUpdateHandler
197
223
  { status }: ProjectChangeOrderSearchStatusAction,
198
224
  ) {
199
225
  if (!resource.searchIndexing?.orders) {
200
- throw new Error("Invalid project state");
226
+ throw new CommercetoolsError<InvalidOperationError>(
227
+ {
228
+ code: "InvalidOperation",
229
+ message: "Invalid project state",
230
+ },
231
+ 400,
232
+ );
201
233
  }
202
234
  resource.searchIndexing.orders.status = status;
203
235
  resource.searchIndexing.orders.lastModifiedAt = new Date().toISOString();
@@ -210,7 +242,13 @@ class ProjectUpdateHandler
210
242
  ) {
211
243
  if (mode === "ProductsSearch") {
212
244
  if (!resource.searchIndexing?.productsSearch) {
213
- throw new Error("Invalid project state");
245
+ throw new CommercetoolsError<InvalidOperationError>(
246
+ {
247
+ code: "InvalidOperation",
248
+ message: "Invalid project state",
249
+ },
250
+ 400,
251
+ );
214
252
  }
215
253
  resource.searchIndexing.productsSearch.status = enabled
216
254
  ? "Activated"
@@ -221,7 +259,13 @@ class ProjectUpdateHandler
221
259
  }
222
260
 
223
261
  if (!resource.searchIndexing?.products) {
224
- throw new Error("Invalid project state");
262
+ throw new CommercetoolsError<InvalidOperationError>(
263
+ {
264
+ code: "InvalidOperation",
265
+ message: "Invalid project state",
266
+ },
267
+ 400,
268
+ );
225
269
  }
226
270
  resource.searchIndexing.products.status = enabled
227
271
  ? "Activated"