@kerne/react 0.1.2 → 0.1.3

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.
@@ -18,7 +18,19 @@ var defaultLocalization = {
18
18
  sending: "Sending...",
19
19
  continueWith: "Continue with {provider}",
20
20
  securedByKerne: "Secured by Kerne",
21
- loading: "Loading"
21
+ loading: "Loading",
22
+ showPassword: "Show password",
23
+ hidePassword: "Hide password",
24
+ capsLockOn: "Caps Lock is on",
25
+ passwordHint: "At least {count} characters",
26
+ passwordRequireUppercase: "One uppercase letter",
27
+ passwordRequireNumber: "One number",
28
+ passwordRequireSymbol: "One special character",
29
+ strengthLabel: "Password strength",
30
+ strengthWeak: "Weak",
31
+ strengthFair: "Fair",
32
+ strengthGood: "Good",
33
+ strengthStrong: "Strong"
22
34
  },
23
35
  signIn: {
24
36
  title: "Welcome back",
@@ -319,6 +331,7 @@ var KerneClient = (_class = class {
319
331
 
320
332
 
321
333
 
334
+
322
335
  __init() {this.refreshTimer = null}
323
336
  __init2() {this.listeners = /* @__PURE__ */ new Set()}
324
337
  __init3() {this._user = null}
@@ -335,6 +348,7 @@ var KerneClient = (_class = class {
335
348
  this.storage = _nullishCoalesce(config.storage, () => ( (typeof window !== "undefined" ? localStorage : null)));
336
349
  this.storageKey = _nullishCoalesce(config.storageKey, () => ( DEFAULT_STORAGE_KEY));
337
350
  this.onAuthChange = config.onAuthChange;
351
+ this.onHandoffError = config.onHandoffError;
338
352
  this.autoRefresh = _nullishCoalesce(config.autoRefresh, () => ( true));
339
353
  this.refreshBuffer = _nullishCoalesce(config.refreshBuffer, () => ( DEFAULT_REFRESH_BUFFER));
340
354
  this.kerne = new (0, _server.Kerne)({
@@ -455,6 +469,7 @@ var KerneClient = (_class = class {
455
469
  continue;
456
470
  }
457
471
  console.warn("[Kerne] Handoff exchange failed:", e);
472
+ _optionalChain([this, 'access', _4 => _4.onHandoffError, 'optionalCall', _5 => _5(e)]);
458
473
  return;
459
474
  }
460
475
  }
@@ -473,7 +488,7 @@ var KerneClient = (_class = class {
473
488
  } catch (e) {
474
489
  console.warn("[Kerne] Startup refresh failed, clearing session:", e);
475
490
  this._refreshToken = null;
476
- _optionalChain([this, 'access', _4 => _4.storage, 'optionalAccess', _5 => _5.removeItem, 'call', _6 => _6(this.storageKey)]);
491
+ _optionalChain([this, 'access', _6 => _6.storage, 'optionalAccess', _7 => _7.removeItem, 'call', _8 => _8(this.storageKey)]);
477
492
  } finally {
478
493
  this._isLoading = false;
479
494
  this.notify();
@@ -491,7 +506,13 @@ var KerneClient = (_class = class {
491
506
  this._refreshToken = response.refresh_token;
492
507
  this._expiresAt = response.expires_at ? new Date(response.expires_at) : null;
493
508
  this.kerne = this.kerne.withToken(response.token);
494
- this._user = await this.kerne.users.me();
509
+ try {
510
+ this._user = await this.kerne.users.me();
511
+ } catch (e) {
512
+ const sameUser = _optionalChain([this, 'access', _9 => _9._user, 'optionalAccess', _10 => _10.id]) === _optionalChain([response, 'access', _11 => _11.user, 'optionalAccess', _12 => _12.id]);
513
+ console.error("[Kerne] Failed to load the user profile:", e);
514
+ this._user = sameUser ? this._user : null;
515
+ }
495
516
  if (this.storage) {
496
517
  this.storage.setItem(
497
518
  this.storageKey,
@@ -504,7 +525,7 @@ var KerneClient = (_class = class {
504
525
  );
505
526
  }
506
527
  this.scheduleRefresh();
507
- _optionalChain([this, 'access', _7 => _7.onAuthChange, 'optionalCall', _8 => _8(this._user)]);
528
+ _optionalChain([this, 'access', _13 => _13.onAuthChange, 'optionalCall', _14 => _14(this._user)]);
508
529
  this.notify();
509
530
  }
510
531
  clearSession() {
@@ -516,7 +537,7 @@ var KerneClient = (_class = class {
516
537
  if (this.storage) {
517
538
  this.storage.removeItem(this.storageKey);
518
539
  }
519
- _optionalChain([this, 'access', _9 => _9.onAuthChange, 'optionalCall', _10 => _10(null)]);
540
+ _optionalChain([this, 'access', _15 => _15.onAuthChange, 'optionalCall', _16 => _16(null)]);
520
541
  this.notify();
521
542
  }
522
543
  scheduleRefresh() {
@@ -579,7 +600,7 @@ var KerneClient = (_class = class {
579
600
  try {
580
601
  const user = await this.kerne.users.me();
581
602
  this._user = user;
582
- _optionalChain([this, 'access', _11 => _11.onAuthChange, 'optionalCall', _12 => _12(user)]);
603
+ _optionalChain([this, 'access', _17 => _17.onAuthChange, 'optionalCall', _18 => _18(user)]);
583
604
  this.notify();
584
605
  return user;
585
606
  } catch (e2) {
@@ -604,7 +625,7 @@ var KerneClient = (_class = class {
604
625
  } catch (e) {
605
626
  }
606
627
  }
607
- _optionalChain([this, 'access', _13 => _13.onAuthChange, 'optionalCall', _14 => _14(updated)]);
628
+ _optionalChain([this, 'access', _19 => _19.onAuthChange, 'optionalCall', _20 => _20(updated)]);
608
629
  this.notify();
609
630
  return updated;
610
631
  }
@@ -777,7 +798,7 @@ function KerneProvider({ children, localization, ...config }) {
777
798
  }, [config.appId, config.baseUrl]);
778
799
  _react.useEffect.call(void 0, () => {
779
800
  return () => {
780
- _optionalChain([client, 'access', _15 => _15.cancelRefresh, 'optionalCall', _16 => _16()]);
801
+ _optionalChain([client, 'access', _21 => _21.cancelRefresh, 'optionalCall', _22 => _22()]);
781
802
  };
782
803
  }, [client]);
783
804
  const l10n = _react.useMemo.call(void 0, () => mergeLocalization(localization), [localization]);
@@ -951,8 +972,8 @@ function useSubscription(productSlug) {
951
972
  mounted = false;
952
973
  };
953
974
  }, [client, productSlug]);
954
- const isActive = _optionalChain([state, 'access', _17 => _17.subscription, 'optionalAccess', _18 => _18.status]) === "ACTIVE" || _optionalChain([state, 'access', _19 => _19.subscription, 'optionalAccess', _20 => _20.status]) === "TRIALING";
955
- const planSlug = _optionalChain([state, 'access', _21 => _21.subscription, 'optionalAccess', _22 => _22.plan, 'optionalAccess', _23 => _23.slug]);
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]);
956
977
  return {
957
978
  ...state,
958
979
  isActive,
@@ -1099,9 +1120,9 @@ function useUser() {
1099
1120
  update: updateProfile,
1100
1121
  // Computed properties
1101
1122
  fullName: user ? `${user.first_name || ""} ${user.last_name || ""}`.trim() : null,
1102
- initials: user ? `${_optionalChain([user, 'access', _24 => _24.first_name, 'optionalAccess', _25 => _25[0]]) || ""}${_optionalChain([user, 'access', _26 => _26.last_name, 'optionalAccess', _27 => _27[0]]) || ""}`.toUpperCase() : null,
1103
- email: _optionalChain([user, 'optionalAccess', _28 => _28.email]) || null,
1104
- emailVerified: _optionalChain([user, 'optionalAccess', _29 => _29.email_verified]) || false
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
1105
1126
  };
1106
1127
  }
1107
1128
 
@@ -18,7 +18,19 @@ var defaultLocalization = {
18
18
  sending: "Sending...",
19
19
  continueWith: "Continue with {provider}",
20
20
  securedByKerne: "Secured by Kerne",
21
- loading: "Loading"
21
+ loading: "Loading",
22
+ showPassword: "Show password",
23
+ hidePassword: "Hide password",
24
+ capsLockOn: "Caps Lock is on",
25
+ passwordHint: "At least {count} characters",
26
+ passwordRequireUppercase: "One uppercase letter",
27
+ passwordRequireNumber: "One number",
28
+ passwordRequireSymbol: "One special character",
29
+ strengthLabel: "Password strength",
30
+ strengthWeak: "Weak",
31
+ strengthFair: "Fair",
32
+ strengthGood: "Good",
33
+ strengthStrong: "Strong"
22
34
  },
23
35
  signIn: {
24
36
  title: "Welcome back",
@@ -317,6 +329,7 @@ var KerneClient = class {
317
329
  storage;
318
330
  storageKey;
319
331
  onAuthChange;
332
+ onHandoffError;
320
333
  autoRefresh;
321
334
  refreshBuffer;
322
335
  refreshTimer = null;
@@ -335,6 +348,7 @@ var KerneClient = class {
335
348
  this.storage = config.storage ?? (typeof window !== "undefined" ? localStorage : null);
336
349
  this.storageKey = config.storageKey ?? DEFAULT_STORAGE_KEY;
337
350
  this.onAuthChange = config.onAuthChange;
351
+ this.onHandoffError = config.onHandoffError;
338
352
  this.autoRefresh = config.autoRefresh ?? true;
339
353
  this.refreshBuffer = config.refreshBuffer ?? DEFAULT_REFRESH_BUFFER;
340
354
  this.kerne = new Kerne({
@@ -455,6 +469,7 @@ var KerneClient = class {
455
469
  continue;
456
470
  }
457
471
  console.warn("[Kerne] Handoff exchange failed:", e);
472
+ this.onHandoffError?.(e);
458
473
  return;
459
474
  }
460
475
  }
@@ -491,7 +506,13 @@ var KerneClient = class {
491
506
  this._refreshToken = response.refresh_token;
492
507
  this._expiresAt = response.expires_at ? new Date(response.expires_at) : null;
493
508
  this.kerne = this.kerne.withToken(response.token);
494
- this._user = await this.kerne.users.me();
509
+ try {
510
+ this._user = await this.kerne.users.me();
511
+ } catch (e) {
512
+ const sameUser = this._user?.id === response.user?.id;
513
+ console.error("[Kerne] Failed to load the user profile:", e);
514
+ this._user = sameUser ? this._user : null;
515
+ }
495
516
  if (this.storage) {
496
517
  this.storage.setItem(
497
518
  this.storageKey,
@@ -16,6 +16,22 @@ interface KerneLocalization {
16
16
  continueWith: string;
17
17
  securedByKerne: string;
18
18
  loading: string;
19
+ showPassword: string;
20
+ hidePassword: string;
21
+ capsLockOn: string;
22
+ /**
23
+ * The tenant's password rules, stated before the server can reject them.
24
+ * Only the rules that tenant actually enforces are rendered.
25
+ */
26
+ passwordHint: string;
27
+ passwordRequireUppercase: string;
28
+ passwordRequireNumber: string;
29
+ passwordRequireSymbol: string;
30
+ strengthLabel: string;
31
+ strengthWeak: string;
32
+ strengthFair: string;
33
+ strengthGood: string;
34
+ strengthStrong: string;
19
35
  };
20
36
  signIn: {
21
37
  title: string;
@@ -16,6 +16,22 @@ interface KerneLocalization {
16
16
  continueWith: string;
17
17
  securedByKerne: string;
18
18
  loading: string;
19
+ showPassword: string;
20
+ hidePassword: string;
21
+ capsLockOn: string;
22
+ /**
23
+ * The tenant's password rules, stated before the server can reject them.
24
+ * Only the rules that tenant actually enforces are rendered.
25
+ */
26
+ passwordHint: string;
27
+ passwordRequireUppercase: string;
28
+ passwordRequireNumber: string;
29
+ passwordRequireSymbol: string;
30
+ strengthLabel: string;
31
+ strengthWeak: string;
32
+ strengthFair: string;
33
+ strengthGood: string;
34
+ strengthStrong: string;
19
35
  };
20
36
  signIn: {
21
37
  title: string;
package/dist/index.cjs CHANGED
@@ -17,25 +17,25 @@
17
17
 
18
18
 
19
19
 
20
- var _chunk3PROPZWWcjs = require('./chunk-3PROPZWW.cjs');
20
+ var _chunk7U3QBMA7cjs = require('./chunk-7U3QBMA7.cjs');
21
21
 
22
22
  // src/components.tsx
23
23
  var _react = require('react'); var _react2 = _interopRequireDefault(_react);
24
24
  var _jsxruntime = require('react/jsx-runtime');
25
25
  function Authenticated({ children, fallback = null }) {
26
- const { isAuthenticated } = _chunk3PROPZWWcjs.useAuth.call(void 0, );
26
+ const { isAuthenticated } = _chunk7U3QBMA7cjs.useAuth.call(void 0, );
27
27
  return isAuthenticated ? children : fallback;
28
28
  }
29
29
  function Unauthenticated({ children, fallback = null }) {
30
- const { isAuthenticated } = _chunk3PROPZWWcjs.useAuth.call(void 0, );
30
+ const { isAuthenticated } = _chunk7U3QBMA7cjs.useAuth.call(void 0, );
31
31
  return !isAuthenticated ? children : fallback;
32
32
  }
33
33
  function AuthLoading({ children }) {
34
- const client = _chunk3PROPZWWcjs.useClient.call(void 0, );
34
+ const client = _chunk7U3QBMA7cjs.useClient.call(void 0, );
35
35
  return client.isLoading ? children : null;
36
36
  }
37
37
  function HasSubscription({ children, fallback = null }) {
38
- const client = _chunk3PROPZWWcjs.useClient.call(void 0, );
38
+ const client = _chunk7U3QBMA7cjs.useClient.call(void 0, );
39
39
  const [hasSubscription, setHasSubscription] = _react2.default.useState(null);
40
40
  _react2.default.useEffect(() => {
41
41
  client.getSubscription().then((sub) => {
@@ -53,7 +53,7 @@ function Allows({
53
53
  minimum,
54
54
  fallback = null
55
55
  }) {
56
- const client = _chunk3PROPZWWcjs.useClient.call(void 0, );
56
+ const client = _chunk7U3QBMA7cjs.useClient.call(void 0, );
57
57
  const [allowed, setAllowed] = _react2.default.useState(null);
58
58
  _react2.default.useEffect(() => {
59
59
  client.allows(featureKey, minimum).then((result) => {
@@ -72,7 +72,7 @@ function Protected({
72
72
  authFallback = null,
73
73
  billingFallback = null
74
74
  }) {
75
- const { isAuthenticated } = _chunk3PROPZWWcjs.useAuth.call(void 0, );
75
+ const { isAuthenticated } = _chunk7U3QBMA7cjs.useAuth.call(void 0, );
76
76
  if (auth && !isAuthenticated) {
77
77
  return authFallback;
78
78
  }
@@ -183,4 +183,4 @@ function useKerneError() {
183
183
 
184
184
 
185
185
 
186
- exports.Allows = Allows; exports.AuthLoading = AuthLoading; exports.Authenticated = Authenticated; exports.HasSubscription = HasSubscription; exports.KerneClient = _chunk3PROPZWWcjs.KerneClient; exports.KerneContext = _chunk3PROPZWWcjs.KerneContext; exports.KerneErrorBoundary = KerneErrorBoundary; exports.KerneProvider = _chunk3PROPZWWcjs.KerneProvider; exports.Protected = Protected; exports.Unauthenticated = Unauthenticated; exports.defaultLocalization = _chunk3PROPZWWcjs.defaultLocalization; exports.useAccess = _chunk3PROPZWWcjs.useAccess; exports.useAuth = _chunk3PROPZWWcjs.useAuth; exports.useAuthConfig = _chunk3PROPZWWcjs.useAuthConfig; exports.useCheckout = _chunk3PROPZWWcjs.useCheckout; exports.useClient = _chunk3PROPZWWcjs.useClient; exports.useEntitlements = _chunk3PROPZWWcjs.useEntitlements; exports.useInvitation = _chunk3PROPZWWcjs.useInvitation; exports.useKerneError = useKerneError; exports.usePlans = _chunk3PROPZWWcjs.usePlans; exports.usePortal = _chunk3PROPZWWcjs.usePortal; exports.useSubscription = _chunk3PROPZWWcjs.useSubscription; exports.useUsage = _chunk3PROPZWWcjs.useUsage; exports.useUser = _chunk3PROPZWWcjs.useUser; exports.useWaitlist = _chunk3PROPZWWcjs.useWaitlist;
186
+ exports.Allows = Allows; exports.AuthLoading = AuthLoading; exports.Authenticated = Authenticated; exports.HasSubscription = HasSubscription; exports.KerneClient = _chunk7U3QBMA7cjs.KerneClient; exports.KerneContext = _chunk7U3QBMA7cjs.KerneContext; exports.KerneErrorBoundary = KerneErrorBoundary; exports.KerneProvider = _chunk7U3QBMA7cjs.KerneProvider; exports.Protected = Protected; exports.Unauthenticated = Unauthenticated; exports.defaultLocalization = _chunk7U3QBMA7cjs.defaultLocalization; exports.useAccess = _chunk7U3QBMA7cjs.useAccess; exports.useAuth = _chunk7U3QBMA7cjs.useAuth; exports.useAuthConfig = _chunk7U3QBMA7cjs.useAuthConfig; exports.useCheckout = _chunk7U3QBMA7cjs.useCheckout; exports.useClient = _chunk7U3QBMA7cjs.useClient; exports.useEntitlements = _chunk7U3QBMA7cjs.useEntitlements; exports.useInvitation = _chunk7U3QBMA7cjs.useInvitation; exports.useKerneError = useKerneError; exports.usePlans = _chunk7U3QBMA7cjs.usePlans; exports.usePortal = _chunk7U3QBMA7cjs.usePortal; exports.useSubscription = _chunk7U3QBMA7cjs.useSubscription; exports.useUsage = _chunk7U3QBMA7cjs.useUsage; exports.useUser = _chunk7U3QBMA7cjs.useUser; exports.useWaitlist = _chunk7U3QBMA7cjs.useWaitlist;
package/dist/index.d.cts CHANGED
@@ -5,13 +5,23 @@ export { JoinWaitlistParams, ValidateCodeResponse, ValidateTokenResponse, Waitli
5
5
  import * as _kerne_types from '@kerne/types';
6
6
  import { User, AuthResponse, ActivationContext, AuthConfig, EntitlementCheck, SubscriptionWithPlan, PublicPlan, Entitlements, UsageRecord } from '@kerne/types';
7
7
  export { ActivationContext, AuthConfig, AuthResponse, EntitlementCheck, Entitlements, PublicPlan, Subscription, SubscriptionWithPlan, UsageRecord, User } from '@kerne/types';
8
- import { D as DeepPartial, K as KerneLocalization } from './i18n-Qketn1RF.cjs';
9
- export { d as defaultLocalization } from './i18n-Qketn1RF.cjs';
8
+ import { D as DeepPartial, K as KerneLocalization } from './i18n-BWTT1DWD.cjs';
9
+ export { d as defaultLocalization } from './i18n-BWTT1DWD.cjs';
10
10
 
11
11
  interface KerneReactConfig extends Omit<KerneConfig, 'secretKey'> {
12
12
  storage?: Storage;
13
13
  storageKey?: string;
14
14
  onAuthChange?: (user: User | null) => void;
15
+ /**
16
+ * A cross-origin handoff arrived but could not be exchanged for a session -
17
+ * an expired one-time code, or an origin this tenant does not allow.
18
+ *
19
+ * Worth handling: the SDK cannot render UI, so without this the user
20
+ * completes a magic link, lands on your app, and is simply not signed in
21
+ * with nothing on screen explaining why. Typically a toast plus a link back
22
+ * to sign in.
23
+ */
24
+ onHandoffError?: (error: unknown) => void;
15
25
  /** Auto-refresh session before expiry (default: true) */
16
26
  autoRefresh?: boolean;
17
27
  /** Refresh buffer in seconds before expiry (default: 60) */
@@ -24,6 +34,7 @@ declare class KerneClient {
24
34
  private storage;
25
35
  private storageKey;
26
36
  private onAuthChange?;
37
+ private onHandoffError?;
27
38
  private autoRefresh;
28
39
  private refreshBuffer;
29
40
  private refreshTimer;
package/dist/index.d.ts CHANGED
@@ -5,13 +5,23 @@ export { JoinWaitlistParams, ValidateCodeResponse, ValidateTokenResponse, Waitli
5
5
  import * as _kerne_types from '@kerne/types';
6
6
  import { User, AuthResponse, ActivationContext, AuthConfig, EntitlementCheck, SubscriptionWithPlan, PublicPlan, Entitlements, UsageRecord } from '@kerne/types';
7
7
  export { ActivationContext, AuthConfig, AuthResponse, EntitlementCheck, Entitlements, PublicPlan, Subscription, SubscriptionWithPlan, UsageRecord, User } from '@kerne/types';
8
- import { D as DeepPartial, K as KerneLocalization } from './i18n-Qketn1RF.js';
9
- export { d as defaultLocalization } from './i18n-Qketn1RF.js';
8
+ import { D as DeepPartial, K as KerneLocalization } from './i18n-BWTT1DWD.js';
9
+ export { d as defaultLocalization } from './i18n-BWTT1DWD.js';
10
10
 
11
11
  interface KerneReactConfig extends Omit<KerneConfig, 'secretKey'> {
12
12
  storage?: Storage;
13
13
  storageKey?: string;
14
14
  onAuthChange?: (user: User | null) => void;
15
+ /**
16
+ * A cross-origin handoff arrived but could not be exchanged for a session -
17
+ * an expired one-time code, or an origin this tenant does not allow.
18
+ *
19
+ * Worth handling: the SDK cannot render UI, so without this the user
20
+ * completes a magic link, lands on your app, and is simply not signed in
21
+ * with nothing on screen explaining why. Typically a toast plus a link back
22
+ * to sign in.
23
+ */
24
+ onHandoffError?: (error: unknown) => void;
15
25
  /** Auto-refresh session before expiry (default: true) */
16
26
  autoRefresh?: boolean;
17
27
  /** Refresh buffer in seconds before expiry (default: 60) */
@@ -24,6 +34,7 @@ declare class KerneClient {
24
34
  private storage;
25
35
  private storageKey;
26
36
  private onAuthChange?;
37
+ private onHandoffError?;
27
38
  private autoRefresh;
28
39
  private refreshBuffer;
29
40
  private refreshTimer;
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  useUsage,
18
18
  useUser,
19
19
  useWaitlist
20
- } from "./chunk-AIUIBAYB.js";
20
+ } from "./chunk-F6NV76OR.js";
21
21
 
22
22
  // src/components.tsx
23
23
  import React from "react";