@decocms/apps-wake 8.1.0-next.0 → 8.1.0-next.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +4 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/storefront.d.ts +14 -0
  6. package/dist/storefront.d.ts.map +1 -0
  7. package/dist/storefront.js +14 -0
  8. package/dist/storefront.js.map +1 -0
  9. package/dist/storefrontTypes.d.ts +7 -0
  10. package/dist/storefrontTypes.d.ts.map +1 -0
  11. package/dist/storefrontTypes.js +2 -0
  12. package/dist/storefrontTypes.js.map +1 -0
  13. package/dist/utils/client.d.ts +12 -0
  14. package/dist/utils/client.d.ts.map +1 -0
  15. package/dist/utils/client.js +2 -0
  16. package/dist/utils/client.js.map +1 -0
  17. package/dist/utils/gql.d.ts +16 -0
  18. package/dist/utils/gql.d.ts.map +1 -0
  19. package/dist/utils/gql.js +16 -0
  20. package/dist/utils/gql.js.map +1 -0
  21. package/dist/utils/graphql/queries.d.ts +117 -0
  22. package/dist/utils/graphql/queries.d.ts.map +1 -0
  23. package/dist/utils/graphql/queries.js +1323 -0
  24. package/dist/utils/graphql/queries.js.map +1 -0
  25. package/dist/utils/graphql/storefront.graphql.gen.d.ts +10344 -0
  26. package/dist/utils/graphql/storefront.graphql.gen.d.ts.map +1 -0
  27. package/dist/utils/graphql/storefront.graphql.gen.js +9 -0
  28. package/dist/utils/graphql/storefront.graphql.gen.js.map +1 -0
  29. package/dist/utils/graphqlOperationName.d.ts +36 -0
  30. package/dist/utils/graphqlOperationName.d.ts.map +1 -0
  31. package/dist/utils/graphqlOperationName.js +59 -0
  32. package/dist/utils/graphqlOperationName.js.map +1 -0
  33. package/dist/wakeClient.d.ts +54 -0
  34. package/dist/wakeClient.d.ts.map +1 -0
  35. package/dist/wakeClient.js +85 -0
  36. package/dist/wakeClient.js.map +1 -0
  37. package/package.json +26 -37
  38. package/src/index.ts +3 -63
  39. package/src/storefront.ts +1 -1
  40. package/src/storefrontTypes.ts +1 -1
  41. package/src/utils/gql.ts +1 -2
  42. package/src/utils/graphql/queries.ts +1 -1
  43. package/src/wakeClient.ts +3 -3
  44. package/src/__tests__/wakeClient.test.ts +0 -136
  45. package/src/actions/cart/addCoupon.ts +0 -43
  46. package/src/actions/cart/addItem.ts +0 -10
  47. package/src/actions/cart/addItems.ts +0 -50
  48. package/src/actions/cart/addKit.ts +0 -53
  49. package/src/actions/cart/partnerAssociate.ts +0 -48
  50. package/src/actions/cart/partnerDisassociate.ts +0 -43
  51. package/src/actions/cart/removeCoupon.ts +0 -39
  52. package/src/actions/cart/removeKit.ts +0 -56
  53. package/src/actions/cart/updateItemQuantity.ts +0 -69
  54. package/src/actions/newsletter/register.ts +0 -32
  55. package/src/actions/notifyme.ts +0 -28
  56. package/src/actions/review/create.ts +0 -30
  57. package/src/actions/shippingSimulation.ts +0 -60
  58. package/src/actions/submmitForm.ts +0 -25
  59. package/src/actions/wishlist/addProduct.ts +0 -43
  60. package/src/actions/wishlist/removeProduct.ts +0 -45
  61. package/src/client.ts +0 -123
  62. package/src/commerceLoaders.ts +0 -137
  63. package/src/handlers/sitemap.ts +0 -61
  64. package/src/loaders/cart.ts +0 -46
  65. package/src/loaders/partners.ts +0 -58
  66. package/src/loaders/productDetailsPage.ts +0 -174
  67. package/src/loaders/productList.ts +0 -262
  68. package/src/loaders/productListingPage.ts +0 -333
  69. package/src/loaders/proxy.ts +0 -79
  70. package/src/loaders/recommendations.ts +0 -84
  71. package/src/loaders/shop.ts +0 -37
  72. package/src/loaders/suggestion.ts +0 -67
  73. package/src/loaders/user.ts +0 -48
  74. package/src/loaders/wishlist.ts +0 -40
  75. package/src/manifest.gen.ts +0 -69
  76. package/src/mod.ts +0 -88
  77. package/src/registry.ts +0 -9
  78. package/src/utils/authError.ts +0 -107
  79. package/src/utils/authenticate.ts +0 -42
  80. package/src/utils/capitalize.ts +0 -9
  81. package/src/utils/cart.ts +0 -33
  82. package/src/utils/cookies.ts +0 -82
  83. package/src/utils/getVariations.ts +0 -47
  84. package/src/utils/graphql.ts +0 -72
  85. package/src/utils/httpError.ts +0 -15
  86. package/src/utils/instrumentedFetch.ts +0 -46
  87. package/src/utils/operationRouter.ts +0 -51
  88. package/src/utils/parseHeaders.ts +0 -19
  89. package/src/utils/partner.ts +0 -34
  90. package/src/utils/requestCtx.ts +0 -41
  91. package/src/utils/transform.ts +0 -460
  92. package/src/utils/types.ts +0 -6
  93. package/src/utils/user.ts +0 -9
  94. package/tsconfig.json +0 -7
