@shopbb/helium 0.3.1 → 0.4.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.
Files changed (36) hide show
  1. package/dist/components/AddressBookProvider.d.ts +93 -0
  2. package/dist/components/AddressBookProvider.d.ts.map +1 -0
  3. package/dist/components/AddressBookProvider.js +182 -0
  4. package/dist/components/AddressBookProvider.js.map +1 -0
  5. package/dist/components/AddressForm.d.ts +54 -0
  6. package/dist/components/AddressForm.d.ts.map +1 -0
  7. package/dist/components/AddressForm.js +87 -0
  8. package/dist/components/AddressForm.js.map +1 -0
  9. package/dist/components/AddressList.d.ts +35 -0
  10. package/dist/components/AddressList.d.ts.map +1 -0
  11. package/dist/components/AddressList.js +40 -0
  12. package/dist/components/AddressList.js.map +1 -0
  13. package/dist/components/AddressPicker.d.ts +39 -0
  14. package/dist/components/AddressPicker.d.ts.map +1 -0
  15. package/dist/components/AddressPicker.js +74 -0
  16. package/dist/components/AddressPicker.js.map +1 -0
  17. package/dist/components/DiscountComponents.d.ts +66 -0
  18. package/dist/components/DiscountComponents.d.ts.map +1 -0
  19. package/dist/components/DiscountComponents.js +169 -0
  20. package/dist/components/DiscountComponents.js.map +1 -0
  21. package/dist/components/DiscountProvider.d.ts +143 -0
  22. package/dist/components/DiscountProvider.d.ts.map +1 -0
  23. package/dist/components/DiscountProvider.js +317 -0
  24. package/dist/components/DiscountProvider.js.map +1 -0
  25. package/dist/components/index.d.ts +12 -0
  26. package/dist/components/index.d.ts.map +1 -1
  27. package/dist/components/index.js +8 -0
  28. package/dist/components/index.js.map +1 -1
  29. package/package.json +1 -1
  30. package/src/components/AddressBookProvider.tsx +279 -0
  31. package/src/components/AddressForm.tsx +198 -0
  32. package/src/components/AddressList.tsx +110 -0
  33. package/src/components/AddressPicker.tsx +152 -0
  34. package/src/components/DiscountComponents.tsx +369 -0
  35. package/src/components/DiscountProvider.tsx +455 -0
  36. package/src/components/index.ts +62 -0
