@labdigital/commercetools-mock 0.6.5 → 0.8.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 (118) hide show
  1. package/dist/index.d.ts +409 -3
  2. package/dist/index.global.js +49983 -0
  3. package/dist/index.global.js.map +1 -0
  4. package/dist/index.js +4835 -6
  5. package/dist/index.js.map +1 -0
  6. package/dist/index.mjs +4803 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/package.json +36 -17
  9. package/src/ctMock.ts +5 -0
  10. package/src/helpers.ts +39 -0
  11. package/src/lib/projectionSearchFilter.test.ts +183 -0
  12. package/src/lib/projectionSearchFilter.ts +347 -0
  13. package/src/priceSelector.test.ts +96 -0
  14. package/src/priceSelector.ts +109 -0
  15. package/src/product-projection-search.ts +345 -0
  16. package/src/projectAPI.ts +19 -20
  17. package/src/repositories/category.ts +36 -0
  18. package/src/repositories/channel.ts +104 -0
  19. package/src/repositories/customer-group.ts +37 -0
  20. package/src/repositories/discount-code.ts +37 -0
  21. package/src/repositories/helpers.ts +46 -4
  22. package/src/repositories/product-discount.ts +181 -0
  23. package/src/repositories/product-projection.ts +30 -59
  24. package/src/repositories/product-type.ts +88 -6
  25. package/src/repositories/product.ts +49 -9
  26. package/src/repositories/shipping-method.ts +31 -0
  27. package/src/repositories/store.ts +43 -3
  28. package/src/repositories/type.ts +19 -0
  29. package/src/services/custom-object.test.ts +2 -2
  30. package/src/services/product-discount.ts +33 -0
  31. package/src/services/product-projection.test.ts +329 -107
  32. package/src/services/product.test.ts +12 -0
  33. package/src/storage.ts +116 -58
  34. package/src/types.ts +9 -2
  35. package/dist/commercetools-mock.cjs.development.js +0 -4382
  36. package/dist/commercetools-mock.cjs.development.js.map +0 -1
  37. package/dist/commercetools-mock.cjs.production.min.js +0 -2
  38. package/dist/commercetools-mock.cjs.production.min.js.map +0 -1
  39. package/dist/commercetools-mock.esm.js +0 -4374
  40. package/dist/commercetools-mock.esm.js.map +0 -1
  41. package/dist/constants.d.ts +0 -2
  42. package/dist/ctMock.d.ts +0 -32
  43. package/dist/exceptions.d.ts +0 -12
  44. package/dist/helpers.d.ts +0 -6
  45. package/dist/lib/expandParser.d.ts +0 -15
  46. package/dist/lib/filterParser.d.ts +0 -1
  47. package/dist/lib/haversine.d.ts +0 -8
  48. package/dist/lib/masking.d.ts +0 -1
  49. package/dist/lib/predicateParser.d.ts +0 -11
  50. package/dist/lib/proxy.d.ts +0 -1
  51. package/dist/oauth/errors.d.ts +0 -8
  52. package/dist/oauth/helpers.d.ts +0 -2
  53. package/dist/oauth/server.d.ts +0 -12
  54. package/dist/oauth/store.d.ts +0 -14
  55. package/dist/projectAPI.d.ts +0 -12
  56. package/dist/repositories/abstract.d.ts +0 -33
  57. package/dist/repositories/cart-discount.d.ts +0 -9
  58. package/dist/repositories/cart.d.ts +0 -21
  59. package/dist/repositories/category.d.ts +0 -18
  60. package/dist/repositories/channel.d.ts +0 -6
  61. package/dist/repositories/custom-object.d.ts +0 -8
  62. package/dist/repositories/customer-group.d.ts +0 -11
  63. package/dist/repositories/customer.d.ts +0 -11
  64. package/dist/repositories/discount-code.d.ts +0 -8
  65. package/dist/repositories/errors.d.ts +0 -2
  66. package/dist/repositories/extension.d.ts +0 -8
  67. package/dist/repositories/helpers.d.ts +0 -10
  68. package/dist/repositories/inventory-entry.d.ts +0 -14
  69. package/dist/repositories/my-order.d.ts +0 -6
  70. package/dist/repositories/order.d.ts +0 -26
  71. package/dist/repositories/payment.d.ts +0 -23
  72. package/dist/repositories/product-projection.d.ts +0 -10
  73. package/dist/repositories/product-type.d.ts +0 -10
  74. package/dist/repositories/product.d.ts +0 -11
  75. package/dist/repositories/project.d.ts +0 -8
  76. package/dist/repositories/shipping-method.d.ts +0 -10
  77. package/dist/repositories/shopping-list.d.ts +0 -6
  78. package/dist/repositories/state.d.ts +0 -8
  79. package/dist/repositories/store.d.ts +0 -10
  80. package/dist/repositories/subscription.d.ts +0 -6
  81. package/dist/repositories/tax-category.d.ts +0 -10
  82. package/dist/repositories/type.d.ts +0 -8
  83. package/dist/repositories/zone.d.ts +0 -8
  84. package/dist/server.d.ts +0 -1
  85. package/dist/services/abstract.d.ts +0 -20
  86. package/dist/services/cart-discount.d.ts +0 -9
  87. package/dist/services/cart.d.ts +0 -12
  88. package/dist/services/category.d.ts +0 -9
  89. package/dist/services/channel.d.ts +0 -9
  90. package/dist/services/custom-object.d.ts +0 -13
  91. package/dist/services/customer-group.d.ts +0 -9
  92. package/dist/services/customer.d.ts +0 -10
  93. package/dist/services/discount-code.d.ts +0 -9
  94. package/dist/services/extension.d.ts +0 -9
  95. package/dist/services/inventory-entry.d.ts +0 -9
  96. package/dist/services/my-cart.d.ts +0 -11
  97. package/dist/services/my-customer.d.ts +0 -13
  98. package/dist/services/my-order.d.ts +0 -10
  99. package/dist/services/my-payment.d.ts +0 -9
  100. package/dist/services/order.d.ts +0 -12
  101. package/dist/services/payment.d.ts +0 -9
  102. package/dist/services/product-projection.d.ts +0 -11
  103. package/dist/services/product-type.d.ts +0 -11
  104. package/dist/services/product.d.ts +0 -9
  105. package/dist/services/project.d.ts +0 -11
  106. package/dist/services/shipping-method.d.ts +0 -10
  107. package/dist/services/shopping-list.d.ts +0 -9
  108. package/dist/services/state.d.ts +0 -9
  109. package/dist/services/store.d.ts +0 -11
  110. package/dist/services/subscription.d.ts +0 -9
  111. package/dist/services/tax-category.d.ts +0 -11
  112. package/dist/services/type.d.ts +0 -9
  113. package/dist/services/zone.d.ts +0 -9
  114. package/dist/storage.d.ts +0 -56
  115. package/dist/types.d.ts +0 -89
  116. package/dist/validate.d.ts +0 -7482
  117. package/src/lib/filterParser.test.ts +0 -15
  118. package/src/lib/filterParser.ts +0 -17
