@decocms/apps-vtex 8.1.0-next.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 (139) hide show
  1. package/package.json +7 -52
  2. package/src/index.ts +10 -28
  3. package/src/utils/constants.ts +2 -56
  4. package/src/utils/cookieSanitizer.ts +59 -59
  5. package/src/utils/operationRouter.ts +75 -65
  6. package/src/utils/types.ts +709 -1557
  7. package/src/vtexClient.ts +354 -343
  8. package/src/README.md +0 -6
  9. package/src/__conformance__/upstream.test.ts +0 -158
  10. package/src/__tests__/client-segment-cookie.test.ts +0 -255
  11. package/src/__tests__/client-set-cookie-forward.test.ts +0 -257
  12. package/src/__tests__/schemas.test.ts +0 -71
  13. package/src/actions/address.ts +0 -250
  14. package/src/actions/analytics/sendEvent.ts +0 -86
  15. package/src/actions/auth.ts +0 -333
  16. package/src/actions/checkout.ts +0 -659
  17. package/src/actions/index.ts +0 -11
  18. package/src/actions/masterData.ts +0 -168
  19. package/src/actions/misc.ts +0 -188
  20. package/src/actions/newsletter.ts +0 -105
  21. package/src/actions/orders.ts +0 -34
  22. package/src/actions/profile.ts +0 -201
  23. package/src/actions/session.ts +0 -85
  24. package/src/actions/trigger.ts +0 -43
  25. package/src/actions/wishlist.ts +0 -114
  26. package/src/client.ts +0 -724
  27. package/src/commerceLoaders.ts +0 -267
  28. package/src/hooks/__tests__/createCart.render.test.ts +0 -114
  29. package/src/hooks/__tests__/createCart.test.ts +0 -92
  30. package/src/hooks/__tests__/createUseCart.test.ts +0 -184
  31. package/src/hooks/__tests__/createUseUser.test.ts +0 -48
  32. package/src/hooks/__tests__/createUseWishlist.test.ts +0 -87
  33. package/src/hooks/cartQuery.ts +0 -204
  34. package/src/hooks/createCart.ts +0 -427
  35. package/src/hooks/createUseCart.ts +0 -360
  36. package/src/hooks/createUseUser.ts +0 -153
  37. package/src/hooks/createUseWishlist.ts +0 -242
  38. package/src/hooks/index.ts +0 -25
  39. package/src/hooks/useAutocomplete.ts +0 -83
  40. package/src/hooks/useCart.ts +0 -243
  41. package/src/hooks/useUser.ts +0 -78
  42. package/src/hooks/useWishlist.ts +0 -119
  43. package/src/invoke.ts +0 -235
  44. package/src/loaders/ProductDetailsPage.ts +0 -1
  45. package/src/loaders/ProductList.ts +0 -1
  46. package/src/loaders/ProductListingPage.ts +0 -1
  47. package/src/loaders/__tests__/legacyProductList.test.ts +0 -157
  48. package/src/loaders/address.ts +0 -115
  49. package/src/loaders/autocomplete.ts +0 -56
  50. package/src/loaders/brands.ts +0 -44
  51. package/src/loaders/cart/attachments.ts +0 -53
  52. package/src/loaders/cart/full.ts +0 -67
  53. package/src/loaders/cart/gifts.ts +0 -43
  54. package/src/loaders/cart/orderFormId.ts +0 -31
  55. package/src/loaders/cart/shipping.test.ts +0 -125
  56. package/src/loaders/cart/shipping.ts +0 -136
  57. package/src/loaders/cart/summary.ts +0 -36
  58. package/src/loaders/cart.ts +0 -52
  59. package/src/loaders/catalog.ts +0 -163
  60. package/src/loaders/collections.ts +0 -55
  61. package/src/loaders/index.ts +0 -20
  62. package/src/loaders/intelligentSearch/__tests__/productListingPage.test.ts +0 -51
  63. package/src/loaders/intelligentSearch/productDetailsPage.ts +0 -111
  64. package/src/loaders/intelligentSearch/productList.ts +0 -170
  65. package/src/loaders/intelligentSearch/productListingPage.ts +0 -525
  66. package/src/loaders/intelligentSearch/suggestions.ts +0 -44
  67. package/src/loaders/legacy/productDetailsPage.ts +0 -1
  68. package/src/loaders/legacy/productList.ts +0 -1
  69. package/src/loaders/legacy/relatedProductsLoader.ts +0 -79
  70. package/src/loaders/legacy.ts +0 -710
  71. package/src/loaders/logistics.ts +0 -111
  72. package/src/loaders/minicart.ts +0 -78
  73. package/src/loaders/navbar.ts +0 -26
  74. package/src/loaders/orders.ts +0 -92
  75. package/src/loaders/pageType.ts +0 -68
  76. package/src/loaders/paths/PDPDefaultPath.ts +0 -51
  77. package/src/loaders/payment.ts +0 -97
  78. package/src/loaders/productListFull.ts +0 -157
  79. package/src/loaders/profile.ts +0 -138
  80. package/src/loaders/promotion.ts +0 -30
  81. package/src/loaders/search.ts +0 -124
  82. package/src/loaders/session.ts +0 -83
  83. package/src/loaders/user.ts +0 -87
  84. package/src/loaders/wishlist.ts +0 -89
  85. package/src/loaders/wishlistProducts.ts +0 -69
  86. package/src/loaders/workflow/products.ts +0 -62
  87. package/src/loaders/workflow.ts +0 -316
  88. package/src/logo.png +0 -0
  89. package/src/manifest.gen.ts +0 -89
  90. package/src/middleware.cacheHeaders.test.ts +0 -44
  91. package/src/middleware.ts +0 -240
  92. package/src/mod.ts +0 -173
  93. package/src/registry.ts +0 -9
  94. package/src/schemas.gen.ts +0 -3191
  95. package/src/schemas.ts +0 -30
  96. package/src/types.ts +0 -248
  97. package/src/utils/__tests__/cartProjection.test.ts +0 -118
  98. package/src/utils/__tests__/cookieSanitizer.test.ts +0 -162
  99. package/src/utils/__tests__/fetch.test.ts +0 -80
  100. package/src/utils/__tests__/fetchCache.test.ts +0 -155
  101. package/src/utils/__tests__/instrumentedFetch.test.ts +0 -158
  102. package/src/utils/__tests__/intelligentSearch.test.ts +0 -88
  103. package/src/utils/__tests__/minicart.test.ts +0 -184
  104. package/src/utils/__tests__/operationRouter.test.ts +0 -227
  105. package/src/utils/__tests__/resilience.test.ts +0 -205
  106. package/src/utils/__tests__/resourceRange.test.ts +0 -32
  107. package/src/utils/__tests__/simulationCache.test.ts +0 -40
  108. package/src/utils/__tests__/sitemap.test.ts +0 -185
  109. package/src/utils/__tests__/slugify.test.ts +0 -31
  110. package/src/utils/__tests__/storefrontBaseUrl.test.ts +0 -61
  111. package/src/utils/__tests__/transform.test.ts +0 -1111
  112. package/src/utils/accountLoaders.ts +0 -203
  113. package/src/utils/authHelpers.ts +0 -85
  114. package/src/utils/batch.ts +0 -18
  115. package/src/utils/buildOfferShelf.test.ts +0 -59
  116. package/src/utils/cartProjection.ts +0 -96
  117. package/src/utils/cookies.ts +0 -167
  118. package/src/utils/enrichment.ts +0 -556
  119. package/src/utils/fetch.ts +0 -111
  120. package/src/utils/fetchCache.ts +0 -55
  121. package/src/utils/index.ts +0 -19
  122. package/src/utils/instrumentedFetch.ts +0 -98
  123. package/src/utils/intelligentSearch.ts +0 -96
  124. package/src/utils/legacy.ts +0 -139
  125. package/src/utils/minicart.ts +0 -139
  126. package/src/utils/pickAndOmit.ts +0 -25
  127. package/src/utils/proxy.ts +0 -495
  128. package/src/utils/resilience.ts +0 -352
  129. package/src/utils/resourceRange.ts +0 -10
  130. package/src/utils/segment.ts +0 -152
  131. package/src/utils/similars.ts +0 -35
  132. package/src/utils/simulationCache.ts +0 -73
  133. package/src/utils/sitemap.ts +0 -283
  134. package/src/utils/slugCache.ts +0 -28
  135. package/src/utils/slugify.ts +0 -13
  136. package/src/utils/transform.ts +0 -1691
  137. package/src/utils/vtexId.ts +0 -151
  138. package/src/vtexClient.test.ts +0 -204
  139. package/tsconfig.json +0 -7
