diff --git a/packages/shopper-common/package.json b/packages/shopper-common/package.json index d7e6e5ef..35719e1d 100644 --- a/packages/shopper-common/package.json +++ b/packages/shopper-common/package.json @@ -38,6 +38,7 @@ }, "dependencies": { "@elasticpath/js-sdk": "5.0.0", + "@epcc-sdk/sdks-shopper": "workspace:*", "tslib": "^2.6.2" }, "publishConfig": { diff --git a/packages/shopper-common/src/navigation/build-navigation.ts b/packages/shopper-common/src/navigation/build-navigation.ts index 5e0678fb..7cfe685e 100644 --- a/packages/shopper-common/src/navigation/build-navigation.ts +++ b/packages/shopper-common/src/navigation/build-navigation.ts @@ -1,17 +1,31 @@ -import type { Hierarchy, ElasticPath } from "@elasticpath/js-sdk" -import { - getHierarchies, - getHierarchyChildren, - getHierarchyNodes, -} from "./services/hierarchy" +import type { Client, Hierarchy } from "@epcc-sdk/sdks-shopper" import { ISchema, NavigationNode } from "./navigation-types" +import { + getByContextAllHierarchies, + getByContextHierarchyChildNodes, + getByContextHierarchyNodes, +} from "@epcc-sdk/sdks-shopper" export async function buildSiteNavigation( - client: ElasticPath, + client?: Client, ): Promise { // Fetch hierarchies to be used as top level nav - const hierarchies = await getHierarchies(client) - return constructTree(hierarchies, client) + const hierarchiesResponse = await getByContextAllHierarchies({ + client, + body: undefined, + query: { + "page[limit]": 100, + "page[offset]": 0, + }, + }) + + if (!hierarchiesResponse.response.ok) { + throw new Error("Failed to fetch hierarchies") + } + + const hierarchies = hierarchiesResponse.data?.data + + return hierarchies ? constructTree(hierarchies, client) : [] } /** @@ -19,40 +33,76 @@ export async function buildSiteNavigation( */ function constructTree( hierarchies: Hierarchy[], - client: ElasticPath, + client?: Client, ): Promise { const tree = hierarchies .slice(0, 4) .map((hierarchy) => createNode({ - name: hierarchy.attributes.name, - id: hierarchy.id, - slug: hierarchy.attributes.slug, + name: hierarchy.attributes?.name!, + id: hierarchy.id!, + slug: hierarchy.attributes?.slug, }), ) .map(async (hierarchy) => { // Fetch first-level nav ('parent nodes') - the direct children of each hierarchy - const directChildren = await getHierarchyChildren(hierarchy.id, client) + const directChildrenResponse = await getByContextHierarchyChildNodes({ + client, + body: undefined, + path: { + hierarchy_id: hierarchy.id, + }, + query: { + "page[limit]": 100, + "page[offset]": 0, + }, + }) + + if (!directChildrenResponse.response.ok) { + throw new Error("Failed to fetch hierarchy children") + } + + const directChildren = directChildrenResponse.data?.data ?? [] + // Fetch all nodes in each hierarchy (i.e. all 'child nodes' belonging to a hierarchy) - const allNodes = await getHierarchyNodes(hierarchy.id, client) + const allNodesResponse = await getByContextHierarchyNodes({ + client, + body: undefined, + path: { + hierarchy_id: hierarchy.id, + }, + query: { + "page[limit]": 100, + "page[offset]": 0, + }, + }) + + if (!allNodesResponse.response.ok) { + throw new Error("Failed to fetch hierarchy nodes") + } + + const allNodes = allNodesResponse.data?.data ?? [] // Build 2nd level by finding all 'child nodes' belonging to each first level featured-nodes - const directs = directChildren.slice(0, 4).map((child) => { - const children: ISchema[] = allNodes - .filter((node) => node?.relationships?.parent.data.id === child.id) - .map((node) => - createNode({ - name: node.attributes.name, - id: node.id, - slug: node.attributes.slug, - hrefBase: `${hierarchy.href}/${child.attributes.slug}`, - }), - ) + const directs = directChildren?.slice(0, 4).map((child) => { + const children: ISchema[] = + allNodes + ?.filter( + (node) => node?.relationships?.parent?.data.id === child.id, + ) + .map((node) => + createNode({ + name: node.attributes?.name!, + id: node.id!, + slug: node.attributes?.slug, + hrefBase: `${hierarchy.href}/${child.attributes?.slug}`, + }), + ) ?? [] return createNode({ - name: child.attributes.name, - id: child.id, - slug: child.attributes.slug, + name: child.attributes?.name!, + id: child.id!, + slug: child.attributes?.slug, hrefBase: hierarchy.href, children, }) diff --git a/packages/shopper-common/src/navigation/services/hierarchy.ts b/packages/shopper-common/src/navigation/services/hierarchy.ts deleted file mode 100644 index ed346b49..00000000 --- a/packages/shopper-common/src/navigation/services/hierarchy.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { Node, Hierarchy } from "@elasticpath/js-sdk" -import { ElasticPath } from "@elasticpath/js-sdk" - -export async function getHierarchies( - client: ElasticPath, -): Promise { - const result = await client.ShopperCatalog.Hierarchies.All() - return result.data -} - -export async function getHierarchyChildren( - hierarchyId: string, - client: ElasticPath, -): Promise { - const result = await client.ShopperCatalog.Hierarchies.GetHierarchyChildren({ - hierarchyId, - }) - return result.data -} - -export async function getHierarchyNodes( - hierarchyId: string, - client: ElasticPath, -): Promise { - const result = await client.ShopperCatalog.Hierarchies.GetHierarchyNodes({ - hierarchyId, - }) - - return result.data -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6fe8aad1..35f62616 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1258,8 +1258,8 @@ importers: packages/sdks/nextjs: dependencies: '@hey-api/client-fetch': - specifier: ^0.1.7 - version: 0.1.14 + specifier: ^0.2.4 + version: 0.2.4 devDependencies: next: specifier: ^14.0.0 @@ -1296,6 +1296,9 @@ importers: '@redocly/openapi-core': specifier: ^1.21.0 version: 1.21.0 + '@tanstack/react-query': + specifier: ^5.52.1 + version: 5.52.1(react@18.3.1) lodash: specifier: ^4.17.21 version: 4.17.21 @@ -1308,6 +1311,9 @@ importers: '@elasticpath/js-sdk': specifier: 5.0.0 version: 5.0.0(encoding@0.1.13) + '@epcc-sdk/sdks-shopper': + specifier: workspace:* + version: link:../sdks/shopper tslib: specifier: ^2.6.2 version: 2.6.2 @@ -10933,6 +10939,10 @@ packages: /@tanstack/query-core@5.51.21: resolution: {integrity: sha512-POQxm42IUp6n89kKWF4IZi18v3fxQWFRolvBA6phNVmA8psdfB1MvDnGacCJdS+EOX12w/CyHM62z//rHmYmvw==} + /@tanstack/query-core@5.52.0: + resolution: {integrity: sha512-U1DOEgltjUwalN6uWYTewSnA14b+tE7lSylOiASKCAO61ENJeCq9VVD/TXHA6O5u9+6v5+UgGYBSccTKDoyMqw==} + dev: true + /@tanstack/query-devtools@5.32.1: resolution: {integrity: sha512-7Xq57Ctopiy/4atpb0uNY5VRuCqRS/1fi/WBCKKX6jHMa6cCgDuV/AQuiwRXcKARbq2OkVAOrW2v4xK9nTbcCA==} dev: true @@ -10956,6 +10966,15 @@ packages: '@tanstack/query-core': 5.51.21 react: 18.3.1 + /@tanstack/react-query@5.52.1(react@18.3.1): + resolution: {integrity: sha512-soyn4dNIUZ8US8NaPVXv06gkZFHaZnPfKWPDjRJjFRW3Y7WZ0jx72eT6zhw3VQlkMPysmXye8l35ewPHspKgbQ==} + peerDependencies: + react: ^18 || ^19 + dependencies: + '@tanstack/query-core': 5.52.0 + react: 18.3.1 + dev: true + /@testing-library/dom@9.3.3: resolution: {integrity: sha512-fB0R+fa3AUqbLHWyxXa2kGVtf1Fe1ZZFr0Zp6AIbIAzXb2mKbEXl+PCQNUOaq5lbTab5tfctfXRNsWXxa2f7Aw==} engines: {node: '>=14'}