@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 c = "undefined" != typeof process && void 0 !== process.env && (process.env.REACT_APP_SC_ATTR || process.env.SC_ATTR) || "data-styled";
5817
5831
  var a = "active";
5818
5832
  var l = "data-styled-version";
5819
- var u = "6.4.3";
5833
+ var u = "6.4.4";
5820
5834
  var h = "/*!sc*/\n";
5821
5835
  var d = "undefined" != typeof window && "undefined" != typeof document;
5822
5836
  function p(e2) {
@@ -7742,11 +7756,13 @@ function InvoiceResponseDataFromJSONTyped(json, ignoreDiscriminator) {
7742
7756
  currency: json["currency"],
7743
7757
  customerExternalId: json["customer_external_id"],
7744
7758
  dueDate: json["due_date"] == null ? void 0 : new Date(json["due_date"]),
7759
+ endingBalance: json["ending_balance"],
7745
7760
  environmentId: json["environment_id"],
7746
7761
  externalId: json["external_id"] == null ? void 0 : json["external_id"],
7747
7762
  id: json["id"],
7748
7763
  paymentMethodExternalId: json["payment_method_external_id"] == null ? void 0 : json["payment_method_external_id"],
7749
7764
  providerType: BillingProviderTypeFromJSON(json["provider_type"]),
7765
+ startingBalance: json["starting_balance"],
7750
7766
  status: json["status"] == null ? void 0 : InvoiceStatusFromJSON(json["status"]),
7751
7767
  subscriptionExternalId: json["subscription_external_id"] == null ? void 0 : json["subscription_external_id"],
7752
7768
  subtotal: json["subtotal"],
@@ -8222,6 +8238,20 @@ function EntitlementValueTypeFromJSONTyped(json, ignoreDiscriminator) {
8222
8238
  return json;
8223
8239
  }
8224
8240
 
8241
+ // src/api/checkoutexternal/models/WarningTier.ts
8242
+ function WarningTierFromJSON(json) {
8243
+ return WarningTierFromJSONTyped(json, false);
8244
+ }
8245
+ function WarningTierFromJSONTyped(json, ignoreDiscriminator) {
8246
+ if (json == null) {
8247
+ return json;
8248
+ }
8249
+ return {
8250
+ key: json["key"],
8251
+ value: json["value"]
8252
+ };
8253
+ }
8254
+
8225
8255
  // src/api/checkoutexternal/models/FeatureEntitlement.ts
8226
8256
  function FeatureEntitlementFromJSON(json) {
8227
8257
  return FeatureEntitlementFromJSONTyped(json, false);
@@ -8248,7 +8278,8 @@ function FeatureEntitlementFromJSONTyped(json, ignoreDiscriminator) {
8248
8278
  monthReset: json["month_reset"] == null ? void 0 : MetricPeriodMonthResetFromJSON(json["month_reset"]),
8249
8279
  softLimit: json["soft_limit"] == null ? void 0 : json["soft_limit"],
8250
8280
  usage: json["usage"] == null ? void 0 : json["usage"],
8251
- valueType: EntitlementValueTypeFromJSON(json["value_type"])
8281
+ valueType: EntitlementValueTypeFromJSON(json["value_type"]),
8282
+ warningTiers: json["warning_tiers"] == null ? void 0 : json["warning_tiers"].map(WarningTierFromJSON)
8252
8283
  };
8253
8284
  }
8254
8285
 
@@ -8595,6 +8626,7 @@ function CompanyOverrideNoteResponseDataFromJSONTyped(json, ignoreDiscriminator)
8595
8626
  var FeatureType = {
8596
8627
  Boolean: "boolean",
8597
8628
  Event: "event",
8629
+ License: "license",
8598
8630
  Trait: "trait"
8599
8631
  };
8600
8632
  function FeatureTypeFromJSON(json) {
@@ -8627,13 +8659,15 @@ function FeatureResponseDataFromJSONTyped(json, ignoreDiscriminator) {
8627
8659
  featureType: FeatureTypeFromJSON(json["feature_type"]),
8628
8660
  icon: json["icon"],
8629
8661
  id: json["id"],
8662
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
8630
8663
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON(json["lifecycle_phase"]),
8631
8664
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
8632
8665
  name: json["name"],
8633
8666
  pluralName: json["plural_name"] == null ? void 0 : json["plural_name"],
8634
8667
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
8635
8668
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
8636
- updatedAt: new Date(json["updated_at"])
8669
+ updatedAt: new Date(json["updated_at"]),
8670
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
8637
8671
  };
8638
8672
  }
8639
8673
 
@@ -8985,6 +9019,7 @@ function FeatureInPlanResponseDataFromJSONTyped(json, ignoreDiscriminator) {
8985
9019
  flags: json["flags"].map(FlagInPlanResponseDataFromJSON),
8986
9020
  icon: json["icon"],
8987
9021
  id: json["id"],
9022
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
8988
9023
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON(json["lifecycle_phase"]),
8989
9024
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
8990
9025
  name: json["name"],
@@ -8993,7 +9028,8 @@ function FeatureInPlanResponseDataFromJSONTyped(json, ignoreDiscriminator) {
8993
9028
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
8994
9029
  trait: json["trait"] == null ? void 0 : EntityTraitDefinitionResponseDataFromJSON(json["trait"]),
8995
9030
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
8996
- updatedAt: new Date(json["updated_at"])
9031
+ updatedAt: new Date(json["updated_at"]),
9032
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
8997
9033
  };
8998
9034
  }
8999
9035
 
@@ -9070,6 +9106,20 @@ function PlanCreditGrantViewFromJSONTyped(json, ignoreDiscriminator) {
9070
9106
  };
9071
9107
  }
9072
9108
 
9109
+ // src/api/checkoutexternal/models/PlanCatalogMembershipResponseData.ts
9110
+ function PlanCatalogMembershipResponseDataFromJSON(json) {
9111
+ return PlanCatalogMembershipResponseDataFromJSONTyped(json, false);
9112
+ }
9113
+ function PlanCatalogMembershipResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9114
+ if (json == null) {
9115
+ return json;
9116
+ }
9117
+ return {
9118
+ id: json["id"],
9119
+ name: json["name"]
9120
+ };
9121
+ }
9122
+
9073
9123
  // src/api/checkoutexternal/models/PlanCurrencyPricesResponseData.ts
9074
9124
  function PlanCurrencyPricesResponseDataFromJSON(json) {
9075
9125
  return PlanCurrencyPricesResponseDataFromJSONTyped(json, false);
@@ -9226,6 +9276,9 @@ function CompanyPlanDetailResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9226
9276
  ),
9227
9277
  billingProduct: json["billing_product"] == null ? void 0 : BillingProductDetailResponseDataFromJSON(json["billing_product"]),
9228
9278
  billingStrategy: BillingStrategyFromJSON(json["billing_strategy"]),
9279
+ catalogs: json["catalogs"] == null ? void 0 : json["catalogs"].map(
9280
+ PlanCatalogMembershipResponseDataFromJSON
9281
+ ),
9229
9282
  chargeType: ChargeTypeFromJSON(json["charge_type"]),
9230
9283
  companyCanTrial: json["company_can_trial"],
9231
9284
  companyCount: json["company_count"],
@@ -9399,6 +9452,9 @@ function PlanDetailResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9399
9452
  ),
9400
9453
  billingProduct: json["billing_product"] == null ? void 0 : BillingProductDetailResponseDataFromJSON(json["billing_product"]),
