@shopbb/helium 0.5.5 → 0.5.7
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.
|
@@ -110,8 +110,18 @@ export interface CartProviderProps {
|
|
|
110
110
|
* 如果传入,fetchOnMount 默认行为变成只在 cart 数据可能过期时 refetch(当前简单实现:不再自动 refetch)。
|
|
111
111
|
*/
|
|
112
112
|
initialCart?: Cart | null;
|
|
113
|
+
/**
|
|
114
|
+
* 取买家 JWT 的函数。
|
|
115
|
+
*
|
|
116
|
+
* 关键意义:cart resolver 服务端会根据 buyer JWT **自动选最佳优惠券**,
|
|
117
|
+
* 写入 cart.cost.totalDiscountAmount + appliedDiscountClaim。
|
|
118
|
+
* 如果不带 token 调 GraphQL,服务端只能返回"无折扣 cart",价格不准。
|
|
119
|
+
*
|
|
120
|
+
* 不传时 fallback 从 localStorage 读 `shopbb:buyer_token` 或 `shopflare:buyer_token`。
|
|
121
|
+
*/
|
|
122
|
+
tokenProvider?: () => string | null;
|
|
113
123
|
}
|
|
114
|
-
export declare function CartProvider({ children, fetchOnMount, initialCart }: CartProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
124
|
+
export declare function CartProvider({ children, fetchOnMount, initialCart, tokenProvider }: CartProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
115
125
|
/**
|
|
116
126
|
* 拿 cart context。Provider 外 throw。
|
|
117
127
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartProvider.d.ts","sourceRoot":"","sources":["../../src/components/CartProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAChG,KAAK,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IACjD,OAAO,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,mBAAmB,CAAC;IACjC,IAAI,EAAE;QAAE,WAAW,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;CACjE;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE;QAAE,KAAK,EAAE,QAAQ,EAAE,CAAA;KAAE,CAAC;IAC7B,IAAI,EAAE;QACJ,cAAc,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,CAAC;QACzD,WAAW,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,CAAC;KACvD,CAAC;CACH;AAED,MAAM,MAAM,UAAU,GAAG,eAAe,GAAG,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;AAErF,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,aAAa;IACb,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxF,mDAAmD;IACnD,WAAW,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,aAAa;IACb,WAAW,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,mBAAmB;IACnB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B;;;;OAIG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IACvC,8BAA8B;IAC9B,SAAS,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,KAAK,MAAM,IAAI,CAAC;CAClE;
|
|
1
|
+
{"version":3,"file":"CartProvider.d.ts","sourceRoot":"","sources":["../../src/components/CartProvider.tsx"],"names":[],"mappings":"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"}
|
|
@@ -103,20 +103,36 @@ function saveCartIdToCookie(cartGid) {
|
|
|
103
103
|
const secureFlag = isHttps ? '; Secure' : '';
|
|
104
104
|
document.cookie = `${COOKIE_NAME}=${encodeURIComponent(id)}; path=/; max-age=${oneYear}; SameSite=Lax${secureFlag}`;
|
|
105
105
|
}
|
|
106
|
-
|
|
106
|
+
// ============================================================
|
|
107
|
+
// Provider
|
|
108
|
+
// ============================================================
|
|
109
|
+
const DEFAULT_TOKEN_KEY = 'shopbb:buyer_token';
|
|
110
|
+
export function CartProvider({ children, fetchOnMount = true, initialCart, tokenProvider }) {
|
|
107
111
|
const shop = useShop();
|
|
108
112
|
// SSR 同构:initialCart 直接进 state,避免 hydrate 时闪烁
|
|
109
113
|
const [cart, setCart] = React.useState(initialCart ?? null);
|
|
110
114
|
const [status, setStatus] = React.useState(initialCart ? 'idle' : 'uninitialized');
|
|
111
115
|
const [error, setError] = React.useState(null);
|
|
112
116
|
const listenersRef = React.useRef(new Set());
|
|
117
|
+
const getToken = React.useCallback(() => {
|
|
118
|
+
if (tokenProvider)
|
|
119
|
+
return tokenProvider();
|
|
120
|
+
if (typeof localStorage === 'undefined')
|
|
121
|
+
return null;
|
|
122
|
+
return localStorage.getItem(DEFAULT_TOKEN_KEY) || localStorage.getItem('shopflare:buyer_token');
|
|
123
|
+
}, [tokenProvider]);
|
|
113
124
|
const gql = React.useCallback(async (query, variables) => {
|
|
125
|
+
const headers = {
|
|
126
|
+
'Content-Type': 'application/json',
|
|
127
|
+
'X-Storefront-Access-Token': shop.storefrontAccessToken,
|
|
128
|
+
};
|
|
129
|
+
// 自动带 buyer JWT — cart resolver 需要它来自动选最佳券
|
|
130
|
+
const token = getToken();
|
|
131
|
+
if (token)
|
|
132
|
+
headers.Authorization = `Bearer ${token}`;
|
|
114
133
|
const res = await fetch(shop.apiUrl, {
|
|
115
134
|
method: 'POST',
|
|
116
|
-
headers
|
|
117
|
-
'Content-Type': 'application/json',
|
|
118
|
-
'X-Storefront-Access-Token': shop.storefrontAccessToken,
|
|
119
|
-
},
|
|
135
|
+
headers,
|
|
120
136
|
body: JSON.stringify({ query, variables }),
|
|
121
137
|
credentials: 'include',
|
|
122
138
|
});
|
|
@@ -124,7 +140,7 @@ export function CartProvider({ children, fetchOnMount = true, initialCart }) {
|
|
|
124
140
|
if (json.errors)
|
|
125
141
|
throw new Error(json.errors[0]?.message || 'GraphQL error');
|
|
126
142
|
return json.data;
|
|
127
|
-
}, [shop.apiUrl, shop.storefrontAccessToken]);
|
|
143
|
+
}, [shop.apiUrl, shop.storefrontAccessToken, getToken]);
|
|
128
144
|
const notifyListeners = React.useCallback((c) => {
|
|
129
145
|
for (const fn of listenersRef.current)
|
|
130
146
|
fn(c);
|
|
@@ -168,10 +184,20 @@ export function CartProvider({ children, fetchOnMount = true, initialCart }) {
|
|
|
168
184
|
}
|
|
169
185
|
}, [gql, applyCart]);
|
|
170
186
|
React.useEffect(() => {
|
|
171
|
-
if (fetchOnMount
|
|
187
|
+
if (!fetchOnMount)
|
|
188
|
+
return;
|
|
189
|
+
if (status === 'uninitialized') {
|
|
172
190
|
void refetch();
|
|
191
|
+
return;
|
|
173
192
|
}
|
|
174
|
-
|
|
193
|
+
// SSR initialCart 命中但客户端有 buyer token → 服务端 SSR 时拿不到 token,
|
|
194
|
+
// 注入的 cart 不带折扣。Hydrate 后立刻刷一次(这次带 buyer auth)。
|
|
195
|
+
// 只在挂载时跑一次。
|
|
196
|
+
if (initialCart && getToken()) {
|
|
197
|
+
void refetch();
|
|
198
|
+
}
|
|
199
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
200
|
+
}, []);
|
|
175
201
|
// optimistic 包装
|
|
176
202
|
const runMutation = React.useCallback(async (optimisticCart, mutator) => {
|
|
177
203
|
const prev = cart;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartProvider.js","sourceRoot":"","sources":["../../src/components/CartProvider.tsx"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AA8DzC,MAAM,WAAW,GAAG,KAAK,CAAC,aAAa,CAA0B,IAAI,CAAC,CAAC;AAEvE,+DAA+D;AAC/D,UAAU;AACV,+DAA+D;AAE/D,MAAM,aAAa,GAAG,aAAa,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCnC,CAAC;AAEF,MAAM,UAAU,GAAG,aAAa,GAAG;;CAElC,CAAC;AACF,MAAM,aAAa,GAAG,aAAa,GAAG;;;;CAIrC,CAAC;AACF,MAAM,WAAW,GAAG,aAAa,GAAG;;;;CAInC,CAAC;AACF,MAAM,cAAc,GAAG,aAAa,GAAG;;;;CAItC,CAAC;AACF,MAAM,cAAc,GAAG,aAAa,GAAG;;;;CAItC,CAAC;AAEF,+DAA+D;AAC/D,iBAAiB;AACjB,+DAA+D;AAE/D,MAAM,WAAW,GAAG,MAAM,CAAC;AAE3B,SAAS,oBAAoB;IAC3B,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACjD,MAAM,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,UAAU,GAAG,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC;IACnF,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACpB,OAAO,qBAAqB,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACzD,CAAC;AAED,SAAS,kBAAkB,CAAC,OAAe;IACzC,IAAI,OAAO,QAAQ,KAAK,WAAW;QAAE,OAAO;IAC5C,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,GAAG,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACnC,2CAA2C;IAC3C,MAAM,OAAO,GAAG,OAAO,QAAQ,KAAK,WAAW,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC;IAClF,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7C,QAAQ,CAAC,MAAM,GAAG,GAAG,WAAW,IAAI,kBAAkB,CAAC,EAAE,CAAC,qBAAqB,OAAO,iBAAiB,UAAU,EAAE,CAAC;AACtH,CAAC;
|
|
1
|
+
{"version":3,"file":"CartProvider.js","sourceRoot":"","sources":["../../src/components/CartProvider.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -173,6 +173,8 @@ function saveCartIdToCookie(cartGid: string) {
|
|
|
173
173
|
// Provider
|
|
174
174
|
// ============================================================
|
|
175
175
|
|
|
176
|
+
const DEFAULT_TOKEN_KEY = 'shopbb:buyer_token';
|
|
177
|
+
|
|
176
178
|
export interface CartProviderProps {
|
|
177
179
|
children: React.ReactNode;
|
|
178
180
|
/** 加载完成后是否自动拉 cart。默认 true */
|
|
@@ -184,9 +186,19 @@ export interface CartProviderProps {
|
|
|
184
186
|
* 如果传入,fetchOnMount 默认行为变成只在 cart 数据可能过期时 refetch(当前简单实现:不再自动 refetch)。
|
|
185
187
|
*/
|
|
186
188
|
initialCart?: Cart | null;
|
|
189
|
+
/**
|
|
190
|
+
* 取买家 JWT 的函数。
|
|
191
|
+
*
|
|
192
|
+
* 关键意义:cart resolver 服务端会根据 buyer JWT **自动选最佳优惠券**,
|
|
193
|
+
* 写入 cart.cost.totalDiscountAmount + appliedDiscountClaim。
|
|
194
|
+
* 如果不带 token 调 GraphQL,服务端只能返回"无折扣 cart",价格不准。
|
|
195
|
+
*
|
|
196
|
+
* 不传时 fallback 从 localStorage 读 `shopbb:buyer_token` 或 `shopflare:buyer_token`。
|
|
197
|
+
*/
|
|
198
|
+
tokenProvider?: () => string | null;
|
|
187
199
|
}
|
|
188
200
|
|
|
189
|
-
export function CartProvider({ children, fetchOnMount = true, initialCart }: CartProviderProps) {
|
|
201
|
+
export function CartProvider({ children, fetchOnMount = true, initialCart, tokenProvider }: CartProviderProps) {
|
|
190
202
|
const shop = useShop();
|
|
191
203
|
// SSR 同构:initialCart 直接进 state,避免 hydrate 时闪烁
|
|
192
204
|
const [cart, setCart] = React.useState<Cart | null>(initialCart ?? null);
|
|
@@ -194,14 +206,25 @@ export function CartProvider({ children, fetchOnMount = true, initialCart }: Car
|
|
|
194
206
|
const [error, setError] = React.useState<string | null>(null);
|
|
195
207
|
const listenersRef = React.useRef(new Set<(c: Cart | null) => void>());
|
|
196
208
|
|
|
209
|
+
const getToken = React.useCallback(() => {
|
|
210
|
+
if (tokenProvider) return tokenProvider();
|
|
211
|
+
if (typeof localStorage === 'undefined') return null;
|
|
212
|
+
return localStorage.getItem(DEFAULT_TOKEN_KEY) || localStorage.getItem('shopflare:buyer_token');
|
|
213
|
+
}, [tokenProvider]);
|
|
214
|
+
|
|
197
215
|
const gql = React.useCallback(
|
|
198
216
|
async <T = any>(query: string, variables?: any): Promise<T> => {
|
|
217
|
+
const headers: Record<string, string> = {
|
|
218
|
+
'Content-Type': 'application/json',
|
|
219
|
+
'X-Storefront-Access-Token': shop.storefrontAccessToken,
|
|
220
|
+
};
|
|
221
|
+
// 自动带 buyer JWT — cart resolver 需要它来自动选最佳券
|
|
222
|
+
const token = getToken();
|
|
223
|
+
if (token) headers.Authorization = `Bearer ${token}`;
|
|
224
|
+
|
|
199
225
|
const res = await fetch(shop.apiUrl, {
|
|
200
226
|
method: 'POST',
|
|
201
|
-
headers
|
|
202
|
-
'Content-Type': 'application/json',
|
|
203
|
-
'X-Storefront-Access-Token': shop.storefrontAccessToken,
|
|
204
|
-
},
|
|
227
|
+
headers,
|
|
205
228
|
body: JSON.stringify({ query, variables }),
|
|
206
229
|
credentials: 'include',
|
|
207
230
|
});
|
|
@@ -209,7 +232,7 @@ export function CartProvider({ children, fetchOnMount = true, initialCart }: Car
|
|
|
209
232
|
if (json.errors) throw new Error(json.errors[0]?.message || 'GraphQL error');
|
|
210
233
|
return json.data;
|
|
211
234
|
},
|
|
212
|
-
[shop.apiUrl, shop.storefrontAccessToken],
|
|
235
|
+
[shop.apiUrl, shop.storefrontAccessToken, getToken],
|
|
213
236
|
);
|
|
214
237
|
|
|
215
238
|
const notifyListeners = React.useCallback((c: Cart | null) => {
|
|
@@ -262,10 +285,19 @@ export function CartProvider({ children, fetchOnMount = true, initialCart }: Car
|
|
|
262
285
|
}, [gql, applyCart]);
|
|
263
286
|
|
|
264
287
|
React.useEffect(() => {
|
|
265
|
-
if (fetchOnMount
|
|
288
|
+
if (!fetchOnMount) return;
|
|
289
|
+
if (status === 'uninitialized') {
|
|
290
|
+
void refetch();
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
// SSR initialCart 命中但客户端有 buyer token → 服务端 SSR 时拿不到 token,
|
|
294
|
+
// 注入的 cart 不带折扣。Hydrate 后立刻刷一次(这次带 buyer auth)。
|
|
295
|
+
// 只在挂载时跑一次。
|
|
296
|
+
if (initialCart && getToken()) {
|
|
266
297
|
void refetch();
|
|
267
298
|
}
|
|
268
|
-
|
|
299
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
300
|
+
}, []);
|
|
269
301
|
|
|
270
302
|
// optimistic 包装
|
|
271
303
|
const runMutation = React.useCallback(
|