@@ -1,262 +0,0 @@
1
- import type { Product } from "@decocms/apps-commerce/types";
2
- import { getWakeClient } from "../client";
3
- import { handleAuthError } from "../utils/authError";
4
- import { getVariations } from "../utils/getVariations";
5
- import { GetProducts } from "../utils/graphql/queries";
6
- import type { GetProductsQuery, ProductFragment } from "../utils/graphql/storefront.graphql.gen";
7
- import { getPartnerCookie } from "../utils/partner";
8
- import { currentRequestHeaders, currentUrl, forwardedHeaders } from "../utils/requestCtx";
9
- import { toProduct } from "../utils/transform";
10
-
11
- export interface StockFilter {
12
- dcId?: number[];
13
- /** @description The distribution center names to match. */
14
- dcName?: string[];
15
- /**
16
- * @title Stock greater than or equal
17
- * @description The product stock must be greater than or equal to.
18
- */
19
- stock_gte?: number;
20
- /**
21
- * @title Stock less than or equal
22
- * @description The product stock must be lesser than or equal to.
23
- */
24
- stock_lte?: number;
25
- }
26
-
27
- export interface PriceFilter {
28
- /**
29
- * @title Discount greater than
30
- * @description The product discount must be greater than or equal to.
31
- */
32
- discount_gte?: number;
33
- /**
34
- * @title Discount lesser than
35
- * @description The product discount must be lesser than or equal to.
36
- */
37
- discount_lte?: number;
38
- /** @description Return only products where the listed price is more than the price. */
39
- discounted?: boolean;
40
- /**
41
- * @title Price greater than
42
- * @description The product price must be greater than or equal to.
43
- */
44
- price_gte?: number;
45
- /**
46
- * @title Price lesser than
47
- * @description The product price must be lesser than or equal to. */
48
- price_lte?: number;
49
- }
50
-
51
- export interface Filters {
52
- /** @description The set of attributes to filter. */
53
- attributes?: {
54
- id?: string[];
55
- name?: string[];
56
- type?: string[];
57
- value?: string[];
58
- };
59
- /** @description Choose if you want to retrieve only the available products in stock. */
60
- available?: boolean;
61
- /** @description The set of brand IDs which the result item brand ID must be included in. */
62
- brandId?: number[];
63
- /** @description The set of category IDs which the result item category ID must be included in. */
64
- categoryId?: number[];
65
- /** @description The set of EANs which the result item EAN must be included. */
66
- ean?: string[];
67
- /** @description Retrieve the product variant only if it contains images. */
68
- hasImages?: boolean;
69
- /** @description Retrieve the product variant only if it is the main product variant. */
70
- mainVariant?: boolean;
71
-
72
- /** @description The set of prices to filter. */
73
- prices?: PriceFilter;
74
-
75
- /** @description The product unique identifier (you may provide a list of IDs if needed). */
76
- productId?: number[];
77
- /** @description The product variant unique identifier (you may provide a list of IDs if needed). */
78
- productVariantId?: number[];
79
- /** @description A product ID or a list of IDs to search for other products with the same parent ID. */
80
- sameParentAs?: number[];
81
- /** @description The set of SKUs which the result item SKU must be included. */
82
- sku?: string[];
83
- /**
84
- * @title Stock greater than
85
- * @description Show products with a quantity of available products in stock greater than or equal to the given number. */
86
- stock_gte?: number;
87
- /**
88
- * @title Stock lesser than
89
- * @description Show products with a quantity of available products in stock less than or equal to the given number. */
90
- stock_lte?: number;
91
- /** @description The set of stocks to filter. */
92
- stocks?: StockFilter;
93
- /**
94
- * @title Upated after
95
- * @format date
96
- * @description Retrieve products which the last update date is greater than or equal to the given date.
97
- */
98
- updatedAt_gte?: string;
99
- /**
100
- * @title Upated before
101
- * @format date
102
- * @description Retrieve products which the last update date is less than or equal to the given date.
103
- */
104
- updatedAt_lte?: string;
105
- }
106
-
107
- export interface Props {
108
- /**
109
- * @title Count
110
- * @description Number of products to return
111
- * @maximum 50
112
- * @default 12
113
- */
114
- first: number;
115
- sortDirection: "ASC" | "DESC";
116
- sortKey: "DISCOUNT" | "NAME" | "PRICE" | "RANDOM" | "RELEASE_DATE" | "SALES" | "STOCK";
117
-
118
- filters: Filters;
119
-
120
- /** @description Retrieve variantions for each product. */
121
- getVariations?: boolean;
122
- }
123
-
124
- // Valid keys of Wake's `ProductExplicitFiltersInput`. Migrated blocks may carry
125
- // other platforms' filter shapes (e.g. Shopify's `tags`/`productTypes`/
126
- // `productVendors`/`variantOptions`), which Wake rejects with a 500. Keep only
127
- // the recognized keys.
128
- const WAKE_FILTER_KEYS = new Set<keyof Filters>([
129
- "attributes",
130
- "available",
131
- "brandId",
132
- "categoryId",
133
- "ean",
134
- "hasImages",
135
- "mainVariant",
136
- "prices",
137
- "productId",
138
- "productVariantId",
139
- "sameParentAs",
140
- "sku",
141
- "stock_gte",
142
- "stock_lte",
143
- "stocks",
144
- "updatedAt_gte",
145
- "updatedAt_lte",
146
- ]);
147
-
148
- const sanitizeFilters = (filters: unknown): Filters => {
149
- if (!filters || typeof filters !== "object") return {};
150
- const out: Record<string, unknown> = {};
151
- for (const [key, value] of Object.entries(filters as Record<string, unknown>)) {
152
- if (WAKE_FILTER_KEYS.has(key as keyof Filters)) out[key] = value;
153
- }
154
- return out as Filters;
155
- };
156
-
157
- /**
158
- * @title Wake Integration
159
- * @description Product List loader
160
- */
161
- const productListLoader = async (props: Props): Promise<Product[] | null> => {
162
- const url = currentUrl();
163
- const storefront = getWakeClient();
164
- const partnerAccessToken = getPartnerCookie(currentRequestHeaders());
165
-
166
- const headers = forwardedHeaders();
167
-
168
- let data: GetProductsQuery | undefined;
169
- try {
170
- // Pass ONLY the declared GraphQL variables. The framework injects extra
171
- // props (e.g. `__pageUrl`, `__pagePath`) that Wake rejects (500) if spread
172
- // into the operation's variables, so we pick explicitly.
173
- const variables = {
174
- // Tolerate legacy/other-platform props (e.g. `count`) and default the
175
- // required GraphQL variables so shelf blocks that don't set them still
176
- // resolve. `first` is `Int!` — an undefined here 500s the Wake API.
177
- first: props.first ?? (props as { count?: number }).count ?? 12,
178
- sortDirection: props.sortDirection ?? "DESC",
179
- sortKey: props.sortKey ?? "SALES",
180
- filters: sanitizeFilters(props.filters),
181
- partnerAccessToken,
182
- };
183
- data = await storefront.query<GetProductsQuery>(GetProducts, variables, headers);
184
- } catch (error: unknown) {
185
- handleAuthError(error, "load product list");
186
- }
187
-
188
- const products = data?.products?.nodes;
189
-
190
- if (!Array.isArray(products)) {
191
- return null;
192
- }
193
-
194
- const productIDs = products.map((i) => i?.productId).filter((id): id is number => id != null);
195
-
196
- const variations = props.getVariations ? await getVariations(productIDs, url, headers) : [];
197
-
198
- return products
199
- .filter((node): node is ProductFragment => Boolean(node))
200
- .map((node) => {
201
- const productVariations = variations?.filter(
202
- (v) => v.inProductGroupWithID === node.productId,
203
- );
204
-
205
- return toProduct(node, { base: url }, productVariations);
206
- });
207
- };
208
-
209
- export const cache = "stale-while-revalidate";
210
-
211
- // Helper function for deterministic filter serialization
212
- function stableStringify(value: unknown): string {
213
- const seen = new WeakSet();
214
- const replacer = (_k: string, v: unknown) => {
215
- if (v && typeof v === "object") {
216
- if (seen.has(v as object)) return "[Circular]";
217
- seen.add(v as object);
218
- if (Array.isArray(v)) return v; // keep array order
219
- const obj = v as Record<string, unknown>;
220
- return Object.keys(obj)
221
- .sort()
222
- .reduce(
223
- (acc, key) => {
224
- acc[key] = obj[key];
225
- return acc;
226
- },
227
- {} as Record<string, unknown>,
228
- );
229
- }
230
- return v;
231
- };
232
- return JSON.stringify(value, replacer);
233
- }
234
-
235
- export const cacheKey = (props: Props): string | null => {
236
- // Avoid cross-tenant cache bleed when a partner token is present
237
- if (getPartnerCookie(currentRequestHeaders())) {
238
- return null;
239
- }
240
-
241
- // Don't cache dynamic/random sorts
242
- if (props.sortKey === "RANDOM") {
243
- return null;
244
- }
245
-
246
- const params = new URLSearchParams([
247
- ["first", String(props.first ?? 12)],
248
- ["sortKey", props.sortKey ?? "NAME"],
249
- ["sortDirection", props.sortDirection ?? "ASC"],
250
- ["getVariations", String(Boolean(props.getVariations ?? false))],
251
- ]);
252
-
253
- // Add filters to cache key with deterministic serialization
254
- if (props.filters) {
255
- params.append("filters", stableStringify(props.filters));
256
- }
257
-
258
- params.sort();
259
- return `wake:productList?${params.toString()}`;
260
- };
261
-
262
- export default productListLoader;
@@ -1,333 +0,0 @@
1
- import type { ProductListingPage, SortOption } from "@decocms/apps-commerce/types";
2
- import partnerAssociate from "../actions/cart/partnerAssociate";
3
- import { getWakeClient } from "../client";
4
- import { handleAuthError } from "../utils/authError";
5
- import { capitalize } from "../utils/capitalize";
6
- import { getVariations, MAXIMUM_REQUEST_QUANTITY } from "../utils/getVariations";
7
- import { GetPartners, GetURL, Hotsite, Search } from "../utils/graphql/queries";
8
- import type {
9
- GetPartnersQuery,
10
- GetUrlQuery,
11
- HotsiteQuery,
12
- ProductFragment,
13
- ProductSortKeys,
14
- SearchQuery,
15
- SortDirection,
16
- } from "../utils/graphql/storefront.graphql.gen";
17
- import { getPartnerCookie } from "../utils/partner";
18
- import { currentRequest, currentRequestHeaders, forwardedHeaders } from "../utils/requestCtx";
19
- import { FILTER_PARAM, toBreadcrumbList, toFilters, toProduct } from "../utils/transform";
20
- import type { RequestURLParam } from "../utils/types";
21
- import type { Filters } from "./productList";
22
-
23
- export type Sort =
24
- | "NAME:ASC"
25
- | "NAME:DESC"
26
- | "RELEASE_DATE:DESC"
27
- | "PRICE:ASC"
28
- | "PRICE:DESC"
29
- | "DISCOUNT:DESC"
30
- | "SALES:DESC";
31
-
32
- export const SORT_OPTIONS: SortOption[] = [
33
- { value: "NAME:ASC", label: "Nome A-Z" },
34
- { value: "NAME:DESC", label: "Nome Z-A" },
35
- { value: "RELEASE_DATE:DESC", label: "Lançamentos" },
36
- { value: "PRICE:ASC", label: "Menores Preços" },
37
- { value: "PRICE:DESC", label: "Maiores Preços" },
38
- { value: "DISCOUNT:DESC", label: "Maiores Descontos" },
39
- { value: "SALES:DESC", label: "Mais Vendidos" },
40
- ];
41
-
42
- type SortValue = `${ProductSortKeys}:${SortDirection}`;
43
- export interface Props {
44
- /**
45
- * @title Count
46
- * @description Number of products to display
47
- * @maximum 50
48
- * @default 12
49
- */
50
- limit?: number;
51
-
52
- /** @description Types of operations to perform between query terms */
53
- operation?: "AND" | "OR";
54
-
55
- /**
56
- * @ignore
57
- */
58
- page: number;
59
-
60
- /**
61
- * @title Sorting
62
- */
63
- sort?: Sort;
64
-
65
- /**
66
- * @description overides the query term
67
- */
68
- query?: string;
69
-
70
- /**
71
- * @title Only Main Variant
72
- * @description Toggle the return of only main variants or all variations separeted.
73
- */
74
- onlyMainVariant?: boolean;
75
-
76
- filters?: Filters;
77
-
78
- /** @description Retrieve variantions for each product. */
79
- getVariations?: boolean;
80
-
81
- /**
82
- * @title Starting page query parameter offset.
83
- * @description Set the starting page offset. Default to 1.
84
- */
85
- pageOffset?: 0 | 1;
86
-
87
- /**
88
- * @hide true
89
- * @description The URL of the page, used to override URL from request
90
- */
91
- pageHref?: string;
92
-
93
- /**
94
- * @title Partner Param
95
- * @description page param to partners page
96
- * @deprecated
97
- */
98
- slug?: RequestURLParam;
99
-
100
- /**
101
- * @title Partner Param
102
- * @description page param to partners page
103
- */
104
- partnerAlias?: RequestURLParam;
105
- }
106
-
107
- const OUTSIDE_ATTRIBUTES_FILTERS = ["precoPor"];
108
-
109
- const filtersFromParams = (searchParams: URLSearchParams) => {
110
- const filters: Array<{ field: string; values: string[] }> = [];
111
-
112
- searchParams.getAll(FILTER_PARAM).forEach((value) => {
113
- const test = /.*:.*/;
114
- const [field, val] = test.test(value) ? value.split(":") : value.split("__");
115
-
116
- if (!OUTSIDE_ATTRIBUTES_FILTERS.includes(field)) {
117
- filters.push({ field, values: [val] });
118
- }
119
- });
120
-
121
- return filters;
122
- };
123
-
124
- /**
125
- * @title Wake Integration
126
- * @description Product Listing Page loader
127
- */
128
- const searchLoader = async (props: Props): Promise<ProductListingPage | null> => {
129
- const req = currentRequest();
130
- const reqUrl = req?.url ?? "https://localhost";
131
- // get url from params
132
- const url =
133
- new URL(reqUrl).pathname === "/live/invoke"
134
- ? new URL(props.pageHref || req?.headers.get("referer") || reqUrl)
135
- : new URL(props.pageHref || reqUrl);
136
-
137
- const storefront = getWakeClient();
138
-
139
- const partnerAlias = props.partnerAlias ?? props.slug;
140
-
141
- const partnerAccessTokenCookie = getPartnerCookie(currentRequestHeaders());
142
-
143
- const headers = forwardedHeaders();
144
-
145
- const limit = Number(url.searchParams.get("tamanho") ?? props.limit ?? 12);
146
-
147
- const filters = filtersFromParams(url.searchParams) ?? props.filters;
148
- const sort =
149
- (url.searchParams.get("sort") as SortValue | null) ??
150
- (url.searchParams.get("ordenacao") as SortValue | null) ??
151
- props.sort ??
152
- "SALES:DESC";
153
- const page =
154
- props.page ??
155
- Number(url.searchParams.get("page")) ??
156
- Number(url.searchParams.get("pagina")) ??
157
- 0;
158
- const query = props.query ?? url.searchParams.get("busca");
159
- const operation = props.operation ?? "AND";
160
-
161
- const [sortKey, sortDirection] = sort.split(":") as [ProductSortKeys, SortDirection];
162
-
163
- const onlyMainVariant = props.onlyMainVariant ?? true;
164
- const [minimumPrice, maximumPrice] =
165
- url.searchParams
166
- .getAll("filtro")
167
- ?.find((i) => i.startsWith("precoPor"))
168
- ?.split(":")[1]
169
- ?.split(";")
170
- .map(Number) ??
171
- url.searchParams.get("precoPor")?.split(";").map(Number) ??
172
- [];
173
-
174
- const offset = page <= 1 ? 0 : (page - 1) * limit;
175
-
176
- const partnerData = partnerAlias
177
- ? await storefront.query<GetPartnersQuery>(
178
- GetPartners,
179
- { first: 1, alias: [partnerAlias] },
180
- headers,
181
- )
182
- : null;
183
-
184
- const partnerAccessToken =
185
- partnerData?.partners?.edges?.[0]?.node?.partnerAccessToken ?? partnerAccessTokenCookie;
186
-
187
- if (partnerAccessToken) {
188
- try {
189
- await partnerAssociate({ partnerAccessToken });
190
- } catch (e) {
191
- console.error(e);
192
- }
193
- }
194
-
195
- const urlData = await storefront.query<GetUrlQuery>(GetURL, { url: url.pathname }, headers);
196
-
197
- const isHotsite = urlData.uri?.kind === "HOTSITE";
198
-
199
- const commonParams = {
200
- sortDirection,
201
- sortKey,
202
- filters,
203
- limit: Math.min(limit, MAXIMUM_REQUEST_QUANTITY),
204
- offset,
205
- onlyMainVariant,
206
- minimumPrice,
207
- maximumPrice,
208
- partnerAccessToken,
209
- };
210
-
211
- if (!query && !isHotsite && !partnerAccessToken) {
212
- console.warn(
213
- "ProductListingPage: No search query, hotsite, or partner token provided - returning null",
214
- );
215
- return null;
216
- }
217
-
218
- let data: SearchQuery | HotsiteQuery | undefined;
219
- try {
220
- data = isHotsite
221
- ? await storefront.query<HotsiteQuery>(
222
- Hotsite,
223
- { ...commonParams, url: url.pathname },
224
- headers,
225
- )
226
- : await storefront.query<SearchQuery>(Search, { ...commonParams, query, operation }, headers);
227
- } catch (error: unknown) {
228
- handleAuthError(error, "load products");
229
- }
230
-
231
- const products = data?.result?.productsByOffset?.items ?? [];
232
-
233
- const nextPage = new URLSearchParams(url.searchParams);
234
- const previousPage = new URLSearchParams(url.searchParams);
235
-
236
- const hasNextPage = Boolean(
237
- (data?.result?.productsByOffset?.totalCount ?? 0) / limit >
238
- (data?.result?.productsByOffset?.page ?? 0),
239
- );
240
-
241
- const hasPreviousPage = page > 1;
242
-
243
- const pageOffset = props.pageOffset ?? 0;
244
-
245
- if (hasNextPage) {
246
- nextPage.set("page", (page + pageOffset + 1).toString());
247
- }
248
-
249
- if (hasPreviousPage) {
250
- previousPage.set("page", (page + pageOffset - 1).toString());
251
- }
252
-
253
- const productIDs = products.map((i) => i?.productId).filter((id): id is number => id != null);
254
-
255
- const variations = props.getVariations ? await getVariations(productIDs, url, headers) : [];
256
-
257
- const breadcrumb = toBreadcrumbList(data?.result?.breadcrumbs, {
258
- base: url,
259
- });
260
-
261
- const title = isHotsite
262
- ? (data as HotsiteQuery)?.result?.seo?.find((i) => i?.type === "TITLE")?.content
263
- : capitalize(query || "");
264
- const description = isHotsite
265
- ? (data as HotsiteQuery)?.result?.seo?.find((i) => i?.name === "description")?.content
266
- : capitalize(query || "");
267
- const canonical = new URL(isHotsite ? `/${(data as HotsiteQuery)?.result?.url}` : url, url).href;
268
-
269
- return {
270
- "@type": "ProductListingPage",
271
- filters: toFilters(data?.result?.aggregations, { base: url }),
272
- pageInfo: {
273
- nextPage: hasNextPage ? `?${nextPage}` : undefined,
274
- previousPage: hasPreviousPage ? `?${previousPage}` : undefined,
275
- currentPage: data?.result?.productsByOffset?.page ?? 1,
276
- records: data?.result?.productsByOffset?.totalCount,
277
- recordPerPage: limit,
278
- },
279
- sortOptions: SORT_OPTIONS,
280
- breadcrumb,
281
- seo: {
282
- description: description || "",
283
- title: title || "",
284
- canonical,
285
- },
286
- products: products
287
- ?.filter((p): p is ProductFragment => Boolean(p))
288
- .map((variant) => {
289
- const productVariations = variations?.filter(
290
- (v) => v.inProductGroupWithID === variant.productId,
291
- );
292
-
293
- return toProduct(variant, { base: url }, productVariations);
294
- }),
295
- };
296
- };
297
-
298
- export const cache = "stale-while-revalidate";
299
-
300
- export const cacheKey = (props: Props): string | null => {
301
- const req = currentRequest();
302
- const url = new URL(props.pageHref || req?.url || "https://localhost");
303
-
304
- // Don't cache search queries to ensure freshness
305
- if (url.searchParams.get("q") || url.searchParams.get("query") || url.searchParams.get("busca")) {
306
- return null;
307
- }
308
-
309
- // Avoid cross-tenant cache bleed when a partner token is present
310
- if (getPartnerCookie(currentRequestHeaders())) {
311
- return null;
312
- }
313
-
314
- const params = new URLSearchParams([
315
- ["limit", (props.limit || 12).toString()],
316
- ["page", (props.page || 0).toString()],
317
- ["sort", props.sort || ""],
318
- ["pageOffset", (props.pageOffset || 0).toString()],
319
- ]);
320
-
321
- // Add any filter parameters
322
- url.searchParams.forEach((value, key) => {
323
- if (key === "filtro" || key === "q" || key === "sort" || key === "page") {
324
- params.append(key, value);
325
- }
326
- });
327
-
328
- params.sort();
329
- url.search = params.toString();
330
- return url.href;
331
- };
332
-
333
- export default searchLoader;
@@ -1,79 +0,0 @@
1
- import { getCheckoutUrl } from "../client";
2
-
3
- /**
4
- * Checkout paths that must be proxied to the Wake checkout host. In the Deno
5
- * runtime this loader returned deco `Route[]` consumed by the `website` router;
6
- * that router does not exist in this architecture, so the loader returns a
7
- * serializable descriptor list that the storefront's worker entry consumes to
8
- * install its own proxy handler.
9
- */
10
- const PATHS_TO_PROXY: Array<[string, string?]> = [
11
- ["/checkout", "/checkout"],
12
- ["/Fechamento"],
13
- ["/Fechamento/*"],
14
- ["/Login"],
15
- ["/Login/*"],
16
- ["/login/*"],
17
- ["/Login/Authenticate"],
18
- ["/Carrinho/*"],
19
- ["/api/*"],
20
- ["/MinhaConta"],
21
- ["/MinhaConta/*"],
22
- ];
23
-
24
- export interface Props {
25
- extraPathsToProxy?: string[];
26
- /**
27
- * @title Other site maps to include
28
- */
29
- includeSiteMap?: string[];
30
- }
31
-
32
- export type WakeProxyRoute =
33
- | {
34
- type: "proxy";
35
- pathTemplate: string;
36
- basePath?: string;
37
- /** Target host to proxy to (the Wake checkout URL). */
38
- url: string;
39
- /** Host header to forward. */
40
- host: string;
41
- }
42
- | {
43
- type: "sitemap";
44
- pathTemplate: string;
45
- include?: string[];
46
- host: string;
47
- };
48
-
49
- /**
50
- * @title Wake Proxy Routes
51
- */
52
- function loader(props: Props): WakeProxyRoute[] {
53
- const { includeSiteMap, extraPathsToProxy = [] } = props;
54
-
55
- const checkoutUrl = getCheckoutUrl();
56
-
57
- const extraPathsAsArray: Array<[string, string?]> = extraPathsToProxy.map((path) => [path]);
58
-
59
- const checkout: WakeProxyRoute[] = [...PATHS_TO_PROXY, ...extraPathsAsArray].map(
60
- ([pathTemplate, basePath]) => ({
61
- type: "proxy",
62
- pathTemplate,
63
- basePath,
64
- url: checkoutUrl,
65
- host: checkoutUrl,
66
- }),
67
- );
68
-
69
- const sitemap: WakeProxyRoute = {
70
- type: "sitemap",
71
- pathTemplate: "/Sitemap.xml",
72
- include: includeSiteMap,
73
- host: checkoutUrl,
74
- };
75
-
76
- return [...checkout, sitemap];
77
- }
78
-
79
- export default loader;