9401
9454
  billingStrategy: BillingStrategyFromJSON(json["billing_strategy"]),
9455
+ catalogs: json["catalogs"] == null ? void 0 : json["catalogs"].map(
9456
+ PlanCatalogMembershipResponseDataFromJSON
9457
+ ),
9402
9458
  chargeType: ChargeTypeFromJSON(json["charge_type"]),
9403
9459
  companyCount: json["company_count"],
9404
9460
  companyId: json["company_id"] == null ? void 0 : json["company_id"],
@@ -9568,6 +9624,7 @@ function ComponentResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9568
9624
  }
9569
9625
  return {
9570
9626
  ast: json["ast"] == null ? void 0 : json["ast"],
9627
+ catalogId: json["catalog_id"] == null ? void 0 : json["catalog_id"],
9571
9628
  createdAt: new Date(json["created_at"]),
9572
9629
  id: json["id"],
9573
9630
  name: json["name"],
@@ -9804,6 +9861,29 @@ function PreviewSubscriptionUpcomingInvoiceLineItemsFromJSONTyped(json, ignoreDi
9804
9861
  };
9805
9862
  }
9806
9863
 
9864
+ // src/api/checkoutexternal/models/PreviewSubscriptionDiscountResponseData.ts
9865
+ function PreviewSubscriptionDiscountResponseDataFromJSON(json) {
9866
+ return PreviewSubscriptionDiscountResponseDataFromJSONTyped(json, false);
9867
+ }
9868
+ function PreviewSubscriptionDiscountResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9869
+ if (json == null) {
9870
+ return json;
9871
+ }
9872
+ return {
9873
+ amountOff: json["amount_off"] == null ? void 0 : json["amount_off"],
9874
+ couponName: json["coupon_name"],
9875
+ currency: json["currency"] == null ? void 0 : json["currency"],
9876
+ customerFacingCode: json["customer_facing_code"] == null ? void 0 : json["customer_facing_code"],
9877
+ duration: json["duration"],
9878
+ durationInMonths: json["duration_in_months"] == null ? void 0 : json["duration_in_months"],
9879
+ endedAt: json["ended_at"] == null ? void 0 : new Date(json["ended_at"]),
9880
+ isActive: json["is_active"],
9881
+ percentOff: json["percent_off"] == null ? void 0 : json["percent_off"],
9882
+ promoCodeExternalId: json["promo_code_external_id"] == null ? void 0 : json["promo_code_external_id"],
9883
+ startedAt: new Date(json["started_at"])
9884
+ };
9885
+ }
9886
+
9807
9887
  // src/api/checkoutexternal/models/PreviewSubscriptionFinanceResponseData.ts
9808
9888
  function PreviewSubscriptionFinanceResponseDataFromJSON(json) {
9809
9889
  return PreviewSubscriptionFinanceResponseDataFromJSONTyped(json, false);
@@ -9814,9 +9894,13 @@ function PreviewSubscriptionFinanceResponseDataFromJSONTyped(json, ignoreDiscrim
9814
9894
  }
9815
9895
  return {
9816
9896
  amountOff: json["amount_off"],
9897
+ discounts: json["discounts"].map(
9898
+ PreviewSubscriptionDiscountResponseDataFromJSON
9899
+ ),
9817
9900
  dueNow: json["due_now"],
9818
9901
  newCharges: json["new_charges"],
9819
9902
  percentOff: json["percent_off"],
9903
+ periodEnd: new Date(json["period_end"]),
9820
9904
  periodStart: new Date(json["period_start"]),
9821
9905
  promoCodeApplied: json["promo_code_applied"],
9822
9906
  proration: json["proration"],
@@ -11430,13 +11514,15 @@ function FeatureResponseDataFromJSONTyped5(json, ignoreDiscriminator) {
11430
11514
  featureType: FeatureTypeFromJSON2(json["feature_type"]),
11431
11515
  icon: json["icon"],
11432
11516
  id: json["id"],
11517
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
11433
11518
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON2(json["lifecycle_phase"]),
11434
11519
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
11435
11520
  name: json["name"],
11436
11521
  pluralName: json["plural_name"] == null ? void 0 : json["plural_name"],
11437
11522
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
11438
11523
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
11439
- updatedAt: new Date(json["updated_at"])
11524
+ updatedAt: new Date(json["updated_at"]),
11525
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
11440
11526
  };
11441
11527
  }
11442
11528
 
@@ -11493,6 +11579,7 @@ function FeatureInPlanResponseDataFromJSONTyped6(json, ignoreDiscriminator) {
11493
11579
  flags: json["flags"].map(FlagInPlanResponseDataFromJSON2),
11494
11580
  icon: json["icon"],
11495
11581
  id: json["id"],
11582
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
11496
11583
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON2(json["lifecycle_phase"]),
11497
11584
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
11498
11585
  name: json["name"],
@@ -11501,7 +11588,8 @@ function FeatureInPlanResponseDataFromJSONTyped6(json, ignoreDiscriminator) {
11501
11588
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
11502
11589
  trait: json["trait"] == null ? void 0 : EntityTraitDefinitionResponseDataFromJSON2(json["trait"]),
11503
11590
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
11504
- updatedAt: new Date(json["updated_at"])
11591
+ updatedAt: new Date(json["updated_at"]),
11592
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
11505
11593
  };
11506
11594
  }
11507
11595
 
@@ -11680,6 +11768,20 @@ function PlanCreditGrantViewFromJSONTyped3(json, ignoreDiscriminator) {
11680
11768
  };
11681
11769
  }
11682
11770
 
11771
+ // src/api/componentspublic/models/PlanCatalogMembershipResponseData.ts
11772
+ function PlanCatalogMembershipResponseDataFromJSON2(json) {
11773
+ return PlanCatalogMembershipResponseDataFromJSONTyped5(json, false);
11774
+ }
11775
+ function PlanCatalogMembershipResponseDataFromJSONTyped5(json, ignoreDiscriminator) {
11776
+ if (json == null) {
11777
+ return json;
11778
+ }
11779
+ return {
11780
+ id: json["id"],
11781
+ name: json["name"]
11782
+ };
11783
+ }
11784
+
11683
11785
  // src/api/componentspublic/models/PlanCurrencyPricesResponseData.ts
