@behio/storefront-sdk 2.8.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 {
@@ -2542,6 +2547,7 @@ interface PickupPointsInput {
2542
2547
  }
2543
2548
  /** Public terms of the eshop's loyalty program. */
2544
2549
  interface LoyaltyProgram {
2550
+ enrollmentType?: "AUTO_ON_REGISTER" | "OPT_IN" | "INVITE_ONLY";
2545
2551
  name: string;
2546
2552
  pointName: string;
2547
2553
  pointNamePlural: string;
@@ -2556,6 +2562,8 @@ interface LoyaltyProgram {
2556
2562
  }
2557
2563
  interface LoyaltyBalance {
2558
2564
  currentPoints: number;
2565
+ /** Revoked points to offset before new rewards become spendable. Absent on older servers. */
2566
+ pointsDebt?: number;
2559
2567
  /** `currentPoints` valued in the program currency. */
2560
2568
  currentPointsValue: number;
2561
2569
  lifetimePointsEarned: number;
@@ -2587,10 +2595,13 @@ interface LoyaltyNextTier {
2587
2595
  progressPercent: number;
2588
2596
  }
2589
2597
  interface LoyaltyTransaction {
2598
+ /** Stable identifier on servers supporting cursor history. */
2599
+ id?: string;
2590
2600
  type: string;
2591
2601
  /** Positive = earned, negative = redeemed / expired. */
2592
2602
  points: number;
2593
2603
  balanceAfter: number;
2604
+ debtAfter?: number;
2594
2605
  eventType: string | null;
2595
2606
  description: string | null;
2596
2607
  createdAt: number;
@@ -2602,6 +2613,7 @@ interface LoyaltyTransaction {
2602
2613
  * "join and earn" CTA).
2603
2614
  */
2604
2615
  interface LoyaltySummary {
2616
+ canJoin?: boolean;
2605
2617
  hasProgram: boolean;
2606
2618
  enrolled: boolean;
2607
2619
  program: LoyaltyProgram | null;
@@ -2610,6 +2622,18 @@ interface LoyaltySummary {
2610
2622
  nextTier: LoyaltyNextTier | null;
2611
2623
  referralCode: string | null;
2612
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;
2613
2637
  }
2614
2638
  interface CrossSellItem {
2615
2639
  productId: string;
@@ -2938,6 +2962,55 @@ interface CartLinkClaimed extends Cart {
2938
2962
  /** Code carried by the link, including a refused code. Null means no code was offered. */
2939
2963
  linkDiscountCode: string | null;
2940
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
+ }
2941
3014
 
2942
3015
  declare class BehioStorefront {
2943
3016
  private baseUrl;
@@ -3561,7 +3634,17 @@ declare class CustomerModule {
3561
3634
  * value, current tier, next-tier progress, point ratio, referral code,
3562
3635
  * recent transactions). Requires an authenticated customer session.
3563
3636
  */
3564
- 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>>;
3565
3648
  /**
3566
3649
  * Digital product delivery (GAP-07): list the logged-in customer's download
3567
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.8.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",