@decocms/apps-wake 7.72.0 → 8.1.0-next.1

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 (57) hide show
  1. package/package.json +8 -29
  2. package/src/index.ts +9 -56
  3. package/src/storefront.ts +13 -0
  4. package/src/storefrontTypes.ts +6 -0
  5. package/src/utils/gql.ts +23 -0
  6. package/src/utils/graphql/queries.ts +1 -1
  7. package/src/wakeClient.ts +104 -0
  8. package/src/actions/cart/addCoupon.ts +0 -43
  9. package/src/actions/cart/addItem.ts +0 -10
  10. package/src/actions/cart/addItems.ts +0 -50
  11. package/src/actions/cart/addKit.ts +0 -53
  12. package/src/actions/cart/partnerAssociate.ts +0 -48
  13. package/src/actions/cart/partnerDisassociate.ts +0 -43
  14. package/src/actions/cart/removeCoupon.ts +0 -39
  15. package/src/actions/cart/removeKit.ts +0 -56
  16. package/src/actions/cart/updateItemQuantity.ts +0 -69
  17. package/src/actions/newsletter/register.ts +0 -32
  18. package/src/actions/notifyme.ts +0 -28
  19. package/src/actions/review/create.ts +0 -30
  20. package/src/actions/shippingSimulation.ts +0 -60
  21. package/src/actions/submmitForm.ts +0 -25
  22. package/src/actions/wishlist/addProduct.ts +0 -43
  23. package/src/actions/wishlist/removeProduct.ts +0 -45
  24. package/src/client.ts +0 -123
  25. package/src/commerceLoaders.ts +0 -137
  26. package/src/handlers/sitemap.ts +0 -61
  27. package/src/loaders/cart.ts +0 -46
  28. package/src/loaders/partners.ts +0 -58
  29. package/src/loaders/productDetailsPage.ts +0 -174
  30. package/src/loaders/productList.ts +0 -262
  31. package/src/loaders/productListingPage.ts +0 -333
  32. package/src/loaders/proxy.ts +0 -79
  33. package/src/loaders/recommendations.ts +0 -84
  34. package/src/loaders/shop.ts +0 -37
  35. package/src/loaders/suggestion.ts +0 -67
  36. package/src/loaders/user.ts +0 -48
  37. package/src/loaders/wishlist.ts +0 -40
  38. package/src/manifest.gen.ts +0 -69
  39. package/src/mod.ts +0 -88
  40. package/src/registry.ts +0 -9
  41. package/src/utils/authError.ts +0 -107
  42. package/src/utils/authenticate.ts +0 -42
  43. package/src/utils/capitalize.ts +0 -9
  44. package/src/utils/cart.ts +0 -33
  45. package/src/utils/cookies.ts +0 -82
  46. package/src/utils/getVariations.ts +0 -47
  47. package/src/utils/graphql.ts +0 -88
  48. package/src/utils/httpError.ts +0 -15
  49. package/src/utils/instrumentedFetch.ts +0 -46
  50. package/src/utils/operationRouter.ts +0 -51
  51. package/src/utils/parseHeaders.ts +0 -19
  52. package/src/utils/partner.ts +0 -34
  53. package/src/utils/requestCtx.ts +0 -41
  54. package/src/utils/transform.ts +0 -460
  55. package/src/utils/types.ts +0 -6
  56. package/src/utils/user.ts +0 -9
  57. package/tsconfig.json +0 -7
