@behio/storefront-sdk 2.7.0 → 2.9.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/dist/react.d.ts CHANGED
@@ -228,6 +228,8 @@ interface CheckoutSettings {
228
228
  type PriceDisplay = "INCL_VAT" | "EXCL_VAT" | "CUSTOMER_CHOICE";
229
229
  type CurrencyDisplayFormat = "SYMBOL_BEFORE" | "SYMBOL_AFTER" | "CODE";
230
230
  interface ShopInfo {
231
+ /** Merchant default catalog order, normalized to the public sort values. */
232
+ defaultProductSort?: ProductSortValue;
231
233
  currencyDisplayFormat?: CurrencyDisplayFormat;
232
234
  account?: {
233
235
  passwordMinLength: number;
@@ -561,6 +563,8 @@ interface ProductLabel {
561
563
  slug: string;
562
564
  name: string;
563
565
  color?: string;
566
+ /** Merchant icon name. Render a trusted local icon, with a safe fallback. */
567
+ iconName?: string | null;
564
568
  }
565
569
  /**
566
570
  * Resolved availability status of a product. Either a merchant preset
@@ -1128,6 +1132,7 @@ interface FacetLabel {
1128
1132
  slug: string;
1129
1133
  name: string;
1130
1134
  color?: string | null;
1135
+ iconName?: string | null;
1131
1136
  count: number;
1132
1137
  }
1133
1138
  interface FacetCategory {
@@ -1625,7 +1630,13 @@ interface OrderListItem {
1625
1630
  interface OrderItem {
1626
1631
  productName: string;
1627
1632
  sku: string;
1628
- imageUrl?: string;
1633
+ /** Photo snapshot from checkout, or the product's current photo. */
1634
+ imageUrl?: string | null;
1635
+ /** Product still in the shop (SDK 2.8.0). Null when it was removed since,
1636
+ * so a template never links to a missing product page. */
1637
+ productId?: string | null;
1638
+ /** URL slug for a link back to the product page (SDK 2.8.0). */
1639
+ productSlug?: string | null;
1629
1640
  quantity: number;
1630
1641
  unitPrice: number;
1631
1642
  totalPrice: number;
@@ -1649,6 +1660,36 @@ interface OrderTracking {
1649
1660
  shippingCountry: string | null;
1650
1661
  items: OrderItem[];
1651
1662
  createdAt: number;
1663
+ /** Order summary, not personal data (SDK 2.8.0). */
1664
+ subtotal?: number;
1665
+ shippingTotal?: number;
1666
+ paymentFee?: number | null;
1667
+ discountTotal?: number;
1668
+ taxTotal?: number;
1669
+ taxBreakdown?: TaxBreakdownLine[];
1670
+ /** Shipping method as the customer chose it (SDK 2.8.0). */
1671
+ shippingMethodName?: string | null;
1672
+ /** Payment method in the order language (SDK 2.8.0). */
1673
+ paymentMethodName?: string | null;
1674
+ /** Pickup point the customer chose, a public place (SDK 2.8.0). */
1675
+ pickupPoint?: OrderPickupPoint | null;
1676
+ /** Parcels the customer can follow (SDK 2.8.0). */
1677
+ shipments?: OrderShipment[];
1678
+ }
1679
+ /** Pickup point the customer chose for an order (SDK 2.8.0). */
1680
+ interface OrderPickupPoint {
1681
+ name: string;
1682
+ street?: string | null;
1683
+ city?: string | null;
1684
+ zip?: string | null;
1685
+ country?: string | null;
1686
+ }
1687
+ /** A parcel on its way, with the carrier's tracking link (SDK 2.8.0). */
1688
+ interface OrderShipment {
1689
+ trackingNumber?: string | null;
1690
+ trackingUrl?: string | null;
1691
+ status: string;
1692
+ createdAt: number;
1652
1693
  }
1653
1694
  interface OrderStatusHistory {
1654
1695
  fromStatus?: OrderStatus;
@@ -1662,6 +1703,14 @@ interface OrderDetail extends OrderListItem {
1662
1703
  contentDeliveryPending?: boolean;
1663
1704
  /** False for an order without physical delivery. */
1664
1705
  requiresShipping?: boolean;
1706
+ /** Shipping method as the customer chose it (SDK 2.8.0). */
1707
+ shippingMethodName?: string | null;
1708
+ /** Payment method in the order language (SDK 2.8.0). */
1709
+ paymentMethodName?: string | null;
1710
+ /** Pickup point the customer chose, a public place (SDK 2.8.0). */
1711
+ pickupPoint?: OrderPickupPoint | null;
1712
+ /** Parcels the customer can follow (SDK 2.8.0). */
1713
+ shipments?: OrderShipment[];
1665
1714
  items: OrderItem[];
1666
1715
  shippingAddress: CheckoutAddress;
1667
1716
  billingAddress: CheckoutAddress;
@@ -2498,6 +2547,7 @@ interface PickupPointsInput {
2498
2547
  }
2499
2548
  /** Public terms of the eshop's loyalty program. */
2500
2549
  interface LoyaltyProgram {
2550
+ enrollmentType?: "AUTO_ON_REGISTER" | "OPT_IN" | "INVITE_ONLY";
2501
2551
  name: string;
2502
2552
  pointName: string;
2503
2553
  pointNamePlural: string;
@@ -2512,6 +2562,8 @@ interface LoyaltyProgram {
2512
2562
  }
2513
2563
  interface LoyaltyBalance {
2514
2564
  currentPoints: number;
2565
+ /** Revoked points to offset before new rewards become spendable. Absent on older servers. */
2566
+ pointsDebt?: number;
2515
2567
  /** `currentPoints` valued in the program currency. */
2516
2568
  currentPointsValue: number;
2517
2569
  lifetimePointsEarned: number;
@@ -2543,10 +2595,13 @@ interface LoyaltyNextTier {
2543
2595
  progressPercent: number;
2544
2596
  }
2545
2597
  interface LoyaltyTransaction {
2598
+ /** Stable identifier on servers supporting cursor history. */
2599
+ id?: string;
2546
2600
  type: string;
2547
2601
  /** Positive = earned, negative = redeemed / expired. */
2548
2602
  points: number;
2549
2603
  balanceAfter: number;
2604
+ debtAfter?: number;
2550
2605
  eventType: string | null;
2551
2606
  description: string | null;
2552
2607
  createdAt: number;
@@ -2558,6 +2613,7 @@ interface LoyaltyTransaction {
2558
2613
  * "join and earn" CTA).
2559
2614
  */
2560
2615
  interface LoyaltySummary {
2616
+ canJoin?: boolean;
2561
2617
  hasProgram: boolean;
2562
2618
  enrolled: boolean;
2563
2619
  program: LoyaltyProgram | null;
@@ -2566,6 +2622,18 @@ interface LoyaltySummary {
2566
2622
  nextTier: LoyaltyNextTier | null;
2567
2623
  referralCode: string | null;
2568
2624
  transactions: LoyaltyTransaction[];
2625
+ /** Follow using getLoyalty({transactionsCursor}); null is the last page. */
2626
+ transactionsNextCursor?: string | null;
2627
+ canApplyReferral?: boolean;
2628
+ }
2629
+ interface LoyaltyReferralResult {
2630
+ alreadyApplied: boolean;
2631
+ recipientPoints: number;
2632
+ }
2633
+ interface LoyaltyQuery {
2634
+ transactionsCursor?: string;
2635
+ /** 1 to 50, default 20. */
2636
+ transactionsLimit?: number;
2569
2637
  }
2570
2638
  interface CrossSellItem {
2571
2639
  productId: string;
@@ -2894,6 +2962,55 @@ interface CartLinkClaimed extends Cart {
2894
2962
  /** Code carried by the link, including a refused code. Null means no code was offered. */
2895
2963
  linkDiscountCode: string | null;
2896
2964
  }
2965
+ /** Earned merchant badges for the current authenticated customer. */
2966
+ interface CustomerBadge {
2967
+ id: string;
2968
+ name: string;
2969
+ slug: string;
2970
+ description: string | null;
2971
+ iconUrl: string | null;
2972
+ type: "MILESTONE" | "CHALLENGE" | "STREAK" | "ACHIEVEMENT" | "CUSTOM";
2973
+ earnedAt: number;
2974
+ }
2975
+ interface CustomerChallenge {
2976
+ id: string;
2977
+ name: string;
2978
+ slug: string;
2979
+ description: string | null;
2980
+ targetType: string;
2981
+ targetValue: number;
2982
+ /** TOTAL_SPEND uses the shop's default currency and stored reference FX rates. */
2983
+ currency: string;
2984
+ startsAt: number;
2985
+ endsAt: number;
2986
+ rewardPoints: number | null;
2987
+ rewardBadgeName: string | null;
2988
+ active: boolean;
2989
+ joined: boolean;
2990
+ currentProgress: number;
2991
+ completedAt: number | null;
2992
+ canJoin: boolean;
2993
+ rewardMembershipRequired: boolean;
2994
+ }
2995
+ interface CustomerGamificationQuery {
2996
+ badgesPage?: number;
2997
+ challengesPage?: number;
2998
+ /** 1..50, default 20. */
2999
+ limit?: number;
3000
+ }
3001
+ interface CustomerGamification {
3002
+ badges: CustomerBadge[];
3003
+ badgesTotal: number;
3004
+ badgesPage: number;
3005
+ challenges: CustomerChallenge[];
3006
+ challengesTotal: number;
3007
+ challengesPage: number;
3008
+ limit: number;
3009
+ }
3010
+ interface GamificationRefreshResult {
3011
+ awarded: number;
3012
+ completed: number;
3013
+ }
2897
3014
 
2898
3015
  declare class BehioStorefront {
2899
3016
  private baseUrl;
@@ -3517,7 +3634,17 @@ declare class CustomerModule {
3517
3634
  * value, current tier, next-tier progress, point ratio, referral code,
3518
3635
  * recent transactions). Requires an authenticated customer session.
3519
3636
  */
3520
- getLoyalty(): Promise<SdkResult<LoyaltySummary>>;
3637
+ getLoyalty(query?: LoyaltyQuery): Promise<SdkResult<LoyaltySummary>>;
3638
+ /** Apply an invitation to the caller's active loyalty membership, once. */
3639
+ applyReferral(code: string): Promise<SdkResult<LoyaltyReferralResult>>;
3640
+ /** Explicit enrollment; invite-only programs require the shop administrator. */
3641
+ joinLoyalty(): Promise<SdkResult<LoyaltySummary>>;
3642
+ /** Authenticated account rewards. Both collections have independent pages. */
3643
+ getGamification(query?: CustomerGamificationQuery): Promise<SdkResult<CustomerGamification>>;
3644
+ /** Join an active challenge; a repeated call preserves the original joinedAt. */
3645
+ joinChallenge(challengeId: string): Promise<SdkResult<GamificationRefreshResult>>;
3646
+ /** Reconcile persisted qualifying activity. Never supplies progress or points. */
3647
+ refreshGamification(): Promise<SdkResult<GamificationRefreshResult>>;
3521
3648
  /**
3522
3649
  * Digital product delivery (GAP-07): list the logged-in customer's download
3523
3650
  * grants across all their orders (file name, product, remaining downloads,
package/dist/react.js CHANGED
@@ -1655,8 +1655,28 @@ var CustomerModule = class {
1655
1655
  * value, current tier, next-tier progress, point ratio, referral code,
1656
1656
  * recent transactions). Requires an authenticated customer session.
1657
1657
  */
1658
- async getLoyalty() {
1659
- return this.client.request("GET", "/customer/loyalty");
1658
+ async getLoyalty(query = {}) {
1659
+ return this.client.request("GET", "/customer/loyalty", { query: { ...query } });
1660
+ }
1661
+ /** Apply an invitation to the caller's active loyalty membership, once. */
1662
+ async applyReferral(code) {
1663
+ return this.client.request("POST", "/customer/loyalty/referral", { body: { code } });
1664
+ }
1665
+ /** Explicit enrollment; invite-only programs require the shop administrator. */
1666
+ async joinLoyalty() {
1667
+ return this.client.request("POST", "/customer/loyalty/join", { body: { consent: true } });
1668
+ }
1669
+ /** Authenticated account rewards. Both collections have independent pages. */
1670
+ async getGamification(query = {}) {
1671
+ return this.client.request("GET", "/customer/gamification", { query: { ...query } });
1672
+ }
1673
+ /** Join an active challenge; a repeated call preserves the original joinedAt. */
1674
+ async joinChallenge(challengeId) {
1675
+ return this.client.request("POST", `/customer/gamification/challenges/${encodeURIComponent(challengeId)}/join`);
1676
+ }
1677
+ /** Reconcile persisted qualifying activity. Never supplies progress or points. */
1678
+ async refreshGamification() {
1679
+ return this.client.request("POST", "/customer/gamification/refresh");
1660
1680
  }
1661
1681
  /**
1662
1682
  * Digital product delivery (GAP-07): list the logged-in customer's download
@@ -4019,16 +4039,19 @@ function errorParams(err) {
4019
4039
  const params = body?.params;
4020
4040
  return params && typeof params === "object" && !Array.isArray(params) ? params : {};
4021
4041
  }
4022
- var FORM_FIELD_ERROR_CODES = /* @__PURE__ */ new Set([
4023
- "required",
4024
- "invalid",
4025
- "tooShort",
4026
- "tooLong",
4027
- "min",
4028
- "max",
4029
- "notOption",
4030
- "pattern"
4031
- ]);
4042
+ var FORM_FIELD_ERROR_CODES = {
4043
+ required: true,
4044
+ invalid: true,
4045
+ tooShort: true,
4046
+ tooLong: true,
4047
+ min: true,
4048
+ max: true,
4049
+ notOption: true,
4050
+ pattern: true,
4051
+ dateNotFuture: true,
4052
+ dateNotPast: true,
4053
+ tooManyFiles: true
4054
+ };
4032
4055
  function formFieldErrors(err) {
4033
4056
  if (errorCode(err) !== "be.forms.validationFailed") return [];
4034
4057
  const raw = errorParams(err).errors;
@@ -4040,7 +4063,7 @@ function formFieldErrors(err) {
4040
4063
  if (idx <= 0) continue;
4041
4064
  const key = entry.slice(0, idx);
4042
4065
  const code = entry.slice(idx + 1);
4043
- if (!FORM_FIELD_ERROR_CODES.has(code)) continue;
4066
+ if (!Object.prototype.hasOwnProperty.call(FORM_FIELD_ERROR_CODES, code)) continue;
4044
4067
  out.push({ key, code });
4045
4068
  }
4046
4069
  return out;
package/dist/react.mjs CHANGED
@@ -1545,8 +1545,28 @@ var CustomerModule = class {
1545
1545
  * value, current tier, next-tier progress, point ratio, referral code,
1546
1546
  * recent transactions). Requires an authenticated customer session.
1547
1547
  */
1548
- async getLoyalty() {
1549
- return this.client.request("GET", "/customer/loyalty");
1548
+ async getLoyalty(query = {}) {
1549
+ return this.client.request("GET", "/customer/loyalty", { query: { ...query } });
1550
+ }
1551
+ /** Apply an invitation to the caller's active loyalty membership, once. */
1552
+ async applyReferral(code) {
1553
+ return this.client.request("POST", "/customer/loyalty/referral", { body: { code } });
1554
+ }
1555
+ /** Explicit enrollment; invite-only programs require the shop administrator. */
1556
+ async joinLoyalty() {
1557
+ return this.client.request("POST", "/customer/loyalty/join", { body: { consent: true } });
1558
+ }
1559
+ /** Authenticated account rewards. Both collections have independent pages. */
1560
+ async getGamification(query = {}) {
1561
+ return this.client.request("GET", "/customer/gamification", { query: { ...query } });
1562
+ }
1563
+ /** Join an active challenge; a repeated call preserves the original joinedAt. */
1564
+ async joinChallenge(challengeId) {
1565
+ return this.client.request("POST", `/customer/gamification/challenges/${encodeURIComponent(challengeId)}/join`);
1566
+ }
1567
+ /** Reconcile persisted qualifying activity. Never supplies progress or points. */
1568
+ async refreshGamification() {
1569
+ return this.client.request("POST", "/customer/gamification/refresh");
1550
1570
  }
1551
1571
  /**
1552
1572
  * Digital product delivery (GAP-07): list the logged-in customer's download
@@ -3909,16 +3929,19 @@ function errorParams(err) {
3909
3929
  const params = body?.params;
3910
3930
  return params && typeof params === "object" && !Array.isArray(params) ? params : {};
3911
3931
  }
3912
- var FORM_FIELD_ERROR_CODES = /* @__PURE__ */ new Set([
3913
- "required",
3914
- "invalid",
3915
- "tooShort",
3916
- "tooLong",
3917
- "min",
3918
- "max",
3919
- "notOption",
3920
- "pattern"
3921
- ]);
3932
+ var FORM_FIELD_ERROR_CODES = {
3933
+ required: true,
3934
+ invalid: true,
3935
+ tooShort: true,
3936
+ tooLong: true,
3937
+ min: true,
3938
+ max: true,
3939
+ notOption: true,
3940
+ pattern: true,
3941
+ dateNotFuture: true,
3942
+ dateNotPast: true,
3943
+ tooManyFiles: true
3944
+ };
3922
3945
  function formFieldErrors(err) {
3923
3946
  if (errorCode(err) !== "be.forms.validationFailed") return [];
3924
3947
  const raw = errorParams(err).errors;
@@ -3930,7 +3953,7 @@ function formFieldErrors(err) {
3930
3953
  if (idx <= 0) continue;
3931
3954
  const key = entry.slice(0, idx);
3932
3955
  const code = entry.slice(idx + 1);
3933
- if (!FORM_FIELD_ERROR_CODES.has(code)) continue;
3956
+ if (!Object.prototype.hasOwnProperty.call(FORM_FIELD_ERROR_CODES, code)) continue;
3934
3957
  out.push({ key, code });
3935
3958
  }
3936
3959
  return out;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@behio/storefront-sdk",
3
- "version": "2.7.0",
3
+ "version": "2.9.0",
4
4
  "description": "TypeScript SDK for Behio headless e-commerce: core client + React hooks",
5
5
  "author": "Behio",
6
6
  "license": "MIT",