11684
11786
  function PlanCurrencyPricesResponseDataFromJSON2(json) {
11685
11787
  return PlanCurrencyPricesResponseDataFromJSONTyped5(json, false);
@@ -11747,6 +11849,9 @@ function PlanViewPublicResponseDataFromJSONTyped(json, ignoreDiscriminator) {
11747
11849
  ),
11748
11850
  billingProduct: json["billing_product"] == null ? void 0 : BillingProductDetailResponseDataFromJSON2(json["billing_product"]),
11749
11851
  billingStrategy: BillingStrategyFromJSON2(json["billing_strategy"]),
11852
+ catalogs: json["catalogs"] == null ? void 0 : json["catalogs"].map(
11853
+ PlanCatalogMembershipResponseDataFromJSON2
11854
+ ),
11750
11855
  chargeType: ChargeTypeFromJSON2(json["charge_type"]),
11751
11856
  companyCount: json["company_count"],
11752
11857
  companyId: json["company_id"] == null ? void 0 : json["company_id"],
@@ -12364,7 +12469,7 @@ function getMetricPeriodName(entitlement) {
12364
12469
  const name = period ? PeriodName[period] : void 0;
12365
12470
  return name;
12366
12471
  }
12367
- function getUsageDetails(entitlement, period, currency) {
12472
+ function getUsageDetails(entitlement, period, currency, options) {
12368
12473
  const billingPrice = currency ? getEntitlementPrice(entitlement, period ?? "month", currency) : period === "year" ? entitlement.yearlyUsageBasedPrice : period === "quarter" ? entitlement.quarterlyUsageBasedPrice : period === "month" ? entitlement.monthlyUsageBasedPrice : void 0;
12369
12474
  let limit;
12370
12475
  if ((!entitlement.priceBehavior || entitlement.priceBehavior === EntitlementPriceBehavior.PayInAdvance) && typeof entitlement.allocation === "number") {
@@ -12412,8 +12517,21 @@ function getUsageDetails(entitlement, period, currency) {
12412
12517
  start = end + 1;
12413
12518
  }
12414
12519
  }
12520
+ if (options?.showWarningThresholdAsLimit) {
12521
+ const warningThreshold = getEntitlementWarningThreshold(
12522
+ entitlement.planEntitlement?.warningTiers
12523
+ );
12524
+ if (typeof warningThreshold === "number") {
12525
+ limit = warningThreshold;
12526
+ }
12527
+ }
12415
12528
  return { billingPrice, limit, amount, cost, currentTier };
12416
12529
  }
12530
+ var WARNING_TIER_DEFAULT_KEY = "default";
12531
+ function getEntitlementWarningThreshold(warningTiers) {
12532
+ const tier = warningTiers?.find((t3) => t3?.key === WARNING_TIER_DEFAULT_KEY);
12533
+ return typeof tier?.value === "number" ? tier.value : void 0;
12534
+ }
12417
12535
  function getCreditBasedEntitlementLimit(entitlement, credits) {
12418
12536
  const matchedCredit = credits.find(
12419
12537
  (credit) => credit.id === entitlement.valueCredit?.id
@@ -12961,85 +13079,6 @@ function modifyDate(date, days) {
12961
13079
  return copy3;
12962
13080
  }
12963
13081
 
12964
- // src/utils/error.ts
12965
- function isError(value) {
12966
- return value instanceof Error;
12967
- }
12968
- var ERROR_UNKNOWN = new Error("An unknown error occurred.");
12969
-
12970
- // src/utils/event.ts
12971
- var createKeyboardExecutionHandler = (fn) => {
12972
- const handler = (event) => {
12973
- if (event.key === "Enter" || event.key === " ") {
12974
- event.preventDefault();
12975
- fn?.(event);
12976
- }
12977
- };
12978
- return handler;
12979
- };
12980
-
12981
- // src/utils/markdown.tsx
12982
- import { Fragment as Fragment2 } from "react";
12983
- import { jsx } from "react/jsx-runtime";
12984
- var TOKEN = /(\[[^\]]+\]\([^)\s]+\))|(\*\*[^*]+\*\*)|(\*[^*]+\*)/g;
12985
- var LINK = /^\[([^\]]+)\]\(([^)\s]+)\)$/;
12986
- var isSafeUrl = (url) => {
12987
- try {
12988
- const { protocol } = new URL(url);
12989
- return protocol === "http:" || protocol === "https:";
12990
- } catch {
12991
- return false;
12992
- }
12993
- };
12994
- var renderOptInMarkdown = (text) => {
12995
- if (!text) {
12996
- return null;
12997
- }
12998
- const nodes = [];
12999
- let lastIndex = 0;
13000
- let key = 0;
13001
- TOKEN.lastIndex = 0;
13002
- let match2;
13003
- while ((match2 = TOKEN.exec(text)) !== null) {
13004
- if (match2.index > lastIndex) {
13005
- nodes.push(
13006
- /* @__PURE__ */ jsx(Fragment2, { children: text.slice(lastIndex, match2.index) }, key++)
13007
- );
13008
- }
13009
- const [token2, link, bold, italic] = match2;
13010
- if (link) {
13011
- const parts = LINK.exec(link);
13012
- if (parts && isSafeUrl(parts[2])) {
13013
- nodes.push(
13014
- /* @__PURE__ */ jsx(
13015
- Text,
13016
- {
13017
- as: "a",
13018
- display: "link",
13019
- href: parts[2],
13020
- target: "_blank",
13021
- rel: "noopener noreferrer",
13022
- children: parts[1]
13023
- },
13024
- key++
13025
- )
13026
- );
13027
- } else {
13028
- nodes.push(/* @__PURE__ */ jsx(Fragment2, { children: parts ? parts[1] : token2 }, key++));
13029
- }
13030
- } else if (bold) {
13031
- nodes.push(/* @__PURE__ */ jsx("strong", { children: bold.slice(2, -2) }, key++));
13032
- } else if (italic) {
13033
- nodes.push(/* @__PURE__ */ jsx("em", { children: italic.slice(1, -1) }, key++));
13034
- }
13035
- lastIndex = match2.index + token2.length;
13036
- }
13037
- if (lastIndex < text.length) {
13038
- nodes.push(/* @__PURE__ */ jsx(Fragment2, { children: text.slice(lastIndex) }, key));
13039
- }
13040
- return nodes;
13041
- };
13042
-
13043
13082
  // src/utils/string.ts
