diff --git a/functions/productIdFromVTEXSlug.ts b/functions/productIdFromVTEXSlug.ts new file mode 100644 index 00000000..aeff2720 --- /dev/null +++ b/functions/productIdFromVTEXSlug.ts @@ -0,0 +1,26 @@ +import type { FunctionContext, LoaderFunction } from "$live/types.ts"; +import type { RequestURLParam } from "./requestToParam.ts"; + +export type ProductID = string; + +export interface Props { + /** + * @default slug + * @description Param name to extract from the Request URL + */ + slug: RequestURLParam; +} + +/** + * @title Extract ID from request parameters + * @description Set param to slug for routes of type /:slug + */ +const productIdFromVTEXSlug: LoaderFunction< + Props, + ProductID, + FunctionContext +> = (_req, _ctx, { slug }) => { + return { data: slug.split("-").at(-1) ?? "" }; +}; + +export default productIdFromVTEXSlug; diff --git a/live.gen.ts b/live.gen.ts index f6f9b5a6..e64d3b53 100644 --- a/live.gen.ts +++ b/live.gen.ts @@ -12,24 +12,25 @@ import * as $5 from "./functions/butterCMSPostDetail.ts"; import * as $6 from "./functions/vndaProductDetailsPage.ts"; import * as $7 from "./functions/vtexLegacyProductDetailsPage.ts"; import * as $8 from "./functions/vtexSuggestions.ts"; -import * as $9 from "./functions/vtexNavbar.ts"; -import * as $10 from "./functions/butterCMSPlaces.ts"; -import * as $11 from "./functions/vtexWishlist.ts"; -import * as $12 from "./functions/shopifyProductListingPage.ts"; -import * as $13 from "./functions/vtexProductList.ts"; -import * as $14 from "./functions/butterCMSFeaturedPosts.ts"; -import * as $15 from "./functions/occProductDetailsPage.ts"; -import * as $16 from "./functions/butterCMSBrands.ts"; -import * as $17 from "./functions/vndaProductListingPage.ts"; -import * as $18 from "./functions/butterCMSRelatedPosts.ts"; -import * as $19 from "./functions/vtexLegacyProductListingPage.ts"; -import * as $20 from "./functions/vtexProductDetailsPage.ts"; -import * as $21 from "./functions/vtexLegacyProductList.ts"; -import * as $22 from "./functions/butterCMSCategories.ts"; -import * as $23 from "./functions/shopifyProductList.ts"; -import * as $24 from "./functions/shopifyProductDetailsPage.ts"; -import * as $25 from "./functions/vtexLegacyRelatedProductsLoader.ts"; -import * as $26 from "./functions/requestToParam.ts"; +import * as $9 from "./functions/productIdFromVTEXSlug.ts"; +import * as $10 from "./functions/vtexNavbar.ts"; +import * as $11 from "./functions/butterCMSPlaces.ts"; +import * as $12 from "./functions/vtexWishlist.ts"; +import * as $13 from "./functions/shopifyProductListingPage.ts"; +import * as $14 from "./functions/vtexProductList.ts"; +import * as $15 from "./functions/butterCMSFeaturedPosts.ts"; +import * as $16 from "./functions/occProductDetailsPage.ts"; +import * as $17 from "./functions/butterCMSBrands.ts"; +import * as $18 from "./functions/vndaProductListingPage.ts"; +import * as $19 from "./functions/butterCMSRelatedPosts.ts"; +import * as $20 from "./functions/vtexLegacyProductListingPage.ts"; +import * as $21 from "./functions/vtexProductDetailsPage.ts"; +import * as $22 from "./functions/vtexLegacyProductList.ts"; +import * as $23 from "./functions/butterCMSCategories.ts"; +import * as $24 from "./functions/shopifyProductList.ts"; +import * as $25 from "./functions/shopifyProductDetailsPage.ts"; +import * as $26 from "./functions/vtexLegacyRelatedProductsLoader.ts"; +import * as $27 from "./functions/requestToParam.ts"; import * as $$0 from "./accounts/butterCMS.ts"; import * as $$1 from "./accounts/linxImpulse.ts"; import * as $$2 from "./accounts/vnda.ts"; @@ -153,32 +154,33 @@ import * as i1$$$$$$$2 from "$live/actions/workflows/start.ts"; const manifest = { "functions": { "deco-sites/std/functions/butterCMSAds.ts": $4, - "deco-sites/std/functions/butterCMSBrands.ts": $16, - "deco-sites/std/functions/butterCMSCategories.ts": $22, - "deco-sites/std/functions/butterCMSFeaturedPosts.ts": $14, + "deco-sites/std/functions/butterCMSBrands.ts": $17, + "deco-sites/std/functions/butterCMSCategories.ts": $23, + "deco-sites/std/functions/butterCMSFeaturedPosts.ts": $15, "deco-sites/std/functions/butterCMSPage.ts": $1, - "deco-sites/std/functions/butterCMSPlaces.ts": $10, + "deco-sites/std/functions/butterCMSPlaces.ts": $11, "deco-sites/std/functions/butterCMSPostDetail.ts": $5, "deco-sites/std/functions/butterCMSPosts.ts": $0, - "deco-sites/std/functions/butterCMSRelatedPosts.ts": $18, - "deco-sites/std/functions/occProductDetailsPage.ts": $15, - "deco-sites/std/functions/requestToParam.ts": $26, - "deco-sites/std/functions/shopifyProductDetailsPage.ts": $24, - "deco-sites/std/functions/shopifyProductList.ts": $23, - "deco-sites/std/functions/shopifyProductListingPage.ts": $12, + "deco-sites/std/functions/butterCMSRelatedPosts.ts": $19, + "deco-sites/std/functions/occProductDetailsPage.ts": $16, + "deco-sites/std/functions/productIdFromVTEXSlug.ts": $9, + "deco-sites/std/functions/requestToParam.ts": $27, + "deco-sites/std/functions/shopifyProductDetailsPage.ts": $25, + "deco-sites/std/functions/shopifyProductList.ts": $24, + "deco-sites/std/functions/shopifyProductListingPage.ts": $13, "deco-sites/std/functions/vndaProductDetailsPage.ts": $6, "deco-sites/std/functions/vndaProductList.ts": $3, - "deco-sites/std/functions/vndaProductListingPage.ts": $17, + "deco-sites/std/functions/vndaProductListingPage.ts": $18, "deco-sites/std/functions/vtexLegacyProductDetailsPage.ts": $7, - "deco-sites/std/functions/vtexLegacyProductList.ts": $21, - "deco-sites/std/functions/vtexLegacyProductListingPage.ts": $19, - "deco-sites/std/functions/vtexLegacyRelatedProductsLoader.ts": $25, - "deco-sites/std/functions/vtexNavbar.ts": $9, - "deco-sites/std/functions/vtexProductDetailsPage.ts": $20, - "deco-sites/std/functions/vtexProductList.ts": $13, + "deco-sites/std/functions/vtexLegacyProductList.ts": $22, + "deco-sites/std/functions/vtexLegacyProductListingPage.ts": $20, + "deco-sites/std/functions/vtexLegacyRelatedProductsLoader.ts": $26, + "deco-sites/std/functions/vtexNavbar.ts": $10, + "deco-sites/std/functions/vtexProductDetailsPage.ts": $21, + "deco-sites/std/functions/vtexProductList.ts": $14, "deco-sites/std/functions/vtexProductListingPage.ts": $2, "deco-sites/std/functions/vtexSuggestions.ts": $8, - "deco-sites/std/functions/vtexWishlist.ts": $11, + "deco-sites/std/functions/vtexWishlist.ts": $12, }, "accounts": { "deco-sites/std/accounts/butterCMS.ts": $$0, diff --git a/packs/linxImpulse/loaders/products/similarItems.ts b/packs/linxImpulse/loaders/products/similarItems.ts index 1dbd9963..a2267ab2 100644 --- a/packs/linxImpulse/loaders/products/similarItems.ts +++ b/packs/linxImpulse/loaders/products/similarItems.ts @@ -1,32 +1,23 @@ import type { Product } from "deco-sites/std/commerce/types.ts"; -import type { RequestURLParam } from "deco-sites/std/functions/requestToParam.ts"; +import type { ProductID } from "deco-sites/std/functions/productIdFromVTEXSlug.ts"; import type { PagesRecommendationsResponse, - Position, SearchProductsResponse, + Shelf, } from "deco-sites/std/packs/linxImpulse/types.ts"; +import type { Context } from "deco-sites/std/packs/linxImpulse/accounts/linxImpulse.ts"; +import { paths } from "deco-sites/std/packs/linxImpulse/utils/path.ts"; import { toProduct, toProductLinxImpulse, toRequestHeader, } from "deco-sites/std/packs/linxImpulse/utils/transform.ts"; -import { paths } from "deco-sites/std/packs/linxImpulse/utils/path.ts"; -import type { Context } from "deco-sites/std/packs/linxImpulse/accounts/linxImpulse.ts"; -import { fetchAPI } from "deco-sites/std/utils/fetch.ts"; import { HttpError } from "deco-sites/std/utils/HttpError.ts"; +import { fetchAPI } from "deco-sites/std/utils/fetch.ts"; export interface Props { - slug: RequestURLParam; - - /** - * @title Position - */ - position: Position; - - /** - * @title Feature - */ + id: ProductID; feature: "SimilarItems" | "FrequentlyBoughtTogether"; } @@ -40,16 +31,15 @@ const loader = async ( ctx: Context, ): Promise => { const { configLinxImpulse: config } = ctx; - const { slug, position, feature } = props; + const { id, feature } = props; const url = new URL(req.url); const skuId = url.searchParams.get("skuId"); const requestHeaders = toRequestHeader(config!); + const linxImpulse = paths(config!); try { - const linxImpulse = paths(config!); - const productSlug = slug.replaceAll("-", " "); const { products: productsBySlug } = await fetchAPI( - `${linxImpulse.product.getProductBySlug.term(productSlug)}`, + `${linxImpulse.product.getProductBySlug.term(id)}`, { headers: requestHeaders }, ); @@ -65,17 +55,14 @@ const loader = async ( `${linxImpulse.product.similarItems.productId(product.id)}`, { headers: requestHeaders }, ); - let shelfs; - if (position) { - shelfs = recommendationsResponse[position]; - } - - if (feature) { - shelfs = shelfs?.filter((shelf) => shelf.feature === feature); - } + const checkFeature = (shelf: Shelf) => shelf.feature === feature; + const topShelfs = recommendationsResponse.top.filter(checkFeature); + const middleShelfs = recommendationsResponse.middle.filter(checkFeature); + const bottomShelfs = recommendationsResponse.bottom.filter(checkFeature); + const shelfs = [...topShelfs, ...middleShelfs, ...bottomShelfs]; - if (!shelfs) return null; + if (!shelfs.length) return null; const options = { baseUrl: req.url, diff --git a/packs/linxImpulse/utils/path.ts b/packs/linxImpulse/utils/path.ts index 3a206b32..4374d871 100644 --- a/packs/linxImpulse/utils/path.ts +++ b/packs/linxImpulse/utils/path.ts @@ -27,7 +27,7 @@ export const paths = ({ apiKey, secretKey }: Account) => { product: { getProductBySlug: { term: (term: string) => - `${searchBaseUrl}/search?apiKey=${apiKey}&productFormat=complete&terms=${term}&hide=quickFilters&hide=suggestions&hide=filters`, + `${searchBaseUrl}/search?apiKey=${apiKey}&productFormat=complete&terms=${term}&hide=quickFilters&hide=suggestions&hide=filters&resultsPerPage=1`, }, similarItems: { productId: (productId: string) => diff --git a/schemas.gen.json b/schemas.gen.json index 3c8b41c8..237a63e5 100644 --- a/schemas.gen.json +++ b/schemas.gen.json @@ -22,6 +22,7 @@ "deco-sites/std/functions/butterCMSPosts.ts", "deco-sites/std/functions/butterCMSRelatedPosts.ts", "deco-sites/std/functions/occProductDetailsPage.ts", + "deco-sites/std/functions/productIdFromVTEXSlug.ts", "deco-sites/std/functions/requestToParam.ts", "deco-sites/std/functions/shopifyProductDetailsPage.ts", "deco-sites/std/functions/shopifyProductList.ts", @@ -1805,7 +1806,7 @@ } }, { - "title": "VTEX Intelligent Search - Product Details Page", + "title": "VTEX product details page - Intelligent Search", "description": "Works on routes of type /:slug/p", "type": "object", "allOf": [ @@ -1827,7 +1828,7 @@ } }, { - "title": "VTEX Catalog - Product Details Page", + "title": "VTEX Legacy - Product Details page", "description": "For routes of type /:slug/p", "type": "object", "allOf": [ @@ -1850,6 +1851,39 @@ } ] }, + "ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3Byb2R1Y3RJZEZyb21WVEVYU2x1Zy50cw==@ProductID": { + "anyOf": [ + { + "$ref": "#/definitions/Resolvable" + }, + { + "type": "string", + "title": "deco-sites/std/functions/productIdFromVTEXSlug.ts@ProductID" + }, + { + "title": "Extract ID from request parameters", + "description": "Set param to slug for routes of type /:slug", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3Byb2R1Y3RJZEZyb21WVEVYU2x1Zy50cw==@Props" + } + ], + "required": [ + "__resolveType" + ], + "properties": { + "__resolveType": { + "type": "string", + "enum": [ + "deco-sites/std/functions/productIdFromVTEXSlug.ts" + ], + "default": "deco-sites/std/functions/productIdFromVTEXSlug.ts" + } + } + } + ] + }, "ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3JlcXVlc3RUb1BhcmFtLnRz@RequestURLParam": { "anyOf": [ { @@ -1857,7 +1891,7 @@ }, { "type": "string", - "title": "deco-sites/std/functions/requestToParam.ts@RequestURLParam" + "title": "RequestURLParam" }, { "title": "Get params from request parameters", @@ -1883,6 +1917,21 @@ } ] }, + "ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3Byb2R1Y3RJZEZyb21WVEVYU2x1Zy50cw==@Props": { + "type": "object", + "properties": { + "slug": { + "$ref": "#/definitions/ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3JlcXVlc3RUb1BhcmFtLnRz@RequestURLParam", + "default": "slug", + "description": "Param name to extract from the Request URL", + "title": "Slug" + } + }, + "required": [ + "slug" + ], + "title": "deco-sites/std/functions/productIdFromVTEXSlug.ts@Props" + }, "ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3JlcXVlc3RUb1BhcmFtLnRz@Props": { "type": "object", "properties": { @@ -2116,7 +2165,7 @@ } }, { - "title": "VTEX Intelligent Search - Search Products", + "title": "VTEX product list - Intelligent Search", "description": "Useful for shelves and galleries.", "type": "object", "allOf": [ @@ -2138,7 +2187,7 @@ } }, { - "title": "VTEX Catalog - Search Products", + "title": "VTEX Legacy - Search Products", "description": "Use it in Shelves and static Galleries.", "type": "object", "allOf": [ @@ -2160,7 +2209,7 @@ } }, { - "title": "VTEX Related Products - Catalog", + "title": "VTEX related products - Portal", "description": "Works on routes of type /:slug/p", "type": "object", "allOf": [ @@ -2688,7 +2737,7 @@ } }, { - "title": "VTEX Catalog - Product Listing Page", + "title": "VTEX product listing page - Portal", "description": "Returns data ready for search pages like category,brand pages", "type": "object", "allOf": [ @@ -3522,7 +3571,7 @@ } }, { - "title": "VTEX Intelligent Search - Search Suggestions", + "title": "VTEX search suggestions - Intelligent Search", "type": "object", "allOf": [ { @@ -4923,30 +4972,9 @@ "ZGVjby1zaXRlcy9zdGQvcGFja3MvbGlueEltcHVsc2UvbG9hZGVycy9wcm9kdWN0cy9zaW1pbGFySXRlbXMudHM=@Props": { "type": "object", "properties": { - "slug": { - "$ref": "#/definitions/ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3JlcXVlc3RUb1BhcmFtLnRz@RequestURLParam", - "title": "Slug" - }, - "position": { - "anyOf": [ - { - "type": "string", - "const": "top", - "default": "top" - }, - { - "type": "string", - "const": "middle", - "default": "middle" - }, - { - "type": "string", - "const": "bottom", - "default": "bottom" - } - ], - "type": "string", - "title": "Position" + "id": { + "$ref": "#/definitions/ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3Byb2R1Y3RJZEZyb21WVEVYU2x1Zy50cw==@ProductID", + "title": "Id" }, "feature": { "anyOf": [ @@ -4966,8 +4994,7 @@ } }, "required": [ - "slug", - "position", + "id", "feature" ], "title": "deco-sites/std/packs/linxImpulse/loaders/products/similarItems.ts@Props" @@ -11717,6 +11744,28 @@ } } }, + "ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3Byb2R1Y3RJZEZyb21WVEVYU2x1Zy50cw==": { + "title": "Extract ID from request parameters", + "description": "Set param to slug for routes of type /:slug", + "type": "object", + "allOf": [ + { + "$ref": "#/definitions/ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3Byb2R1Y3RJZEZyb21WVEVYU2x1Zy50cw==@Props" + } + ], + "required": [ + "__resolveType" + ], + "properties": { + "__resolveType": { + "type": "string", + "enum": [ + "deco-sites/std/functions/productIdFromVTEXSlug.ts" + ], + "default": "deco-sites/std/functions/productIdFromVTEXSlug.ts" + } + } + }, "ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3JlcXVlc3RUb1BhcmFtLnRz": { "title": "Get params from request parameters", "description": "Set param to slug for routes of type /:slug", @@ -12598,7 +12647,7 @@ } }, "ZGVjby1zaXRlcy9zdGQvbG9hZGVycy92dGV4L2ludGVsbGlnZW50U2VhcmNoL3Byb2R1Y3REZXRhaWxzUGFnZS50cw==": { - "title": "VTEX Intelligent Search - Product Details Page", + "title": "VTEX product details page - Intelligent Search", "description": "Works on routes of type /:slug/p", "type": "object", "allOf": [ @@ -12620,7 +12669,7 @@ } }, "ZGVjby1zaXRlcy9zdGQvbG9hZGVycy92dGV4L2ludGVsbGlnZW50U2VhcmNoL3Byb2R1Y3RMaXN0LnRz": { - "title": "VTEX Intelligent Search - Search Products", + "title": "VTEX product list - Intelligent Search", "description": "Useful for shelves and galleries.", "type": "object", "allOf": [ @@ -12664,7 +12713,7 @@ } }, "ZGVjby1zaXRlcy9zdGQvbG9hZGVycy92dGV4L2ludGVsbGlnZW50U2VhcmNoL3N1Z2dlc3Rpb25zLnRz": { - "title": "VTEX Intelligent Search - Search Suggestions", + "title": "VTEX search suggestions - Intelligent Search", "type": "object", "allOf": [ { @@ -12685,7 +12734,7 @@ } }, "ZGVjby1zaXRlcy9zdGQvbG9hZGVycy92dGV4L2xlZ2FjeS9wcm9kdWN0RGV0YWlsc1BhZ2UudHM=": { - "title": "VTEX Catalog - Product Details Page", + "title": "VTEX Legacy - Product Details page", "description": "For routes of type /:slug/p", "type": "object", "allOf": [ @@ -12707,7 +12756,7 @@ } }, "ZGVjby1zaXRlcy9zdGQvbG9hZGVycy92dGV4L2xlZ2FjeS9wcm9kdWN0TGlzdC50cw==": { - "title": "VTEX Catalog - Search Products", + "title": "VTEX Legacy - Search Products", "description": "Use it in Shelves and static Galleries.", "type": "object", "allOf": [ @@ -12729,7 +12778,7 @@ } }, "ZGVjby1zaXRlcy9zdGQvbG9hZGVycy92dGV4L2xlZ2FjeS9wcm9kdWN0TGlzdGluZ1BhZ2UudHM=": { - "title": "VTEX Catalog - Product Listing Page", + "title": "VTEX product listing page - Portal", "description": "Returns data ready for search pages like category,brand pages", "type": "object", "allOf": [ @@ -12751,7 +12800,7 @@ } }, "ZGVjby1zaXRlcy9zdGQvbG9hZGVycy92dGV4L2xlZ2FjeS9yZWxhdGVkUHJvZHVjdHNMb2FkZXIudHM=": { - "title": "VTEX Related Products - Catalog", + "title": "VTEX related products - Portal", "description": "Works on routes of type /:slug/p", "type": "object", "allOf": [ @@ -14284,6 +14333,9 @@ { "$ref": "#/definitions/ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL29jY1Byb2R1Y3REZXRhaWxzUGFnZS50cw==" }, + { + "$ref": "#/definitions/ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3Byb2R1Y3RJZEZyb21WVEVYU2x1Zy50cw==" + }, { "$ref": "#/definitions/ZGVjby1zaXRlcy9zdGQvZnVuY3Rpb25zL3JlcXVlc3RUb1BhcmFtLnRz" },