@@ -1,69 +0,0 @@
1
- import { getWakeClient } from "../../client";
2
- import cartLoader from "../../loaders/cart";
3
- import { getCartCookie, setCartCookie } from "../../utils/cart";
4
- import { RemoveItemFromCart } from "../../utils/graphql/queries";
5
- import type {
6
- CheckoutFragment,
7
- RemoveItemFromCartMutation,
8
- } from "../../utils/graphql/storefront.graphql.gen";
9
- import { HttpError } from "../../utils/httpError";
10
- import {
11
- currentRequestHeaders,
12
- currentResponseHeaders,
13
- forwardedHeaders,
14
- } from "../../utils/requestCtx";
15
- import addItem from "./addItem";
16
-
17
- export interface Props {
18
- productVariantId: number;
19
- quantity: number;
20
- customization?: { customizationId: number; value: string }[];
21
- subscription?: { subscriptionGroupId: number; recurringTypeId: number };
22
- }
23
-
24
- const removeFromCart = (props: Props, cartId: string, headers: Record<string, string>) =>
25
- getWakeClient().query<RemoveItemFromCartMutation>(
26
- RemoveItemFromCart,
27
- { input: { id: cartId, products: [props] } },
28
- headers,
29
- );
30
-
31
- const action = async (props: Props): Promise<Partial<CheckoutFragment>> => {
32
- const cartId = getCartCookie(currentRequestHeaders());
33
- const headers = forwardedHeaders();
34
-
35
- if (!cartId) {
36
- throw new HttpError(400, "Missing cart cookie");
37
- }
38
-
39
- /*
40
- * get cart
41
- * find the current product on cart
42
- * the current amount
43
- * calculate the difference between the current item amount and requested new amount
44
- */
45
-
46
- const cart = await cartLoader();
47
- const item = cart.products?.find((item) => item?.productVariantId === props.productVariantId);
48
- const quantityItem = item?.quantity ?? 0;
49
- const quantity = props.quantity - quantityItem;
50
-
51
- let checkout: Partial<CheckoutFragment> | undefined;
52
-
53
- if (props.quantity > 0 && quantity > 0) {
54
- checkout = await addItem({ ...props, quantity });
55
- } else {
56
- const data = await removeFromCart({ ...props, quantity: -quantity }, cartId, headers);
57
- checkout = data.checkout ?? undefined;
58
- }
59
-
60
- const checkoutId = checkout?.checkoutId;
61
-
62
- if (checkoutId && cartId !== checkoutId) {
63
- setCartCookie(currentResponseHeaders(), checkoutId);
64
- }
65
-
66
- return checkout ?? {};
67
- };
68
-
69
- export default action;
@@ -1,32 +0,0 @@
1
- import { getWakeClient } from "../../client";
2
- import { CreateNewsletterRegister } from "../../utils/graphql/queries";
3
- import type {
4
- CreateNewsletterRegisterMutation,
5
- NewsletterNode,
6
- } from "../../utils/graphql/storefront.graphql.gen";
7
- import { HttpError } from "../../utils/httpError";
8
- import { forwardedHeaders } from "../../utils/requestCtx";
9
-
10
- export interface Props {
11
- email: string;
12
- name: string;
13
- }
14
-
15
- const action = async (props: Props): Promise<NewsletterNode> => {
16
- const storefront = getWakeClient();
17
- const headers = forwardedHeaders();
18
-
19
- const data = await storefront.query<CreateNewsletterRegisterMutation>(
20
- CreateNewsletterRegister,
21
- { input: { ...props } },
22
- headers,
23
- );
24
-
25
- if (!data.createNewsletterRegister) {
26
- throw new HttpError(400, "Error on Register");
27
- }
28
-
29
- return data.createNewsletterRegister;
30
- };
31
-
32
- export default action;
@@ -1,28 +0,0 @@
1
- import { getWakeClient } from "../client";
2
- import { ProductRestockAlert } from "../utils/graphql/queries";
3
- import type {
4
- ProductRestockAlertMutation,
5
- RestockAlertNode,
6
- } from "../utils/graphql/storefront.graphql.gen";
7
- import { forwardedHeaders } from "../utils/requestCtx";
8
-
9
- export interface Props {
10
- email: string;
11
- name: string;
12
- productVariantId: number;
13
- }
14
-
15
- const action = async (props: Props): Promise<RestockAlertNode | null> => {
16
- const storefront = getWakeClient();
17
- const headers = forwardedHeaders();
18
-
19
- const data = await storefront.query<ProductRestockAlertMutation>(
20
- ProductRestockAlert,
21
- { input: props },
22
- headers,
23
- );
24
-
25
- return data.productRestockAlert ?? null;
26
- };
27
-
28
- export default action;
@@ -1,30 +0,0 @@
1
- import { getWakeClient } from "../../client";
2
- import { CreateProductReview } from "../../utils/graphql/queries";
3
- import type {
4
- CreateProductReviewMutation,
5
- Review,
6
- } from "../../utils/graphql/storefront.graphql.gen";
7
- import { forwardedHeaders } from "../../utils/requestCtx";
8
-
9
- export interface Props {
10
- email: string;
11
- name: string;
12
- productVariantId: number;
13
- rating: number;
14
- review: string;
15
- }
16
-
17
- const action = async (props: Props): Promise<Review | null> => {
18
- const storefront = getWakeClient();
19
- const headers = forwardedHeaders();
20
-
21
- const data = await storefront.query<CreateProductReviewMutation>(
22
- CreateProductReview,
23
- props as unknown as Record<string, unknown>,
24
- headers,
25
- );
26
-
27
- return data.createProductReview ?? null;
28
- };
29
-
30
- export default action;
@@ -1,60 +0,0 @@
1
- import { getWakeClient } from "../client";
2
- import { getCartCookie } from "../utils/cart";
3
- import { ShippingQuotes } from "../utils/graphql/queries";
4
- import type {
5
- ShippingQuotesQuery,
6
- ShippingQuotesQueryVariables,
7
- } from "../utils/graphql/storefront.graphql.gen";
8
- import { HttpError } from "../utils/httpError";
9
- import { currentRequestHeaders, forwardedHeaders } from "../utils/requestCtx";
10
-
11
- export interface Props {
12
- cep?: string;
13
- simulateCartItems?: boolean;
14
- productVariantId?: number;
15
- quantity?: number;
16
- useSelectedAddress?: boolean;
17
- }
18
-
19
- const buildSimulationParams = (props: Props, checkoutId?: string): ShippingQuotesQueryVariables => {
20
- const { cep, simulateCartItems, productVariantId, quantity, useSelectedAddress } = props;
21
-
22
- const defaultQueryParams = {
23
- cep,
24
- useSelectedAddress,
25
- };
26
-
27
- if (simulateCartItems) {
28
- if (!checkoutId) throw new HttpError(400, "Missing cart cookie");
29
-
30
- return {
31
- ...defaultQueryParams,
32
- checkoutId,
33
- };
34
- }
35
-
36
- return {
37
- ...defaultQueryParams,
38
- productVariantId,
39
- quantity,
40
- };
41
- };
42
-
43
- const action = async (props: Props): Promise<ShippingQuotesQuery["shippingQuotes"]> => {
44
- const storefront = getWakeClient();
45
- const headers = forwardedHeaders();
46
-
47
- const cartId = getCartCookie(currentRequestHeaders());
48
-
49
- const simulationParams = buildSimulationParams(props, cartId);
50
-
51
- const data = await storefront.query<ShippingQuotesQuery>(
52
- ShippingQuotes,
53
- { ...simulationParams },
54
- headers,
55
- );
56
-
57
- return data.shippingQuotes ?? [];
58
- };
59
-
60
- export default action;
@@ -1,25 +0,0 @@
1
- import { getWakeClient } from "../client";
2
- import { SendGenericForm } from "../utils/graphql/queries";
3
- import type { SendGenericFormMutation } from "../utils/graphql/storefront.graphql.gen";
4
- import { forwardedHeaders } from "../utils/requestCtx";
5
-
6
- export interface Props {
7
- body: unknown;
8
- // file: Upload,
9
- recaptchaToken: string;
10
- }
11
-
12
- const action = async (props: Props): Promise<SendGenericFormMutation["sendGenericForm"]> => {
13
- const storefront = getWakeClient();
14
- const headers = forwardedHeaders();
15
-
16
- const data = await storefront.query<SendGenericFormMutation>(
17
- SendGenericForm,
18
- props as unknown as Record<string, unknown>,
19
- headers,
20
- );
21
-
22
- return data.sendGenericForm!;
23
- };
24
-
25
- export default action;
@@ -1,43 +0,0 @@
1
- import { getWakeClient } from "../../client";
2
- import authenticate from "../../utils/authenticate";
3
- import { WishlistAddProduct } from "../../utils/graphql/queries";
4
- import type {
5
- ProductFragment,
6
- WishlistAddProductMutation,
7
- WishlistReducedProductFragment,
8
- } from "../../utils/graphql/storefront.graphql.gen";
9
- import { forwardedHeaders } from "../../utils/requestCtx";
10
-
11
- export interface Props {
12
- productId: number;
13
- }
14
-
15
- const action = async (props: Props): Promise<WishlistReducedProductFragment[] | null> => {
16
- const storefront = getWakeClient();
17
- const { productId } = props;
18
- const customerAccessToken = await authenticate();
19
- const headers = forwardedHeaders();
20
-
21
- if (!customerAccessToken) return [];
22
-
23
- const data = await storefront.query<WishlistAddProductMutation>(
24
- WishlistAddProduct,
25
- { customerAccessToken, productId },
26
- headers,
27
- );
28
-
29
- const products = data.wishlistAddProduct;
30
-
31
- if (!Array.isArray(products)) {
32
- return null;
33
- }
34
-
35
- return products
36
- .filter((node): node is ProductFragment => Boolean(node))
37
- .map(({ productId, productName }) => ({
38
- productId,
39
- productName,
40
- }));
41
- };
42
-
43
- export default action;
@@ -1,45 +0,0 @@
1
- import { getWakeClient } from "../../client";
2
- import authenticate from "../../utils/authenticate";
3
- import { WishlistRemoveProduct } from "../../utils/graphql/queries";
4
- import type {
5
- ProductFragment,
6
- WishlistReducedProductFragment,
7
- WishlistRemoveProductMutation,
8
- } from "../../utils/graphql/storefront.graphql.gen";
9
- import { forwardedHeaders } from "../../utils/requestCtx";
10
-
11
- export interface Props {
12
- productId: number;
13
- }
14
-
15
- const action = async (props: Props): Promise<WishlistReducedProductFragment[] | null> => {
16
- const storefront = getWakeClient();
17
- const { productId } = props;
18
-
19
- const headers = forwardedHeaders();
20
-
21
- const customerAccessToken = await authenticate();
22
-
23
- if (!customerAccessToken) return [];
24
-
25
- const data = await storefront.query<WishlistRemoveProductMutation>(
26
- WishlistRemoveProduct,
27
- { customerAccessToken, productId },
28
- headers,
29
- );
30
-
31
- const products = data.wishlistRemoveProduct;
32
-
33
- if (!Array.isArray(products)) {
34
- return null;
35
- }
36
-
37
- return products
38
- .filter((node): node is ProductFragment => Boolean(node))
39
- .map(({ productId, productName }) => ({
40
- productId,
41
- productName,
42
- }));
43
- };
44
-
45
- export default action;
package/src/client.ts DELETED
@@ -1,123 +0,0 @@
1
- import type { FetchFn } from "@decocms/blocks/sdk/fetchTimeout";
2
- import { createGraphqlClient, type GraphQLClient } from "./utils/graphql";
3
-
4
- export interface WakeConfig {
5
- /** Wake account name, e.g. "erploja2". */
6
- account: string;
7
- /**
8
- * Checkout/login domain, e.g. "https://secure.sprint55.com.br". Used only for
9
- * the checkout REST API (login/cart) and proxy — NOT for the storefront
10
- * GraphQL, which is a fixed multi-tenant endpoint resolved by the token.
11
- */
12
- checkoutUrl: string;
13
- /** Wake Storefront API token (sent as `TCS-Access-Token`). */
14
- storefrontToken: string;
15
- /**
16
- * Storefront GraphQL endpoint. Defaults to Wake's canonical multi-tenant
17
- * endpoint; override only for a custom storefront host.
18
- */
19
- storefrontEndpoint?: string;
20
- /** Wake Admin API token (Basic auth). Currently unused by the loaders/actions. */
21
- token?: string;
22
- }
23
-
24
- const STOREFRONT_ENDPOINT = "https://storefront-api.fbits.net/graphql";
25
-
26
- /**
27
- * Read an env var. Wake's tokens are provided ONLY via environment variables
28
- * (no CMS secret / `resolveSecret`): `WAKE_TOKEN` (storefront) and, if ever
29
- * needed, `WAKE_KEY` (admin). `process.env` is populated in Node and in
30
- * Cloudflare Workers via `nodejs_compat` — the same source the framework's
31
- * own `getEnvVar()` reads first.
32
- */
33
- function readEnv(name: string): string | undefined {
34
- const env = (globalThis as { process?: { env?: Record<string, string | undefined> } }).process
35
- ?.env;
36
- const value = env?.[name];
37
- return value && value.length > 0 ? value : undefined;
38
- }
39
-
40
- /** Wake Storefront API token from `WAKE_TOKEN`. */
41
- export function getWakeStorefrontTokenFromEnv(): string | undefined {
42
- return readEnv("WAKE_TOKEN");
43
- }
44
-
45
- /** Wake Admin API token from `WAKE_KEY` (currently unused by loaders/actions). */
46
- export function getWakeAdminTokenFromEnv(): string | undefined {
47
- return readEnv("WAKE_KEY");
48
- }
49
-
50
- let _client: GraphQLClient | null = null;
51
- let _config: WakeConfig | null = null;
52
- let _fetch: FetchFn | undefined;
53
-
54
- /**
55
- * Override the fetch function used by the Wake GraphQL client. Use this to plug
56
- * in an instrumented fetch for logging/tracing.
57
- *
58
- * @example
59
- * ```ts
60
- * import { createInstrumentedFetch } from "@decocms/blocks/sdk/instrumentedFetch";
61
- * import { setWakeFetch } from "@decocms/apps-wake";
62
- * setWakeFetch(createInstrumentedFetch("wake"));
63
- * ```
64
- */
65
- export function setWakeFetch(fetchFn: FetchFn) {
66
- _fetch = fetchFn;
67
- if (_config) configureWake(_config);
68
- }
69
-
70
- export function configureWake(config: WakeConfig) {
71
- _config = config;
72
- const endpoint = config.storefrontEndpoint || STOREFRONT_ENDPOINT;
73
- _client = createGraphqlClient(
74
- endpoint,
75
- {
76
- "TCS-Access-Token": config.storefrontToken,
77
- },
78
- _fetch,
79
- );
80
- }
81
-
82
- export function getWakeClient(): GraphQLClient {
83
- if (!_client || !_config) {
84
- throw new Error(
85
- "Wake not configured. Call configureWake() first or check deco-wake.json block.",
86
- );
87
- }
88
- return _client;
89
- }
90
-
91
- export function getWakeConfig(): WakeConfig {
92
- if (!_config) {
93
- throw new Error("Wake not configured.");
94
- }
95
- return _config;
96
- }
97
-
98
- /** Base URL of the checkout REST API (`GET /api/Login/Get`, proxied paths). */
99
- export function getCheckoutUrl(): string {
100
- const config = getWakeConfig();
101
- return config.checkoutUrl || `https://${config.account}.checkout.fbits.store`;
102
- }
103
-
104
- export function getBaseUrl(): string {
105
- return _config?.checkoutUrl || "";
106
- }
107
-
108
- /**
109
- * Convenience initializer used by the site setup: reads the Wake app block from
110
- * the generated blocks map and configures the singleton.
111
- */
112
- export function initWakeFromBlocks(blocks: Record<string, unknown>) {
113
- const block = (blocks.wake ?? blocks["deco-wake"]) as Partial<WakeConfig> | undefined;
114
- if (!block?.account) return;
115
- configureWake({
116
- account: block.account as string,
117
- checkoutUrl: (block.checkoutUrl as string) ?? "",
118
- // Tokens come from env only (WAKE_TOKEN / WAKE_KEY), never the CMS block.
119
- storefrontToken: getWakeStorefrontTokenFromEnv() ?? "",
120
- storefrontEndpoint: block.storefrontEndpoint as string | undefined,
121
- token: getWakeAdminTokenFromEnv(),
122
- });
123
- }
@@ -1,137 +0,0 @@
1
- /**
2
- * Standard Wake commerce loader map factory for CMS block resolution.
3
- *
4
- * Wraps the cacheable catalog loaders with `createCachedLoader` (single-flight
5
- * dedup + SWR + stale-if-error via the unified cache profiles), applies the
6
- * PDP slug fallback and PLP page-URL resolution, and registers both `.ts` and
7
- * `.ts`-less aliases.
8
- *
9
- * Sites call `createWakeCommerceLoaders()` and hand the result to
10
- * `registerCommerceLoaders(...)` instead of wiring each loader (and its cache
11
- * policy) by hand — mirroring `createVtexCommerceLoaders()`.
12
- *
13
- * User-specific loaders (cart/user/wishlist) are intentionally NOT included:
14
- * they are per-session and must not be cached; the app manifest registers them
15
- * uncached via `autoconfigApps`.
16
- */
17
-
18
- import { createCachedLoader } from "@decocms/blocks/sdk/cachedLoader";
19
- import type { CacheProfileName } from "@decocms/blocks/sdk/cacheHeaders";
20
- import { RequestContext } from "@decocms/blocks/sdk/requestContext";
21
- import partnersLoader from "./loaders/partners";
22
- import productDetailsPage from "./loaders/productDetailsPage";
23
- import productList from "./loaders/productList";
24
- import productListingPage from "./loaders/productListingPage";
25
- import recommendations from "./loaders/recommendations";
26
- import shopLoader from "./loaders/shop";
27
- import suggestion from "./loaders/suggestion";
28
-
29
- export type CommerceLoaderFn = (props: any) => Promise<any>;
30
-
31
- export interface WakeCommerceLoadersOptions {
32
- /** Override cache profiles per loader type. */
33
- cacheProfiles?: {
34
- listing?: CacheProfileName;
35
- product?: CacheProfileName;
36
- search?: CacheProfileName;
37
- static?: CacheProfileName;
38
- };
39
- /** Additional loaders to merge into the map (site-specific). */
40
- extra?: Record<string, CommerceLoaderFn>;
41
- }
42
-
43
- const PAGE_URL_HEADER = "x-deco-page-url";
44
-
45
- /**
46
- * Resolve the real page URL for the productListingPage loader. Wake's PLP reads
47
- * the URL from `props.pageHref`; the framework injects `__pageUrl`, but on CSR
48
- * home navigations that is unreliable, so an explicit `x-deco-page-url` header
49
- * (set by the site) wins, then `__pageUrl`, then the worker request URL.
50
- */
51
- function resolvePageHref(props: any): string | undefined {
52
- try {
53
- const headerUrl = RequestContext.request.headers.get(PAGE_URL_HEADER);
54
- if (headerUrl) return new URL(headerUrl, "http://localhost").href;
55
- } catch {
56
- // RequestContext may be unavailable in isolated calls.
57
- }
58
- if (props?.__pageUrl) {
59
- try {
60
- return new URL(props.__pageUrl, "http://localhost").href;
61
- } catch {
62
- // ignore malformed injected URL
63
- }
64
- }
65
- try {
66
- return new URL(RequestContext.request.url).href;
67
- } catch {
68
- return props?.pageHref;
69
- }
70
- }
71
-
72
- /** Bridge `__pagePath` → `slug` when the CMS doesn't set slug explicitly. */
73
- function pdpWithSlugFallback(props: any): Promise<any> {
74
- if ((!props.slug || props.slug.length === 0) && props.__pagePath) {
75
- props = { ...props, slug: props.__pagePath };
76
- }
77
- return productDetailsPage(props);
78
- }
79
-
80
- export function createWakeCommerceLoaders(
81
- options?: WakeCommerceLoadersOptions,
82
- ): Record<string, CommerceLoaderFn> {
83
- const profiles = {
84
- listing: options?.cacheProfiles?.listing ?? "listing",
85
- product: options?.cacheProfiles?.product ?? "product",
86
- search: options?.cacheProfiles?.search ?? "search",
87
- static: options?.cacheProfiles?.static ?? "static",
88
- };
89
-
90
- const cachedPDP = createCachedLoader(
91
- "wake/productDetailsPage",
92
- pdpWithSlugFallback,
93
- profiles.product,
94
- );
95
- const _cachedPLP = createCachedLoader(
96
- "wake/productListingPage",
97
- productListingPage,
98
- profiles.listing,
99
- );
100
- const cachedProductList = createCachedLoader("wake/productList", productList, profiles.listing);
101
- const cachedSuggestion = createCachedLoader("wake/suggestion", suggestion, profiles.search);
102
- const cachedRecommendations = createCachedLoader(
103
- "wake/recommendations",
104
- recommendations,
105
- profiles.product,
106
- );
107
- const cachedShop = createCachedLoader("wake/shop", shopLoader, profiles.static);
108
- const cachedPartners = createCachedLoader("wake/partners", partnersLoader, profiles.static);
109
-
110
- // PLP wrapper: forward the resolved page URL as `pageHref` before caching.
111
- const cachedPLP: CommerceLoaderFn = (props) =>
112
- _cachedPLP({ ...props, pageHref: resolvePageHref(props) ?? props?.pageHref });
113
-
114
- const loaders: Record<string, CommerceLoaderFn> = {
115
- "wake/loaders/productDetailsPage.ts": cachedPDP,
116
- "wake/loaders/productListingPage.ts": cachedPLP,
117
- "wake/loaders/productList.ts": cachedProductList,
118
- "wake/loaders/suggestion.ts": cachedSuggestion,
119
- "wake/loaders/recommendations.ts": cachedRecommendations,
120
- "wake/loaders/shop.ts": cachedShop,
121
- "wake/loaders/partners.ts": cachedPartners,
122
- };
123
-
124
- // Register .ts-less aliases for invoke compatibility.
125
- const withAliases: Record<string, CommerceLoaderFn> = { ...loaders };
126
- for (const key of Object.keys(loaders)) {
127
- if (key.endsWith(".ts")) {
128
- withAliases[key.slice(0, -3)] = loaders[key];
129
- }
130
- }
131
-
132
- if (options?.extra) {
133
- Object.assign(withAliases, options.extra);
134
- }
135
-
136
- return withAliases;
137
- }
@@ -1,61 +0,0 @@
1
- import { withFetchTimeout } from "@decocms/blocks/sdk/fetchTimeout";
2
- import { getWakeConfig } from "../client";
3
-
4
- const fetchSafe = withFetchTimeout();
5
-
6
- const BASE_SITEMAP_URL = "https://p-general-sitemap-public.s3.us-east-2.amazonaws.com/Sitemap";
7
-
8
- const xmlHeader = '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
9
-
10
- const includeSiteMaps = (currentXML: string, origin: string, includes?: string[]) => {
11
- const siteMapIncludeTags: string[] = [];
12
-
13
- for (const include of includes ?? []) {
14
- siteMapIncludeTags.push(`
15
- <sitemap>
16
- <loc>${include.startsWith("/") ? `${origin}${include}` : include}</loc>
17
- <lastmod>${new Date().toISOString().substring(0, 10)}</lastmod>
18
- </sitemap>
19
- `);
20
- }
21
-
22
- return siteMapIncludeTags.length > 0
23
- ? currentXML.replace(xmlHeader, `${xmlHeader}\n${siteMapIncludeTags.join("\n")}`)
24
- : currentXML;
25
- };
26
-
27
- export interface Props {
28
- include?: string[];
29
- }
30
-
31
- /**
32
- * @title Sitemap Proxy
33
- *
34
- * Returns a request handler that proxies the Wake public S3 sitemap for the
35
- * configured account, rewriting the public URL to the current origin and
36
- * optionally injecting extra `<sitemap>` entries.
37
- */
38
- export default function Sitemap({ include }: Props = {}) {
39
- return async (req: Request): Promise<Response> => {
40
- const { account } = getWakeConfig();
41
-
42
- if (!account) {
43
- throw new Error("Missing account");
44
- }
45
-
46
- const publicUrl = `${BASE_SITEMAP_URL}/${encodeURIComponent(account)}/`;
47
-
48
- const response = await fetchSafe(publicUrl);
49
-
50
- const reqUrl = new URL(req.url);
51
- const text = await response.text();
52
-
53
- return new Response(
54
- includeSiteMaps(text.replaceAll(publicUrl, `${reqUrl.origin}/`), reqUrl.origin, include),
55
- {
56
- headers: response.headers,
57
- status: response.status,
58
- },
59
- );
60
- };
61
- }