13044
13083
  var ZERO_DECIMAL_CURRENCIES = /* @__PURE__ */ new Set([
13045
13084
  "BIF",
@@ -13188,6 +13227,168 @@ function getCurrencySymbol(currency) {
13188
13227
  }
13189
13228
  }
13190
13229
 
13230
+ // src/utils/discount.ts
13231
+ function getSubscriptionDiscount(discounts, subscriptionTotal, subscriptionCurrency) {
13232
+ const activeDiscounts = (discounts || []).filter(
13233
+ (discount2) => discount2.isActive && (typeof discount2.percentOff === "number" && discount2.percentOff > 0 || typeof discount2.amountOff === "number" && discount2.amountOff > 0)
13234
+ );
13235
+ if (activeDiscounts.length !== 1) {
13236
+ return void 0;
13237
+ }
13238
+ const discount = activeDiscounts[0];
13239
+ const isPercentOff = typeof discount.percentOff === "number" && discount.percentOff > 0;
13240
+ if (!isPercentOff && discount.currency && subscriptionCurrency && discount.currency.toLowerCase() !== subscriptionCurrency.toLowerCase()) {
13241
+ return void 0;
13242
+ }
13243
+ const discountedTotal = isPercentOff ? subscriptionTotal * (1 - discount.percentOff / 100) : Math.max(0, subscriptionTotal - (discount.amountOff ?? 0));
13244
+ if (discountedTotal >= subscriptionTotal) {
13245
+ return void 0;
13246
+ }
13247
+ return {
13248
+ duration: discount.duration,
13249
+ durationInMonths: discount.durationInMonths ?? void 0,
13250
+ discountedPrice: formatCurrency(
13251
+ discountedTotal,
13252
+ subscriptionCurrency ?? void 0
13253
+ )
13254
+ };
13255
+ }
13256
+ function getBillingPreviewText({
13257
+ subscriptionPrice,
13258
+ planPeriod,
13259
+ periodStart,
13260
+ hasUsageBasedCosts,
13261
+ discount
13262
+ }, t3) {
13263
+ if (!subscriptionPrice) {
13264
+ return null;
13265
+ }
13266
+ const usage = hasUsageBasedCosts ? `${t3("plus usage based costs")} ` : "";
13267
+ const scheduleParts = [];
13268
+ if (periodStart) {
13269
+ scheduleParts.push(
13270
+ t3("on the day", { day: formatOrdinal(periodStart.getDate()) })
13271
+ );
13272
+ }
13273
+ if (planPeriod === "year" && periodStart) {
13274
+ scheduleParts.push(t3("of month", { month: getMonthName(periodStart) }));
13275
+ }
13276
+ const schedule = scheduleParts.length > 0 ? `${scheduleParts.join(" ")} ` : "";
13277
+ if (!discount) {
13278
+ return t3("You will be billed", {
13279
+ price: subscriptionPrice,
13280
+ usage,
13281
+ period: planPeriod,
13282
+ schedule
13283
+ });
13284
+ }
13285
+ const { duration, durationInMonths, discountedPrice } = discount;
13286
+ if (duration === "forever") {
13287
+ return t3("You will be billed", {
13288
+ price: discountedPrice,
13289
+ usage,
13290
+ period: planPeriod,
13291
+ schedule
13292
+ });
13293
+ }
13294
+ if (duration === "repeating" && durationInMonths) {
13295
+ return t3("You will be billed with discount window", {
13296
+ price: discountedPrice,
13297
+ usage,
13298
+ period: planPeriod,
13299
+ schedule,
13300
+ window: t3("for the next months", { count: durationInMonths }),
13301
+ fullPrice: subscriptionPrice
13302
+ });
13303
+ }
13304
+ return t3("You will be billed next bill discount", {
13305
+ price: discountedPrice,
13306
+ usage,
13307
+ period: planPeriod,
13308
+ schedule,
13309
+ fullPrice: subscriptionPrice
13310
+ });
13311
+ }
13312
+
13313
+ // src/utils/error.ts
13314
+ function isError(value) {
13315
+ return value instanceof Error;
13316
+ }
13317
+ var ERROR_UNKNOWN = new Error("An unknown error occurred.");
13318
+
13319
+ // src/utils/event.ts
13320
+ var createKeyboardExecutionHandler = (fn) => {
13321
+ const handler = (event) => {
13322
+ if (event.key === "Enter" || event.key === " ") {
13323
+ event.preventDefault();
13324
+ fn?.(event);
13325
+ }
13326
+ };
13327
+ return handler;
13328
+ };
13329
+
13330
+ // src/utils/markdown.tsx
13331
+ import { Fragment as Fragment2 } from "react";
13332
+ import { jsx } from "react/jsx-runtime";
13333
+ var TOKEN = /(\[[^\]]+\]\([^)\s]+\))|(\*\*[^*]+\*\*)|(\*[^*]+\*)/g;
13334
+ var LINK = /^\[([^\]]+)\]\(([^)\s]+)\)$/;
13335
+ var isSafeUrl = (url) => {
13336
+ try {
13337
+ const { protocol } = new URL(url);
13338
+ return protocol === "http:" || protocol === "https:";
13339
+ } catch {
13340
+ return false;
13341
+ }
13342
+ };
13343
+ var renderOptInMarkdown = (text) => {
13344
+ if (!text) {
13345
+ return null;
13346
+ }
13347
+ const nodes = [];
13348
+ let lastIndex = 0;
13349
+ let key = 0;
13350
+ TOKEN.lastIndex = 0;
13351
+ let match2;
13352
+ while ((match2 = TOKEN.exec(text)) !== null) {
13353
+ if (match2.index > lastIndex) {
13354
+ nodes.push(
13355
+ /* @__PURE__ */ jsx(Fragment2, { children: text.slice(lastIndex, match2.index) }, key++)
13356
+ );
13357
+ }
13358
+ const [token2, link, bold, italic] = match2;
13359
+ if (link) {
13360
+ const parts = LINK.exec(link);
13361
+ if (parts && isSafeUrl(parts[2])) {
13362
+ nodes.push(
13363
+ /* @__PURE__ */ jsx(
13364
+ Text,
13365
+ {
13366
+ as: "a",
13367
+ display: "link",
13368
+ href: parts[2],
13369
+ target: "_blank",
13370
+ rel: "noopener noreferrer",
13371
+ children: parts[1]
13372
+ },
13373
+ key++
13374
+ )
13375
+ );
13376
+ } else {
13377
+ nodes.push(/* @__PURE__ */ jsx(Fragment2, { children: parts ? parts[1] : token2 }, key++));
13378
+ }
13379
+ } else if (bold) {
13380
+ nodes.push(/* @__PURE__ */ jsx("strong", { children: bold.slice(2, -2) }, key++));
13381
+ } else if (italic) {
13382
+ nodes.push(/* @__PURE__ */ jsx("em", { children: italic.slice(1, -1) }, key++));
13383
+ }
13384
+ lastIndex = match2.index + token2.length;
13385
+ }
13386
+ if (lastIndex < text.length) {
13387
+ nodes.push(/* @__PURE__ */ jsx(Fragment2, { children: text.slice(lastIndex) }, key));
13388
+ }
13389
+ return nodes;
13390
+ };
13391
+
13191
13392
  // src/utils/style.ts