@@ -0,0 +1,317 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * <DiscountProvider> + useDiscounts() + useProductDiscounts()
4
+ *
5
+ * 优惠券完整能力:
6
+ * - publicDiscounts: 公开可领的券(storefront 首页 / cart 展示)
7
+ * - myDiscounts: 我领过的有效券(卡包)
8
+ * - claim(code): 领取
9
+ * - cart 上的折扣:appliedToCart / applyToCart / removeFromCart
10
+ * - bestApplicableForCart: 当前 cart 最大可省(哪张最划算)
11
+ *
12
+ * 内部走 Storefront GraphQL + Customer Account GraphQL。
13
+ */
14
+ import * as React from 'react';
15
+ import { useShop } from './ShopProvider';
16
+ import { useCartOptional } from './CartProvider';
17
+ const Ctx = React.createContext(null);
18
+ const DEFAULT_TOKEN_KEY = 'shopbb:buyer_token';
19
+ export function DiscountProvider(props) {
20
+ const { children, fetchPublicOnMount = true, fetchMyOnMount = true, tokenProvider } = props;
21
+ const shop = useShop();
22
+ const cartCtx = useCartOptional();
23
+ const [publicDiscounts, setPublicDiscounts] = React.useState([]);
24
+ const [publicDiscountsStatus, setPublicDiscountsStatus] = React.useState('idle');
25
+ const [myDiscounts, setMyDiscounts] = React.useState([]);
26
+ const [myDiscountsStatus, setMyDiscountsStatus] = React.useState('idle');
27
+ const [error, setError] = React.useState(null);
28
+ const customerEndpoint = React.useMemo(() => {
29
+ try {
30
+ const u = new URL(shop.apiUrl);
31
+ return `${u.origin}/customer/api/2026-04/graphql`;
32
+ }
33
+ catch {
34
+ return shop.apiUrl;
35
+ }
36
+ }, [shop.apiUrl]);
37
+ const getToken = React.useCallback(() => {
38
+ if (tokenProvider)
39
+ return tokenProvider();
40
+ if (typeof localStorage === 'undefined')
41
+ return null;
42
+ return localStorage.getItem(DEFAULT_TOKEN_KEY) || localStorage.getItem('shopflare:buyer_token');
43
+ }, [tokenProvider]);
44
+ const storefrontGql = React.useCallback(async (query, variables) => {
45
+ const res = await fetch(shop.apiUrl, {
46
+ method: 'POST',
47
+ headers: {
48
+ 'Content-Type': 'application/json',
49
+ 'X-Storefront-Access-Token': shop.storefrontAccessToken,
50
+ },
51
+ body: JSON.stringify({ query, variables }),
52
+ credentials: 'include',
53
+ });
54
+ return res.json();
55
+ }, [shop.apiUrl, shop.storefrontAccessToken]);
56
+ const customerGql = React.useCallback(async (query, variables) => {
57
+ const token = getToken();
58
+ if (!token)
59
+ throw new Error('not authenticated');
60
+ const res = await fetch(customerEndpoint, {
61
+ method: 'POST',
62
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
63
+ body: JSON.stringify({ query, variables }),
64
+ });
65
+ return res.json();
66
+ }, [customerEndpoint, getToken]);
67
+ // ----- public discounts -----
68
+ const refetchPublicDiscounts = React.useCallback(async () => {
69
+ setPublicDiscountsStatus('loading');
70
+ try {
71
+ const result = await storefrontGql(`query { publicDiscounts(first: 50) {
72
+ nodes {
73
+ id code title description distribution appliesTo
74
+ valueType
75
+ value {
76
+ __typename
77
+ ... on DiscountPercentage { percentage }
78
+ ... on DiscountAmount { amount { amount currencyCode } }
79
+ ... on DiscountFreeShipping { freeShipping }
80
+ }
81
+ minSubtotal { amount currencyCode }
82
+ startsAt endsAt
83
+ bannerImage { url altText }
84
+ }
85
+ } }`);
86
+ if (result.errors?.length)
87
+ throw new Error(result.errors[0].message);
88
+ setPublicDiscounts(result.data?.publicDiscounts?.nodes ?? []);
89
+ setPublicDiscountsStatus('idle');
90
+ }
91
+ catch (e) {
92
+ setError(e?.message);
93
+ setPublicDiscountsStatus('error');
94
+ }
95
+ }, [storefrontGql]);
96
+ // ----- my discounts -----
97
+ const refetchMyDiscounts = React.useCallback(async () => {
98
+ const token = getToken();
99
+ if (!token) {
100
+ setMyDiscountsStatus('unauthenticated');
101
+ setMyDiscounts([]);
102
+ return;
103
+ }
104
+ setMyDiscountsStatus('loading');
105
+ try {
106
+ const result = await customerGql(`query { customer { discountClaims(first: 50) {
107
+ nodes {
108
+ id claimedAt usedCount remainingUses expiresAt isExpired
109
+ discount {
110
+ id code title description
111
+ valueType valuePercentage
112
+ valueAmount { amount currencyCode }
113
+ minSubtotal { amount currencyCode }
114
+ endsAt bannerImage
115
+ }
116
+ }
117
+ } } }`);
118
+ if (result.errors?.length)
119
+ throw new Error(result.errors[0].message);
120
+ setMyDiscounts(result.data?.customer?.discountClaims?.nodes ?? []);
121
+ setMyDiscountsStatus('idle');
122
+ }
123
+ catch (e) {
124
+ setError(e?.message);
125
+ setMyDiscountsStatus('error');
126
+ }
127
+ }, [customerGql, getToken]);
128
+ React.useEffect(() => {
129
+ if (fetchPublicOnMount)
130
+ void refetchPublicDiscounts();
131
+ }, [fetchPublicOnMount, refetchPublicDiscounts]);
132
+ React.useEffect(() => {
133
+ if (fetchMyOnMount)
134
+ void refetchMyDiscounts();
135
+ }, [fetchMyOnMount, refetchMyDiscounts]);
136
+ // ----- claim -----
137
+ const claim = React.useCallback(async (code) => {
138
+ try {
139
+ const result = await customerGql(`mutation C($code: String!) {
140
+ discountClaim(code: $code) {
141
+ discountClaim {
142
+ id claimedAt usedCount remainingUses expiresAt isExpired
143
+ discount {
144
+ id code title valueType valuePercentage
145
+ valueAmount { amount currencyCode }
146
+ minSubtotal { amount currencyCode }
147
+ }
148
+ }
149
+ userErrors { field code message }
150
+ }
151
+ }`, { code });
152
+ if (result.errors?.length)
153
+ throw new Error(result.errors[0].message);
154
+ await refetchMyDiscounts();
155
+ const payload = result.data.discountClaim;
156
+ return { claim: payload.discountClaim ?? undefined, userErrors: payload.userErrors };
157
+ }
158
+ catch (e) {
159
+ return { userErrors: [{ code: 'NETWORK_ERROR', message: e?.message ?? String(e) }] };
160
+ }
161
+ }, [customerGql, refetchMyDiscounts]);
162
+ // ----- cart apply / remove -----
163
+ const appliedToCart = cartCtx?.cart && cartCtx.cart.discountCodes ? cartCtx.cart.discountCodes : [];
164
+ const cartAllocations = cartCtx?.cart && cartCtx.cart.discountAllocations ? cartCtx.cart.discountAllocations : [];
165
+ const applyCodes = React.useCallback(async (codes) => {
166
+ if (!cartCtx?.cart)
167
+ return { userErrors: [{ code: 'NO_CART', message: 'cart 不存在' }] };
168
+ const result = await storefrontGql(`mutation U($id: ID!, $codes: [String!]!) {
169
+ cartDiscountCodesUpdate(cartId: $id, discountCodes: $codes) {
170
+ cart { id }
171
+ userErrors { field code message }
172
+ }
173
+ }`, { id: cartCtx.cart.id, codes });
174
+ if (result.errors?.length) {
175
+ return { userErrors: [{ code: 'NETWORK_ERROR', message: result.errors[0].message }] };
176
+ }
177
+ // 刷 cart(拉新的 discountCodes / allocations)
178
+ await cartCtx.refetch();
179
+ return { userErrors: result.data.cartDiscountCodesUpdate.userErrors };
180
+ }, [cartCtx, storefrontGql]);
181
+ const applyToCart = React.useCallback(async (code) => {
182
+ const existing = appliedToCart.map((d) => d.code);
183
+ if (existing.includes(code.toUpperCase()))
184
+ return { userErrors: [] };
185
+ return applyCodes([...existing, code.toUpperCase()]);
186
+ }, [appliedToCart, applyCodes]);
187
+ const removeFromCart = React.useCallback(async (code) => {
188
+ const next = appliedToCart.map((d) => d.code).filter((c) => c !== code.toUpperCase());
189
+ return applyCodes(next);
190
+ }, [appliedToCart, applyCodes]);
191
+ // ----- best applicable for cart -----
192
+ const bestApplicableForCart = React.useMemo(() => {
193
+ if (!cartCtx?.cart || myDiscounts.length === 0)
194
+ return null;
195
+ const subtotalStr = cartCtx.cart.cost?.subtotalAmount?.amount;
196
+ const subtotal = Number(subtotalStr || 0);
197
+ if (subtotal <= 0)
198
+ return null;
199
+ const currentApplied = new Set(appliedToCart.map((d) => d.code));
200
+ let best = null;
201
+ for (const claimed of myDiscounts) {
202
+ const d = claimed.discount;
203
+ if (!d.code || claimed.isExpired)
204
+ continue;
205
+ if (currentApplied.has(d.code))
206
+ continue;
207
+ // 门槛
208
+ if (d.minSubtotal && Number(d.minSubtotal.amount) > subtotal)
209
+ continue;
210
+ // 估算折扣
211
+ let amount = 0;
212
+ if (d.valueType === 'PERCENTAGE' && d.valuePercentage != null) {
213
+ amount = Math.floor(subtotal * (d.valuePercentage / 100) * 100) / 100;
214
+ }
215
+ else if (d.valueType === 'FIXED_AMOUNT' && d.valueAmount) {
216
+ amount = Math.min(Number(d.valueAmount.amount), subtotal);
217
+ }
218
+ if (amount > 0 && (best == null || amount > best.estimatedAmount)) {
219
+ best = { discount: claimed, estimatedAmount: amount };
220
+ }
221
+ }
222
+ return best;
223
+ }, [cartCtx, myDiscounts, appliedToCart]);
224
+ const value = React.useMemo(() => ({
225
+ publicDiscounts, publicDiscountsStatus,
226
+ myDiscounts, myDiscountsStatus,
227
+ appliedToCart, cartAllocations,
228
+ bestApplicableForCart,
229
+ error,
230
+ claim, applyToCart, removeFromCart,
231
+ refetchMyDiscounts, refetchPublicDiscounts,
232
+ }), [
233
+ publicDiscounts, publicDiscountsStatus,
234
+ myDiscounts, myDiscountsStatus,
235
+ appliedToCart, cartAllocations,
236
+ bestApplicableForCart, error,
237
+ claim, applyToCart, removeFromCart,
238
+ refetchMyDiscounts, refetchPublicDiscounts,
239
+ ]);
240
+ return _jsx(Ctx.Provider, { value: value, children: children });
241
+ }
242
+ export function useDiscounts() {
243
+ const v = React.useContext(Ctx);
244
+ if (!v)
245
+ throw new Error('useDiscounts must be used inside <DiscountProvider>');
246
+ return v;
247
+ }
248
+ export function useDiscountsOptional() {
249
+ return React.useContext(Ctx);
250
+ }
251
+ // ============================================================
252
+ // useProductDiscounts(handle) — 商品页用
253
+ // ============================================================
254
+ export function useProductDiscounts(productHandle) {
255
+ const shop = useShop();
256
+ const [discounts, setDiscounts] = React.useState([]);
257
+ const [loading, setLoading] = React.useState(false);
258
+ const [error, setError] = React.useState(null);
259
+ React.useEffect(() => {
260
+ if (!productHandle) {
261
+ setDiscounts([]);
262
+ return;
263
+ }
264
+ let cancelled = false;
265
+ setLoading(true);
266
+ (async () => {
267
+ try {
268
+ const res = await fetch(shop.apiUrl, {
269
+ method: 'POST',
270
+ headers: {
271
+ 'Content-Type': 'application/json',
272
+ 'X-Storefront-Access-Token': shop.storefrontAccessToken,
273
+ },
274
+ body: JSON.stringify({
275
+ query: `query P($h: String!) {
276
+ productDiscounts(productHandle: $h) {
277
+ id code title description
278
+ valueType
279
+ value {
280
+ __typename
281
+ ... on DiscountPercentage { percentage }
282
+ ... on DiscountAmount { amount { amount currencyCode } }
283
+ ... on DiscountFreeShipping { freeShipping }
284
+ }
285
+ minSubtotal { amount currencyCode }
286
+ endsAt
287
+ bannerImage { url }
288
+ }
289
+ }`,
290
+ variables: { h: productHandle },
291
+ }),
292
+ credentials: 'include',
293
+ });
294
+ const r = await res.json();
295
+ if (cancelled)
296
+ return;
297
+ if (r.errors?.length) {
298
+ setError(r.errors[0].message);
299
+ }
300
+ else {
301
+ setDiscounts(r.data?.productDiscounts ?? []);
302
+ }
303
+ }
304
+ catch (e) {
305
+ if (!cancelled)
306
+ setError(e?.message);
307
+ }
308
+ finally {
309
+ if (!cancelled)
310
+ setLoading(false);
311
+ }
312
+ })();
313
+ return () => { cancelled = true; };
314
+ }, [productHandle, shop.apiUrl, shop.storefrontAccessToken]);
315
+ return { discounts, loading, error };
316
+ }
317
+ //# sourceMappingURL=DiscountProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiscountProvider.js","sourceRoot":"","sources":["../../src/components/DiscountProvider.tsx"],"names":[],"mappings":"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"}
@@ -38,4 +38,16 @@ export { CartLineQuantityAdjustButton } from './CartLineQuantityAdjustButton';
38
38
  export type { CartLineQuantityAdjustButtonProps } from './CartLineQuantityAdjustButton';
