@schematichq/schematic-components 2.19.0 → 2.21.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.
@@ -2837,7 +2837,10 @@ var Translator = class _Translator extends EventEmitter {
2837
2837
  const useOptionsReplaceForData = options.replace && !isString(options.replace);
2838
2838
  let data = useOptionsReplaceForData ? options.replace : options;
2839
2839
  if (useOptionsReplaceForData && typeof options.count !== "undefined") {
2840
- data.count = options.count;
2840
+ data = {
2841
+ ...data,
2842
+ count: options.count
2843
+ };
2841
2844
  }
2842
2845
  if (this.options.interpolation.defaultVariables) {
2843
2846
  data = {
@@ -3148,10 +3151,10 @@ var Interpolator = class {
3148
3151
  const skipOnVariables = options?.interpolation?.skipOnVariables !== void 0 ? options.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables;
3149
3152
  const todos = [{
3150
3153
  regex: this.regexpUnescape,
3151
- safeValue: (val) => regexSafe(val)
3154
+ safeValue: (val) => val
3152
3155
  }, {
3153
3156
  regex: this.regexp,
3154
- safeValue: (val) => this.escapeValue ? regexSafe(this.escape(val)) : regexSafe(val)
3157
+ safeValue: (val) => this.escapeValue ? this.escape(val) : val
3155
3158
  }];
3156
3159
  todos.forEach((todo) => {
3157
3160
  replaces = 0;
@@ -3175,9 +3178,9 @@ var Interpolator = class {
3175
3178
  value = makeString(value);
3176
3179
  }
3177
3180
  const safeValue = todo.safeValue(value);
3178
- str = str.replace(match2[0], safeValue);
3181
+ str = str.replace(match2[0], regexSafe(safeValue));
3179
3182
  if (skipOnVariables) {
3180
- todo.regex.lastIndex += value.length;
3183
+ todo.regex.lastIndex += safeValue.length;
3181
3184
  todo.regex.lastIndex -= match2[0].length;
3182
3185
  } else {
3183
3186
  todo.regex.lastIndex = 0;
@@ -3227,7 +3230,7 @@ var Interpolator = class {
3227
3230
  clonedOptions = clonedOptions.replace && !isString(clonedOptions.replace) ? clonedOptions.replace : clonedOptions;
3228
3231
  clonedOptions.applyPostProcessor = false;
3229
3232
  delete clonedOptions.defaultValue;
3230
- const keyEndIndex = /{.*}/.test(match2[1]) ? match2[1].lastIndexOf("}") + 1 : match2[1].indexOf(this.formatSeparator);
3233
+ const keyEndIndex = /{.*}/s.test(match2[1]) ? match2[1].lastIndexOf("}") + 1 : match2[1].indexOf(this.formatSeparator);
3231
3234
  if (keyEndIndex !== -1) {
3232
3235
  formatters = match2[1].slice(keyEndIndex).split(this.formatSeparator).map((elem) => elem.trim()).filter(Boolean);
3233
3236
  match2[1] = match2[1].slice(0, keyEndIndex);
@@ -4959,6 +4962,9 @@ var en_default = {
4959
4962
  "After the trial, subscribe": "After the trial, subscription starts and you will be billed.",
4960
4963
  Agreement: "Agreement",
4961
4964
  "Amount off": "{{amount}} off",
4965
+ "Applied balance towards next invoice": "Applied balance towards next invoice",
4966
+ "Discount for months_one": "{{discount}} for next month",
4967
+ "Discount for months_other": "{{discount}} for next {{count}} months",
4962
4968
  "Auto Top-up": "Auto top-up",
4963
4969
  "Auto top-up enabled": "Auto top-up enabled",
4964
4970
  "Auto top-up disabled": "Auto top-up disabled",
@@ -5054,7 +5060,7 @@ var en_default = {
5054
5060
  Proration: "Proration",
5055
5061
  Quantity: "Quantity",
5056
5062
  "Quantity to pay for in advance": "Quantity to pay for in advance",
5057
- "Remaining balance": "Remaining balance",
5063
+ "Remaining balance after next invoice": "Remaining balance after next invoice",
5058
5064
  Remove: "Remove",
5059
5065
  "Remove add-on": "Remove add-on",
5060
5066
  Resets: "Resets {{date}}",
@@ -5129,6 +5135,14 @@ var en_default = {
5129
5135
  "X units per use": "{{amount}} {{units}} per use",
5130
5136
  "X time left in trial": "{{amount}} {{units}} left in trial",
5131
5137
  "Yearly total": "Yearly total",
5138
+ "You will be billed": "You will be billed {{price}} {{usage}}for this subscription every {{period}} {{schedule}}unless you unsubscribe.",
5139
+ "You will be billed with discount window": "You will be billed {{price}} {{usage}}for this subscription every {{period}} {{schedule}}{{window}}, then {{fullPrice}} every {{period}} afterward, unless you unsubscribe.",
5140
+ "You will be billed next bill discount": "You will be billed {{price}} {{usage}}for this subscription on your next bill, then {{fullPrice}} every {{period}} {{schedule}}afterward, unless you unsubscribe.",
5141
+ "plus usage based costs": "plus usage based costs",
5142
+ "on the day": "on the {{day}}",
5143
+ "of month": "of {{month}}",
5144
+ "for the next months_one": "for the next month",
5145
+ "for the next months_other": "for the next {{count}} months",
5132
5146
  "You will be downgraded at the end of your billing period.": "You will be downgraded to the {{plan}} plan at the end of your billing period on {{date}}.",
5133
5147
  "You will retain access to your plan until the end of the billing period, on": "You will retain access to your plan until the end of the billing period, on",
5134
5148
  "$X per unit": "{{cost}} per {{unit}}",
@@ -5816,7 +5830,7 @@ var i;
5816
5830
  var l = "undefined" != typeof process && void 0 !== process.env && (process.env.REACT_APP_SC_ATTR || process.env.SC_ATTR) || "data-styled";
5817
5831
  var c = "active";
5818
5832
  var a = "data-styled-version";
5819
- var u = "6.4.3";
5833
+ var u = "6.4.4";
5820
5834
  var d = "/*!sc*/\n";
5821
5835
  var h = "undefined" != typeof window && "undefined" != typeof document;
5822
5836
  var p = void 0 === t2.createContext;
@@ -7867,11 +7881,13 @@ function InvoiceResponseDataFromJSONTyped(json, ignoreDiscriminator) {
7867
7881
  currency: json["currency"],
7868
7882
  customerExternalId: json["customer_external_id"],
7869
7883
  dueDate: json["due_date"] == null ? void 0 : new Date(json["due_date"]),
7884
+ endingBalance: json["ending_balance"],
7870
7885
  environmentId: json["environment_id"],
7871
7886
  externalId: json["external_id"] == null ? void 0 : json["external_id"],
7872
7887
  id: json["id"],
7873
7888
  paymentMethodExternalId: json["payment_method_external_id"] == null ? void 0 : json["payment_method_external_id"],
7874
7889
  providerType: BillingProviderTypeFromJSON(json["provider_type"]),
7890
+ startingBalance: json["starting_balance"],
7875
7891
  status: json["status"] == null ? void 0 : InvoiceStatusFromJSON(json["status"]),
7876
7892
  subscriptionExternalId: json["subscription_external_id"] == null ? void 0 : json["subscription_external_id"],
7877
7893
  subtotal: json["subtotal"],
@@ -8347,6 +8363,20 @@ function EntitlementValueTypeFromJSONTyped(json, ignoreDiscriminator) {
8347
8363
  return json;
8348
8364
  }
8349
8365
 
8366
+ // src/api/checkoutexternal/models/WarningTier.ts
8367
+ function WarningTierFromJSON(json) {
8368
+ return WarningTierFromJSONTyped(json, false);
8369
+ }
8370
+ function WarningTierFromJSONTyped(json, ignoreDiscriminator) {
8371
+ if (json == null) {
8372
+ return json;
8373
+ }
8374
+ return {
8375
+ key: json["key"],
8376
+ value: json["value"]
8377
+ };
8378
+ }
8379
+
8350
8380
  // src/api/checkoutexternal/models/FeatureEntitlement.ts
8351
8381
  function FeatureEntitlementFromJSON(json) {
8352
8382
  return FeatureEntitlementFromJSONTyped(json, false);
@@ -8373,7 +8403,8 @@ function FeatureEntitlementFromJSONTyped(json, ignoreDiscriminator) {
8373
8403
  monthReset: json["month_reset"] == null ? void 0 : MetricPeriodMonthResetFromJSON(json["month_reset"]),
8374
8404
  softLimit: json["soft_limit"] == null ? void 0 : json["soft_limit"],
8375
8405
  usage: json["usage"] == null ? void 0 : json["usage"],
8376
- valueType: EntitlementValueTypeFromJSON(json["value_type"])
8406
+ valueType: EntitlementValueTypeFromJSON(json["value_type"]),
8407
+ warningTiers: json["warning_tiers"] == null ? void 0 : json["warning_tiers"].map(WarningTierFromJSON)
8377
8408
  };
8378
8409
  }
8379
8410
 
@@ -8720,6 +8751,7 @@ function CompanyOverrideNoteResponseDataFromJSONTyped(json, ignoreDiscriminator)
8720
8751
  var FeatureType = {
8721
8752
  Boolean: "boolean",
8722
8753
  Event: "event",
8754
+ License: "license",
8723
8755
  Trait: "trait"
8724
8756
  };
8725
8757
  function FeatureTypeFromJSON(json) {
@@ -8752,13 +8784,15 @@ function FeatureResponseDataFromJSONTyped(json, ignoreDiscriminator) {
8752
8784
  featureType: FeatureTypeFromJSON(json["feature_type"]),
8753
8785
  icon: json["icon"],
8754
8786
  id: json["id"],
8787
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
8755
8788
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON(json["lifecycle_phase"]),
8756
8789
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
8757
8790
  name: json["name"],
8758
8791
  pluralName: json["plural_name"] == null ? void 0 : json["plural_name"],
8759
8792
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
8760
8793
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
8761
- updatedAt: new Date(json["updated_at"])
8794
+ updatedAt: new Date(json["updated_at"]),
8795
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
8762
8796
  };
8763
8797
  }
8764
8798
 
@@ -9110,6 +9144,7 @@ function FeatureInPlanResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9110
9144
  flags: json["flags"].map(FlagInPlanResponseDataFromJSON),
9111
9145
  icon: json["icon"],
9112
9146
  id: json["id"],
9147
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
9113
9148
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON(json["lifecycle_phase"]),
9114
9149
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
9115
9150
  name: json["name"],
@@ -9118,7 +9153,8 @@ function FeatureInPlanResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9118
9153
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
9119
9154
  trait: json["trait"] == null ? void 0 : EntityTraitDefinitionResponseDataFromJSON(json["trait"]),
9120
9155
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
9121
- updatedAt: new Date(json["updated_at"])
9156
+ updatedAt: new Date(json["updated_at"]),
9157
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
9122
9158
  };
9123
9159
  }
9124
9160
 
@@ -9195,6 +9231,20 @@ function PlanCreditGrantViewFromJSONTyped(json, ignoreDiscriminator) {
9195
9231
  };
9196
9232
  }
9197
9233
 
9234
+ // src/api/checkoutexternal/models/PlanCatalogMembershipResponseData.ts
9235
+ function PlanCatalogMembershipResponseDataFromJSON(json) {
9236
+ return PlanCatalogMembershipResponseDataFromJSONTyped(json, false);
9237
+ }
9238
+ function PlanCatalogMembershipResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9239
+ if (json == null) {
9240
+ return json;
9241
+ }
9242
+ return {
9243
+ id: json["id"],
9244
+ name: json["name"]
9245
+ };
9246
+ }
9247
+
9198
9248
  // src/api/checkoutexternal/models/PlanCurrencyPricesResponseData.ts
9199
9249
  function PlanCurrencyPricesResponseDataFromJSON(json) {
9200
9250
  return PlanCurrencyPricesResponseDataFromJSONTyped(json, false);
@@ -9351,6 +9401,9 @@ function CompanyPlanDetailResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9351
9401
  ),
9352
9402
  billingProduct: json["billing_product"] == null ? void 0 : BillingProductDetailResponseDataFromJSON(json["billing_product"]),
9353
9403
  billingStrategy: BillingStrategyFromJSON(json["billing_strategy"]),
9404
+ catalogs: json["catalogs"] == null ? void 0 : json["catalogs"].map(
9405
+ PlanCatalogMembershipResponseDataFromJSON
9406
+ ),
9354
9407
  chargeType: ChargeTypeFromJSON(json["charge_type"]),
9355
9408
  companyCanTrial: json["company_can_trial"],
9356
9409
  companyCount: json["company_count"],
@@ -9524,6 +9577,9 @@ function PlanDetailResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9524
9577
  ),
9525
9578
  billingProduct: json["billing_product"] == null ? void 0 : BillingProductDetailResponseDataFromJSON(json["billing_product"]),
9526
9579
  billingStrategy: BillingStrategyFromJSON(json["billing_strategy"]),
9580
+ catalogs: json["catalogs"] == null ? void 0 : json["catalogs"].map(
9581
+ PlanCatalogMembershipResponseDataFromJSON
9582
+ ),
9527
9583
  chargeType: ChargeTypeFromJSON(json["charge_type"]),
9528
9584
  companyCount: json["company_count"],
9529
9585
  companyId: json["company_id"] == null ? void 0 : json["company_id"],
@@ -9693,6 +9749,7 @@ function ComponentResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9693
9749
  }
9694
9750
  return {
9695
9751
  ast: json["ast"] == null ? void 0 : json["ast"],
9752
+ catalogId: json["catalog_id"] == null ? void 0 : json["catalog_id"],
9696
9753
  createdAt: new Date(json["created_at"]),
9697
9754
  id: json["id"],
9698
9755
  name: json["name"],
@@ -9929,6 +9986,29 @@ function PreviewSubscriptionUpcomingInvoiceLineItemsFromJSONTyped(json, ignoreDi
9929
9986
  };
9930
9987
  }
9931
9988
 
9989
+ // src/api/checkoutexternal/models/PreviewSubscriptionDiscountResponseData.ts
9990
+ function PreviewSubscriptionDiscountResponseDataFromJSON(json) {
9991
+ return PreviewSubscriptionDiscountResponseDataFromJSONTyped(json, false);
9992
+ }
9993
+ function PreviewSubscriptionDiscountResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9994
+ if (json == null) {
9995
+ return json;
9996
+ }
9997
+ return {
9998
+ amountOff: json["amount_off"] == null ? void 0 : json["amount_off"],
9999
+ couponName: json["coupon_name"],
10000
+ currency: json["currency"] == null ? void 0 : json["currency"],
10001
+ customerFacingCode: json["customer_facing_code"] == null ? void 0 : json["customer_facing_code"],
10002
+ duration: json["duration"],
10003
+ durationInMonths: json["duration_in_months"] == null ? void 0 : json["duration_in_months"],
10004
+ endedAt: json["ended_at"] == null ? void 0 : new Date(json["ended_at"]),
10005
+ isActive: json["is_active"],
10006
+ percentOff: json["percent_off"] == null ? void 0 : json["percent_off"],
10007
+ promoCodeExternalId: json["promo_code_external_id"] == null ? void 0 : json["promo_code_external_id"],
10008
+ startedAt: new Date(json["started_at"])
10009
+ };
10010
+ }
10011
+
9932
10012
  // src/api/checkoutexternal/models/PreviewSubscriptionFinanceResponseData.ts
9933
10013
  function PreviewSubscriptionFinanceResponseDataFromJSON(json) {
9934
10014
  return PreviewSubscriptionFinanceResponseDataFromJSONTyped(json, false);
@@ -9939,9 +10019,13 @@ function PreviewSubscriptionFinanceResponseDataFromJSONTyped(json, ignoreDiscrim
9939
10019
  }
9940
10020
  return {
9941
10021
  amountOff: json["amount_off"],
10022
+ discounts: json["discounts"].map(
10023
+ PreviewSubscriptionDiscountResponseDataFromJSON
10024
+ ),
9942
10025
  dueNow: json["due_now"],
9943
10026
  newCharges: json["new_charges"],
9944
10027
  percentOff: json["percent_off"],
10028
+ periodEnd: new Date(json["period_end"]),
9945
10029
  periodStart: new Date(json["period_start"]),
9946
10030
  promoCodeApplied: json["promo_code_applied"],
9947
10031
  proration: json["proration"],
@@ -11555,13 +11639,15 @@ function FeatureResponseDataFromJSONTyped5(json, ignoreDiscriminator) {
11555
11639
  featureType: FeatureTypeFromJSON2(json["feature_type"]),
11556
11640
  icon: json["icon"],
11557
11641
  id: json["id"],
11642
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
11558
11643
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON2(json["lifecycle_phase"]),
11559
11644
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
11560
11645
  name: json["name"],
11561
11646
  pluralName: json["plural_name"] == null ? void 0 : json["plural_name"],
11562
11647
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
11563
11648
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
11564
- updatedAt: new Date(json["updated_at"])
11649
+ updatedAt: new Date(json["updated_at"]),
11650
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
11565
11651
  };
11566
11652
  }
11567
11653
 
@@ -11618,6 +11704,7 @@ function FeatureInPlanResponseDataFromJSONTyped6(json, ignoreDiscriminator) {
11618
11704
  flags: json["flags"].map(FlagInPlanResponseDataFromJSON2),
11619
11705
  icon: json["icon"],
11620
11706
  id: json["id"],
11707
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
11621
11708
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON2(json["lifecycle_phase"]),
11622
11709
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
11623
11710
  name: json["name"],
@@ -11626,7 +11713,8 @@ function FeatureInPlanResponseDataFromJSONTyped6(json, ignoreDiscriminator) {
11626
11713
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
11627
11714
  trait: json["trait"] == null ? void 0 : EntityTraitDefinitionResponseDataFromJSON2(json["trait"]),
11628
11715
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
11629
- updatedAt: new Date(json["updated_at"])
11716
+ updatedAt: new Date(json["updated_at"]),
11717
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
11630
11718
  };
11631
11719
  }
11632
11720
 
@@ -11805,6 +11893,20 @@ function PlanCreditGrantViewFromJSONTyped3(json, ignoreDiscriminator) {
11805
11893
  };
11806
11894
  }
11807
11895
 
11896
+ // src/api/componentspublic/models/PlanCatalogMembershipResponseData.ts
11897
+ function PlanCatalogMembershipResponseDataFromJSON2(json) {
11898
+ return PlanCatalogMembershipResponseDataFromJSONTyped5(json, false);
11899
+ }
11900
+ function PlanCatalogMembershipResponseDataFromJSONTyped5(json, ignoreDiscriminator) {
11901
+ if (json == null) {
11902
+ return json;
11903
+ }
11904
+ return {
11905
+ id: json["id"],
11906
+ name: json["name"]
11907
+ };
11908
+ }
11909
+
11808
11910
  // src/api/componentspublic/models/PlanCurrencyPricesResponseData.ts
11809
11911
  function PlanCurrencyPricesResponseDataFromJSON2(json) {
11810
11912
  return PlanCurrencyPricesResponseDataFromJSONTyped5(json, false);
@@ -11872,6 +11974,9 @@ function PlanViewPublicResponseDataFromJSONTyped(json, ignoreDiscriminator) {
11872
11974
  ),
11873
11975
  billingProduct: json["billing_product"] == null ? void 0 : BillingProductDetailResponseDataFromJSON2(json["billing_product"]),
11874
11976
  billingStrategy: BillingStrategyFromJSON2(json["billing_strategy"]),
11977
+ catalogs: json["catalogs"] == null ? void 0 : json["catalogs"].map(
11978
+ PlanCatalogMembershipResponseDataFromJSON2
11979
+ ),
11875
11980
  chargeType: ChargeTypeFromJSON2(json["charge_type"]),
11876
11981
  companyCount: json["company_count"],
11877
11982
  companyId: json["company_id"] == null ? void 0 : json["company_id"],
@@ -12489,7 +12594,7 @@ function getMetricPeriodName(entitlement) {
12489
12594
  const name = period ? PeriodName[period] : void 0;
12490
12595
  return name;
12491
12596
  }
12492
- function getUsageDetails(entitlement, period, currency) {
12597
+ function getUsageDetails(entitlement, period, currency, options) {
12493
12598
  const billingPrice = currency ? getEntitlementPrice(entitlement, period ?? "month", currency) : period === "year" ? entitlement.yearlyUsageBasedPrice : period === "quarter" ? entitlement.quarterlyUsageBasedPrice : period === "month" ? entitlement.monthlyUsageBasedPrice : void 0;
12494
12599
  let limit;
12495
12600
  if ((!entitlement.priceBehavior || entitlement.priceBehavior === EntitlementPriceBehavior.PayInAdvance) && typeof entitlement.allocation === "number") {
@@ -12537,8 +12642,21 @@ function getUsageDetails(entitlement, period, currency) {
12537
12642
  start = end + 1;
12538
12643
  }
12539
12644
  }
12645
+ if (options?.showWarningThresholdAsLimit) {
12646
+ const warningThreshold = getEntitlementWarningThreshold(
12647
+ entitlement.planEntitlement?.warningTiers
12648
+ );
12649
+ if (typeof warningThreshold === "number") {
12650
+ limit = warningThreshold;
12651
+ }
12652
+ }
12540
12653
  return { billingPrice, limit, amount, cost, currentTier };
12541
12654
  }
12655
+ var WARNING_TIER_DEFAULT_KEY = "default";
12656
+ function getEntitlementWarningThreshold(warningTiers) {
12657
+ const tier = warningTiers?.find((t3) => t3?.key === WARNING_TIER_DEFAULT_KEY);
12658
+ return typeof tier?.value === "number" ? tier.value : void 0;
12659
+ }
12542
12660
  function getCreditBasedEntitlementLimit(entitlement, credits) {
12543
12661
  const matchedCredit = credits.find(
12544
12662
  (credit) => credit.id === entitlement.valueCredit?.id
@@ -13086,85 +13204,6 @@ function modifyDate(date, days) {
13086
13204
  return copy3;
13087
13205
  }
13088
13206
 
13089
- // src/utils/error.ts
13090
- function isError(value) {
13091
- return value instanceof Error;
13092
- }
13093
- var ERROR_UNKNOWN = new Error("An unknown error occurred.");
13094
-
13095
- // src/utils/event.ts
13096
- var createKeyboardExecutionHandler = (fn) => {
13097
- const handler = (event) => {
13098
- if (event.key === "Enter" || event.key === " ") {
13099
- event.preventDefault();
13100
- fn?.(event);
13101
- }
13102
- };
13103
- return handler;
13104
- };
13105
-
13106
- // src/utils/markdown.tsx
13107
- import { Fragment as Fragment2 } from "react";
13108
- import { jsx } from "react/jsx-runtime";
13109
- var TOKEN = /(\[[^\]]+\]\([^)\s]+\))|(\*\*[^*]+\*\*)|(\*[^*]+\*)/g;
13110
- var LINK = /^\[([^\]]+)\]\(([^)\s]+)\)$/;
13111
- var isSafeUrl = (url) => {
13112
- try {
13113
- const { protocol } = new URL(url);
13114
- return protocol === "http:" || protocol === "https:";
13115
- } catch {
13116
- return false;
13117
- }
13118
- };
13119
- var renderOptInMarkdown = (text) => {
13120
- if (!text) {
13121
- return null;
13122
- }
13123
- const nodes = [];
13124
- let lastIndex = 0;
13125
- let key = 0;
13126
- TOKEN.lastIndex = 0;
13127
- let match2;
13128
- while ((match2 = TOKEN.exec(text)) !== null) {
13129
- if (match2.index > lastIndex) {
13130
- nodes.push(
13131
- /* @__PURE__ */ jsx(Fragment2, { children: text.slice(lastIndex, match2.index) }, key++)
13132
- );
13133
- }
13134
- const [token2, link, bold, italic] = match2;
13135
- if (link) {
13136
- const parts = LINK.exec(link);
13137
- if (parts && isSafeUrl(parts[2])) {
13138
- nodes.push(
13139
- /* @__PURE__ */ jsx(
13140
- Text,
13141
- {
13142
- as: "a",
13143
- display: "link",
13144
- href: parts[2],
13145
- target: "_blank",
13146
- rel: "noopener noreferrer",
13147
- children: parts[1]
13148
- },
13149
- key++
13150
- )
13151
- );
13152
- } else {
13153
- nodes.push(/* @__PURE__ */ jsx(Fragment2, { children: parts ? parts[1] : token2 }, key++));
13154
- }
13155
- } else if (bold) {
13156
- nodes.push(/* @__PURE__ */ jsx("strong", { children: bold.slice(2, -2) }, key++));
13157
- } else if (italic) {
13158
- nodes.push(/* @__PURE__ */ jsx("em", { children: italic.slice(1, -1) }, key++));
13159
- }
13160
- lastIndex = match2.index + token2.length;
13161
- }
13162
- if (lastIndex < text.length) {
13163
- nodes.push(/* @__PURE__ */ jsx(Fragment2, { children: text.slice(lastIndex) }, key));
13164
- }
13165
- return nodes;
13166
- };
13167
-
13168
13207
  // src/utils/string.ts
13169
13208
  var ZERO_DECIMAL_CURRENCIES = /* @__PURE__ */ new Set([
13170
13209
  "BIF",
@@ -13313,6 +13352,168 @@ function getCurrencySymbol(currency) {
13313
13352
  }
13314
13353
  }
13315
13354
 
13355
+ // src/utils/discount.ts
13356
+ function getSubscriptionDiscount(discounts, subscriptionTotal, subscriptionCurrency) {
13357
+ const activeDiscounts = (discounts || []).filter(
13358
+ (discount2) => discount2.isActive && (typeof discount2.percentOff === "number" && discount2.percentOff > 0 || typeof discount2.amountOff === "number" && discount2.amountOff > 0)
13359
+ );
13360
+ if (activeDiscounts.length !== 1) {
13361
+ return void 0;
13362
+ }
13363
+ const discount = activeDiscounts[0];
13364
+ const isPercentOff = typeof discount.percentOff === "number" && discount.percentOff > 0;
13365
+ if (!isPercentOff && discount.currency && subscriptionCurrency && discount.currency.toLowerCase() !== subscriptionCurrency.toLowerCase()) {
13366
+ return void 0;
13367
+ }
13368
+ const discountedTotal = isPercentOff ? subscriptionTotal * (1 - discount.percentOff / 100) : Math.max(0, subscriptionTotal - (discount.amountOff ?? 0));
13369
+ if (discountedTotal >= subscriptionTotal) {
13370
+ return void 0;
13371
+ }
13372
+ return {
13373
+ duration: discount.duration,
13374
+ durationInMonths: discount.durationInMonths ?? void 0,
13375
+ discountedPrice: formatCurrency(
13376
+ discountedTotal,
13377
+ subscriptionCurrency ?? void 0
13378
+ )
13379
+ };
13380
+ }
13381
+ function getBillingPreviewText({
13382
+ subscriptionPrice,
13383
+ planPeriod,
13384
+ periodStart,
13385
+ hasUsageBasedCosts,
13386
+ discount
13387
+ }, t3) {
13388
+ if (!subscriptionPrice) {
13389
+ return null;
13390
+ }
13391
+ const usage = hasUsageBasedCosts ? `${t3("plus usage based costs")} ` : "";
13392
+ const scheduleParts = [];
13393
+ if (periodStart) {
13394
+ scheduleParts.push(
13395
+ t3("on the day", { day: formatOrdinal(periodStart.getDate()) })
13396
+ );
13397
+ }
13398
+ if (planPeriod === "year" && periodStart) {
13399
+ scheduleParts.push(t3("of month", { month: getMonthName(periodStart) }));
13400
+ }
13401
+ const schedule = scheduleParts.length > 0 ? `${scheduleParts.join(" ")} ` : "";
13402
+ if (!discount) {
13403
+ return t3("You will be billed", {
13404
+ price: subscriptionPrice,
13405
+ usage,
13406
+ period: planPeriod,
13407
+ schedule
13408
+ });
13409
+ }
13410
+ const { duration, durationInMonths, discountedPrice } = discount;
13411
+ if (duration === "forever") {
13412
+ return t3("You will be billed", {
13413
+ price: discountedPrice,
13414
+ usage,
13415
+ period: planPeriod,
13416
+ schedule
13417
+ });
13418
+ }
13419
+ if (duration === "repeating" && durationInMonths) {
13420
+ return t3("You will be billed with discount window", {
13421
+ price: discountedPrice,
13422
+ usage,
13423
+ period: planPeriod,
13424
+ schedule,
13425
+ window: t3("for the next months", { count: durationInMonths }),
13426
+ fullPrice: subscriptionPrice
13427
+ });
13428
+ }
13429
+ return t3("You will be billed next bill discount", {
13430
+ price: discountedPrice,
13431
+ usage,
13432
+ period: planPeriod,
13433
+ schedule,
13434
+ fullPrice: subscriptionPrice
13435
+ });
13436
+ }
13437
+
13438
+ // src/utils/error.ts
13439
+ function isError(value) {
13440
+ return value instanceof Error;
13441
+ }
13442
+ var ERROR_UNKNOWN = new Error("An unknown error occurred.");
13443
+
13444
+ // src/utils/event.ts
13445
+ var createKeyboardExecutionHandler = (fn) => {
13446
+ const handler = (event) => {
13447
+ if (event.key === "Enter" || event.key === " ") {
13448
+ event.preventDefault();
13449
+ fn?.(event);
13450
+ }
13451
+ };
13452
+ return handler;
13453
+ };
13454
+
13455
+ // src/utils/markdown.tsx
13456
+ import { Fragment as Fragment2 } from "react";
13457
+ import { jsx } from "react/jsx-runtime";
13458
+ var TOKEN = /(\[[^\]]+\]\([^)\s]+\))|(\*\*[^*]+\*\*)|(\*[^*]+\*)/g;
13459
+ var LINK = /^\[([^\]]+)\]\(([^)\s]+)\)$/;
13460
+ var isSafeUrl = (url) => {
13461
+ try {
13462
+ const { protocol } = new URL(url);
13463
+ return protocol === "http:" || protocol === "https:";
13464
+ } catch {
13465
+ return false;
13466
+ }
13467
+ };
13468
+ var renderOptInMarkdown = (text) => {
13469
+ if (!text) {
13470
+ return null;
13471
+ }
13472
+ const nodes = [];
13473
+ let lastIndex = 0;
13474
+ let key = 0;
13475
+ TOKEN.lastIndex = 0;
13476
+ let match2;
13477
+ while ((match2 = TOKEN.exec(text)) !== null) {
13478
+ if (match2.index > lastIndex) {
13479
+ nodes.push(
13480
+ /* @__PURE__ */ jsx(Fragment2, { children: text.slice(lastIndex, match2.index) }, key++)
13481
+ );
13482
+ }
13483
+ const [token2, link, bold, italic] = match2;
13484
+ if (link) {
13485
+ const parts = LINK.exec(link);
13486
+ if (parts && isSafeUrl(parts[2])) {
13487
+ nodes.push(
13488
+ /* @__PURE__ */ jsx(
13489
+ Text,
13490
+ {
13491
+ as: "a",
13492
+ display: "link",
13493
+ href: parts[2],
13494
+ target: "_blank",
13495
+ rel: "noopener noreferrer",
13496
+ children: parts[1]
13497
+ },
13498
+ key++
13499
+ )
13500
+ );
13501
+ } else {
13502
+ nodes.push(/* @__PURE__ */ jsx(Fragment2, { children: parts ? parts[1] : token2 }, key++));
13503
+ }
13504
+ } else if (bold) {
13505
+ nodes.push(/* @__PURE__ */ jsx("strong", { children: bold.slice(2, -2) }, key++));
13506
+ } else if (italic) {
13507
+ nodes.push(/* @__PURE__ */ jsx("em", { children: italic.slice(1, -1) }, key++));
13508
+ }
13509
+ lastIndex = match2.index + token2.length;
13510
+ }
13511
+ if (lastIndex < text.length) {
13512
+ nodes.push(/* @__PURE__ */ jsx(Fragment2, { children: text.slice(lastIndex) }, key));
13513
+ }
13514
+ return nodes;
13515
+ };
13516
+
13316
13517
  // src/utils/style.ts
13317
13518
  function attr(key, value) {
13318
13519
  if (typeof value !== "undefined") {
@@ -13568,7 +13769,7 @@ var reducer = (state, action) => {
13568
13769
  // src/context/EmbedProvider.tsx
13569
13770
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
13570
13771
  var getCustomHeaders = (sessionId) => ({
13571
- "X-Schematic-Components-Version": "2.19.0",
13772
+ "X-Schematic-Components-Version": "2.21.0",
13572
13773
  "X-Schematic-Session-ID": sessionId
13573
13774
  });
13574
13775
  var normalizeCurrencyFilter = (filter2) => {
@@ -13592,6 +13793,7 @@ var EmbedProvider = ({
13592
13793
  apiKey,
13593
13794
  apiConfig,
13594
13795
  currencyFilter,
13796
+ warningThresholdConfig,
13595
13797
  checkoutPrefill,
13596
13798
  ...options
13597
13799
  }) => {
@@ -13607,6 +13809,7 @@ var EmbedProvider = ({
13607
13809
  const providedState = {
13608
13810
  settings: opts.settings || {},
13609
13811
  currencyFilter: normalizeCurrencyFilter(currencyFilter),
13812
+ warningThresholdConfig,
13610
13813
  checkoutPrefill: normalizeCheckoutPrefill(checkoutPrefill)
13611
13814
  };
13612
13815
  const resolvedState = (0, import_merge2.default)({}, initialState, providedState);
@@ -14035,6 +14238,7 @@ var EmbedProvider = ({
14035
14238
  layout: state.layout,
14036
14239
  checkoutState: state.checkoutState,
14037
14240
  currencyFilter: state.currencyFilter,
14241
+ warningThresholdConfig: state.warningThresholdConfig,
14038
14242
  checkoutPrefill: state.checkoutPrefill,
14039
14243
  hydratePublic: debouncedHydratePublic,
14040
14244
  hydrate: debouncedHydrate,
@@ -15983,7 +16187,8 @@ var Entitlement = ({
15983
16187
  currency: selectedCurrency
15984
16188
  }) => {
15985
16189
  const { t: t3 } = useTranslation();
15986
- const { data, settings } = useEmbed();
16190
+ const { data, settings, warningThresholdConfig } = useEmbed();
16191
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
15987
16192
  const isLightBackground = useIsLightBackground();
15988
16193
  const showCredits = data?.displaySettings?.showCredits ?? true;
15989
16194
  const showFeatureDescription = data?.displaySettings?.showFeatureDescription ?? false;
@@ -16007,7 +16212,8 @@ var Entitlement = ({
16007
16212
  return;
16008
16213
  }
16009
16214
  const hasNumericValue = entitlement.valueType === EntitlementValueType.Numeric || entitlement.valueType === EntitlementValueType.Unlimited || entitlement.valueType === EntitlementValueType.Trait;
16010
- const limit = entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
16215
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
16216
+ const limit = typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
16011
16217
  const creditBasedEntitlementLimit = getCreditBasedEntitlementLimit(
16012
16218
  entitlement,
16013
16219
  credits
@@ -16100,7 +16306,8 @@ var Entitlement = ({
16100
16306
  currency,
16101
16307
  packageSize,
16102
16308
  tiered,
16103
- selectedCurrency
16309
+ selectedCurrency,
16310
+ showWarningThresholdAsLimit
16104
16311
  ]);
16105
16312
  const usageText = useMemo10(() => {
16106
16313
  if (!entitlement.feature) {
@@ -16831,7 +17038,8 @@ var AddOns = ({
16831
17038
  currency
16832
17039
  }) => {
16833
17040
  const { t: t3 } = useTranslation();
16834
- const { settings } = useEmbed();
17041
+ const { settings, warningThresholdConfig } = useEmbed();
17042
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
16835
17043
  const isLightBackground = useIsLightBackground();
16836
17044
  const periodKey = period === "year" ? "yearlyPrice" : period === "quarter" ? "quarterlyPrice" : "monthlyPrice";
16837
17045
  const cardPadding = settings.theme.card.padding / TEXT_BASE_SIZE;
@@ -16863,10 +17071,14 @@ var AddOns = ({
16863
17071
  period,
16864
17072
  currency
16865
17073
  );
17074
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
16866
17075
  return {
16867
17076
  isUnlimited: false,
16868
17077
  priceBehavior: entitlement.priceBehavior,
16869
17078
  softLimit: entitlement.softLimit,
17079
+ // The limit shown next to the feature: the warning threshold when
17080
+ // the option is on and one is configured, else the overage soft limit.
17081
+ limit: typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage ? entitlement.softLimit : void 0,
16870
17082
  price: priceData?.price ?? 0,
16871
17083
  currency: priceData?.currency || addOnCurrency,
16872
17084
  featureName: entitlement.feature?.name,
@@ -17015,7 +17227,7 @@ var AddOns = ({
17015
17227
  {
17016
17228
  $flexDirection: "column",
17017
17229
  $justifyContent: "center",
17018
- children: /* @__PURE__ */ jsx21(Text, { children: meteredEntitlement.priceBehavior === EntitlementPriceBehavior.Overage && meteredEntitlement.softLimit ? `${meteredEntitlement.softLimit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) })
17230
+ children: /* @__PURE__ */ jsx21(Text, { children: typeof meteredEntitlement.limit === "number" ? `${meteredEntitlement.limit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) })
17019
17231
  }
17020
17232
  )
17021
17233
  ] }),
@@ -20319,7 +20531,7 @@ var SubscriptionSidebar = forwardRef7(
20319
20531
  );
20320
20532
  return { payAsYouGoEntitlements, payInAdvanceEntitlements: payInAdvanceEntitlements2 };
20321
20533
  }, [usageBasedEntitlements]);
20322
- const subscriptionPrice = useMemo18(() => {
20534
+ const { subscriptionPrice, subscriptionTotal, subscriptionCurrency } = useMemo18(() => {
20323
20535
  let planPrice;
20324
20536
  let resolvedCurrency;
20325
20537
  if (selectedPlan) {
@@ -20355,7 +20567,11 @@ var SubscriptionSidebar = forwardRef7(
20355
20567
  0
20356
20568
  );
20357
20569
  total += addOnPayInAdvanceCost;
20358
- return formatCurrency(total, resolvedCurrency);
20570
+ return {
20571
+ subscriptionPrice: formatCurrency(total, resolvedCurrency),
20572
+ subscriptionTotal: total,
20573
+ subscriptionCurrency: resolvedCurrency
20574
+ };
20359
20575
  }, [
20360
20576
  selectedPlan,
20361
20577
  currentPlan,
@@ -20370,6 +20586,7 @@ var SubscriptionSidebar = forwardRef7(
20370
20586
  dueNow,
20371
20587
  newCharges,
20372
20588
  percentOff,
20589
+ periodEnd,
20373
20590
  periodStart,
20374
20591
  proration,
20375
20592
  taxAmount,
@@ -20380,12 +20597,14 @@ var SubscriptionSidebar = forwardRef7(
20380
20597
  dueNow: charges?.dueNow ?? 0,
20381
20598
  newCharges: charges?.newCharges ?? 0,
20382
20599
  percentOff: charges?.percentOff ?? 0,
20600
+ periodEnd: charges?.periodEnd,
20383
20601
  periodStart: charges?.periodStart,
20384
20602
  proration: charges?.proration ?? 0,
20385
20603
  taxAmount: charges?.taxAmount ?? 0,
20386
20604
  taxDescription: charges?.taxDisplayName
20387
20605
  };
20388
20606
  }, [charges]);
20607
+ const renewDate = periodEnd && !Number.isNaN(periodEnd.getTime()) ? periodEnd : periodStart;
20389
20608
  const updatedUsageBasedEntitlements = useMemo18(() => {
20390
20609
  const changedUsageBasedEntitlements = [];
20391
20610
  const allSelectedUsageBasedEntitlements = [
@@ -20479,6 +20698,14 @@ var SubscriptionSidebar = forwardRef7(
20479
20698
  () => promoCode && (amountOff > 0 || percentOff > 0),
20480
20699
  [promoCode, amountOff, percentOff]
20481
20700
  );
20701
+ const subscriptionDiscount = useMemo18(
20702
+ () => getSubscriptionDiscount(
20703
+ charges?.discounts,
20704
+ subscriptionTotal,
20705
+ subscriptionCurrency
20706
+ ),
20707
+ [charges?.discounts, subscriptionTotal, subscriptionCurrency]
20708
+ );
20482
20709
  const handleCheckout = useCallback10(async () => {
20483
20710
  const planId = selectedPlan?.id;
20484
20711
  const currencyPrice = selectedPlan ? getPlanPrice(
@@ -20725,6 +20952,16 @@ var SubscriptionSidebar = forwardRef7(
20725
20952
  if (isSelectedPlanTrialable && selectedPlan.trialDays) {
20726
20953
  trialEndsOn.setDate(trialEndsOn.getDate() + selectedPlan.trialDays);
20727
20954
  }
20955
+ const billingPreviewText = getBillingPreviewText(
20956
+ {
20957
+ subscriptionPrice,
20958
+ planPeriod,
20959
+ periodStart: renewDate,
20960
+ hasUsageBasedCosts: usageBasedEntitlements.length > 0,
20961
+ discount: subscriptionDiscount
20962
+ },
20963
+ t3
20964
+ );
20728
20965
  return /* @__PURE__ */ jsxs29(
20729
20966
  Flex,
20730
20967
  {
@@ -21273,9 +21510,7 @@ var SubscriptionSidebar = forwardRef7(
21273
21510
  }
21274
21511
  )
21275
21512
  }
21276
- ) : subscriptionPrice && // TODO: localize
21277
- `You will be billed ${subscriptionPrice} ${usageBasedEntitlements.length > 0 ? "plus usage based costs" : ""} for this subscription
21278
- every ${planPeriod} ${periodStart ? `on the ${formatOrdinal(periodStart.getDate())}` : ""} ${planPeriod === "year" && periodStart ? `of ${getMonthName(periodStart)}` : ""} unless you unsubscribe.` }) })
21513
+ ) : billingPreviewText }) })
21279
21514
  ]
21280
21515
  }
21281
21516
  )
@@ -21795,7 +22030,8 @@ var UsageDetails = ({ entitlement, layout }) => {
21795
22030
  metricResetAt
21796
22031
  } = entitlement;
21797
22032
  const { t: t3 } = useTranslation();
21798
- const { data } = useEmbed();
22033
+ const { data, warningThresholdConfig } = useEmbed();
22034
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
21799
22035
  const period = getSubscriptionPeriod(data?.company?.billingSubscription) ?? data?.company?.plan?.planPeriod ?? void 0;
21800
22036
  const showCredits = data?.displaySettings?.showCredits ?? true;
21801
22037
  const {
@@ -21811,7 +22047,9 @@ var UsageDetails = ({ entitlement, layout }) => {
21811
22047
  } = useMemo21(() => {
21812
22048
  const { billingPrice, amount, limit: limit2, cost: cost2, currentTier: currentTier2 } = getUsageDetails(
21813
22049
  entitlement,
21814
- period
22050
+ period,
22051
+ void 0,
22052
+ { showWarningThresholdAsLimit }
21815
22053
  );
21816
22054
  const {
21817
22055
  price: price2,
@@ -21832,7 +22070,7 @@ var UsageDetails = ({ entitlement, layout }) => {
21832
22070
  tiersMode: tiersMode2,
21833
22071
  tiered: priceBehavior === EntitlementPriceBehavior.PayInAdvance && isTieredPrice(billingPrice)
21834
22072
  };
21835
- }, [entitlement, period, priceBehavior]);
22073
+ }, [entitlement, period, priceBehavior, showWarningThresholdAsLimit]);
21836
22074
  const text = useMemo21(() => {
21837
22075
  if (!feature || feature.featureType !== FeatureType.Event && feature.featureType !== FeatureType.Trait) {
21838
22076
  return;
@@ -21882,9 +22120,10 @@ var UsageDetails = ({ entitlement, layout }) => {
21882
22120
  });
21883
22121
  }
21884
22122
  if (!priceBehavior && typeof allocation === "number") {
22123
+ const numericLimit = limit ?? allocation;
21885
22124
  return t3("X units", {
21886
- amount: formatNumber(allocation),
21887
- units: getFeatureName(feature, allocation)
22125
+ amount: formatNumber(numericLimit),
22126
+ units: getFeatureName(feature, numericLimit)
21888
22127
  });
21889
22128
  }
21890
22129
  if (!priceBehavior && allocationType === "unlimited") {
@@ -21970,7 +22209,7 @@ var UsageDetails = ({ entitlement, layout }) => {
21970
22209
  if (typeof usage === "number") {
21971
22210
  return typeof allocation === "number" ? t3("usage.limited", {
21972
22211
  amount: formatNumber(usage),
21973
- allocation: formatNumber(allocation)
22212
+ allocation: formatNumber(limit ?? allocation)
21974
22213
  }) : t3("usage.unlimited", {
21975
22214
  amount: formatNumber(usage)
21976
22215
  });
@@ -21984,6 +22223,7 @@ var UsageDetails = ({ entitlement, layout }) => {
21984
22223
  priceBehavior,
21985
22224
  packageSize,
21986
22225
  allocation,
22226
+ limit,
21987
22227
  usage,
21988
22228
  metricResetAt,
21989
22229
  cost,
@@ -22415,7 +22655,12 @@ import { forwardRef as forwardRef12, useCallback as useCallback13, useMemo as us
22415
22655
  import { jsx as jsx50 } from "react/jsx-runtime";
22416
22656
  var Meter = ({ entitlement }) => {
22417
22657
  const { allocation, priceBehavior, softLimit, usage } = entitlement;
22418
- const limit = softLimit ?? allocation;
22658
+ const { warningThresholdConfig } = useEmbed();
22659
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
22660
+ const warningThreshold = getEntitlementWarningThreshold(
22661
+ entitlement.planEntitlement?.warningTiers
22662
+ );
22663
+ const limit = showWarningThresholdAsLimit && typeof warningThreshold === "number" ? warningThreshold : softLimit ?? allocation;
22419
22664
  if (typeof usage !== "number" || typeof limit !== "number") {
22420
22665
  return null;
22421
22666
  }
@@ -22554,14 +22799,7 @@ import { Fragment as Fragment22, jsx as jsx52, jsxs as jsxs38 } from "react/jsx-
22554
22799
  var Limit = ({ entitlement, usageDetails, fontStyle }) => {
22555
22800
  const { t: t3 } = useTranslation();
22556
22801
  const { data } = useEmbed();
22557
- const {
22558
- feature,
22559
- planEntitlement,
22560
- priceBehavior,
22561
- allocation,
22562
- usage,
22563
- metricResetAt
22564
- } = entitlement;
22802
+ const { feature, planEntitlement, priceBehavior, usage, metricResetAt } = entitlement;
22565
22803
  const { billingPrice, limit, cost, currentTier } = usageDetails;
22566
22804
  const acc = [];
22567
22805
  acc.push(
@@ -22583,8 +22821,8 @@ var Limit = ({ entitlement, usageDetails, fontStyle }) => {
22583
22821
  }) : priceBehavior === EntitlementPriceBehavior.CreditBurndown && typeof feature !== "undefined" && typeof limit === "number" ? t3("X units remaining", {
22584
22822
  amount: formatNumber(limit),
22585
22823
  units: getFeatureName(feature, limit)
22586
- }) : typeof allocation === "number" ? t3("Limit of", {
22587
- amount: formatNumber(allocation)
22824
+ }) : typeof limit === "number" ? t3("Limit of", {
22825
+ amount: formatNumber(limit)
22588
22826
  }) : t3("No limit")
22589
22827
  );
22590
22828
  if (metricResetAt) {
@@ -22639,7 +22877,8 @@ var MeteredFeatures = forwardRef12(({ className, ...rest }, ref) => {
22639
22877
  const elementsRef = useRef12([]);
22640
22878
  const shouldWrapChildren = useWrapChildren(elementsRef);
22641
22879
  const { t: t3 } = useTranslation();
22642
- const { data, settings, setCheckoutState } = useEmbed();
22880
+ const { data, settings, setCheckoutState, warningThresholdConfig } = useEmbed();
22881
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
22643
22882
  const isLightBackground = useIsLightBackground();
22644
22883
  const meteredFeatures = useMemo23(() => {
22645
22884
  const orderedFeatureUsage = props.visibleFeatures?.reduce(
@@ -22693,7 +22932,9 @@ var MeteredFeatures = forwardRef12(({ className, ...rest }, ref) => {
22693
22932
  return acc;
22694
22933
  }
22695
22934
  const { feature, priceBehavior, usage } = entitlement;
22696
- const usageDetails = getUsageDetails(entitlement, period);
22935
+ const usageDetails = getUsageDetails(entitlement, period, void 0, {
22936
+ showWarningThresholdAsLimit
22937
+ });
22697
22938
  const { limit } = usageDetails;
22698
22939
  acc.push(
22699
22940
  /* @__PURE__ */ jsxs38(Element, { as: Flex, $flexDirection: "column", $gap: "1.5rem", children: [
@@ -23311,7 +23552,7 @@ var registerWrapper = function registerWrapper2(stripe, startTime) {
23311
23552
  }
23312
23553
  stripe._registerWrapper({
23313
23554
  name: "stripe-js",
23314
- version: "9.9.0",
23555
+ version: "9.12.0",
23315
23556
  startTime
23316
23557
  });
23317
23558
  };
@@ -23389,7 +23630,7 @@ var initStripe = function initStripe2(maybeStripe, args, startTime) {
23389
23630
  var version = runtimeVersionToUrlVersion(maybeStripe.version);
23390
23631
  var expectedVersion = RELEASE_TRAIN;
23391
23632
  if (isTestKey && version !== expectedVersion) {
23392
- console.warn("Stripe.js@".concat(version, " was loaded on the page, but @stripe/stripe-js@").concat("9.9.0", " expected Stripe.js@").concat(expectedVersion, ". This may result in unexpected behavior. For more information, see https://docs.stripe.com/sdks/stripejs-versioning"));
23633
+ console.warn("Stripe.js@".concat(version, " was loaded on the page, but @stripe/stripe-js@").concat("9.12.0", " expected Stripe.js@").concat(expectedVersion, ". This may result in unexpected behavior. For more information, see https://docs.stripe.com/sdks/stripejs-versioning"));
23393
23634
  }
23394
23635
  var stripe = maybeStripe.apply(void 0, args);
23395
23636
  registerWrapper(stripe, startTime);
@@ -23803,14 +24044,17 @@ var UsageDetails2 = ({
23803
24044
  layout
23804
24045
  }) => {
23805
24046
  const { t: t3 } = useTranslation();
23806
- const { settings } = useEmbed();
24047
+ const { settings, warningThresholdConfig } = useEmbed();
24048
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
23807
24049
  const {
23808
24050
  billingPrice,
23809
24051
  limit,
23810
24052
  cost = 0
23811
24053
  } = useMemo27(
23812
- () => getUsageDetails(entitlement, period, currency),
23813
- [entitlement, period, currency]
24054
+ () => getUsageDetails(entitlement, period, currency, {
24055
+ showWarningThresholdAsLimit
24056
+ }),
24057
+ [entitlement, period, currency, showWarningThresholdAsLimit]
23814
24058
  );
23815
24059
  const description = useMemo27(() => {
23816
24060
  const acc = [];
@@ -24579,7 +24823,8 @@ var AddOn2 = ({
24579
24823
  }) => {
24580
24824
  const { layout } = sharedProps;
24581
24825
  const { t: t3 } = useTranslation();
24582
- const { data, settings, setCheckoutState } = useEmbed();
24826
+ const { data, settings, setCheckoutState, warningThresholdConfig } = useEmbed();
24827
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
24583
24828
  const isLightBackground = useIsLightBackground();
24584
24829
  const { currentAddOns, canCheckout, isStandalone } = useMemo29(() => {
24585
24830
  const isStandalone2 = typeof data?.component === "undefined";
@@ -24608,12 +24853,16 @@ var AddOn2 = ({
24608
24853
  selectedPeriod,
24609
24854
  currency
24610
24855
  );
24856
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
24611
24857
  return {
24612
24858
  isUnlimited: false,
24613
24859
  featureName: entitlement.feature?.name,
24614
24860
  feature: entitlement.feature,
24615
24861
  priceBehavior: entitlement.priceBehavior,
24616
24862
  softLimit: entitlement.softLimit,
24863
+ // The limit shown next to the feature: the warning threshold when the
24864
+ // option is on and one is configured, else the overage soft limit.
24865
+ limit: typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage ? entitlement.softLimit : void 0,
24617
24866
  price: priceData?.price ?? 0,
24618
24867
  currency: priceData?.currency || addOnCurrency,
24619
24868
  packageSize: priceData?.packageSize ?? 1,
@@ -24783,7 +25032,7 @@ var AddOn2 = ({
24783
25032
  rounded: true
24784
25033
  }
24785
25034
  ),
24786
- /* @__PURE__ */ jsx59(Flex, { $flexDirection: "column", $justifyContent: "center", children: /* @__PURE__ */ jsx59(Text, { children: meteredEntitlement.priceBehavior === EntitlementPriceBehavior.Overage && meteredEntitlement.softLimit ? `${meteredEntitlement.softLimit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) }) })
25035
+ /* @__PURE__ */ jsx59(Flex, { $flexDirection: "column", $justifyContent: "center", children: /* @__PURE__ */ jsx59(Text, { children: typeof meteredEntitlement.limit === "number" ? `${meteredEntitlement.limit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) }) })
24787
25036
  ] }),
24788
25037
  /* @__PURE__ */ jsx59(
24789
25038
  Text,
@@ -24854,7 +25103,8 @@ var Entitlement2 = ({
24854
25103
  }) => {
24855
25104
  const { layout } = sharedProps;
24856
25105
  const { t: t3 } = useTranslation();
24857
- const { settings } = useEmbed();
25106
+ const { settings, warningThresholdConfig } = useEmbed();
25107
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
24858
25108
  const isLightBackground = useIsLightBackground();
24859
25109
  const entitlementBillingPrice = getEntitlementPrice(
24860
25110
  entitlement,
@@ -24869,7 +25119,8 @@ var Entitlement2 = ({
24869
25119
  tiersMode: entitlementTiersMode
24870
25120
  } = entitlementBillingPrice || {};
24871
25121
  const tiered = entitlement.priceBehavior === EntitlementPriceBehavior.PayInAdvance && isTieredPrice(entitlementBillingPrice);
24872
- const limit = entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
25122
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
25123
+ const limit = typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
24873
25124
  const metricPeriodName = getMetricPeriodName(entitlement);
24874
25125
  const creditBasedEntitlementLimit = getCreditBasedEntitlementLimit(
24875
25126
  entitlement,
@@ -25759,20 +26010,27 @@ function resolveDesignProps11(props) {
25759
26010
  var UpcomingBill = forwardRef18(({ className, ...rest }, ref) => {
25760
26011
  const props = resolveDesignProps11(rest);
25761
26012
  const { t: t3 } = useTranslation();
25762
- const { data, settings, debug, getUpcomingInvoice, getCustomerBalance } = useEmbed();
26013
+ const { data, settings, getUpcomingInvoice } = useEmbed();
25763
26014
  const isLightBackground = useIsLightBackground();
25764
26015
  const [isLoading, setIsLoading] = useState22(false);
25765
26016
  const [error, setError] = useState22();
25766
26017
  const [upcomingInvoice, setUpcomingInvoice] = useState22(data?.upcomingInvoice);
25767
- const [balances, setBalances] = useState22([]);
25768
26018
  const discounts = useMemo32(() => {
25769
- return (data?.subscription?.discounts || []).map((discount) => ({
26019
+ return (data?.subscription?.discounts || []).filter(
26020
+ (discount) => (
26021
+ // Only surface discounts that are currently active and actually
26022
+ // reduce the bill; the API computes `isActive` at read time, so an
26023
+ // expired coupon must not linger in the account summary.
26024
+ discount.isActive && (typeof discount.percentOff === "number" && discount.percentOff > 0 || typeof discount.amountOff === "number" && discount.amountOff > 0)
26025
+ )
26026
+ ).map((discount) => ({
25770
26027
  couponId: discount.couponId,
25771
26028
  customerFacingCode: discount.customerFacingCode || void 0,
25772
26029
  currency: discount.currency || void 0,
25773
26030
  amountOff: discount.amountOff ?? void 0,
25774
26031
  percentOff: discount.percentOff ?? void 0,
25775
- isActive: discount.isActive
26032
+ duration: discount.duration,
26033
+ durationInMonths: discount.durationInMonths ?? void 0
25776
26034
  }));
25777
26035
  }, [data?.subscription?.discounts]);
25778
26036
  const getInvoice = useCallback16(async () => {
@@ -25791,27 +26049,30 @@ var UpcomingBill = forwardRef18(({ className, ...rest }, ref) => {
25791
26049
  }
25792
26050
  }
25793
26051
  }, [data?.component?.id, data?.subscription, getUpcomingInvoice]);
25794
- const getBalances = useCallback16(async () => {
25795
- try {
25796
- const response = await getCustomerBalance();
25797
- if (response) {
25798
- setBalances(response.data.balances);
25799
- }
25800
- } catch (err) {
25801
- debug("Failed to fetch customer balance.", err);
25802
- }
25803
- }, [debug, getCustomerBalance]);
25804
26052
  useEffect9(() => {
25805
26053
  getInvoice();
25806
26054
  }, [getInvoice]);
25807
- useEffect9(() => {
25808
- getBalances();
25809
- }, [getBalances]);
25810
26055
  useEffect9(() => {
25811
26056
  if (data?.upcomingInvoice) {
25812
26057
  setUpcomingInvoice(data.upcomingInvoice);
25813
26058
  }
25814
26059
  }, [data?.upcomingInvoice]);
26060
+ const { currency, applied, remaining } = useMemo32(() => {
26061
+ const currency2 = upcomingInvoice?.currency;
26062
+ const startingBalance = upcomingInvoice?.startingBalance ?? 0;
26063
+ const endingBalance = upcomingInvoice?.endingBalance ?? 0;
26064
+ const credit = Math.max(0, -startingBalance);
26065
+ const subtotal = Math.max(0, upcomingInvoice?.subtotal ?? 0);
26066
+ const applied2 = endingBalance < 0 ? credit + endingBalance : Math.min(credit, subtotal);
26067
+ return { currency: currency2, applied: applied2, remaining: credit - applied2 };
26068
+ }, [
26069
+ upcomingInvoice?.currency,
26070
+ upcomingInvoice?.startingBalance,
26071
+ upcomingInvoice?.endingBalance,
26072
+ upcomingInvoice?.subtotal
26073
+ ]);
26074
+ const hasApplied = applied > 0;
26075
+ const hasBalance = remaining > 0 || applied > 0;
25815
26076
  if (!data?.subscription || data.subscription.cancelAt) {
25816
26077
  return null;
25817
26078
  }
@@ -25861,7 +26122,7 @@ var UpcomingBill = forwardRef18(({ className, ...rest }, ref) => {
25861
26122
  ]
25862
26123
  }
25863
26124
  ),
25864
- balances.length > 0 && /* @__PURE__ */ jsxs48(
26125
+ hasApplied && /* @__PURE__ */ jsxs48(
25865
26126
  Flex,
25866
26127
  {
25867
26128
  as: TransitionBox,
@@ -25869,8 +26130,21 @@ var UpcomingBill = forwardRef18(({ className, ...rest }, ref) => {
25869
26130
  $alignItems: "start",
25870
26131
  $gap: "1rem",
25871
26132
  children: [
25872
- /* @__PURE__ */ jsx65(Text, { $weight: 600, children: t3("Remaining balance") }),
25873
- /* @__PURE__ */ jsx65(Flex, { $flexDirection: "column", $gap: "0.5rem", children: balances.map((item, idx) => /* @__PURE__ */ jsx65(Text, { children: formatCurrency(item.balance, item.currency) }, idx)) })
26133
+ /* @__PURE__ */ jsx65(Text, { $weight: 600, children: t3("Applied balance towards next invoice") }),
26134
+ /* @__PURE__ */ jsx65(Text, { children: formatCurrency(-applied, currency) })
26135
+ ]
26136
+ }
26137
+ ),
26138
+ hasBalance && /* @__PURE__ */ jsxs48(
26139
+ Flex,
26140
+ {
26141
+ as: TransitionBox,
26142
+ $justifyContent: "space-between",
26143
+ $alignItems: "start",
26144
+ $gap: "1rem",
26145
+ children: [
26146
+ /* @__PURE__ */ jsx65(Text, { $weight: 600, children: t3("Remaining balance after next invoice") }),
26147
+ /* @__PURE__ */ jsx65(Text, { children: formatCurrency(remaining, currency) })
25874
26148
  ]
25875
26149
  }
25876
26150
  ),
@@ -25888,54 +26162,50 @@ var UpcomingBill = forwardRef18(({ className, ...rest }, ref) => {
25888
26162
  $flexDirection: "column",
25889
26163
  $alignItems: "end",
25890
26164
  $gap: "0.5rem",
25891
- children: discounts.reduce(
25892
- (acc, discount) => {
25893
- if (typeof discount.percentOff === "number" || typeof discount.amountOff === "number") {
25894
- acc.push(
25895
- /* @__PURE__ */ jsxs48(
26165
+ children: discounts.map((discount) => {
26166
+ const label = typeof discount.percentOff === "number" && discount.percentOff > 0 ? t3("Percent off", {
26167
+ percent: discount.percentOff
26168
+ }) : t3("Amount off", {
26169
+ amount: formatCurrency(
26170
+ discount.amountOff,
26171
+ // active discounts always carry a positive amount or percent
26172
+ discount?.currency
26173
+ )
26174
+ });
26175
+ return /* @__PURE__ */ jsxs48(
26176
+ Flex,
26177
+ {
26178
+ $alignItems: "center",
26179
+ $gap: "0.5rem",
26180
+ children: [
26181
+ discount.customerFacingCode && /* @__PURE__ */ jsx65(
25896
26182
  Flex,
25897
26183
  {
25898
26184
  $alignItems: "center",
25899
- $gap: "0.5rem",
25900
- children: [
25901
- discount.customerFacingCode && /* @__PURE__ */ jsx65(
25902
- Flex,
25903
- {
25904
- $alignItems: "center",
25905
- $padding: "0.1875rem 0.375rem",
25906
- $borderWidth: "1px",
25907
- $borderStyle: "solid",
25908
- $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.15)" : "hsla(0, 0%, 100%, 0.15)",
25909
- $borderRadius: "0.3125rem",
25910
- children: /* @__PURE__ */ jsx65(
25911
- Text,
25912
- {
25913
- $size: 0.75 * settings.theme.typography.text.fontSize,
25914
- style: { textTransform: "uppercase" },
25915
- children: discount.customerFacingCode
25916
- }
25917
- )
25918
- }
25919
- ),
25920
- /* @__PURE__ */ jsx65(Box, { children: /* @__PURE__ */ jsx65(Text, { children: typeof discount.percentOff === "number" ? t3("Percent off", {
25921
- percent: discount.percentOff
25922
- }) : t3("Amount off", {
25923
- amount: formatCurrency(
25924
- discount.amountOff,
25925
- // we already checked for `number` type
25926
- discount?.currency
25927
- )
25928
- }) }) })
25929
- ]
25930
- },
25931
- discount.couponId
25932
- )
25933
- );
25934
- }
25935
- return acc;
25936
- },
25937
- []
25938
- )
26185
+ $padding: "0.1875rem 0.375rem",
26186
+ $borderWidth: "1px",
26187
+ $borderStyle: "solid",
26188
+ $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.15)" : "hsla(0, 0%, 100%, 0.15)",
26189
+ $borderRadius: "0.3125rem",
26190
+ children: /* @__PURE__ */ jsx65(
26191
+ Text,
26192
+ {
26193
+ $size: 0.75 * settings.theme.typography.text.fontSize,
26194
+ style: { textTransform: "uppercase" },
26195
+ children: discount.customerFacingCode
26196
+ }
26197
+ )
26198
+ }
26199
+ ),
26200
+ /* @__PURE__ */ jsx65(Box, { children: /* @__PURE__ */ jsx65(Text, { children: discount.duration === "repeating" && discount.durationInMonths ? t3("Discount for months", {
26201
+ discount: label,
26202
+ count: discount.durationInMonths
26203
+ }) : label }) })
26204
+ ]
26205
+ },
26206
+ discount.couponId
26207
+ );
26208
+ })
25939
26209
  }
25940
26210
  )
25941
26211
  ]