SearchProducts
Implements SearchProducts
Unified Method.
Source
/* eslint-disable no-secrets/no-secrets */
/* eslint-disable max-statements */
import { defineApi } from "@vsf-enterprise/unified-api-sapcc";
import type { SapccIntegrationContext } from "@vsf-enterprise/sapcc-api";
import {
type SearchProducts,
type SearchProductsArgs,
getNormalizers,
assignToNormalizerContext,
} from "@vsf-enterprise/unified-api-sapcc/udl";
import { buildFilters, buildProductsResponse, buildQueryString } from "@vsf-enterprise/unified-api-sapcc";
declare module "@vsf-enterprise/unified-api-sapcc" {
interface SearchProductsExtendedArgs {
/**
* Response configuration. List of fields returned in the response body.
*/
fields?: "BASIC" | "DEFAULT" | "FULL" | string | string[];
/**
* Parameter allowing us to pass on a raw query string expected by SAP OCC API.
*
* @remarks
* Useful whenever SAP Commerce Cloud gives us ready-to-use search queries (such as the ones
* in {@link @vsf-enterprise/sap-commerce-webservices-sdk#FacetValue | FacetValues}). When you use the `query` parameter, other
* query-building parameters such `filters`, `searchTerm` and `sort` are ignored.
*
* @example
* ```ts
* const query = ':undefined:allCategories:collections:allCategories:brands:reviewAvgRating:4.4';
* ```
*/
query?: string;
/**
* The context to be used in the search query.
*/
searchQueryContext?: string;
}
}
export const searchProducts = defineApi.searchProducts(async (context, args) => {
try {
return await searchProductsByQuery(context, args);
} catch (error) {
console.error("/searchProducts", error);
return {
products: [],
pagination: {
currentPage: 0,
pageSize: 0,
totalResults: 0,
totalPages: 0,
},
facets: [],
};
}
});
function translateSort(sortBy: SearchProductsArgs["sortBy"]) {
switch (sortBy) {
case "relevant": {
return "relevance";
}
case "price-low-to-high": {
return "price-asc";
}
case "price-high-to-low": {
return "price-desc";
}
default: {
return sortBy;
}
}
}
async function searchProductsByQuery(
context: SapccIntegrationContext,
{ search, sortBy, facets: facetsQuery, category, currentPage = 1, pageSize }: SearchProductsArgs,
): ReturnType<SearchProducts> {
const filters = buildFilters({ category, facets: facetsQuery });
const { filterFacets = () => true } = context.config.unified;
const { normalizePagination, normalizeFacet } = getNormalizers(context);
const sort = translateSort(sortBy);
const searchTerm = search;
const { data: searchProductResponse } = await context.api.getProducts({
currentPage: Math.max(currentPage - 1, 0),
pageSize,
sort,
query: buildQueryString({ searchTerm, filters, sort }),
});
const {
facets: rawFacets = [],
products: rawProducts = [],
pagination: rawPagination = {},
currentQuery,
} = searchProductResponse;
assignToNormalizerContext(context, {
currentQuery,
});
return {
pagination: normalizePagination(rawPagination),
facets: rawFacets
.filter((facet) => filterFacets(facet))
.map((facet) => normalizeFacet(facet))
.filter(Boolean),
...buildProductsResponse(context, rawProducts),
};
}