39
39
  export { VariantSelector } from './VariantSelector';
40
40
  export type { VariantSelectorProps, VariantSelectorRenderProps, VariantOption, } from './VariantSelector';
41
+ export { AddressBookProvider, useAddressBook, useAddressBookOptional, } from './AddressBookProvider';
42
+ export type { Address, AddressInput, AddressBookStatus, AddressBookUserError, AddressBookContextValue, AddressBookProviderProps, } from './AddressBookProvider';
43
+ export { AddressList } from './AddressList';
44
+ export type { AddressListProps, AddressListItemActions } from './AddressList';
45
+ export { AddressForm } from './AddressForm';
46
+ export type { AddressFormProps, AddressFormI18n } from './AddressForm';
47
+ export { AddressPicker } from './AddressPicker';
48
+ export type { AddressPickerProps } from './AddressPicker';
49
+ export { DiscountProvider, useDiscounts, useDiscountsOptional, useProductDiscounts, } from './DiscountProvider';
50
+ export type { Discount, DiscountClaim, DiscountValueType, DiscountValuePercentage, DiscountValueAmount, DiscountValueFreeShipping, CartDiscountCode, CartDiscountAllocation, DiscountUserError, DiscountContextValue, DiscountProviderProps, } from './DiscountProvider';
51
+ export { DiscountCodeInput, AppliedDiscountList, BestDiscountHint, ClaimableDiscountList, DiscountClaimButton, MyDiscountList, } from './DiscountComponents';
52
+ export type { DiscountCodeInputProps, AppliedDiscountListProps, BestDiscountHintProps, ClaimableDiscountListProps, DiscountClaimButtonProps, MyDiscountListProps, } from './DiscountComponents';
41
53
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACxE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE1E,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACxE,YAAY,EACV,IAAI,EACJ,QAAQ,EACR,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAClC,YAAY,EACV,0BAA0B,EAC1B,2BAA2B,EAC3B,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACjF,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGzG,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAEvE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAErD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE9D,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAC9E,YAAY,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAC;AAExF,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EACV,oBAAoB,EACpB,0BAA0B,EAC1B,aAAa,GACd,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"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"}
@@ -30,4 +30,12 @@ export { ProductPrice } from './ProductPrice';
30
30
  export { AddToCartButton } from './AddToCartButton';
