@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.
@@ -2927,7 +2927,10 @@ var Translator = class _Translator extends EventEmitter {
2927
2927
  const useOptionsReplaceForData = options.replace && !isString(options.replace);
2928
2928
  let data = useOptionsReplaceForData ? options.replace : options;
2929
2929
  if (useOptionsReplaceForData && typeof options.count !== "undefined") {
2930
- data.count = options.count;
2930
+ data = {
2931
+ ...data,
2932
+ count: options.count
2933
+ };
2931
2934
  }
2932
2935
  if (this.options.interpolation.defaultVariables) {
2933
2936
  data = {
@@ -3238,10 +3241,10 @@ var Interpolator = class {
3238
3241
  const skipOnVariables = options?.interpolation?.skipOnVariables !== void 0 ? options.interpolation.skipOnVariables : this.options.interpolation.skipOnVariables;
3239
3242
  const todos = [{
3240
3243
  regex: this.regexpUnescape,
3241
- safeValue: (val) => regexSafe(val)
3244
+ safeValue: (val) => val
3242
3245
  }, {
3243
3246
  regex: this.regexp,
3244
- safeValue: (val) => this.escapeValue ? regexSafe(this.escape(val)) : regexSafe(val)
3247
+ safeValue: (val) => this.escapeValue ? this.escape(val) : val
3245
3248
  }];
3246
3249
  todos.forEach((todo) => {
3247
3250
  replaces = 0;
@@ -3265,9 +3268,9 @@ var Interpolator = class {
3265
3268
  value = makeString(value);
3266
3269
  }
3267
3270
  const safeValue = todo.safeValue(value);
3268
- str = str.replace(match2[0], safeValue);
3271
+ str = str.replace(match2[0], regexSafe(safeValue));
3269
3272
  if (skipOnVariables) {
3270
- todo.regex.lastIndex += value.length;
3273
+ todo.regex.lastIndex += safeValue.length;
3271
3274
  todo.regex.lastIndex -= match2[0].length;
3272
3275
  } else {
3273
3276
  todo.regex.lastIndex = 0;
@@ -3317,7 +3320,7 @@ var Interpolator = class {
3317
3320
  clonedOptions = clonedOptions.replace && !isString(clonedOptions.replace) ? clonedOptions.replace : clonedOptions;
3318
3321
  clonedOptions.applyPostProcessor = false;
3319
3322
  delete clonedOptions.defaultValue;
3320
- const keyEndIndex = /{.*}/.test(match2[1]) ? match2[1].lastIndexOf("}") + 1 : match2[1].indexOf(this.formatSeparator);
3323
+ const keyEndIndex = /{.*}/s.test(match2[1]) ? match2[1].lastIndexOf("}") + 1 : match2[1].indexOf(this.formatSeparator);
3321
3324
  if (keyEndIndex !== -1) {
3322
3325
  formatters = match2[1].slice(keyEndIndex).split(this.formatSeparator).map((elem) => elem.trim()).filter(Boolean);
3323
3326
  match2[1] = match2[1].slice(0, keyEndIndex);
@@ -5049,6 +5052,9 @@ var en_default = {
5049
5052
  "After the trial, subscribe": "After the trial, subscription starts and you will be billed.",
5050
5053
  Agreement: "Agreement",
5051
5054
  "Amount off": "{{amount}} off",
5055
+ "Applied balance towards next invoice": "Applied balance towards next invoice",
5056
+ "Discount for months_one": "{{discount}} for next month",
5057
+ "Discount for months_other": "{{discount}} for next {{count}} months",
5052
5058
  "Auto Top-up": "Auto top-up",
5053
5059
  "Auto top-up enabled": "Auto top-up enabled",
5054
5060
  "Auto top-up disabled": "Auto top-up disabled",
@@ -5144,7 +5150,7 @@ var en_default = {
5144
5150
  Proration: "Proration",
5145
5151
  Quantity: "Quantity",
5146
5152
  "Quantity to pay for in advance": "Quantity to pay for in advance",
5147
- "Remaining balance": "Remaining balance",
5153
+ "Remaining balance after next invoice": "Remaining balance after next invoice",
5148
5154
  Remove: "Remove",
5149
5155
  "Remove add-on": "Remove add-on",
5150
5156
  Resets: "Resets {{date}}",
@@ -5219,6 +5225,14 @@ var en_default = {
5219
5225
  "X units per use": "{{amount}} {{units}} per use",
5220
5226
  "X time left in trial": "{{amount}} {{units}} left in trial",
5221
5227
  "Yearly total": "Yearly total",
5228
+ "You will be billed": "You will be billed {{price}} {{usage}}for this subscription every {{period}} {{schedule}}unless you unsubscribe.",
5229
+ "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.",
5230
+ "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.",
5231
+ "plus usage based costs": "plus usage based costs",
5232
+ "on the day": "on the {{day}}",
5233
+ "of month": "of {{month}}",
5234
+ "for the next months_one": "for the next month",
5235
+ "for the next months_other": "for the next {{count}} months",
5222
5236
  "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}}.",
5223
5237
  "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",
5224
5238
  "$X per unit": "{{cost}} per {{unit}}",
@@ -5906,7 +5920,7 @@ var i;
5906
5920
  var c = "undefined" != typeof process && void 0 !== process.env && (process.env.REACT_APP_SC_ATTR || process.env.SC_ATTR) || "data-styled";
5907
5921
  var a = "active";
5908
5922
  var l = "data-styled-version";
5909
- var u = "6.4.3";
5923
+ var u = "6.4.4";
5910
5924
  var h = "/*!sc*/\n";
5911
5925
  var d = "undefined" != typeof window && "undefined" != typeof document;
5912
5926
  function p(e2) {
@@ -7832,11 +7846,13 @@ function InvoiceResponseDataFromJSONTyped(json, ignoreDiscriminator) {
7832
7846
  currency: json["currency"],
7833
7847
  customerExternalId: json["customer_external_id"],
7834
7848
  dueDate: json["due_date"] == null ? void 0 : new Date(json["due_date"]),
7849
+ endingBalance: json["ending_balance"],
7835
7850
  environmentId: json["environment_id"],
7836
7851
  externalId: json["external_id"] == null ? void 0 : json["external_id"],
7837
7852
  id: json["id"],
7838
7853
  paymentMethodExternalId: json["payment_method_external_id"] == null ? void 0 : json["payment_method_external_id"],
7839
7854
  providerType: BillingProviderTypeFromJSON(json["provider_type"]),
7855
+ startingBalance: json["starting_balance"],
7840
7856
  status: json["status"] == null ? void 0 : InvoiceStatusFromJSON(json["status"]),
7841
7857
  subscriptionExternalId: json["subscription_external_id"] == null ? void 0 : json["subscription_external_id"],
7842
7858
  subtotal: json["subtotal"],
@@ -8312,6 +8328,20 @@ function EntitlementValueTypeFromJSONTyped(json, ignoreDiscriminator) {
8312
8328
  return json;
8313
8329
  }
8314
8330
 
8331
+ // src/api/checkoutexternal/models/WarningTier.ts
8332
+ function WarningTierFromJSON(json) {
8333
+ return WarningTierFromJSONTyped(json, false);
8334
+ }
8335
+ function WarningTierFromJSONTyped(json, ignoreDiscriminator) {
8336
+ if (json == null) {
8337
+ return json;
8338
+ }
8339
+ return {
8340
+ key: json["key"],
8341
+ value: json["value"]
8342
+ };
8343
+ }
8344
+
8315
8345
  // src/api/checkoutexternal/models/FeatureEntitlement.ts
8316
8346
  function FeatureEntitlementFromJSON(json) {
8317
8347
  return FeatureEntitlementFromJSONTyped(json, false);
@@ -8338,7 +8368,8 @@ function FeatureEntitlementFromJSONTyped(json, ignoreDiscriminator) {
8338
8368
  monthReset: json["month_reset"] == null ? void 0 : MetricPeriodMonthResetFromJSON(json["month_reset"]),
8339
8369
  softLimit: json["soft_limit"] == null ? void 0 : json["soft_limit"],
8340
8370
  usage: json["usage"] == null ? void 0 : json["usage"],
8341
- valueType: EntitlementValueTypeFromJSON(json["value_type"])
8371
+ valueType: EntitlementValueTypeFromJSON(json["value_type"]),
8372
+ warningTiers: json["warning_tiers"] == null ? void 0 : json["warning_tiers"].map(WarningTierFromJSON)
8342
8373
  };
8343
8374
  }
8344
8375
 
@@ -8685,6 +8716,7 @@ function CompanyOverrideNoteResponseDataFromJSONTyped(json, ignoreDiscriminator)
8685
8716
  var FeatureType = {
8686
8717
  Boolean: "boolean",
8687
8718
  Event: "event",
8719
+ License: "license",
8688
8720
  Trait: "trait"
8689
8721
  };
8690
8722
  function FeatureTypeFromJSON(json) {
@@ -8717,13 +8749,15 @@ function FeatureResponseDataFromJSONTyped(json, ignoreDiscriminator) {
8717
8749
  featureType: FeatureTypeFromJSON(json["feature_type"]),
8718
8750
  icon: json["icon"],
8719
8751
  id: json["id"],
8752
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
8720
8753
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON(json["lifecycle_phase"]),
8721
8754
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
8722
8755
  name: json["name"],
8723
8756
  pluralName: json["plural_name"] == null ? void 0 : json["plural_name"],
8724
8757
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
8725
8758
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
8726
- updatedAt: new Date(json["updated_at"])
8759
+ updatedAt: new Date(json["updated_at"]),
8760
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
8727
8761
  };
8728
8762
  }
8729
8763
 
@@ -9075,6 +9109,7 @@ function FeatureInPlanResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9075
9109
  flags: json["flags"].map(FlagInPlanResponseDataFromJSON),
9076
9110
  icon: json["icon"],
9077
9111
  id: json["id"],
9112
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
9078
9113
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON(json["lifecycle_phase"]),
9079
9114
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
9080
9115
  name: json["name"],
@@ -9083,7 +9118,8 @@ function FeatureInPlanResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9083
9118
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
9084
9119
  trait: json["trait"] == null ? void 0 : EntityTraitDefinitionResponseDataFromJSON(json["trait"]),
9085
9120
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
9086
- updatedAt: new Date(json["updated_at"])
9121
+ updatedAt: new Date(json["updated_at"]),
9122
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
9087
9123
  };
9088
9124
  }
9089
9125
 
@@ -9160,6 +9196,20 @@ function PlanCreditGrantViewFromJSONTyped(json, ignoreDiscriminator) {
9160
9196
  };
9161
9197
  }
9162
9198
 
9199
+ // src/api/checkoutexternal/models/PlanCatalogMembershipResponseData.ts
9200
+ function PlanCatalogMembershipResponseDataFromJSON(json) {
9201
+ return PlanCatalogMembershipResponseDataFromJSONTyped(json, false);
9202
+ }
9203
+ function PlanCatalogMembershipResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9204
+ if (json == null) {
9205
+ return json;
9206
+ }
9207
+ return {
9208
+ id: json["id"],
9209
+ name: json["name"]
9210
+ };
9211
+ }
9212
+
9163
9213
  // src/api/checkoutexternal/models/PlanCurrencyPricesResponseData.ts
9164
9214
  function PlanCurrencyPricesResponseDataFromJSON(json) {
9165
9215
  return PlanCurrencyPricesResponseDataFromJSONTyped(json, false);
@@ -9316,6 +9366,9 @@ function CompanyPlanDetailResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9316
9366
  ),
9317
9367
  billingProduct: json["billing_product"] == null ? void 0 : BillingProductDetailResponseDataFromJSON(json["billing_product"]),
9318
9368
  billingStrategy: BillingStrategyFromJSON(json["billing_strategy"]),
9369
+ catalogs: json["catalogs"] == null ? void 0 : json["catalogs"].map(
9370
+ PlanCatalogMembershipResponseDataFromJSON
9371
+ ),
9319
9372
  chargeType: ChargeTypeFromJSON(json["charge_type"]),
9320
9373
  companyCanTrial: json["company_can_trial"],
9321
9374
  companyCount: json["company_count"],
@@ -9489,6 +9542,9 @@ function PlanDetailResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9489
9542
  ),
9490
9543
  billingProduct: json["billing_product"] == null ? void 0 : BillingProductDetailResponseDataFromJSON(json["billing_product"]),
9491
9544
  billingStrategy: BillingStrategyFromJSON(json["billing_strategy"]),
9545
+ catalogs: json["catalogs"] == null ? void 0 : json["catalogs"].map(
9546
+ PlanCatalogMembershipResponseDataFromJSON
9547
+ ),
9492
9548
  chargeType: ChargeTypeFromJSON(json["charge_type"]),
9493
9549
  companyCount: json["company_count"],
9494
9550
  companyId: json["company_id"] == null ? void 0 : json["company_id"],
@@ -9658,6 +9714,7 @@ function ComponentResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9658
9714
  }
9659
9715
  return {
9660
9716
  ast: json["ast"] == null ? void 0 : json["ast"],
9717
+ catalogId: json["catalog_id"] == null ? void 0 : json["catalog_id"],
9661
9718
  createdAt: new Date(json["created_at"]),
9662
9719
  id: json["id"],
9663
9720
  name: json["name"],
@@ -9894,6 +9951,29 @@ function PreviewSubscriptionUpcomingInvoiceLineItemsFromJSONTyped(json, ignoreDi
9894
9951
  };
9895
9952
  }
9896
9953
 
9954
+ // src/api/checkoutexternal/models/PreviewSubscriptionDiscountResponseData.ts
9955
+ function PreviewSubscriptionDiscountResponseDataFromJSON(json) {
9956
+ return PreviewSubscriptionDiscountResponseDataFromJSONTyped(json, false);
9957
+ }
9958
+ function PreviewSubscriptionDiscountResponseDataFromJSONTyped(json, ignoreDiscriminator) {
9959
+ if (json == null) {
9960
+ return json;
9961
+ }
9962
+ return {
9963
+ amountOff: json["amount_off"] == null ? void 0 : json["amount_off"],
9964
+ couponName: json["coupon_name"],
9965
+ currency: json["currency"] == null ? void 0 : json["currency"],
9966
+ customerFacingCode: json["customer_facing_code"] == null ? void 0 : json["customer_facing_code"],
9967
+ duration: json["duration"],
9968
+ durationInMonths: json["duration_in_months"] == null ? void 0 : json["duration_in_months"],
9969
+ endedAt: json["ended_at"] == null ? void 0 : new Date(json["ended_at"]),
9970
+ isActive: json["is_active"],
9971
+ percentOff: json["percent_off"] == null ? void 0 : json["percent_off"],
9972
+ promoCodeExternalId: json["promo_code_external_id"] == null ? void 0 : json["promo_code_external_id"],
9973
+ startedAt: new Date(json["started_at"])
9974
+ };
9975
+ }
9976
+
9897
9977
  // src/api/checkoutexternal/models/PreviewSubscriptionFinanceResponseData.ts
9898
9978
  function PreviewSubscriptionFinanceResponseDataFromJSON(json) {
9899
9979
  return PreviewSubscriptionFinanceResponseDataFromJSONTyped(json, false);
@@ -9904,9 +9984,13 @@ function PreviewSubscriptionFinanceResponseDataFromJSONTyped(json, ignoreDiscrim
9904
9984
  }
9905
9985
  return {
9906
9986
  amountOff: json["amount_off"],
9987
+ discounts: json["discounts"].map(
9988
+ PreviewSubscriptionDiscountResponseDataFromJSON
9989
+ ),
9907
9990
  dueNow: json["due_now"],
9908
9991
  newCharges: json["new_charges"],
9909
9992
  percentOff: json["percent_off"],
9993
+ periodEnd: new Date(json["period_end"]),
9910
9994
  periodStart: new Date(json["period_start"]),
9911
9995
  promoCodeApplied: json["promo_code_applied"],
9912
9996
  proration: json["proration"],
@@ -11520,13 +11604,15 @@ function FeatureResponseDataFromJSONTyped5(json, ignoreDiscriminator) {
11520
11604
  featureType: FeatureTypeFromJSON2(json["feature_type"]),
11521
11605
  icon: json["icon"],
11522
11606
  id: json["id"],
11607
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
11523
11608
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON2(json["lifecycle_phase"]),
11524
11609
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
11525
11610
  name: json["name"],
11526
11611
  pluralName: json["plural_name"] == null ? void 0 : json["plural_name"],
11527
11612
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
11528
11613
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
11529
- updatedAt: new Date(json["updated_at"])
11614
+ updatedAt: new Date(json["updated_at"]),
11615
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
11530
11616
  };
11531
11617
  }
11532
11618
 
@@ -11583,6 +11669,7 @@ function FeatureInPlanResponseDataFromJSONTyped6(json, ignoreDiscriminator) {
11583
11669
  flags: json["flags"].map(FlagInPlanResponseDataFromJSON2),
11584
11670
  icon: json["icon"],
11585
11671
  id: json["id"],
11672
+ licenseId: json["license_id"] == null ? void 0 : json["license_id"],
11586
11673
  lifecyclePhase: json["lifecycle_phase"] == null ? void 0 : FeatureLifecyclePhaseFromJSON2(json["lifecycle_phase"]),
11587
11674
  maintainerAccountMemberId: json["maintainer_account_member_id"] == null ? void 0 : json["maintainer_account_member_id"],
11588
11675
  name: json["name"],
@@ -11591,7 +11678,8 @@ function FeatureInPlanResponseDataFromJSONTyped6(json, ignoreDiscriminator) {
11591
11678
  singularName: json["singular_name"] == null ? void 0 : json["singular_name"],
11592
11679
  trait: json["trait"] == null ? void 0 : EntityTraitDefinitionResponseDataFromJSON2(json["trait"]),
11593
11680
  traitId: json["trait_id"] == null ? void 0 : json["trait_id"],
11594
- updatedAt: new Date(json["updated_at"])
11681
+ updatedAt: new Date(json["updated_at"]),
11682
+ usageLimitTraitId: json["usage_limit_trait_id"] == null ? void 0 : json["usage_limit_trait_id"]
11595
11683
  };
11596
11684
  }
11597
11685
 
@@ -11770,6 +11858,20 @@ function PlanCreditGrantViewFromJSONTyped3(json, ignoreDiscriminator) {
11770
11858
  };
11771
11859
  }
11772
11860
 
11861
+ // src/api/componentspublic/models/PlanCatalogMembershipResponseData.ts
11862
+ function PlanCatalogMembershipResponseDataFromJSON2(json) {
11863
+ return PlanCatalogMembershipResponseDataFromJSONTyped5(json, false);
11864
+ }
11865
+ function PlanCatalogMembershipResponseDataFromJSONTyped5(json, ignoreDiscriminator) {
11866
+ if (json == null) {
11867
+ return json;
11868
+ }
11869
+ return {
11870
+ id: json["id"],
11871
+ name: json["name"]
11872
+ };
11873
+ }
11874
+
11773
11875
  // src/api/componentspublic/models/PlanCurrencyPricesResponseData.ts
11774
11876
  function PlanCurrencyPricesResponseDataFromJSON2(json) {
11775
11877
  return PlanCurrencyPricesResponseDataFromJSONTyped5(json, false);
@@ -11837,6 +11939,9 @@ function PlanViewPublicResponseDataFromJSONTyped(json, ignoreDiscriminator) {
11837
11939
  ),
11838
11940
  billingProduct: json["billing_product"] == null ? void 0 : BillingProductDetailResponseDataFromJSON2(json["billing_product"]),
11839
11941
  billingStrategy: BillingStrategyFromJSON2(json["billing_strategy"]),
11942
+ catalogs: json["catalogs"] == null ? void 0 : json["catalogs"].map(
11943
+ PlanCatalogMembershipResponseDataFromJSON2
11944
+ ),
11840
11945
  chargeType: ChargeTypeFromJSON2(json["charge_type"]),
11841
11946
  companyCount: json["company_count"],
11842
11947
  companyId: json["company_id"] == null ? void 0 : json["company_id"],
@@ -12454,7 +12559,7 @@ function getMetricPeriodName(entitlement) {
12454
12559
  const name = period ? PeriodName[period] : void 0;
12455
12560
  return name;
12456
12561
  }
12457
- function getUsageDetails(entitlement, period, currency) {
12562
+ function getUsageDetails(entitlement, period, currency, options) {
12458
12563
  const billingPrice = currency ? getEntitlementPrice(entitlement, period ?? "month", currency) : period === "year" ? entitlement.yearlyUsageBasedPrice : period === "quarter" ? entitlement.quarterlyUsageBasedPrice : period === "month" ? entitlement.monthlyUsageBasedPrice : void 0;
12459
12564
  let limit;
12460
12565
  if ((!entitlement.priceBehavior || entitlement.priceBehavior === EntitlementPriceBehavior.PayInAdvance) && typeof entitlement.allocation === "number") {
@@ -12502,8 +12607,21 @@ function getUsageDetails(entitlement, period, currency) {
12502
12607
  start = end + 1;
12503
12608
  }
12504
12609
  }
12610
+ if (options?.showWarningThresholdAsLimit) {
12611
+ const warningThreshold = getEntitlementWarningThreshold(
12612
+ entitlement.planEntitlement?.warningTiers
12613
+ );
12614
+ if (typeof warningThreshold === "number") {
12615
+ limit = warningThreshold;
12616
+ }
12617
+ }
12505
12618
  return { billingPrice, limit, amount, cost, currentTier };
12506
12619
  }
12620
+ var WARNING_TIER_DEFAULT_KEY = "default";
12621
+ function getEntitlementWarningThreshold(warningTiers) {
12622
+ const tier = warningTiers?.find((t3) => t3?.key === WARNING_TIER_DEFAULT_KEY);
12623
+ return typeof tier?.value === "number" ? tier.value : void 0;
12624
+ }
12507
12625
  function getCreditBasedEntitlementLimit(entitlement, credits) {
12508
12626
  const matchedCredit = credits.find(
12509
12627
  (credit) => credit.id === entitlement.valueCredit?.id
@@ -13051,85 +13169,6 @@ function modifyDate(date, days) {
13051
13169
  return copy3;
13052
13170
  }
13053
13171
 
13054
- // src/utils/error.ts
13055
- function isError(value) {
13056
- return value instanceof Error;
13057
- }
13058
- var ERROR_UNKNOWN = new Error("An unknown error occurred.");
13059
-
13060
- // src/utils/event.ts
13061
- var createKeyboardExecutionHandler = (fn) => {
13062
- const handler = (event) => {
13063
- if (event.key === "Enter" || event.key === " ") {
13064
- event.preventDefault();
13065
- fn?.(event);
13066
- }
13067
- };
13068
- return handler;
13069
- };
13070
-
13071
- // src/utils/markdown.tsx
13072
- var import_react14 = require("react");
13073
- var import_jsx_runtime2 = require("react/jsx-runtime");
13074
- var TOKEN = /(\[[^\]]+\]\([^)\s]+\))|(\*\*[^*]+\*\*)|(\*[^*]+\*)/g;
13075
- var LINK = /^\[([^\]]+)\]\(([^)\s]+)\)$/;
13076
- var isSafeUrl = (url) => {
13077
- try {
13078
- const { protocol } = new URL(url);
13079
- return protocol === "http:" || protocol === "https:";
13080
- } catch {
13081
- return false;
13082
- }
13083
- };
13084
- var renderOptInMarkdown = (text) => {
13085
- if (!text) {
13086
- return null;
13087
- }
13088
- const nodes = [];
13089
- let lastIndex = 0;
13090
- let key = 0;
13091
- TOKEN.lastIndex = 0;
13092
- let match2;
13093
- while ((match2 = TOKEN.exec(text)) !== null) {
13094
- if (match2.index > lastIndex) {
13095
- nodes.push(
13096
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react14.Fragment, { children: text.slice(lastIndex, match2.index) }, key++)
13097
- );
13098
- }
13099
- const [token2, link, bold, italic] = match2;
13100
- if (link) {
13101
- const parts = LINK.exec(link);
13102
- if (parts && isSafeUrl(parts[2])) {
13103
- nodes.push(
13104
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
13105
- Text,
13106
- {
13107
- as: "a",
13108
- display: "link",
13109
- href: parts[2],
13110
- target: "_blank",
13111
- rel: "noopener noreferrer",
13112
- children: parts[1]
13113
- },
13114
- key++
13115
- )
13116
- );
13117
- } else {
13118
- nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react14.Fragment, { children: parts ? parts[1] : token2 }, key++));
13119
- }
13120
- } else if (bold) {
13121
- nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: bold.slice(2, -2) }, key++));
13122
- } else if (italic) {
13123
- nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("em", { children: italic.slice(1, -1) }, key++));
13124
- }
13125
- lastIndex = match2.index + token2.length;
13126
- }
13127
- if (lastIndex < text.length) {
13128
- nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react14.Fragment, { children: text.slice(lastIndex) }, key));
13129
- }
13130
- return nodes;
13131
- };
13132
-
13133
13172
  // src/utils/string.ts
