@kerne/react 0.1.3 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,20 +44,32 @@ function LoginForm() {
44
44
 
45
45
  ## Gating a feature
46
46
 
47
- `Allows` (and the underlying `useAccess` hook) check the logged-in user automatically - no scope to pass, the SDK already knows who's authenticated.
47
+ `Access` (and the underlying `useAccess` hook) check the logged-in user automatically - no scope to pass, the SDK already knows who's authenticated.
48
48
 
49
49
  ```tsx
50
- import { Allows } from '@kerne/react';
50
+ import { Access } from '@kerne/react';
51
51
 
52
52
  function ExportButton() {
53
53
  return (
54
- <Allows featureKey="export_pdf" fallback={<UpgradePrompt />}>
54
+ <Access featureKey="export_pdf" fallback={<UpgradePrompt />}>
55
55
  <button onClick={exportPdf}>Export as PDF</button>
56
- </Allows>
56
+ </Access>
57
57
  );
58
58
  }
59
59
  ```
60
60
 
61
+ Pass `requested` to check a quantity before it's spent, not after - useful right before a batch action:
62
+
63
+ ```tsx
64
+ <Access
65
+ featureKey="ai_credits"
66
+ requested={5}
67
+ fallback={<UpgradePrompt reason="Not enough credits for batch processing" />}
68
+ >
69
+ <BatchProcessButton count={5} />
70
+ </Access>
71
+ ```
72
+
61
73
  For the full detail behind a check (limit/used/remaining, not just a boolean), read `details` from the same hook - `const { allowed, details } = useAccess('api_calls')`.
62
74
 
63
75
  ## Checkout & billing portal
@@ -75,8 +87,9 @@ const { openPortal } = usePortal();
75
87
  - `useUser`: the current authenticated user's profile.
76
88
  - `useAccess`: feature access - `allowed` for the go/no-go, `details` for limit/used/remaining.
77
89
  - `useUsage`, `useEntitlements`: usage and full entitlement lists for the current user.
78
- - `useSubscription`, `usePlans`: the current subscription and the tenant's public plan catalog.
90
+ - `useSubscription`, `usePlans`: the current subscription (with `refetch`) and the tenant's public plan catalog.
79
91
  - `useCheckout`, `usePortal`: hosted checkout and billing-portal sessions.
92
+ - `useCancelSubscription`, `useChangePlan`: cancel or switch plan. Both act on the payment provider first, then on Kerne, so a cancellation really stops the next invoice.
80
93
 
81
94
  ## Documentation
82
95
 
@@ -185,9 +185,20 @@ var defaultLocalization = {
185
185
  freePlan: "You are on the free plan.",
186
186
  seePlans: "See plans",
187
187
  cancelNotice: "Your plan is set to end - you keep access until the date above.",
188
+ cancelSubscription: "Cancel subscription",
189
+ canceling: "Canceling...",
190
+ cancelConfirmTitle: "Cancel your subscription?",
191
+ cancelConfirmBody: "You'll keep access until the end of the current billing period.",
192
+ cancelConfirmButton: "Yes, cancel",
193
+ cancelConfirmDismiss: "Never mind",
188
194
  changePlan: "Change plan",
189
195
  current: "Current",
190
196
  switchTo: "Switch",
197
+ switching: "Switching...",
198
+ switchConfirmTitle: "Switch to {plan}?",
199
+ switchConfirmBody: "This applies right away, and your next invoice reflects the price difference for the rest of this period.",
200
+ switchConfirmButton: "Yes, switch",
201
+ switchConfirmDismiss: "Never mind",
191
202
  noPlans: "No other plans are available right now.",
192
203
  notOnInterval: "Not available on this interval",
193
204
  loadFailed: "Could not load your plan right now.",
@@ -212,11 +223,23 @@ var defaultLocalization = {
212
223
  subtitle: "Counted against your plan for the current period.",
213
224
  used: "{count} used",
214
225
  nothingMetered: "Nothing metered on your plan - you have no usage limits to watch.",
215
- overage: "{count} over your included amount - billed as overage.",
226
+ overage: "{count} over your included amount - at no extra charge.",
227
+ overageBilled: "{count} over your included amount - the extra is billed on top of your plan.",
216
228
  limitReached: "You have reached your limit.",
229
+ capReached: "You've reached your billing cap for this period - everything past this is free.",
230
+ billedAmount: "{amount} billed this period.",
217
231
  loading: "Loading usage",
218
232
  loadFailed: "Could not load your usage right now."
219
233
  },
234
+ pricing: {
235
+ getStarted: "Get started",
236
+ billedAt: "Billed {amount} / {interval}",
237
+ save: "Save {percent}%",
238
+ unlimited: "Unlimited",
239
+ moreFeatures: "+{count} more",
240
+ loading: "Loading plans",
241
+ loadFailed: "Could not load plans right now."
242
+ },
220
243
  checkout: {
221
244
  confirmingTitle: "Confirming your payment",
222
245
  confirmingBody: "This takes a few seconds - please keep this tab open.",
@@ -714,7 +737,7 @@ var KerneClient = class {
714
737
  * caught everything and returned `false`) - a 401/500 must not be
715
738
  * indistinguishable from a real denial, that's exactly what let the
716
739
  * `has_access`/`allowed` mismatch below ship unnoticed. Callers that want
717
- * a fail-closed boolean regardless of the reason (e.g. `<Allows>`)
740
+ * a fail-closed boolean regardless of the reason (e.g. `<Access>`)
718
741
  * catch around this themselves.
719
742
  */
720
743
  async allows(featureKey, requested) {
@@ -744,13 +767,21 @@ var KerneClient = class {
744
767
  async getSubscription(productSlug) {
745
768
  const subs = await this.kerne.billing.subscriptions.list({
746
769
  productSlug,
747
- scopeType: "USER"
770
+ subjectType: "USER"
748
771
  });
749
772
  const active = subs.find(
750
773
  (s) => s.status === "ACTIVE" || s.status === "TRIALING" || s.status === "PAST_DUE"
751
774
  );
752
775
  return active ?? null;
753
776
  }
777
+ /** `immediately: true` ends it now; otherwise cancels at period end (API default). */
778
+ async cancelSubscription(subscriptionId, immediately) {
779
+ return this.kerne.billing.subscriptions.cancel(subscriptionId, immediately);
780
+ }
781
+ /** Swaps the plan/price, effective immediately - deferring a downgrade isn't supported yet. */
782
+ async changeSubscriptionPlan(subscriptionId, planPriceId, options) {
783
+ return this.kerne.billing.subscriptions.changePlanPrice(subscriptionId, planPriceId, options);
784
+ }
754
785
  /** Public pricing data - omit `productIdOrSlug` for the tenant's default product. */
755
786
  async getPlans(productIdOrSlug) {
756
787
  return this.kerne.billing.plans(productIdOrSlug);
@@ -923,6 +954,95 @@ function usePortal() {
923
954
  openPortal: useCallback2((returnUrl) => client.openPortal(returnUrl), [client])
924
955
  };
925
956
  }
957
+ function useCancelSubscription() {
958
+ const client = useClient();
959
+ const [isCanceling, setIsCanceling] = useState(false);
960
+ const cancelSubscription = useCallback2(
961
+ async (subscriptionId, immediately) => {
962
+ setIsCanceling(true);
963
+ try {
964
+ return await client.cancelSubscription(subscriptionId, immediately);
965
+ } finally {
966
+ setIsCanceling(false);
967
+ }
968
+ },
969
+ [client]
970
+ );
971
+ return { cancelSubscription, isCanceling };
972
+ }
973
+ function useChangePlan() {
974
+ const client = useClient();
975
+ const [isChanging, setIsChanging] = useState(false);
976
+ const changePlan = useCallback2(
977
+ async (subscriptionId, planPriceId, options) => {
978
+ setIsChanging(true);
979
+ try {
980
+ return await client.changeSubscriptionPlan(subscriptionId, planPriceId, options);
981
+ } finally {
982
+ setIsChanging(false);
983
+ }
984
+ },
985
+ [client]
986
+ );
987
+ return { changePlan, isChanging };
988
+ }
989
+ function usePlanSwitch(subscription, refetchSubscription, options) {
990
+ const { openCheckout } = useCheckout();
991
+ const { changePlan } = useChangePlan();
992
+ const [pending, setPending] = useState(null);
993
+ const [switching, setSwitching] = useState(false);
994
+ const [switchError, setSwitchError] = useState(null);
995
+ const [checkoutPriceId, setCheckoutPriceId] = useState(null);
996
+ const [checkoutError, setCheckoutError] = useState(null);
997
+ const successUrl = options?.successUrl;
998
+ const cancelUrl = options?.cancelUrl;
999
+ const selectPlan = useCallback2(
1000
+ async (plan, price) => {
1001
+ if (subscription) {
1002
+ setSwitchError(null);
1003
+ setPending({ plan, price });
1004
+ return;
1005
+ }
1006
+ setCheckoutError(null);
1007
+ setCheckoutPriceId(price.id);
1008
+ try {
1009
+ await openCheckout(price.id, { successUrl, cancelUrl });
1010
+ } catch (e) {
1011
+ setCheckoutError(e);
1012
+ setCheckoutPriceId(null);
1013
+ }
1014
+ },
1015
+ [subscription, openCheckout, successUrl, cancelUrl]
1016
+ );
1017
+ const confirmSwitch = useCallback2(async () => {
1018
+ if (!pending || !subscription) return;
1019
+ setSwitching(true);
1020
+ setSwitchError(null);
1021
+ try {
1022
+ await changePlan(subscription.id, pending.price.id);
1023
+ setPending(null);
1024
+ refetchSubscription();
1025
+ } catch (e) {
1026
+ setSwitchError(e);
1027
+ } finally {
1028
+ setSwitching(false);
1029
+ }
1030
+ }, [pending, subscription, changePlan, refetchSubscription]);
1031
+ const dismissSwitch = useCallback2(() => {
1032
+ setPending(null);
1033
+ setSwitchError(null);
1034
+ }, []);
1035
+ return {
1036
+ pending,
1037
+ switching,
1038
+ switchError,
1039
+ checkoutPriceId,
1040
+ checkoutError,
1041
+ selectPlan,
1042
+ confirmSwitch,
1043
+ dismissSwitch
1044
+ };
1045
+ }
926
1046
  function useAccess(featureKey, requested) {
927
1047
  const client = useClient();
928
1048
  const [state, setState] = useState({
@@ -957,27 +1077,38 @@ function useSubscription(productSlug) {
957
1077
  isLoading: true,
958
1078
  error: null
959
1079
  });
1080
+ const fetchOnce = useCallback2(
1081
+ (mountedRef) => {
1082
+ client.getSubscription(productSlug).then((subscription) => {
1083
+ if (mountedRef.current) {
1084
+ setState({ subscription, isLoading: false, error: null });
1085
+ }
1086
+ }).catch((error) => {
1087
+ if (mountedRef.current) {
1088
+ setState({ subscription: null, isLoading: false, error });
1089
+ }
1090
+ });
1091
+ },
1092
+ [client, productSlug]
1093
+ );
960
1094
  useEffect2(() => {
961
- let mounted = true;
962
- client.getSubscription(productSlug).then((subscription) => {
963
- if (mounted) {
964
- setState({ subscription, isLoading: false, error: null });
965
- }
966
- }).catch((error) => {
967
- if (mounted) {
968
- setState({ subscription: null, isLoading: false, error });
969
- }
970
- });
1095
+ const mountedRef = { current: true };
1096
+ fetchOnce(mountedRef);
971
1097
  return () => {
972
- mounted = false;
1098
+ mountedRef.current = false;
973
1099
  };
974
- }, [client, productSlug]);
1100
+ }, [fetchOnce]);
1101
+ const refetch = useCallback2(() => {
1102
+ setState((prev) => ({ ...prev, isLoading: true }));
1103
+ fetchOnce({ current: true });
1104
+ }, [fetchOnce]);
975
1105
  const isActive = state.subscription?.status === "ACTIVE" || state.subscription?.status === "TRIALING";
976
1106
  const planSlug = state.subscription?.plan?.slug;
977
1107
  return {
978
1108
  ...state,
979
1109
  isActive,
980
- planSlug
1110
+ planSlug,
1111
+ refetch
981
1112
  };
982
1113
  }
983
1114
  function usePlans(productIdOrSlug) {
@@ -1139,6 +1270,9 @@ export {
1139
1270
  useAuth,
1140
1271
  useCheckout,
1141
1272
  usePortal,
1273
+ useCancelSubscription,
1274
+ useChangePlan,
1275
+ usePlanSwitch,
1142
1276
  useAccess,
1143
1277
  useSubscription,
1144
1278
  usePlans,
@@ -185,9 +185,20 @@ var defaultLocalization = {
185
185
  freePlan: "You are on the free plan.",
186
186
  seePlans: "See plans",
187
187
  cancelNotice: "Your plan is set to end - you keep access until the date above.",
188
+ cancelSubscription: "Cancel subscription",
189
+ canceling: "Canceling...",
190
+ cancelConfirmTitle: "Cancel your subscription?",
191
+ cancelConfirmBody: "You'll keep access until the end of the current billing period.",
192
+ cancelConfirmButton: "Yes, cancel",
193
+ cancelConfirmDismiss: "Never mind",
188
194
  changePlan: "Change plan",
189
195
  current: "Current",
190
196
  switchTo: "Switch",
197
+ switching: "Switching...",
198
+ switchConfirmTitle: "Switch to {plan}?",
199
+ switchConfirmBody: "This applies right away, and your next invoice reflects the price difference for the rest of this period.",
200
+ switchConfirmButton: "Yes, switch",
201
+ switchConfirmDismiss: "Never mind",
191
202
  noPlans: "No other plans are available right now.",
192
203
  notOnInterval: "Not available on this interval",
193
204
  loadFailed: "Could not load your plan right now.",
@@ -212,11 +223,23 @@ var defaultLocalization = {
212
223
  subtitle: "Counted against your plan for the current period.",
213
224
  used: "{count} used",
214
225
  nothingMetered: "Nothing metered on your plan - you have no usage limits to watch.",
215
- overage: "{count} over your included amount - billed as overage.",
226
+ overage: "{count} over your included amount - at no extra charge.",
227
+ overageBilled: "{count} over your included amount - the extra is billed on top of your plan.",
216
228
  limitReached: "You have reached your limit.",
229
+ capReached: "You've reached your billing cap for this period - everything past this is free.",
230
+ billedAmount: "{amount} billed this period.",
217
231
  loading: "Loading usage",
218
232
  loadFailed: "Could not load your usage right now."
219
233
  },
234
+ pricing: {
235
+ getStarted: "Get started",
236
+ billedAt: "Billed {amount} / {interval}",
237
+ save: "Save {percent}%",
238
+ unlimited: "Unlimited",
239
+ moreFeatures: "+{count} more",
240
+ loading: "Loading plans",
241
+ loadFailed: "Could not load plans right now."
242
+ },
220
243
  checkout: {
221
244
  confirmingTitle: "Confirming your payment",
222
245
  confirmingBody: "This takes a few seconds - please keep this tab open.",
@@ -714,7 +737,7 @@ var KerneClient = (_class = class {
714
737
  * caught everything and returned `false`) - a 401/500 must not be
715
738
  * indistinguishable from a real denial, that's exactly what let the
716
739
  * `has_access`/`allowed` mismatch below ship unnoticed. Callers that want
717
- * a fail-closed boolean regardless of the reason (e.g. `<Allows>`)
740
+ * a fail-closed boolean regardless of the reason (e.g. `<Access>`)
718
741
  * catch around this themselves.
719
742
  */
720
743
  async allows(featureKey, requested) {
@@ -744,13 +767,21 @@ var KerneClient = (_class = class {
744
767
  async getSubscription(productSlug) {
745
768
  const subs = await this.kerne.billing.subscriptions.list({
746
769
  productSlug,
747
- scopeType: "USER"
770
+ subjectType: "USER"
748
771
  });
749
772
  const active = subs.find(
750
773
  (s) => s.status === "ACTIVE" || s.status === "TRIALING" || s.status === "PAST_DUE"
751
774
  );
752
775
  return _nullishCoalesce(active, () => ( null));
753
776
  }
777
+ /** `immediately: true` ends it now; otherwise cancels at period end (API default). */
778
+ async cancelSubscription(subscriptionId, immediately) {
779
+ return this.kerne.billing.subscriptions.cancel(subscriptionId, immediately);
780
+ }
781
+ /** Swaps the plan/price, effective immediately - deferring a downgrade isn't supported yet. */
782
+ async changeSubscriptionPlan(subscriptionId, planPriceId, options) {
783
+ return this.kerne.billing.subscriptions.changePlanPrice(subscriptionId, planPriceId, options);
784
+ }
754
785
  /** Public pricing data - omit `productIdOrSlug` for the tenant's default product. */
755
786
  async getPlans(productIdOrSlug) {
756
787
  return this.kerne.billing.plans(productIdOrSlug);
@@ -923,6 +954,95 @@ function usePortal() {
923
954
  openPortal: _react.useCallback.call(void 0, (returnUrl) => client.openPortal(returnUrl), [client])
924
955
  };
925
956
  }
957
+ function useCancelSubscription() {
958
+ const client = useClient();
959
+ const [isCanceling, setIsCanceling] = _react.useState.call(void 0, false);
960
+ const cancelSubscription = _react.useCallback.call(void 0,
961
+ async (subscriptionId, immediately) => {
962
+ setIsCanceling(true);
963
+ try {
964
+ return await client.cancelSubscription(subscriptionId, immediately);
965
+ } finally {
966
+ setIsCanceling(false);
967
+ }
968
+ },
969
+ [client]
970
+ );
971
+ return { cancelSubscription, isCanceling };
972
+ }
973
+ function useChangePlan() {
974
+ const client = useClient();
975
+ const [isChanging, setIsChanging] = _react.useState.call(void 0, false);
976
+ const changePlan = _react.useCallback.call(void 0,
977
+ async (subscriptionId, planPriceId, options) => {
978
+ setIsChanging(true);
979
+ try {
980
+ return await client.changeSubscriptionPlan(subscriptionId, planPriceId, options);
981
+ } finally {
982
+ setIsChanging(false);
983
+ }
984
+ },
985
+ [client]
986
+ );
987
+ return { changePlan, isChanging };
988
+ }
989
+ function usePlanSwitch(subscription, refetchSubscription, options) {
990
+ const { openCheckout } = useCheckout();
991
+ const { changePlan } = useChangePlan();
992
+ const [pending, setPending] = _react.useState.call(void 0, null);
993
+ const [switching, setSwitching] = _react.useState.call(void 0, false);
994
+ const [switchError, setSwitchError] = _react.useState.call(void 0, null);
995
+ const [checkoutPriceId, setCheckoutPriceId] = _react.useState.call(void 0, null);
996
+ const [checkoutError, setCheckoutError] = _react.useState.call(void 0, null);
997
+ const successUrl = _optionalChain([options, 'optionalAccess', _23 => _23.successUrl]);
998
+ const cancelUrl = _optionalChain([options, 'optionalAccess', _24 => _24.cancelUrl]);
999
+ const selectPlan = _react.useCallback.call(void 0,
1000
+ async (plan, price) => {
1001
+ if (subscription) {
1002
+ setSwitchError(null);
1003
+ setPending({ plan, price });
1004
+ return;
1005
+ }
1006
+ setCheckoutError(null);
1007
+ setCheckoutPriceId(price.id);
1008
+ try {
1009
+ await openCheckout(price.id, { successUrl, cancelUrl });
1010
+ } catch (e) {
1011
+ setCheckoutError(e);
1012
+ setCheckoutPriceId(null);
1013
+ }
1014
+ },
1015
+ [subscription, openCheckout, successUrl, cancelUrl]
1016
+ );
1017
+ const confirmSwitch = _react.useCallback.call(void 0, async () => {
1018
+ if (!pending || !subscription) return;
1019
+ setSwitching(true);
1020
+ setSwitchError(null);
1021
+ try {
1022
+ await changePlan(subscription.id, pending.price.id);
1023
+ setPending(null);
1024
+ refetchSubscription();
1025
+ } catch (e) {
1026
+ setSwitchError(e);
1027
+ } finally {
1028
+ setSwitching(false);
1029
+ }
1030
+ }, [pending, subscription, changePlan, refetchSubscription]);
1031
+ const dismissSwitch = _react.useCallback.call(void 0, () => {
1032
+ setPending(null);
1033
+ setSwitchError(null);
1034
+ }, []);
1035
+ return {
1036
+ pending,
1037
+ switching,
1038
+ switchError,
1039
+ checkoutPriceId,
1040
+ checkoutError,
1041
+ selectPlan,
1042
+ confirmSwitch,
1043
+ dismissSwitch
1044
+ };
1045
+ }
926
1046
  function useAccess(featureKey, requested) {
927
1047
  const client = useClient();
928
1048
  const [state, setState] = _react.useState.call(void 0, {
@@ -957,27 +1077,38 @@ function useSubscription(productSlug) {
957
1077
  isLoading: true,
958
1078
  error: null
959
1079
  });
1080
+ const fetchOnce = _react.useCallback.call(void 0,
1081
+ (mountedRef) => {
1082
+ client.getSubscription(productSlug).then((subscription) => {
1083
+ if (mountedRef.current) {
1084
+ setState({ subscription, isLoading: false, error: null });
1085
+ }
1086
+ }).catch((error) => {
1087
+ if (mountedRef.current) {
1088
+ setState({ subscription: null, isLoading: false, error });
1089
+ }
1090
+ });
1091
+ },
1092
+ [client, productSlug]
1093
+ );
960
1094
  _react.useEffect.call(void 0, () => {
961
- let mounted = true;
962
- client.getSubscription(productSlug).then((subscription) => {
963
- if (mounted) {
964
- setState({ subscription, isLoading: false, error: null });
965
- }
966
- }).catch((error) => {
967
- if (mounted) {
968
- setState({ subscription: null, isLoading: false, error });
969
- }
970
- });
1095
+ const mountedRef = { current: true };
1096
+ fetchOnce(mountedRef);
971
1097
  return () => {
972
- mounted = false;
1098
+ mountedRef.current = false;
973
1099
  };
974
- }, [client, productSlug]);
975
- const isActive = _optionalChain([state, 'access', _23 => _23.subscription, 'optionalAccess', _24 => _24.status]) === "ACTIVE" || _optionalChain([state, 'access', _25 => _25.subscription, 'optionalAccess', _26 => _26.status]) === "TRIALING";
976
- const planSlug = _optionalChain([state, 'access', _27 => _27.subscription, 'optionalAccess', _28 => _28.plan, 'optionalAccess', _29 => _29.slug]);
1100
+ }, [fetchOnce]);
1101
+ const refetch = _react.useCallback.call(void 0, () => {
1102
+ setState((prev) => ({ ...prev, isLoading: true }));
1103
+ fetchOnce({ current: true });
1104
+ }, [fetchOnce]);
1105
+ const isActive = _optionalChain([state, 'access', _25 => _25.subscription, 'optionalAccess', _26 => _26.status]) === "ACTIVE" || _optionalChain([state, 'access', _27 => _27.subscription, 'optionalAccess', _28 => _28.status]) === "TRIALING";
1106
+ const planSlug = _optionalChain([state, 'access', _29 => _29.subscription, 'optionalAccess', _30 => _30.plan, 'optionalAccess', _31 => _31.slug]);
977
1107
  return {
978
1108
  ...state,
979
1109
  isActive,
980
- planSlug
1110
+ planSlug,
1111
+ refetch
981
1112
  };
982
1113
  }
983
1114
  function usePlans(productIdOrSlug) {
@@ -1120,9 +1251,9 @@ function useUser() {
1120
1251
  update: updateProfile,
1121
1252
  // Computed properties
1122
1253
  fullName: user ? `${user.first_name || ""} ${user.last_name || ""}`.trim() : null,
1123
- initials: user ? `${_optionalChain([user, 'access', _30 => _30.first_name, 'optionalAccess', _31 => _31[0]]) || ""}${_optionalChain([user, 'access', _32 => _32.last_name, 'optionalAccess', _33 => _33[0]]) || ""}`.toUpperCase() : null,
1124
- email: _optionalChain([user, 'optionalAccess', _34 => _34.email]) || null,
1125
- emailVerified: _optionalChain([user, 'optionalAccess', _35 => _35.email_verified]) || false
1254
+ initials: user ? `${_optionalChain([user, 'access', _32 => _32.first_name, 'optionalAccess', _33 => _33[0]]) || ""}${_optionalChain([user, 'access', _34 => _34.last_name, 'optionalAccess', _35 => _35[0]]) || ""}`.toUpperCase() : null,
1255
+ email: _optionalChain([user, 'optionalAccess', _36 => _36.email]) || null,
1256
+ emailVerified: _optionalChain([user, 'optionalAccess', _37 => _37.email_verified]) || false
1126
1257
  };
1127
1258
  }
1128
1259
 
@@ -1148,4 +1279,7 @@ function useUser() {
1148
1279
 
1149
1280
 
1150
1281
 
1151
- exports.defaultLocalization = defaultLocalization; exports.useLocalization = useLocalization; exports.fill = fill; exports.fillNode = fillNode; exports.useErrorResolver = useErrorResolver; exports.KerneClient = KerneClient; exports.KerneContext = KerneContext; exports.KerneProvider = KerneProvider; exports.useClient = useClient; exports.useAuth = useAuth; exports.useCheckout = useCheckout; exports.usePortal = usePortal; exports.useAccess = useAccess; exports.useSubscription = useSubscription; exports.usePlans = usePlans; exports.useAuthConfig = useAuthConfig; exports.useEntitlements = useEntitlements; exports.useUsage = useUsage; exports.useWaitlist = useWaitlist; exports.useInvitation = useInvitation; exports.useUser = useUser;
1282
+
1283
+
1284
+
1285
+ exports.defaultLocalization = defaultLocalization; exports.useLocalization = useLocalization; exports.fill = fill; exports.fillNode = fillNode; exports.useErrorResolver = useErrorResolver; exports.KerneClient = KerneClient; exports.KerneContext = KerneContext; exports.KerneProvider = KerneProvider; exports.useClient = useClient; exports.useAuth = useAuth; exports.useCheckout = useCheckout; exports.usePortal = usePortal; exports.useCancelSubscription = useCancelSubscription; exports.useChangePlan = useChangePlan; exports.usePlanSwitch = usePlanSwitch; exports.useAccess = useAccess; exports.useSubscription = useSubscription; exports.usePlans = usePlans; exports.useAuthConfig = useAuthConfig; exports.useEntitlements = useEntitlements; exports.useUsage = useUsage; exports.useWaitlist = useWaitlist; exports.useInvitation = useInvitation; exports.useUser = useUser;
@@ -186,9 +186,20 @@ interface KerneLocalization {
186
186
  freePlan: string;
187
187
  seePlans: string;
188
188
  cancelNotice: string;
189
+ cancelSubscription: string;
190
+ canceling: string;
191
+ cancelConfirmTitle: string;
192
+ cancelConfirmBody: string;
193
+ cancelConfirmButton: string;
194
+ cancelConfirmDismiss: string;
189
195
  changePlan: string;
190
196
  current: string;
191
197
  switchTo: string;
198
+ switching: string;
199
+ switchConfirmTitle: string;
200
+ switchConfirmBody: string;
201
+ switchConfirmButton: string;
202
+ switchConfirmDismiss: string;
192
203
  noPlans: string;
193
204
  notOnInterval: string;
194
205
  loadFailed: string;
@@ -211,8 +222,30 @@ interface KerneLocalization {
211
222
  subtitle: string;
212
223
  used: string;
213
224
  nothingMetered: string;
225
+ /** Overage ALLOW: past the included amount, tolerated and free. */
214
226
  overage: string;
227
+ /** Overage BILL: past the included amount, charged on top of the plan. */
228
+ overageBilled: string;
229
+ /** Overage BLOCK only - ALLOW and BILL never "reach" a limit, they keep going. */
215
230
  limitReached: string;
231
+ /** Overage BILL whose billing cap was hit: charging stopped, access didn't - the opposite of limitReached, not a variant of overageBilled. */
232
+ capReached: string;
233
+ /** Shown under a BILL entitlement once something has actually been billed this period. */
234
+ billedAmount: string;
235
+ loading: string;
236
+ loadFailed: string;
237
+ };
238
+ /** `<PricingTable>` - the marketing surface. Distinct from `billing.*`, the settings-page plan switcher. */
239
+ pricing: {
240
+ getStarted: string;
241
+ /** "{amount} / {interval}" - the caption under a price shown at a different cadence than it's billed. */
242
+ billedAt: string;
243
+ /** "Save {percent}%" - the label-switch hint. */
244
+ save: string;
245
+ /** Prefixes a QUOTA entitlement with no ceiling, e.g. "Unlimited projects". */
246
+ unlimited: string;
247
+ /** "+{count} more" - shown when `maxFeatures` truncates a plan's entitlement list. */
248
+ moreFeatures: string;
216
249
  loading: string;
217
250
  loadFailed: string;
218
251
  };
@@ -186,9 +186,20 @@ interface KerneLocalization {
186
186
  freePlan: string;
187
187
  seePlans: string;
188
188
  cancelNotice: string;
189
+ cancelSubscription: string;
190
+ canceling: string;
191
+ cancelConfirmTitle: string;
192
+ cancelConfirmBody: string;
193
+ cancelConfirmButton: string;
194
+ cancelConfirmDismiss: string;
189
195
  changePlan: string;
190
196
  current: string;
191
197
  switchTo: string;
198
+ switching: string;
199
+ switchConfirmTitle: string;
200
+ switchConfirmBody: string;
201
+ switchConfirmButton: string;
202
+ switchConfirmDismiss: string;
192
203
  noPlans: string;
193
204
  notOnInterval: string;
194
205
  loadFailed: string;
@@ -211,8 +222,30 @@ interface KerneLocalization {
211
222
  subtitle: string;
212
223
  used: string;
213
224
  nothingMetered: string;
225
+ /** Overage ALLOW: past the included amount, tolerated and free. */
214
226
  overage: string;
227
+ /** Overage BILL: past the included amount, charged on top of the plan. */
228
+ overageBilled: string;
229
+ /** Overage BLOCK only - ALLOW and BILL never "reach" a limit, they keep going. */
215
230
  limitReached: string;
231
+ /** Overage BILL whose billing cap was hit: charging stopped, access didn't - the opposite of limitReached, not a variant of overageBilled. */
232
+ capReached: string;
233
+ /** Shown under a BILL entitlement once something has actually been billed this period. */
234
+ billedAmount: string;
235
+ loading: string;
236
+ loadFailed: string;
237
+ };
238
+ /** `<PricingTable>` - the marketing surface. Distinct from `billing.*`, the settings-page plan switcher. */
239
+ pricing: {
240
+ getStarted: string;
241
+ /** "{amount} / {interval}" - the caption under a price shown at a different cadence than it's billed. */
242
+ billedAt: string;
243
+ /** "Save {percent}%" - the label-switch hint. */
244
+ save: string;
245
+ /** Prefixes a QUOTA entitlement with no ceiling, e.g. "Unlimited projects". */
246
+ unlimited: string;
247
+ /** "+{count} more" - shown when `maxFeatures` truncates a plan's entitlement list. */
248
+ moreFeatures: string;
216
249
  loading: string;
217
250
  loadFailed: string;
218
251
  };