@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.js CHANGED
@@ -683,7 +683,7 @@ var resolveValue = (obj, val) => {
683
683
  if (Array.isArray(obj)) {
684
684
  return Object.values(obj).filter((v) => val.value in v).map((v) => v[val.value]);
685
685
  }
686
- throw new PredicateError(`The field '${val.value}' does not exist.`);
686
+ return void 0;
687
687
  }
688
688
  return obj[val.value];
689
689
  };
@@ -763,22 +763,43 @@ var generateMatchFunc = (predicate) => {
763
763
  const expr = parser.parse();
764
764
  lexer.expect(")");
765
765
  return (obj, vars) => {
766
- const value = resolveValue(obj, left);
767
- if (value) {
768
- return expr(value, vars);
766
+ if (Array.isArray(obj)) {
767
+ return obj.some((item) => {
768
+ const value = resolveValue(item, left);
769
+ if (value) {
770
+ return expr(value, vars);
771
+ }
772
+ return false;
773
+ });
774
+ } else {
775
+ const value = resolveValue(obj, left);
776
+ if (value) {
777
+ return expr(value, vars);
778
+ }
779
+ return false;
769
780
  }
770
- return false;
771
781
  };
772
782
  }).bp(")", 0).led("=", 20, ({ left, bp }) => {
773
783
  const expr = parser.parse({ terminals: [bp - 1] });
774
784
  validateSymbol(expr);
775
785
  return (obj, vars) => {
776
- const resolvedValue = resolveValue(obj, left);
777
- const resolvedSymbol = resolveSymbol(expr, vars);
778
- if (Array.isArray(resolvedValue)) {
779
- return !!resolvedValue.some((elem) => elem === resolvedSymbol);
786
+ if (Array.isArray(obj)) {
787
+ return obj.some((item) => {
788
+ const value = resolveValue(item, left);
789
+ const other = resolveSymbol(expr, vars);
790
+ if (Array.isArray(value)) {
791
+ return !!value.some((elem) => elem === other);
792
+ }
793
+ return value === other;
794
+ });
795
+ } else {
796
+ const resolvedValue = resolveValue(obj, left);
797
+ const resolvedSymbol = resolveSymbol(expr, vars);
798
+ if (Array.isArray(resolvedValue)) {
799
+ return !!resolvedValue.some((elem) => elem === resolvedSymbol);
800
+ }
801
+ return resolvedValue === resolvedSymbol;
780
802
  }
781
- return resolvedValue === resolvedSymbol;
782
803
  };
783
804
  }).led("!=", 20, ({ left, bp }) => {
784
805
  const expr = parser.parse({ terminals: [bp - 1] });
@@ -846,10 +867,11 @@ var generateMatchFunc = (predicate) => {
846
867
  if (!Array.isArray(symbols)) {
847
868
  symbols = [expr];
848
869
  }
849
- const inValues = symbols.map(
870
+ const inValues = symbols.flatMap(
850
871
  (item) => resolveSymbol(item, vars)
851
872
  );
852
- return inValues.includes(resolveValue(obj, left));
873
+ const value = resolveValue(obj, left);
874
+ return inValues.includes(value);
853
875
  };
854
876
  }).led("MATCHES_IGNORE_CASE", 20, ({ left, bp }) => {
855
877
  const expr = parser.parse({ terminals: [bp - 1] });
@@ -1027,9 +1049,12 @@ var InMemoryStorage = class extends AbstractStorage {
1027
1049
  }
1028
1050
  let resources = this.all(projectKey, typeId);
1029
1051
  if (params.where) {
1052
+ const vars = Object.fromEntries(
1053
+ Object.entries(params).filter(([key]) => key.startsWith("var.")).map(([key, value]) => [key.slice(4), value])
1054
+ );
1030
1055
  try {
1031
1056
  const filterFunc = parseQueryExpression(params.where);
1032
- resources = resources.filter((resource) => filterFunc(resource, {}));
1057
+ resources = resources.filter((resource) => filterFunc(resource, vars));
1033
1058
  } catch (err) {
1034
1059
  throw new CommercetoolsError(
1035
1060
  {
@@ -1096,28 +1121,34 @@ var InMemoryStorage = class extends AbstractStorage {
1096
1121
  if (resource) {
1097
1122
  return resource;
1098
1123
  }
1099
- console.error(
1100
- `No resource found with typeId=${identifier.typeId}, id=${identifier.id}`
1101
- );
1102
- return null;
1124
+ throw new CommercetoolsError({
1125
+ code: "ReferencedResourceNotFound",
1126
+ 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).`,
1127
+ typeId: identifier.typeId,
1128
+ id: identifier.id
1129
+ });
1103
1130
  }
1104
1131
  if (identifier.key) {
1105
- const store = this.forProjectKey(projectKey)[identifier.typeId];
1106
- if (store) {
1107
- const resource = Array.from(store.values()).find(
1108
- // @ts-ignore
1109
- (r) => r.key === identifier.key
1110
- );
1111
- if (resource) {
1112
- return resource;
1113
- }
1114
- } else {
1115
- throw new Error(
1116
- `No storage found for resource type: ${identifier.typeId}`
1117
- );
1132
+ const resource = this.getByKey(
1133
+ projectKey,
1134
+ identifier.typeId,
1135
+ identifier.key
1136
+ );
1137
+ if (resource) {
1138
+ return resource;
1118
1139
  }
1140
+ throw new CommercetoolsError({
1141
+ code: "ReferencedResourceNotFound",
1142
+ 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).`,
1143
+ typeId: identifier.typeId,
1144
+ key: identifier.key
1145
+ });
1119
1146
  }
1120
- return null;
1147
+ throw new CommercetoolsError({
1148
+ code: "InvalidJsonInput",
1149
+ message: "Request body does not contain valid JSON.",
1150
+ detailedErrorMessage: "ResourceIdentifier requires an 'id' xor a 'key'"
1151
+ });
1121
1152
  }
1122
1153
  addProject = (projectKey) => {
1123
1154
  if (!this.projects[projectKey]) {
@@ -1194,11 +1225,13 @@ var InMemoryStorage = class extends AbstractStorage {
1194
1225
  if (reference === void 0)
1195
1226
  return;
1196
1227
  if (reference.typeId !== void 0 && (reference.id !== void 0 || reference.key !== void 0)) {
1197
- reference.obj = this.getByResourceIdentifier(projectKey, {
1198
- typeId: reference.typeId,
1199
- id: reference.id,
1200
- key: reference.key
1201
- });
1228
+ if (!reference.obj) {
1229
+ reference.obj = this.getByResourceIdentifier(projectKey, {
1230
+ typeId: reference.typeId,
1231
+ id: reference.id,
1232
+ key: reference.key
1233
+ });
1234
+ }
1202
1235
  if (expand) {
1203
1236
  this._resolveResource(projectKey, reference.obj, expand);
1204
1237
  }
@@ -1269,11 +1302,12 @@ var hashPassword = (clearPassword) => Buffer.from(clearPassword).toString("base6
1269
1302
 
1270
1303
  // src/oauth/server.ts
1271
1304
  var OAuth2Server = class {
1272
- store;
1273
- customerRepository;
1274
1305
  constructor(options) {
1306
+ this.options = options;
1275
1307
  this.store = new OAuth2Store(options.validate);
1276
1308
  }
1309
+ store;
1310
+ customerRepository;
1277
1311
  setCustomerRepository(repository) {
1278
1312
  this.customerRepository = repository;
1279
1313
  }
@@ -1297,6 +1331,11 @@ var OAuth2Server = class {
1297
1331
  return router;
1298
1332
  }
1299
1333
  createMiddleware() {
1334
+ if (!this.options.validate) {
1335
+ return async (request, response, next) => {
1336
+ next();
1337
+ };
1338
+ }
1300
1339
  return async (request, response, next) => {
1301
1340
  const token = getBearerToken(request);
1302
1341
  if (!token) {
@@ -1633,7 +1672,7 @@ var getReferenceFromResourceIdentifier = (resourceIdentifier, projectKey, storag
1633
1672
  resourceIdentifier
1634
1673
  );
1635
1674
  if (!resource) {
1636
- const errIdentifier = resourceIdentifier.key ? `key '${resourceIdentifier.key}'` : `identifier '${resourceIdentifier.key}'`;
1675
+ const errIdentifier = resourceIdentifier.key ? `key '${resourceIdentifier.key}'` : `identifier '${resourceIdentifier.id}'`;
1637
1676
  throw new CommercetoolsError(
1638
1677
  {
1639
1678
  code: "ReferencedResourceNotFound",
@@ -1834,10 +1873,7 @@ var AbstractResourceRepository = class extends AbstractRepository {
1834
1873
  }
1835
1874
  query(context, params = {}) {
1836
1875
  const result = this._storage.query(context.projectKey, this.getTypeId(), {
1837
- expand: params.expand,
1838
- where: params.where,
1839
- offset: params.offset,
1840
- limit: params.limit
1876
+ ...params
1841
1877
  });
1842
1878
  result.results = result.results.map(this.postProcessResource);
1843
1879
  return result;
@@ -2157,6 +2193,11 @@ var CartRepository = class extends AbstractResourceRepository {
2157
2193
  fractionDigits: 0
2158
2194
  },
2159
2195
  shippingMode: "Single",
2196
+ shippingAddress: createAddress(
2197
+ draft.shippingAddress,
2198
+ context.projectKey,
2199
+ this._storage
2200
+ ),
2160
2201
  shipping: [],
2161
2202
  origin: draft.origin ?? "Customer",
2162
2203
  refusedGifts: [],
@@ -2358,9 +2399,6 @@ var CartRepository = class extends AbstractResourceRepository {
2358
2399
  context.projectKey,
2359
2400
  shippingMethod
2360
2401
  );
2361
- if (!method) {
2362
- throw new Error(`Type ${shippingMethod} not found`);
2363
- }
2364
2402
  resource.shippingInfo = {
2365
2403
  shippingMethod: {
2366
2404
  typeId: "shipping-method",
@@ -2384,6 +2422,33 @@ var CartRepository = class extends AbstractResourceRepository {
2384
2422
  }
2385
2423
  resource.custom.fields[name] = value;
2386
2424
  },
2425
+ setCustomShippingMethod: (context, resource, {
2426
+ shippingMethodName,
2427
+ shippingRate,
2428
+ taxCategory,
2429
+ externalTaxRate
2430
+ }) => {
2431
+ if (externalTaxRate) {
2432
+ throw new Error("External tax rate is not supported");
2433
+ }
2434
+ const tax = taxCategory ? this._storage.getByResourceIdentifier(
2435
+ context.projectKey,
2436
+ taxCategory
2437
+ ) : void 0;
2438
+ resource.shippingInfo = {
2439
+ shippingMethodName,
2440
+ price: createCentPrecisionMoney(shippingRate.price),
2441
+ shippingRate: {
2442
+ price: createTypedMoney(shippingRate.price),
2443
+ tiers: []
2444
+ },
2445
+ taxCategory: tax ? {
2446
+ typeId: "tax-category",
2447
+ id: tax?.id
2448
+ } : void 0,
2449
+ shippingMethodState: "MatchesCart"
2450
+ };
2451
+ },
2387
2452
  setCustomType: (context, resource, { type, fields }) => {
2388
2453
  if (!type) {
2389
2454
  resource.custom = void 0;
@@ -2935,6 +3000,16 @@ var CustomObjectRepository = class extends AbstractResourceRepository {
2935
3000
  return resource;
2936
3001
  }
2937
3002
  }
3003
+ queryWithContainer(context, container, params = {}) {
3004
+ const whereClause = params.where || [];
3005
+ whereClause.push(`container="${container}"`);
3006
+ const result = this._storage.query(context.projectKey, this.getTypeId(), {
3007
+ ...params,
3008
+ where: whereClause
3009
+ });
3010
+ result.results = result.results.map(this.postProcessResource);
3011
+ return result;
3012
+ }
2938
3013
  getWithContainerAndKey(context, container, key) {
2939
3014
  const items = this._storage.all(context.projectKey, this.getTypeId());
2940
3015
  return items.find(
@@ -2973,7 +3048,8 @@ var CustomerRepository = class extends AbstractResourceRepository {
2973
3048
  email: draft.email.toLowerCase(),
2974
3049
  password: draft.password ? hashPassword(draft.password) : void 0,
2975
3050
  isEmailVerified: draft.isEmailVerified || false,
2976
- addresses: []
3051
+ addresses: [],
3052
+ customerNumber: draft.customerNumber
2977
3053
  };
2978
3054
  this.saveNew(context, resource);
2979
3055
  return resource;
@@ -3479,10 +3555,11 @@ var OrderRepository = class extends AbstractResourceRepository {
3479
3555
  name: draft.name,
3480
3556
  quantity: draft.quantity ?? 0,
3481
3557
  perMethodTaxRate: [],
3482
- priceMode: draft.priceMode,
3558
+ priceMode: draft.priceMode ?? "Standard",
3483
3559
  slug: draft.slug,
3484
3560
  state: [],
3485
- totalPrice: createCentPrecisionMoney(draft.money)
3561
+ totalPrice: createCentPrecisionMoney(draft.money),
3562
+ taxedPricePortions: []
3486
3563
  };
3487
3564
  return lineItem;
3488
3565
  }
@@ -3518,6 +3595,37 @@ var OrderRepository = class extends AbstractResourceRepository {
3518
3595
  id: payment.id
3519
3596
  });
3520
3597
  },
3598
+ addReturnInfo: (context, resource, info) => {
3599
+ if (!resource.returnInfo) {
3600
+ resource.returnInfo = [];
3601
+ }
3602
+ const resolved = {
3603
+ items: info.items.map((item) => {
3604
+ const common = {
3605
+ ...getBaseResourceProperties(),
3606
+ quantity: item.quantity,
3607
+ paymentState: "Initial",
3608
+ shipmentState: "Initial",
3609
+ comment: item.comment
3610
+ };
3611
+ if (item.customLineItemId) {
3612
+ return {
3613
+ ...common,
3614
+ type: "CustomLineItemReturnItem",
3615
+ customLineItemId: item.customLineItemId
3616
+ };
3617
+ }
3618
+ return {
3619
+ ...common,
3620
+ type: "LineItemReturnItem",
3621
+ lineItemId: item.customLineItemId || item.lineItemId
3622
+ };
3623
+ }),
3624
+ returnTrackingId: info.returnTrackingId,
3625
+ returnDate: info.returnDate
3626
+ };
3627
+ resource.returnInfo.push(resolved);
3628
+ },
3521
3629
  changeOrderState: (context, resource, { orderState }) => {
3522
3630
  resource.orderState = orderState;
3523
3631
  },
@@ -3828,9 +3936,9 @@ var ProductRepository = class extends AbstractResourceRepository {
3828
3936
  slug: draft.slug,
3829
3937
  description: draft.description,
3830
3938
  categories: categoryReferences,
3831
- masterVariant: variantFromDraft(1, draft.masterVariant),
3939
+ masterVariant: this.variantFromDraft(context, 1, draft.masterVariant),
3832
3940
  variants: draft.variants?.map(
3833
- (variant, index) => variantFromDraft(index + 2, variant)
3941
+ (variant, index) => this.variantFromDraft(context, index + 2, variant)
3834
3942
  ) ?? [],
3835
3943
  metaTitle: draft.metaTitle,
3836
3944
  metaDescription: draft.metaDescription,
@@ -3853,6 +3961,30 @@ var ProductRepository = class extends AbstractResourceRepository {
3853
3961
  this.saveNew(context, resource);
3854
3962
  return resource;
3855
3963
  }
3964
+ variantFromDraft(context, variantId, variant) {
3965
+ return {
3966
+ id: variantId,
3967
+ sku: variant?.sku,
3968
+ key: variant?.key,
3969
+ attributes: variant?.attributes ?? [],
3970
+ prices: variant?.prices?.map((p) => this.priceFromDraft(context, p)),
3971
+ assets: [],
3972
+ images: []
3973
+ };
3974
+ }
3975
+ priceFromDraft(context, draft) {
3976
+ return {
3977
+ id: uuidv46(),
3978
+ key: draft.key,
3979
+ country: draft.country,
3980
+ value: createTypedMoney(draft.value),
3981
+ channel: draft.channel ? getReferenceFromResourceIdentifier(
3982
+ draft.channel,
3983
+ context.projectKey,
3984
+ this._storage
3985
+ ) : void 0
3986
+ };
3987
+ }
3856
3988
  actions = {
3857
3989
  publish: (context, resource, { scope }) => {
3858
3990
  resource.masterData.current = resource.masterData.staged;
@@ -4097,7 +4229,7 @@ var ProductRepository = class extends AbstractResourceRepository {
4097
4229
  data.variants[variantIndex] = variant;
4098
4230
  }
4099
4231
  };
4100
- const priceToAdd = priceFromDraft(price);
4232
+ const priceToAdd = this.priceFromDraft(context, price);
4101
4233
  const onlyStaged = staged !== void 0 ? staged : true;
4102
4234
  addVariantPrice(resource.masterData.staged, priceToAdd);
4103
4235
  if (!onlyStaged) {
@@ -4254,7 +4386,7 @@ var ProductRepository = class extends AbstractResourceRepository {
4254
4386
  (max, element) => element.id > max ? element.id : max,
4255
4387
  0
4256
4388
  );
4257
- const variant = variantFromDraft(maxId + 1, variantDraft);
4389
+ const variant = this.variantFromDraft(context, maxId + 1, variantDraft);
4258
4390
  dataStaged.variants.push(variant);
4259
4391
  const onlyStaged = staged !== void 0 ? staged : true;
4260
4392
  if (!onlyStaged) {
@@ -4492,21 +4624,6 @@ var getVariant = (productData, variantId, sku) => {
4492
4624
  variantIndex: !isMasterVariant && foundVariant ? productData.variants.indexOf(foundVariant) : -1
4493
4625
  };
4494
4626
  };
4495
- var variantFromDraft = (variantId, variant) => ({
4496
- id: variantId,
4497
- sku: variant?.sku,
4498
- key: variant?.key,
4499
- attributes: variant?.attributes ?? [],
4500
- prices: variant?.prices?.map(priceFromDraft),
4501
- assets: [],
4502
- images: []
4503
- });
4504
- var priceFromDraft = (draft) => ({
4505
- id: uuidv46(),
4506
- key: draft.key,
4507
- country: draft.country,
4508
- value: createTypedMoney(draft.value)
4509
- });
4510
4627
 
4511
4628
  // src/repositories/product-discount.ts
4512
4629
  var ProductDiscountRepository = class extends AbstractResourceRepository {
@@ -4778,7 +4895,7 @@ var getVariants = (p) => [
4778
4895
  ];
4779
4896
 
4780
4897
  // src/priceSelector.ts
4781
- var applyPriceSelector = (products, selector) => {
4898
+ var applyPriceSelector = (products, selector, noScopedPrice = false) => {
4782
4899
  validatePriceSelector(selector);
4783
4900
  for (const product of products) {
4784
4901
  const variants = [
@@ -4789,11 +4906,14 @@ var applyPriceSelector = (products, selector) => {
4789
4906
  const scopedPrices = variant.prices?.filter((p) => priceSelectorFilter(p, selector)) ?? [];
4790
4907
  if (scopedPrices.length > 0) {
4791
4908
  const price = scopedPrices[0];
4792
- variant.scopedPriceDiscounted = false;
4793
- variant.scopedPrice = {
4794
- ...price,
4795
- currentValue: price.value
4796
- };
4909
+ variant.price = scopedPrices[0];
4910
+ if (!noScopedPrice) {
4911
+ variant.scopedPriceDiscounted = false;
4912
+ variant.scopedPrice = {
4913
+ ...price,
4914
+ currentValue: price.value
4915
+ };
4916
+ }
4797
4917
  }
4798
4918
  }
4799
4919
  }
@@ -5128,6 +5248,16 @@ var ProductProjectionRepository = class extends AbstractResourceRepository {
5128
5248
  );
5129
5249
  }
5130
5250
  }
5251
+ applyPriceSelector(
5252
+ resources,
5253
+ {
5254
+ country: params.priceCountry,
5255
+ channel: params.priceChannel,
5256
+ customerGroup: params.priceCustomerGroup,
5257
+ currency: params.priceCurrency
5258
+ },
5259
+ true
5260
+ );
5131
5261
  if (params.expand !== void 0) {
5132
5262
  resources = resources.map(
5133
5263
  (resource) => this._storage.expand(context.projectKey, resource, params.expand)
@@ -5162,7 +5292,6 @@ var ProductSelectionRepository = class extends AbstractResourceRepository {
5162
5292
  productCount: 0,
5163
5293
  key: draft.key,
5164
5294
  name: draft.name,
5165
- type: "individual",
5166
5295
  mode: "Individual"
5167
5296
  };
5168
5297
  this.saveNew(context, resource);
@@ -5378,9 +5507,28 @@ var ReviewRepository = class extends AbstractResourceRepository {
5378
5507
  return "review";
5379
5508
  }
5380
5509
  create(context, draft) {
5510
+ if (!draft.target)
5511
+ throw new Error("Missing target");
5381
5512
  const resource = {
5382
5513
  ...getBaseResourceProperties(),
5383
- includedInStatistics: false
5514
+ locale: draft.locale,
5515
+ authorName: draft.authorName,
5516
+ title: draft.title,
5517
+ text: draft.text,
5518
+ rating: draft.rating,
5519
+ uniquenessValue: draft.uniquenessValue,
5520
+ state: draft.state ? getReferenceFromResourceIdentifier(
5521
+ draft.state,
5522
+ context.projectKey,
5523
+ this._storage
5524
+ ) : void 0,
5525
+ target: draft.target ? getReferenceFromResourceIdentifier(draft.target, context.projectKey, this._storage) : void 0,
5526
+ includedInStatistics: false,
5527
+ custom: createCustomFields(
5528
+ draft.custom,
5529
+ context.projectKey,
5530
+ this._storage
5531
+ )
5384
5532
  };
5385
5533
  this.saveNew(context, resource);
5386
5534
  return resource;
@@ -5390,6 +5538,50 @@ var ReviewRepository = class extends AbstractResourceRepository {
5390
5538
 
5391
5539
  // src/repositories/shipping-method.ts
5392
5540
  import deepEqual3 from "deep-equal";
5541
+
5542
+ // src/shippingCalculator.ts
5543
+ var markMatchingShippingRate = (cart, shippingRate) => {
5544
+ const isMatching = shippingRate.price.currencyCode === cart.totalPrice.currencyCode;
5545
+ return {
5546
+ ...shippingRate,
5547
+ tiers: markMatchingShippingRatePriceTiers(cart, shippingRate.tiers),
5548
+ isMatching
5549
+ };
5550
+ };
5551
+ var markMatchingShippingRatePriceTiers = (cart, tiers) => {
5552
+ if (tiers.length === 0) {
5553
+ return [];
5554
+ }
5555
+ if (new Set(tiers.map((tier) => tier.type)).size > 1) {
5556
+ throw new Error("Can't handle multiple types of tiers");
5557
+ }
5558
+ const tierType = tiers[0].type;
5559
+ switch (tierType) {
5560
+ case "CartValue":
5561
+ return markMatchingCartValueTiers(cart, tiers);
5562
+ default:
5563
+ throw new Error(`Unsupported tier type: ${tierType}`);
5564
+ }
5565
+ };
5566
+ var markMatchingCartValueTiers = (cart, tiers) => {
5567
+ const sortedTiers = [...tiers].sort(
5568
+ (a, b) => b.minimumCentAmount - a.minimumCentAmount
5569
+ );
5570
+ const result = {};
5571
+ let hasMatchingTier = false;
5572
+ for (const tier of sortedTiers) {
5573
+ const isMatching = !hasMatchingTier && cart.totalPrice.currencyCode === tier.price.currencyCode && cart.totalPrice.centAmount >= tier.minimumCentAmount;
5574
+ if (isMatching)
5575
+ hasMatchingTier = true;
5576
+ result[tier.minimumCentAmount] = {
5577
+ ...tier,
5578
+ isMatching
5579
+ };
5580
+ }
5581
+ return tiers.map((tier) => result[tier.minimumCentAmount]);
5582
+ };
5583
+
5584
+ // src/repositories/shipping-method.ts
5393
5585
  var ShippingMethodRepository = class extends AbstractResourceRepository {
5394
5586
  getTypeId() {
5395
5587
  return "shipping-method";
@@ -5429,6 +5621,53 @@ var ShippingMethodRepository = class extends AbstractResourceRepository {
5429
5621
  freeAbove: rate.freeAbove && createTypedMoney(rate.freeAbove),
5430
5622
  tiers: rate.tiers || []
5431
5623
  });
5624
+ /*
5625
+ * Retrieves all the ShippingMethods that can ship to the shipping address of
5626
+ * the given Cart. Each ShippingMethod contains exactly one ShippingRate with
5627
+ * the flag isMatching set to true. This ShippingRate is used when the
5628
+ * ShippingMethod is added to the Cart.
5629
+ */
5630
+ matchingCart(context, cartId, params = {}) {
5631
+ const cart = this._storage.get(context.projectKey, "cart", cartId);
5632
+ if (!cart) {
5633
+ return void 0;
5634
+ }
5635
+ if (!cart.shippingAddress?.country) {
5636
+ throw new CommercetoolsError({
5637
+ code: "InvalidOperation",
5638
+ message: `The cart with ID '${cart.id}' does not have a shipping address set.`
5639
+ });
5640
+ }
5641
+ const zones = this._storage.query(context.projectKey, "zone", {
5642
+ where: [`locations(country="${cart.shippingAddress.country}"))`],
5643
+ limit: 100
5644
+ });
5645
+ const zoneIds = zones.results.map((zone) => zone.id);
5646
+ const shippingMethods = this.query(context, {
5647
+ where: [
5648
+ `zoneRates(zone(id in (:zoneIds)))`,
5649
+ `zoneRates(shippingRates(price(currencyCode="${cart.totalPrice.currencyCode}")))`
5650
+ ],
5651
+ "var.zoneIds": zoneIds,
5652
+ expand: params.expand
5653
+ });
5654
+ const results = shippingMethods.results.map((shippingMethod) => {
5655
+ const rates = shippingMethod.zoneRates.map((zoneRate) => ({
5656
+ zone: zoneRate.zone,
5657
+ // Iterate through the shippingRates and mark the matching ones
5658
+ // then we filter out the non-matching ones
5659
+ shippingRates: zoneRate.shippingRates.map((rate) => markMatchingShippingRate(cart, rate)).filter((rate) => rate.isMatching)
5660
+ })).filter((zoneRate) => zoneRate.shippingRates.length > 0);
5661
+ return {
5662
+ ...shippingMethod,
5663
+ zoneRates: rates
5664
+ };
5665
+ }).filter((shippingMethod) => shippingMethod.zoneRates.length > 0);
5666
+ return {
5667
+ ...shippingMethods,
5668
+ results
5669
+ };
5670
+ }
5432
5671
  actions = {
5433
5672
  addShippingRate: (_context, resource, { shippingRate, zone }) => {
5434
5673
  const rate = this._transformShippingRate(shippingRate);
@@ -6282,10 +6521,26 @@ var CustomObjectService = class extends AbstractService {
6282
6521
  return "custom-objects";
6283
6522
  }
6284
6523
  extraRoutes(router) {
6524
+ router.get("/:container", this.getWithContainer.bind(this));
6285
6525
  router.get("/:container/:key", this.getWithContainerAndKey.bind(this));
6286
6526
  router.post("/:container/:key", this.createWithContainerAndKey.bind(this));
6287
6527
  router.delete("/:container/:key", this.deleteWithContainerAndKey.bind(this));
6288
6528
  }
6529
+ getWithContainer(request, response) {
6530
+ const limit = this._parseParam(request.query.limit);
6531
+ const offset = this._parseParam(request.query.offset);
6532
+ const result = this.repository.queryWithContainer(
6533
+ getRepositoryContext(request),
6534
+ request.params.container,
6535
+ {
6536
+ expand: this._parseParam(request.query.expand),
6537
+ where: this._parseParam(request.query.where),
6538
+ limit: limit !== void 0 ? Number(limit) : void 0,
6539
+ offset: offset !== void 0 ? Number(offset) : void 0
6540
+ }
6541
+ );
6542
+ return response.status(200).send(result);
6543
+ }
6289
6544
  getWithContainerAndKey(request, response) {
6290
6545
  const result = this.repository.getWithContainerAndKey(
6291
6546
  getRepositoryContext(request),
@@ -6700,6 +6955,18 @@ var ProductService = class extends AbstractService {
6700
6955
  }
6701
6956
  };
6702
6957
 
6958
+ // src/services/reviews.ts
6959
+ var ReviewService = class extends AbstractService {
6960
+ repository;
6961
+ constructor(parent, repository) {
6962
+ super(parent);
6963
+ this.repository = repository;
6964
+ }
6965
+ getBasePath() {
6966
+ return "reviews";
6967
+ }
6968
+ };
6969
+
6703
6970
  // src/services/shipping-method.ts
6704
6971
  var ShippingMethodService = class extends AbstractService {
6705
6972
  repository;
@@ -6712,7 +6979,21 @@ var ShippingMethodService = class extends AbstractService {
6712
6979
  return "shipping-methods";
6713
6980
  }
6714
6981
  extraRoutes(parent) {
6715
- parent.get("/matching-cart", this.get.bind(this));
6982
+ parent.get("/matching-cart", this.matchingCart.bind(this));
6983
+ }
6984
+ matchingCart(request, response) {
6985
+ const cartId = queryParamsValue(request.query.cartId);
6986
+ if (!cartId) {
6987
+ return response.status(400).send();
6988
+ }
6989
+ const result = this.repository.matchingCart(
6990
+ getRepositoryContext(request),
6991
+ cartId,
6992
+ {
6993
+ expand: this._parseParam(request.query.expand)
6994
+ }
6995
+ );
6996
+ return response.status(200).send(result);
6716
6997
  }
6717
6998
  };
6718
6999
 
@@ -6864,6 +7145,7 @@ var createServices = (router, repos) => ({
6864
7145
  router,
6865
7146
  repos["product-selection"]
6866
7147
  ),
7148
+ reviews: new ReviewService(router, repos["review"]),
6867
7149
  "shopping-list": new ShoppingListService(router, repos["shopping-list"]),
6868
7150
  state: new StateService(router, repos["state"]),
6869
7151
  store: new StoreService(router, repos["store"]),
@@ -7053,6 +7335,9 @@ var CommercetoolsMock = class {
7053
7335
  })
7054
7336
  );
7055
7337
  }
7338
+ mswServer() {
7339
+ return this._mswServer;
7340
+ }
7056
7341
  startServer() {
7057
7342
  if (_globalListeners.length > 0) {
7058
7343
  if (this._mswServer !== void 0) {