@kerne/react 1.2.0 → 1.3.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.
@@ -201,7 +201,9 @@ interface KerneLocalization {
201
201
  switchConfirmButton: string;
202
202
  switchConfirmDismiss: string;
203
203
  noPlans: string;
204
+ /** A plan with no price under the selected PriceLabel - which needn't be a billing interval (see PublicPriceLabel). */
204
205
  notOnInterval: string;
206
+ differentCurrency: string;
205
207
  loadFailed: string;
206
208
  loadingPlan: string;
207
209
  loadingPlans: string;
@@ -242,8 +244,61 @@ interface KerneLocalization {
242
244
  billedAt: string;
243
245
  /** "Save {percent}%" - the label-switch hint. */
244
246
  save: string;
245
- /** Prefixes a QUOTA entitlement with no ceiling, e.g. "Unlimited projects". */
247
+ /** The value column for a QUOTA with no ceiling. */
246
248
  unlimited: string;
249
+ /** The value column for an entitlement that carries no figure - a boolean, or a quota with no declared ceiling. */
250
+ included: string;
251
+ /** The value column for a boolean the plan does NOT grant. */
252
+ notIncluded: string;
253
+ /** Replaces the amount when a plan costs nothing. */
254
+ free: string;
255
+ /** Replaces "/ month" beside `free`. */
256
+ forever: string;
257
+ /** The call to action on a plan that costs nothing. */
258
+ startFree: string;
259
+ /** "{days}-day trial, no card" - under the button that accepts the offer. */
260
+ trialNote: string;
261
+ /** Beside an allowance that keeps serving past its included amount, and bills. */
262
+ thenMetered: string;
263
+ /** Heading of the popover that explains a metered overage. */
264
+ meterTitle: string;
265
+ /** "Rate per {thing}" - the thing being counted, a customer or a slice. */
266
+ meterRatePer: string;
267
+ meterShape: string;
268
+ meterCounted: string;
269
+ meterResets: string;
270
+ meterCapped: string;
271
+ /** "{count} tiers, cheapest {amount}" / "one rate" - how the schedule is read. */
272
+ meterTiers: string;
273
+ meterFlat: string;
274
+ /** Whole quantity at the reached rate, vs each slice at its own. */
275
+ meterVolume: string;
276
+ meterGraduated: string;
277
+ /** "per {slice}" / "per customer", then how a partial block is counted. */
278
+ meterPerSlice: string;
279
+ meterPerCustomer: string;
280
+ /** "every {interval}" - the cadence the allowance actually comes back on. */
281
+ meterResetsEvery: string;
282
+ /** "{amount} per {slice}" on an allowance counted once per slice. */
283
+ perSlice: string;
284
+ meterRoundedUp: string;
285
+ meterRoundedDown: string;
286
+ meterResetsCycle: string;
287
+ meterResetsNever: string;
288
+ /** Stands in for the allowance when nothing is included and every unit bills. */
289
+ metered: string;
290
+ /** Prefixes a rate that falls as volume grows, e.g. "from $0.10 / GB". */
291
+ from: string;
292
+ /** Header of the block where a buyer sizes prepaid volume. */
293
+ sizeUpFront: string;
294
+ /** Caption beside it - prepaid steps bill on the plan's own cycle. */
295
+ billedWithPlan: string;
296
+ /** "{amount} {unit} included" under a sizing rail left at zero. */
297
+ includedAmount: string;
298
+ /** "+{amount} {unit} prepaid" once the rail moves. */
299
+ prepaidAmount: string;
300
+ /** Shown under a plan's hairline when it grants nothing the catalogue can list. */
301
+ nothingListed: string;
247
302
  /** "+{count} more" - shown when `maxFeatures` truncates a plan's entitlement list. */
248
303
  moreFeatures: string;
249
304
  loading: string;
@@ -282,9 +337,86 @@ interface KerneLocalization {
282
337
  };
283
338
  }
284
339
  declare const defaultLocalization: KerneLocalization;
340
+ /**
341
+ * Shallow-merges each top-level group of `override` onto `base` (the English pack by
342
+ * default) so a partial override keeps the rest. Pass a full pack (e.g. `fr`) as `base`
343
+ * to layer a few overrides on top of a whole-language translation instead of English.
344
+ */
345
+ declare function mergeLocalization(override?: DeepPartial<KerneLocalization>, base?: KerneLocalization): KerneLocalization;
285
346
  type DeepPartial<T> = {
286
347
  [K in keyof T]?: Partial<T[K]>;
287
348
  };
288
349
  declare function useLocalization(): KerneLocalization;
289
350
 
290
- export { type DeepPartial as D, type KerneLocalization as K, defaultLocalization as d, useLocalization as u };
351
+ /**
352
+ * Styling for the prebuilt components.
353
+ *
354
+ * A single stylesheet injected once at runtime, rather than a CSS file the
355
+ * host app has to import: the whole point of these components is that a tenant
356
+ * drops one in and it works, and "don't forget to import @kerne/react/styles.css"
357
+ * is exactly the step people forget. It also keeps the package dependency-free -
358
+ * no CSS-in-JS runtime, no Tailwind assumption about the host build.
359
+ *
360
+ * Everything visual resolves from `--kerne-*` custom properties, so a tenant
361
+ * restyles by setting those anywhere in their own CSS (no `!important` war, no
362
+ * forking) and `appearance` overrides them per instance.
363
+ */
364
+ /**
365
+ * The default palette's raw values, for a host that wants its OWN stylesheet to match Kerne's
366
+ * rather than reading them off the rendered page - `.dark` is only the tokens dark actually
367
+ * overrides, not the full set (unset ones inherit `.light`, same as the CSS does).
368
+ */
369
+ declare const defaultTokens: {
370
+ light: Record<string, string>;
371
+ dark: Record<string, string>;
372
+ };
373
+ /**
374
+ * Per-instance overrides of the same custom properties the stylesheet reads,
375
+ * applied as inline style so they win over the class defaults without
376
+ * specificity tricks.
377
+ */
378
+ interface KerneAppearance {
379
+ /**
380
+ * `light` (default), `dark`, or `system` to follow the visitor's OS. Not
381
+ * defaulted to `system`: a light-only host would silently render a dark form
382
+ * for half its users.
383
+ */
384
+ theme?: 'light' | 'dark' | 'system';
385
+ /**
386
+ * The brand colour. Drives the primary button, and - unless overridden below -
387
+ * its label, its hover, and the accent used for focus rings and links.
388
+ */
389
+ primaryColor?: string;
390
+ /** Label on the primary button. Derived from `primaryColor` when omitted. */
391
+ primaryTextColor?: string;
392
+ /** Focus rings and links. Falls back to `primaryColor`. */
393
+ accentColor?: string;
394
+ textColor?: string;
395
+ borderColor?: string;
396
+ /** Background of error/info panels. */
397
+ panelColor?: string;
398
+ /**
399
+ * The ground the component sits on. Leave unset when embedding (the host's
400
+ * page shows through); set it when the component owns the viewport, so its
401
+ * text can never resolve against a background it doesn't know about.
402
+ */
403
+ background?: string;
404
+ /** Opaque ground for the card variant, the account dropdown, a pressed segment. */
405
+ surfaceColor?: string;
406
+ /** `card` wraps the screen in a bordered, raised container. Defaults to `none`. */
407
+ surface?: 'none' | 'card';
408
+ fontFamily?: string;
409
+ /** Corner radius on inputs and buttons, e.g. `"0px"` for square. */
410
+ radius?: string;
411
+ /** Height of inputs and buttons. Defaults to `"44px"`. */
412
+ controlHeight?: string;
413
+ }
414
+
415
+ /**
416
+ * French pack for the prebuilt components - see `KerneLocalization` for the full shape and
417
+ * `defaultLocalization` (English) for the reference this was translated from.
418
+ */
419
+
420
+ declare const fr: KerneLocalization;
421
+
422
+ export { type DeepPartial as D, type KerneLocalization as K, type KerneAppearance as a, defaultTokens as b, defaultLocalization as d, fr as f, mergeLocalization as m, useLocalization as u };
@@ -201,7 +201,9 @@ interface KerneLocalization {
201
201
  switchConfirmButton: string;
202
202
  switchConfirmDismiss: string;
203
203
  noPlans: string;
204
+ /** A plan with no price under the selected PriceLabel - which needn't be a billing interval (see PublicPriceLabel). */
204
205
  notOnInterval: string;
206
+ differentCurrency: string;
205
207
  loadFailed: string;
206
208
  loadingPlan: string;
207
209
  loadingPlans: string;
@@ -242,8 +244,61 @@ interface KerneLocalization {
242
244
  billedAt: string;
243
245
  /** "Save {percent}%" - the label-switch hint. */
244
246
  save: string;
245
- /** Prefixes a QUOTA entitlement with no ceiling, e.g. "Unlimited projects". */
247
+ /** The value column for a QUOTA with no ceiling. */
246
248
  unlimited: string;
249
+ /** The value column for an entitlement that carries no figure - a boolean, or a quota with no declared ceiling. */
250
+ included: string;
251
+ /** The value column for a boolean the plan does NOT grant. */
252
+ notIncluded: string;
253
+ /** Replaces the amount when a plan costs nothing. */
254
+ free: string;
255
+ /** Replaces "/ month" beside `free`. */
256
+ forever: string;
257
+ /** The call to action on a plan that costs nothing. */
258
+ startFree: string;
259
+ /** "{days}-day trial, no card" - under the button that accepts the offer. */
260
+ trialNote: string;
261
+ /** Beside an allowance that keeps serving past its included amount, and bills. */
262
+ thenMetered: string;
263
+ /** Heading of the popover that explains a metered overage. */
264
+ meterTitle: string;
265
+ /** "Rate per {thing}" - the thing being counted, a customer or a slice. */
266
+ meterRatePer: string;
267
+ meterShape: string;
268
+ meterCounted: string;
269
+ meterResets: string;
270
+ meterCapped: string;
271
+ /** "{count} tiers, cheapest {amount}" / "one rate" - how the schedule is read. */
272
+ meterTiers: string;
273
+ meterFlat: string;
274
+ /** Whole quantity at the reached rate, vs each slice at its own. */
275
+ meterVolume: string;
276
+ meterGraduated: string;
277
+ /** "per {slice}" / "per customer", then how a partial block is counted. */
278
+ meterPerSlice: string;
279
+ meterPerCustomer: string;
280
+ /** "every {interval}" - the cadence the allowance actually comes back on. */
281
+ meterResetsEvery: string;
282
+ /** "{amount} per {slice}" on an allowance counted once per slice. */
283
+ perSlice: string;
284
+ meterRoundedUp: string;
285
+ meterRoundedDown: string;
286
+ meterResetsCycle: string;
287
+ meterResetsNever: string;
288
+ /** Stands in for the allowance when nothing is included and every unit bills. */
289
+ metered: string;
290
+ /** Prefixes a rate that falls as volume grows, e.g. "from $0.10 / GB". */
291
+ from: string;
292
+ /** Header of the block where a buyer sizes prepaid volume. */
293
+ sizeUpFront: string;
294
+ /** Caption beside it - prepaid steps bill on the plan's own cycle. */
295
+ billedWithPlan: string;
296
+ /** "{amount} {unit} included" under a sizing rail left at zero. */
297
+ includedAmount: string;
298
+ /** "+{amount} {unit} prepaid" once the rail moves. */
299
+ prepaidAmount: string;
300
+ /** Shown under a plan's hairline when it grants nothing the catalogue can list. */
301
+ nothingListed: string;
247
302
  /** "+{count} more" - shown when `maxFeatures` truncates a plan's entitlement list. */
248
303
  moreFeatures: string;
249
304
  loading: string;
@@ -282,9 +337,86 @@ interface KerneLocalization {
282
337
  };
283
338
  }
284
339
  declare const defaultLocalization: KerneLocalization;
340
+ /**
341
+ * Shallow-merges each top-level group of `override` onto `base` (the English pack by
342
+ * default) so a partial override keeps the rest. Pass a full pack (e.g. `fr`) as `base`
343
+ * to layer a few overrides on top of a whole-language translation instead of English.
344
+ */
345
+ declare function mergeLocalization(override?: DeepPartial<KerneLocalization>, base?: KerneLocalization): KerneLocalization;
285
346
  type DeepPartial<T> = {
286
347
  [K in keyof T]?: Partial<T[K]>;
287
348
  };
288
349
  declare function useLocalization(): KerneLocalization;
289
350
 
290
- export { type DeepPartial as D, type KerneLocalization as K, defaultLocalization as d, useLocalization as u };
351
+ /**
352
+ * Styling for the prebuilt components.
353
+ *
354
+ * A single stylesheet injected once at runtime, rather than a CSS file the
355
+ * host app has to import: the whole point of these components is that a tenant
356
+ * drops one in and it works, and "don't forget to import @kerne/react/styles.css"
357
+ * is exactly the step people forget. It also keeps the package dependency-free -
358
+ * no CSS-in-JS runtime, no Tailwind assumption about the host build.
359
+ *
360
+ * Everything visual resolves from `--kerne-*` custom properties, so a tenant
361
+ * restyles by setting those anywhere in their own CSS (no `!important` war, no
362
+ * forking) and `appearance` overrides them per instance.
363
+ */
364
+ /**
365
+ * The default palette's raw values, for a host that wants its OWN stylesheet to match Kerne's
366
+ * rather than reading them off the rendered page - `.dark` is only the tokens dark actually
367
+ * overrides, not the full set (unset ones inherit `.light`, same as the CSS does).
368
+ */
369
+ declare const defaultTokens: {
370
+ light: Record<string, string>;
371
+ dark: Record<string, string>;
372
+ };
373
+ /**
374
+ * Per-instance overrides of the same custom properties the stylesheet reads,
375
+ * applied as inline style so they win over the class defaults without
376
+ * specificity tricks.
377
+ */
378
+ interface KerneAppearance {
379
+ /**
380
+ * `light` (default), `dark`, or `system` to follow the visitor's OS. Not
381
+ * defaulted to `system`: a light-only host would silently render a dark form
382
+ * for half its users.
383
+ */
384
+ theme?: 'light' | 'dark' | 'system';
385
+ /**
386
+ * The brand colour. Drives the primary button, and - unless overridden below -
387
+ * its label, its hover, and the accent used for focus rings and links.
388
+ */
389
+ primaryColor?: string;
390
+ /** Label on the primary button. Derived from `primaryColor` when omitted. */
391
+ primaryTextColor?: string;
392
+ /** Focus rings and links. Falls back to `primaryColor`. */
393
+ accentColor?: string;
394
+ textColor?: string;
395
+ borderColor?: string;
396
+ /** Background of error/info panels. */
397
+ panelColor?: string;
398
+ /**
399
+ * The ground the component sits on. Leave unset when embedding (the host's
400
+ * page shows through); set it when the component owns the viewport, so its
401
+ * text can never resolve against a background it doesn't know about.
402
+ */
403
+ background?: string;
404
+ /** Opaque ground for the card variant, the account dropdown, a pressed segment. */
405
+ surfaceColor?: string;
406
+ /** `card` wraps the screen in a bordered, raised container. Defaults to `none`. */
407
+ surface?: 'none' | 'card';
408
+ fontFamily?: string;
409
+ /** Corner radius on inputs and buttons, e.g. `"0px"` for square. */
410
+ radius?: string;
411
+ /** Height of inputs and buttons. Defaults to `"44px"`. */
412
+ controlHeight?: string;
413
+ }
414
+
415
+ /**
416
+ * French pack for the prebuilt components - see `KerneLocalization` for the full shape and
417
+ * `defaultLocalization` (English) for the reference this was translated from.
418
+ */
419
+
420
+ declare const fr: KerneLocalization;
421
+
422
+ export { type DeepPartial as D, type KerneLocalization as K, type KerneAppearance as a, defaultTokens as b, defaultLocalization as d, fr as f, mergeLocalization as m, useLocalization as u };
package/dist/index.cjs CHANGED
@@ -21,25 +21,27 @@
21
21
 
22
22
 
23
23
 
24
- var _chunkN6VPGJ36cjs = require('./chunk-N6VPGJ36.cjs');
24
+
25
+
26
+ var _chunk3R66S7BYcjs = require('./chunk-3R66S7BY.cjs');
25
27
 
26
28
  // src/components.tsx
27
29
  var _react = require('react'); var _react2 = _interopRequireDefault(_react);
28
30
  var _jsxruntime = require('react/jsx-runtime');
29
31
  function Authenticated({ children, fallback = null }) {
30
- const { isAuthenticated } = _chunkN6VPGJ36cjs.useAuth.call(void 0, );
32
+ const { isAuthenticated } = _chunk3R66S7BYcjs.useAuth.call(void 0, );
31
33
  return isAuthenticated ? children : fallback;
32
34
  }
33
35
  function Unauthenticated({ children, fallback = null }) {
34
- const { isAuthenticated } = _chunkN6VPGJ36cjs.useAuth.call(void 0, );
36
+ const { isAuthenticated } = _chunk3R66S7BYcjs.useAuth.call(void 0, );
35
37
  return !isAuthenticated ? children : fallback;
36
38
  }
37
39
  function AuthLoading({ children }) {
38
- const client = _chunkN6VPGJ36cjs.useClient.call(void 0, );
40
+ const client = _chunk3R66S7BYcjs.useClient.call(void 0, );
39
41
  return client.isLoading ? children : null;
40
42
  }
41
43
  function HasSubscription({ children, fallback = null }) {
42
- const client = _chunkN6VPGJ36cjs.useClient.call(void 0, );
44
+ const client = _chunk3R66S7BYcjs.useClient.call(void 0, );
43
45
  const [hasSubscription, setHasSubscription] = _react2.default.useState(null);
44
46
  _react2.default.useEffect(() => {
45
47
  client.getSubscription().then((sub) => {
@@ -57,7 +59,7 @@ function Access({
57
59
  requested,
58
60
  fallback = null
59
61
  }) {
60
- const { allowed, isLoading } = _chunkN6VPGJ36cjs.useAccess.call(void 0, featureKey, requested);
62
+ const { allowed, isLoading } = _chunk3R66S7BYcjs.useAccess.call(void 0, featureKey, requested);
61
63
  if (isLoading) return null;
62
64
  return allowed ? children : fallback;
63
65
  }
@@ -68,7 +70,7 @@ function Protected({
68
70
  authFallback = null,
69
71
  billingFallback = null
70
72
  }) {
71
- const { isAuthenticated } = _chunkN6VPGJ36cjs.useAuth.call(void 0, );
73
+ const { isAuthenticated } = _chunk3R66S7BYcjs.useAuth.call(void 0, );
72
74
  if (auth && !isAuthenticated) {
73
75
  return authFallback;
74
76
  }
@@ -81,6 +83,37 @@ function Protected({
81
83
  // src/error-boundary.tsx
82
84
 
83
85
 
86
+ var STYLE_ELEMENT_ID = "kerne-error-boundary-styles";
87
+ var CSS = `
88
+ .kerne-eb { padding: 24px; text-align: center; color: #16171a; }
89
+ .kerne-eb-title { font-size: 20px; font-weight: 600; letter-spacing: -.01em; margin: 0 0 8px; }
90
+ .kerne-eb-body { color: #6b7280; margin: 0 auto 20px; max-width: 40ch; font-size: 14px; line-height: 1.5; }
91
+ .kerne-eb-code { color: #6f7681; margin: -12px 0 20px; font-size: 12px; }
92
+ .kerne-eb-button {
93
+ font: inherit; font-size: 14px; font-weight: 500; height: 44px;
94
+ padding: 0 20px; border-radius: 8px; border: none; cursor: pointer;
95
+ background: #16171a; color: #fff;
96
+ transition: background-color .12s ease;
97
+ }
98
+ .kerne-eb-button:hover { background: #2c2e33; }
99
+ .kerne-eb-button:focus-visible { outline: 2px solid #16171a; outline-offset: 2px; }
100
+ @media (prefers-color-scheme: dark) {
101
+ .kerne-eb { color: #f0f1f3; }
102
+ .kerne-eb-body { color: #9ba2ad; }
103
+ .kerne-eb-code { color: #838b96; }
104
+ .kerne-eb-button { background: #f0f1f3; color: #16181d; }
105
+ .kerne-eb-button:hover { background: #d8dade; }
106
+ .kerne-eb-button:focus-visible { outline-color: #f0f1f3; }
107
+ }
108
+ `;
109
+ function ensureErrorBoundaryStylesInjected() {
110
+ if (typeof document === "undefined") return;
111
+ if (document.getElementById(STYLE_ELEMENT_ID)) return;
112
+ const style = document.createElement("style");
113
+ style.id = STYLE_ELEMENT_ID;
114
+ style.textContent = CSS;
115
+ document.head.appendChild(style);
116
+ }
84
117
  var KerneErrorBoundary = (_class = class extends _react.Component {
85
118
  constructor(props) {
86
119
  super(props);_class.prototype.__init.call(this);;
@@ -111,28 +144,15 @@ var KerneErrorBoundary = (_class = class extends _react.Component {
111
144
  }
112
145
  return fallback;
113
146
  }
114
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { style: { padding: "20px", textAlign: "center" }, children: [
115
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { style: { color: "#dc2626", marginBottom: "10px" }, children: "Something went wrong" }),
116
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { style: { color: "#6b7280", marginBottom: "20px" }, children: error.message || "An unexpected error occurred" }),
117
- error.code && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { style: { color: "#9ca3af", fontSize: "12px", marginBottom: "20px" }, children: [
147
+ ensureErrorBoundaryStylesInjected();
148
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { className: "kerne-eb", children: [
149
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { className: "kerne-eb-title", children: "Something went wrong" }),
150
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { className: "kerne-eb-body", children: error.message || "An unexpected error occurred" }),
151
+ error.code && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { className: "kerne-eb-code", children: [
118
152
  "Error code: ",
119
153
  error.code
120
154
  ] }),
121
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
122
- "button",
123
- {
124
- onClick: this.reset,
125
- style: {
126
- padding: "10px 20px",
127
- backgroundColor: "#3b82f6",
128
- color: "white",
129
- border: "none",
130
- borderRadius: "6px",
131
- cursor: "pointer"
132
- },
133
- children: "Try again"
134
- }
135
- )
155
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { type: "button", className: "kerne-eb-button", onClick: this.reset, children: "Try again" })
136
156
  ] });
137
157
  }
138
158
  return this.props.children;
@@ -183,4 +203,6 @@ function useKerneError() {
183
203
 
184
204
 
185
205
 
186
- exports.Access = Access; exports.AuthLoading = AuthLoading; exports.Authenticated = Authenticated; exports.HasSubscription = HasSubscription; exports.KerneClient = _chunkN6VPGJ36cjs.KerneClient; exports.KerneContext = _chunkN6VPGJ36cjs.KerneContext; exports.KerneErrorBoundary = KerneErrorBoundary; exports.KerneProvider = _chunkN6VPGJ36cjs.KerneProvider; exports.Protected = Protected; exports.Unauthenticated = Unauthenticated; exports.defaultLocalization = _chunkN6VPGJ36cjs.defaultLocalization; exports.useAccess = _chunkN6VPGJ36cjs.useAccess; exports.useAuth = _chunkN6VPGJ36cjs.useAuth; exports.useAuthConfig = _chunkN6VPGJ36cjs.useAuthConfig; exports.useCancelSubscription = _chunkN6VPGJ36cjs.useCancelSubscription; exports.useChangePlan = _chunkN6VPGJ36cjs.useChangePlan; exports.useCheckout = _chunkN6VPGJ36cjs.useCheckout; exports.useClient = _chunkN6VPGJ36cjs.useClient; exports.useEntitlements = _chunkN6VPGJ36cjs.useEntitlements; exports.useInvitation = _chunkN6VPGJ36cjs.useInvitation; exports.useKerneError = useKerneError; exports.usePlanSwitch = _chunkN6VPGJ36cjs.usePlanSwitch; exports.usePlans = _chunkN6VPGJ36cjs.usePlans; exports.usePortal = _chunkN6VPGJ36cjs.usePortal; exports.useReportUsage = _chunkN6VPGJ36cjs.useReportUsage; exports.useSubscription = _chunkN6VPGJ36cjs.useSubscription; exports.useUsage = _chunkN6VPGJ36cjs.useUsage; exports.useUser = _chunkN6VPGJ36cjs.useUser; exports.useWaitlist = _chunkN6VPGJ36cjs.useWaitlist;
206
+
207
+
208
+ exports.Access = Access; exports.AuthLoading = AuthLoading; exports.Authenticated = Authenticated; exports.HasSubscription = HasSubscription; exports.KerneClient = _chunk3R66S7BYcjs.KerneClient; exports.KerneContext = _chunk3R66S7BYcjs.KerneContext; exports.KerneErrorBoundary = KerneErrorBoundary; exports.KerneProvider = _chunk3R66S7BYcjs.KerneProvider; exports.Protected = Protected; exports.Unauthenticated = Unauthenticated; exports.defaultLocalization = _chunk3R66S7BYcjs.defaultLocalization; exports.fr = _chunk3R66S7BYcjs.fr; exports.mergeLocalization = _chunk3R66S7BYcjs.mergeLocalization; exports.useAccess = _chunk3R66S7BYcjs.useAccess; exports.useAuth = _chunk3R66S7BYcjs.useAuth; exports.useAuthConfig = _chunk3R66S7BYcjs.useAuthConfig; exports.useCancelSubscription = _chunk3R66S7BYcjs.useCancelSubscription; exports.useChangePlan = _chunk3R66S7BYcjs.useChangePlan; exports.useCheckout = _chunk3R66S7BYcjs.useCheckout; exports.useClient = _chunk3R66S7BYcjs.useClient; exports.useEntitlements = _chunk3R66S7BYcjs.useEntitlements; exports.useInvitation = _chunk3R66S7BYcjs.useInvitation; exports.useKerneError = useKerneError; exports.usePlanSwitch = _chunk3R66S7BYcjs.usePlanSwitch; exports.usePlans = _chunk3R66S7BYcjs.usePlans; exports.usePortal = _chunk3R66S7BYcjs.usePortal; exports.useReportUsage = _chunk3R66S7BYcjs.useReportUsage; exports.useSubscription = _chunk3R66S7BYcjs.useSubscription; exports.useUsage = _chunk3R66S7BYcjs.useUsage; exports.useUser = _chunk3R66S7BYcjs.useUser; exports.useWaitlist = _chunk3R66S7BYcjs.useWaitlist;
package/dist/index.d.cts CHANGED
@@ -3,10 +3,10 @@ import React, { ReactNode, Component, ErrorInfo } from 'react';
3
3
  import { KerneConfig, ConsumeParams, ReportUsageParams, ReportUsageBatchEvent, BatchUsageResult, JoinWaitlistParams, ValidateTokenResponse, ValidateCodeResponse } from '@kerne/server';
4
4
  export { JoinWaitlistParams, ValidateCodeResponse, ValidateTokenResponse, WaitlistEntry } from '@kerne/server';
5
5
  import * as _kerne_types from '@kerne/types';
6
- import { User, AuthResponse, ActivationContext, AuthConfig, EntitlementCheck, UsageRecord, SubscriptionWithPlan, Subscription, PublicPlan, Entitlements, PublicPlanPrice } from '@kerne/types';
6
+ import { User, AuthResponse, ActivationContext, AuthConfig, EntitlementCheck, UsageRecord, DriverSelection, SubscriptionWithPlan, Subscription, PublicPlan, Entitlements, PublicPlanPrice } from '@kerne/types';
7
7
  export { ActivationContext, AuthConfig, AuthResponse, BatchUsageResult, EntitlementCheck, Entitlements, PublicPlan, Subscription, SubscriptionWithPlan, UsageRecord, User, ValidationFieldError } from '@kerne/types';
8
- import { D as DeepPartial, K as KerneLocalization } from './i18n-CXEhPK58.cjs';
9
- export { d as defaultLocalization } from './i18n-CXEhPK58.cjs';
8
+ import { D as DeepPartial, K as KerneLocalization, a as KerneAppearance } from './fr-E5mmylSH.cjs';
9
+ export { d as defaultLocalization, f as fr, m as mergeLocalization } from './fr-E5mmylSH.cjs';
10
10
 
11
11
  interface KerneReactConfig extends Omit<KerneConfig, 'secretKey'> {
12
12
  storage?: Storage;
@@ -119,14 +119,14 @@ declare class KerneClient {
119
119
  /** Soft-deletes (deactivates) the caller's own account, then clears the local session. */
120
120
  requestAccountDeletion(): Promise<void>;
121
121
  /** Forgot-password flow (logged out) - sends the reset email. */
122
- requestPasswordReset(email: string, callbackUrl?: string): Promise<void>;
122
+ requestPasswordReset(email: string): Promise<void>;
123
123
  /** Confirms a password reset with the token from the email. */
124
124
  confirmPasswordReset(token: string, password: string): Promise<void>;
125
125
  /**
126
126
  * Sends a magic-link email (logged out). Anti-enumeration: always resolves,
127
127
  * regardless of whether the email is registered.
128
128
  */
129
- startPasswordless(email: string, callbackUrl?: string, invitation?: {
129
+ startPasswordless(email: string, invitation?: {
130
130
  invitationToken?: string;
131
131
  invitationCode?: string;
132
132
  }): Promise<void>;
@@ -173,16 +173,10 @@ declare class KerneClient {
173
173
  /** Several usage events in one request instead of one call each - kills the manual request staggering. */
174
174
  reportUsageBatch(events: Array<Omit<ReportUsageBatchEvent, 'subject'>>): Promise<BatchUsageResult[]>;
175
175
  private requireUserId;
176
- createCheckout(planPriceId: string, options?: {
177
- successUrl?: string;
178
- cancelUrl?: string;
179
- }): Promise<string>;
180
- openCheckout(planPriceId: string, options?: {
181
- successUrl?: string;
182
- cancelUrl?: string;
183
- }): Promise<void>;
184
- createPortal(returnUrl?: string): Promise<string>;
185
- openPortal(returnUrl?: string): Promise<void>;
176
+ createCheckout(planPriceId: string, drivers?: DriverSelection[]): Promise<string>;
177
+ openCheckout(planPriceId: string, drivers?: DriverSelection[]): Promise<void>;
178
+ createPortal(): Promise<string>;
179
+ openPortal(): Promise<void>;
186
180
  getSubscription(productSlug?: string): Promise<SubscriptionWithPlan | null>;
187
181
  /** `immediately: true` ends it now; otherwise cancels at period end (API default). */
188
182
  cancelSubscription(subscriptionId: string, immediately?: boolean): Promise<Subscription>;
@@ -203,7 +197,7 @@ declare class KerneClient {
203
197
  validateInvitationToken(token: string): Promise<ValidateTokenResponse>;
204
198
  /** Validate an invitation code before showing the registration form. */
205
199
  validateInvitationCode(code: string): Promise<ValidateCodeResponse>;
206
- sendVerificationEmail(verificationType?: 'code' | 'link', callbackUrl?: string): Promise<void>;
200
+ sendVerificationEmail(verificationType?: 'code' | 'link'): Promise<void>;
207
201
  verifyEmailWithCode(code: string): Promise<{
208
202
  success: boolean;
209
203
  needsTokenRefresh: boolean;
@@ -229,8 +223,14 @@ interface KerneProviderProps extends KerneReactConfig {
229
223
  * override keeps everything it does not mention.
230
224
  */
231
225
  localization?: DeepPartial<KerneLocalization>;
226
+ /**
227
+ * Appearance for every prebuilt component, set once. A host with its own dark
228
+ * mode would otherwise pass it to each one and keep them in sync by hand; a
229
+ * component's own `appearance` still wins, field by field.
230
+ */
231
+ appearance?: KerneAppearance;
232
232
  }
233
- declare function KerneProvider({ children, localization, ...config }: KerneProviderProps): react_jsx_runtime.JSX.Element;
233
+ declare function KerneProvider({ children, localization, appearance, ...config }: KerneProviderProps): react_jsx_runtime.JSX.Element;
234
234
 
235
235
  /**
236
236
  * Access the Kerne client instance
@@ -273,14 +273,14 @@ declare function useAuth(): {
273
273
  newPassword: string;
274
274
  }) => Promise<void>;
275
275
  requestAccountDeletion: () => Promise<void>;
276
- requestPasswordReset: (email: string, callbackUrl?: string) => Promise<void>;
276
+ requestPasswordReset: (email: string) => Promise<void>;
277
277
  confirmPasswordReset: (token: string, password: string) => Promise<void>;
278
- startPasswordless: (email: string, callbackUrl?: string, invitation?: {
278
+ startPasswordless: (email: string, invitation?: {
279
279
  invitationToken?: string;
280
280
  invitationCode?: string;
281
281
  }) => Promise<void>;
282
282
  loginWithMagicLink: (token: string) => Promise<_kerne_types.AuthResponse>;
283
- sendVerificationEmail: (verificationType?: "code" | "link", callbackUrl?: string) => Promise<void>;
283
+ sendVerificationEmail: (verificationType?: "code" | "link") => Promise<void>;
284
284
  verifyEmailWithCode: (code: string) => Promise<{
285
285
  success: boolean;
286
286
  needsTokenRefresh: boolean;
@@ -308,14 +308,8 @@ declare function useAuth(): {
308
308
  * ```
309
309
  */
310
310
  declare function useCheckout(): {
311
- createCheckout: (planPriceId: string, options?: {
312
- successUrl?: string;
313
- cancelUrl?: string;
314
- }) => Promise<string>;
315
- openCheckout: (planPriceId: string, options?: {
316
- successUrl?: string;
317
- cancelUrl?: string;
318
- }) => Promise<void>;
311
+ createCheckout: (planPriceId: string, drivers?: DriverSelection[]) => Promise<string>;
312
+ openCheckout: (planPriceId: string, drivers?: DriverSelection[]) => Promise<void>;
319
313
  };
320
314
  /**
321
315
  * Billing portal hook - lets a user manage their subscription/payment method.
@@ -327,8 +321,8 @@ declare function useCheckout(): {
327
321
  * ```
328
322
  */
329
323
  declare function usePortal(): {
330
- createPortal: (returnUrl?: string) => Promise<string>;
331
- openPortal: (returnUrl?: string) => Promise<void>;
324
+ createPortal: () => Promise<string>;
325
+ openPortal: () => Promise<void>;
332
326
  };
333
327
  /**
334
328
  * Cancels or changes the current scope's own subscription - JWT-scoped like every other hook
@@ -383,16 +377,13 @@ interface PlanSwitchTarget {
383
377
  * usePlanSwitch(subscription, refetch);
384
378
  * ```
385
379
  */
386
- declare function usePlanSwitch(subscription: SubscriptionWithPlan | null, refetchSubscription: () => void, options?: {
387
- successUrl?: string;
388
- cancelUrl?: string;
389
- }): {
380
+ declare function usePlanSwitch(subscription: SubscriptionWithPlan | null, refetchSubscription: () => void): {
390
381
  pending: PlanSwitchTarget | null;
391
382
  switching: boolean;
392
383
  switchError: unknown;
393
384
  checkoutPriceId: string | null;
394
385
  checkoutError: unknown;
395
- selectPlan: (plan: PublicPlan, price: PublicPlanPrice) => Promise<void>;
386
+ selectPlan: (plan: PublicPlan, price: PublicPlanPrice, drivers?: DriverSelection[]) => Promise<void>;
396
387
  confirmSwitch: () => Promise<void>;
397
388
  dismissSwitch: () => void;
398
389
  };
@@ -475,9 +466,13 @@ declare function useAuthConfig(): {
475
466
  };
476
467
  /**
477
468
  * Every entitlement for the current user in one call - for a "your plan"
478
- * screen. Use `useAccess` instead for a single feature - this response
479
- * never carries `allowed` (see docs: the list is cached, a stale verdict
480
- * would be unsafe).
469
+ * screen. `EntitlementSummary` carries no `allowed` field, on purpose: this
470
+ * list is a cached snapshot for display ("12/50 calls used"), not a live
471
+ * verdict. **Never gate access by reading `limit`/`remaining`/`enabled`
472
+ * yourself** - that silently reimplements override precedence, overage
473
+ * rules, and the race against concurrent usage that `useAccess()` already
474
+ * handles server-side. Use `useAccess()` (or `kerne.allows()`/`enforce()`)
475
+ * for every actual gate, and this hook only to render numbers.
481
476
  *
482
477
  * @example
483
478
  * ```tsx