13134
13173
  var ZERO_DECIMAL_CURRENCIES = /* @__PURE__ */ new Set([
13135
13174
  "BIF",
@@ -13278,6 +13317,168 @@ function getCurrencySymbol(currency) {
13278
13317
  }
13279
13318
  }
13280
13319
 
13320
+ // src/utils/discount.ts
13321
+ function getSubscriptionDiscount(discounts, subscriptionTotal, subscriptionCurrency) {
13322
+ const activeDiscounts = (discounts || []).filter(
13323
+ (discount2) => discount2.isActive && (typeof discount2.percentOff === "number" && discount2.percentOff > 0 || typeof discount2.amountOff === "number" && discount2.amountOff > 0)
13324
+ );
13325
+ if (activeDiscounts.length !== 1) {
13326
+ return void 0;
13327
+ }
13328
+ const discount = activeDiscounts[0];
13329
+ const isPercentOff = typeof discount.percentOff === "number" && discount.percentOff > 0;
13330
+ if (!isPercentOff && discount.currency && subscriptionCurrency && discount.currency.toLowerCase() !== subscriptionCurrency.toLowerCase()) {
13331
+ return void 0;
13332
+ }
13333
+ const discountedTotal = isPercentOff ? subscriptionTotal * (1 - discount.percentOff / 100) : Math.max(0, subscriptionTotal - (discount.amountOff ?? 0));
13334
+ if (discountedTotal >= subscriptionTotal) {
13335
+ return void 0;
13336
+ }
13337
+ return {
13338
+ duration: discount.duration,
13339
+ durationInMonths: discount.durationInMonths ?? void 0,
13340
+ discountedPrice: formatCurrency(
13341
+ discountedTotal,
13342
+ subscriptionCurrency ?? void 0
13343
+ )
13344
+ };
13345
+ }
13346
+ function getBillingPreviewText({
13347
+ subscriptionPrice,
13348
+ planPeriod,
13349
+ periodStart,
13350
+ hasUsageBasedCosts,
13351
+ discount
13352
+ }, t3) {
13353
+ if (!subscriptionPrice) {
13354
+ return null;
13355
+ }
13356
+ const usage = hasUsageBasedCosts ? `${t3("plus usage based costs")} ` : "";
13357
+ const scheduleParts = [];
13358
+ if (periodStart) {
13359
+ scheduleParts.push(
13360
+ t3("on the day", { day: formatOrdinal(periodStart.getDate()) })
13361
+ );
13362
+ }
13363
+ if (planPeriod === "year" && periodStart) {
13364
+ scheduleParts.push(t3("of month", { month: getMonthName(periodStart) }));
13365
+ }
13366
+ const schedule = scheduleParts.length > 0 ? `${scheduleParts.join(" ")} ` : "";
13367
+ if (!discount) {
13368
+ return t3("You will be billed", {
13369
+ price: subscriptionPrice,
13370
+ usage,
13371
+ period: planPeriod,
13372
+ schedule
13373
+ });
13374
+ }
13375
+ const { duration, durationInMonths, discountedPrice } = discount;
13376
+ if (duration === "forever") {
13377
+ return t3("You will be billed", {
13378
+ price: discountedPrice,
13379
+ usage,
13380
+ period: planPeriod,
13381
+ schedule
13382
+ });
13383
+ }
13384
+ if (duration === "repeating" && durationInMonths) {
13385
+ return t3("You will be billed with discount window", {
13386
+ price: discountedPrice,
13387
+ usage,
13388
+ period: planPeriod,
13389
+ schedule,
13390
+ window: t3("for the next months", { count: durationInMonths }),
13391
+ fullPrice: subscriptionPrice
13392
+ });
13393
+ }
13394
+ return t3("You will be billed next bill discount", {
13395
+ price: discountedPrice,
13396
+ usage,
13397
+ period: planPeriod,
13398
+ schedule,
13399
+ fullPrice: subscriptionPrice
13400
+ });
13401
+ }
13402
+
13403
+ // src/utils/error.ts
13404
+ function isError(value) {
13405
+ return value instanceof Error;
13406
+ }
13407
+ var ERROR_UNKNOWN = new Error("An unknown error occurred.");
13408
+
13409
+ // src/utils/event.ts
13410
+ var createKeyboardExecutionHandler = (fn) => {
13411
+ const handler = (event) => {
13412
+ if (event.key === "Enter" || event.key === " ") {
13413
+ event.preventDefault();
13414
+ fn?.(event);
13415
+ }
13416
+ };
13417
+ return handler;
13418
+ };
13419
+
13420
+ // src/utils/markdown.tsx
13421
+ var import_react14 = require("react");
13422
+ var import_jsx_runtime2 = require("react/jsx-runtime");
13423
+ var TOKEN = /(\[[^\]]+\]\([^)\s]+\))|(\*\*[^*]+\*\*)|(\*[^*]+\*)/g;
13424
+ var LINK = /^\[([^\]]+)\]\(([^)\s]+)\)$/;
13425
+ var isSafeUrl = (url) => {
13426
+ try {
13427
+ const { protocol } = new URL(url);
13428
+ return protocol === "http:" || protocol === "https:";
13429
+ } catch {
13430
+ return false;
13431
+ }
13432
+ };
13433
+ var renderOptInMarkdown = (text) => {
13434
+ if (!text) {
13435
+ return null;
13436
+ }
13437
+ const nodes = [];
13438
+ let lastIndex = 0;
13439
+ let key = 0;
13440
+ TOKEN.lastIndex = 0;
13441
+ let match2;
13442
+ while ((match2 = TOKEN.exec(text)) !== null) {
13443
+ if (match2.index > lastIndex) {
13444
+ nodes.push(
13445
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react14.Fragment, { children: text.slice(lastIndex, match2.index) }, key++)
13446
+ );
13447
+ }
13448
+ const [token2, link, bold, italic] = match2;
13449
+ if (link) {
13450
+ const parts = LINK.exec(link);
13451
+ if (parts && isSafeUrl(parts[2])) {
13452
+ nodes.push(
13453
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
13454
+ Text,
13455
+ {
13456
+ as: "a",
13457
+ display: "link",
13458
+ href: parts[2],
13459
+ target: "_blank",
13460
+ rel: "noopener noreferrer",
13461
+ children: parts[1]
13462
+ },
13463
+ key++
13464
+ )
13465
+ );
13466
+ } else {
13467
+ nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react14.Fragment, { children: parts ? parts[1] : token2 }, key++));
13468
+ }
13469
+ } else if (bold) {
13470
+ nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { children: bold.slice(2, -2) }, key++));
13471
+ } else if (italic) {
13472
+ nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("em", { children: italic.slice(1, -1) }, key++));
13473
+ }
13474
+ lastIndex = match2.index + token2.length;
13475
+ }
13476
+ if (lastIndex < text.length) {
13477
+ nodes.push(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react14.Fragment, { children: text.slice(lastIndex) }, key));
13478
+ }
13479
+ return nodes;
13480
+ };
13481
+
13281
13482
  // src/utils/style.ts