@@ -4,9 +4,13 @@ import {
4
4
  AttributeDefinitionDraft,
5
5
  AttributeType,
6
6
  ProductType,
7
+ ProductTypeAddAttributeDefinitionAction,
8
+ ProductTypeChangeAttributeOrderAction,
7
9
  ProductTypeChangeLabelAction,
8
10
  ProductTypeChangeLocalizedEnumValueLabelAction,
9
11
  ProductTypeDraft,
12
+ ProductTypeRemoveAttributeDefinitionAction,
13
+ ProductTypeRemoveEnumValuesAction,
10
14
  ProductTypeUpdateAction,
11
15
  ReferenceTypeId,
12
16
  } from '@commercetools/platform-sdk'
@@ -36,12 +40,18 @@ export class ProductTypeRepository extends AbstractResourceRepository {
36
40
  attributeDefinitionFromAttributeDefinitionDraft = (
37
41
  _context: RepositoryContext,
38
42
  draft: AttributeDefinitionDraft
39
- ): AttributeDefinition => ({
40
- ...draft,
41
- attributeConstraint: draft.attributeConstraint ?? 'None',
42
- inputHint: draft.inputHint ?? 'SingleLine',
43
- isSearchable: draft.isSearchable ?? true,
44
- })
43
+ ): AttributeDefinition => {
44
+ return {
45
+ ...draft,
46
+ attributeConstraint: draft.attributeConstraint ?? 'None',
47
+ inputHint: draft.inputHint ?? 'SingleLine',
48
+ inputTip:
49
+ draft.inputTip && Object.keys(draft.inputTip).length > 0
50
+ ? draft.inputTip
51
+ : undefined,
52
+ isSearchable: draft.isSearchable ?? true,
53
+ }
54
+ }
45
55
 