13192
13393
  function attr(key, value) {
13193
13394
  if (typeof value !== "undefined") {
@@ -13443,7 +13644,7 @@ var reducer = (state, action) => {
13443
13644
  // src/context/EmbedProvider.tsx
13444
13645
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
13445
13646
  var getCustomHeaders = (sessionId) => ({
13446
- "X-Schematic-Components-Version": "2.19.0",
13647
+ "X-Schematic-Components-Version": "2.21.0",
13447
13648
  "X-Schematic-Session-ID": sessionId
13448
13649
  });
13449
13650
  var normalizeCurrencyFilter = (filter2) => {
@@ -13467,6 +13668,7 @@ var EmbedProvider = ({
13467
13668
  apiKey,
13468
13669
  apiConfig,
13469
13670
  currencyFilter,
13671
+ warningThresholdConfig,
13470
13672
  checkoutPrefill,
13471
13673
  ...options
13472
13674
  }) => {
@@ -13482,6 +13684,7 @@ var EmbedProvider = ({
13482
13684
  const providedState = {
13483
13685
  settings: opts.settings || {},
13484
13686
  currencyFilter: normalizeCurrencyFilter(currencyFilter),
13687
+ warningThresholdConfig,
13485
13688
  checkoutPrefill: normalizeCheckoutPrefill(checkoutPrefill)
13486
13689
  };
13487
13690
  const resolvedState = (0, import_merge2.default)({}, initialState, providedState);
@@ -13910,6 +14113,7 @@ var EmbedProvider = ({
13910
14113
  layout: state.layout,
13911
14114
  checkoutState: state.checkoutState,
13912
14115
  currencyFilter: state.currencyFilter,
14116
+ warningThresholdConfig: state.warningThresholdConfig,
13913
14117
  checkoutPrefill: state.checkoutPrefill,
13914
14118
  hydratePublic: debouncedHydratePublic,
13915
14119
  hydrate: debouncedHydrate,
@@ -15858,7 +16062,8 @@ var Entitlement = ({
15858
16062
  currency: selectedCurrency
15859
16063
  }) => {
15860
16064
  const { t: t3 } = useTranslation();
15861
- const { data, settings } = useEmbed();
16065
+ const { data, settings, warningThresholdConfig } = useEmbed();
16066
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
15862
16067
  const isLightBackground = useIsLightBackground();
15863
16068
  const showCredits = data?.displaySettings?.showCredits ?? true;
15864
16069
  const showFeatureDescription = data?.displaySettings?.showFeatureDescription ?? false;
@@ -15882,7 +16087,8 @@ var Entitlement = ({
15882
16087
  return;
15883
16088
  }
15884
16089
  const hasNumericValue = entitlement.valueType === EntitlementValueType.Numeric || entitlement.valueType === EntitlementValueType.Unlimited || entitlement.valueType === EntitlementValueType.Trait;
15885
- const limit = entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
16090
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
16091
+ const limit = typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
15886
16092
  const creditBasedEntitlementLimit = getCreditBasedEntitlementLimit(
15887
16093
  entitlement,
15888
16094
  credits
@@ -15975,7 +16181,8 @@ var Entitlement = ({
15975
16181
  currency,
15976
16182
  packageSize,
15977
16183
  tiered,
15978
- selectedCurrency
16184
+ selectedCurrency,
16185
+ showWarningThresholdAsLimit
15979
16186
  ]);
15980
16187
  const usageText = useMemo10(() => {
15981
16188
  if (!entitlement.feature) {
@@ -16706,7 +16913,8 @@ var AddOns = ({
16706
16913
  currency
16707
16914
  }) => {
16708
16915
  const { t: t3 } = useTranslation();
16709
- const { settings } = useEmbed();
16916
+ const { settings, warningThresholdConfig } = useEmbed();
16917
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
16710
16918
  const isLightBackground = useIsLightBackground();
16711
16919
  const periodKey = period === "year" ? "yearlyPrice" : period === "quarter" ? "quarterlyPrice" : "monthlyPrice";
16712
16920
  const cardPadding = settings.theme.card.padding / TEXT_BASE_SIZE;
@@ -16738,10 +16946,14 @@ var AddOns = ({
16738
16946
  period,
16739
16947
  currency
16740
16948
  );
16949
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
16741
16950
  return {
16742
16951
  isUnlimited: false,
16743
16952
  priceBehavior: entitlement.priceBehavior,
16744
16953
  softLimit: entitlement.softLimit,
16954
+ // The limit shown next to the feature: the warning threshold when
16955
+ // the option is on and one is configured, else the overage soft limit.
16956
+ limit: typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage ? entitlement.softLimit : void 0,
16745
16957
  price: priceData?.price ?? 0,
16746
16958
  currency: priceData?.currency || addOnCurrency,
16747
16959
  featureName: entitlement.feature?.name,
@@ -16890,7 +17102,7 @@ var AddOns = ({
16890
17102
  {
16891
17103
  $flexDirection: "column",
16892
17104
  $justifyContent: "center",
16893
- children: /* @__PURE__ */ jsx21(Text, { children: meteredEntitlement.priceBehavior === EntitlementPriceBehavior.Overage && meteredEntitlement.softLimit ? `${meteredEntitlement.softLimit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) })
17105
+ children: /* @__PURE__ */ jsx21(Text, { children: typeof meteredEntitlement.limit === "number" ? `${meteredEntitlement.limit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) })
16894
17106
  }
16895
17107
  )
16896
17108
  ] }),
@@ -20194,7 +20406,7 @@ var SubscriptionSidebar = forwardRef7(
20194
20406
  );
20195
20407
  return { payAsYouGoEntitlements, payInAdvanceEntitlements: payInAdvanceEntitlements2 };
20196
20408
  }, [usageBasedEntitlements]);
20197
- const subscriptionPrice = useMemo18(() => {
20409
+ const { subscriptionPrice, subscriptionTotal, subscriptionCurrency } = useMemo18(() => {
20198
20410
  let planPrice;
20199
20411
  let resolvedCurrency;
20200
20412
  if (selectedPlan) {
@@ -20230,7 +20442,11 @@ var SubscriptionSidebar = forwardRef7(
20230
20442
  0
20231
20443
  );
20232
20444
  total += addOnPayInAdvanceCost;
20233
- return formatCurrency(total, resolvedCurrency);
20445
+ return {
20446
+ subscriptionPrice: formatCurrency(total, resolvedCurrency),
20447
+ subscriptionTotal: total,
20448
+ subscriptionCurrency: resolvedCurrency
20449
+ };
20234
20450
  }, [
20235
20451
  selectedPlan,
20236
20452
  currentPlan,
@@ -20245,6 +20461,7 @@ var SubscriptionSidebar = forwardRef7(
20245
20461
  dueNow,
20246
20462
  newCharges,
20247
20463
  percentOff,
20464
+ periodEnd,
20248
20465
  periodStart,
20249
20466
  proration,
20250
20467
  taxAmount,
@@ -20255,12 +20472,14 @@ var SubscriptionSidebar = forwardRef7(
20255
20472
  dueNow: charges?.dueNow ?? 0,
20256
20473
  newCharges: charges?.newCharges ?? 0,
20257
20474
  percentOff: charges?.percentOff ?? 0,
20475
+ periodEnd: charges?.periodEnd,
20258
20476
  periodStart: charges?.periodStart,
20259
20477
  proration: charges?.proration ?? 0,
20260
20478
  taxAmount: charges?.taxAmount ?? 0,
20261
20479
  taxDescription: charges?.taxDisplayName
20262
20480
  };
20263
20481
  }, [charges]);
20482
+ const renewDate = periodEnd && !Number.isNaN(periodEnd.getTime()) ? periodEnd : periodStart;
20264
20483
  const updatedUsageBasedEntitlements = useMemo18(() => {
20265
20484
  const changedUsageBasedEntitlements = [];
20266
20485
  const allSelectedUsageBasedEntitlements = [
@@ -20354,6 +20573,14 @@ var SubscriptionSidebar = forwardRef7(
20354
20573
  () => promoCode && (amountOff > 0 || percentOff > 0),
20355
20574
  [promoCode, amountOff, percentOff]
20356
20575
  );
20576
+ const subscriptionDiscount = useMemo18(
20577
+ () => getSubscriptionDiscount(
20578
+ charges?.discounts,
20579
+ subscriptionTotal,
20580
+ subscriptionCurrency
20581
+ ),
20582
+ [charges?.discounts, subscriptionTotal, subscriptionCurrency]
20583
+ );
20357
20584
  const handleCheckout = useCallback10(async () => {
20358
20585
  const planId = selectedPlan?.id;
20359
20586
  const currencyPrice = selectedPlan ? getPlanPrice(
@@ -20600,6 +20827,16 @@ var SubscriptionSidebar = forwardRef7(
20600
20827
  if (isSelectedPlanTrialable && selectedPlan.trialDays) {
20601
20828
  trialEndsOn.setDate(trialEndsOn.getDate() + selectedPlan.trialDays);
20602
20829
  }
20830
+ const billingPreviewText = getBillingPreviewText(
20831
+ {
20832
+ subscriptionPrice,
20833
+ planPeriod,
20834
+ periodStart: renewDate,
20835
+ hasUsageBasedCosts: usageBasedEntitlements.length > 0,
20836
+ discount: subscriptionDiscount
20837
+ },
20838
+ t3
20839
+ );
20603
20840
  return /* @__PURE__ */ jsxs29(
20604
20841
  Flex,
20605
20842
  {
@@ -21148,9 +21385,7 @@ var SubscriptionSidebar = forwardRef7(
21148
21385
  }
21149
21386
  )
21150
21387
  }
21151
- ) : subscriptionPrice && // TODO: localize
21152
- `You will be billed ${subscriptionPrice} ${usageBasedEntitlements.length > 0 ? "plus usage based costs" : ""} for this subscription
21153
- every ${planPeriod} ${periodStart ? `on the ${formatOrdinal(periodStart.getDate())}` : ""} ${planPeriod === "year" && periodStart ? `of ${getMonthName(periodStart)}` : ""} unless you unsubscribe.` }) })
21388
+ ) : billingPreviewText }) })
21154
21389
  ]
21155
21390
  }
21156
21391
  )
@@ -21670,7 +21905,8 @@ var UsageDetails = ({ entitlement, layout }) => {
21670
21905
  metricResetAt
21671
21906
  } = entitlement;
21672
21907
  const { t: t3 } = useTranslation();
21673
- const { data } = useEmbed();
21908
+ const { data, warningThresholdConfig } = useEmbed();
21909
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
21674
21910
  const period = getSubscriptionPeriod(data?.company?.billingSubscription) ?? data?.company?.plan?.planPeriod ?? void 0;
21675
21911
  const showCredits = data?.displaySettings?.showCredits ?? true;
21676
21912
  const {
@@ -21686,7 +21922,9 @@ var UsageDetails = ({ entitlement, layout }) => {
21686
21922
  } = useMemo21(() => {
21687
21923
  const { billingPrice, amount, limit: limit2, cost: cost2, currentTier: currentTier2 } = getUsageDetails(
21688
21924
  entitlement,
21689
- period
21925
+ period,
21926
+ void 0,
21927
+ { showWarningThresholdAsLimit }
21690
21928
  );
21691
21929
  const {
21692
21930
  price: price2,
@@ -21707,7 +21945,7 @@ var UsageDetails = ({ entitlement, layout }) => {
21707
21945
  tiersMode: tiersMode2,
21708
21946
  tiered: priceBehavior === EntitlementPriceBehavior.PayInAdvance && isTieredPrice(billingPrice)
21709
21947
  };
21710
- }, [entitlement, period, priceBehavior]);
21948
+ }, [entitlement, period, priceBehavior, showWarningThresholdAsLimit]);
21711
21949
  const text = useMemo21(() => {
21712
21950
  if (!feature || feature.featureType !== FeatureType.Event && feature.featureType !== FeatureType.Trait) {
21713
21951
  return;
@@ -21757,9 +21995,10 @@ var UsageDetails = ({ entitlement, layout }) => {
21757
21995
  });
21758
21996
  }
21759
21997
  if (!priceBehavior && typeof allocation === "number") {
21998
+ const numericLimit = limit ?? allocation;
21760
21999
  return t3("X units", {
21761
- amount: formatNumber(allocation),
21762
- units: getFeatureName(feature, allocation)
22000
+ amount: formatNumber(numericLimit),
22001
+ units: getFeatureName(feature, numericLimit)
21763
22002
  });
21764
22003
  }
21765
22004
  if (!priceBehavior && allocationType === "unlimited") {
@@ -21845,7 +22084,7 @@ var UsageDetails = ({ entitlement, layout }) => {
21845
22084
  if (typeof usage === "number") {
21846
22085
  return typeof allocation === "number" ? t3("usage.limited", {
21847
22086
  amount: formatNumber(usage),
21848
- allocation: formatNumber(allocation)
22087
+ allocation: formatNumber(limit ?? allocation)
21849
22088
  }) : t3("usage.unlimited", {
21850
22089
  amount: formatNumber(usage)
21851
22090
  });
@@ -21859,6 +22098,7 @@ var UsageDetails = ({ entitlement, layout }) => {
21859
22098
  priceBehavior,
21860
22099
  packageSize,
21861
22100
  allocation,
22101
+ limit,
21862
22102
  usage,
21863
22103
  metricResetAt,
21864
22104
  cost,
@@ -22290,7 +22530,12 @@ import { forwardRef as forwardRef12, useCallback as useCallback13, useMemo as us
22290
22530
  import { jsx as jsx50 } from "react/jsx-runtime";
22291
22531
  var Meter = ({ entitlement }) => {
22292
22532
  const { allocation, priceBehavior, softLimit, usage } = entitlement;
22293
- const limit = softLimit ?? allocation;
22533
+ const { warningThresholdConfig } = useEmbed();
22534
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
22535
+ const warningThreshold = getEntitlementWarningThreshold(
22536
+ entitlement.planEntitlement?.warningTiers
22537
+ );
22538
+ const limit = showWarningThresholdAsLimit && typeof warningThreshold === "number" ? warningThreshold : softLimit ?? allocation;
22294
22539
  if (typeof usage !== "number" || typeof limit !== "number") {
22295
22540
  return null;
22296
22541
  }
@@ -22429,14 +22674,7 @@ import { Fragment as Fragment22, jsx as jsx52, jsxs as jsxs38 } from "react/jsx-
22429
22674
  var Limit = ({ entitlement, usageDetails, fontStyle }) => {
22430
22675
  const { t: t3 } = useTranslation();
22431
22676
  const { data } = useEmbed();
22432
- const {
22433
- feature,
22434
- planEntitlement,
22435
- priceBehavior,
22436
- allocation,
22437
- usage,
22438
- metricResetAt
22439
- } = entitlement;
22677
+ const { feature, planEntitlement, priceBehavior, usage, metricResetAt } = entitlement;
22440
22678
  const { billingPrice, limit, cost, currentTier } = usageDetails;
22441
22679
  const acc = [];
22442
22680
  acc.push(
@@ -22458,8 +22696,8 @@ var Limit = ({ entitlement, usageDetails, fontStyle }) => {
22458
22696
  }) : priceBehavior === EntitlementPriceBehavior.CreditBurndown && typeof feature !== "undefined" && typeof limit === "number" ? t3("X units remaining", {
22459
22697
  amount: formatNumber(limit),
22460
22698
  units: getFeatureName(feature, limit)
22461
- }) : typeof allocation === "number" ? t3("Limit of", {
22462
- amount: formatNumber(allocation)
22699
+ }) : typeof limit === "number" ? t3("Limit of", {
22700
+ amount: formatNumber(limit)
22463
22701
  }) : t3("No limit")
22464
22702
  );
22465
22703
  if (metricResetAt) {
@@ -22514,7 +22752,8 @@ var MeteredFeatures = forwardRef12(({ className, ...rest }, ref) => {
22514
22752
  const elementsRef = useRef12([]);
22515
22753
  const shouldWrapChildren = useWrapChildren(elementsRef);
22516
22754
  const { t: t3 } = useTranslation();
22517
- const { data, settings, setCheckoutState } = useEmbed();
22755
+ const { data, settings, setCheckoutState, warningThresholdConfig } = useEmbed();
22756
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
22518
22757
  const isLightBackground = useIsLightBackground();
22519
22758
  const meteredFeatures = useMemo23(() => {
22520
22759
  const orderedFeatureUsage = props.visibleFeatures?.reduce(
@@ -22568,7 +22807,9 @@ var MeteredFeatures = forwardRef12(({ className, ...rest }, ref) => {
22568
22807
  return acc;
22569
22808
  }
22570
22809
  const { feature, priceBehavior, usage } = entitlement;
22571
- const usageDetails = getUsageDetails(entitlement, period);
22810
+ const usageDetails = getUsageDetails(entitlement, period, void 0, {
22811
+ showWarningThresholdAsLimit
22812
+ });
22572
22813
  const { limit } = usageDetails;
22573
22814
  acc.push(
22574
22815
  /* @__PURE__ */ jsxs38(Element, { as: Flex, $flexDirection: "column", $gap: "1.5rem", children: [
@@ -23186,7 +23427,7 @@ var registerWrapper = function registerWrapper2(stripe, startTime) {
23186
23427
  }
23187
23428
  stripe._registerWrapper({
23188
23429
  name: "stripe-js",
23189
- version: "9.9.0",
23430
+ version: "9.12.0",
23190
23431
  startTime
23191
23432
  });
23192
23433
  };
@@ -23264,7 +23505,7 @@ var initStripe = function initStripe2(maybeStripe, args, startTime) {
23264
23505
  var version = runtimeVersionToUrlVersion(maybeStripe.version);
23265
23506
  var expectedVersion = RELEASE_TRAIN;
23266
23507
  if (isTestKey && version !== expectedVersion) {
23267
- 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"));
23508
+ 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"));
23268
23509
  }
23269
23510
  var stripe = maybeStripe.apply(void 0, args);
23270
23511
  registerWrapper(stripe, startTime);
@@ -23678,14 +23919,17 @@ var UsageDetails2 = ({
23678
23919
  layout
23679
23920
  }) => {
23680
23921
  const { t: t3 } = useTranslation();
23681
- const { settings } = useEmbed();
23922
+ const { settings, warningThresholdConfig } = useEmbed();
23923
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
23682
23924
  const {
23683
23925
  billingPrice,
23684
23926
  limit,
23685
23927
  cost = 0
23686
23928
  } = useMemo27(
23687
- () => getUsageDetails(entitlement, period, currency),
23688
- [entitlement, period, currency]
23929
+ () => getUsageDetails(entitlement, period, currency, {
23930
+ showWarningThresholdAsLimit
23931
+ }),
23932
+ [entitlement, period, currency, showWarningThresholdAsLimit]
23689
23933
  );
23690
23934
  const description = useMemo27(() => {
23691
23935
  const acc = [];
@@ -24454,7 +24698,8 @@ var AddOn2 = ({
24454
24698
  }) => {
24455
24699
  const { layout } = sharedProps;
24456
24700
  const { t: t3 } = useTranslation();
24457
- const { data, settings, setCheckoutState } = useEmbed();
24701
+ const { data, settings, setCheckoutState, warningThresholdConfig } = useEmbed();
24702
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
24458
24703
  const isLightBackground = useIsLightBackground();
24459
24704
  const { currentAddOns, canCheckout, isStandalone } = useMemo29(() => {
24460
24705
  const isStandalone2 = typeof data?.component === "undefined";
@@ -24483,12 +24728,16 @@ var AddOn2 = ({
24483
24728
  selectedPeriod,
24484
24729
  currency
24485
24730
  );
24731
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
24486
24732
  return {
24487
24733
  isUnlimited: false,
24488
24734
  featureName: entitlement.feature?.name,
24489
24735
  feature: entitlement.feature,
24490
24736
  priceBehavior: entitlement.priceBehavior,
24491
24737
  softLimit: entitlement.softLimit,
24738
+ // The limit shown next to the feature: the warning threshold when the
24739
+ // option is on and one is configured, else the overage soft limit.
24740
+ limit: typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage ? entitlement.softLimit : void 0,
24492
24741
  price: priceData?.price ?? 0,
24493
24742
  currency: priceData?.currency || addOnCurrency,
24494
24743
  packageSize: priceData?.packageSize ?? 1,
@@ -24658,7 +24907,7 @@ var AddOn2 = ({
24658
24907
  rounded: true
24659
24908
  }
24660
24909
  ),
24661
- /* @__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) }) })
24910
+ /* @__PURE__ */ jsx59(Flex, { $flexDirection: "column", $justifyContent: "center", children: /* @__PURE__ */ jsx59(Text, { children: typeof meteredEntitlement.limit === "number" ? `${meteredEntitlement.limit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) }) })
24662
24911
  ] }),
24663
24912
  /* @__PURE__ */ jsx59(
24664
24913
  Text,
@@ -24729,7 +24978,8 @@ var Entitlement2 = ({
24729
24978
  }) => {
24730
24979
  const { layout } = sharedProps;
24731
24980
  const { t: t3 } = useTranslation();
24732
- const { settings } = useEmbed();
24981
+ const { settings, warningThresholdConfig } = useEmbed();
24982
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
24733
24983
  const isLightBackground = useIsLightBackground();
24734
24984
  const entitlementBillingPrice = getEntitlementPrice(
24735
24985
  entitlement,
@@ -24744,7 +24994,8 @@ var Entitlement2 = ({
24744
24994
  tiersMode: entitlementTiersMode
24745
24995
  } = entitlementBillingPrice || {};
24746
24996
  const tiered = entitlement.priceBehavior === EntitlementPriceBehavior.PayInAdvance && isTieredPrice(entitlementBillingPrice);
24747
- const limit = entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
24997
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
24998
+ const limit = typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
24748
24999
  const metricPeriodName = getMetricPeriodName(entitlement);
24749
25000
  const creditBasedEntitlementLimit = getCreditBasedEntitlementLimit(
24750
25001
  entitlement,
@@ -25634,20 +25885,27 @@ function resolveDesignProps11(props) {
25634
25885
  var UpcomingBill = forwardRef18(({ className, ...rest }, ref) => {
25635
25886
  const props = resolveDesignProps11(rest);
25636
25887
  const { t: t3 } = useTranslation();
25637
- const { data, settings, debug, getUpcomingInvoice, getCustomerBalance } = useEmbed();
25888
+ const { data, settings, getUpcomingInvoice } = useEmbed();
25638
25889
  const isLightBackground = useIsLightBackground();
25639
25890
  const [isLoading, setIsLoading] = useState22(false);
25640
25891
  const [error, setError] = useState22();
25641
25892
  const [upcomingInvoice, setUpcomingInvoice] = useState22(data?.upcomingInvoice);
25642
- const [balances, setBalances] = useState22([]);
25643
25893
  const discounts = useMemo32(() => {
25644
- return (data?.subscription?.discounts || []).map((discount) => ({
25894
+ return (data?.subscription?.discounts || []).filter(
25895
+ (discount) => (
25896
+ // Only surface discounts that are currently active and actually
25897
+ // reduce the bill; the API computes `isActive` at read time, so an
25898
+ // expired coupon must not linger in the account summary.
25899
+ discount.isActive && (typeof discount.percentOff === "number" && discount.percentOff > 0 || typeof discount.amountOff === "number" && discount.amountOff > 0)
25900
+ )
25901
+ ).map((discount) => ({
25645
25902
  couponId: discount.couponId,
25646
25903
  customerFacingCode: discount.customerFacingCode || void 0,
25647
25904
  currency: discount.currency || void 0,
25648
25905
  amountOff: discount.amountOff ?? void 0,
25649
25906
  percentOff: discount.percentOff ?? void 0,
25650
- isActive: discount.isActive
25907
+ duration: discount.duration,
25908
+ durationInMonths: discount.durationInMonths ?? void 0
25651
25909
  }));
25652
25910
  }, [data?.subscription?.discounts]);
25653
25911
  const getInvoice = useCallback16(async () => {
@@ -25666,27 +25924,30 @@ var UpcomingBill = forwardRef18(({ className, ...rest }, ref) => {
25666
25924
  }
25667
25925
  }
25668
25926
  }, [data?.component?.id, data?.subscription, getUpcomingInvoice]);
25669
- const getBalances = useCallback16(async () => {
25670
- try {
25671
- const response = await getCustomerBalance();
25672
- if (response) {
25673
- setBalances(response.data.balances);
25674
- }
25675
- } catch (err) {
25676
- debug("Failed to fetch customer balance.", err);
25677
- }
25678
- }, [debug, getCustomerBalance]);
25679
25927
  useEffect9(() => {
25680
25928
  getInvoice();
25681
25929
  }, [getInvoice]);
25682
- useEffect9(() => {
25683
- getBalances();
25684
- }, [getBalances]);
25685
25930
  useEffect9(() => {
25686
25931
  if (data?.upcomingInvoice) {
25687
25932
  setUpcomingInvoice(data.upcomingInvoice);
25688
25933
  }
25689
25934
  }, [data?.upcomingInvoice]);
25935
+ const { currency, applied, remaining } = useMemo32(() => {
25936
+ const currency2 = upcomingInvoice?.currency;
25937
+ const startingBalance = upcomingInvoice?.startingBalance ?? 0;
25938
+ const endingBalance = upcomingInvoice?.endingBalance ?? 0;
25939
+ const credit = Math.max(0, -startingBalance);
25940
+ const subtotal = Math.max(0, upcomingInvoice?.subtotal ?? 0);
25941
+ const applied2 = endingBalance < 0 ? credit + endingBalance : Math.min(credit, subtotal);
25942
+ return { currency: currency2, applied: applied2, remaining: credit - applied2 };
25943
+ }, [
25944
+ upcomingInvoice?.currency,
25945
+ upcomingInvoice?.startingBalance,
25946
+ upcomingInvoice?.endingBalance,
25947
+ upcomingInvoice?.subtotal
25948
+ ]);
25949
+ const hasApplied = applied > 0;
25950
+ const hasBalance = remaining > 0 || applied > 0;
25690
25951
  if (!data?.subscription || data.subscription.cancelAt) {
25691
25952
  return null;
25692
25953
  }
@@ -25736,7 +25997,7 @@ var UpcomingBill = forwardRef18(({ className, ...rest }, ref) => {
25736
25997
  ]
25737
25998
  }
25738
25999
  ),
25739
- balances.length > 0 && /* @__PURE__ */ jsxs48(
26000
+ hasApplied && /* @__PURE__ */ jsxs48(
25740
26001
  Flex,
25741
26002
  {
25742
26003
  as: TransitionBox,
@@ -25744,8 +26005,21 @@ var UpcomingBill = forwardRef18(({ className, ...rest }, ref) => {
25744
26005
  $alignItems: "start",
25745
26006
  $gap: "1rem",
25746
26007
  children: [
25747
- /* @__PURE__ */ jsx65(Text, { $weight: 600, children: t3("Remaining balance") }),
25748
- /* @__PURE__ */ jsx65(Flex, { $flexDirection: "column", $gap: "0.5rem", children: balances.map((item, idx) => /* @__PURE__ */ jsx65(Text, { children: formatCurrency(item.balance, item.currency) }, idx)) })
26008
+ /* @__PURE__ */ jsx65(Text, { $weight: 600, children: t3("Applied balance towards next invoice") }),
26009
+ /* @__PURE__ */ jsx65(Text, { children: formatCurrency(-applied, currency) })
26010
+ ]
26011
+ }
26012
+ ),
26013
+ hasBalance && /* @__PURE__ */ jsxs48(
26014
+ Flex,
26015
+ {
26016
+ as: TransitionBox,
26017
+ $justifyContent: "space-between",
26018
+ $alignItems: "start",
26019
+ $gap: "1rem",
26020
+ children: [
26021
+ /* @__PURE__ */ jsx65(Text, { $weight: 600, children: t3("Remaining balance after next invoice") }),
26022
+ /* @__PURE__ */ jsx65(Text, { children: formatCurrency(remaining, currency) })
25749
26023
  ]
25750
26024
  }
25751
26025
  ),
@@ -25763,54 +26037,50 @@ var UpcomingBill = forwardRef18(({ className, ...rest }, ref) => {
25763
26037
  $flexDirection: "column",
25764
26038
  $alignItems: "end",
25765
26039
  $gap: "0.5rem",
25766
- children: discounts.reduce(
25767
- (acc, discount) => {
25768
- if (typeof discount.percentOff === "number" || typeof discount.amountOff === "number") {
25769
- acc.push(
25770
- /* @__PURE__ */ jsxs48(
26040
+ children: discounts.map((discount) => {
26041
+ const label = typeof discount.percentOff === "number" && discount.percentOff > 0 ? t3("Percent off", {
26042
+ percent: discount.percentOff
26043
+ }) : t3("Amount off", {
26044
+ amount: formatCurrency(
26045
+ discount.amountOff,
26046
+ // active discounts always carry a positive amount or percent
26047
+ discount?.currency
26048
+ )
26049
+ });
26050
+ return /* @__PURE__ */ jsxs48(
26051
+ Flex,
26052
+ {
26053
+ $alignItems: "center",
26054
+ $gap: "0.5rem",
26055
+ children: [
26056
+ discount.customerFacingCode && /* @__PURE__ */ jsx65(
25771
26057
  Flex,
25772
26058
  {
25773
26059
  $alignItems: "center",
25774
- $gap: "0.5rem",
25775
- children: [
25776
- discount.customerFacingCode && /* @__PURE__ */ jsx65(
25777
- Flex,
25778
- {
25779
- $alignItems: "center",
25780
- $padding: "0.1875rem 0.375rem",
25781
- $borderWidth: "1px",
25782
- $borderStyle: "solid",
25783
- $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.15)" : "hsla(0, 0%, 100%, 0.15)",
25784
- $borderRadius: "0.3125rem",
25785
- children: /* @__PURE__ */ jsx65(
25786
- Text,
25787
- {
25788
- $size: 0.75 * settings.theme.typography.text.fontSize,
25789
- style: { textTransform: "uppercase" },
25790
- children: discount.customerFacingCode
25791
- }
25792
- )
25793
- }
25794
- ),
25795
- /* @__PURE__ */ jsx65(Box, { children: /* @__PURE__ */ jsx65(Text, { children: typeof discount.percentOff === "number" ? t3("Percent off", {
25796
- percent: discount.percentOff
25797
- }) : t3("Amount off", {
25798
- amount: formatCurrency(
25799
- discount.amountOff,
25800
- // we already checked for `number` type
25801
- discount?.currency
25802
- )
25803
- }) }) })
25804
- ]
25805
- },
25806
- discount.couponId
25807
- )
25808
- );
25809
- }
25810
- return acc;
25811
- },
25812
- []
25813
- )
26060
+ $padding: "0.1875rem 0.375rem",
26061
+ $borderWidth: "1px",
26062
+ $borderStyle: "solid",
26063
+ $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.15)" : "hsla(0, 0%, 100%, 0.15)",
26064
+ $borderRadius: "0.3125rem",
26065
+ children: /* @__PURE__ */ jsx65(
26066
+ Text,
26067
+ {
26068
+ $size: 0.75 * settings.theme.typography.text.fontSize,
26069
+ style: { textTransform: "uppercase" },
26070
+ children: discount.customerFacingCode
26071
+ }
26072
+ )
26073
+ }
26074
+ ),
26075
+ /* @__PURE__ */ jsx65(Box, { children: /* @__PURE__ */ jsx65(Text, { children: discount.duration === "repeating" && discount.durationInMonths ? t3("Discount for months", {
26076
+ discount: label,
26077
+ count: discount.durationInMonths
26078
+ }) : label }) })
26079
+ ]
26080
+ },
26081
+ discount.couponId
26082
+ );
26083
+ })
25814
26084
  }
25815
26085
  )
25816
26086
  ]