@labdigital/commercetools-mock 2.29.1 → 2.30.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 CHANGED
@@ -4541,6 +4541,165 @@ var PaymentRepository = class extends AbstractResourceRepository {
4541
4541
  }
4542
4542
  };
4543
4543
 
4544
+ // src/lib/searchQueryTypeChecker.ts
4545
+ var validateSearchQuery = (query) => {
4546
+ if (isSearchAndExpression(query)) {
4547
+ query.and.forEach((expr) => validateSearchQuery(expr));
4548
+ } else if (isSearchOrExpression(query)) {
4549
+ query.or.forEach((expr) => validateSearchQuery(expr));
4550
+ } else if (isSearchNotExpression(query)) {
4551
+ validateSearchQuery(query.not);
4552
+ } else if (isSearchFilterExpression(query) || isSearchRangeExpression(query) || isSearchExactExpression(query) || isSearchExistsExpression(query) || isSearchFullTextExpression(query) || isSearchFullTextPrefixExpression(query) || isSearchPrefixExpression(query) || isSearchWildCardExpression(query) || isSearchAnyValue(query)) {
4553
+ return;
4554
+ } else {
4555
+ throw new Error("Unsupported search query expression");
4556
+ }
4557
+ };
4558
+ var isSearchAndExpression = (expr) => expr.and !== void 0;
4559
+ var isSearchOrExpression = (expr) => expr.or !== void 0;
4560
+ var isSearchNotExpression = (expr) => expr.not !== void 0;
4561
+ var isSearchFilterExpression = (expr) => expr.filter !== void 0;
4562
+ var isSearchRangeExpression = (expr) => expr.range !== void 0;
4563
+ var isSearchExactExpression = (expr) => expr.exact !== void 0;
4564
+ var isSearchExistsExpression = (expr) => expr.exists !== void 0;
4565
+ var isSearchFullTextExpression = (expr) => expr.fullText !== void 0;
4566
+ var isSearchFullTextPrefixExpression = (expr) => expr.fullTextPrefix !== void 0;
4567
+ var isSearchPrefixExpression = (expr) => expr.prefix !== void 0;
4568
+ var isSearchWildCardExpression = (expr) => expr.wildcard !== void 0;
4569
+ var isSearchAnyValue = (expr) => expr.value !== void 0;
4570
+
4571
+ // src/priceSelector.ts
4572
+ var applyPriceSelector = (products, selector, noScopedPrice = false) => {
4573
+ validatePriceSelector(selector);
4574
+ for (const product of products) {
4575
+ const variants = [
4576
+ product.masterVariant,
4577
+ ...product.variants ?? []
4578
+ ].filter((x) => x != void 0);
4579
+ for (const variant of variants) {
4580
+ const scopedPrices = variant.prices?.filter((p) => priceSelectorFilter(p, selector)) ?? [];
4581
+ if (scopedPrices.length > 0) {
4582
+ const price = scopedPrices[0];
4583
+ variant.price = scopedPrices[0];
4584
+ if (!noScopedPrice) {
4585
+ variant.scopedPriceDiscounted = false;
4586
+ variant.scopedPrice = {
4587
+ ...price,
4588
+ currentValue: price.value
4589
+ };
4590
+ }
4591
+ }
4592
+ }
4593
+ }
4594
+ };
4595
+ var validatePriceSelector = (selector) => {
4596
+ if ((selector.country || selector.channel || selector.customerGroup) && !selector.currency) {
4597
+ throw new CommercetoolsError(
4598
+ {
4599
+ code: "InvalidInput",
4600
+ message: "The price selecting parameters country, channel and customerGroup cannot be used without the currency."
4601
+ },
4602
+ 400
4603
+ );
4604
+ }
4605
+ };
4606
+ var priceSelectorFilter = (price, selector) => {
4607
+ if ((selector.country || price.country) && selector.country !== price.country) {
4608
+ return false;
4609
+ }
4610
+ if ((selector.currency || price.value.currencyCode) && selector.currency !== price.value.currencyCode) {
4611
+ return false;
4612
+ }
4613
+ if ((selector.channel || price.channel?.id) && selector.channel !== price.channel?.id) {
4614
+ return false;
4615
+ }
4616
+ if ((selector.customerGroup || price.customerGroup?.id) && selector.customerGroup !== price.customerGroup?.id) {
4617
+ return false;
4618
+ }
4619
+ return true;
4620
+ };
4621
+
4622
+ // src/product-search.ts
4623
+ var ProductSearch = class {
4624
+ _storage;
4625
+ constructor(storage) {
4626
+ this._storage = storage;
4627
+ }
4628
+ search(projectKey, params) {
4629
+ const resources = this._storage.all(projectKey, "product").map(
4630
+ (r) => this.transform(r, params.productProjectionParameters?.staged ?? false)
4631
+ ).filter((p) => {
4632
+ if (!params.productProjectionParameters?.staged) {
4633
+ return p.published;
4634
+ }
4635
+ return true;
4636
+ });
4637
+ if (params.query) {
4638
+ try {
4639
+ validateSearchQuery(params.query);
4640
+ } catch (err) {
4641
+ console.error(err);
4642
+ throw new CommercetoolsError(
4643
+ {
4644
+ code: "InvalidInput",
4645
+ message: err.message
4646
+ },
4647
+ 400
4648
+ );
4649
+ }
4650
+ }
4651
+ if (params.productProjectionParameters) {
4652
+ applyPriceSelector(resources, {
4653
+ country: params.productProjectionParameters.priceCountry,
4654
+ channel: params.productProjectionParameters.priceChannel,
4655
+ customerGroup: params.productProjectionParameters.priceCustomerGroup,
4656
+ currency: params.productProjectionParameters.priceCurrency
4657
+ });
4658
+ }
4659
+ const offset = params.offset || 0;
4660
+ const limit = params.limit || 20;
4661
+ const productProjectionsResult = resources.slice(offset, offset + limit);
4662
+ const productProjectionsParameterGiven = !!params?.productProjectionParameters;
4663
+ const results = productProjectionsResult.map(
4664
+ (product) => ({
4665
+ productProjection: productProjectionsParameterGiven ? product : void 0,
4666
+ id: product.id
4667
+ /**
4668
+ * @TODO: possibly add support for optional matchingVariants
4669
+ * https://docs.commercetools.com/api/projects/product-search#productsearchmatchingvariants
4670
+ */
4671
+ })
4672
+ );
4673
+ return {
4674
+ total: resources.length,
4675
+ offset,
4676
+ limit,
4677
+ results,
4678
+ facets: []
4679
+ };
4680
+ }
4681
+ transform(product, staged) {
4682
+ const obj = !staged ? product.masterData.current : product.masterData.staged;
4683
+ return {
4684
+ id: product.id,
4685
+ createdAt: product.createdAt,
4686
+ lastModifiedAt: product.lastModifiedAt,
4687
+ version: product.version,
4688
+ name: obj.name,
4689
+ key: product.key,
4690
+ description: obj.description,
4691
+ metaDescription: obj.metaDescription,
4692
+ slug: obj.slug,
4693
+ categories: obj.categories,
4694
+ masterVariant: obj.masterVariant,
4695
+ variants: obj.variants,
4696
+ productType: product.productType,
4697
+ hasStagedChanges: product.masterData.hasStagedChanges,
4698
+ published: product.masterData.published
4699
+ };
4700
+ }
4701
+ };
4702
+
4544
4703
  // src/repositories/product/helpers.ts
