@labdigital/commercetools-mock 0.9.1 → 0.10.1

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 (108) hide show
  1. package/README.md +8 -0
  2. package/dist/index.d.ts +354 -188
  3. package/dist/index.global.js +2346 -2209
  4. package/dist/index.global.js.map +1 -1
  5. package/dist/index.js +1968 -1829
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +2171 -2032
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +30 -21
  10. package/src/constants.ts +4 -2
  11. package/src/ctMock.ts +27 -86
  12. package/src/helpers.ts +10 -11
  13. package/src/index.test.ts +1 -1
  14. package/src/lib/haversine.ts +2 -2
  15. package/src/lib/masking.ts +3 -1
  16. package/src/lib/predicateParser.ts +93 -92
  17. package/src/lib/projectionSearchFilter.test.ts +28 -36
  18. package/src/lib/projectionSearchFilter.ts +88 -103
  19. package/src/oauth/store.ts +3 -3
  20. package/src/priceSelector.test.ts +16 -35
  21. package/src/priceSelector.ts +6 -9
  22. package/src/product-projection-search.ts +49 -57
  23. package/src/projectAPI.test.ts +7 -0
  24. package/src/projectAPI.ts +17 -22
  25. package/src/repositories/abstract.ts +102 -51
  26. package/src/repositories/cart-discount.ts +4 -5
  27. package/src/repositories/cart.ts +56 -46
  28. package/src/repositories/category.ts +23 -26
  29. package/src/repositories/channel.ts +5 -6
  30. package/src/repositories/custom-object.ts +41 -32
  31. package/src/repositories/customer-group.ts +4 -5
  32. package/src/repositories/customer.ts +42 -5
  33. package/src/repositories/discount-code.ts +5 -6
  34. package/src/repositories/errors.ts +10 -14
  35. package/src/repositories/extension.ts +16 -15
  36. package/src/repositories/helpers.ts +10 -15
  37. package/src/repositories/index.ts +75 -0
  38. package/src/repositories/inventory-entry.ts +5 -6
  39. package/src/repositories/my-order.ts +2 -2
  40. package/src/repositories/order-edit.ts +39 -0
  41. package/src/repositories/order.test.ts +16 -11
  42. package/src/repositories/order.ts +21 -14
  43. package/src/repositories/payment.ts +9 -10
  44. package/src/repositories/product-discount.ts +5 -25
  45. package/src/repositories/product-projection.ts +12 -5
  46. package/src/repositories/product-selection.ts +40 -0
  47. package/src/repositories/product-type.ts +38 -60
  48. package/src/repositories/product.ts +128 -85
  49. package/src/repositories/project.ts +16 -33
  50. package/src/repositories/quote-request.ts +28 -0
  51. package/src/repositories/quote.ts +28 -0
  52. package/src/repositories/review.ts +34 -0
  53. package/src/repositories/shipping-method.ts +25 -28
  54. package/src/repositories/shopping-list.ts +6 -6
  55. package/src/repositories/staged-quote.ts +29 -0
  56. package/src/repositories/standalone-price.ts +36 -0
  57. package/src/repositories/state.ts +16 -17
  58. package/src/repositories/store.ts +13 -29
  59. package/src/repositories/subscription.ts +4 -5
  60. package/src/repositories/tax-category.ts +9 -26
  61. package/src/repositories/type.ts +24 -27
  62. package/src/repositories/zone.ts +9 -11
  63. package/src/server.ts +5 -0
  64. package/src/services/abstract.ts +43 -12
  65. package/src/services/cart-discount.ts +3 -4
  66. package/src/services/cart.test.ts +9 -11
  67. package/src/services/cart.ts +42 -38
  68. package/src/services/category.test.ts +1 -2
  69. package/src/services/category.ts +3 -4
  70. package/src/services/channel.ts +3 -4
  71. package/src/services/custom-object.test.ts +6 -6
  72. package/src/services/custom-object.ts +4 -5
  73. package/src/services/customer-group.ts +3 -4
  74. package/src/services/customer.test.ts +136 -0
  75. package/src/services/customer.ts +5 -6
  76. package/src/services/discount-code.ts +3 -4
  77. package/src/services/extension.ts +3 -4
  78. package/src/services/index.ts +74 -0
  79. package/src/services/inventory-entry.test.ts +9 -13
  80. package/src/services/inventory-entry.ts +3 -4
  81. package/src/services/my-cart.test.ts +2 -0
  82. package/src/services/my-cart.ts +4 -5
  83. package/src/services/my-customer.ts +3 -4
  84. package/src/services/my-order.ts +4 -5
  85. package/src/services/my-payment.ts +3 -4
  86. package/src/services/order.test.ts +28 -26
  87. package/src/services/order.ts +4 -5
  88. package/src/services/payment.ts +3 -4
  89. package/src/services/product-discount.ts +3 -20
  90. package/src/services/product-projection.test.ts +76 -8
  91. package/src/services/product-projection.ts +4 -5
  92. package/src/services/product-type.ts +3 -20
  93. package/src/services/product.test.ts +200 -90
  94. package/src/services/product.ts +3 -4
  95. package/src/services/project.ts +5 -6
  96. package/src/services/shipping-method.ts +3 -4
  97. package/src/services/shopping-list.ts +3 -4
  98. package/src/services/state.ts +3 -4
  99. package/src/services/store.test.ts +11 -2
  100. package/src/services/store.ts +4 -21
  101. package/src/services/subscription.ts +3 -4
  102. package/src/services/tax-category.ts +3 -20
  103. package/src/services/type.ts +3 -4
  104. package/src/services/zone.ts +3 -4
  105. package/src/storage/abstract.ts +82 -0
  106. package/src/{storage.ts → storage/in-memory.ts} +79 -147
  107. package/src/storage/index.ts +2 -0
  108. package/src/types.ts +52 -83
