Skip to content

Commit

Permalink
Adjust infra to fetch menu
Browse files Browse the repository at this point in the history
  • Loading branch information
soniaklimas committed Nov 6, 2024
1 parent 34fa70f commit d648acc
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 64 deletions.
5 changes: 5 additions & 0 deletions apps/storefront/src/services/cms.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { butterCMSMenuService } from "@nimara/infrastructure/public/butter-cms/cms-menu/providers";
import { butterCMSPageService } from "@nimara/infrastructure/public/butter-cms/cms-page/providers";
import { saleorCMSMenuService } from "@nimara/infrastructure/public/saleor/cms-menu/providers";
import { saleorCMSPageService } from "@nimara/infrastructure/public/saleor/cms-page/providers";
Expand All @@ -18,6 +19,10 @@ export const cmsPageServiceButterCMS = butterCMSPageService({
token: clientEnvs.NEXT_PUBLIC_BUTTER_CMS_API_KEY,
});

export const cmsMenuServiceButterCMS = butterCMSMenuService({
token: clientEnvs.NEXT_PUBLIC_BUTTER_CMS_API_KEY,
});

export const cmsPageService: CMSPageService = cmsPageServiceSaleor;

export const cmsMenuService: CMSMenuService = cmsMenuServiceSaleor;
26 changes: 18 additions & 8 deletions packages/domain/src/objects/Menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ type Product = {
id: string;
};

