@labdigital/commercetools-mock 2.29.1 → 2.30.1
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 +178 -51
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.js +178 -51
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/lib/searchQueryTypeChecker.test.ts +96 -0
- package/src/lib/searchQueryTypeChecker.ts +120 -0
- package/src/product-projection-search.ts +1 -1
- package/src/product-search.ts +123 -0
- package/src/repositories/order/actions.ts +9 -0
- package/src/repositories/product/index.ts +13 -0
- package/src/services/order.test.ts +14 -0
- package/src/services/product.test.ts +76 -1
- package/src/services/product.ts +15 -1
- package/src/types.ts +2 -2
package/dist/index.cjs
CHANGED
|
@@ -3990,6 +3990,9 @@ var OrderUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
3990
3990
|
changePaymentState(context, resource, { paymentState }) {
|
|
3991
3991
|
resource.paymentState = paymentState;
|
|
3992
3992
|
}
|
|
3993
|
+
changeShipmentState(context, resource, { shipmentState }) {
|
|
3994
|
+
resource.shipmentState = shipmentState;
|
|
3995
|
+
}
|
|
3993
3996
|
setBillingAddress(context, resource, { address }) {
|
|
3994
3997
|
resource.billingAddress = createAddress(
|
|
3995
3998
|
address,
|
|
@@ -4541,6 +4544,165 @@ var PaymentRepository = class extends AbstractResourceRepository {
|
|
|
4541
4544
|
}
|
|
4542
4545
|
};
|
|
4543
4546
|
|
|
4547
|
+
// src/lib/searchQueryTypeChecker.ts
|
|
4548
|
+
var validateSearchQuery = (query) => {
|
|
4549
|
+
if (isSearchAndExpression(query)) {
|
|
4550
|
+
query.and.forEach((expr) => validateSearchQuery(expr));
|
|
4551
|
+
} else if (isSearchOrExpression(query)) {
|
|
4552
|
+
query.or.forEach((expr) => validateSearchQuery(expr));
|
|
4553
|
+
} else if (isSearchNotExpression(query)) {
|
|
4554
|
+
validateSearchQuery(query.not);
|
|
4555
|
+
} else if (isSearchFilterExpression(query) || isSearchRangeExpression(query) || isSearchExactExpression(query) || isSearchExistsExpression(query) || isSearchFullTextExpression(query) || isSearchFullTextPrefixExpression(query) || isSearchPrefixExpression(query) || isSearchWildCardExpression(query) || isSearchAnyValue(query)) {
|
|
4556
|
+
return;
|
|
4557
|
+
} else {
|
|
4558
|
+
throw new Error("Unsupported search query expression");
|
|
4559
|
+
}
|
|
4560
|
+
};
|
|
4561
|
+
var isSearchAndExpression = (expr) => expr.and !== void 0;
|
|
4562
|
+
var isSearchOrExpression = (expr) => expr.or !== void 0;
|
|
4563
|
+
var isSearchNotExpression = (expr) => expr.not !== void 0;
|
|
4564
|
+
var isSearchFilterExpression = (expr) => expr.filter !== void 0;
|
|
4565
|
+
var isSearchRangeExpression = (expr) => expr.range !== void 0;
|
|
4566
|
+
var isSearchExactExpression = (expr) => expr.exact !== void 0;
|
|
4567
|
+
var isSearchExistsExpression = (expr) => expr.exists !== void 0;
|
|
4568
|
+
var isSearchFullTextExpression = (expr) => expr.fullText !== void 0;
|
|
4569
|
+
var isSearchFullTextPrefixExpression = (expr) => expr.fullTextPrefix !== void 0;
|
|
4570
|
+
var isSearchPrefixExpression = (expr) => expr.prefix !== void 0;
|
|
4571
|
+
var isSearchWildCardExpression = (expr) => expr.wildcard !== void 0;
|
|
4572
|
+
var isSearchAnyValue = (expr) => expr.value !== void 0;
|
|
4573
|
+
|
|
4574
|
+
// src/priceSelector.ts
|
|
4575
|
+
var applyPriceSelector = (products, selector, noScopedPrice = false) => {
|
|
4576
|
+
validatePriceSelector(selector);
|
|
4577
|
+
for (const product of products) {
|
|
4578
|
+
const variants = [
|
|
4579
|
+
product.masterVariant,
|
|
4580
|
+
...product.variants ?? []
|
|
4581
|
+
].filter((x) => x != void 0);
|
|
4582
|
+
for (const variant of variants) {
|
|
4583
|
+
const scopedPrices = variant.prices?.filter((p) => priceSelectorFilter(p, selector)) ?? [];
|
|
4584
|
+
if (scopedPrices.length > 0) {
|
|
4585
|
+
const price = scopedPrices[0];
|
|
4586
|
+
variant.price = scopedPrices[0];
|
|
4587
|
+
if (!noScopedPrice) {
|
|
4588
|
+
variant.scopedPriceDiscounted = false;
|
|
4589
|
+
variant.scopedPrice = {
|
|
4590
|
+
...price,
|
|
4591
|
+
currentValue: price.value
|
|
4592
|
+
};
|
|
4593
|
+
}
|
|
4594
|
+
}
|
|
4595
|
+
}
|
|
4596
|
+
}
|
|
4597
|
+
};
|
|
4598
|
+
var validatePriceSelector = (selector) => {
|
|
4599
|
+
if ((selector.country || selector.channel || selector.customerGroup) && !selector.currency) {
|
|
4600
|
+
throw new CommercetoolsError(
|
|
4601
|
+
{
|
|
4602
|
+
code: "InvalidInput",
|
|
4603
|
+
message: "The price selecting parameters country, channel and customerGroup cannot be used without the currency."
|
|
4604
|
+
},
|
|
4605
|
+
400
|
|
4606
|
+
);
|
|
4607
|
+
}
|
|
4608
|
+
};
|
|
4609
|
+
var priceSelectorFilter = (price, selector) => {
|
|
4610
|
+
if ((selector.country || price.country) && selector.country !== price.country) {
|
|
4611
|
+
return false;
|
|
4612
|
+
}
|
|
4613
|
+
if ((selector.currency || price.value.currencyCode) && selector.currency !== price.value.currencyCode) {
|
|
4614
|
+
return false;
|
|
4615
|
+
}
|
|
4616
|
+
if ((selector.channel || price.channel?.id) && selector.channel !== price.channel?.id) {
|
|
4617
|
+
return false;
|
|
4618
|
+
}
|
|
4619
|
+
if ((selector.customerGroup || price.customerGroup?.id) && selector.customerGroup !== price.customerGroup?.id) {
|
|
4620
|
+
return false;
|
|
4621
|
+
}
|
|
4622
|
+
return true;
|
|
4623
|
+
};
|
|
4624
|
+
|
|
4625
|
+
// src/product-search.ts
|
|
4626
|
+
var ProductSearch = class {
|
|
4627
|
+
_storage;
|
|
4628
|
+
constructor(storage) {
|
|
4629
|
+
this._storage = storage;
|
|
4630
|
+
}
|
|
4631
|
+
search(projectKey, params) {
|
|
4632
|
+
const resources = this._storage.all(projectKey, "product").map(
|
|
4633
|
+
(r) => this.transform(r, params.productProjectionParameters?.staged ?? false)
|
|
4634
|
+
).filter((p) => {
|
|
4635
|
+
if (!params.productProjectionParameters?.staged) {
|
|
4636
|
+
return p.published;
|
|
4637
|
+
}
|
|
4638
|
+
return true;
|
|
4639
|
+
});
|
|
4640
|
+
if (params.query) {
|
|
4641
|
+
try {
|
|
4642
|
+
validateSearchQuery(params.query);
|
|
4643
|
+
} catch (err) {
|
|
4644
|
+
console.error(err);
|
|
4645
|
+
throw new CommercetoolsError(
|
|
4646
|
+
{
|
|
4647
|
+
code: "InvalidInput",
|
|
4648
|
+
message: err.message
|
|
4649
|
+
},
|
|
4650
|
+
400
|
|
4651
|
+
);
|
|
4652
|
+
}
|
|
4653
|
+
}
|
|
4654
|
+
if (params.productProjectionParameters) {
|
|
4655
|
+
applyPriceSelector(resources, {
|
|
4656
|
+
country: params.productProjectionParameters.priceCountry,
|
|
4657
|
+
channel: params.productProjectionParameters.priceChannel,
|
|
4658
|
+
customerGroup: params.productProjectionParameters.priceCustomerGroup,
|
|
4659
|
+
currency: params.productProjectionParameters.priceCurrency
|
|
4660
|
+
});
|
|
4661
|
+
}
|
|
4662
|
+
const offset = params.offset || 0;
|
|
4663
|
+
const limit = params.limit || 20;
|
|
4664
|
+
const productProjectionsResult = resources.slice(offset, offset + limit);
|
|
4665
|
+
const productProjectionsParameterGiven = !!params?.productProjectionParameters;
|
|
4666
|
+
const results = productProjectionsResult.map(
|
|
4667
|
+
(product) => ({
|
|
4668
|
+
productProjection: productProjectionsParameterGiven ? product : void 0,
|
|
4669
|
+
id: product.id
|
|
4670
|
+
/**
|
|
4671
|
+
* @TODO: possibly add support for optional matchingVariants
|
|
4672
|
+
* https://docs.commercetools.com/api/projects/product-search#productsearchmatchingvariants
|
|
4673
|
+
*/
|
|
4674
|
+
})
|
|
4675
|
+
);
|
|
4676
|
+
return {
|
|
4677
|
+
total: resources.length,
|
|
4678
|
+
offset,
|
|
4679
|
+
limit,
|
|
4680
|
+
results,
|
|
4681
|
+
facets: []
|
|
4682
|
+
};
|
|
4683
|
+
}
|
|
4684
|
+
transform(product, staged) {
|
|
4685
|
+
const obj = !staged ? product.masterData.current : product.masterData.staged;
|
|
4686
|
+
return {
|
|
4687
|
+
id: product.id,
|
|
4688
|
+
createdAt: product.createdAt,
|
|
4689
|
+
lastModifiedAt: product.lastModifiedAt,
|
|
4690
|
+
version: product.version,
|
|
4691
|
+
name: obj.name,
|
|
4692
|
+
key: product.key,
|
|
4693
|
+
description: obj.description,
|
|
4694
|
+
metaDescription: obj.metaDescription,
|
|
4695
|
+
slug: obj.slug,
|
|
4696
|
+
categories: obj.categories,
|
|
4697
|
+
masterVariant: obj.masterVariant,
|
|
4698
|
+
variants: obj.variants,
|
|
4699
|
+
productType: product.productType,
|
|
4700
|
+
hasStagedChanges: product.masterData.hasStagedChanges,
|
|
4701
|
+
published: product.masterData.published
|
|
4702
|
+
};
|
|
4703
|
+
}
|
|
4704
|
+
};
|
|
4705
|
+
|
|
4544
4706
|
// src/repositories/product/helpers.ts
|
|
4545
4707
|
var import_deep_equal2 = __toESM(require("deep-equal"), 1);
|
|
4546
4708
|
var import_uuid10 = require("uuid");
|
|
@@ -5271,9 +5433,11 @@ var ProductUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
5271
5433
|
|
|
5272
5434
|
// src/repositories/product/index.ts
|
|
5273
5435
|
var ProductRepository = class extends AbstractResourceRepository {
|
|
5436
|
+
_searchService;
|
|
5274
5437
|
constructor(storage) {
|
|
5275
5438
|
super("product", storage);
|
|
5276
5439
|
this.actions = new ProductUpdateHandler(storage);
|
|
5440
|
+
this._searchService = new ProductSearch(storage);
|
|
5277
5441
|
}
|
|
5278
5442
|
create(context, draft) {
|
|
5279
5443
|
if (!draft.masterVariant) {
|
|
@@ -5366,6 +5530,9 @@ var ProductRepository = class extends AbstractResourceRepository {
|
|
|
5366
5530
|
};
|
|
5367
5531
|
return this.saveNew(context, resource);
|
|
5368
5532
|
}
|
|
5533
|
+
search(context, searchRequest) {
|
|
5534
|
+
return this._searchService.search(context.projectKey, searchRequest);
|
|
5535
|
+
}
|
|
5369
5536
|
};
|
|
5370
5537
|
|
|
5371
5538
|
// src/repositories/product-discount.ts
|
|
@@ -5449,57 +5616,6 @@ var ProductDiscountUpdateHandler = class extends AbstractUpdateHandler {
|
|
|
5449
5616
|
}
|
|
5450
5617
|
};
|
|
5451
5618
|
|
|
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
5619
|
// src/lib/projectionSearchFilter.ts
|
|
5504
5620
|
var parseFilterExpression = (filter) => {
|
|
5505
5621
|
const exprFunc = generateMatchFunc2(filter);
|
|
@@ -8004,6 +8120,17 @@ var ProductService = class extends AbstractService {
|
|
|
8004
8120
|
getBasePath() {
|
|
8005
8121
|
return "products";
|
|
8006
8122
|
}
|
|
8123
|
+
extraRoutes(router) {
|
|
8124
|
+
router.post("/search", this.search.bind(this));
|
|
8125
|
+
}
|
|
8126
|
+
search(request, response) {
|
|
8127
|
+
const searchBody = request.body;
|
|
8128
|
+
const resource = this.repository.search(
|
|
8129
|
+
getRepositoryContext(request),
|
|
8130
|
+
searchBody
|
|
8131
|
+
);
|
|
8132
|
+
return response.status(200).send(resource);
|
|
8133
|
+
}
|
|
8007
8134
|
};
|
|
8008
8135
|
|
|
8009
8136
|
// src/services/product-discount.ts
|