Skip to content

Commit

Permalink
feat: add "advancedConfigs" to PDP and PLP loaders (#996)
Browse files Browse the repository at this point in the history
  • Loading branch information
pedrobernardina authored Jan 29, 2025
1 parent 63ef581 commit a934621
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 3 deletions.
12 changes: 11 additions & 1 deletion vtex/loaders/intelligentSearch/productDetailsPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ import { pageTypesToSeo } from "../../utils/legacy.ts";
import { getSegmentFromBag, withSegmentCookie } from "../../utils/segment.ts";
import { withIsSimilarTo } from "../../utils/similars.ts";
import { pickSku, toProductPage } from "../../utils/transform.ts";
import type { PageType, Product as VTEXProduct } from "../../utils/types.ts";
import type {
AdvancedLoaderConfig,
PageType,
Product as VTEXProduct,
} from "../../utils/types.ts";
import PDPDefaultPath from "../paths/PDPDefaultPath.ts";

export interface Props {
Expand All @@ -26,6 +30,11 @@ export interface Props {
* @description Index of product pages with the `skuId` parameter
*/
indexingSkus?: boolean;
/**
* @title Advanced Configuration
* @description Further change loader behaviour
*/
advancedConfigs?: AdvancedLoaderConfig;
}

/**
Expand Down Expand Up @@ -130,6 +139,7 @@ const loader = async (
const page = toProductPage(product, sku, kitItems, {
baseUrl,
priceCurrency: segment?.payload?.currencyCode ?? "BRL",
includeOriginalAttributes: props.advancedConfigs?.includeOriginalAttributes,
});

const isPageProduct = pageType.pageType === "Product";
Expand Down
8 changes: 8 additions & 0 deletions vtex/loaders/intelligentSearch/productListingPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
toProduct,
} from "../../utils/transform.ts";
import type {
AdvancedLoaderConfig,
Facet,
Fuzzy,
PageType,
Expand Down Expand Up @@ -142,6 +143,11 @@ export interface Props {
* @title Include price in facets
*/
priceFacets?: boolean;
/**
* @title Advanced Configuration
* @description Further change loader behaviour
*/
advancedConfigs?: AdvancedLoaderConfig;
}
const searchArgsOf = (props: Props, url: URL) => {
const hideUnavailableItems = props.hideUnavailableItems;
Expand Down Expand Up @@ -362,6 +368,8 @@ const loader = async (
toProduct(p, p.items.find(getFirstItemAvailable) || p.items[0], 0, {
baseUrl: baseUrl,
priceCurrency: segment?.payload?.currencyCode ?? "BRL",
includeOriginalAttributes: props.advancedConfigs
?.includeOriginalAttributes,
})
)
.map((product) =>
Expand Down
7 changes: 7 additions & 0 deletions vtex/loaders/intelligentSearch/suggestions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
import { getSegmentFromBag, withSegmentCookie } from "../../utils/segment.ts";
import { withIsSimilarTo } from "../../utils/similars.ts";
import { toProduct } from "../../utils/transform.ts";
import type { AdvancedLoaderConfig } from "../../utils/types.ts";

export interface Props {
query?: string;
Expand All @@ -23,6 +24,11 @@ export interface Props {
* @deprecated Use product extensions instead
*/
similars?: boolean;
/**
* @title Advanced Configuration
* @description Further change loader behaviour
*/
advancedConfigs?: AdvancedLoaderConfig;
}

/**
Expand Down Expand Up @@ -79,6 +85,7 @@ const loaders = async (
const options = {
baseUrl: url,
priceCurrency: segment?.payload?.currencyCode ?? "BRL",
includeOriginalAttributes: props.advancedConfigs?.includeOriginalAttributes,
};

return {
Expand Down
8 changes: 7 additions & 1 deletion vtex/loaders/legacy/productDetailsPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { toSegmentParams } from "../../utils/legacy.ts";
import { getSegmentFromBag, withSegmentCookie } from "../../utils/segment.ts";
import { withIsSimilarTo } from "../../utils/similars.ts";
import { pickSku, toProductPage } from "../../utils/transform.ts";
import type { LegacyProduct } from "../../utils/types.ts";
import type { AdvancedLoaderConfig, LegacyProduct } from "../../utils/types.ts";
import PDPDefaultPath from "../paths/PDPDefaultPath.ts";

export interface Props {
Expand All @@ -22,6 +22,11 @@ export interface Props {
* @description Index of product pages with the `skuId` parameter
*/
indexingSkus?: boolean;
/**
* @title Advanced Configuration
* @description Further change loader behaviour
*/
advancedConfigs?: AdvancedLoaderConfig;
}

/**
Expand Down Expand Up @@ -86,6 +91,7 @@ async function loader(
const page = toProductPage(product, sku, kitItems, {
baseUrl,
priceCurrency: segment?.payload?.currencyCode ?? "BRL",
includeOriginalAttributes: props.advancedConfigs?.includeOriginalAttributes,
});

return {
Expand Down
9 changes: 9 additions & 0 deletions vtex/loaders/legacy/productListingPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { withIsSimilarTo } from "../../utils/similars.ts";
import { parsePageType } from "../../utils/transform.ts";
import { legacyFacetToFilter, toProduct } from "../../utils/transform.ts";
import type {
AdvancedLoaderConfig,
Item,
LegacyFacet,
LegacyProduct,
Expand Down Expand Up @@ -92,6 +93,12 @@ export interface Props {
* @title Ignore case by checking for selected filter
*/
ignoreCaseSelected?: boolean;

/**
* @title Advanced Configuration
* @description Further change loader behaviour
*/
advancedConfigs?: AdvancedLoaderConfig;
}

export const sortOptions = [
Expand Down Expand Up @@ -277,6 +284,8 @@ const loader = async (
{
baseUrl,
priceCurrency: segment?.payload?.currencyCode ?? "BRL",
includeOriginalAttributes: props.advancedConfigs
?.includeOriginalAttributes,
},
)
)
Expand Down
30 changes: 30 additions & 0 deletions vtex/utils/pickAndOmit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export function pick<
T extends object,
K extends keyof T = keyof T,
>(
keys: K[],
obj: T | null | undefined,
): Pick<T, K> | null {
if (!keys.length || !obj) {
return null;
}

const entries = keys.map((key) => [key, obj[key]]);

return Object.fromEntries(entries);
}

export function omit<T extends object, K extends keyof T>(
keys: K[],
obj: T | null | undefined,
): Omit<T, K> | null {
if (!keys.length || !obj) {
return null;
}

const pickedKeys = (Object.keys(obj) as K[]).filter(
(key) => !keys.includes(key),
);

return pick(pickedKeys, obj) as unknown as Omit<T, K>;
}
36 changes: 35 additions & 1 deletion vtex/utils/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import type {
import { DEFAULT_IMAGE } from "../../commerce/utils/constants.ts";
import { formatRange } from "../../commerce/utils/filters.ts";
import type { PickupPoint as PickupPointVCS } from "./openapi/vcs.openapi.gen.ts";
import { pick } from "./pickAndOmit.ts";
import { slugify } from "./slugify.ts";
import type {
Brand as BrandVTEX,
Expand All @@ -29,7 +30,9 @@ import type {
Item as SkuVTEX,
LegacyFacet,
LegacyItem as LegacySkuVTEX,
LegacyProduct,
LegacyProduct as LegacyProductVTEX,
Maybe,
OrderForm,
PageType as PageTypeVTEX,
PickupHolidays,
Expand Down Expand Up @@ -81,6 +84,8 @@ interface ProductOptions {
/** Price coded currency, e.g.: USD, BRL */
priceCurrency: string;
imagesByKey?: Map<string, string>;
/** Original attributes to be included in the transformed product */
includeOriginalAttributes?: string[];
}

/** Returns first available sku */
Expand Down Expand Up @@ -363,6 +368,11 @@ export const toProduct = <P extends LegacyProductVTEX | ProductVTEX>(
const groupAdditionalProperty = isLegacyProduct(product)
? legacyToProductGroupAdditionalProperties(product)
: toProductGroupAdditionalProperties(product);
const originalAttributesAdditionalProperties =
toOriginalAttributesAdditionalProperties(
options.includeOriginalAttributes,
product,
);
const specificationsAdditionalProperty = isLegacySku(sku)
? toAdditionalPropertiesLegacy(sku)
: toAdditionalProperties(sku);
Expand All @@ -383,7 +393,10 @@ export const toProduct = <P extends LegacyProductVTEX | ProductVTEX>(
),
url: getProductGroupURL(baseUrl, product).href,
name: product.productName,
additionalProperty: groupAdditionalProperty,
additionalProperty: [
...groupAdditionalProperty,
...originalAttributesAdditionalProperties,
],
model: productReference,
} satisfies ProductGroup)
: undefined;
Expand Down Expand Up @@ -554,6 +567,27 @@ const toProductGroupAdditionalProperties = (
)
);

const toOriginalAttributesAdditionalProperties = (
originalAttributes: Maybe<string[]>,
product: ProductVTEX | LegacyProduct,
) => {
if (!originalAttributes) {
return [];
}

const attributes =
pick(originalAttributes as Array<keyof typeof product>, product) ?? {};

return Object.entries(attributes).map(([name, value]) =>
({
"@type": "PropertyValue",
name,
value,
valueReference: "ORIGINAL_PROPERTY" as string,
}) as const
) as unknown as PropertyValue[];
};

const toAdditionalProperties = (sku: SkuVTEX): PropertyValue[] =>
sku.variations?.flatMap(({ name, values }) =>
values.map((value) => toAdditionalPropertySpecification({ name, value }))
Expand Down
7 changes: 7 additions & 0 deletions vtex/utils/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1516,3 +1516,10 @@ export interface Promotion {
maxNumberOfAffectedItems: number;
maxNumberOfAffectedItemsGroupKey: string;
}

export interface AdvancedLoaderConfig {
/** @description Specifies an array of attribute names from the original object to be directly included in the transformed object. */
includeOriginalAttributes: string[];
}

export type Maybe<T> = T | null | undefined;

0 comments on commit a934621

Please sign in to comment.