4545
4704
  var import_deep_equal2 = __toESM(require("deep-equal"), 1);
4546
4705
  var import_uuid10 = require("uuid");
@@ -5271,9 +5430,11 @@ var ProductUpdateHandler = class extends AbstractUpdateHandler {
5271
5430
 
5272
5431
  // src/repositories/product/index.ts
5273
5432
  var ProductRepository = class extends AbstractResourceRepository {
5433
+ _searchService;
5274
5434
  constructor(storage) {
5275
5435
  super("product", storage);
5276
5436
  this.actions = new ProductUpdateHandler(storage);
5437
+ this._searchService = new ProductSearch(storage);
5277
5438
  }
5278
5439
  create(context, draft) {
5279
5440
  if (!draft.masterVariant) {
@@ -5366,6 +5527,9 @@ var ProductRepository = class extends AbstractResourceRepository {
5366
5527
  };
5367
5528
  return this.saveNew(context, resource);
5368
5529
  }
5530
+ search(context, searchRequest) {
5531
+ return this._searchService.search(context.projectKey, searchRequest);
5532
+ }
5369
5533
  };
5370
5534
 
5371
5535
  // src/repositories/product-discount.ts
@@ -5449,57 +5613,6 @@ var ProductDiscountUpdateHandler = class extends AbstractUpdateHandler {
5449
5613
  }
5450
5614
  };
5451
5615
 
5452
- // src/priceSelector.ts
5453
- var applyPriceSelector = (products, selector, noScopedPrice = false) => {
5454
- validatePriceSelector(selector);
5455
- for (const product of products) {
5456
- const variants = [
5457
- product.masterVariant,
5458
- ...product.variants ?? []
5459
- ].filter((x) => x != void 0);
5460
- for (const variant of variants) {
5461
- const scopedPrices = variant.prices?.filter((p) => priceSelectorFilter(p, selector)) ?? [];
5462
- if (scopedPrices.length > 0) {
5463
- const price = scopedPrices[0];
5464
- variant.price = scopedPrices[0];
5465
- if (!noScopedPrice) {
5466
- variant.scopedPriceDiscounted = false;
5467
- variant.scopedPrice = {
5468
- ...price,
5469
- currentValue: price.value
5470
- };
5471
- }
5472
- }
5473
- }
5474
- }
5475
- };
5476
- var validatePriceSelector = (selector) => {
5477
- if ((selector.country || selector.channel || selector.customerGroup) && !selector.currency) {
5478
- throw new CommercetoolsError(
5479
- {
5480
- code: "InvalidInput",
5481
- message: "The price selecting parameters country, channel and customerGroup cannot be used without the currency."
5482
- },
5483
- 400
5484
- );
5485
- }
5486
- };
5487
- var priceSelectorFilter = (price, selector) => {
5488
- if ((selector.country || price.country) && selector.country !== price.country) {
5489
- return false;
5490
- }
5491
- if ((selector.currency || price.value.currencyCode) && selector.currency !== price.value.currencyCode) {
5492
- return false;
5493
- }
5494
- if ((selector.channel || price.channel?.id) && selector.channel !== price.channel?.id) {
5495
- return false;
5496
- }
5497
- if ((selector.customerGroup || price.customerGroup?.id) && selector.customerGroup !== price.customerGroup?.id) {
5498
- return false;
5499
- }
5500
- return true;
5501
- };
5502
-
5503
5616
  // src/lib/projectionSearchFilter.ts
5504
5617
  var parseFilterExpression = (filter) => {
5505
5618
  const exprFunc = generateMatchFunc2(filter);
@@ -8004,6 +8117,17 @@ var ProductService = class extends AbstractService {
8004
8117
  getBasePath() {
8005
8118
  return "products";
8006
8119
  }
8120
+ extraRoutes(router) {
8121
+ router.post("/search", this.search.bind(this));
8122
+ }
8123
+ search(request, response) {
8124
+ const searchBody = request.body;
8125
+ const resource = this.repository.search(
8126
+ getRepositoryContext(request),
8127
+ searchBody
8128
+ );
8129
+ return response.status(200).send(resource);
8130
+ }
8007
8131
  };
8008
8132
 
8009
8133
  // src/services/product-discount.ts