@schematichq/schematic-components 2.16.2 → 2.17.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -5
- package/dist/schematic-components.cjs.js +86 -13
- package/dist/schematic-components.d.ts +44 -0
- package/dist/schematic-components.esm.js +86 -13
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -48,24 +48,34 @@ selection stage.
|
|
|
48
48
|
initializeWithPlan('plan_VBXv4bHjSf3');
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
Passing a config object allows pre-selecting Add-ons
|
|
52
|
-
specific stages.
|
|
51
|
+
Passing a config object allows pre-selecting Add-ons and pay-in-advance
|
|
52
|
+
quantities, as well as hiding specific stages.
|
|
53
53
|
|
|
54
54
|
```ts
|
|
55
55
|
const config = {
|
|
56
56
|
planId: 'plan_VBXv4bHjSf3', // pre-select a Plan
|
|
57
57
|
addOnIds: ['plan_AWv7bPjSx2'], // pre-select 1 or more Add-ons
|
|
58
58
|
period: 'month', // pre-select 'month' or 'year' for the billing period (optional)
|
|
59
|
+
payInAdvanceQuantities: { // pre-fill pay-in-advance quantities, keyed by feature id (optional)
|
|
60
|
+
feat_seats: 3,
|
|
61
|
+
},
|
|
59
62
|
skipped: {
|
|
60
63
|
planStage: true, // if true, skip Plan selection
|
|
61
|
-
addOnStage: true
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
addOnStage: true, // if true, skip Add-on selection
|
|
65
|
+
usageStage: true, // if true, skip the pay-in-advance Quantity stage
|
|
66
|
+
addOnUsageStage: true, // if true, skip the add-on Quantity stage
|
|
67
|
+
},
|
|
68
|
+
hideSkipped: true, // if true, hide skipped stages from breadcrumb navigation
|
|
64
69
|
};
|
|
65
70
|
|
|
66
71
|
initializeWithPlan(config);
|
|
67
72
|
```
|
|
68
73
|
|
|
74
|
+
`payInAdvanceQuantities` only applies to entitlements with pay-in-advance
|
|
75
|
+
pricing; entries for other (or unknown) features are ignored. Combine it with
|
|
76
|
+
`skipped.usageStage` / `skipped.addOnUsageStage` to send the customer straight to
|
|
77
|
+
the final checkout step with the quantities already set.
|
|
78
|
+
|
|
69
79
|
The Plans and Add-ons available to the checkout flows must be live in your
|
|
70
80
|
Schematic account [Catalog configuration](https://docs.schematichq.com/catalog/overview).
|
|
71
81
|
|
|
@@ -1866,6 +1866,7 @@ __export(index_exports, {
|
|
|
1866
1866
|
UnsubscribeButton: () => UnsubscribeButton,
|
|
1867
1867
|
UpcomingBill: () => UpcomingBill,
|
|
1868
1868
|
Viewport: () => Viewport,
|
|
1869
|
+
applyPrefilledQuantities: () => applyPrefilledQuantities,
|
|
1869
1870
|
cardBoxShadow: () => cardBoxShadow,
|
|
1870
1871
|
createActiveUsageBasedEntitlementsReducer: () => createActiveUsageBasedEntitlementsReducer,
|
|
1871
1872
|
defaultSettings: () => defaultSettings,
|
|
@@ -8291,6 +8292,7 @@ function FeatureEntitlementFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
8291
8292
|
}
|
|
8292
8293
|
return {
|
|
8293
8294
|
allocation: json["allocation"] == null ? void 0 : json["allocation"],
|
|
8295
|
+
consumptionRate: json["consumption_rate"] == null ? void 0 : json["consumption_rate"],
|
|
8294
8296
|
creditId: json["credit_id"] == null ? void 0 : json["credit_id"],
|
|
8295
8297
|
creditRemaining: json["credit_remaining"] == null ? void 0 : json["credit_remaining"],
|
|
8296
8298
|
creditReserved: json["credit_reserved"] == null ? void 0 : json["credit_reserved"],
|
|
@@ -8298,6 +8300,7 @@ function FeatureEntitlementFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
8298
8300
|
creditTotal: json["credit_total"] == null ? void 0 : json["credit_total"],
|
|
8299
8301
|
creditUsed: json["credit_used"] == null ? void 0 : json["credit_used"],
|
|
8300
8302
|
eventName: json["event_name"] == null ? void 0 : json["event_name"],
|
|
8303
|
+
eventSubtype: json["event_subtype"] == null ? void 0 : json["event_subtype"],
|
|
8301
8304
|
featureId: json["feature_id"],
|
|
8302
8305
|
featureKey: json["feature_key"],
|
|
8303
8306
|
metricPeriod: json["metric_period"] == null ? void 0 : MetricPeriodFromJSON(json["metric_period"]),
|
|
@@ -13313,18 +13316,26 @@ var reducer = (state, action) => {
|
|
|
13313
13316
|
let bypassPlanSelection;
|
|
13314
13317
|
let bypassAddOnSelection;
|
|
13315
13318
|
let bypassCreditsSelection;
|
|
13319
|
+
let bypassUsageSelection;
|
|
13320
|
+
let bypassAddOnUsageSelection;
|
|
13316
13321
|
if (config.skipped !== void 0) {
|
|
13317
13322
|
bypassPlanSelection = config.skipped.planStage ?? false;
|
|
13318
13323
|
bypassAddOnSelection = config.skipped.addOnStage ?? false;
|
|
13319
13324
|
bypassCreditsSelection = config.skipped.creditStage ?? false;
|
|
13325
|
+
bypassUsageSelection = config.skipped.usageStage ?? false;
|
|
13326
|
+
bypassAddOnUsageSelection = config.skipped.addOnUsageStage ?? false;
|
|
13320
13327
|
} else if (isStringFormat) {
|
|
13321
13328
|
bypassPlanSelection = true;
|
|
13322
13329
|
bypassAddOnSelection = false;
|
|
13323
13330
|
bypassCreditsSelection = false;
|
|
13331
|
+
bypassUsageSelection = false;
|
|
13332
|
+
bypassAddOnUsageSelection = false;
|
|
13324
13333
|
} else {
|
|
13325
13334
|
bypassPlanSelection = false;
|
|
13326
13335
|
bypassAddOnSelection = false;
|
|
13327
13336
|
bypassCreditsSelection = false;
|
|
13337
|
+
bypassUsageSelection = false;
|
|
13338
|
+
bypassAddOnUsageSelection = false;
|
|
13328
13339
|
}
|
|
13329
13340
|
return {
|
|
13330
13341
|
...state,
|
|
@@ -13335,7 +13346,12 @@ var reducer = (state, action) => {
|
|
|
13335
13346
|
bypassPlanSelection,
|
|
13336
13347
|
bypassAddOnSelection,
|
|
13337
13348
|
bypassCreditsSelection,
|
|
13349
|
+
bypassUsageSelection,
|
|
13350
|
+
bypassAddOnUsageSelection,
|
|
13338
13351
|
...config.addOnIds && { addOnIds: config.addOnIds },
|
|
13352
|
+
...config.payInAdvanceQuantities && {
|
|
13353
|
+
payInAdvanceQuantities: config.payInAdvanceQuantities
|
|
13354
|
+
},
|
|
13339
13355
|
...config.currency && {
|
|
13340
13356
|
selectedCurrency: config.currency.toUpperCase()
|
|
13341
13357
|
},
|
|
@@ -13371,7 +13387,7 @@ var reducer = (state, action) => {
|
|
|
13371
13387
|
// src/context/EmbedProvider.tsx
|
|
13372
13388
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
13373
13389
|
var getCustomHeaders = (sessionId) => ({
|
|
13374
|
-
"X-Schematic-Components-Version": "2.
|
|
13390
|
+
"X-Schematic-Components-Version": "2.17.1",
|
|
13375
13391
|
"X-Schematic-Session-ID": sessionId
|
|
13376
13392
|
});
|
|
13377
13393
|
var normalizeCurrencyFilter = (filter2) => {
|
|
@@ -17241,6 +17257,18 @@ var createActiveUsageBasedEntitlementsReducer = (entitlements, period) => (acc,
|
|
|
17241
17257
|
}
|
|
17242
17258
|
return acc;
|
|
17243
17259
|
};
|
|
17260
|
+
var applyPrefilledQuantities = (entitlements, prefill) => {
|
|
17261
|
+
if (!prefill) {
|
|
17262
|
+
return entitlements;
|
|
17263
|
+
}
|
|
17264
|
+
return entitlements.map((entitlement) => {
|
|
17265
|
+
const prefilled = prefill[entitlement.featureId];
|
|
17266
|
+
if (entitlement.priceBehavior === EntitlementPriceBehavior.PayInAdvance && typeof prefilled === "number") {
|
|
17267
|
+
return { ...entitlement, quantity: Math.max(0, Math.floor(prefilled)) };
|
|
17268
|
+
}
|
|
17269
|
+
return entitlement;
|
|
17270
|
+
});
|
|
17271
|
+
};
|
|
17244
17272
|
var CheckoutDialog = ({ top }) => {
|
|
17245
17273
|
const { t: t3 } = useTranslation();
|
|
17246
17274
|
const {
|
|
@@ -17474,9 +17502,12 @@ var CheckoutDialog = ({ top }) => {
|
|
|
17474
17502
|
effectiveCurrency
|
|
17475
17503
|
]);
|
|
17476
17504
|
const [usageBasedEntitlements, setUsageBasedEntitlements] = (0, import_react36.useState)(
|
|
17477
|
-
() => (
|
|
17478
|
-
|
|
17479
|
-
|
|
17505
|
+
() => applyPrefilledQuantities(
|
|
17506
|
+
(selectedPlan?.entitlements || []).reduce(
|
|
17507
|
+
createActiveUsageBasedEntitlementsReducer(featureUsage, planPeriod),
|
|
17508
|
+
[]
|
|
17509
|
+
),
|
|
17510
|
+
checkoutState?.payInAdvanceQuantities
|
|
17480
17511
|
)
|
|
17481
17512
|
);
|
|
17482
17513
|
const [addOnUsageBasedEntitlements, setAddOnUsageBasedEntitlements] = (0, import_react36.useState)(() => {
|
|
@@ -17515,7 +17546,10 @@ var CheckoutDialog = ({ top }) => {
|
|
|
17515
17546
|
allEntitlements.push(bypassEnt);
|
|
17516
17547
|
}
|
|
17517
17548
|
}
|
|
17518
|
-
return
|
|
17549
|
+
return applyPrefilledQuantities(
|
|
17550
|
+
allEntitlements,
|
|
17551
|
+
checkoutState?.payInAdvanceQuantities
|
|
17552
|
+
);
|
|
17519
17553
|
});
|
|
17520
17554
|
const payInAdvanceEntitlements = (0, import_react36.useMemo)(
|
|
17521
17555
|
() => usageBasedEntitlements.filter(
|
|
@@ -17651,7 +17685,7 @@ var CheckoutDialog = ({ top }) => {
|
|
|
17651
17685
|
hasInitialPaymentMethod
|
|
17652
17686
|
]);
|
|
17653
17687
|
const [isBypassLoading, setIsBypassLoading] = (0, import_react36.useState)(
|
|
17654
|
-
() => checkoutState?.bypassPlanSelection || checkoutState?.bypassAddOnSelection || checkoutState?.bypassCreditsSelection
|
|
17688
|
+
() => checkoutState?.bypassPlanSelection || checkoutState?.bypassAddOnSelection || checkoutState?.bypassCreditsSelection || checkoutState?.bypassUsageSelection || checkoutState?.bypassAddOnUsageSelection
|
|
17655
17689
|
);
|
|
17656
17690
|
const [checkoutStage, setCheckoutStage] = (0, import_react36.useState)(() => {
|
|
17657
17691
|
if (checkoutState?.addOnId) {
|
|
@@ -17671,7 +17705,7 @@ var CheckoutDialog = ({ top }) => {
|
|
|
17671
17705
|
const effectiveCheckoutStage = (0, import_react36.useMemo)(() => {
|
|
17672
17706
|
if (isBypassLoading) return checkoutStage;
|
|
17673
17707
|
let id = checkoutStage;
|
|
17674
|
-
while (id === "plan" && checkoutState?.bypassPlanSelection || id === "addons" && checkoutState?.bypassAddOnSelection || id === "credits" && checkoutState?.bypassCreditsSelection) {
|
|
17708
|
+
while (id === "plan" && checkoutState?.bypassPlanSelection || id === "usage" && checkoutState?.bypassUsageSelection || id === "addons" && checkoutState?.bypassAddOnSelection || id === "addonsUsage" && checkoutState?.bypassAddOnUsageSelection || id === "credits" && checkoutState?.bypassCreditsSelection) {
|
|
17675
17709
|
const idx = checkoutStages.findIndex((s) => s.id === id);
|
|
17676
17710
|
const next2 = checkoutStages[idx + 1];
|
|
17677
17711
|
if (!next2) break;
|
|
@@ -17896,9 +17930,12 @@ var CheckoutDialog = ({ top }) => {
|
|
|
17896
17930
|
(updates) => {
|
|
17897
17931
|
const plan = updates.plan;
|
|
17898
17932
|
const period = showPeriodToggle ? updates.period || planPeriod : plan.monthlyPrice ? BillingProductPriceInterval.Month : plan.quarterlyPrice ? "quarter" : plan.yearlyPrice ? BillingProductPriceInterval.Year : BillingProductPriceInterval.Month;
|
|
17899
|
-
const updatedUsageBasedEntitlements = (
|
|
17900
|
-
|
|
17901
|
-
|
|
17933
|
+
const updatedUsageBasedEntitlements = applyPrefilledQuantities(
|
|
17934
|
+
(plan.entitlements ?? []).reduce(
|
|
17935
|
+
createActiveUsageBasedEntitlementsReducer(featureUsage, period),
|
|
17936
|
+
[]
|
|
17937
|
+
),
|
|
17938
|
+
checkoutState?.payInAdvanceQuantities
|
|
17902
17939
|
);
|
|
17903
17940
|
if (period !== planPeriod || plan.id !== selectedPlan?.id) {
|
|
17904
17941
|
setUsageBasedEntitlements((prev2) => {
|
|
@@ -17948,7 +17985,8 @@ var CheckoutDialog = ({ top }) => {
|
|
|
17948
17985
|
featureUsage,
|
|
17949
17986
|
shouldTrial,
|
|
17950
17987
|
willTrialWithoutPaymentMethod,
|
|
17951
|
-
handlePreviewCheckout
|
|
17988
|
+
handlePreviewCheckout,
|
|
17989
|
+
checkoutState?.payInAdvanceQuantities
|
|
17952
17990
|
]
|
|
17953
17991
|
);
|
|
17954
17992
|
const changePlanPeriod = (0, import_react36.useCallback)(
|
|
@@ -18176,9 +18214,15 @@ var CheckoutDialog = ({ top }) => {
|
|
|
18176
18214
|
if (stage.id === "plan" && checkoutState.bypassPlanSelection) {
|
|
18177
18215
|
return false;
|
|
18178
18216
|
}
|
|
18217
|
+
if (stage.id === "usage" && checkoutState.bypassUsageSelection) {
|
|
18218
|
+
return false;
|
|
18219
|
+
}
|
|
18179
18220
|
if (stage.id === "addons" && checkoutState.bypassAddOnSelection) {
|
|
18180
18221
|
return false;
|
|
18181
18222
|
}
|
|
18223
|
+
if (stage.id === "addonsUsage" && checkoutState.bypassAddOnUsageSelection) {
|
|
18224
|
+
return false;
|
|
18225
|
+
}
|
|
18182
18226
|
if (stage.id === "credits" && checkoutState.bypassCreditsSelection) {
|
|
18183
18227
|
return false;
|
|
18184
18228
|
}
|
|
@@ -18190,9 +18234,15 @@ var CheckoutDialog = ({ top }) => {
|
|
|
18190
18234
|
if (stage.id === "plan" && checkoutState?.bypassPlanSelection) {
|
|
18191
18235
|
return false;
|
|
18192
18236
|
}
|
|
18237
|
+
if (stage.id === "usage" && checkoutState?.bypassUsageSelection) {
|
|
18238
|
+
return false;
|
|
18239
|
+
}
|
|
18193
18240
|
if (stage.id === "addons" && checkoutState?.bypassAddOnSelection) {
|
|
18194
18241
|
return false;
|
|
18195
18242
|
}
|
|
18243
|
+
if (stage.id === "addonsUsage" && checkoutState?.bypassAddOnUsageSelection) {
|
|
18244
|
+
return false;
|
|
18245
|
+
}
|
|
18196
18246
|
if (stage.id === "credits" && checkoutState?.bypassCreditsSelection) {
|
|
18197
18247
|
return false;
|
|
18198
18248
|
}
|
|
@@ -18201,7 +18251,9 @@ var CheckoutDialog = ({ top }) => {
|
|
|
18201
18251
|
}, [
|
|
18202
18252
|
checkoutStages,
|
|
18203
18253
|
checkoutState?.bypassPlanSelection,
|
|
18254
|
+
checkoutState?.bypassUsageSelection,
|
|
18204
18255
|
checkoutState?.bypassAddOnSelection,
|
|
18256
|
+
checkoutState?.bypassAddOnUsageSelection,
|
|
18205
18257
|
checkoutState?.bypassCreditsSelection
|
|
18206
18258
|
]);
|
|
18207
18259
|
const shouldShowBypassOverlay = isBypassLoading;
|
|
@@ -18935,6 +18987,8 @@ var PaymentForm = ({ onConfirm, financeData }) => {
|
|
|
18935
18987
|
const [isPaymentComplete, setIsPaymentComplete] = (0, import_react39.useState)(false);
|
|
18936
18988
|
const [isPaymentReady, setIsPaymentReady] = (0, import_react39.useState)(false);
|
|
18937
18989
|
const [loadError, setLoadError] = (0, import_react39.useState)();
|
|
18990
|
+
const [isEmailValid, setIsEmailValid] = (0, import_react39.useState)(() => !collectEmail);
|
|
18991
|
+
const emailInputRef = (0, import_react39.useRef)(null);
|
|
18938
18992
|
const [isAddressComplete, setIsAddressComplete] = (0, import_react39.useState)(
|
|
18939
18993
|
() => !shouldCollectAddress
|
|
18940
18994
|
);
|
|
@@ -18947,6 +19001,11 @@ var PaymentForm = ({ onConfirm, financeData }) => {
|
|
|
18947
19001
|
setEmail(billing.email);
|
|
18948
19002
|
}
|
|
18949
19003
|
}, [billing?.email]);
|
|
19004
|
+
(0, import_react39.useEffect)(() => {
|
|
19005
|
+
setIsEmailValid(
|
|
19006
|
+
!collectEmail || (emailInputRef.current?.checkValidity() ?? false)
|
|
19007
|
+
);
|
|
19008
|
+
}, [email, collectEmail, stripe]);
|
|
18950
19009
|
const handleSubmit = async (event) => {
|
|
18951
19010
|
event.preventDefault();
|
|
18952
19011
|
if (!stripe || !elements) {
|
|
@@ -19046,11 +19105,13 @@ var PaymentForm = ({ onConfirm, financeData }) => {
|
|
|
19046
19105
|
/* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
|
|
19047
19106
|
Input2,
|
|
19048
19107
|
{
|
|
19108
|
+
ref: emailInputRef,
|
|
19049
19109
|
id: "email",
|
|
19050
|
-
type: "
|
|
19110
|
+
type: "email",
|
|
19051
19111
|
value: email,
|
|
19052
19112
|
autoComplete: "email",
|
|
19053
19113
|
placeholder: "Enter email address",
|
|
19114
|
+
required: true,
|
|
19054
19115
|
onChange: (e2) => {
|
|
19055
19116
|
userEditedEmailRef.current = true;
|
|
19056
19117
|
setEmail(e2.target.value);
|
|
@@ -19081,7 +19142,7 @@ var PaymentForm = ({ onConfirm, financeData }) => {
|
|
|
19081
19142
|
Button,
|
|
19082
19143
|
{
|
|
19083
19144
|
id: "submit",
|
|
19084
|
-
disabled: isLoading || !stripe || !elements || isConfirmed || !isPaymentComplete || !isAddressComplete,
|
|
19145
|
+
disabled: isLoading || !stripe || !elements || isConfirmed || !isPaymentComplete || !isAddressComplete || !isEmailValid,
|
|
19085
19146
|
style: { flexShrink: 0 },
|
|
19086
19147
|
$color: "primary",
|
|
19087
19148
|
$isLoading: isLoading,
|
|
@@ -22682,6 +22743,18 @@ var getPaymentMethodData = ({
|
|
|
22682
22743
|
iconTitle: billingName || billingEmail || "Amazon Pay account",
|
|
22683
22744
|
label: billingName || billingEmail || "Amazon Pay account"
|
|
22684
22745
|
},
|
|
22746
|
+
apple_pay: {
|
|
22747
|
+
iconName: "applepay",
|
|
22748
|
+
iconTitle: "Apple Pay",
|
|
22749
|
+
label: cardLast4 ? "Apple Pay ending in" : "Apple Pay",
|
|
22750
|
+
paymentLast4: cardLast4
|
|
22751
|
+
},
|
|
22752
|
+
google_pay: {
|
|
22753
|
+
iconName: "google",
|
|
22754
|
+
iconTitle: "Google Pay",
|
|
22755
|
+
label: cardLast4 ? "Google Pay ending in" : "Google Pay",
|
|
22756
|
+
paymentLast4: cardLast4
|
|
22757
|
+
},
|
|
22685
22758
|
cashapp: {
|
|
22686
22759
|
iconName: "cashapp",
|
|
22687
22760
|
iconTitle: accountName || billingEmail || "CashApp account",
|
|
@@ -26,6 +26,8 @@ declare interface AddOnsProps {
|
|
|
26
26
|
currency?: string;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
export declare const applyPrefilledQuantities: (entitlements: UsageBasedEntitlement[], prefill?: Record<string, number>) => UsageBasedEntitlement[];
|
|
30
|
+
|
|
29
31
|
export declare const AutoTopup: ({ planCreditGrants, autoTopupConfigs, updateAutoTopupConfig, }: AutoTopupProps) => JSX.Element;
|
|
30
32
|
|
|
31
33
|
declare type AutoTopupConfig = Pick<CompanyPlanCreditGrantView, "companyAutoTopupEnabled" | "companyAutoTopupThresholdCredits" | "companyAutoTopupAmount">;
|
|
@@ -2901,6 +2903,19 @@ export declare interface BypassConfig {
|
|
|
2901
2903
|
* currency is locked (the selector is already hidden in those cases).
|
|
2902
2904
|
*/
|
|
2903
2905
|
showCurrencySelector?: boolean;
|
|
2906
|
+
/**
|
|
2907
|
+
* Pre-fill pay-in-advance quantities, keyed by feature id.
|
|
2908
|
+
*
|
|
2909
|
+
* Only applies to entitlements whose price behavior is pay-in-advance; entries
|
|
2910
|
+
* for other features (or unknown feature ids) are ignored. Values are clamped
|
|
2911
|
+
* to whole numbers >= 0. Combine with `skipped.usageStage` /
|
|
2912
|
+
* `skipped.addOnUsageStage` to land the customer directly on the checkout step
|
|
2913
|
+
* with the quantities already set.
|
|
2914
|
+
*
|
|
2915
|
+
* @example
|
|
2916
|
+
* { planId: "plan_abc", payInAdvanceQuantities: { feat_seats: 3 } }
|
|
2917
|
+
*/
|
|
2918
|
+
payInAdvanceQuantities?: Record<string, number>;
|
|
2904
2919
|
}
|
|
2905
2920
|
|
|
2906
2921
|
export declare const Card: ForwardRefExoticComponent<CardProps & RefAttributes<HTMLDivElement | null>>;
|
|
@@ -3399,6 +3414,20 @@ export declare interface CheckoutStageSkipConfig {
|
|
|
3399
3414
|
* - undefined: Defaults to false (show stage)
|
|
3400
3415
|
*/
|
|
3401
3416
|
creditStage?: boolean;
|
|
3417
|
+
/**
|
|
3418
|
+
* Skip the pay-in-advance quantity stage for the plan.
|
|
3419
|
+
* - true: Skip directly to next stage (uses prefilled or current quantities)
|
|
3420
|
+
* - false: Show quantity stage (user can review/change quantities)
|
|
3421
|
+
* - undefined: Defaults to false (show stage)
|
|
3422
|
+
*/
|
|
3423
|
+
usageStage?: boolean;
|
|
3424
|
+
/**
|
|
3425
|
+
* Skip the pay-in-advance quantity stage for add-ons.
|
|
3426
|
+
* - true: Skip directly to next stage (uses prefilled or current quantities)
|
|
3427
|
+
* - false: Show add-on quantity stage (user can review/change quantities)
|
|
3428
|
+
* - undefined: Defaults to false (show stage)
|
|
3429
|
+
*/
|
|
3430
|
+
addOnUsageStage?: boolean;
|
|
3402
3431
|
}
|
|
3403
3432
|
|
|
3404
3433
|
export declare type CheckoutState = {
|
|
@@ -3411,11 +3440,14 @@ export declare type CheckoutState = {
|
|
|
3411
3440
|
bypassPlanSelection?: boolean;
|
|
3412
3441
|
bypassAddOnSelection?: boolean;
|
|
3413
3442
|
bypassCreditsSelection?: boolean;
|
|
3443
|
+
bypassUsageSelection?: boolean;
|
|
3444
|
+
bypassAddOnUsageSelection?: boolean;
|
|
3414
3445
|
addOnIds?: string[];
|
|
3415
3446
|
hideSkippedStages?: boolean;
|
|
3416
3447
|
selectedCurrency?: string;
|
|
3417
3448
|
showCurrencySelector?: boolean;
|
|
3418
3449
|
startTrialIfAvailable?: boolean;
|
|
3450
|
+
payInAdvanceQuantities?: Record<string, number>;
|
|
3419
3451
|
};
|
|
3420
3452
|
|
|
3421
3453
|
/**
|
|
@@ -6949,6 +6981,12 @@ declare interface FeatureEntitlement {
|
|
|
6949
6981
|
* @memberof FeatureEntitlement
|
|
6950
6982
|
*/
|
|
6951
6983
|
allocation?: number | null;
|
|
6984
|
+
/**
|
|
6985
|
+
* If the company has a credit-based entitlement for this feature, the credit cost per unit of usage
|
|
6986
|
+
* @type {number}
|
|
6987
|
+
* @memberof FeatureEntitlement
|
|
6988
|
+
*/
|
|
6989
|
+
consumptionRate?: number | null;
|
|
6952
6990
|
/**
|
|
6953
6991
|
* If the company has a credit-based entitlement for this feature, the ID of the credit
|
|
6954
6992
|
* @type {string}
|
|
@@ -6991,6 +7029,12 @@ declare interface FeatureEntitlement {
|
|
|
6991
7029
|
* @memberof FeatureEntitlement
|
|
6992
7030
|
*/
|
|
6993
7031
|
eventName?: string | null;
|
|
7032
|
+
/**
|
|
7033
|
+
* For event-based or credit-metered feature entitlements, the event subtype whose usage is tracked
|
|
7034
|
+
* @type {string}
|
|
7035
|
+
* @memberof FeatureEntitlement
|
|
7036
|
+
*/
|
|
7037
|
+
eventSubtype?: string | null;
|
|
6994
7038
|
/**
|
|
6995
7039
|
* The ID of the feature
|
|
6996
7040
|
* @type {string}
|
|
@@ -8202,6 +8202,7 @@ function FeatureEntitlementFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
8202
8202
|
}
|
|
8203
8203
|
return {
|
|
8204
8204
|
allocation: json["allocation"] == null ? void 0 : json["allocation"],
|
|
8205
|
+
consumptionRate: json["consumption_rate"] == null ? void 0 : json["consumption_rate"],
|
|
8205
8206
|
creditId: json["credit_id"] == null ? void 0 : json["credit_id"],
|
|
8206
8207
|
creditRemaining: json["credit_remaining"] == null ? void 0 : json["credit_remaining"],
|
|
8207
8208
|
creditReserved: json["credit_reserved"] == null ? void 0 : json["credit_reserved"],
|
|
@@ -8209,6 +8210,7 @@ function FeatureEntitlementFromJSONTyped(json, ignoreDiscriminator) {
|
|
|
8209
8210
|
creditTotal: json["credit_total"] == null ? void 0 : json["credit_total"],
|
|
8210
8211
|
creditUsed: json["credit_used"] == null ? void 0 : json["credit_used"],
|
|
8211
8212
|
eventName: json["event_name"] == null ? void 0 : json["event_name"],
|
|
8213
|
+
eventSubtype: json["event_subtype"] == null ? void 0 : json["event_subtype"],
|
|
8212
8214
|
featureId: json["feature_id"],
|
|
8213
8215
|
featureKey: json["feature_key"],
|
|
8214
8216
|
metricPeriod: json["metric_period"] == null ? void 0 : MetricPeriodFromJSON(json["metric_period"]),
|
|
@@ -13224,18 +13226,26 @@ var reducer = (state, action) => {
|
|
|
13224
13226
|
let bypassPlanSelection;
|
|
13225
13227
|
let bypassAddOnSelection;
|
|
13226
13228
|
let bypassCreditsSelection;
|
|
13229
|
+
let bypassUsageSelection;
|
|
13230
|
+
let bypassAddOnUsageSelection;
|
|
13227
13231
|
if (config.skipped !== void 0) {
|
|
13228
13232
|
bypassPlanSelection = config.skipped.planStage ?? false;
|
|
13229
13233
|
bypassAddOnSelection = config.skipped.addOnStage ?? false;
|
|
13230
13234
|
bypassCreditsSelection = config.skipped.creditStage ?? false;
|
|
13235
|
+
bypassUsageSelection = config.skipped.usageStage ?? false;
|
|
13236
|
+
bypassAddOnUsageSelection = config.skipped.addOnUsageStage ?? false;
|
|
13231
13237
|
} else if (isStringFormat) {
|
|
13232
13238
|
bypassPlanSelection = true;
|
|
13233
13239
|
bypassAddOnSelection = false;
|
|
13234
13240
|
bypassCreditsSelection = false;
|
|
13241
|
+
bypassUsageSelection = false;
|
|
13242
|
+
bypassAddOnUsageSelection = false;
|
|
13235
13243
|
} else {
|
|
13236
13244
|
bypassPlanSelection = false;
|
|
13237
13245
|
bypassAddOnSelection = false;
|
|
13238
13246
|
bypassCreditsSelection = false;
|
|
13247
|
+
bypassUsageSelection = false;
|
|
13248
|
+
bypassAddOnUsageSelection = false;
|
|
13239
13249
|
}
|
|
13240
13250
|
return {
|
|
13241
13251
|
...state,
|
|
@@ -13246,7 +13256,12 @@ var reducer = (state, action) => {
|
|
|
13246
13256
|
bypassPlanSelection,
|
|
13247
13257
|
bypassAddOnSelection,
|
|
13248
13258
|
bypassCreditsSelection,
|
|
13259
|
+
bypassUsageSelection,
|
|
13260
|
+
bypassAddOnUsageSelection,
|
|
13249
13261
|
...config.addOnIds && { addOnIds: config.addOnIds },
|
|
13262
|
+
...config.payInAdvanceQuantities && {
|
|
13263
|
+
payInAdvanceQuantities: config.payInAdvanceQuantities
|
|
13264
|
+
},
|
|
13250
13265
|
...config.currency && {
|
|
13251
13266
|
selectedCurrency: config.currency.toUpperCase()
|
|
13252
13267
|
},
|
|
@@ -13282,7 +13297,7 @@ var reducer = (state, action) => {
|
|
|
13282
13297
|
// src/context/EmbedProvider.tsx
|
|
13283
13298
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
13284
13299
|
var getCustomHeaders = (sessionId) => ({
|
|
13285
|
-
"X-Schematic-Components-Version": "2.
|
|
13300
|
+
"X-Schematic-Components-Version": "2.17.1",
|
|
13286
13301
|
"X-Schematic-Session-ID": sessionId
|
|
13287
13302
|
});
|
|
13288
13303
|
var normalizeCurrencyFilter = (filter2) => {
|
|
@@ -17171,6 +17186,18 @@ var createActiveUsageBasedEntitlementsReducer = (entitlements, period) => (acc,
|
|
|
17171
17186
|
}
|
|
17172
17187
|
return acc;
|
|
17173
17188
|
};
|
|
17189
|
+
var applyPrefilledQuantities = (entitlements, prefill) => {
|
|
17190
|
+
if (!prefill) {
|
|
17191
|
+
return entitlements;
|
|
17192
|
+
}
|
|
17193
|
+
return entitlements.map((entitlement) => {
|
|
17194
|
+
const prefilled = prefill[entitlement.featureId];
|
|
17195
|
+
if (entitlement.priceBehavior === EntitlementPriceBehavior.PayInAdvance && typeof prefilled === "number") {
|
|
17196
|
+
return { ...entitlement, quantity: Math.max(0, Math.floor(prefilled)) };
|
|
17197
|
+
}
|
|
17198
|
+
return entitlement;
|
|
17199
|
+
});
|
|
17200
|
+
};
|
|
17174
17201
|
var CheckoutDialog = ({ top }) => {
|
|
17175
17202
|
const { t: t3 } = useTranslation();
|
|
17176
17203
|
const {
|
|
@@ -17404,9 +17431,12 @@ var CheckoutDialog = ({ top }) => {
|
|
|
17404
17431
|
effectiveCurrency
|
|
17405
17432
|
]);
|
|
17406
17433
|
const [usageBasedEntitlements, setUsageBasedEntitlements] = useState8(
|
|
17407
|
-
() => (
|
|
17408
|
-
|
|
17409
|
-
|
|
17434
|
+
() => applyPrefilledQuantities(
|
|
17435
|
+
(selectedPlan?.entitlements || []).reduce(
|
|
17436
|
+
createActiveUsageBasedEntitlementsReducer(featureUsage, planPeriod),
|
|
17437
|
+
[]
|
|
17438
|
+
),
|
|
17439
|
+
checkoutState?.payInAdvanceQuantities
|
|
17410
17440
|
)
|
|
17411
17441
|
);
|
|
17412
17442
|
const [addOnUsageBasedEntitlements, setAddOnUsageBasedEntitlements] = useState8(() => {
|
|
@@ -17445,7 +17475,10 @@ var CheckoutDialog = ({ top }) => {
|
|
|
17445
17475
|
allEntitlements.push(bypassEnt);
|
|
17446
17476
|
}
|
|
17447
17477
|
}
|
|
17448
|
-
return
|
|
17478
|
+
return applyPrefilledQuantities(
|
|
17479
|
+
allEntitlements,
|
|
17480
|
+
checkoutState?.payInAdvanceQuantities
|
|
17481
|
+
);
|
|
17449
17482
|
});
|
|
17450
17483
|
const payInAdvanceEntitlements = useMemo12(
|
|
17451
17484
|
() => usageBasedEntitlements.filter(
|
|
@@ -17581,7 +17614,7 @@ var CheckoutDialog = ({ top }) => {
|
|
|
17581
17614
|
hasInitialPaymentMethod
|
|
17582
17615
|
]);
|
|
17583
17616
|
const [isBypassLoading, setIsBypassLoading] = useState8(
|
|
17584
|
-
() => checkoutState?.bypassPlanSelection || checkoutState?.bypassAddOnSelection || checkoutState?.bypassCreditsSelection
|
|
17617
|
+
() => checkoutState?.bypassPlanSelection || checkoutState?.bypassAddOnSelection || checkoutState?.bypassCreditsSelection || checkoutState?.bypassUsageSelection || checkoutState?.bypassAddOnUsageSelection
|
|
17585
17618
|
);
|
|
17586
17619
|
const [checkoutStage, setCheckoutStage] = useState8(() => {
|
|
17587
17620
|
if (checkoutState?.addOnId) {
|
|
@@ -17601,7 +17634,7 @@ var CheckoutDialog = ({ top }) => {
|
|
|
17601
17634
|
const effectiveCheckoutStage = useMemo12(() => {
|
|
17602
17635
|
if (isBypassLoading) return checkoutStage;
|
|
17603
17636
|
let id = checkoutStage;
|
|
17604
|
-
while (id === "plan" && checkoutState?.bypassPlanSelection || id === "addons" && checkoutState?.bypassAddOnSelection || id === "credits" && checkoutState?.bypassCreditsSelection) {
|
|
17637
|
+
while (id === "plan" && checkoutState?.bypassPlanSelection || id === "usage" && checkoutState?.bypassUsageSelection || id === "addons" && checkoutState?.bypassAddOnSelection || id === "addonsUsage" && checkoutState?.bypassAddOnUsageSelection || id === "credits" && checkoutState?.bypassCreditsSelection) {
|
|
17605
17638
|
const idx = checkoutStages.findIndex((s) => s.id === id);
|
|
17606
17639
|
const next2 = checkoutStages[idx + 1];
|
|
17607
17640
|
if (!next2) break;
|
|
@@ -17826,9 +17859,12 @@ var CheckoutDialog = ({ top }) => {
|
|
|
17826
17859
|
(updates) => {
|
|
17827
17860
|
const plan = updates.plan;
|
|
17828
17861
|
const period = showPeriodToggle ? updates.period || planPeriod : plan.monthlyPrice ? BillingProductPriceInterval.Month : plan.quarterlyPrice ? "quarter" : plan.yearlyPrice ? BillingProductPriceInterval.Year : BillingProductPriceInterval.Month;
|
|
17829
|
-
const updatedUsageBasedEntitlements = (
|
|
17830
|
-
|
|
17831
|
-
|
|
17862
|
+
const updatedUsageBasedEntitlements = applyPrefilledQuantities(
|
|
17863
|
+
(plan.entitlements ?? []).reduce(
|
|
17864
|
+
createActiveUsageBasedEntitlementsReducer(featureUsage, period),
|
|
17865
|
+
[]
|
|
17866
|
+
),
|
|
17867
|
+
checkoutState?.payInAdvanceQuantities
|
|
17832
17868
|
);
|
|
17833
17869
|
if (period !== planPeriod || plan.id !== selectedPlan?.id) {
|
|
17834
17870
|
setUsageBasedEntitlements((prev2) => {
|
|
@@ -17878,7 +17914,8 @@ var CheckoutDialog = ({ top }) => {
|
|
|
17878
17914
|
featureUsage,
|
|
17879
17915
|
shouldTrial,
|
|
17880
17916
|
willTrialWithoutPaymentMethod,
|
|
17881
|
-
handlePreviewCheckout
|
|
17917
|
+
handlePreviewCheckout,
|
|
17918
|
+
checkoutState?.payInAdvanceQuantities
|
|
17882
17919
|
]
|
|
17883
17920
|
);
|
|
17884
17921
|
const changePlanPeriod = useCallback7(
|
|
@@ -18106,9 +18143,15 @@ var CheckoutDialog = ({ top }) => {
|
|
|
18106
18143
|
if (stage.id === "plan" && checkoutState.bypassPlanSelection) {
|
|
18107
18144
|
return false;
|
|
18108
18145
|
}
|
|
18146
|
+
if (stage.id === "usage" && checkoutState.bypassUsageSelection) {
|
|
18147
|
+
return false;
|
|
18148
|
+
}
|
|
18109
18149
|
if (stage.id === "addons" && checkoutState.bypassAddOnSelection) {
|
|
18110
18150
|
return false;
|
|
18111
18151
|
}
|
|
18152
|
+
if (stage.id === "addonsUsage" && checkoutState.bypassAddOnUsageSelection) {
|
|
18153
|
+
return false;
|
|
18154
|
+
}
|
|
18112
18155
|
if (stage.id === "credits" && checkoutState.bypassCreditsSelection) {
|
|
18113
18156
|
return false;
|
|
18114
18157
|
}
|
|
@@ -18120,9 +18163,15 @@ var CheckoutDialog = ({ top }) => {
|
|
|
18120
18163
|
if (stage.id === "plan" && checkoutState?.bypassPlanSelection) {
|
|
18121
18164
|
return false;
|
|
18122
18165
|
}
|
|
18166
|
+
if (stage.id === "usage" && checkoutState?.bypassUsageSelection) {
|
|
18167
|
+
return false;
|
|
18168
|
+
}
|
|
18123
18169
|
if (stage.id === "addons" && checkoutState?.bypassAddOnSelection) {
|
|
18124
18170
|
return false;
|
|
18125
18171
|
}
|
|
18172
|
+
if (stage.id === "addonsUsage" && checkoutState?.bypassAddOnUsageSelection) {
|
|
18173
|
+
return false;
|
|
18174
|
+
}
|
|
18126
18175
|
if (stage.id === "credits" && checkoutState?.bypassCreditsSelection) {
|
|
18127
18176
|
return false;
|
|
18128
18177
|
}
|
|
@@ -18131,7 +18180,9 @@ var CheckoutDialog = ({ top }) => {
|
|
|
18131
18180
|
}, [
|
|
18132
18181
|
checkoutStages,
|
|
18133
18182
|
checkoutState?.bypassPlanSelection,
|
|
18183
|
+
checkoutState?.bypassUsageSelection,
|
|
18134
18184
|
checkoutState?.bypassAddOnSelection,
|
|
18185
|
+
checkoutState?.bypassAddOnUsageSelection,
|
|
18135
18186
|
checkoutState?.bypassCreditsSelection
|
|
18136
18187
|
]);
|
|
18137
18188
|
const shouldShowBypassOverlay = isBypassLoading;
|
|
@@ -18870,6 +18921,8 @@ var PaymentForm = ({ onConfirm, financeData }) => {
|
|
|
18870
18921
|
const [isPaymentComplete, setIsPaymentComplete] = useState11(false);
|
|
18871
18922
|
const [isPaymentReady, setIsPaymentReady] = useState11(false);
|
|
18872
18923
|
const [loadError, setLoadError] = useState11();
|
|
18924
|
+
const [isEmailValid, setIsEmailValid] = useState11(() => !collectEmail);
|
|
18925
|
+
const emailInputRef = useRef8(null);
|
|
18873
18926
|
const [isAddressComplete, setIsAddressComplete] = useState11(
|
|
18874
18927
|
() => !shouldCollectAddress
|
|
18875
18928
|
);
|
|
@@ -18882,6 +18935,11 @@ var PaymentForm = ({ onConfirm, financeData }) => {
|
|
|
18882
18935
|
setEmail(billing.email);
|
|
18883
18936
|
}
|
|
18884
18937
|
}, [billing?.email]);
|
|
18938
|
+
useEffect5(() => {
|
|
18939
|
+
setIsEmailValid(
|
|
18940
|
+
!collectEmail || (emailInputRef.current?.checkValidity() ?? false)
|
|
18941
|
+
);
|
|
18942
|
+
}, [email, collectEmail, stripe]);
|
|
18885
18943
|
const handleSubmit = async (event) => {
|
|
18886
18944
|
event.preventDefault();
|
|
18887
18945
|
if (!stripe || !elements) {
|
|
@@ -18981,11 +19039,13 @@ var PaymentForm = ({ onConfirm, financeData }) => {
|
|
|
18981
19039
|
/* @__PURE__ */ jsx33(
|
|
18982
19040
|
Input2,
|
|
18983
19041
|
{
|
|
19042
|
+
ref: emailInputRef,
|
|
18984
19043
|
id: "email",
|
|
18985
|
-
type: "
|
|
19044
|
+
type: "email",
|
|
18986
19045
|
value: email,
|
|
18987
19046
|
autoComplete: "email",
|
|
18988
19047
|
placeholder: "Enter email address",
|
|
19048
|
+
required: true,
|
|
18989
19049
|
onChange: (e2) => {
|
|
18990
19050
|
userEditedEmailRef.current = true;
|
|
18991
19051
|
setEmail(e2.target.value);
|
|
@@ -19016,7 +19076,7 @@ var PaymentForm = ({ onConfirm, financeData }) => {
|
|
|
19016
19076
|
Button,
|
|
19017
19077
|
{
|
|
19018
19078
|
id: "submit",
|
|
19019
|
-
disabled: isLoading || !stripe || !elements || isConfirmed || !isPaymentComplete || !isAddressComplete,
|
|
19079
|
+
disabled: isLoading || !stripe || !elements || isConfirmed || !isPaymentComplete || !isAddressComplete || !isEmailValid,
|
|
19020
19080
|
style: { flexShrink: 0 },
|
|
19021
19081
|
$color: "primary",
|
|
19022
19082
|
$isLoading: isLoading,
|
|
@@ -22624,6 +22684,18 @@ var getPaymentMethodData = ({
|
|
|
22624
22684
|
iconTitle: billingName || billingEmail || "Amazon Pay account",
|
|
22625
22685
|
label: billingName || billingEmail || "Amazon Pay account"
|
|
22626
22686
|
},
|
|
22687
|
+
apple_pay: {
|
|
22688
|
+
iconName: "applepay",
|
|
22689
|
+
iconTitle: "Apple Pay",
|
|
22690
|
+
label: cardLast4 ? "Apple Pay ending in" : "Apple Pay",
|
|
22691
|
+
paymentLast4: cardLast4
|
|
22692
|
+
},
|
|
22693
|
+
google_pay: {
|
|
22694
|
+
iconName: "google",
|
|
22695
|
+
iconTitle: "Google Pay",
|
|
22696
|
+
label: cardLast4 ? "Google Pay ending in" : "Google Pay",
|
|
22697
|
+
paymentLast4: cardLast4
|
|
22698
|
+
},
|
|
22627
22699
|
cashapp: {
|
|
22628
22700
|
iconName: "cashapp",
|
|
22629
22701
|
iconTitle: accountName || billingEmail || "CashApp account",
|
|
@@ -29979,6 +30051,7 @@ export {
|
|
|
29979
30051
|
UnsubscribeButton,
|
|
29980
30052
|
UpcomingBill,
|
|
29981
30053
|
Viewport,
|
|
30054
|
+
applyPrefilledQuantities,
|
|
29982
30055
|
cardBoxShadow,
|
|
29983
30056
|
createActiveUsageBasedEntitlementsReducer,
|
|
29984
30057
|
defaultSettings,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@schematichq/schematic-components",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.17.1",
|
|
4
4
|
"main": "dist/schematic-components.cjs.js",
|
|
5
5
|
"module": "dist/schematic-components.esm.js",
|
|
6
6
|
"types": "dist/schematic-components.d.ts",
|
|
@@ -40,16 +40,16 @@
|
|
|
40
40
|
"pako": "^2.1.0",
|
|
41
41
|
"react-i18next": "16.1.6",
|
|
42
42
|
"styled-components": "^6.4.2",
|
|
43
|
-
"uuid": "^14.0.
|
|
43
|
+
"uuid": "^14.0.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@eslint/js": "^10.0.1",
|
|
47
47
|
"@eslint/json": "^2.0.0",
|
|
48
48
|
"@eslint/markdown": "^8.0.2",
|
|
49
49
|
"@microsoft/api-extractor": "^7.58.9",
|
|
50
|
-
"@openapitools/openapi-generator-cli": "^2.
|
|
50
|
+
"@openapitools/openapi-generator-cli": "^2.39.0",
|
|
51
51
|
"@stripe/react-stripe-js": "^6.6.0",
|
|
52
|
-
"@swc/core": "^1.15.
|
|
52
|
+
"@swc/core": "^1.15.43",
|
|
53
53
|
"@testing-library/dom": "^10.4.1",
|
|
54
54
|
"@testing-library/jest-dom": "^6.9.1",
|
|
55
55
|
"@testing-library/react": "^16.3.2",
|
|
@@ -64,15 +64,15 @@
|
|
|
64
64
|
"eslint-plugin-import-x": "^4.16.2",
|
|
65
65
|
"eslint-plugin-react": "^7.37.5",
|
|
66
66
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
67
|
-
"globals": "^17.
|
|
68
|
-
"happy-dom": "^20.10.
|
|
67
|
+
"globals": "^17.7.0",
|
|
68
|
+
"happy-dom": "^20.10.6",
|
|
69
69
|
"jsdom": "^29.1.1",
|
|
70
70
|
"msw": "^2.14.6",
|
|
71
71
|
"prettier": "^3.8.4",
|
|
72
72
|
"react": "^19.2.7",
|
|
73
73
|
"react-dom": "^19.2.7",
|
|
74
74
|
"typescript": "^6.0.3",
|
|
75
|
-
"typescript-eslint": "^8.
|
|
75
|
+
"typescript-eslint": "^8.62.0",
|
|
76
76
|
"vitest": "^4.1.9"
|
|
77
77
|
},
|
|
78
78
|
"peerDependencies": {
|