@labdigital/commercetools-mock 2.7.0 → 2.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.
- package/dist/index.cjs +127 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +127 -36
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/ctMock.ts +4 -0
- package/src/priceSelector.ts +10 -5
- package/src/repositories/customer.ts +1 -0
- package/src/repositories/helpers.ts +1 -1
- package/src/repositories/order.ts +45 -3
- package/src/repositories/product-projection.ts +15 -0
- package/src/repositories/product-selection.ts +0 -1
- package/src/repositories/product.ts +37 -24
- package/src/repositories/review.ts +36 -4
- package/src/services/index.ts +2 -0
- package/src/services/product-selection.test.ts +0 -1
- package/src/services/reviews.ts +16 -0
- package/src/storage/in-memory.ts +9 -6
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@labdigital/commercetools-mock",
|
|
3
3
|
"author": "Michael van Tellingen",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.8.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@changesets/changelog-github": "^0.4.8",
|
|
48
48
|
"@changesets/cli": "^2.26.2",
|
|
49
|
-
"@commercetools/platform-sdk": "
|
|
49
|
+
"@commercetools/platform-sdk": "6.0.0",
|
|
50
50
|
"@types/basic-auth": "^1.1.3",
|
|
51
51
|
"@types/body-parser": "^1.19.2",
|
|
52
52
|
"@types/deep-equal": "^1.0.1",
|
package/src/ctMock.ts
CHANGED
package/src/priceSelector.ts
CHANGED
|
@@ -21,11 +21,13 @@ export type PriceSelector = {
|
|
|
21
21
|
*/
|
|
22
22
|
export const applyPriceSelector = (
|
|
23
23
|
products: ProductProjection[],
|
|
24
|
-
selector: PriceSelector
|
|
24
|
+
selector: PriceSelector,
|
|
25
|
+
noScopedPrice: boolean = false
|
|
25
26
|
) => {
|
|
26
27
|
validatePriceSelector(selector)
|
|
27
28
|
|
|
28
29
|
for (const product of products) {
|
|
30
|
+
// Get list of all variants (master + variants)
|
|
29
31
|
const variants: Writable<ProductVariant>[] = [
|
|
30
32
|
product.masterVariant,
|
|
31
33
|
...(product.variants ?? []),
|
|
@@ -38,10 +40,13 @@ export const applyPriceSelector = (
|
|
|
38
40
|
if (scopedPrices.length > 0) {
|
|
39
41
|
const price = scopedPrices[0]
|
|
40
42
|
|
|
41
|
-
variant.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
variant.price = scopedPrices[0]
|
|
44
|
+
if (!noScopedPrice) {
|
|
45
|
+
variant.scopedPriceDiscounted = false
|
|
46
|
+
variant.scopedPrice = {
|
|
47
|
+
...price,
|
|
48
|
+
currentValue: price.value,
|
|
49
|
+
}
|
|
45
50
|
}
|
|
46
51
|
}
|
|
47
52
|
}
|
|
@@ -51,6 +51,7 @@ export class CustomerRepository extends AbstractResourceRepository<'customer'> {
|
|
|
51
51
|
password: draft.password ? hashPassword(draft.password) : undefined,
|
|
52
52
|
isEmailVerified: draft.isEmailVerified || false,
|
|
53
53
|
addresses: [],
|
|
54
|
+
customerNumber: draft.customerNumber,
|
|
54
55
|
}
|
|
55
56
|
this.saveNew(context, resource)
|
|
56
57
|
return resource
|
|
@@ -180,7 +180,7 @@ export const getReferenceFromResourceIdentifier = <T extends Reference>(
|
|
|
180
180
|
if (!resource) {
|
|
181
181
|
const errIdentifier = resourceIdentifier.key
|
|
182
182
|
? `key '${resourceIdentifier.key}'`
|
|
183
|
-
: `identifier '${resourceIdentifier.
|
|
183
|
+
: `identifier '${resourceIdentifier.id}'`
|
|
184
184
|
|
|
185
185
|
throw new CommercetoolsError<ReferencedResourceNotFoundError>(
|
|
186
186
|
{
|
|
@@ -2,12 +2,15 @@ import type {
|
|
|
2
2
|
Cart,
|
|
3
3
|
CartReference,
|
|
4
4
|
CustomLineItem,
|
|
5
|
-
|
|
5
|
+
CustomLineItemImportDraft,
|
|
6
|
+
CustomLineItemReturnItem,
|
|
6
7
|
GeneralError,
|
|
7
8
|
LineItem,
|
|
8
9
|
LineItemImportDraft,
|
|
10
|
+
LineItemReturnItem,
|
|
9
11
|
Order,
|
|
10
12
|
OrderAddPaymentAction,
|
|
13
|
+
OrderAddReturnInfoAction,
|
|
11
14
|
OrderChangeOrderStateAction,
|
|
12
15
|
OrderChangePaymentStateAction,
|
|
13
16
|
OrderFromCartDraft,
|
|
@@ -24,6 +27,7 @@ import type {
|
|
|
24
27
|
Product,
|
|
25
28
|
ProductPagedQueryResponse,
|
|
26
29
|
ProductVariant,
|
|
30
|
+
ReturnInfo,
|
|
27
31
|
State,
|
|
28
32
|
Store,
|
|
29
33
|
} from '@commercetools/platform-sdk'
|
|
@@ -227,7 +231,7 @@ export class OrderRepository extends AbstractResourceRepository<'order'> {
|
|
|
227
231
|
|
|
228
232
|
private customLineItemFromImportDraft(
|
|
229
233
|
context: RepositoryContext,
|
|
230
|
-
draft:
|
|
234
|
+
draft: CustomLineItemImportDraft
|
|
231
235
|
): CustomLineItem {
|
|
232
236
|
const lineItem: CustomLineItem = {
|
|
233
237
|
...getBaseResourceProperties(),
|
|
@@ -241,10 +245,11 @@ export class OrderRepository extends AbstractResourceRepository<'order'> {
|
|
|
241
245
|
name: draft.name,
|
|
242
246
|
quantity: draft.quantity ?? 0,
|
|
243
247
|
perMethodTaxRate: [],
|
|
244
|
-
priceMode: draft.priceMode,
|
|
248
|
+
priceMode: draft.priceMode ?? 'Standard',
|
|
245
249
|
slug: draft.slug,
|
|
246
250
|
state: [],
|
|
247
251
|
totalPrice: createCentPrecisionMoney(draft.money),
|
|
252
|
+
taxedPricePortions: [],
|
|
248
253
|
}
|
|
249
254
|
|
|
250
255
|
return lineItem
|
|
@@ -296,6 +301,43 @@ export class OrderRepository extends AbstractResourceRepository<'order'> {
|
|
|
296
301
|
id: payment.id!,
|
|
297
302
|
})
|
|
298
303
|
},
|
|
304
|
+
addReturnInfo: (
|
|
305
|
+
context: RepositoryContext,
|
|
306
|
+
resource: Writable<Order>,
|
|
307
|
+
info: OrderAddReturnInfoAction
|
|
308
|
+
) => {
|
|
309
|
+
if (!resource.returnInfo) {
|
|
310
|
+
resource.returnInfo = []
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const resolved: ReturnInfo = {
|
|
314
|
+
items: info.items.map((item) => {
|
|
315
|
+
const common = {
|
|
316
|
+
...getBaseResourceProperties(),
|
|
317
|
+
quantity: item.quantity,
|
|
318
|
+
paymentState: 'Initial',
|
|
319
|
+
shipmentState: 'Initial',
|
|
320
|
+
comment: item.comment,
|
|
321
|
+
}
|
|
322
|
+
if (item.customLineItemId) {
|
|
323
|
+
return {
|
|
324
|
+
...common,
|
|
325
|
+
type: 'CustomLineItemReturnItem',
|
|
326
|
+
customLineItemId: item.customLineItemId,
|
|
327
|
+
} as CustomLineItemReturnItem
|
|
328
|
+
}
|
|
329
|
+
return {
|
|
330
|
+
...common,
|
|
331
|
+
type: 'LineItemReturnItem',
|
|
332
|
+
lineItemId: item.customLineItemId || item.lineItemId,
|
|
333
|
+
} as LineItemReturnItem
|
|
334
|
+
}),
|
|
335
|
+
returnTrackingId: info.returnTrackingId,
|
|
336
|
+
returnDate: info.returnDate,
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
resource.returnInfo.push(resolved)
|
|
340
|
+
},
|
|
299
341
|
changeOrderState: (
|
|
300
342
|
context: RepositoryContext,
|
|
301
343
|
resource: Writable<Order>,
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
GetParams,
|
|
14
14
|
RepositoryContext,
|
|
15
15
|
} from './abstract.js'
|
|
16
|
+
import { applyPriceSelector } from '../priceSelector.js'
|
|
16
17
|
|
|
17
18
|
export type ProductProjectionQueryParams = {
|
|
18
19
|
staged?: boolean
|
|
@@ -100,6 +101,20 @@ export class ProductProjectionRepository extends AbstractResourceRepository<'pro
|
|
|
100
101
|
}
|
|
101
102
|
}
|
|
102
103
|
|
|
104
|
+
// We do this after the filtering, since the docs mention:
|
|
105
|
+
// Only available when Price selection is used. Cannot be used in a Query
|
|
106
|
+
// Predicate.
|
|
107
|
+
applyPriceSelector(
|
|
108
|
+
resources,
|
|
109
|
+
{
|
|
110
|
+
country: params.priceCountry,
|
|
111
|
+
channel: params.priceChannel,
|
|
112
|
+
customerGroup: params.priceCustomerGroup,
|
|
113
|
+
currency: params.priceCurrency,
|
|
114
|
+
},
|
|
115
|
+
true
|
|
116
|
+
)
|
|
117
|
+
|
|
103
118
|
// Expand the resources
|
|
104
119
|
if (params.expand !== undefined) {
|
|
105
120
|
resources = resources.map((resource) =>
|
|
@@ -36,6 +36,7 @@ import type {
|
|
|
36
36
|
ProductAddToCategoryAction,
|
|
37
37
|
ProductRemoveFromCategoryAction,
|
|
38
38
|
ProductTransitionStateAction,
|
|
39
|
+
ChannelReference,
|
|
39
40
|
} from '@commercetools/platform-sdk'
|
|
40
41
|
import { v4 as uuidv4 } from 'uuid'
|
|
41
42
|
import type { Writable } from '../types.js'
|
|
@@ -126,10 +127,10 @@ export class ProductRepository extends AbstractResourceRepository<'product'> {
|
|
|
126
127
|
slug: draft.slug,
|
|
127
128
|
description: draft.description,
|
|
128
129
|
categories: categoryReferences,
|
|
129
|
-
masterVariant: variantFromDraft(1, draft.masterVariant),
|
|
130
|
+
masterVariant: this.variantFromDraft(context, 1, draft.masterVariant),
|
|
130
131
|
variants:
|
|
131
132
|
draft.variants?.map((variant, index) =>
|
|
132
|
-
variantFromDraft(index + 2, variant)
|
|
133
|
+
this.variantFromDraft(context, index + 2, variant)
|
|
133
134
|
) ?? [],
|
|
134
135
|
metaTitle: draft.metaTitle,
|
|
135
136
|
metaDescription: draft.metaDescription,
|
|
@@ -156,6 +157,38 @@ export class ProductRepository extends AbstractResourceRepository<'product'> {
|
|
|
156
157
|
return resource
|
|
157
158
|
}
|
|
158
159
|
|
|
160
|
+
private variantFromDraft(
|
|
161
|
+
context: RepositoryContext,
|
|
162
|
+
variantId: number,
|
|
163
|
+
variant: ProductVariantDraft
|
|
164
|
+
): ProductVariant {
|
|
165
|
+
return {
|
|
166
|
+
id: variantId,
|
|
167
|
+
sku: variant?.sku,
|
|
168
|
+
key: variant?.key,
|
|
169
|
+
attributes: variant?.attributes ?? [],
|
|
170
|
+
prices: variant?.prices?.map((p) => this.priceFromDraft(context, p)),
|
|
171
|
+
assets: [],
|
|
172
|
+
images: [],
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private priceFromDraft(context: RepositoryContext, draft: PriceDraft): Price {
|
|
177
|
+
return {
|
|
178
|
+
id: uuidv4(),
|
|
179
|
+
key: draft.key,
|
|
180
|
+
country: draft.country,
|
|
181
|
+
value: createTypedMoney(draft.value),
|
|
182
|
+
channel: draft.channel
|
|
183
|
+
? getReferenceFromResourceIdentifier<ChannelReference>(
|
|
184
|
+
draft.channel,
|
|
185
|
+
context.projectKey,
|
|
186
|
+
this._storage
|
|
187
|
+
)
|
|
188
|
+
: undefined,
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
159
192
|
actions: Partial<
|
|
160
193
|
Record<
|
|
161
194
|
ProductUpdateAction['action'],
|
|
@@ -528,7 +561,7 @@ export class ProductRepository extends AbstractResourceRepository<'product'> {
|
|
|
528
561
|
}
|
|
529
562
|
|
|
530
563
|
// Pre-creating the price object ensures consistency between staged and current versions
|
|
531
|
-
const priceToAdd = priceFromDraft(price)
|
|
564
|
+
const priceToAdd = this.priceFromDraft(context, price)
|
|
532
565
|
|
|
533
566
|
// If true, only the staged Attribute is set. If false, both current and
|
|
534
567
|
// staged Attribute is set. Default is true
|
|
@@ -754,7 +787,7 @@ export class ProductRepository extends AbstractResourceRepository<'product'> {
|
|
|
754
787
|
(max, element) => (element.id > max ? element.id : max),
|
|
755
788
|
0
|
|
756
789
|
)
|
|
757
|
-
const variant = variantFromDraft(maxId + 1, variantDraft)
|
|
790
|
+
const variant = this.variantFromDraft(context, maxId + 1, variantDraft)
|
|
758
791
|
dataStaged.variants.push(variant)
|
|
759
792
|
|
|
760
793
|
const onlyStaged = staged !== undefined ? staged : true
|
|
@@ -1071,23 +1104,3 @@ const getVariant = (
|
|
|
1071
1104
|
: -1,
|
|
1072
1105
|
}
|
|
1073
1106
|
}
|
|
1074
|
-
|
|
1075
|
-
const variantFromDraft = (
|
|
1076
|
-
variantId: number,
|
|
1077
|
-
variant: ProductVariantDraft
|
|
1078
|
-
): ProductVariant => ({
|
|
1079
|
-
id: variantId,
|
|
1080
|
-
sku: variant?.sku,
|
|
1081
|
-
key: variant?.key,
|
|
1082
|
-
attributes: variant?.attributes ?? [],
|
|
1083
|
-
prices: variant?.prices?.map(priceFromDraft),
|
|
1084
|
-
assets: [],
|
|
1085
|
-
images: [],
|
|
1086
|
-
})
|
|
1087
|
-
|
|
1088
|
-
const priceFromDraft = (draft: PriceDraft): Price => ({
|
|
1089
|
-
id: uuidv4(),
|
|
1090
|
-
key: draft.key,
|
|
1091
|
-
country: draft.country,
|
|
1092
|
-
value: createTypedMoney(draft.value),
|
|
1093
|
-
})
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
ChannelReference,
|
|
3
|
+
ProductReference,
|
|
4
|
+
type Review,
|
|
5
|
+
type ReviewDraft,
|
|
6
|
+
type ReviewUpdateAction,
|
|
7
|
+
type StateReference,
|
|
5
8
|
} from '@commercetools/platform-sdk'
|
|
6
9
|
import { getBaseResourceProperties } from '../helpers.js'
|
|
7
10
|
import type { Writable } from '../types.js'
|
|
8
11
|
import { AbstractResourceRepository, RepositoryContext } from './abstract.js'
|
|
12
|
+
import {
|
|
13
|
+
createCustomFields,
|
|
14
|
+
getReferenceFromResourceIdentifier,
|
|
15
|
+
} from './helpers.js'
|
|
9
16
|
|
|
10
17
|
export class ReviewRepository extends AbstractResourceRepository<'review'> {
|
|
11
18
|
getTypeId() {
|
|
@@ -13,9 +20,34 @@ export class ReviewRepository extends AbstractResourceRepository<'review'> {
|
|
|
13
20
|
}
|
|
14
21
|
|
|
15
22
|
create(context: RepositoryContext, draft: ReviewDraft): Review {
|
|
23
|
+
if (!draft.target) throw new Error('Missing target')
|
|
16
24
|
const resource: Review = {
|
|
17
25
|
...getBaseResourceProperties(),
|
|
26
|
+
|
|
27
|
+
locale: draft.locale,
|
|
28
|
+
authorName: draft.authorName,
|
|
29
|
+
title: draft.title,
|
|
30
|
+
text: draft.text,
|
|
31
|
+
rating: draft.rating,
|
|
32
|
+
uniquenessValue: draft.uniquenessValue,
|
|
33
|
+
state: draft.state
|
|
34
|
+
? getReferenceFromResourceIdentifier<StateReference>(
|
|
35
|
+
draft.state,
|
|
36
|
+
context.projectKey,
|
|
37
|
+
this._storage
|
|
38
|
+
)
|
|
39
|
+
: undefined,
|
|
40
|
+
target: draft.target
|
|
41
|
+
? getReferenceFromResourceIdentifier<
|
|
42
|
+
ProductReference | ChannelReference
|
|
43
|
+
>(draft.target, context.projectKey, this._storage)
|
|
44
|
+
: undefined,
|
|
18
45
|
includedInStatistics: false,
|
|
46
|
+
custom: createCustomFields(
|
|
47
|
+
draft.custom,
|
|
48
|
+
context.projectKey,
|
|
49
|
+
this._storage
|
|
50
|
+
),
|
|
19
51
|
}
|
|
20
52
|
this.saveNew(context, resource)
|
|
21
53
|
return resource
|
package/src/services/index.ts
CHANGED
|
@@ -23,6 +23,7 @@ import { ProductProjectionService } from './product-projection.js'
|
|
|
23
23
|
import { ProductSelectionService } from './product-selection.js'
|
|
24
24
|
import { ProductTypeService } from './product-type.js'
|
|
25
25
|
import { ProductService } from './product.js'
|
|
26
|
+
import { ReviewService } from './reviews.js'
|
|
26
27
|
import { ShippingMethodService } from './shipping-method.js'
|
|
27
28
|
import { ShoppingListService } from './shopping-list.js'
|
|
28
29
|
import { StandAlonePriceService } from './standalone-price.js'
|
|
@@ -84,6 +85,7 @@ export const createServices = (router: any, repos: any) => ({
|
|
|
84
85
|
router,
|
|
85
86
|
repos['product-selection']
|
|
86
87
|
),
|
|
88
|
+
reviews: new ReviewService(router, repos['review']),
|
|
87
89
|
'shopping-list': new ShoppingListService(router, repos['shopping-list']),
|
|
88
90
|
state: new StateService(router, repos['state']),
|
|
89
91
|
store: new StoreService(router, repos['store']),
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Router } from 'express'
|
|
2
|
+
import AbstractService from './abstract.js'
|
|
3
|
+
import { ReviewRepository } from '../repositories/review.js'
|
|
4
|
+
|
|
5
|
+
export class ReviewService extends AbstractService {
|
|
6
|
+
public repository: ReviewRepository
|
|
7
|
+
|
|
8
|
+
constructor(parent: Router, repository: ReviewRepository) {
|
|
9
|
+
super(parent)
|
|
10
|
+
this.repository = repository
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
getBasePath() {
|
|
14
|
+
return 'reviews'
|
|
15
|
+
}
|
|
16
|
+
}
|
package/src/storage/in-memory.ts
CHANGED
|
@@ -415,12 +415,15 @@ export class InMemoryStorage extends AbstractStorage {
|
|
|
415
415
|
reference.typeId !== undefined &&
|
|
416
416
|
(reference.id !== undefined || reference.key !== undefined)
|
|
417
417
|
) {
|
|
418
|
-
//
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
418
|
+
// First check if the object is already resolved. This is the case when
|
|
419
|
+
// the complete resource is pushed via the .add() method.
|
|
420
|
+
if (!reference.obj) {
|
|
421
|
+
reference.obj = this.getByResourceIdentifier(projectKey, {
|
|
422
|
+
typeId: reference.typeId,
|
|
423
|
+
id: reference.id,
|
|
424
|
+
key: reference.key,
|
|
425
|
+
} as ResourceIdentifier)
|
|
426
|
+
}
|
|
424
427
|
if (expand) {
|
|
425
428
|
this._resolveResource(projectKey, reference.obj, expand)
|
|
426
429
|
}
|