46
56
  getWithKey(context: RepositoryContext, key: string): ProductType | undefined {
47
57
  const result = this._storage.query(context.projectKey, this.getTypeId(), {
@@ -109,5 +119,77 @@ export class ProductTypeRepository extends AbstractResourceRepository {
109
119
  }
110
120
  })
111
121
  },
122
+ addAttributeDefinition: (
123
+ context: RepositoryContext,
124
+ resource: Writable<ProductType>,
125
+ { attribute }: ProductTypeAddAttributeDefinitionAction
126
+ ) => {
127
+ resource.attributes?.push(
128
+ this.attributeDefinitionFromAttributeDefinitionDraft(context, attribute)
129
+ )
130
+ },
131
+ changeAttributeOrder: (
132
+ context: RepositoryContext,
133
+ resource: Writable<ProductType>,
134
+ { attributes }: ProductTypeChangeAttributeOrderAction
135
+ ) => {
136
+ const attrs = new Map(resource.attributes?.map(item => [item.name, item]))
137
+ const result: AttributeDefinition[] = []
138
+ let current = resource.attributes
139
+
140
+ attributes.forEach(iAttr => {
141
+ const attr = attrs.get(iAttr.name)
142
+ if (attr === undefined) {
143
+ throw new Error('New attr')
144
+ }
145
+ result.push(attr)
146
+
147
+ // Remove from current items
148
+ current = current?.filter(f => {
149
+ return f.name !== iAttr.name
150
+ })
151
+ })
152
+
153
+ resource.attributes = result
154
+ // Add attrs which were not specified in the order as last items. Not
155
+ // sure if this follows commercetools
156
+ if (current) {
157
+ resource.attributes.push(...current)
158
+ }
159
+ },
160
+ removeAttributeDefinition: (
161
+ context: RepositoryContext,
162
+ resource: Writable<ProductType>,
163
+ { name }: ProductTypeRemoveAttributeDefinitionAction
164
+ ) => {
165
+ resource.attributes = resource.attributes?.filter(f => {
166
+ return f.name !== name
167
+ })
168
+ },
169
+ removeEnumValues: (
170
+ context: RepositoryContext,
171
+ resource: Writable<ProductType>,
172
+ { attributeName, keys }: ProductTypeRemoveEnumValuesAction
173
+ ) => {
174
+ resource.attributes?.forEach(attr => {
175
+ if (attr.name == attributeName) {
176
+ if (attr.type.name == 'enum') {
177
+ attr.type.values = attr.type.values.filter(v => {
178
+ return !keys.includes(v.key)
179
+ })
180
+ }
181
+
182
+ if (attr.type.name == 'set') {
183
+ if (attr.type.elementType.name == 'enum') {
184
+ attr.type.elementType.values = attr.type.elementType.values.filter(
185
+ v => {
186
+ return !keys.includes(v.key)
187
+ }
188
+ )
189
+ }
190
+ }
191
+ }
192
+ })
193
+ },
112
194
  }
113
195
  }