@@ -18,23 +18,22 @@ import {
18
18
  Product,
19
19
  ProductPagedQueryResponse,
20
20
  ProductVariant,
21
- ReferenceTypeId,
22
21
  } from '@commercetools/platform-sdk'
23
22
  import { v4 as uuidv4 } from 'uuid'
23
+ import { CommercetoolsError } from '../exceptions'
24
24
  import { getBaseResourceProperties } from '../helpers'
25
+ import { Writable } from '../types'
25
26
  import { AbstractResourceRepository, RepositoryContext } from './abstract'
26
27
  import { createCustomFields } from './helpers'
27
- import { Writable } from '../types'
28
- import { CommercetoolsError } from '../exceptions'
29
28
 
30
- export class CartRepository extends AbstractResourceRepository {
31
- getTypeId(): ReferenceTypeId {
32
- return 'cart'
29
+ export class CartRepository extends AbstractResourceRepository<'cart'> {
30
+ getTypeId() {
31
+ return 'cart' as const
33
32
  }
34
33
 
35
34
  create(context: RepositoryContext, draft: CartDraft): Cart {
36
35
  const lineItems =
37
- draft.lineItems?.map(draftLineItem =>
36
+ draft.lineItems?.map((draftLineItem) =>
38
37
  this.draftLineItemtoLineItem(
39
38
  context.projectKey,
40
39
  draftLineItem,
@@ -43,35 +42,35 @@ export class CartRepository extends AbstractResourceRepository {
43
42
  )
44
43
  ) ?? []
45
44
 
46
- const resource: Cart = {
45
+ const resource: Writable<Cart> = {
47
46
  ...getBaseResourceProperties(),
48
47
  cartState: 'Active',
49
- lineItems,
48
+ country: draft.country,
50
49
  customLineItems: [],
50
+ lineItems,
51
+ locale: draft.locale,
52
+ taxCalculationMode: draft.taxCalculationMode ?? 'LineItemLevel',
53
+ taxMode: draft.taxMode ?? 'Platform',
54
+ taxRoundingMode: draft.taxRoundingMode ?? 'HalfEven',
51
55
  totalPrice: {
52
56
  type: 'centPrecision',
53
57
  centAmount: 0,
54
58
  currencyCode: draft.currency,
55
59
  fractionDigits: 0,
56
60
  },
57
- taxMode: draft.taxMode ?? 'Platform',
58
- taxRoundingMode: draft.taxRoundingMode ?? 'HalfEven',
59
- taxCalculationMode: draft.taxCalculationMode ?? 'LineItemLevel',
60
- refusedGifts: [],
61
- locale: draft.locale,
62
- country: draft.country,
61
+ shippingMode: 'Single',
62
+ shipping: [],
63
63
  origin: draft.origin ?? 'Customer',
64
+ refusedGifts: [],
64
65
  custom: createCustomFields(
65
66
  draft.custom,
66
67
  context.projectKey,
67
68
  this._storage
68
69
  ),
69
70
  }
70
-
71
- // @ts-ignore
72
71
  resource.totalPrice.centAmount = calculateCartTotalPrice(resource)
73
72
 
74
- this.save(context, resource)
73
+ this.saveNew(context, resource)
75
74
  return resource
76
75
  }
77
76
 
@@ -94,7 +93,6 @@ export class CartRepository extends AbstractResourceRepository {
94
93
  { productId, variantId, sku, quantity = 1 }: CartAddLineItemAction
95
94
  ) => {
96
95
  let product: Product | null = null
97
- let variant: ProductVariant | undefined
98
96
 
99
97
  if (productId && variantId) {
100
98
  // Fetch product and variant by ID
@@ -128,10 +126,10 @@ export class CartRepository extends AbstractResourceRepository {
128
126
  }
129
127
 
130
128
  // Find matching variant
131
- variant = [
129
+ const variant: ProductVariant | undefined = [
132
130
  product.masterData.current.masterVariant,
133
131
  ...product.masterData.current.variants,
134
- ].find(x => {
132
+ ].find((x) => {
135
133
  if (sku) return x.sku === sku
136
134
  if (variantId) return x.id === variantId
137
135
  return false
@@ -148,11 +146,11 @@ export class CartRepository extends AbstractResourceRepository {
148
146
  }
149
147
 
150
148
  const alreadyAdded = resource.lineItems.some(
151
- x => x.productId === product?.id && x.variant.id === variant?.id
149
+ (x) => x.productId === product?.id && x.variant.id === variant?.id
152
150
  )
153
151
  if (alreadyAdded) {
154
152
  // increase quantity and update total price
155
- resource.lineItems.map(x => {
153
+ resource.lineItems.map((x) => {
156
154
  if (x.productId === product?.id && x.variant.id === variant?.id) {
157
155
  x.quantity += quantity
158
156
  x.totalPrice.centAmount = calculateLineItemTotalPrice(x)
@@ -184,11 +182,13 @@ export class CartRepository extends AbstractResourceRepository {
184
182
  id: uuidv4(),
185
183
  productId: product.id,
186
184
  productKey: product.key,
187
- name: product.masterData.current.name,
188
185
  productSlug: product.masterData.current.slug,
189
186
  productType: product.productType,
187
+ name: product.masterData.current.name,
190
188
  variant,
191
189
  price: price,
190
+ taxedPricePortions: [],
191
+ perMethodTaxRate: [],
192
192
  totalPrice: {
193
193
  ...price.value,
194
194
  centAmount: price.value.centAmount * quantity,
@@ -209,7 +209,7 @@ export class CartRepository extends AbstractResourceRepository {
209
209
  resource: Writable<Cart>,
210
210
  { lineItemId, quantity }: CartRemoveLineItemAction
211
211
  ) => {
212
- const lineItem = resource.lineItems.find(x => x.id === lineItemId)
212
+ const lineItem = resource.lineItems.find((x) => x.id === lineItemId)
213
213
  if (!lineItem) {
214
214
  // Check if product is found
215
215
  throw new CommercetoolsError<GeneralError>({
@@ -221,10 +221,12 @@ export class CartRepository extends AbstractResourceRepository {
221
221
  const shouldDelete = !quantity || quantity >= lineItem.quantity
222
222
  if (shouldDelete) {
223
223
  // delete line item
224
- resource.lineItems = resource.lineItems.filter(x => x.id !== lineItemId)
224
+ resource.lineItems = resource.lineItems.filter(
225
+ (x) => x.id !== lineItemId
226
+ )
225
227
  } else {
226
228
  // decrease quantity and update total price
227
- resource.lineItems.map(x => {
229
+ resource.lineItems.map((x) => {
228
230
  if (x.id === lineItemId && quantity) {
229
231
  x.quantity -= quantity
230
232
  x.totalPrice.centAmount = calculateLineItemTotalPrice(x)
@@ -248,21 +250,28 @@ export class CartRepository extends AbstractResourceRepository {
248
250
  resource: Writable<Cart>,
249
251
  { shippingMethod }: CartSetShippingMethodAction
250
252
  ) => {
251
- const resolvedType = this._storage.getByResourceIdentifier(
252
- context.projectKey,
253
- //@ts-ignore
254
- shippingMethod
255
- )
253
+ if (shippingMethod) {
254
+ const method = this._storage.getByResourceIdentifier<'shipping-method'>(
255
+ context.projectKey,
256
+ shippingMethod
257
+ )
256
258
 
257
- if (!resolvedType) {
258
- throw new Error(`Type ${shippingMethod} not found`)
259
- }
260
- //@ts-ignore
261
- resource.shippingInfo = {
262
- shippingMethod: {
263
- typeId: 'shipping-method',
264
- id: resolvedType.id,
265
- },
259
+ if (!method) {
260
+ throw new Error(`Type ${shippingMethod} not found`)
261
+ }
262
+
263
+ // Based on the address we should select a shipping zone and
264
+ // use that to define the price.
265
+ // @ts-ignore
266
+ resource.shippingInfo = {
267
+ shippingMethod: {
268
+ typeId: 'shipping-method',
269
+ id: method.id,
270
+ },
271
+ shippingMethodName: method.name,
272
+ }
273
+ } else {
274
+ resource.shippingInfo = undefined
266
275
  }
267
276
  },
268
277
  setCountry: (
@@ -338,7 +347,6 @@ export class CartRepository extends AbstractResourceRepository {
338
347
  const { productId, quantity, variantId, sku } = draftLineItem
339
348
 
340
349
  let product: Product | null = null
341
- let variant: ProductVariant | undefined
342
350
 
343
351
  if (productId && variantId) {
344
352
  // Fetch product and variant by ID
@@ -367,10 +375,10 @@ export class CartRepository extends AbstractResourceRepository {
367
375
  }
368
376
 
369
377
  // Find matching variant
370
- variant = [
378
+ const variant = [
371
379
  product.masterData.current.masterVariant,
372
380
  ...product.masterData.current.variants,
373
- ].find(x => {
381
+ ].find((x) => {
374
382
  if (sku) return x.sku === sku
375
383
  if (variantId) return x.id === variantId
376
384
  return false
@@ -398,15 +406,17 @@ export class CartRepository extends AbstractResourceRepository {
398
406
  id: uuidv4(),
399
407
  productId: product.id,
400
408
  productKey: product.key,
401
- name: product.masterData.current.name,
402
409
  productSlug: product.masterData.current.slug,
403
410
  productType: product.productType,
411
+ name: product.masterData.current.name,
404
412
  variant,
405
413
  price: price,
406
414
  totalPrice: {
407
415
  ...price.value,
408
416
  centAmount: price.value.centAmount * quant,
409
417
  },
418
+ taxedPricePortions: [],
419
+ perMethodTaxRate: [],
410
420
  quantity: quant,
411
421
  discountedPricePerQuantity: [],
412
422
  lineItemMode: 'Standard',
@@ -432,7 +442,7 @@ const selectPrice = ({
432
442
  // Quick-and-dirty way of selecting price based on the given currency and country.
433
443
  // Can be improved later to give more priority to exact matches over
434
444
  // 'all country' matches, and include customer groups in the mix as well
435
- return prices.find(price => {
445
+ return prices.find((price) => {
436
446
  const countryMatch = !price.country || price.country === country
437
447
  const currencyMatch = price.value.currencyCode === currency
438
448
  return countryMatch && currencyMatch
@@ -1,4 +1,3 @@
1
- import { v4 as uuidv4 } from 'uuid'
2
1
  import {
3
2
  Category,
4
3
  CategoryChangeAssetNameAction,
@@ -13,16 +12,16 @@ import {
13
12
  CategorySetMetaDescriptionAction,
14
13
  CategorySetMetaKeywordsAction,
15
14
  CategorySetMetaTitleAction,
16
- ReferenceTypeId,
17
15
  } from '@commercetools/platform-sdk'
18
- import { Writable } from 'types'
16
+ import { v4 as uuidv4 } from 'uuid'
19
17
  import { getBaseResourceProperties } from '../helpers'
20
- import { createCustomFields } from './helpers'
18
+ import { Writable } from '../types'
21
19
  import { AbstractResourceRepository, RepositoryContext } from './abstract'
20
+ import { createCustomFields } from './helpers'
22
21
 
23
- export class CategoryRepository extends AbstractResourceRepository {
24
- getTypeId(): ReferenceTypeId {
25
- return 'category'
22
+ export class CategoryRepository extends AbstractResourceRepository<'category'> {
23
+ getTypeId() {
24
+ return 'category' as const
26
25
  }
27
26
 
28
27
  create(context: RepositoryContext, draft: CategoryDraft): Category {
@@ -38,28 +37,26 @@ export class CategoryRepository extends AbstractResourceRepository {
38
37
  : undefined,
39
38
  ancestors: [], // TODO
40
39
  assets:
41
- draft.assets?.map(d => {
42
- return {
43
- id: uuidv4(),
44
- name: d.name,
45
- description: d.description,
46
- sources: d.sources,
47
- tags: d.tags,
48
- key: d.key,
49
- custom: createCustomFields(
50
- draft.custom,
51
- context.projectKey,
52
- this._storage
53
- ),
54
- }
55
- }) || [],
40
+ draft.assets?.map((d) => ({
41
+ id: uuidv4(),
42
+ name: d.name,
43
+ description: d.description,
44
+ sources: d.sources,
45
+ tags: d.tags,
46
+ key: d.key,
47
+ custom: createCustomFields(
48
+ draft.custom,
49
+ context.projectKey,
50
+ this._storage
51
+ ),
52
+ })) || [],
56
53
  custom: createCustomFields(
57
54
  draft.custom,
58
55
  context.projectKey,
59
56
  this._storage
60
57
  ),
61
58
  }
62
- this.save(context, resource)
59
+ this.saveNew(context, resource)
63
60
  return resource
64
61
  }
65
62
 
@@ -69,7 +66,7 @@ export class CategoryRepository extends AbstractResourceRepository {
69
66
  resource: Writable<Category>,
70
67
  { assetId, assetKey, name }: CategoryChangeAssetNameAction
71
68
  ) => {
72
- resource.assets?.forEach(asset => {
69
+ resource.assets?.forEach((asset) => {
73
70
  if (assetId && assetId === asset.id) {
74
71
  asset.name = name
75
72
  }
@@ -97,7 +94,7 @@ export class CategoryRepository extends AbstractResourceRepository {
97
94
  resource: Writable<Category>,
98
95
  { assetId, assetKey, description }: CategorySetAssetDescriptionAction
99
96
  ) => {
100
- resource.assets?.forEach(asset => {
97
+ resource.assets?.forEach((asset) => {
101
98
  if (assetId && assetId === asset.id) {
102
99
  asset.description = description
103
100
  }
@@ -111,7 +108,7 @@ export class CategoryRepository extends AbstractResourceRepository {
111
108
  resource: Writable<Category>,
112
109
  { assetId, assetKey, sources }: CategorySetAssetSourcesAction
113
110
  ) => {
114
- resource.assets?.forEach(asset => {
111
+ resource.assets?.forEach((asset) => {
115
112
  if (assetId && assetId === asset.id) {
116
113
  asset.sources = sources
117
114
  }
@@ -9,16 +9,15 @@ import {
9
9
  ChannelSetCustomTypeAction,
10
10
  ChannelSetGeoLocationAction,
11
11
  ChannelUpdateAction,
12
- ReferenceTypeId,
13
12
  } from '@commercetools/platform-sdk'
14
- import { Writable } from 'types'
15
13
  import { getBaseResourceProperties } from '../helpers'
14
+ import { Writable } from '../types'
16
15
  import { AbstractResourceRepository, RepositoryContext } from './abstract'
17
16
  import { createAddress, createCustomFields } from './helpers'
18
17
 
19
- export class ChannelRepository extends AbstractResourceRepository {
20
- getTypeId(): ReferenceTypeId {
21
- return 'channel'
18
+ export class ChannelRepository extends AbstractResourceRepository<'channel'> {
19
+ getTypeId() {
20
+ return 'channel' as const
22
21
  }
23
22
 
24
23
  create(context: RepositoryContext, draft: ChannelDraft): Channel {
@@ -36,7 +35,7 @@ export class ChannelRepository extends AbstractResourceRepository {
36
35
  this._storage
37
36
  ),
38
37
  }
39
- this.save(context, resource)
38
+ this.saveNew(context, resource)
40
39
  return resource
41
40
  }
42
41
 
@@ -1,16 +1,17 @@
1
1
  import {
2
2
  CustomObject,
3
3
  CustomObjectDraft,
4
- ReferenceTypeId,
4
+ InvalidOperationError,
5
5
  } from '@commercetools/platform-sdk'
6
- import { checkConcurrentModification } from './errors'
7
- import { AbstractResourceRepository, RepositoryContext } from './abstract'
6
+ import { CommercetoolsError } from '../exceptions'
7
+ import { cloneObject, getBaseResourceProperties } from '../helpers'
8
8
  import { Writable } from '../types'
9
- import { getBaseResourceProperties } from '../helpers'
9
+ import { AbstractResourceRepository, RepositoryContext } from './abstract'
10
+ import { checkConcurrentModification } from './errors'
10
11
 
11
- export class CustomObjectRepository extends AbstractResourceRepository {
12
- getTypeId(): ReferenceTypeId {
13
- return 'key-value-document'
12
+ export class CustomObjectRepository extends AbstractResourceRepository<'key-value-document'> {
13
+ getTypeId() {
14
+ return 'key-value-document' as const
14
15
  }
15
16
 
16
17
  create(
@@ -21,37 +22,46 @@ export class CustomObjectRepository extends AbstractResourceRepository {
21
22
  context,
22
23
  draft.container,
23
24
  draft.key
24
- )
25
+ ) as Writable<CustomObject | undefined>
25
26
 
26
- const baseProperties = getBaseResourceProperties()
27
27
  if (current) {
28
- baseProperties.id = current.id
29
-
30
- if (!draft.version) {
28
+ // Only check version if it is passed in the draft
29
+ if (draft.version) {
30
+ checkConcurrentModification(current.version, draft.version, current.id)
31
+ } else {
31
32
  draft.version = current.version
32
33
  }
33
34
 
34
- checkConcurrentModification(current, draft.version)
35
- if (draft.value === current.value) {
36
- return current
35
+ if (draft.value !== current.value) {
36
+ const updated = cloneObject(current) as Writable<CustomObject>
37
+ updated.value = draft.value
38
+ updated.version += 1
39
+ this.saveUpdate(context, draft.version, updated)
40
+ return updated
37
41
  }
38
-
39
- baseProperties.version = current.version
42
+ return current
40
43
  } else {
44
+ // If the resource is new the only valid version is 0
41
45
  if (draft.version) {
42
- baseProperties.version = draft.version
46
+ throw new CommercetoolsError<InvalidOperationError>(
47
+ {
48
+ code: 'InvalidOperation',
49
+ message: 'version on create must be 0',
50
+ },
51
+ 400
52
+ )
53
+ }
54
+ const baseProperties = getBaseResourceProperties()
55
+ const resource: CustomObject = {
56
+ ...baseProperties,
57
+ container: draft.container,
58
+ key: draft.key,
59
+ value: draft.value,
43
60
  }
44
- }
45
61
 
46
- const resource: CustomObject = {
47
- ...baseProperties,
48
- container: draft.container,
49
- key: draft.key,
50
- value: draft.value,
62
+ this.saveNew(context, resource)
63
+ return resource
51
64
  }
52
-
53
- this.save(context, resource)
54
- return resource
55
65
  }
56
66
 
57
67
  getWithContainerAndKey(
@@ -59,10 +69,9 @@ export class CustomObjectRepository extends AbstractResourceRepository {
59
69
  container: string,
60
70
  key: string
61
71
  ) {
62
- const items = this._storage.all(
63
- context.projectKey,
64
- this.getTypeId()
65
- ) as Array<CustomObject>
66
- return items.find(item => item.container === container && item.key === key)
72
+ const items = this._storage.all(context.projectKey, this.getTypeId())
73
+ return items.find(
74
+ (item) => item.container === container && item.key === key
75
+ )
67
76
  }
68
77
  }
@@ -5,16 +5,15 @@ import {
5
5
  CustomerGroupSetCustomFieldAction,
6
6
  CustomerGroupSetCustomTypeAction,
7
7
  CustomerGroupSetKeyAction,
8
- ReferenceTypeId,
9
8
  } from '@commercetools/platform-sdk'
10
9
  import { Writable } from 'types'
11
10
  import { getBaseResourceProperties } from '../helpers'
12
11
  import { AbstractResourceRepository, RepositoryContext } from './abstract'
13
12
  import { createCustomFields } from './helpers'
14
13
 
15
- export class CustomerGroupRepository extends AbstractResourceRepository {
16
- getTypeId(): ReferenceTypeId {
17
- return 'customer'
14
+ export class CustomerGroupRepository extends AbstractResourceRepository<'customer-group'> {
15
+ getTypeId() {
16
+ return 'customer-group' as const
18
17
  }
19
18
  create(context: RepositoryContext, draft: CustomerGroupDraft): CustomerGroup {
20
19
  const resource: CustomerGroup = {
@@ -27,7 +26,7 @@ export class CustomerGroupRepository extends AbstractResourceRepository {
27
26
  this._storage
28
27
  ),
29
28
  }
30
- this.save(context, resource)
29
+ this.saveNew(context, resource)
31
30
  return resource
32
31
  }
33
32
 
@@ -2,15 +2,18 @@ import {
2
2
  Customer,
3
3
  CustomerChangeEmailAction,
4
4
  CustomerDraft,
5
- ReferenceTypeId,
5
+ CustomerSetAuthenticationModeAction,
6
+ InvalidInputError,
7
+ InvalidJsonInputError,
6
8
  } from '@commercetools/platform-sdk'
7
9
  import { Writable } from 'types'
10
+ import { CommercetoolsError } from '../exceptions'
8
11
  import { getBaseResourceProperties } from '../helpers'
9
12
  import { AbstractResourceRepository, RepositoryContext } from './abstract'
10
13
 
11
- export class CustomerRepository extends AbstractResourceRepository {
12
- getTypeId(): ReferenceTypeId {
13
- return 'customer'
14
+ export class CustomerRepository extends AbstractResourceRepository<'customer'> {
15
+ getTypeId() {
16
+ return 'customer' as const
14
17
  }
15
18
 
16
19
  create(context: RepositoryContext, draft: CustomerDraft): Customer {
@@ -23,7 +26,7 @@ export class CustomerRepository extends AbstractResourceRepository {
23
26
  isEmailVerified: draft.isEmailVerified || false,
24
27
  addresses: [],
25
28
  }
26
- this.save(context, resource)
29
+ this.saveNew(context, resource)
27
30
  return resource
28
31
  }
29
32
 
@@ -48,5 +51,39 @@ export class CustomerRepository extends AbstractResourceRepository {
48
51
  ) => {
49
52
  resource.email = email
50
53
  },
54
+ setAuthenticationMode: (
55
+ _context: RepositoryContext,
56
+ resource: Writable<Customer>,
57
+ { authMode, password }: CustomerSetAuthenticationModeAction
58
+ ) => {
59
+ if (resource.authenticationMode === authMode) {
60
+ throw new CommercetoolsError<InvalidInputError>(
61
+ {
62
+ code: 'InvalidInput',
63
+ message: `The customer is already using the '${resource.authenticationMode}' authentication mode.`,
64
+ },
65
+ 400
66
+ )
67
+ }
68
+ resource.authenticationMode = authMode
69
+ if (authMode === 'ExternalAuth') {
70
+ delete resource.password
71
+ return
72
+ }
73
+ if (authMode === 'Password') {
74
+ resource.password = password
75
+ ? Buffer.from(password).toString('base64')
76
+ : undefined
77
+ return
78
+ }
79
+ throw new CommercetoolsError<InvalidJsonInputError>(
80
+ {
81
+ code: 'InvalidJsonInput',
82
+ message: 'Request body does not contain valid JSON.',
83
+ detailedErrorMessage: `actions -> authMode: Invalid enum value: '${authMode}'. Expected one of: 'Password','ExternalAuth'`,
84
+ },
85
+ 400
86
+ )
87
+ },
51
88
  }
52
89
  }
@@ -15,16 +15,15 @@ import {
15
15
  DiscountCodeSetValidFromAndUntilAction,
16
16
  DiscountCodeSetValidUntilAction,
17
17
  DiscountCodeUpdateAction,
18
- ReferenceTypeId,
19
18
  } from '@commercetools/platform-sdk'
20
- import { Writable } from 'types'
21
19
  import { getBaseResourceProperties } from '../helpers'
20
+ import { Writable } from '../types'
22
21
  import { AbstractResourceRepository, RepositoryContext } from './abstract'
23
22
  import { createCustomFields } from './helpers'
24
23
 
25
- export class DiscountCodeRepository extends AbstractResourceRepository {
26
- getTypeId(): ReferenceTypeId {
27
- return 'cart-discount'
24
+ export class DiscountCodeRepository extends AbstractResourceRepository<'discount-code'> {
25
+ getTypeId() {
26
+ return 'discount-code' as const
28
27
  }
29
28
 
30
29
  create(context: RepositoryContext, draft: DiscountCodeDraft): DiscountCode {
@@ -54,7 +53,7 @@ export class DiscountCodeRepository extends AbstractResourceRepository {
54
53
  this._storage
55
54
  ),
56
55
  }
57
- this.save(context, resource)
56
+ this.saveNew(context, resource)
58
57
  return resource
59
58
  }
60
59
 
@@ -1,24 +1,20 @@
1
- import {
2
- BaseResource,
3
- ConcurrentModificationError,
4
- Project,
5
- } from '@commercetools/platform-sdk'
1
+ import { ConcurrentModificationError } from '@commercetools/platform-sdk'
6
2
  import { CommercetoolsError } from '../exceptions'
7
3
 
8
4
  export const checkConcurrentModification = (
9
- resource: BaseResource | Project,
10
- expectedVersion: number
5
+ currentVersion: number,
6
+ expectedVersion: number,
7
+ identifier: string
11
8
  ) => {
12
- if (resource.version === expectedVersion) return
13
-
14
- const identifier = (resource as BaseResource).id
15
- ? (resource as BaseResource).id
16
- : (resource as Project).key
9
+ if (currentVersion === expectedVersion) return
10
+ console.error(
11
+ `Object ${identifier} has a different version than expected. Expected: ${expectedVersion} - Actual: ${currentVersion}.`
12
+ )
17
13
 
18
14
  throw new CommercetoolsError<ConcurrentModificationError>(
19
15
  {
20
- message: `Object ${identifier} has a different version than expected. Expected: ${expectedVersion} - Actual: ${resource.version}.`,
21
- currentVersion: resource.version,
16
+ message: `Object ${identifier} has a different version than expected. Expected: ${expectedVersion} - Actual: ${currentVersion}.`,
17
+ currentVersion: currentVersion,
22
18
  code: 'ConcurrentModification',
23
19
  },
24
20
  409