@replohq/sdk 1.12.0 → 1.13.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/cart/cart-actions.d.ts +17 -1
- package/cart/cart-actions.js +11 -1
- package/cart/cart-provider.d.ts +24 -2
- package/cart/cart-provider.js +55 -17
- package/cart/cart-schema.d.ts +10 -0
- package/cart/cart-schema.js +3 -1
- package/cart/cart-types.d.ts +12 -0
- package/cart/gateways/cart-gateway.d.ts +3 -1
- package/cart/gateways/cookie-cart-gateway.d.ts +4 -1
- package/cart/gateways/cookie-cart-gateway.js +40 -0
- package/cart/gateways/resolver-cart-gateway.js +27 -0
- package/cart/utils/cart-error.js +3 -1
- package/gateways/canopy-api.d.ts +11 -0
- package/gateways/canopy-api.js +12 -0
- package/lib/buildMetadata.js +3 -3
- package/package.json +4 -4
package/cart/cart-actions.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StorefrontCountryCode } from "../loaders/markets";
|
|
2
|
-
import type { AddToCartPayload, Cart, CartLinePayload, RemoveFromCartPayload, UpdateCartLineItemPayload } from "./cart-types";
|
|
2
|
+
import type { AddToCartPayload, Cart, CartLineAttribute, CartLinePayload, RemoveFromCartPayload, UpdateCartLineItemPayload } from "./cart-types";
|
|
3
3
|
/**
|
|
4
4
|
* Gets the existing cart or creates a new one if none exists. This is necessary
|
|
5
5
|
* because we may not have cookies in the server context during initial load.
|
|
@@ -73,3 +73,19 @@ export declare function removeCartLineItemsAction(lineIds: RemoveFromCartPayload
|
|
|
73
73
|
* @returns The updated cart
|
|
74
74
|
*/
|
|
75
75
|
export declare function updateCartDiscountCodesAction(discountCodes: string[], cartId: string): Promise<Cart | null>;
|
|
76
|
+
/**
|
|
77
|
+
* Sets the order-level note on a cart. Pass an empty string to clear it.
|
|
78
|
+
*
|
|
79
|
+
* @param note - The note text
|
|
80
|
+
* @param cartId - The ID of the cart to update
|
|
81
|
+
* @returns The updated cart
|
|
82
|
+
*/
|
|
83
|
+
export declare function updateCartNoteAction(note: string, cartId: string): Promise<Cart | null>;
|
|
84
|
+
/**
|
|
85
|
+
* Replaces the order-level attributes on a cart.
|
|
86
|
+
*
|
|
87
|
+
* @param attributes - The full attribute list to store on the cart
|
|
88
|
+
* @param cartId - The ID of the cart to update
|
|
89
|
+
* @returns The updated cart
|
|
90
|
+
*/
|
|
91
|
+
export declare function replaceCartAttributesAction(attributes: CartLineAttribute[], cartId: string): Promise<Cart | null>;
|
package/cart/cart-actions.js
CHANGED
|
@@ -108,6 +108,14 @@ async function updateCartDiscountCodesAction(discountCodes, cartId) {
|
|
|
108
108
|
const cartGateway = await getCartGateway();
|
|
109
109
|
return await cartGateway.updateCartDiscountCodes({ discountCodes, cartId });
|
|
110
110
|
}
|
|
111
|
+
async function updateCartNoteAction(note, cartId) {
|
|
112
|
+
const cartGateway = await getCartGateway();
|
|
113
|
+
return await cartGateway.updateCartNote({ note, cartId });
|
|
114
|
+
}
|
|
115
|
+
async function replaceCartAttributesAction(attributes, cartId) {
|
|
116
|
+
const cartGateway = await getCartGateway();
|
|
117
|
+
return await cartGateway.replaceCartAttributes({ attributes, cartId });
|
|
118
|
+
}
|
|
111
119
|
export {
|
|
112
120
|
addToCartAction,
|
|
113
121
|
createCartAction,
|
|
@@ -115,6 +123,8 @@ export {
|
|
|
115
123
|
getOrCreateCartAction,
|
|
116
124
|
reconcileCartAction,
|
|
117
125
|
removeCartLineItemsAction,
|
|
126
|
+
replaceCartAttributesAction,
|
|
118
127
|
updateCartDiscountCodesAction,
|
|
119
|
-
updateCartLineItemAction
|
|
128
|
+
updateCartLineItemAction,
|
|
129
|
+
updateCartNoteAction
|
|
120
130
|
};
|
package/cart/cart-provider.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StorefrontCountryCode } from "../loaders/markets";
|
|
2
|
-
import type { Cart, CartLine, CartLineAdjustment, CartLinePayload } from "./cart-types";
|
|
2
|
+
import type { Cart, CartLine, CartLineAdjustment, CartLineAttribute, CartLinePayload } from "./cart-types";
|
|
3
3
|
import React from "react";
|
|
4
|
-
export type CartOperation = "add" | "update" | "remove" | "discount";
|
|
4
|
+
export type CartOperation = "add" | "update" | "remove" | "discount" | "note" | "attributes";
|
|
5
5
|
/**
|
|
6
6
|
* The most recent cart change that could not be saved. `message` is written
|
|
7
7
|
* for the shopper, so a cart UI can render it as-is next to a retry.
|
|
@@ -39,6 +39,10 @@ export interface CartContextTypeInternal {
|
|
|
39
39
|
removeCartItem: (lineId: string) => Promise<void>;
|
|
40
40
|
/** Function to update discount codes on cart */
|
|
41
41
|
updateDiscountCodes: (discountCodes: string[]) => Promise<void>;
|
|
42
|
+
/** Function to set the order-level cart note (empty string clears it) */
|
|
43
|
+
updateNote: (note: string) => Promise<void>;
|
|
44
|
+
/** Function to replace the order-level cart attributes */
|
|
45
|
+
replaceAttributes: (attributes: CartLineAttribute[]) => Promise<void>;
|
|
42
46
|
/** Re-read the persisted cart and adopt it if no mutations are in flight */
|
|
43
47
|
refreshCart: () => Promise<void>;
|
|
44
48
|
/** Function to create cart and checkout immediately */
|
|
@@ -72,6 +76,24 @@ export interface CartContextType {
|
|
|
72
76
|
closeCart: () => void;
|
|
73
77
|
/** Function to update discount codes on cart */
|
|
74
78
|
updateDiscountCodes: (discountCodes: string[]) => Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Set the order-level cart note (Shopify `cart.note`, the "special
|
|
81
|
+
* instructions" field on the order). Pass an empty string to clear it.
|
|
82
|
+
* Each call is one Shopify mutation: save on blur or after the shopper
|
|
83
|
+
* stops typing, never on every keystroke. Shopify checkout only; on Replo
|
|
84
|
+
* Products (Stripe) sites the note is kept on the cart but is not
|
|
85
|
+
* forwarded to the order.
|
|
86
|
+
*/
|
|
87
|
+
updateNote: (note: string) => Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Replace the order-level cart attributes (Shopify `cart.attributes`), the
|
|
90
|
+
* key/value pairs gift-message and fulfillment apps read off the order.
|
|
91
|
+
* These are distinct from per-line `properties`. The full list is replaced
|
|
92
|
+
* on every call, so a key left out is removed; values are stored as
|
|
93
|
+
* strings. Shopify checkout only; on Replo Products (Stripe) sites the
|
|
94
|
+
* attributes are kept on the cart but are not forwarded to the order.
|
|
95
|
+
*/
|
|
96
|
+
replaceAttributes: (attributes: CartLineAttribute[]) => Promise<void>;
|
|
75
97
|
/**
|
|
76
98
|
* Re-read the persisted cart and adopt it if no mutations are in flight.
|
|
77
99
|
* Call after something outside the provider rewrote the cart — e.g. the
|
package/cart/cart-provider.js
CHANGED
|
@@ -10,8 +10,10 @@ import {
|
|
|
10
10
|
getOrCreateCartAction,
|
|
11
11
|
reconcileCartAction,
|
|
12
12
|
removeCartLineItemsAction,
|
|
13
|
+
replaceCartAttributesAction,
|
|
13
14
|
updateCartDiscountCodesAction,
|
|
14
|
-
updateCartLineItemAction
|
|
15
|
+
updateCartLineItemAction,
|
|
16
|
+
updateCartNoteAction
|
|
15
17
|
} from "./cart-actions";
|
|
16
18
|
import { CartCountryContext } from "./cart-country-context";
|
|
17
19
|
import { useShouldReconcileSuppliedCart } from "./supplied-cart-reconciliation";
|
|
@@ -487,22 +489,15 @@ function CartProvider({
|
|
|
487
489
|
updateCartData
|
|
488
490
|
]
|
|
489
491
|
);
|
|
490
|
-
const
|
|
491
|
-
(
|
|
492
|
-
return runWithErrorState(
|
|
492
|
+
const updateCartField = React.useCallback(
|
|
493
|
+
(operation, patch, save) => {
|
|
494
|
+
return runWithErrorState(operation, async () => {
|
|
493
495
|
const readyCart = cartData ?? serverCart.current ?? await initializeCart();
|
|
494
|
-
updateCartData((currentCart) => {
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
applicable: true
|
|
500
|
-
}))
|
|
501
|
-
};
|
|
502
|
-
});
|
|
503
|
-
await enqueueMutation((currentCart) => {
|
|
504
|
-
return updateCartDiscountCodesAction(discountCodes, currentCart.id);
|
|
505
|
-
});
|
|
496
|
+
updateCartData((currentCart) => ({
|
|
497
|
+
...currentCart ?? readyCart,
|
|
498
|
+
...patch
|
|
499
|
+
}));
|
|
500
|
+
await enqueueMutation((currentCart) => save(currentCart.id));
|
|
506
501
|
});
|
|
507
502
|
},
|
|
508
503
|
[
|
|
@@ -513,6 +508,43 @@ function CartProvider({
|
|
|
513
508
|
updateCartData
|
|
514
509
|
]
|
|
515
510
|
);
|
|
511
|
+
const updateDiscountCodes = React.useCallback(
|
|
512
|
+
(discountCodes) => {
|
|
513
|
+
return updateCartField(
|
|
514
|
+
"discount",
|
|
515
|
+
{
|
|
516
|
+
discountCodes: discountCodes.map((code) => ({
|
|
517
|
+
code,
|
|
518
|
+
applicable: true
|
|
519
|
+
}))
|
|
520
|
+
},
|
|
521
|
+
(cartId) => updateCartDiscountCodesAction(discountCodes, cartId)
|
|
522
|
+
);
|
|
523
|
+
},
|
|
524
|
+
[updateCartField]
|
|
525
|
+
);
|
|
526
|
+
const updateNote = React.useCallback(
|
|
527
|
+
(note) => {
|
|
528
|
+
return updateCartField("note", { note }, (cartId) => {
|
|
529
|
+
return updateCartNoteAction(note, cartId);
|
|
530
|
+
});
|
|
531
|
+
},
|
|
532
|
+
[updateCartField]
|
|
533
|
+
);
|
|
534
|
+
const replaceAttributes = React.useCallback(
|
|
535
|
+
(attributes) => {
|
|
536
|
+
const stringAttributes = attributes.map((attribute) => ({
|
|
537
|
+
key: attribute.key,
|
|
538
|
+
value: String(attribute.value)
|
|
539
|
+
}));
|
|
540
|
+
return updateCartField(
|
|
541
|
+
"attributes",
|
|
542
|
+
{ attributes: stringAttributes },
|
|
543
|
+
(cartId) => replaceCartAttributesAction(stringAttributes, cartId)
|
|
544
|
+
);
|
|
545
|
+
},
|
|
546
|
+
[updateCartField]
|
|
547
|
+
);
|
|
516
548
|
const buyNow = React.useCallback(
|
|
517
549
|
(lines, discountCodes) => {
|
|
518
550
|
return createBuyNowCart({ lines, discountCodes, country });
|
|
@@ -530,6 +562,8 @@ function CartProvider({
|
|
|
530
562
|
updateCartItem,
|
|
531
563
|
removeCartItem,
|
|
532
564
|
updateDiscountCodes,
|
|
565
|
+
updateNote,
|
|
566
|
+
replaceAttributes,
|
|
533
567
|
refreshCart,
|
|
534
568
|
buyNow,
|
|
535
569
|
checkoutUrl: cartData?.checkoutUrl ?? "/",
|
|
@@ -552,8 +586,10 @@ function CartProvider({
|
|
|
552
586
|
refreshCart,
|
|
553
587
|
removeCartItem,
|
|
554
588
|
subtotal,
|
|
589
|
+
replaceAttributes,
|
|
555
590
|
updateCartItem,
|
|
556
|
-
updateDiscountCodes
|
|
591
|
+
updateDiscountCodes,
|
|
592
|
+
updateNote
|
|
557
593
|
]
|
|
558
594
|
);
|
|
559
595
|
return /* @__PURE__ */ jsx(CartCountryContext.Provider, { value: country, children: /* @__PURE__ */ jsx(CartContext.Provider, { value: contextValue, children }) });
|
|
@@ -580,6 +616,8 @@ function useCart() {
|
|
|
580
616
|
openCart: context.openCart,
|
|
581
617
|
closeCart: context.closeCart,
|
|
582
618
|
updateDiscountCodes: context.updateDiscountCodes,
|
|
619
|
+
updateNote: context.updateNote,
|
|
620
|
+
replaceAttributes: context.replaceAttributes,
|
|
583
621
|
refreshCart: context.refreshCart,
|
|
584
622
|
error: context.error,
|
|
585
623
|
clearError: context.clearError
|
package/cart/cart-schema.d.ts
CHANGED
|
@@ -77,6 +77,11 @@ export declare const cartSchema: z.ZodObject<{
|
|
|
77
77
|
buyerIdentity: z.ZodOptional<z.ZodObject<{
|
|
78
78
|
country: z.ZodNullable<z.ZodString>;
|
|
79
79
|
}, z.core.$strip>>;
|
|
80
|
+
note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
81
|
+
attributes: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
82
|
+
key: z.ZodString;
|
|
83
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>;
|
|
84
|
+
}, z.core.$strip>>>;
|
|
80
85
|
}, z.core.$strip>;
|
|
81
86
|
export declare const clientCartSchema: z.ZodObject<{
|
|
82
87
|
id: z.ZodString;
|
|
@@ -97,6 +102,11 @@ export declare const clientCartSchema: z.ZodObject<{
|
|
|
97
102
|
buyerIdentity: z.ZodOptional<z.ZodObject<{
|
|
98
103
|
country: z.ZodNullable<z.ZodString>;
|
|
99
104
|
}, z.core.$strip>>;
|
|
105
|
+
note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
106
|
+
attributes: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
107
|
+
key: z.ZodString;
|
|
108
|
+
value: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>;
|
|
109
|
+
}, z.core.$strip>>>;
|
|
100
110
|
lines: z.ZodArray<z.ZodObject<{
|
|
101
111
|
id: z.ZodString;
|
|
102
112
|
quantity: z.ZodNumber;
|
package/cart/cart-schema.js
CHANGED
|
@@ -67,7 +67,9 @@ const cartSchema = z.object({
|
|
|
67
67
|
checkoutUrl: z.string().optional(),
|
|
68
68
|
discountCodes: z.array(cartDiscountCodeSchema).optional(),
|
|
69
69
|
discountAllocations: z.array(cartDiscountAllocationSchema).optional(),
|
|
70
|
-
buyerIdentity: z.object({ country: z.string().nullable() }).optional()
|
|
70
|
+
buyerIdentity: z.object({ country: z.string().nullable() }).optional(),
|
|
71
|
+
note: z.string().nullish(),
|
|
72
|
+
attributes: z.array(cartLineAttributeSchema).optional()
|
|
71
73
|
});
|
|
72
74
|
const clientCartSchema = cartSchema.extend({
|
|
73
75
|
lines: z.array(
|
package/cart/cart-types.d.ts
CHANGED
|
@@ -127,6 +127,10 @@ export interface Cart {
|
|
|
127
127
|
buyerIdentity?: {
|
|
128
128
|
country: string | null;
|
|
129
129
|
};
|
|
130
|
+
/** Order-level note the shopper attached to the cart (Shopify `cart.note`) */
|
|
131
|
+
note?: string | null;
|
|
132
|
+
/** Order-level attributes (Shopify `cart.attributes`), distinct from line properties */
|
|
133
|
+
attributes?: CartLineAttribute[];
|
|
130
134
|
}
|
|
131
135
|
/**
|
|
132
136
|
* How a cart write differed from what the shopper asked for, derived by
|
|
@@ -166,6 +170,14 @@ export interface UpdateCartDiscountCodesPayload {
|
|
|
166
170
|
cartId: string;
|
|
167
171
|
discountCodes: string[];
|
|
168
172
|
}
|
|
173
|
+
export interface UpdateCartNotePayload {
|
|
174
|
+
cartId: string;
|
|
175
|
+
note: string;
|
|
176
|
+
}
|
|
177
|
+
export interface ReplaceCartAttributesPayload {
|
|
178
|
+
cartId: string;
|
|
179
|
+
attributes: CartLineAttribute[];
|
|
180
|
+
}
|
|
169
181
|
export interface CartBuyerIdentity {
|
|
170
182
|
country: StorefrontCountryCode;
|
|
171
183
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AddToCartPayload, Cart, CartBuyerIdentity, CartLinePayload, RemoveFromCartPayload, UpdateCartDiscountCodesPayload, UpdateCartLineItemPayload } from "../cart-types";
|
|
1
|
+
import type { AddToCartPayload, Cart, CartBuyerIdentity, CartLinePayload, RemoveFromCartPayload, ReplaceCartAttributesPayload, UpdateCartDiscountCodesPayload, UpdateCartLineItemPayload, UpdateCartNotePayload } from "../cart-types";
|
|
2
2
|
export interface CartGateway {
|
|
3
3
|
getCart(cartId: string): Promise<Cart | null>;
|
|
4
4
|
/**
|
|
@@ -21,5 +21,7 @@ export interface CartGateway {
|
|
|
21
21
|
updateCartLineItem(cartPayload: UpdateCartLineItemPayload): Promise<Cart | null>;
|
|
22
22
|
removeCartLineItems(cartPayload: RemoveFromCartPayload): Promise<Cart | null>;
|
|
23
23
|
updateCartDiscountCodes(cartPayload: UpdateCartDiscountCodesPayload): Promise<Cart | null>;
|
|
24
|
+
updateCartNote(cartPayload: UpdateCartNotePayload): Promise<Cart | null>;
|
|
25
|
+
replaceCartAttributes(cartPayload: ReplaceCartAttributesPayload): Promise<Cart | null>;
|
|
24
26
|
}
|
|
25
27
|
export declare function getCartGateway(): Promise<CartGateway>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ReconciledCartLine } from "../../gateways/canopy-api";
|
|
2
|
-
import type { AddToCartPayload, Cart, CartBuyerIdentity, CartLinePayload, RemoveFromCartPayload, UpdateCartDiscountCodesPayload, UpdateCartLineItemPayload } from "../cart-types";
|
|
2
|
+
import type { AddToCartPayload, Cart, CartBuyerIdentity, CartLinePayload, RemoveFromCartPayload, ReplaceCartAttributesPayload, UpdateCartDiscountCodesPayload, UpdateCartLineItemPayload, UpdateCartNotePayload } from "../cart-types";
|
|
3
3
|
import type { LineMergeFn } from "../utils/cookie-cart-persistence";
|
|
4
4
|
import type { CartGateway } from "./cart-gateway";
|
|
5
5
|
/**
|
|
@@ -41,5 +41,8 @@ export declare abstract class CookieBasedCartGateway implements CartGateway {
|
|
|
41
41
|
cartId: string;
|
|
42
42
|
buyerIdentity: CartBuyerIdentity;
|
|
43
43
|
}): Promise<Cart | null>;
|
|
44
|
+
updateCartNote({ cartId, note, }: UpdateCartNotePayload): Promise<Cart | null>;
|
|
45
|
+
replaceCartAttributes({ cartId, attributes, }: ReplaceCartAttributesPayload): Promise<Cart | null>;
|
|
46
|
+
private patchCart;
|
|
44
47
|
}
|
|
45
48
|
export {};
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
loadCartFromCookie,
|
|
6
6
|
removeCartLineItemsWithPersistence,
|
|
7
7
|
saveCartToCookie,
|
|
8
|
+
updateCartInCookie,
|
|
8
9
|
updateCartLineItemWithPersistence
|
|
9
10
|
} from "../utils/cookie-cart-persistence";
|
|
10
11
|
class CookieBasedCartGateway {
|
|
@@ -156,6 +157,45 @@ class CookieBasedCartGateway {
|
|
|
156
157
|
}) {
|
|
157
158
|
return this.getCart(cartId);
|
|
158
159
|
}
|
|
160
|
+
async updateCartNote({
|
|
161
|
+
cartId,
|
|
162
|
+
note
|
|
163
|
+
}) {
|
|
164
|
+
return this.patchCart(cartId, { note });
|
|
165
|
+
}
|
|
166
|
+
async replaceCartAttributes({
|
|
167
|
+
cartId,
|
|
168
|
+
attributes
|
|
169
|
+
}) {
|
|
170
|
+
return this.patchCart(cartId, {
|
|
171
|
+
attributes: attributes.map((attribute) => ({
|
|
172
|
+
key: attribute.key,
|
|
173
|
+
value: String(attribute.value)
|
|
174
|
+
}))
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
async patchCart(cartId, patch) {
|
|
178
|
+
console.warn(
|
|
179
|
+
`${this.config.gatewayName} cart gateway keeps cart note/attributes on the cart but does not forward them to checkout`
|
|
180
|
+
);
|
|
181
|
+
try {
|
|
182
|
+
return await updateCartInCookie(
|
|
183
|
+
cartId,
|
|
184
|
+
this.config.cookieName,
|
|
185
|
+
(cart) => ({
|
|
186
|
+
...cart,
|
|
187
|
+
...patch
|
|
188
|
+
})
|
|
189
|
+
);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
console.warn(`Failed to update ${this.config.gatewayName} cart:`, {
|
|
192
|
+
error: error instanceof Error ? error.message : String(error),
|
|
193
|
+
cartId,
|
|
194
|
+
patch
|
|
195
|
+
});
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
159
199
|
}
|
|
160
200
|
export {
|
|
161
201
|
CookieBasedCartGateway
|
|
@@ -117,6 +117,33 @@ class ResolverCartGateway {
|
|
|
117
117
|
return null;
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
+
async updateCartNote(cartPayload) {
|
|
121
|
+
try {
|
|
122
|
+
const gateway = await getCanopyApiGateway();
|
|
123
|
+
return await gateway.cartUpdateNote({
|
|
124
|
+
cartId: cartPayload.cartId,
|
|
125
|
+
note: cartPayload.note
|
|
126
|
+
});
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.warn("Failed to update cart note via canopy-api:", error);
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
async replaceCartAttributes(cartPayload) {
|
|
133
|
+
try {
|
|
134
|
+
const gateway = await getCanopyApiGateway();
|
|
135
|
+
return await gateway.cartReplaceAttributes({
|
|
136
|
+
cartId: cartPayload.cartId,
|
|
137
|
+
attributes: cartPayload.attributes.map((attribute) => ({
|
|
138
|
+
key: attribute.key,
|
|
139
|
+
value: String(attribute.value)
|
|
140
|
+
}))
|
|
141
|
+
});
|
|
142
|
+
} catch (error) {
|
|
143
|
+
console.warn("Failed to update cart attributes via canopy-api:", error);
|
|
144
|
+
return null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
120
147
|
}
|
|
121
148
|
async function createResolverCartGateway() {
|
|
122
149
|
return new ResolverCartGateway();
|
package/cart/utils/cart-error.js
CHANGED
|
@@ -5,7 +5,9 @@ const FALLBACK_MESSAGES = {
|
|
|
5
5
|
add: "Could not add to your cart. Please try again.",
|
|
6
6
|
update: "Could not update your cart. Please try again.",
|
|
7
7
|
remove: "Could not remove that item. Please try again.",
|
|
8
|
-
discount: "Could not apply that discount. Please try again."
|
|
8
|
+
discount: "Could not apply that discount. Please try again.",
|
|
9
|
+
note: "Could not save your note. Please try again.",
|
|
10
|
+
attributes: "Could not save your cart details. Please try again."
|
|
9
11
|
};
|
|
10
12
|
function toCartError(operation, caught) {
|
|
11
13
|
return {
|
package/gateways/canopy-api.d.ts
CHANGED
|
@@ -110,6 +110,17 @@ declare class CanopyApiGateway {
|
|
|
110
110
|
cartId: string;
|
|
111
111
|
country: StorefrontCountryCode;
|
|
112
112
|
}): Promise<Cart>;
|
|
113
|
+
cartUpdateNote({ cartId, note, }: {
|
|
114
|
+
cartId: string;
|
|
115
|
+
note: string;
|
|
116
|
+
}): Promise<Cart>;
|
|
117
|
+
cartReplaceAttributes({ cartId, attributes, }: {
|
|
118
|
+
cartId: string;
|
|
119
|
+
attributes: {
|
|
120
|
+
key: string;
|
|
121
|
+
value: string;
|
|
122
|
+
}[];
|
|
123
|
+
}): Promise<Cart>;
|
|
113
124
|
}
|
|
114
125
|
export declare function getCanopyApiGateway(): Promise<CanopyApiGateway>;
|
|
115
126
|
export {};
|
package/gateways/canopy-api.js
CHANGED
|
@@ -228,6 +228,18 @@ If you're running locally, make sure the canopy-api cloudflare worker is running
|
|
|
228
228
|
}) {
|
|
229
229
|
return this._cartPost("/update-buyer-identity", { cartId, country });
|
|
230
230
|
}
|
|
231
|
+
async cartUpdateNote({
|
|
232
|
+
cartId,
|
|
233
|
+
note
|
|
234
|
+
}) {
|
|
235
|
+
return this._cartPost("/update-note", { cartId, note });
|
|
236
|
+
}
|
|
237
|
+
async cartReplaceAttributes({
|
|
238
|
+
cartId,
|
|
239
|
+
attributes
|
|
240
|
+
}) {
|
|
241
|
+
return this._cartPost("/replace-attributes", { cartId, attributes });
|
|
242
|
+
}
|
|
231
243
|
}
|
|
232
244
|
async function getCanopyApiGateway() {
|
|
233
245
|
return CanopyApiGateway.setup();
|
package/lib/buildMetadata.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const BUILD_METADATA = {
|
|
2
2
|
"packageName": "@replohq/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"branch": "HEAD",
|
|
5
|
-
"commit": "
|
|
6
|
-
"builtAt": "2026-09-
|
|
5
|
+
"commit": "55186f7cb6b1441e4d471b2d954118f3d11767ae",
|
|
6
|
+
"builtAt": "2026-09-22T17:30:33.714Z"
|
|
7
7
|
};
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@replohq/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"reploBuild": {
|
|
5
5
|
"packageName": "@replohq/sdk",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.13.0",
|
|
7
7
|
"branch": "HEAD",
|
|
8
|
-
"commit": "
|
|
9
|
-
"builtAt": "2026-09-
|
|
8
|
+
"commit": "55186f7cb6b1441e4d471b2d954118f3d11767ae",
|
|
9
|
+
"builtAt": "2026-09-22T17:30:33.714Z"
|
|
10
10
|
},
|
|
11
11
|
"description": "Replo SDK — cart, analytics, and data loaders for agent-built Next.js sites.",
|
|
12
12
|
"license": "SEE LICENSE IN LICENSE",
|