@@ -1,17 +1,22 @@
1
1
  import {
2
2
  Price,
3
+ PriceDraft,
3
4
  Product,
4
5
  ProductData,
5
6
  ProductDraft,
6
7
  ProductPublishAction,
7
8
  ProductSetAttributeAction,
9
+ ProductType,
10
+ ProductTypeReference,
8
11
  ProductVariant,
9
12
  ProductVariantDraft,
10
13
  ReferenceTypeId,
11
14
  } from '@commercetools/platform-sdk'
15
+ import { v4 as uuidv4 } from 'uuid'
12
16
  import { getBaseResourceProperties } from '../helpers'
13
17
  import { AbstractResourceRepository, RepositoryContext } from './abstract'
14
18
  import { Writable } from '../types'
19
+ import { getReferenceFromResourceIdentifier } from './helpers'
15
20
 
16
21
  export class ProductRepository extends AbstractResourceRepository {
17
22
  getTypeId(): ReferenceTypeId {
@@ -19,17 +24,37 @@ export class ProductRepository extends AbstractResourceRepository {
19
24
  }
20
25
 
21
26
  create(context: RepositoryContext, draft: ProductDraft): Product {
22
- const productData = {
27
+ if (!draft.masterVariant) {
28
+ throw new Error('Missing master variant')
29
+ }
30
+
31
+ let productType: ProductTypeReference | undefined = undefined
32
+ try {
33
+ productType = getReferenceFromResourceIdentifier<ProductTypeReference>(
34
+ draft.productType,
35
+ context.projectKey,
36
+ this._storage
37
+ )
38
+ } catch (err) {
39
+ // For now accept missing product types (but warn)
40
+ console.warn(
41
+ `Error resolving product-type '${draft.productType.id}'. This will be throw an error in later releases.`
42
+ )
43
+ productType = {
44
+ typeId: 'product-type',
45
+ id: draft.productType.id || '',
46
+ }
47
+ }
48
+
49
+ const productData: ProductData = {
23
50
  name: draft.name,
24
51
  slug: draft.slug,
25
52
  categories: [],
26
- masterVariant:
27
- draft.masterVariant && variantFromDraft(0, draft.masterVariant!),
53
+ masterVariant: variantFromDraft(1, draft.masterVariant),
28
54
  variants:
29
- draft.variants &&
30
- draft.variants.map((variant, index) => {
31
- return variantFromDraft(index + 1, variant)
32
- }),
55
+ draft.variants?.map((variant, index) => {
56
+ return variantFromDraft(index + 2, variant)
57
+ }) ?? [],
33
58
 
34
59
  // @ts-ignore
35
60
  searchKeywords: draft.searchKeywords,
@@ -37,6 +62,7 @@ export class ProductRepository extends AbstractResourceRepository {
37
62
 
38
63
  const resource: Product = {
39
64
  ...getBaseResourceProperties(),
65
+ productType: productType,
40
66
  masterData: {
41
67
  // @ts-ignore
42
68
  current: draft.publish ? productData : undefined,
@@ -207,7 +233,21 @@ const variantFromDraft = (
207
233
  return {
208
234
  id: variantId,
209
235
  sku: variant?.sku,
210
- attributes: variant?.attributes,
211
- prices: variant?.prices as Price[],
236
+ attributes: variant?.attributes ?? [],
237
+ prices: variant?.prices?.map(priceFromDraft),
238
+ assets: [],
239
+ images: [],
240
+ }
241
+ }
242
+
243
+ const priceFromDraft = (draft: PriceDraft): Price => {
244
+ return {
245
+ id: uuidv4(),
246
+ value: {
247
+ currencyCode: draft.value.currencyCode,
248
+ centAmount: draft.value.centAmount,
249
+ fractionDigits: 2,
250
+ type: 'centPrecision',
251
+ },
212
252
  }
213
253
  }
@@ -12,6 +12,8 @@ import {
12
12
  ShippingMethodChangeNameAction,
13
13
  ShippingMethodDraft,
14
14
  ShippingMethodRemoveZoneAction,
15
+ ShippingMethodSetCustomFieldAction,
16
+ ShippingMethodSetCustomTypeAction,
15
17
  ShippingMethodSetDescriptionAction,
16
18
  ShippingMethodSetKeyAction,
17
19
  ShippingMethodSetLocalizedDescriptionAction,
@@ -196,5 +198,34 @@ export class ShippingMethodRepository extends AbstractResourceRepository {
196
198
  ) => {
197
199
  resource.name = name
198
200
  },
201
+ setCustomType: (
202
+ context: RepositoryContext,
203
+ resource: Writable<ShippingMethod>,
204
+ { type, fields }: ShippingMethodSetCustomTypeAction
205
+ ) => {
206
+ if (type) {
207
+ resource.custom = createCustomFields(
208
+ { type, fields },
209
+ context.projectKey,
210
+ this._storage
211
+ )
212
+ } else {
213
+ resource.custom = undefined
214
+ }
215
+ },
216
+ setCustomField: (
217
+ context: RepositoryContext,
218
+ resource: Writable<ShippingMethod>,
219
+ { name, value }: ShippingMethodSetCustomFieldAction
220
+ ) => {
221
+ if (!resource.custom) {
222
+ return
223
+ }
224
+ if (value === null) {
225
+ delete resource.custom.fields[name]
226
+ } else {
227
+ resource.custom.fields[name] = value
228
+ }
229
+ },
199
230
  }
200
231
  }
@@ -8,11 +8,16 @@ import {
8
8
  StoreSetDistributionChannelsAction,
9
9
  ChannelResourceIdentifier,
10
10
  StoreSetLanguagesAction,
11
+ StoreSetCustomFieldAction,
12
+ StoreSetCustomTypeAction,
11
13
  } from '@commercetools/platform-sdk'
12
14
  import { Writable } from 'types'
13
15
  import { getBaseResourceProperties } from '../helpers'
14
16
  import { AbstractResourceRepository, RepositoryContext } from './abstract'
15
- import { getReferenceFromResourceIdentifier } from './helpers'
17
+ import {
18
+ getReferenceFromResourceIdentifier,
19
+ createCustomFields,
20
+ } from './helpers'
16
21
 
17
22
  export class StoreRepository extends AbstractResourceRepository {
18
23
  getTypeId(): ReferenceTypeId {
@@ -24,12 +29,18 @@ export class StoreRepository extends AbstractResourceRepository {
24
29
  ...getBaseResourceProperties(),
25
30
  key: draft.key,
26
31
  name: draft.name,
27
- languages: draft.languages,
32
+ languages: draft.languages ?? [],
28
33
  distributionChannels: this.transformChannels(
29
34
  context,
30
35
  draft.distributionChannels
31
36
  ),
32
37
  supplyChannels: this.transformChannels(context, draft.supplyChannels),
38
+ productSelections: [],
39
+ custom: createCustomFields(
40
+ draft.custom,
41
+ context.projectKey,
42
+ this._storage
43
+ ),
33
44
  }
34
45
  this.save(context, resource)
35
46
  return resource
@@ -97,7 +108,36 @@ export class StoreRepository extends AbstractResourceRepository {
97
108
  resource: Writable<Store>,
98
109
  { languages }: StoreSetLanguagesAction
99
110
  ) => {
100
- resource.languages = languages
111
+ resource.languages = languages ?? []
112
+ },
113
+ setCustomType: (
114
+ context: RepositoryContext,
115
+ resource: Writable<Store>,
116
+ { type, fields }: StoreSetCustomTypeAction
117
+ ) => {
118
+ if (type) {
119
+ resource.custom = createCustomFields(
120
+ { type, fields },
121
+ context.projectKey,
122
+ this._storage
123
+ )
124
+ } else {
125
+ resource.custom = undefined
126
+ }
127
+ },
128
+ setCustomField: (
129
+ context: RepositoryContext,
130
+ resource: Writable<Store>,
131
+ { name, value }: StoreSetCustomFieldAction
132
+ ) => {
133
+ if (!resource.custom) {
134
+ return
135
+ }
136
+ if (value === null) {
137
+ delete resource.custom.fields[name]
138
+ } else {
139
+ resource.custom.fields[name] = value
140
+ }
101
141
  },
102
142
  }
103
143
  }
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  Type,
3
3
  TypeDraft,
4
+ InvalidOperationError,
4
5
  ReferenceTypeId,
5
6
  TypeUpdateAction,
6
7
  FieldDefinition,
@@ -12,6 +13,8 @@ import {
12
13
  TypeChangeFieldDefinitionOrderAction,
13
14
  TypeRemoveFieldDefinitionAction,
14
15
  } from '@commercetools/platform-sdk'
16
+ import { CommercetoolsError } from '../exceptions'
17
+ import { isEqual } from 'lodash'
15
18
  import { Writable } from 'types'
16
19
  import { getBaseResourceProperties } from '../helpers'
17
20
  import { AbstractResourceRepository, RepositoryContext } from './abstract'
@@ -97,6 +100,22 @@ export class TypeRepository extends AbstractResourceRepository {
97
100
  })
98
101
  })
99
102
 
103
+ if (
104
+ isEqual(
105
+ fieldNames,
106
+ resource.fieldDefinitions.map(item => item.name)
107
+ )
108
+ ) {
109
+ throw new CommercetoolsError<InvalidOperationError>({
110
+ code: 'InvalidOperation',
111
+ message: "'fieldDefinitions' has no changes.",
112
+ action: {
113
+ action: 'changeFieldDefinitionOrder',
114
+ fieldNames: fieldNames,
115
+ },
116
+ })
117
+ }
118
+
100
119
  resource.fieldDefinitions = result
101
120
  // Add fields which were not specified in the order as last items. Not
102
121
  // sure if this follows commercetools
@@ -118,7 +118,7 @@ describe('CustomObject retrieve', () => {
118
118
  })
119
119
 
120
120
  test('can use the add function with the custom object name', async () => {
121
- ctMock.project('dummy').add('custom-object', {
121
+ ctMock.project('dummy').add('key-value-document', {
122
122
  ...getBaseResourceProperties(),
123
123
  container: 'my-container',
124
124
  key: 'my-key',
@@ -143,7 +143,7 @@ describe('CustomObject retrieve', () => {
143
143
  })
144
144
 
145
145
  test('update with container and key', async () => {
146
- ctMock.project('dummy').add('custom-object', {
146
+ ctMock.project('dummy').add('key-value-document', {
147
147
  ...getBaseResourceProperties(),
148
148
  container: 'my-container',
149
149
  key: 'my-key',
@@ -0,0 +1,33 @@
1
+ import { ProductDiscountRepository } from '../repositories/product-discount'
2
+ import AbstractService from './abstract'
3
+ import { Request, Response, Router } from 'express'
4
+ import { AbstractStorage } from '../storage'
5
+ import { getRepositoryContext } from '../repositories/helpers'
6
+
7
+ export class ProductDiscountService extends AbstractService {
8
+ public repository: ProductDiscountRepository
9
+
10
+ constructor(parent: Router, storage: AbstractStorage) {
11
+ super(parent)
12
+ this.repository = new ProductDiscountRepository(storage)
13
+ }
14
+
15
+ getBasePath() {
16
+ return 'product-discounts'
17
+ }
18
+
19
+ extraRoutes(router: Router) {
20
+ router.get('/key=:key', this.getWithKey.bind(this))
21
+ }
22
+
23
+ getWithKey(request: Request, response: Response) {
24
+ const resource = this.repository.getWithKey(
25
+ getRepositoryContext(request),
26
+ request.params.key
27
+ )
28
+ if (resource) {
29
+ return response.status(200).send(resource)
30
+ }
31
+ return response.status(404).send('Not found')
32
+ }
33
+ }