13282
13483
  function attr(key, value) {
13283
13484
  if (typeof value !== "undefined") {
@@ -13533,7 +13734,7 @@ var reducer = (state, action) => {
13533
13734
  // src/context/EmbedProvider.tsx
13534
13735
  var import_jsx_runtime3 = require("react/jsx-runtime");
13535
13736
  var getCustomHeaders = (sessionId) => ({
13536
- "X-Schematic-Components-Version": "2.19.0",
13737
+ "X-Schematic-Components-Version": "2.21.0",
13537
13738
  "X-Schematic-Session-ID": sessionId
13538
13739
  });
13539
13740
  var normalizeCurrencyFilter = (filter2) => {
@@ -13557,6 +13758,7 @@ var EmbedProvider = ({
13557
13758
  apiKey,
13558
13759
  apiConfig,
13559
13760
  currencyFilter,
13761
+ warningThresholdConfig,
13560
13762
  checkoutPrefill,
13561
13763
  ...options
13562
13764
  }) => {
@@ -13572,6 +13774,7 @@ var EmbedProvider = ({
13572
13774
  const providedState = {
13573
13775
  settings: opts.settings || {},
13574
13776
  currencyFilter: normalizeCurrencyFilter(currencyFilter),
13777
+ warningThresholdConfig,
13575
13778
  checkoutPrefill: normalizeCheckoutPrefill(checkoutPrefill)
13576
13779
  };
13577
13780
  const resolvedState = (0, import_merge2.default)({}, initialState, providedState);
@@ -14000,6 +14203,7 @@ var EmbedProvider = ({
14000
14203
  layout: state.layout,
14001
14204
  checkoutState: state.checkoutState,
14002
14205
  currencyFilter: state.currencyFilter,
14206
+ warningThresholdConfig: state.warningThresholdConfig,
14003
14207
  checkoutPrefill: state.checkoutPrefill,
14004
14208
  hydratePublic: debouncedHydratePublic,
14005
14209
  hydrate: debouncedHydrate,
@@ -15936,7 +16140,8 @@ var Entitlement = ({
15936
16140
  currency: selectedCurrency
15937
16141
  }) => {
15938
16142
  const { t: t3 } = useTranslation();
15939
- const { data, settings } = useEmbed();
16143
+ const { data, settings, warningThresholdConfig } = useEmbed();
16144
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
15940
16145
  const isLightBackground = useIsLightBackground();
15941
16146
  const showCredits = data?.displaySettings?.showCredits ?? true;
15942
16147
  const showFeatureDescription = data?.displaySettings?.showFeatureDescription ?? false;
@@ -15960,7 +16165,8 @@ var Entitlement = ({
15960
16165
  return;
15961
16166
  }
15962
16167
  const hasNumericValue = entitlement.valueType === EntitlementValueType.Numeric || entitlement.valueType === EntitlementValueType.Unlimited || entitlement.valueType === EntitlementValueType.Trait;
15963
- const limit = entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
16168
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
16169
+ const limit = typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
15964
16170
  const creditBasedEntitlementLimit = getCreditBasedEntitlementLimit(
15965
16171
  entitlement,
15966
16172
  credits
@@ -16053,7 +16259,8 @@ var Entitlement = ({
16053
16259
  currency,
16054
16260
  packageSize,
16055
16261
  tiered,
16056
- selectedCurrency
16262
+ selectedCurrency,
16263
+ showWarningThresholdAsLimit
16057
16264
  ]);
16058
16265
  const usageText = (0, import_react32.useMemo)(() => {
16059
16266
  if (!entitlement.feature) {
@@ -16784,7 +16991,8 @@ var AddOns = ({
16784
16991
  currency
16785
16992
  }) => {
16786
16993
  const { t: t3 } = useTranslation();
16787
- const { settings } = useEmbed();
16994
+ const { settings, warningThresholdConfig } = useEmbed();
16995
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
16788
16996
  const isLightBackground = useIsLightBackground();
16789
16997
  const periodKey = period === "year" ? "yearlyPrice" : period === "quarter" ? "quarterlyPrice" : "monthlyPrice";
16790
16998
  const cardPadding = settings.theme.card.padding / TEXT_BASE_SIZE;
@@ -16816,10 +17024,14 @@ var AddOns = ({
16816
17024
  period,
16817
17025
  currency
16818
17026
  );
17027
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
16819
17028
  return {
16820
17029
  isUnlimited: false,
16821
17030
  priceBehavior: entitlement.priceBehavior,
16822
17031
  softLimit: entitlement.softLimit,
17032
+ // The limit shown next to the feature: the warning threshold when
17033
+ // the option is on and one is configured, else the overage soft limit.
17034
+ limit: typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage ? entitlement.softLimit : void 0,
16823
17035
  price: priceData?.price ?? 0,
16824
17036
  currency: priceData?.currency || addOnCurrency,
16825
17037
  featureName: entitlement.feature?.name,
@@ -16968,7 +17180,7 @@ var AddOns = ({
16968
17180
  {
16969
17181
  $flexDirection: "column",
16970
17182
  $justifyContent: "center",
16971
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Text, { children: meteredEntitlement.priceBehavior === EntitlementPriceBehavior.Overage && meteredEntitlement.softLimit ? `${meteredEntitlement.softLimit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) })
17183
+ children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(Text, { children: typeof meteredEntitlement.limit === "number" ? `${meteredEntitlement.limit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) })
16972
17184
  }
16973
17185
  )
16974
17186
  ] }),
@@ -20253,7 +20465,7 @@ var SubscriptionSidebar = (0, import_react44.forwardRef)(
20253
20465
  );
20254
20466
  return { payAsYouGoEntitlements, payInAdvanceEntitlements: payInAdvanceEntitlements2 };
20255
20467
  }, [usageBasedEntitlements]);
20256
- const subscriptionPrice = (0, import_react44.useMemo)(() => {
20468
+ const { subscriptionPrice, subscriptionTotal, subscriptionCurrency } = (0, import_react44.useMemo)(() => {
20257
20469
  let planPrice;
20258
20470
  let resolvedCurrency;
20259
20471
  if (selectedPlan) {
@@ -20289,7 +20501,11 @@ var SubscriptionSidebar = (0, import_react44.forwardRef)(
20289
20501
  0
20290
20502
  );
20291
20503
  total += addOnPayInAdvanceCost;
20292
- return formatCurrency(total, resolvedCurrency);
20504
+ return {
20505
+ subscriptionPrice: formatCurrency(total, resolvedCurrency),
20506
+ subscriptionTotal: total,
20507
+ subscriptionCurrency: resolvedCurrency
20508
+ };
20293
20509
  }, [
20294
20510
  selectedPlan,
20295
20511
  currentPlan,
@@ -20304,6 +20520,7 @@ var SubscriptionSidebar = (0, import_react44.forwardRef)(
20304
20520
  dueNow,
20305
20521
  newCharges,
20306
20522
  percentOff,
20523
+ periodEnd,
20307
20524
  periodStart,
20308
20525
  proration,
20309
20526
  taxAmount,
@@ -20314,12 +20531,14 @@ var SubscriptionSidebar = (0, import_react44.forwardRef)(
20314
20531
  dueNow: charges?.dueNow ?? 0,
20315
20532
  newCharges: charges?.newCharges ?? 0,
20316
20533
  percentOff: charges?.percentOff ?? 0,
20534
+ periodEnd: charges?.periodEnd,
20317
20535
  periodStart: charges?.periodStart,
20318
20536
  proration: charges?.proration ?? 0,
20319
20537
  taxAmount: charges?.taxAmount ?? 0,
20320
20538
  taxDescription: charges?.taxDisplayName
20321
20539
  };
20322
20540
  }, [charges]);
20541
+ const renewDate = periodEnd && !Number.isNaN(periodEnd.getTime()) ? periodEnd : periodStart;
20323
20542
  const updatedUsageBasedEntitlements = (0, import_react44.useMemo)(() => {
20324
20543
  const changedUsageBasedEntitlements = [];
20325
20544
  const allSelectedUsageBasedEntitlements = [
@@ -20413,6 +20632,14 @@ var SubscriptionSidebar = (0, import_react44.forwardRef)(
20413
20632
  () => promoCode && (amountOff > 0 || percentOff > 0),
20414
20633
  [promoCode, amountOff, percentOff]
20415
20634
  );
20635
+ const subscriptionDiscount = (0, import_react44.useMemo)(
20636
+ () => getSubscriptionDiscount(
20637
+ charges?.discounts,
20638
+ subscriptionTotal,
20639
+ subscriptionCurrency
20640
+ ),
20641
+ [charges?.discounts, subscriptionTotal, subscriptionCurrency]
20642
+ );
20416
20643
  const handleCheckout = (0, import_react44.useCallback)(async () => {
20417
20644
  const planId = selectedPlan?.id;
20418
20645
  const currencyPrice = selectedPlan ? getPlanPrice(
@@ -20659,6 +20886,16 @@ var SubscriptionSidebar = (0, import_react44.forwardRef)(
20659
20886
  if (isSelectedPlanTrialable && selectedPlan.trialDays) {
20660
20887
  trialEndsOn.setDate(trialEndsOn.getDate() + selectedPlan.trialDays);
20661
20888
  }
20889
+ const billingPreviewText = getBillingPreviewText(
20890
+ {
20891
+ subscriptionPrice,
20892
+ planPeriod,
20893
+ periodStart: renewDate,
20894
+ hasUsageBasedCosts: usageBasedEntitlements.length > 0,
20895
+ discount: subscriptionDiscount
20896
+ },
20897
+ t3
20898
+ );
20662
20899
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
20663
20900
  Flex,
20664
20901
  {
@@ -21207,9 +21444,7 @@ var SubscriptionSidebar = (0, import_react44.forwardRef)(
21207
21444
  }
21208
21445
  )
21209
21446
  }
21210
- ) : subscriptionPrice && // TODO: localize
21211
- `You will be billed ${subscriptionPrice} ${usageBasedEntitlements.length > 0 ? "plus usage based costs" : ""} for this subscription
21212
- every ${planPeriod} ${periodStart ? `on the ${formatOrdinal(periodStart.getDate())}` : ""} ${planPeriod === "year" && periodStart ? `of ${getMonthName(periodStart)}` : ""} unless you unsubscribe.` }) })
21447
+ ) : billingPreviewText }) })
21213
21448
  ]
21214
21449
  }
21215
21450
  )
@@ -21729,7 +21964,8 @@ var UsageDetails = ({ entitlement, layout }) => {
21729
21964
  metricResetAt
21730
21965
  } = entitlement;
21731
21966
  const { t: t3 } = useTranslation();
21732
- const { data } = useEmbed();
21967
+ const { data, warningThresholdConfig } = useEmbed();
21968
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
21733
21969
  const period = getSubscriptionPeriod(data?.company?.billingSubscription) ?? data?.company?.plan?.planPeriod ?? void 0;
21734
21970
  const showCredits = data?.displaySettings?.showCredits ?? true;
21735
21971
  const {
@@ -21745,7 +21981,9 @@ var UsageDetails = ({ entitlement, layout }) => {
21745
21981
  } = (0, import_react49.useMemo)(() => {
21746
21982
  const { billingPrice, amount, limit: limit2, cost: cost2, currentTier: currentTier2 } = getUsageDetails(
21747
21983
  entitlement,
21748
- period
21984
+ period,
21985
+ void 0,
21986
+ { showWarningThresholdAsLimit }
21749
21987
  );
21750
21988
  const {
21751
21989
  price: price2,
@@ -21766,7 +22004,7 @@ var UsageDetails = ({ entitlement, layout }) => {
21766
22004
  tiersMode: tiersMode2,
21767
22005
  tiered: priceBehavior === EntitlementPriceBehavior.PayInAdvance && isTieredPrice(billingPrice)
21768
22006
  };
21769
- }, [entitlement, period, priceBehavior]);
22007
+ }, [entitlement, period, priceBehavior, showWarningThresholdAsLimit]);
21770
22008
  const text = (0, import_react49.useMemo)(() => {
21771
22009
  if (!feature || feature.featureType !== FeatureType.Event && feature.featureType !== FeatureType.Trait) {
21772
22010
  return;
@@ -21816,9 +22054,10 @@ var UsageDetails = ({ entitlement, layout }) => {
21816
22054
  });
21817
22055
  }
21818
22056
  if (!priceBehavior && typeof allocation === "number") {
22057
+ const numericLimit = limit ?? allocation;
21819
22058
  return t3("X units", {
21820
- amount: formatNumber(allocation),
21821
- units: getFeatureName(feature, allocation)
22059
+ amount: formatNumber(numericLimit),
22060
+ units: getFeatureName(feature, numericLimit)
21822
22061
  });
21823
22062
  }
21824
22063
  if (!priceBehavior && allocationType === "unlimited") {
@@ -21904,7 +22143,7 @@ var UsageDetails = ({ entitlement, layout }) => {
21904
22143
  if (typeof usage === "number") {
21905
22144
  return typeof allocation === "number" ? t3("usage.limited", {
21906
22145
  amount: formatNumber(usage),
21907
- allocation: formatNumber(allocation)
22146
+ allocation: formatNumber(limit ?? allocation)
21908
22147
  }) : t3("usage.unlimited", {
21909
22148
  amount: formatNumber(usage)
21910
22149
  });
@@ -21918,6 +22157,7 @@ var UsageDetails = ({ entitlement, layout }) => {
21918
22157
  priceBehavior,
21919
22158
  packageSize,
21920
22159
  allocation,
22160
+ limit,
21921
22161
  usage,
21922
22162
  metricResetAt,
21923
22163
  cost,
@@ -22349,7 +22589,12 @@ var import_react52 = require("react");
22349
22589
  var import_jsx_runtime51 = require("react/jsx-runtime");
22350
22590
  var Meter = ({ entitlement }) => {
22351
22591
  const { allocation, priceBehavior, softLimit, usage } = entitlement;
22352
- const limit = softLimit ?? allocation;
22592
+ const { warningThresholdConfig } = useEmbed();
22593
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
22594
+ const warningThreshold = getEntitlementWarningThreshold(
22595
+ entitlement.planEntitlement?.warningTiers
22596
+ );
22597
+ const limit = showWarningThresholdAsLimit && typeof warningThreshold === "number" ? warningThreshold : softLimit ?? allocation;
22353
22598
  if (typeof usage !== "number" || typeof limit !== "number") {
22354
22599
  return null;
22355
22600
  }
@@ -22488,14 +22733,7 @@ var import_jsx_runtime53 = require("react/jsx-runtime");
22488
22733
  var Limit = ({ entitlement, usageDetails, fontStyle }) => {
22489
22734
  const { t: t3 } = useTranslation();
22490
22735
  const { data } = useEmbed();
22491
- const {
22492
- feature,
22493
- planEntitlement,
22494
- priceBehavior,
22495
- allocation,
22496
- usage,
22497
- metricResetAt
22498
- } = entitlement;
22736
+ const { feature, planEntitlement, priceBehavior, usage, metricResetAt } = entitlement;
22499
22737
  const { billingPrice, limit, cost, currentTier } = usageDetails;
22500
22738
  const acc = [];
22501
22739
  acc.push(
@@ -22517,8 +22755,8 @@ var Limit = ({ entitlement, usageDetails, fontStyle }) => {
22517
22755
  }) : priceBehavior === EntitlementPriceBehavior.CreditBurndown && typeof feature !== "undefined" && typeof limit === "number" ? t3("X units remaining", {
22518
22756
  amount: formatNumber(limit),
22519
22757
  units: getFeatureName(feature, limit)
22520
- }) : typeof allocation === "number" ? t3("Limit of", {
22521
- amount: formatNumber(allocation)
22758
+ }) : typeof limit === "number" ? t3("Limit of", {
22759
+ amount: formatNumber(limit)
22522
22760
  }) : t3("No limit")
22523
22761
  );
22524
22762
  if (metricResetAt) {
@@ -22573,7 +22811,8 @@ var MeteredFeatures = (0, import_react52.forwardRef)(({ className, ...rest }, re
22573
22811
  const elementsRef = (0, import_react52.useRef)([]);
22574
22812
  const shouldWrapChildren = useWrapChildren(elementsRef);
22575
22813
  const { t: t3 } = useTranslation();
22576
- const { data, settings, setCheckoutState } = useEmbed();
22814
+ const { data, settings, setCheckoutState, warningThresholdConfig } = useEmbed();
22815
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
22577
22816
  const isLightBackground = useIsLightBackground();
22578
22817
  const meteredFeatures = (0, import_react52.useMemo)(() => {
22579
22818
  const orderedFeatureUsage = props.visibleFeatures?.reduce(
@@ -22627,7 +22866,9 @@ var MeteredFeatures = (0, import_react52.forwardRef)(({ className, ...rest }, re
22627
22866
  return acc;
22628
22867
  }
22629
22868
  const { feature, priceBehavior, usage } = entitlement;
22630
- const usageDetails = getUsageDetails(entitlement, period);
22869
+ const usageDetails = getUsageDetails(entitlement, period, void 0, {
22870
+ showWarningThresholdAsLimit
22871
+ });
22631
22872
  const { limit } = usageDetails;
22632
22873
  acc.push(
22633
22874
  /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(Element, { as: Flex, $flexDirection: "column", $gap: "1.5rem", children: [
@@ -23245,7 +23486,7 @@ var registerWrapper = function registerWrapper2(stripe, startTime) {
23245
23486
  }
23246
23487
  stripe._registerWrapper({
23247
23488
  name: "stripe-js",
23248
- version: "9.9.0",
23489
+ version: "9.12.0",
23249
23490
  startTime
23250
23491
  });
23251
23492
  };
@@ -23323,7 +23564,7 @@ var initStripe = function initStripe2(maybeStripe, args, startTime) {
23323
23564
  var version = runtimeVersionToUrlVersion(maybeStripe.version);
23324
23565
  var expectedVersion = RELEASE_TRAIN;
23325
23566
  if (isTestKey && version !== expectedVersion) {
23326
- 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"));
23567
+ 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"));
23327
23568
  }
23328
23569
  var stripe = maybeStripe.apply(void 0, args);
23329
23570
  registerWrapper(stripe, startTime);
@@ -23737,14 +23978,17 @@ var UsageDetails2 = ({
23737
23978
  layout
23738
23979
  }) => {
23739
23980
  const { t: t3 } = useTranslation();
23740
- const { settings } = useEmbed();
23981
+ const { settings, warningThresholdConfig } = useEmbed();
23982
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
23741
23983
  const {
23742
23984
  billingPrice,
23743
23985
  limit,
23744
23986
  cost = 0
23745
23987
  } = (0, import_react56.useMemo)(
23746
- () => getUsageDetails(entitlement, period, currency),
23747
- [entitlement, period, currency]
23988
+ () => getUsageDetails(entitlement, period, currency, {
23989
+ showWarningThresholdAsLimit
23990
+ }),
23991
+ [entitlement, period, currency, showWarningThresholdAsLimit]
23748
23992
  );
23749
23993
  const description = (0, import_react56.useMemo)(() => {
23750
23994
  const acc = [];
@@ -24506,7 +24750,8 @@ var AddOn2 = ({
24506
24750
  }) => {
24507
24751
  const { layout } = sharedProps;
24508
24752
  const { t: t3 } = useTranslation();
24509
- const { data, settings, setCheckoutState } = useEmbed();
24753
+ const { data, settings, setCheckoutState, warningThresholdConfig } = useEmbed();
24754
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
24510
24755
  const isLightBackground = useIsLightBackground();
24511
24756
  const { currentAddOns, canCheckout, isStandalone } = (0, import_react58.useMemo)(() => {
24512
24757
  const isStandalone2 = typeof data?.component === "undefined";
@@ -24535,12 +24780,16 @@ var AddOn2 = ({
24535
24780
  selectedPeriod,
24536
24781
  currency
24537
24782
  );
24783
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
24538
24784
  return {
24539
24785
  isUnlimited: false,
24540
24786
  featureName: entitlement.feature?.name,
24541
24787
  feature: entitlement.feature,
24542
24788
  priceBehavior: entitlement.priceBehavior,
24543
24789
  softLimit: entitlement.softLimit,
24790
+ // The limit shown next to the feature: the warning threshold when the
24791
+ // option is on and one is configured, else the overage soft limit.
24792
+ limit: typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage ? entitlement.softLimit : void 0,
24544
24793
  price: priceData?.price ?? 0,
24545
24794
  currency: priceData?.currency || addOnCurrency,
24546
24795
  packageSize: priceData?.packageSize ?? 1,
@@ -24710,7 +24959,7 @@ var AddOn2 = ({
24710
24959
  rounded: true
24711
24960
  }
24712
24961
  ),
24713
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Flex, { $flexDirection: "column", $justifyContent: "center", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Text, { children: meteredEntitlement.priceBehavior === EntitlementPriceBehavior.Overage && meteredEntitlement.softLimit ? `${meteredEntitlement.softLimit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) }) })
24962
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Flex, { $flexDirection: "column", $justifyContent: "center", children: /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(Text, { children: typeof meteredEntitlement.limit === "number" ? `${meteredEntitlement.limit} ${getEntitlementFeatureName(meteredEntitlement, "units")}` : getEntitlementFeatureName(meteredEntitlement) }) })
24714
24963
  ] }),
24715
24964
  /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(
24716
24965
  Text,
@@ -24781,7 +25030,8 @@ var Entitlement2 = ({
24781
25030
  }) => {
24782
25031
  const { layout } = sharedProps;
24783
25032
  const { t: t3 } = useTranslation();
24784
- const { settings } = useEmbed();
25033
+ const { settings, warningThresholdConfig } = useEmbed();
25034
+ const showWarningThresholdAsLimit = warningThresholdConfig?.showAsLimit ?? false;
24785
25035
  const isLightBackground = useIsLightBackground();
24786
25036
  const entitlementBillingPrice = getEntitlementPrice(
24787
25037
  entitlement,
@@ -24796,7 +25046,8 @@ var Entitlement2 = ({
24796
25046
  tiersMode: entitlementTiersMode
24797
25047
  } = entitlementBillingPrice || {};
24798
25048
  const tiered = entitlement.priceBehavior === EntitlementPriceBehavior.PayInAdvance && isTieredPrice(entitlementBillingPrice);
24799
- const limit = entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
25049
+ const warningThreshold = showWarningThresholdAsLimit ? getEntitlementWarningThreshold(entitlement.warningTiers) : void 0;
25050
+ const limit = typeof warningThreshold === "number" ? warningThreshold : entitlement.priceBehavior === EntitlementPriceBehavior.Overage && typeof entitlement.softLimit === "number" ? entitlement.softLimit : entitlement.valueNumeric ?? void 0;
24800
25051
  const metricPeriodName = getMetricPeriodName(entitlement);
24801
25052
  const creditBasedEntitlementLimit = getCreditBasedEntitlementLimit(
24802
25053
  entitlement,
@@ -25686,20 +25937,27 @@ function resolveDesignProps11(props) {
25686
25937
  var UpcomingBill = (0, import_react63.forwardRef)(({ className, ...rest }, ref) => {
25687
25938
  const props = resolveDesignProps11(rest);
25688
25939
  const { t: t3 } = useTranslation();
25689
- const { data, settings, debug, getUpcomingInvoice, getCustomerBalance } = useEmbed();
25940
+ const { data, settings, getUpcomingInvoice } = useEmbed();
25690
25941
  const isLightBackground = useIsLightBackground();
25691
25942
  const [isLoading, setIsLoading] = (0, import_react63.useState)(false);
25692
25943
  const [error, setError] = (0, import_react63.useState)();
25693
25944
  const [upcomingInvoice, setUpcomingInvoice] = (0, import_react63.useState)(data?.upcomingInvoice);
25694
- const [balances, setBalances] = (0, import_react63.useState)([]);
25695
25945
  const discounts = (0, import_react63.useMemo)(() => {
25696
- return (data?.subscription?.discounts || []).map((discount) => ({
25946
+ return (data?.subscription?.discounts || []).filter(
25947
+ (discount) => (
25948
+ // Only surface discounts that are currently active and actually
25949
+ // reduce the bill; the API computes `isActive` at read time, so an
25950
+ // expired coupon must not linger in the account summary.
25951
+ discount.isActive && (typeof discount.percentOff === "number" && discount.percentOff > 0 || typeof discount.amountOff === "number" && discount.amountOff > 0)
25952
+ )
25953
+ ).map((discount) => ({
25697
25954
  couponId: discount.couponId,
25698
25955
  customerFacingCode: discount.customerFacingCode || void 0,
25699
25956
  currency: discount.currency || void 0,
25700
25957
  amountOff: discount.amountOff ?? void 0,
25701
25958
  percentOff: discount.percentOff ?? void 0,
25702
- isActive: discount.isActive
25959
+ duration: discount.duration,
25960
+ durationInMonths: discount.durationInMonths ?? void 0
25703
25961
  }));
25704
25962
  }, [data?.subscription?.discounts]);
25705
25963
  const getInvoice = (0, import_react63.useCallback)(async () => {
@@ -25718,27 +25976,30 @@ var UpcomingBill = (0, import_react63.forwardRef)(({ className, ...rest }, ref)
25718
25976
  }
25719
25977
  }
25720
25978
  }, [data?.component?.id, data?.subscription, getUpcomingInvoice]);
25721
- const getBalances = (0, import_react63.useCallback)(async () => {
25722
- try {
25723
- const response = await getCustomerBalance();
25724
- if (response) {
25725
- setBalances(response.data.balances);
25726
- }
25727
- } catch (err) {
25728
- debug("Failed to fetch customer balance.", err);
25729
- }
25730
- }, [debug, getCustomerBalance]);
25731
25979
  (0, import_react63.useEffect)(() => {
25732
25980
  getInvoice();
25733
25981
  }, [getInvoice]);
25734
- (0, import_react63.useEffect)(() => {
25735
- getBalances();
25736
- }, [getBalances]);
25737
25982
  (0, import_react63.useEffect)(() => {
25738
25983
  if (data?.upcomingInvoice) {
25739
25984
  setUpcomingInvoice(data.upcomingInvoice);
25740
25985
  }
25741
25986
  }, [data?.upcomingInvoice]);
25987
+ const { currency, applied, remaining } = (0, import_react63.useMemo)(() => {
25988
+ const currency2 = upcomingInvoice?.currency;
25989
+ const startingBalance = upcomingInvoice?.startingBalance ?? 0;
25990
+ const endingBalance = upcomingInvoice?.endingBalance ?? 0;
25991
+ const credit = Math.max(0, -startingBalance);
25992
+ const subtotal = Math.max(0, upcomingInvoice?.subtotal ?? 0);
25993
+ const applied2 = endingBalance < 0 ? credit + endingBalance : Math.min(credit, subtotal);
25994
+ return { currency: currency2, applied: applied2, remaining: credit - applied2 };
25995
+ }, [
25996
+ upcomingInvoice?.currency,
25997
+ upcomingInvoice?.startingBalance,
25998
+ upcomingInvoice?.endingBalance,
25999
+ upcomingInvoice?.subtotal
26000
+ ]);
26001
+ const hasApplied = applied > 0;
26002
+ const hasBalance = remaining > 0 || applied > 0;
25742
26003
  if (!data?.subscription || data.subscription.cancelAt) {
25743
26004
  return null;
25744
26005
  }
@@ -25788,7 +26049,7 @@ var UpcomingBill = (0, import_react63.forwardRef)(({ className, ...rest }, ref)
25788
26049
  ]
25789
26050
  }
25790
26051
  ),
25791
- balances.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
26052
+ hasApplied && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
25792
26053
  Flex,
25793
26054
  {
25794
26055
  as: TransitionBox,
@@ -25796,8 +26057,21 @@ var UpcomingBill = (0, import_react63.forwardRef)(({ className, ...rest }, ref)
25796
26057
  $alignItems: "start",
25797
26058
  $gap: "1rem",
25798
26059
  children: [
25799
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { $weight: 600, children: t3("Remaining balance") }),
25800
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Flex, { $flexDirection: "column", $gap: "0.5rem", children: balances.map((item, idx) => /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { children: formatCurrency(item.balance, item.currency) }, idx)) })
26060
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { $weight: 600, children: t3("Applied balance towards next invoice") }),
26061
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { children: formatCurrency(-applied, currency) })
26062
+ ]
26063
+ }
26064
+ ),
26065
+ hasBalance && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
26066
+ Flex,
26067
+ {
26068
+ as: TransitionBox,
26069
+ $justifyContent: "space-between",
26070
+ $alignItems: "start",
26071
+ $gap: "1rem",
26072
+ children: [
26073
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { $weight: 600, children: t3("Remaining balance after next invoice") }),
26074
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { children: formatCurrency(remaining, currency) })
25801
26075
  ]
25802
26076
  }
25803
26077
  ),
@@ -25815,54 +26089,50 @@ var UpcomingBill = (0, import_react63.forwardRef)(({ className, ...rest }, ref)
25815
26089
  $flexDirection: "column",
25816
26090
  $alignItems: "end",
25817
26091
  $gap: "0.5rem",
25818
- children: discounts.reduce(
25819
- (acc, discount) => {
25820
- if (typeof discount.percentOff === "number" || typeof discount.amountOff === "number") {
25821
- acc.push(
25822
- /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
26092
+ children: discounts.map((discount) => {
26093
+ const label = typeof discount.percentOff === "number" && discount.percentOff > 0 ? t3("Percent off", {
26094
+ percent: discount.percentOff
26095
+ }) : t3("Amount off", {
26096
+ amount: formatCurrency(
26097
+ discount.amountOff,
26098
+ // active discounts always carry a positive amount or percent
26099
+ discount?.currency
26100
+ )
26101
+ });
26102
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
26103
+ Flex,
26104
+ {
26105
+ $alignItems: "center",
26106
+ $gap: "0.5rem",
26107
+ children: [
26108
+ discount.customerFacingCode && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
25823
26109
  Flex,
25824
26110
  {
25825
26111
  $alignItems: "center",
25826
- $gap: "0.5rem",
25827
- children: [
25828
- discount.customerFacingCode && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
25829
- Flex,
25830
- {
25831
- $alignItems: "center",
25832
- $padding: "0.1875rem 0.375rem",
25833
- $borderWidth: "1px",
25834
- $borderStyle: "solid",
25835
- $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.15)" : "hsla(0, 0%, 100%, 0.15)",
25836
- $borderRadius: "0.3125rem",
25837
- children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
25838
- Text,
25839
- {
25840
- $size: 0.75 * settings.theme.typography.text.fontSize,
25841
- style: { textTransform: "uppercase" },
25842
- children: discount.customerFacingCode
25843
- }
25844
- )
25845
- }
25846
- ),
25847
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { children: typeof discount.percentOff === "number" ? t3("Percent off", {
25848
- percent: discount.percentOff
25849
- }) : t3("Amount off", {
25850
- amount: formatCurrency(
25851
- discount.amountOff,
25852
- // we already checked for `number` type
25853
- discount?.currency
25854
- )
25855
- }) }) })
25856
- ]
25857
- },
25858
- discount.couponId
25859
- )
25860
- );
25861
- }
25862
- return acc;
25863
- },
25864
- []
25865
- )
26112
+ $padding: "0.1875rem 0.375rem",
26113
+ $borderWidth: "1px",
26114
+ $borderStyle: "solid",
26115
+ $borderColor: isLightBackground ? "hsla(0, 0%, 0%, 0.15)" : "hsla(0, 0%, 100%, 0.15)",
26116
+ $borderRadius: "0.3125rem",
26117
+ children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
26118
+ Text,
26119
+ {
26120
+ $size: 0.75 * settings.theme.typography.text.fontSize,
26121
+ style: { textTransform: "uppercase" },
26122
+ children: discount.customerFacingCode
26123
+ }
26124
+ )
26125
+ }
26126
+ ),
26127
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Box, { children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(Text, { children: discount.duration === "repeating" && discount.durationInMonths ? t3("Discount for months", {
26128
+ discount: label,
26129
+ count: discount.durationInMonths
26130
+ }) : label }) })
26131
+ ]
26132
+ },
26133
+ discount.couponId
26134
+ );
26135
+ })
25866
26136
  }
25867
26137
  )
25868
26138
  ]