type Category = {
export type Category = {
id: string;
name: string;
products: {
products?: {
edges: {
node: Product;
}[];
} | null;
slug: string;
translation: { name: string | null } | null;
translation?: { name: string | null } | null;
};

type Collection = {
Expand All @@ -28,25 +28,35 @@ type Collection = {
translation: { name: string | null } | null;
};

type Page = {
export type Page = {
id: string;
slug: string;
title: string;
translation: { title: string | null } | null;
translation?: { title: string | null } | null;
};

export type MenuItem = {
category: Category | null;
children?: MenuItem[] | null;
collection: Collection | null;
collection?: Collection | null;
id: string;
level: number;
level?: number;
name: string;
page: Page | null;
translation: { name: string } | null;
translation?: { name: string } | null;
url: string | null;
};

export type Menu = {
items: MenuItem[];
};

export type ButterCMSMenuItem = {
category: string[];
meta: {
id: string;
};
name: string;
page: string;
url: string;
};
109 changes: 109 additions & 0 deletions packages/infrastructure/src/lib/serializers/cms-menu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import type {
ButterCMSMenuItem,
Category,
Menu,
MenuItem,
Page,
} from "@nimara/domain/objects/Menu";

import type { MenuGet_menu_Menu_items_MenuItem } from "#root/public/saleor/cms-menu/graphql/queries/generated";

const serializeSaleorMenuItem = ({
id,
name,
translation,
level,
url,
category,
collection,
page,
children,
}: MenuGet_menu_Menu_items_MenuItem): MenuItem => {
return {
id,
name: translation?.name || name,
translation,
level,
url,
category: category
? {
...category,
name: category.translation?.name || category.name,
}
: null,
collection: collection
? {
...collection,
name: collection.translation?.name || collection.name,
}
: null,
page: page
? {
...page,
title: page.translation?.title || page.title,
}
: null,
children,
};
};

const serializeButterCMSMenuItem = (items: ButterCMSMenuItem[]): MenuItem[] => {
return items.map((item) => {
const categoryId = item.category.length
? item.category[0].split("category[_id=")[1]?.split("]")[0] || ""
: "";

const category: Category | null = categoryId
? {
id: categoryId,
name: item.name,
slug: item.name.toLowerCase(),
translation: null,
}
: null;

const pageSlug =
typeof item.page === "string"
? item.page.split("/").filter(Boolean).pop() || ""
: "";
const page: Page | null = item.page
? {
id: item.meta.id.toString(),
slug: pageSlug,
title: item.name,
translation: null,
}
: null;

return {
id: item.meta.id.toString(),
name: item.name,
translation: null,
level: 0,
url: item.url,
category,
collection: null,
page,
children: null,
};
});
};

export const serializeMenu = (
items: MenuGet_menu_Menu_items_MenuItem[] | ButterCMSMenuItem[],
source: "saleor" | "butterCms",
): Menu => {
if (source === "saleor") {
return {
items: (items as MenuGet_menu_Menu_items_MenuItem[]).map(
serializeSaleorMenuItem,
),
};
} else if (source === "butterCms") {
return {
items: serializeButterCMSMenuItem(items as ButterCMSMenuItem[]),
};
}

return { items: [] };
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import Butter from "buttercms/lib/butter";

import type { ButterCMSMenuItem } from "@nimara/domain/objects/Menu";

import { serializeMenu } from "#root/lib/serializers/cms-menu";
import { convertLanguageCode } from "#root/lib/serializers/cms-page";
import type { CMSMenuGetInfra } from "#root/use-cases/cms-menu/types";

import type { ButterCMSMenuServiceConfig } from "../types";

export const butterCMSMenuGetInfra =
({ token }: ButterCMSMenuServiceConfig): CMSMenuGetInfra =>
async ({ languageCode, slug }) => {
const locale = languageCode ? convertLanguageCode(languageCode) : undefined;

// Using `as any` to bypass TypeScript's deep type inference issues with ButterCMS types.
const menu = await (Butter(token).content as any).retrieve(
["navigation_menu"],
locale ? { locale } : undefined,
);

if (!menu?.data?.data?.navigation_menu) {
return null;
}

const selectedMenu = menu.data.data.navigation_menu.find(
(menu: ButterCMSMenuItem) =>
menu.name.toLowerCase() === slug?.toLowerCase(),
);

return {
menu: serializeMenu(
selectedMenu.menu_items as ButterCMSMenuItem[],
"butterCms",
),
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { cmsMenuGetUseCase } from "#root/use-cases/cms-menu/cms-menu-get-use-case";
import type { CMSMenuService } from "#root/use-cases/cms-menu/types";

import { butterCMSMenuGetInfra } from "./infrastructure/cms-menu-get-infra";
import type { ButterCMSMenuServiceConfig } from "./types";

export const butterCMSMenuService = (config: ButterCMSMenuServiceConfig) =>
({
menuGet: cmsMenuGetUseCase({
cmsMenuGetInfra: butterCMSMenuGetInfra(config),
}),
}) satisfies CMSMenuService;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export type ButterCMSMenuServiceConfig = {
token: string;
};
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import {
convertLanguageCode,
parseDataToCMSFields,
} from "#root/lib/serializers/cmsData";
} from "#root/lib/serializers/cms-page";
import type { CMSPageGetInfra } from "#root/use-cases/cms-page/types";

import type { ButterCMSPageServiceConfig } from "../types";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,59 +1,10 @@
import type { Menu, MenuItem } from "@nimara/domain/objects/Menu";

import { graphqlClient } from "#root/graphql/client";
import { serializeMenu } from "#root/lib/serializers/cms-menu";
import type { CMSMenuGetInfra } from "#root/use-cases/cms-menu/types";

import {
type MenuGet_menu_Menu_items_MenuItem,
MenuGetDocument,
} from "../graphql/queries/generated";
import { MenuGetDocument } from "../graphql/queries/generated";
import type { SaleorCMSMenuServiceConfig } from "../types";

const serializeMenuItem = ({
id,
name,
translation,
level,
url,
category,
collection,
page,
children,
}: MenuGet_menu_Menu_items_MenuItem): MenuItem => {
return {
id,
name: translation?.name || name,
translation,
level,
url,
category: category
? {
...category,
name: category.translation?.name || category.name,
}
: null,
collection: collection
? {
...collection,
name: collection.translation?.name || collection.name,
}
: null,
page: page
? {
...page,
title: page.translation?.title || page.title,
}
: null,
children,
};
};

const serializeMenu = (items: MenuGet_menu_Menu_items_MenuItem[]): Menu => {
return {
items: items.map(serializeMenuItem),
};
};

export const saleorCMSMenuGetInfra =
({ apiURL }: SaleorCMSMenuServiceConfig): CMSMenuGetInfra =>
async ({ channel, languageCode, slug, id, options }) => {
Expand All @@ -67,9 +18,9 @@ export const saleorCMSMenuGetInfra =
},
});

if (data?.menu) {
return { menu: serializeMenu(data.menu.items || []) };
if (!data?.menu) {
return null;
}

return null;
return { menu: serializeMenu(data.menu.items || [], "saleor") };
};
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { graphqlClient } from "#root/graphql/client";
import { parseDataToCMSFields } from "#root/lib/serializers/cmsData";
import { parseDataToCMSFields } from "#root/lib/serializers/cms-page";
import type { CMSPageGetInfra } from "#root/use-cases/cms-page/types";

import { PageDocument } from "../graphql/queries/generated";
Expand Down

0 comments on commit d648acc

Please sign in to comment.