GetCategories
Implements GetCategories
Unified Method.
Source
import { defineApi } from "@vsf-enterprise/unified-api-sfcc";
import type { Category } from "@vsf-enterprise/sfcc-types";
import type { GetCategoriesArgs } from "@vsf-enterprise/unified-api-sfcc/udl";
import { getNormalizers } from "@vue-storefront/unified-data-model";
import { slugify } from "@vsf-enterprise/unified-api-sfcc";
declare module "@vsf-enterprise/unified-api-sfcc" {
interface GetCategoriesExtendedArgs {
/**
* The nesting depth of subcategories to get
* @default 0
*/
levels?: number;
}
}
export const getCategories = defineApi.getCategories(async (context, args) => {
const rootCategory = await context.api.getCategory({ id: "root", levels: 10 });
const { normalizeCategory } = getNormalizers(context);
const filteredData = filterCategories(rootCategory.categories || [], {
ids: args?.ids ?? [],
slugs: args?.slugs ?? [],
});
return filteredData.map((category) => normalizeCategory(category));
});
function filterCategories(
categories: Category[],
args: Required<Pick<GetCategoriesArgs, "ids" | "slugs">>,
): Category[] {
const { ids, slugs } = args;
let filteredData = categories;
if (ids.length > 0 || slugs.length > 0) {
filteredData = flattenCategories(categories);
const idsSet = ids ? new Set(ids) : null;
const slugsSet = slugs ? new Set(slugs) : null;
filteredData = filteredData.filter((category) => {
const idMatches = !idsSet || idsSet.has(category.id as string);
const slugMatches = !slugsSet || slugsSet.has(slugify(category.id));
return idMatches || slugMatches;
});
}
return filteredData;
}
function flattenCategories(categories: Category[]): Category[] {
return categories.flatMap((category) => [
category,
...(category.categories ? flattenCategories(category.categories) : []),
]);
}