Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
jsm1t committed Aug 15, 2024
1 parent d60e09c commit 7c9f1f1
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib/productSearchFilter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type ProductSearchFilterFunc = (
markMatchingVariants: boolean,
) => boolean;

// TODO: fieldType checking, better text/wildcard search, result boosting
export const parseSearchQuery = (searchQuery: _SearchQuery): ProductSearchFilterFunc => {
if (isSearchAndExpression(searchQuery)) {
return (obj, markMatchingVariant) => searchQuery.and.every((expr) => {
Expand Down
100 changes: 100 additions & 0 deletions src/product-search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { InvalidInputError, Product, ProductPagedSearchResponse, ProductProjection, ProductSearchRequest } from "@commercetools/platform-sdk";
import { AbstractStorage } from "./storage";
import { CommercetoolsError } from "./exceptions";
import { parseSearchQuery } from "./lib/productSearchFilter";
import { applyPriceSelector } from "./priceSelector";

export class ProductSearch {
protected _storage: AbstractStorage;

constructor(storage: AbstractStorage) {
this._storage = storage;
}

search(
projectKey: string,
params: ProductSearchRequest,
): ProductPagedSearchResponse {
let resources = this._storage
.all(projectKey, "product")
.map((r) => this.transform(r, params.productProjectionParameters?.staged ?? false))
.filter((p) => {
if (!params.productProjectionParameters?.staged ?? false) {
return p.published;
}
return true;
});

const markMatchingVariant = params.markMatchingVariants ?? false;

// Apply filters pre facetting
if (params.query) {
try {
const matchFunc = parseSearchQuery(params.query);

// Filters can modify the output. So clone the resources first.
resources = resources.filter((resource) =>
matchFunc(resource, markMatchingVariant),
);
} catch (err) {
console.error(err);
throw new CommercetoolsError<InvalidInputError>(
{
code: "InvalidInput",
message: (err as any).message,
},
400,
);
}
}

// Apply the priceSelector
if (params.productProjectionParameters) {
applyPriceSelector(resources, {
country: params.productProjectionParameters.priceCountry,
channel: params.productProjectionParameters.priceChannel,
customerGroup: params.productProjectionParameters.priceCustomerGroup,
currency: params.productProjectionParameters.priceCurrency,
});
}

// TODO: Calculate facets
// TODO: sorting based on boosts

const offset = params.offset || 0;
const limit = params.limit || 20;
const results = resources.slice(offset, offset + limit);

return {
total: resources.length,
offset: offset,
limit: limit,
results: results,
facets: [],
};
}

transform(product: Product, staged: boolean): ProductProjection {
const obj = !staged
? product.masterData.current
: product.masterData.staged;

return {
id: product.id,
createdAt: product.createdAt,
lastModifiedAt: product.lastModifiedAt,
version: product.version,
name: obj.name,
key: product.key,
description: obj.description,
metaDescription: obj.metaDescription,
slug: obj.slug,
categories: obj.categories,
masterVariant: obj.masterVariant,
variants: obj.variants,
productType: product.productType,
hasStagedChanges: product.masterData.hasStagedChanges,
published: product.masterData.published,
};
}
}

0 comments on commit 7c9f1f1

Please sign in to comment.