@decocms/apps-commerce 7.24.0 → 7.25.0

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decocms/apps-commerce",
3
- "version": "7.24.0",
3
+ "version": "7.25.0",
4
4
  "type": "module",
5
5
  "description": "Deco commerce apps: shared types, app-registry, and portable commerce utilities",
6
6
  "repository": {
@@ -11,6 +11,7 @@
11
11
  "main": "./src/types/commerce.ts",
12
12
  "exports": {
13
13
  "./types": "./src/types/commerce.ts",
14
+ "./types/cart": "./src/types/cart.ts",
14
15
  "./app-types": "./src/app-types.ts",
15
16
  "./resolve": "./src/resolve.ts",
16
17
  "./manifest-utils": "./src/manifest-utils.ts",
@@ -25,7 +26,7 @@
25
26
  "lint:unused": "knip"
26
27
  },
27
28
  "dependencies": {
28
- "@decocms/blocks": "7.24.0"
29
+ "@decocms/blocks": "7.25.0"
29
30
  },
30
31
  "peerDependencies": {
31
32
  "react": "^19.0.0",
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Cart v2 — platform-agnostic fragmentation contract.
3
+ *
4
+ * Two independent dimensions govern every cart operation:
5
+ *
6
+ * 1. `sections` — WHAT WE ASK THE PLATFORM FOR. Maps to VTEX's
7
+ * `expectedOrderFormSections`; other platforms map it to their own
8
+ * partial-response mechanism. Controls the upstream payload + compute.
9
+ * 2. `projection` — WHAT THE SERVER RETURNS TO THE CLIENT. Independent of
10
+ * `sections`: we can ask the platform for the full cart yet project a slim
11
+ * `{ totalItems, total }` down the wire, or vice-versa.
12
+ *
13
+ * The whole point is "default to the minimum, everything opt-in". A mutation
14
+ * that only needs to bump a badge should not ship the entire cart to the
15
+ * browser, and a page view where the user never clicked "add" should not hit
16
+ * the cart API at all.
17
+ *
18
+ * This module is deliberately platform-neutral — VTEX is the first
19
+ * implementation (see `@decocms/apps/vtex/utils/cartProjection`), Shopify/Wake
20
+ * reuse the same contract. Only types + presets live here; the actual
21
+ * OrderForm→projection mapping is platform-specific.
22
+ */
23
+
24
+ import type { MinicartItem } from "./commerce";
25
+
26
+ /**
27
+ * A VTEX OrderForm section (the canonical superset). Other platforms map the
28
+ * subset they support; unknown strings are allowed so a platform can request a
29
+ * section this union doesn't yet name without a type error.
30
+ */
31
+ export type CartSection =
32
+ | "items"
33
+ | "totalizers"
34
+ | "clientProfileData"
35
+ | "shippingData"
36
+ | "paymentData"
37
+ | "sellers"
38
+ | "messages"
39
+ | "marketingData"
40
+ | "clientPreferencesData"
41
+ | "storePreferencesData"
42
+ | "giftRegistryData"
43
+ | "ratesAndBenefitsData"
44
+ | "openTextField"
45
+ | "commercialConditionData"
46
+ | "customData"
47
+ | (string & {});
48
+
49
+ /**
50
+ * Shape of the response the server sends to the client after a cart read or
51
+ * mutation. Ordered from cheapest to richest:
52
+ *
53
+ * - `none` — `{ ok: true }`. The platform payload is discarded server-side.
54
+ * Use when the client updates optimistically and needs no confirmation data.
55
+ * - `summary` — `{ orderFormId, totalItems, total }`. Enough for a badge.
56
+ * - `summary+items` — summary plus the slim line items (the **default** for
57
+ * add-to-cart: the platform returns the items regardless, so we forward a
58
+ * trimmed view — name, image, price, chosen variant, quantity).
59
+ * - `minicart` — the full canonical `Minicart` (drawer view).
60
+ * - `raw` — the untouched platform cart (escape hatch for platform-specific
61
+ * reads: GTM, pixels, custom integrations).
62
+ */
63
+ export type CartProjection = "none" | "summary" | "summary+items" | "minicart" | "raw";
64
+
65
+ /** Minimal, cacheable-shaped cart totals for a badge. All money in major units. */
66
+ export interface CartSummary {
67
+ orderFormId: string | null;
68
+ /** Sum of line quantities. `0` when there is no cart yet. */
69
+ totalItems: number;
70
+ /** Total payable, in major units. */
71
+ total: number;
72
+ }
73
+
74
+ /**
75
+ * A trimmed cart line — the "at least name, image, price, chosen size" the
76
+ * user asked for. Structurally a subset of `MinicartItem` so it forwards
77
+ * straight to analytics and drawer UIs without re-mapping.
78
+ */
79
+ export interface CartItemSlim {
80
+ item_id?: string;
81
+ item_name?: string;
82
+ item_variant?: string;
83
+ image: string;
84
+ /** Selling price per unit, in major units. */
85
+ price: number;
86
+ quantity: number;
87
+ }
88
+
89
+ /** `projection: "none"` result. */
90
+ export interface CartOk {
91
+ ok: true;
92
+ }
93
+
94
+ /** `projection: "summary+items"` result — the add-to-cart default. */
95
+ export interface CartSummaryWithItems extends CartSummary {
96
+ items: CartItemSlim[];
97
+ }
98
+
99
+ /**
100
+ * Discriminated union of every projection result, so callers can narrow on the
101
+ * `projection` they requested. `minicart`/`raw` payload types are supplied by
102
+ * the platform binding via the generic params.
103
+ */
104
+ export type CartProjectionResult<TMinicart = unknown, TRaw = unknown> =
105
+ | CartOk
106
+ | CartSummary
107
+ | CartSummaryWithItems
108
+ | TMinicart
109
+ | TRaw;
110
+
111
+ // ---------------------------------------------------------------------------
112
+ // Section presets — the "which sections per operation" defaults.
113
+ // ---------------------------------------------------------------------------
114
+
115
+ /**
116
+ * Smallest useful set for a mutation: line items + totals, plus `messages` so
117
+ * stock/availability errors surface. This is the add-to-cart default and the
118
+ * single biggest lever for shrinking both the VTEX payload and its compute.
119
+ */
120
+ export const SECTIONS_MINIMAL: CartSection[] = ["items", "totalizers", "messages"];
121
+
122
+ /** Everything a drawer/minicart renders: totals, coupon, shipping, sellers. */
123
+ export const SECTIONS_DRAWER: CartSection[] = [
124
+ "items",
125
+ "totalizers",
126
+ "messages",
127
+ "marketingData",
128
+ "sellers",
129
+ "ratesAndBenefitsData",
130
+ "storePreferencesData",
131
+ "clientPreferencesData",
132
+ "shippingData",
133
+ ];
134
+
135
+ /** The full superset — parity with the legacy hardcoded default. */
136
+ export const SECTIONS_FULL: CartSection[] = [
137
+ "items",
138
+ "totalizers",
139
+ "clientProfileData",
140
+ "shippingData",
141
+ "paymentData",
142
+ "sellers",
143
+ "messages",
144
+ "marketingData",
145
+ "clientPreferencesData",
146
+ "storePreferencesData",
147
+ "giftRegistryData",
148
+ "ratesAndBenefitsData",
149
+ "openTextField",
150
+ "commercialConditionData",
151
+ "customData",
152
+ ];
153
+
154
+ /** Default sections per projection — used when a caller passes a projection but no explicit sections. */
155
+ export function defaultSectionsFor(projection: CartProjection): CartSection[] {
156
+ switch (projection) {
157
+ case "none":
158
+ case "summary":
159
+ case "summary+items":
160
+ return SECTIONS_MINIMAL;
161
+ case "minicart":
162
+ return SECTIONS_DRAWER;
163
+ case "raw":
164
+ return SECTIONS_FULL;
165
+ }
166
+ }
167
+
168
+ /** Re-export so consumers can build slim items against the canonical type. */
169
+ export type { MinicartItem };
@@ -1226,3 +1226,8 @@ export interface Minicart<TRaw = unknown> {
1226
1226
  postalCode?: string;
1227
1227
  };
1228
1228
  }
1229
+
1230
+ // ---------------------------------------------------------------------------
1231
+ // Cart v2 — platform-agnostic fragmentation contract (sections + projections).
1232
+ // ---------------------------------------------------------------------------
1233
+ export * from "./cart";