31
31
  export { CartLineQuantityAdjustButton } from './CartLineQuantityAdjustButton';
32
32
  export { VariantSelector } from './VariantSelector';
33
+ // 地址簿(W4a)
34
+ export { AddressBookProvider, useAddressBook, useAddressBookOptional, } from './AddressBookProvider';
35
+ export { AddressList } from './AddressList';
36
+ export { AddressForm } from './AddressForm';
37
+ export { AddressPicker } from './AddressPicker';
38
+ // 优惠券(W4b)
39
+ export { DiscountProvider, useDiscounts, useDiscountsOptional, useProductDiscounts, } from './DiscountProvider';
40
+ export { DiscountCodeInput, AppliedDiscountList, BestDiscountHint, ClaimableDiscountList, DiscountClaimButton, MyDiscountList, } from './DiscountComponents';
33
41
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGxE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAWxE,OAAO,EACL,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGjF,QAAQ;AACR,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAG9E,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/components/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGxE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAWxE,OAAO,EACL,sBAAsB,EACtB,iBAAiB,GAClB,MAAM,0BAA0B,CAAC;AAOlC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGjF,QAAQ;AACR,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAGhC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGpD,OAAO,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAG9E,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAOpD,WAAW;AACX,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAU/B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAG5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD,WAAW;AACX,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAe5B,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,GACf,MAAM,sBAAsB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopbb/helium",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "shopbb storefront framework — components, React SSR, GraphQL client, cart handler, cache for Cloudflare Workers",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -0,0 +1,279 @@
1
+ /**
2
+ * <AddressBookProvider> + useAddressBook()
3
+ *
4
+ * 接管买家地址簿全部能力。内部走 Customer Account GraphQL(不直接 fetch REST),
5
+ * 让商家代码不需要关心后端实现细节。
6
+ *
7
+ * 鉴权:内部通过 ShopProvider 拿 apiUrl,通过浏览器 localStorage 读 buyer token
8
+ * (key: 'shopbb:buyer_token')。商家也可以传 `tokenProvider` 自定义 token 取法。
9
+ *
10
+ * 用法:
11
+ * <ShopProvider {...}>
12
+ * <AddressBookProvider>
13
+ * <App />
14
+ * </AddressBookProvider>
15
+ * </ShopProvider>
16
+ *
17
+ * const { addresses, defaultAddress, createAddress, ... } = useAddressBook();
18
+ */
19
+
20
+ import * as React from 'react';
21
+ import { useShop } from './ShopProvider';
22
+
23
+ export interface Address {
24
+ id: string;
25
+ firstName?: string | null;
26
+ lastName?: string | null;
27
+ company?: string | null;
28
+ address1?: string | null;
29
+ address2?: string | null;
30
+ city?: string | null;
31
+ district?: string | null;
32
+ province?: string | null;
33
+ provinceCode?: string | null;
34
+ country?: string | null;
35
+ countryCode?: string | null;
36
+ zip?: string | null;
37
+ phone?: string | null;
38
+ latitude?: number | null;
39
+ longitude?: number | null;
40
+ isDefault: boolean;
41
+ }
42
+
43
+ export interface AddressInput {
44
+ firstName?: string;
45
+ lastName?: string;
46
+ company?: string;
47
+ address1?: string;
48
+ address2?: string;
49
+ city?: string;
50
+ district?: string;
51
+ province?: string;
52
+ provinceCode?: string;
53
+ country?: string;
54
+ countryCode?: string;
55
+ zip?: string;
56
+ phone?: string;
57
+ }
58
+
59
+ export type AddressBookStatus = 'unauthenticated' | 'loading' | 'idle' | 'updating' | 'error';
60
+
61
+ export interface AddressBookUserError {
62
+ field?: string[];
63
+ code?: string;
64
+ message: string;
65
+ }
66
+
67
+ export interface AddressBookContextValue {
68
+ addresses: Address[];
69
+ defaultAddress: Address | null;
70
+ status: AddressBookStatus;
71
+ error: string | null;
72
+ createAddress: (input: AddressInput, asDefault?: boolean) => Promise<{ address?: Address; userErrors: AddressBookUserError[] }>;
73
+ updateAddress: (id: string, input: AddressInput, asDefault?: boolean) => Promise<{ address?: Address; userErrors: AddressBookUserError[] }>;
74
+ deleteAddress: (id: string) => Promise<{ userErrors: AddressBookUserError[] }>;
75
+ setDefault: (id: string) => Promise<{ userErrors: AddressBookUserError[] }>;
76
+ refetch: () => Promise<void>;
77
+ }
78
+
79
+ const Ctx = React.createContext<AddressBookContextValue | null>(null);
80
+
81
+ const DEFAULT_TOKEN_KEY = 'shopbb:buyer_token';
82
+
83
+ export interface AddressBookProviderProps {
84
+ children: React.ReactNode;
85
+ /** 自定义 token 取法。默认 localStorage[DEFAULT_TOKEN_KEY] */
86
+ tokenProvider?: () => string | null;
87
+ /** 自动 fetch;默认 true */
88
+ fetchOnMount?: boolean;
89
+ /** Customer Account GraphQL endpoint。默认 ${shop.apiUrl 替换为 /customer/api/2026-04/graphql} */
90
+ endpoint?: string;
91
+ }
92
+
93
+ export function AddressBookProvider(props: AddressBookProviderProps) {
94
+ const { children, tokenProvider, fetchOnMount = true, endpoint: endpointProp } = props;
95
+ const shop = useShop();
96
+
97
+ const [addresses, setAddresses] = React.useState<Address[]>([]);
98
+ const [defaultAddress, setDefaultAddressState] = React.useState<Address | null>(null);
99
+ const [status, setStatus] = React.useState<AddressBookStatus>('loading');
100
+ const [error, setError] = React.useState<string | null>(null);
101
+
102
+ const endpoint = React.useMemo(() => {
103
+ if (endpointProp) return endpointProp;
104
+ try {
105
+ const u = new URL(shop.apiUrl);
106
+ return `${u.origin}/customer/api/2026-04/graphql`;
107
+ } catch {
108
+ return shop.apiUrl;
109
+ }
110
+ }, [endpointProp, shop.apiUrl]);
111
+
112
+ const getToken = React.useCallback(() => {
113
+ if (tokenProvider) return tokenProvider();
114
+ if (typeof localStorage === 'undefined') return null;
115
+ return localStorage.getItem(DEFAULT_TOKEN_KEY) || localStorage.getItem('shopflare:buyer_token');
116
+ }, [tokenProvider]);
117
+
118
+ const gql = React.useCallback(
119
+ async <T = any>(query: string, variables?: any): Promise<{ data?: T; errors?: any[] }> => {
120
+ const token = getToken();
121
+ if (!token) throw new Error('未登录');
122
+ const res = await fetch(endpoint, {
123
+ method: 'POST',
124
+ headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
125
+ body: JSON.stringify({ query, variables }),
126
+ });
127
+ return res.json();
128
+ },
129
+ [endpoint, getToken],
130
+ );
131
+
132
+ const refetch = React.useCallback(async () => {
133
+ const token = getToken();
134
+ if (!token) {
135
+ setStatus('unauthenticated');
136
+ setAddresses([]);
137
+ setDefaultAddressState(null);
138
+ return;
139
+ }
140
+ setStatus('loading');
141
+ try {
142
+ const result = await gql<{ customer: { defaultAddress: Address | null; addresses: { nodes: Address[] } } | null }>(
143
+ `query { customer { defaultAddress { id firstName lastName phone city district province address1 address2 country zip isDefault } addresses(first: 50) { nodes { id firstName lastName company phone city district province provinceCode country countryCode address1 address2 zip latitude longitude isDefault } } } }`,
144
+ );
145
+ if (result.errors?.length) throw new Error(result.errors[0].message);
146
+ const c = result.data?.customer;
147
+ setAddresses(c?.addresses?.nodes ?? []);
148
+ setDefaultAddressState(c?.defaultAddress ?? null);
149
+ setStatus('idle');
150
+ setError(null);
151
+ } catch (e: any) {
152
+ setError(e?.message ?? String(e));
153
+ setStatus('error');
154
+ }
155
+ }, [gql, getToken]);
156
+
157
+ React.useEffect(() => {
158
+ if (fetchOnMount) void refetch();
159
+ }, [fetchOnMount, refetch]);
160
+
161
+ const createAddress = React.useCallback(
162
+ async (input: AddressInput, asDefault?: boolean) => {
163
+ setStatus('updating');
164
+ try {
165
+ const result = await gql<{ customerAddressCreate: { customerAddress: Address | null; userErrors: AddressBookUserError[] } }>(
166
+ `mutation Create($a: MailingAddressInput!, $d: Boolean) {
167
+ customerAddressCreate(address: $a, defaultAddress: $d) {
168
+ customerAddress { id firstName lastName phone city district province address1 address2 country zip isDefault }
169
+ userErrors { field code message }
170
+ }
171
+ }`,
172
+ { a: input, d: asDefault ?? false },
173
+ );
174
+ if (result.errors?.length) throw new Error(result.errors[0].message);
175
+ const payload = result.data!.customerAddressCreate;
176
+ await refetch();
177
+ return { address: payload.customerAddress ?? undefined, userErrors: payload.userErrors };
178
+ } catch (e: any) {
179
+ setStatus('error');
180
+ setError(e?.message);
181
+ return { userErrors: [{ code: 'NETWORK_ERROR', message: e?.message ?? String(e) }] };
182
+ }
183
+ },
184
+ [gql, refetch],
185
+ );
186
+
187
+ const updateAddress = React.useCallback(
188
+ async (id: string, input: AddressInput, asDefault?: boolean) => {
189
+ setStatus('updating');
190
+ try {
191
+ const result = await gql<{ customerAddressUpdate: { customerAddress: Address | null; userErrors: AddressBookUserError[] } }>(
192
+ `mutation Upd($id: ID!, $a: MailingAddressInput!, $d: Boolean) {
193
+ customerAddressUpdate(addressId: $id, address: $a, defaultAddress: $d) {
194
+ customerAddress { id firstName lastName phone city district province address1 address2 country zip isDefault }
195
+ userErrors { field code message }
196
+ }
197
+ }`,
198
+ { id, a: input, d: asDefault },
199
+ );
200
+ if (result.errors?.length) throw new Error(result.errors[0].message);
201
+ const payload = result.data!.customerAddressUpdate;
202
+ await refetch();
203
+ return { address: payload.customerAddress ?? undefined, userErrors: payload.userErrors };
204
+ } catch (e: any) {
205
+ setStatus('error');
206
+ setError(e?.message);
207
+ return { userErrors: [{ code: 'NETWORK_ERROR', message: e?.message ?? String(e) }] };
208
+ }
209
+ },
210
+ [gql, refetch],
211
+ );
212
+
213
+ const deleteAddress = React.useCallback(
214
+ async (id: string) => {
215
+ setStatus('updating');
216
+ try {
217
+ const result = await gql<{ customerAddressDelete: { deletedAddressId: string | null; userErrors: AddressBookUserError[] } }>(
218
+ `mutation D($id: ID!) {
219
+ customerAddressDelete(addressId: $id) {
220
+ deletedAddressId
221
+ userErrors { field code message }
222
+ }
223
+ }`,
224
+ { id },
225
+ );
226
+ if (result.errors?.length) throw new Error(result.errors[0].message);
227
+ await refetch();
228
+ return { userErrors: result.data!.customerAddressDelete.userErrors };
229
+ } catch (e: any) {
230
+ setStatus('error');
231
+ setError(e?.message);
232
+ return { userErrors: [{ code: 'NETWORK_ERROR', message: e?.message ?? String(e) }] };
233
+ }
234
+ },
235
+ [gql, refetch],
236
+ );
237
+
238
+ const setDefault = React.useCallback(
239
+ async (id: string) => {
240
+ setStatus('updating');
241
+ try {
242
+ const result = await gql<{ customerDefaultAddressUpdate: { customer: any; userErrors: AddressBookUserError[] } }>(
243
+ `mutation SD($id: ID!) {
244
+ customerDefaultAddressUpdate(addressId: $id) {
245
+ customer { id }
246
+ userErrors { field code message }
247
+ }
248
+ }`,
249
+ { id },
250
+ );
251
+ if (result.errors?.length) throw new Error(result.errors[0].message);
252
+ await refetch();
253
+ return { userErrors: result.data!.customerDefaultAddressUpdate.userErrors };
254
+ } catch (e: any) {
255
+ setStatus('error');
256
+ setError(e?.message);
257
+ return { userErrors: [{ code: 'NETWORK_ERROR', message: e?.message ?? String(e) }] };
258
+ }
259
+ },
260
+ [gql, refetch],
261
+ );
262
+
263
+ const value: AddressBookContextValue = React.useMemo(
264
+ () => ({ addresses, defaultAddress, status, error, createAddress, updateAddress, deleteAddress, setDefault, refetch }),
265
+ [addresses, defaultAddress, status, error, createAddress, updateAddress, deleteAddress, setDefault, refetch],
266
+ );
267
+
268
+ return <Ctx.Provider value={value}>{children}</Ctx.Provider>;
269
+ }
270
+
271
+ export function useAddressBook(): AddressBookContextValue {
272
+ const v = React.useContext(Ctx);
273
+ if (!v) throw new Error('useAddressBook must be used inside <AddressBookProvider>');
274
+ return v;
275
+ }
276
+
277
+ export function useAddressBookOptional(): AddressBookContextValue | null {
278
+ return React.useContext(Ctx);
279
+ }