@labdigital/commercetools-mock 2.7.0 → 2.9.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 +362 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +36 -2
- package/dist/index.d.ts +36 -2
- package/dist/index.js +362 -77
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/ctMock.ts +4 -0
- package/src/lib/predicateParser.test.ts +96 -11
- package/src/lib/predicateParser.ts +43 -12
- package/src/oauth/server.ts +11 -1
- package/src/priceSelector.ts +10 -5
- package/src/repositories/abstract.ts +5 -4
- package/src/repositories/cart.ts +77 -33
- package/src/repositories/custom-object.ts +18 -0
- 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/repositories/shipping-method.ts +98 -22
- package/src/services/custom-object.ts +19 -0
- 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/services/shipping-method.test.ts +120 -21
- package/src/services/shipping-method.ts +19 -2
- package/src/shippingCalculator.test.ts +280 -0
- package/src/shippingCalculator.ts +74 -0
- package/src/storage/abstract.ts +1 -1
- package/src/storage/in-memory.ts +91 -65
- package/src/types.ts +2 -0
package/dist/index.cjs
CHANGED
|
@@ -720,7 +720,7 @@ var resolveValue = (obj, val) => {
|
|
|
720
720
|
if (Array.isArray(obj)) {
|
|
721
721
|
return Object.values(obj).filter((v) => val.value in v).map((v) => v[val.value]);
|
|
722
722
|
}
|
|
723
|
-
|
|
723
|
+
return void 0;
|
|
724
724
|
}
|
|
725
725
|
return obj[val.value];
|
|
726
726
|
};
|
|
@@ -800,22 +800,43 @@ var generateMatchFunc = (predicate) => {
|
|
|
800
800
|
const expr = parser.parse();
|
|
801
801
|
lexer.expect(")");
|
|
802
802
|
return (obj, vars) => {
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
803
|
+
if (Array.isArray(obj)) {
|
|
804
|
+
return obj.some((item) => {
|
|
805
|
+
const value = resolveValue(item, left);
|
|
806
|
+
if (value) {
|
|
807
|
+
return expr(value, vars);
|
|
808
|
+
}
|
|
809
|
+
return false;
|
|
810
|
+
});
|
|
811
|
+
} else {
|
|
812
|
+
const value = resolveValue(obj, left);
|
|
813
|
+
if (value) {
|
|
814
|
+
return expr(value, vars);
|
|
815
|
+
}
|
|
816
|
+
return false;
|
|
806
817
|
}
|
|
807
|
-
return false;
|
|
808
818
|
};
|
|
809
819
|
}).bp(")", 0).led("=", 20, ({ left, bp }) => {
|
|
810
820
|
const expr = parser.parse({ terminals: [bp - 1] });
|
|
811
821
|
validateSymbol(expr);
|
|
812
822
|
return (obj, vars) => {
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
823
|
+
if (Array.isArray(obj)) {
|
|
824
|
+
return obj.some((item) => {
|
|
825
|
+
const value = resolveValue(item, left);
|
|
826
|
+
const other = resolveSymbol(expr, vars);
|
|
827
|
+
if (Array.isArray(value)) {
|
|
828
|
+
return !!value.some((elem) => elem === other);
|
|
829
|
+
}
|
|
830
|
+
return value === other;
|
|
831
|
+
});
|
|
832
|
+
} else {
|
|
833
|
+
const resolvedValue = resolveValue(obj, left);
|
|
834
|
+
const resolvedSymbol = resolveSymbol(expr, vars);
|
|
835
|
+
if (Array.isArray(resolvedValue)) {
|
|
836
|
+
return !!resolvedValue.some((elem) => elem === resolvedSymbol);
|
|
837
|
+
}
|
|
838
|
+
return resolvedValue === resolvedSymbol;
|
|
817
839
|
}
|
|
818
|
-
return resolvedValue === resolvedSymbol;
|
|
819
840
|
};
|
|
820
841
|
}).led("!=", 20, ({ left, bp }) => {
|
|
821
842
|
const expr = parser.parse({ terminals: [bp - 1] });
|
|
@@ -883,10 +904,11 @@ var generateMatchFunc = (predicate) => {
|
|
|
883
904
|
if (!Array.isArray(symbols)) {
|
|
884
905
|
symbols = [expr];
|
|
885
906
|
}
|
|
886
|
-
const inValues = symbols.
|
|
907
|
+
const inValues = symbols.flatMap(
|
|
887
908
|
(item) => resolveSymbol(item, vars)
|
|
888
909
|
);
|
|
889
|
-
|
|
910
|
+
const value = resolveValue(obj, left);
|
|
911
|
+
return inValues.includes(value);
|
|
890
912
|
};
|
|
891
913
|
}).led("MATCHES_IGNORE_CASE", 20, ({ left, bp }) => {
|
|
892
914
|
const expr = parser.parse({ terminals: [bp - 1] });
|
|
@@ -1064,9 +1086,12 @@ var InMemoryStorage = class extends AbstractStorage {
|
|
|
1064
1086
|
}
|
|
1065
1087
|
let resources = this.all(projectKey, typeId);
|
|
1066
1088
|
if (params.where) {
|
|
1089
|
+
const vars = Object.fromEntries(
|
|
1090
|
+
Object.entries(params).filter(([key]) => key.startsWith("var.")).map(([key, value]) => [key.slice(4), value])
|
|
1091
|
+
);
|
|
1067
1092
|
try {
|
|
1068
1093
|
const filterFunc = parseQueryExpression(params.where);
|
|
1069
|
-
resources = resources.filter((resource) => filterFunc(resource,
|
|
1094
|
+
resources = resources.filter((resource) => filterFunc(resource, vars));
|
|
1070
1095
|
} catch (err) {
|
|
1071
1096
|
throw new CommercetoolsError(
|
|
1072
1097
|
{
|
|
@@ -1133,28 +1158,34 @@ var InMemoryStorage = class extends AbstractStorage {
|
|
|
1133
1158
|
if (resource) {
|
|
1134
1159
|
return resource;
|
|
1135
1160
|
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1161
|
+
throw new CommercetoolsError({
|
|
1162
|
+
code: "ReferencedResourceNotFound",
|
|
1163
|
+
message: `The referenced object of type '${identifier.typeId}' with id '${identifier.id}' was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).`,
|
|
1164
|
+
typeId: identifier.typeId,
|
|
1165
|
+
id: identifier.id
|
|
1166
|
+
});
|
|
1140
1167
|
}
|
|
1141
1168
|
if (identifier.key) {
|
|
1142
|
-
const
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
return resource;
|
|
1150
|
-
}
|
|
1151
|
-
} else {
|
|
1152
|
-
throw new Error(
|
|
1153
|
-
`No storage found for resource type: ${identifier.typeId}`
|
|
1154
|
-
);
|
|
1169
|
+
const resource = this.getByKey(
|
|
1170
|
+
projectKey,
|
|
1171
|
+
identifier.typeId,
|
|
1172
|
+
identifier.key
|
|
1173
|
+
);
|
|
1174
|
+
if (resource) {
|
|
1175
|
+
return resource;
|
|
1155
1176
|
}
|
|
1177
|
+
throw new CommercetoolsError({
|
|
1178
|
+
code: "ReferencedResourceNotFound",
|
|
1179
|
+
message: `The referenced object of type '${identifier.typeId}' with key '${identifier.key}' was not found. It either doesn't exist, or it can't be accessed from this endpoint (e.g., if the endpoint filters by store or customer account).`,
|
|
1180
|
+
typeId: identifier.typeId,
|
|
1181
|
+
key: identifier.key
|
|
1182
|
+
});
|
|
1156
1183
|
}
|
|
1157
|
-
|
|
1184
|
+
throw new CommercetoolsError({
|
|
1185
|
+
code: "InvalidJsonInput",
|
|
1186
|
+
message: "Request body does not contain valid JSON.",
|
|
1187
|
+
detailedErrorMessage: "ResourceIdentifier requires an 'id' xor a 'key'"
|
|
1188
|
+
});
|
|
1158
1189
|
}
|
|
1159
1190
|
addProject = (projectKey) => {
|
|
1160
1191
|
if (!this.projects[projectKey]) {
|
|
@@ -1231,11 +1262,13 @@ var InMemoryStorage = class extends AbstractStorage {
|
|
|
1231
1262
|
if (reference === void 0)
|
|
1232
1263
|
return;
|
|
1233
1264
|
if (reference.typeId !== void 0 && (reference.id !== void 0 || reference.key !== void 0)) {
|
|
1234
|
-
reference.obj
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1265
|
+
if (!reference.obj) {
|
|
1266
|
+
reference.obj = this.getByResourceIdentifier(projectKey, {
|
|
1267
|
+
typeId: reference.typeId,
|
|
1268
|
+
id: reference.id,
|
|
1269
|
+
key: reference.key
|
|
1270
|
+
});
|
|
1271
|
+
}
|
|
1239
1272
|
if (expand) {
|
|
1240
1273
|
this._resolveResource(projectKey, reference.obj, expand);
|
|
1241
1274
|
}
|
|
@@ -1306,11 +1339,12 @@ var hashPassword = (clearPassword) => Buffer.from(clearPassword).toString("base6
|
|
|
1306
1339
|
|
|
1307
1340
|
// src/oauth/server.ts
|
|
1308
1341
|
var OAuth2Server = class {
|
|
1309
|
-
store;
|
|
1310
|
-
customerRepository;
|
|
1311
1342
|
constructor(options) {
|
|
1343
|
+
this.options = options;
|
|
1312
1344
|
this.store = new OAuth2Store(options.validate);
|
|
1313
1345
|
}
|
|
1346
|
+
store;
|
|
1347
|
+
customerRepository;
|
|
1314
1348
|
setCustomerRepository(repository) {
|
|
1315
1349
|
this.customerRepository = repository;
|
|
1316
1350
|
}
|
|
@@ -1334,6 +1368,11 @@ var OAuth2Server = class {
|
|
|
1334
1368
|
return router;
|
|
1335
1369
|
}
|
|
1336
1370
|
createMiddleware() {
|
|
1371
|
+
if (!this.options.validate) {
|
|
1372
|
+
return async (request, response, next) => {
|
|
1373
|
+
next();
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1337
1376
|
return async (request, response, next) => {
|
|
1338
1377
|
const token = getBearerToken(request);
|
|
1339
1378
|
if (!token) {
|
|
@@ -1670,7 +1709,7 @@ var getReferenceFromResourceIdentifier = (resourceIdentifier, projectKey, storag
|
|
|
1670
1709
|
resourceIdentifier
|
|
1671
1710
|
);
|
|
1672
1711
|
if (!resource) {
|
|
1673
|
-
const errIdentifier = resourceIdentifier.key ? `key '${resourceIdentifier.key}'` : `identifier '${resourceIdentifier.
|
|
1712
|
+
const errIdentifier = resourceIdentifier.key ? `key '${resourceIdentifier.key}'` : `identifier '${resourceIdentifier.id}'`;
|
|
1674
1713
|
throw new CommercetoolsError(
|
|
1675
1714
|
{
|
|
1676
1715
|
code: "ReferencedResourceNotFound",
|
|
@@ -1871,10 +1910,7 @@ var AbstractResourceRepository = class extends AbstractRepository {
|
|
|
1871
1910
|
}
|
|
1872
1911
|
query(context, params = {}) {
|
|
1873
1912
|
const result = this._storage.query(context.projectKey, this.getTypeId(), {
|
|
1874
|
-
|
|
1875
|
-
where: params.where,
|
|
1876
|
-
offset: params.offset,
|
|
1877
|
-
limit: params.limit
|
|
1913
|
+
...params
|
|
1878
1914
|
});
|
|
1879
1915
|
result.results = result.results.map(this.postProcessResource);
|
|
1880
1916
|
return result;
|
|
@@ -2194,6 +2230,11 @@ var CartRepository = class extends AbstractResourceRepository {
|
|
|
2194
2230
|
fractionDigits: 0
|
|
2195
2231
|
},
|
|
2196
2232
|
shippingMode: "Single",
|
|
2233
|
+
shippingAddress: createAddress(
|
|
2234
|
+
draft.shippingAddress,
|
|
2235
|
+
context.projectKey,
|
|
2236
|
+
this._storage
|
|
2237
|
+
),
|
|
2197
2238
|
shipping: [],
|
|
2198
2239
|
origin: draft.origin ?? "Customer",
|
|
2199
2240
|
refusedGifts: [],
|
|
@@ -2395,9 +2436,6 @@ var CartRepository = class extends AbstractResourceRepository {
|
|
|
2395
2436
|
context.projectKey,
|
|
2396
2437
|
shippingMethod
|
|
2397
2438
|
);
|
|
2398
|
-
if (!method) {
|
|
2399
|
-
throw new Error(`Type ${shippingMethod} not found`);
|
|
2400
|
-
}
|
|
2401
2439
|
resource.shippingInfo = {
|
|
2402
2440
|
shippingMethod: {
|
|
2403
2441
|
typeId: "shipping-method",
|
|
@@ -2421,6 +2459,33 @@ var CartRepository = class extends AbstractResourceRepository {
|
|
|
2421
2459
|
}
|
|
2422
2460
|
resource.custom.fields[name] = value;
|
|
2423
2461
|
},
|
|
2462
|
+
setCustomShippingMethod: (context, resource, {
|
|
2463
|
+
shippingMethodName,
|
|
2464
|
+
shippingRate,
|
|
2465
|
+
taxCategory,
|
|
2466
|
+
externalTaxRate
|
|
2467
|
+
}) => {
|
|
2468
|
+
if (externalTaxRate) {
|
|
2469
|
+
throw new Error("External tax rate is not supported");
|
|
2470
|
+
}
|
|
2471
|
+
const tax = taxCategory ? this._storage.getByResourceIdentifier(
|
|
2472
|
+
context.projectKey,
|
|
2473
|
+
taxCategory
|
|
2474
|
+
) : void 0;
|
|
2475
|
+
resource.shippingInfo = {
|
|
2476
|
+
shippingMethodName,
|
|
2477
|
+
price: createCentPrecisionMoney(shippingRate.price),
|
|
2478
|
+
shippingRate: {
|
|
2479
|
+
price: createTypedMoney(shippingRate.price),
|
|
2480
|
+
tiers: []
|
|
2481
|
+
},
|
|
2482
|
+
taxCategory: tax ? {
|
|
2483
|
+
typeId: "tax-category",
|
|
2484
|
+
id: tax?.id
|
|
2485
|
+
} : void 0,
|
|
2486
|
+
shippingMethodState: "MatchesCart"
|
|
2487
|
+
};
|
|
2488
|
+
},
|
|
2424
2489
|
setCustomType: (context, resource, { type, fields }) => {
|
|
2425
2490
|
if (!type) {
|
|
2426
2491
|
resource.custom = void 0;
|
|
@@ -2972,6 +3037,16 @@ var CustomObjectRepository = class extends AbstractResourceRepository {
|
|
|
2972
3037
|
return resource;
|
|
2973
3038
|
}
|
|
2974
3039
|
}
|
|
3040
|
+
queryWithContainer(context, container, params = {}) {
|
|
3041
|
+
const whereClause = params.where || [];
|
|
3042
|
+
whereClause.push(`container="${container}"`);
|
|
3043
|
+
const result = this._storage.query(context.projectKey, this.getTypeId(), {
|
|
3044
|
+
...params,
|
|
3045
|
+
where: whereClause
|
|
3046
|
+
});
|
|
3047
|
+
result.results = result.results.map(this.postProcessResource);
|
|
3048
|
+
return result;
|
|
3049
|
+
}
|
|
2975
3050
|
getWithContainerAndKey(context, container, key) {
|
|
2976
3051
|
const items = this._storage.all(context.projectKey, this.getTypeId());
|
|
2977
3052
|
return items.find(
|
|
@@ -3010,7 +3085,8 @@ var CustomerRepository = class extends AbstractResourceRepository {
|
|
|
3010
3085
|
email: draft.email.toLowerCase(),
|
|
3011
3086
|
password: draft.password ? hashPassword(draft.password) : void 0,
|
|
3012
3087
|
isEmailVerified: draft.isEmailVerified || false,
|
|
3013
|
-
addresses: []
|
|
3088
|
+
addresses: [],
|
|
3089
|
+
customerNumber: draft.customerNumber
|
|
3014
3090
|
};
|
|
3015
3091
|
this.saveNew(context, resource);
|
|
3016
3092
|
return resource;
|
|
@@ -3516,10 +3592,11 @@ var OrderRepository = class extends AbstractResourceRepository {
|
|
|
3516
3592
|
name: draft.name,
|
|
3517
3593
|
quantity: draft.quantity ?? 0,
|
|
3518
3594
|
perMethodTaxRate: [],
|
|
3519
|
-
priceMode: draft.priceMode,
|
|
3595
|
+
priceMode: draft.priceMode ?? "Standard",
|
|
3520
3596
|
slug: draft.slug,
|
|
3521
3597
|
state: [],
|
|
3522
|
-
totalPrice: createCentPrecisionMoney(draft.money)
|
|
3598
|
+
totalPrice: createCentPrecisionMoney(draft.money),
|
|
3599
|
+
taxedPricePortions: []
|
|
3523
3600
|
};
|
|
3524
3601
|
return lineItem;
|
|
3525
3602
|
}
|
|
@@ -3555,6 +3632,37 @@ var OrderRepository = class extends AbstractResourceRepository {
|
|
|
3555
3632
|
id: payment.id
|
|
3556
3633
|
});
|
|
3557
3634
|
},
|
|
3635
|
+
addReturnInfo: (context, resource, info) => {
|
|
3636
|
+
if (!resource.returnInfo) {
|
|
3637
|
+
resource.returnInfo = [];
|
|
3638
|
+
}
|
|
3639
|
+
const resolved = {
|
|
3640
|
+
items: info.items.map((item) => {
|
|
3641
|
+
const common = {
|
|
3642
|
+
...getBaseResourceProperties(),
|
|
3643
|
+
quantity: item.quantity,
|
|
3644
|
+
paymentState: "Initial",
|
|
3645
|
+
shipmentState: "Initial",
|
|
3646
|
+
comment: item.comment
|
|
3647
|
+
};
|
|
3648
|
+
if (item.customLineItemId) {
|
|
3649
|
+
return {
|
|
3650
|
+
...common,
|
|
3651
|
+
type: "CustomLineItemReturnItem",
|
|
3652
|
+
customLineItemId: item.customLineItemId
|
|
3653
|
+
};
|
|
3654
|
+
}
|
|
3655
|
+
return {
|
|
3656
|
+
...common,
|
|
3657
|
+
type: "LineItemReturnItem",
|
|
3658
|
+
lineItemId: item.customLineItemId || item.lineItemId
|
|
3659
|
+
};
|
|
3660
|
+
}),
|
|
3661
|
+
returnTrackingId: info.returnTrackingId,
|
|
3662
|
+
returnDate: info.returnDate
|
|
3663
|
+
};
|
|
3664
|
+
resource.returnInfo.push(resolved);
|
|
3665
|
+
},
|
|
3558
3666
|
changeOrderState: (context, resource, { orderState }) => {
|
|
3559
3667
|
resource.orderState = orderState;
|
|
3560
3668
|
},
|
|
@@ -3865,9 +3973,9 @@ var ProductRepository = class extends AbstractResourceRepository {
|
|
|
3865
3973
|
slug: draft.slug,
|
|
3866
3974
|
description: draft.description,
|
|
3867
3975
|
categories: categoryReferences,
|
|
3868
|
-
masterVariant: variantFromDraft(1, draft.masterVariant),
|
|
3976
|
+
masterVariant: this.variantFromDraft(context, 1, draft.masterVariant),
|
|
3869
3977
|
variants: draft.variants?.map(
|
|
3870
|
-
(variant, index) => variantFromDraft(index + 2, variant)
|
|
3978
|
+
(variant, index) => this.variantFromDraft(context, index + 2, variant)
|
|
3871
3979
|
) ?? [],
|
|
3872
3980
|
metaTitle: draft.metaTitle,
|
|
3873
3981
|
metaDescription: draft.metaDescription,
|
|
@@ -3890,6 +3998,30 @@ var ProductRepository = class extends AbstractResourceRepository {
|
|
|
3890
3998
|
this.saveNew(context, resource);
|
|
3891
3999
|
return resource;
|
|
3892
4000
|
}
|
|
4001
|
+
variantFromDraft(context, variantId, variant) {
|
|
4002
|
+
return {
|
|
4003
|
+
id: variantId,
|
|
4004
|
+
sku: variant?.sku,
|
|
4005
|
+
key: variant?.key,
|
|
4006
|
+
attributes: variant?.attributes ?? [],
|
|
4007
|
+
prices: variant?.prices?.map((p) => this.priceFromDraft(context, p)),
|
|
4008
|
+
assets: [],
|
|
4009
|
+
images: []
|
|
4010
|
+
};
|
|
4011
|
+
}
|
|
4012
|
+
priceFromDraft(context, draft) {
|
|
4013
|
+
return {
|
|
4014
|
+
id: (0, import_uuid6.v4)(),
|
|
4015
|
+
key: draft.key,
|
|
4016
|
+
country: draft.country,
|
|
4017
|
+
value: createTypedMoney(draft.value),
|
|
4018
|
+
channel: draft.channel ? getReferenceFromResourceIdentifier(
|
|
4019
|
+
draft.channel,
|
|
4020
|
+
context.projectKey,
|
|
4021
|
+
this._storage
|
|
4022
|
+
) : void 0
|
|
4023
|
+
};
|
|
4024
|
+
}
|
|
3893
4025
|
actions = {
|
|
3894
4026
|
publish: (context, resource, { scope }) => {
|
|
3895
4027
|
resource.masterData.current = resource.masterData.staged;
|
|
@@ -4134,7 +4266,7 @@ var ProductRepository = class extends AbstractResourceRepository {
|
|
|
4134
4266
|
data.variants[variantIndex] = variant;
|
|
4135
4267
|
}
|
|
4136
4268
|
};
|
|
4137
|
-
const priceToAdd = priceFromDraft(price);
|
|
4269
|
+
const priceToAdd = this.priceFromDraft(context, price);
|
|
4138
4270
|
const onlyStaged = staged !== void 0 ? staged : true;
|
|
4139
4271
|
addVariantPrice(resource.masterData.staged, priceToAdd);
|
|
4140
4272
|
if (!onlyStaged) {
|
|
@@ -4291,7 +4423,7 @@ var ProductRepository = class extends AbstractResourceRepository {
|
|
|
4291
4423
|
(max, element) => element.id > max ? element.id : max,
|
|
4292
4424
|
0
|
|
4293
4425
|
);
|
|
4294
|
-
const variant = variantFromDraft(maxId + 1, variantDraft);
|
|
4426
|
+
const variant = this.variantFromDraft(context, maxId + 1, variantDraft);
|
|
4295
4427
|
dataStaged.variants.push(variant);
|
|
4296
4428
|
const onlyStaged = staged !== void 0 ? staged : true;
|
|
4297
4429
|
if (!onlyStaged) {
|
|
@@ -4529,21 +4661,6 @@ var getVariant = (productData, variantId, sku) => {
|
|
|
4529
4661
|
variantIndex: !isMasterVariant && foundVariant ? productData.variants.indexOf(foundVariant) : -1
|
|
4530
4662
|
};
|
|
4531
4663
|
};
|
|
4532
|
-
var variantFromDraft = (variantId, variant) => ({
|
|
4533
|
-
id: variantId,
|
|
4534
|
-
sku: variant?.sku,
|
|
4535
|
-
key: variant?.key,
|
|
4536
|
-
attributes: variant?.attributes ?? [],
|
|
4537
|
-
prices: variant?.prices?.map(priceFromDraft),
|
|
4538
|
-
assets: [],
|
|
4539
|
-
images: []
|
|
4540
|
-
});
|
|
4541
|
-
var priceFromDraft = (draft) => ({
|
|
4542
|
-
id: (0, import_uuid6.v4)(),
|
|
4543
|
-
key: draft.key,
|
|
4544
|
-
country: draft.country,
|
|
4545
|
-
value: createTypedMoney(draft.value)
|
|
4546
|
-
});
|
|
4547
4664
|
|
|
4548
4665
|
// src/repositories/product-discount.ts
|
|
4549
4666
|
var ProductDiscountRepository = class extends AbstractResourceRepository {
|
|
@@ -4815,7 +4932,7 @@ var getVariants = (p) => [
|
|
|
4815
4932
|
];
|
|
4816
4933
|
|
|
4817
4934
|
// src/priceSelector.ts
|
|
4818
|
-
var applyPriceSelector = (products, selector) => {
|
|
4935
|
+
var applyPriceSelector = (products, selector, noScopedPrice = false) => {
|
|
4819
4936
|
validatePriceSelector(selector);
|
|
4820
4937
|
for (const product of products) {
|
|
4821
4938
|
const variants = [
|
|
@@ -4826,11 +4943,14 @@ var applyPriceSelector = (products, selector) => {
|
|
|
4826
4943
|
const scopedPrices = variant.prices?.filter((p) => priceSelectorFilter(p, selector)) ?? [];
|
|
4827
4944
|
if (scopedPrices.length > 0) {
|
|
4828
4945
|
const price = scopedPrices[0];
|
|
4829
|
-
variant.
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4946
|
+
variant.price = scopedPrices[0];
|
|
4947
|
+
if (!noScopedPrice) {
|
|
4948
|
+
variant.scopedPriceDiscounted = false;
|
|
4949
|
+
variant.scopedPrice = {
|
|
4950
|
+
...price,
|
|
4951
|
+
currentValue: price.value
|
|
4952
|
+
};
|
|
4953
|
+
}
|
|
4834
4954
|
}
|
|
4835
4955
|
}
|
|
4836
4956
|
}
|
|
@@ -5165,6 +5285,16 @@ var ProductProjectionRepository = class extends AbstractResourceRepository {
|
|
|
5165
5285
|
);
|
|
5166
5286
|
}
|
|
5167
5287
|
}
|
|
5288
|
+
applyPriceSelector(
|
|
5289
|
+
resources,
|
|
5290
|
+
{
|
|
5291
|
+
country: params.priceCountry,
|
|
5292
|
+
channel: params.priceChannel,
|
|
5293
|
+
customerGroup: params.priceCustomerGroup,
|
|
5294
|
+
currency: params.priceCurrency
|
|
5295
|
+
},
|
|
5296
|
+
true
|
|
5297
|
+
);
|
|
5168
5298
|
if (params.expand !== void 0) {
|
|
5169
5299
|
resources = resources.map(
|
|
5170
5300
|
(resource) => this._storage.expand(context.projectKey, resource, params.expand)
|
|
@@ -5199,7 +5329,6 @@ var ProductSelectionRepository = class extends AbstractResourceRepository {
|
|
|
5199
5329
|
productCount: 0,
|
|
5200
5330
|
key: draft.key,
|
|
5201
5331
|
name: draft.name,
|
|
5202
|
-
type: "individual",
|
|
5203
5332
|
mode: "Individual"
|
|
5204
5333
|
};
|
|
5205
5334
|
this.saveNew(context, resource);
|
|
@@ -5415,9 +5544,28 @@ var ReviewRepository = class extends AbstractResourceRepository {
|
|
|
5415
5544
|
return "review";
|
|
5416
5545
|
}
|
|
5417
5546
|
create(context, draft) {
|
|
5547
|
+
if (!draft.target)
|
|
5548
|
+
throw new Error("Missing target");
|
|
5418
5549
|
const resource = {
|
|
5419
5550
|
...getBaseResourceProperties(),
|
|
5420
|
-
|
|
5551
|
+
locale: draft.locale,
|
|
5552
|
+
authorName: draft.authorName,
|
|
5553
|
+
title: draft.title,
|
|
5554
|
+
text: draft.text,
|
|
5555
|
+
rating: draft.rating,
|
|
5556
|
+
uniquenessValue: draft.uniquenessValue,
|
|
5557
|
+
state: draft.state ? getReferenceFromResourceIdentifier(
|
|
5558
|
+
draft.state,
|
|
5559
|
+
context.projectKey,
|
|
5560
|
+
this._storage
|
|
5561
|
+
) : void 0,
|
|
5562
|
+
target: draft.target ? getReferenceFromResourceIdentifier(draft.target, context.projectKey, this._storage) : void 0,
|
|
5563
|
+
includedInStatistics: false,
|
|
5564
|
+
custom: createCustomFields(
|
|
5565
|
+
draft.custom,
|
|
5566
|
+
context.projectKey,
|
|
5567
|
+
this._storage
|
|
5568
|
+
)
|
|
5421
5569
|
};
|
|
5422
5570
|
this.saveNew(context, resource);
|
|
5423
5571
|
return resource;
|
|
@@ -5427,6 +5575,50 @@ var ReviewRepository = class extends AbstractResourceRepository {
|
|
|
5427
5575
|
|
|
5428
5576
|
// src/repositories/shipping-method.ts
|
|
5429
5577
|
var import_deep_equal3 = __toESM(require("deep-equal"), 1);
|
|
5578
|
+
|
|
5579
|
+
// src/shippingCalculator.ts
|
|
5580
|
+
var markMatchingShippingRate = (cart, shippingRate) => {
|
|
5581
|
+
const isMatching = shippingRate.price.currencyCode === cart.totalPrice.currencyCode;
|
|
5582
|
+
return {
|
|
5583
|
+
...shippingRate,
|
|
5584
|
+
tiers: markMatchingShippingRatePriceTiers(cart, shippingRate.tiers),
|
|
5585
|
+
isMatching
|
|
5586
|
+
};
|
|
5587
|
+
};
|
|
5588
|
+
var markMatchingShippingRatePriceTiers = (cart, tiers) => {
|
|
5589
|
+
if (tiers.length === 0) {
|
|
5590
|
+
return [];
|
|
5591
|
+
}
|
|
5592
|
+
if (new Set(tiers.map((tier) => tier.type)).size > 1) {
|
|
5593
|
+
throw new Error("Can't handle multiple types of tiers");
|
|
5594
|
+
}
|
|
5595
|
+
const tierType = tiers[0].type;
|
|
5596
|
+
switch (tierType) {
|
|
5597
|
+
case "CartValue":
|
|
5598
|
+
return markMatchingCartValueTiers(cart, tiers);
|
|
5599
|
+
default:
|
|
5600
|
+
throw new Error(`Unsupported tier type: ${tierType}`);
|
|
5601
|
+
}
|
|
5602
|
+
};
|
|
5603
|
+
var markMatchingCartValueTiers = (cart, tiers) => {
|
|
5604
|
+
const sortedTiers = [...tiers].sort(
|
|
5605
|
+
(a, b) => b.minimumCentAmount - a.minimumCentAmount
|
|
5606
|
+
);
|
|
5607
|
+
const result = {};
|
|
5608
|
+
let hasMatchingTier = false;
|
|
5609
|
+
for (const tier of sortedTiers) {
|
|
5610
|
+
const isMatching = !hasMatchingTier && cart.totalPrice.currencyCode === tier.price.currencyCode && cart.totalPrice.centAmount >= tier.minimumCentAmount;
|
|
5611
|
+
if (isMatching)
|
|
5612
|
+
hasMatchingTier = true;
|
|
5613
|
+
result[tier.minimumCentAmount] = {
|
|
5614
|
+
...tier,
|
|
5615
|
+
isMatching
|
|
5616
|
+
};
|
|
5617
|
+
}
|
|
5618
|
+
return tiers.map((tier) => result[tier.minimumCentAmount]);
|
|
5619
|
+
};
|
|
5620
|
+
|
|
5621
|
+
// src/repositories/shipping-method.ts
|
|
5430
5622
|
var ShippingMethodRepository = class extends AbstractResourceRepository {
|
|
5431
5623
|
getTypeId() {
|
|
5432
5624
|
return "shipping-method";
|
|
@@ -5466,6 +5658,53 @@ var ShippingMethodRepository = class extends AbstractResourceRepository {
|
|
|
5466
5658
|
freeAbove: rate.freeAbove && createTypedMoney(rate.freeAbove),
|
|
5467
5659
|
tiers: rate.tiers || []
|
|
5468
5660
|
});
|
|
5661
|
+
/*
|
|
5662
|
+
* Retrieves all the ShippingMethods that can ship to the shipping address of
|
|
5663
|
+
* the given Cart. Each ShippingMethod contains exactly one ShippingRate with
|
|
5664
|
+
* the flag isMatching set to true. This ShippingRate is used when the
|
|
5665
|
+
* ShippingMethod is added to the Cart.
|
|
5666
|
+
*/
|
|
5667
|
+
matchingCart(context, cartId, params = {}) {
|
|
5668
|
+
const cart = this._storage.get(context.projectKey, "cart", cartId);
|
|
5669
|
+
if (!cart) {
|
|
5670
|
+
return void 0;
|
|
5671
|
+
}
|
|
5672
|
+
if (!cart.shippingAddress?.country) {
|
|
5673
|
+
throw new CommercetoolsError({
|
|
5674
|
+
code: "InvalidOperation",
|
|
5675
|
+
message: `The cart with ID '${cart.id}' does not have a shipping address set.`
|
|
5676
|
+
});
|
|
5677
|
+
}
|
|
5678
|
+
const zones = this._storage.query(context.projectKey, "zone", {
|
|
5679
|
+
where: [`locations(country="${cart.shippingAddress.country}"))`],
|
|
5680
|
+
limit: 100
|
|
5681
|
+
});
|
|
5682
|
+
const zoneIds = zones.results.map((zone) => zone.id);
|
|
5683
|
+
const shippingMethods = this.query(context, {
|
|
5684
|
+
where: [
|
|
5685
|
+
`zoneRates(zone(id in (:zoneIds)))`,
|
|
5686
|
+
`zoneRates(shippingRates(price(currencyCode="${cart.totalPrice.currencyCode}")))`
|
|
5687
|
+
],
|
|
5688
|
+
"var.zoneIds": zoneIds,
|
|
5689
|
+
expand: params.expand
|
|
5690
|
+
});
|
|
5691
|
+
const results = shippingMethods.results.map((shippingMethod) => {
|
|
5692
|
+
const rates = shippingMethod.zoneRates.map((zoneRate) => ({
|
|
5693
|
+
zone: zoneRate.zone,
|
|
5694
|
+
// Iterate through the shippingRates and mark the matching ones
|
|
5695
|
+
// then we filter out the non-matching ones
|
|
5696
|
+
shippingRates: zoneRate.shippingRates.map((rate) => markMatchingShippingRate(cart, rate)).filter((rate) => rate.isMatching)
|
|
5697
|
+
})).filter((zoneRate) => zoneRate.shippingRates.length > 0);
|
|
5698
|
+
return {
|
|
5699
|
+
...shippingMethod,
|
|
5700
|
+
zoneRates: rates
|
|
5701
|
+
};
|
|
5702
|
+
}).filter((shippingMethod) => shippingMethod.zoneRates.length > 0);
|
|
5703
|
+
return {
|
|
5704
|
+
...shippingMethods,
|
|
5705
|
+
results
|
|
5706
|
+
};
|
|
5707
|
+
}
|
|
5469
5708
|
actions = {
|
|
5470
5709
|
addShippingRate: (_context, resource, { shippingRate, zone }) => {
|
|
5471
5710
|
const rate = this._transformShippingRate(shippingRate);
|
|
@@ -6319,10 +6558,26 @@ var CustomObjectService = class extends AbstractService {
|
|
|
6319
6558
|
return "custom-objects";
|
|
6320
6559
|
}
|
|
6321
6560
|
extraRoutes(router) {
|
|
6561
|
+
router.get("/:container", this.getWithContainer.bind(this));
|
|
6322
6562
|
router.get("/:container/:key", this.getWithContainerAndKey.bind(this));
|
|
6323
6563
|
router.post("/:container/:key", this.createWithContainerAndKey.bind(this));
|
|
6324
6564
|
router.delete("/:container/:key", this.deleteWithContainerAndKey.bind(this));
|
|
6325
6565
|
}
|
|
6566
|
+
getWithContainer(request, response) {
|
|
6567
|
+
const limit = this._parseParam(request.query.limit);
|
|
6568
|
+
const offset = this._parseParam(request.query.offset);
|
|
6569
|
+
const result = this.repository.queryWithContainer(
|
|
6570
|
+
getRepositoryContext(request),
|
|
6571
|
+
request.params.container,
|
|
6572
|
+
{
|
|
6573
|
+
expand: this._parseParam(request.query.expand),
|
|
6574
|
+
where: this._parseParam(request.query.where),
|
|
6575
|
+
limit: limit !== void 0 ? Number(limit) : void 0,
|
|
6576
|
+
offset: offset !== void 0 ? Number(offset) : void 0
|
|
6577
|
+
}
|
|
6578
|
+
);
|
|
6579
|
+
return response.status(200).send(result);
|
|
6580
|
+
}
|
|
6326
6581
|
getWithContainerAndKey(request, response) {
|
|
6327
6582
|
const result = this.repository.getWithContainerAndKey(
|
|
6328
6583
|
getRepositoryContext(request),
|
|
@@ -6737,6 +6992,18 @@ var ProductService = class extends AbstractService {
|
|
|
6737
6992
|
}
|
|
6738
6993
|
};
|
|
6739
6994
|
|
|
6995
|
+
// src/services/reviews.ts
|
|
6996
|
+
var ReviewService = class extends AbstractService {
|
|
6997
|
+
repository;
|
|
6998
|
+
constructor(parent, repository) {
|
|
6999
|
+
super(parent);
|
|
7000
|
+
this.repository = repository;
|
|
7001
|
+
}
|
|
7002
|
+
getBasePath() {
|
|
7003
|
+
return "reviews";
|
|
7004
|
+
}
|
|
7005
|
+
};
|
|
7006
|
+
|
|
6740
7007
|
// src/services/shipping-method.ts
|
|
6741
7008
|
var ShippingMethodService = class extends AbstractService {
|
|
6742
7009
|
repository;
|
|
@@ -6749,7 +7016,21 @@ var ShippingMethodService = class extends AbstractService {
|
|
|
6749
7016
|
return "shipping-methods";
|
|
6750
7017
|
}
|
|
6751
7018
|
extraRoutes(parent) {
|
|
6752
|
-
parent.get("/matching-cart", this.
|
|
7019
|
+
parent.get("/matching-cart", this.matchingCart.bind(this));
|
|
7020
|
+
}
|
|
7021
|
+
matchingCart(request, response) {
|
|
7022
|
+
const cartId = queryParamsValue(request.query.cartId);
|
|
7023
|
+
if (!cartId) {
|
|
7024
|
+
return response.status(400).send();
|
|
7025
|
+
}
|
|
7026
|
+
const result = this.repository.matchingCart(
|
|
7027
|
+
getRepositoryContext(request),
|
|
7028
|
+
cartId,
|
|
7029
|
+
{
|
|
7030
|
+
expand: this._parseParam(request.query.expand)
|
|
7031
|
+
}
|
|
7032
|
+
);
|
|
7033
|
+
return response.status(200).send(result);
|
|
6753
7034
|
}
|
|
6754
7035
|
};
|
|
6755
7036
|
|
|
@@ -6901,6 +7182,7 @@ var createServices = (router, repos) => ({
|
|
|
6901
7182
|
router,
|
|
6902
7183
|
repos["product-selection"]
|
|
6903
7184
|
),
|
|
7185
|
+
reviews: new ReviewService(router, repos["review"]),
|
|
6904
7186
|
"shopping-list": new ShoppingListService(router, repos["shopping-list"]),
|
|
6905
7187
|
state: new StateService(router, repos["state"]),
|
|
6906
7188
|
store: new StoreService(router, repos["store"]),
|
|
@@ -7090,6 +7372,9 @@ var CommercetoolsMock = class {
|
|
|
7090
7372
|
})
|
|
7091
7373
|
);
|
|
7092
7374
|
}
|
|
7375
|
+
mswServer() {
|
|
7376
|
+
return this._mswServer;
|
|
7377
|
+
}
|
|
7093
7378
|
startServer() {
|
|
7094
7379
|
if (_globalListeners.length > 0) {
|
|
7095
7380
|
if (this._mswServer !== void 0) {
|