@@ -1,87 +0,0 @@
1
- /**
2
- * Tests for the `createUseWishlist` factory.
3
- *
4
- * The hook itself depends on React (useState/useEffect), and apps-start
5
- * does not pull in @testing-library/react. So we test the parts that
6
- * don't require a renderer: factory shape, isolation, and the pure
7
- * helpers `findWishlistEntry` + `legacyAddArgsToCanonical` which encode
8
- * the most error-prone invariants (id matching + legacy arg swap).
9
- */
10
-
11
- import { describe, expect, it } from "vitest";
12
- import type { WishlistItem } from "../../loaders/wishlist";
13
- import {
14
- type CreateUseWishlistInvoke,
15
- createUseWishlist,
16
- findWishlistEntry,
17
- legacyAddArgsToCanonical,
18
- } from "../createUseWishlist";
19
-
20
- function makeInvoke(): CreateUseWishlistInvoke {
21
- return {
22
- vtex: {
23
- loaders: {
24
- wishlist: async () => [],
25
- },
26
- actions: {
27
- addToWishlist: async () => [],
28
- removeFromWishlist: async () => [],
29
- },
30
- },
31
- };
32
- }
33
-
34
- describe("createUseWishlist — factory shape", () => {
35
- it("returns useWishlist, resetWishlist", () => {
36
- const w = createUseWishlist({ invoke: makeInvoke() });
37
- expect(typeof w.useWishlist).toBe("function");
38
- expect(typeof w.resetWishlist).toBe("function");
39
- });
40
-
41
- it("two factory calls produce independent function references", () => {
42
- const a = createUseWishlist({ invoke: makeInvoke() });
43
- const b = createUseWishlist({ invoke: makeInvoke() });
44
- expect(a.useWishlist).not.toBe(b.useWishlist);
45
- expect(a.resetWishlist).not.toBe(b.resetWishlist);
46
- });
47
- });
48
-
49
- describe("legacyAddArgsToCanonical — arg swap", () => {
50
- it("maps legacy (productId=sku, productGroupId=parent) to canonical { productId, sku }", () => {
51
- // In analytics terms: item_id is the SKU; item_group_id is the
52
- // VTEX productId. Sites destructure these from analytics objects
53
- // and pass them to wishlist.addItem in that order.
54
- const out = legacyAddArgsToCanonical("sku-1", "prod-100");
55
- expect(out).toEqual({ productId: "prod-100", sku: "sku-1" });
56
- });
57
-
58
- it("preserves empty strings without coercing", () => {
59
- const out = legacyAddArgsToCanonical("", "");
60
- expect(out).toEqual({ productId: "", sku: "" });
61
- });
62
- });
63
-
64
- describe("findWishlistEntry — id matching", () => {
65
- const items: WishlistItem[] = [
66
- { id: "entry-1", productId: "prod-1", sku: "sku-1", title: "A" },
67
- { id: "entry-2", productId: "prod-2", sku: "sku-2", title: "B" },
68
- ];
69
-
70
- it("matches by sku (the legacy `productId` arg passed by sites)", () => {
71
- const entry = findWishlistEntry(items, "sku-1");
72
- expect(entry?.id).toBe("entry-1");
73
- });
74
-
75
- it("matches by productId as a fallback", () => {
76
- const entry = findWishlistEntry(items, "prod-2");
77
- expect(entry?.id).toBe("entry-2");
78
- });
79
-
80
- it("returns undefined when no match", () => {
81
- expect(findWishlistEntry(items, "missing")).toBeUndefined();
82
- });
83
-
84
- it("returns undefined for empty list", () => {
85
- expect(findWishlistEntry([], "anything")).toBeUndefined();
86
- });
87
- });
@@ -1,204 +0,0 @@
1
- /**
2
- * Cart v2 — optional TanStack Query adapter.
3
- *
4
- * The base factory (`createCart`) is intentionally QueryClient-free so it runs
5
- * anywhere. Sites already invested in TanStack Query can use this adapter
6
- * instead to get cache integration, `staleTime`, devtools, and cross-component
7
- * query sharing — while keeping the exact same invoke injection and the same
8
- * server-side fragmentation/projection contract.
9
- *
10
- * Importing this module pulls in `@tanstack/react-query` (a peer dependency).
11
- * If your site does not use react-query, import `createCart` instead.
12
- *
13
- * @example
14
- * ```ts
15
- * import { createCartQuery } from "@decocms/apps/vtex/hooks/cartQuery";
16
- * import { invoke } from "~/server/invoke";
17
- * export const { useCartSummary, useCartFull, useAddToCart } = createCartQuery({ invoke });
18
- * ```
19
- */
20
-
21
- import type {
22
- CartProjection,
23
- CartSection,
24
- CartSummary,
25
- Minicart,
26
- } from "@decocms/apps-commerce/types";
27
- import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
28
- import type { CartItemAttachments } from "../loaders/cart/attachments";
29
- import type { CartGifts } from "../loaders/cart/gifts";
30
- import type { CartShipping } from "../loaders/cart/shipping";
31
- import type { OrderForm } from "../types";
32
- import type { CreateCartInvoke } from "./createCart";
33
-
34
- export interface CreateCartQueryOptions {
35
- invoke: CreateCartInvoke;
36
- orderFormCookieName?: string;
37
- }
38
-
39
- const SUMMARY_KEY = ["vtex", "cart", "summary"] as const;
40
- const FULL_KEY = ["vtex", "cart", "full"] as const;
41
- const SHIPPING_KEY = ["vtex", "cart", "shipping"] as const;
42
- const GIFTS_KEY = ["vtex", "cart", "gifts"] as const;
43
- const ATTACHMENTS_KEY = ["vtex", "cart", "attachments"] as const;
44
-
45
- /** TanStack Query flavour of the Cart v2 hooks. */
46
- export function createCartQuery(opts: CreateCartQueryOptions) {
47
- const { invoke } = opts;
48
- const COOKIE_NAME = opts.orderFormCookieName ?? "checkout.vtex.com__orderFormId";
49
-
50
- function escapeRegex(s: string): string {
51
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
52
- }
53
- function getOrderFormIdFromCookie(): string | null {
54
- if (typeof document === "undefined") return null;
55
- const m = document.cookie.match(new RegExp(`${escapeRegex(COOKIE_NAME)}=([^;]*)`));
56
- return m ? decodeURIComponent(m[1]) : null;
57
- }
58
- function setOrderFormIdCookie(id: string) {
59
- if (typeof document === "undefined") return;
60
- // biome-ignore lint/suspicious/noDocumentCookie: the orderFormId cookie is intentionally client-readable (VTEX standard).
61
- document.cookie = `${COOKIE_NAME}=${encodeURIComponent(id)}; path=/; max-age=${7 * 24 * 3600}; SameSite=Lax`;
62
- }
63
- async function ensureOrderFormId(current: string | null): Promise<string> {
64
- const existing = current ?? getOrderFormIdFromCookie();
65
- if (existing) return existing;
66
- const created = (await invoke.vtex.actions.getOrCreateCartV2({
67
- data: { projection: "summary" },
68
- })) as CartSummary;
69
- if (created.orderFormId) setOrderFormIdCookie(created.orderFormId);
70
- return created.orderFormId ?? "";
71
- }
72
-
73
- /**
74
- * Badge query. Lazy: `enabled` defaults to false so it only runs when the
75
- * caller opts in (e.g. after the cart cookie exists) — no cart is created on
76
- * mount.
77
- */
78
- function useCartSummary(options?: { enabled?: boolean; staleTime?: number }) {
79
- return useQuery({
80
- queryKey: SUMMARY_KEY,
81
- queryFn: () => invoke.vtex.loaders.cart.summary({ data: {} }),
82
- enabled: options?.enabled ?? false,
83
- staleTime: options?.staleTime ?? 30_000,
84
- });
85
- }
86
-
87
- /** Full drawer query. `enabled` gated so it fires when the drawer opens. */
88
- function useCartFull(options?: {
89
- enabled?: boolean;
90
- staleTime?: number;
91
- freeShippingTarget?: number;
92
- locale?: string;
93
- checkoutHref?: string;
94
- enableCoupon?: boolean;
95
- }) {
96
- return useQuery<Minicart<OrderForm | null>>({
97
- queryKey: FULL_KEY,
98
- queryFn: () =>
99
- invoke.vtex.loaders.cart.full({
100
- data: {
101
- freeShippingTarget: options?.freeShippingTarget,
102
- locale: options?.locale,
103
- checkoutHref: options?.checkoutHref,
104
- enableCoupon: options?.enableCoupon,
105
- },
106
- }),
107
- enabled: options?.enabled ?? false,
108
- staleTime: options?.staleTime ?? 30_000,
109
- });
110
- }
111
-
112
- function useAddToCart(hookOpts?: { projection?: CartProjection; sections?: CartSection[] }) {
113
- const queryClient = useQueryClient();
114
- const projection: CartProjection = hookOpts?.projection ?? "summary+items";
115
-
116
- return useMutation({
117
- mutationFn: async (params: { id: string; seller: string; quantity?: number }) => {
118
- const current = queryClient.getQueryData<CartSummary>(SUMMARY_KEY)?.orderFormId ?? null;
119
- const orderFormId = await ensureOrderFormId(current);
120
- return invoke.vtex.actions.addItemsToCartV2({
121
- data: {
122
- orderFormId,
123
- orderItems: [{ id: params.id, seller: params.seller, quantity: params.quantity ?? 1 }],
124
- projection,
125
- sections: hookOpts?.sections,
126
- },
127
- });
128
- },
129
- // Optimistic badge bump.
130
- onMutate: async (params) => {
131
- await queryClient.cancelQueries({ queryKey: SUMMARY_KEY });
132
- const prev = queryClient.getQueryData<CartSummary>(SUMMARY_KEY);
133
- const qty = params.quantity ?? 1;
134
- queryClient.setQueryData<CartSummary>(SUMMARY_KEY, (s) => ({
135
- orderFormId: s?.orderFormId ?? null,
136
- total: s?.total ?? 0,
137
- totalItems: (s?.totalItems ?? 0) + qty,
138
- }));
139
- return { prev };
140
- },
141
- onError: (_err, _params, ctx) => {
142
- if (ctx?.prev) queryClient.setQueryData(SUMMARY_KEY, ctx.prev);
143
- },
144
- onSuccess: (result) => {
145
- if (projection === "minicart") {
146
- queryClient.setQueryData(FULL_KEY, result);
147
- } else if (projection !== "none") {
148
- const r = result as Partial<CartSummary>;
149
- if (r && typeof r.totalItems === "number") {
150
- queryClient.setQueryData<CartSummary>(SUMMARY_KEY, {
151
- orderFormId: r.orderFormId ?? null,
152
- totalItems: r.totalItems,
153
- total: r.total ?? 0,
154
- });
155
- }
156
- }
157
- },
158
- });
159
- }
160
-
161
- /**
162
- * Shipping estimate query. Keyed by `{ postalCode, items }` — which is NOT
163
- * user-personalized — so react-query's cache/dedupe gives you the caching
164
- * the server-side loader can't do yet (see the loader's caching note).
165
- * `enabled` defaults on when a postal code is present.
166
- */
167
- function useShipping(
168
- params: {
169
- items: Array<{ id: string | number; quantity: number; seller: string }>;
170
- postalCode: string;
171
- country?: string;
172
- },
173
- options?: { enabled?: boolean; staleTime?: number },
174
- ) {
175
- return useQuery<CartShipping>({
176
- queryKey: [...SHIPPING_KEY, params.postalCode, params.items],
177
- queryFn: () => invoke.vtex.loaders.cart.shipping({ data: params }),
178
- enabled: options?.enabled ?? Boolean(params.postalCode && params.items.length),
179
- staleTime: options?.staleTime ?? 5 * 60_000,
180
- });
181
- }
182
-
183
- /** Selectable-gifts / promotions query. `enabled` gated (default false). */
184
- function useGifts(options?: { enabled?: boolean; staleTime?: number }) {
185
- return useQuery<CartGifts>({
186
- queryKey: GIFTS_KEY,
187
- queryFn: () => invoke.vtex.loaders.cart.gifts({ data: {} }),
188
- enabled: options?.enabled ?? false,
189
- staleTime: options?.staleTime ?? 30_000,
190
- });
191
- }
192
-
193
- /** Single-line attachments query. `enabled` gated (default false). */
194
- function useAttachments(itemIndex: number, options?: { enabled?: boolean; staleTime?: number }) {
195
- return useQuery<CartItemAttachments>({
196
- queryKey: [...ATTACHMENTS_KEY, itemIndex],
197
- queryFn: () => invoke.vtex.loaders.cart.attachments({ data: { itemIndex } }),
198
- enabled: options?.enabled ?? false,
199
- staleTime: options?.staleTime ?? 30_000,
200
- });
201
- }
202
-
203
- return { useCartSummary, useCartFull, useAddToCart, useShipping, useGifts, useAttachments };
204
- }