@insforge/react 1.0.5-dev.0 → 1.0.5-dev.2

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/dist/index.d.cts CHANGED
@@ -5,6 +5,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import { ReactNode } from 'react';
6
6
  import { InsforgeUser, InsforgeContextValue, OAuthProvider } from '@insforge/shared';
7
7
  export { InsforgeContextValue, InsforgeUser, OAuthProvider } from '@insforge/shared';
8
+ import { InsForgeClient } from '@insforge/sdk';
8
9
  export { useAuth, usePublicAuthConfig, useUser } from './hooks.cjs';
9
10
  export { checkPasswordStrength, createPasswordSchema, emailSchema, passwordSchema, resolveAuthPath, resolveAuthUrl, validateEmail, validatePassword } from './lib.cjs';
10
11
  import { OAuthProviderConfig } from './types.cjs';
@@ -19,7 +20,7 @@ interface InitialAuthState {
19
20
  }
20
21
  interface InsforgeProviderProps {
21
22
  children: ReactNode;
22
- baseUrl: string;
23
+ client: InsForgeClient;
23
24
  /**
24
25
  * URL to redirect to after successful sign in (when token is detected in URL)
25
26
  * @default '/'
@@ -73,7 +74,7 @@ interface InsforgeProviderProps {
73
74
  * </InsforgeProvider>
74
75
  * ```
75
76
  */
76
- declare function InsforgeProviderCore({ children, baseUrl, afterSignInUrl, onAuthChange, onSignIn, onSignOut, onRefresh, initialState, }: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
77
+ declare function InsforgeProviderCore({ children, client, afterSignInUrl, onAuthChange, onSignIn, onSignOut, onRefresh, initialState, }: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
77
78
  declare function InsforgeProvider(props: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
78
79
  /**
79
80
  * Hook to access Insforge context
package/dist/index.d.ts CHANGED
@@ -5,6 +5,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
5
5
  import { ReactNode } from 'react';
6
6
  import { InsforgeUser, InsforgeContextValue, OAuthProvider } from '@insforge/shared';
7
7
  export { InsforgeContextValue, InsforgeUser, OAuthProvider } from '@insforge/shared';
8
+ import { InsForgeClient } from '@insforge/sdk';
8
9
  export { useAuth, usePublicAuthConfig, useUser } from './hooks.js';
9
10
  export { checkPasswordStrength, createPasswordSchema, emailSchema, passwordSchema, resolveAuthPath, resolveAuthUrl, validateEmail, validatePassword } from './lib.js';
10
11
  import { OAuthProviderConfig } from './types.js';
@@ -19,7 +20,7 @@ interface InitialAuthState {
19
20
  }
20
21
  interface InsforgeProviderProps {
21
22
  children: ReactNode;
22
- baseUrl: string;
23
+ client: InsForgeClient;
23
24
  /**
24
25
  * URL to redirect to after successful sign in (when token is detected in URL)
25
26
  * @default '/'
@@ -73,7 +74,7 @@ interface InsforgeProviderProps {
73
74
  * </InsforgeProvider>
74
75
  * ```
75
76
  */
76
- declare function InsforgeProviderCore({ children, baseUrl, afterSignInUrl, onAuthChange, onSignIn, onSignOut, onRefresh, initialState, }: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
77
+ declare function InsforgeProviderCore({ children, client, afterSignInUrl, onAuthChange, onSignIn, onSignOut, onRefresh, initialState, }: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
77
78
  declare function InsforgeProvider(props: InsforgeProviderProps): react_jsx_runtime.JSX.Element;
78
79
  /**
79
80
  * Hook to access Insforge context
package/dist/index.js CHANGED
@@ -15,7 +15,6 @@ if (typeof document !== 'undefined' && typeof window !== 'undefined') {
15
15
  import * as React2 from 'react';
16
16
  import { createContext, forwardRef, useContext, useState, useMemo, useEffect, useRef, useCallback, isValidElement, cloneElement } from 'react';
17
17
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
18
- import { createClient } from '@insforge/sdk';
19
18
  import { InsforgeContext } from '@insforge/shared/react';
20
19
  import { AlertTriangle, Check, EyeOff, Eye, Loader2, CircleCheck, X, User, LogOut } from 'lucide-react';
21
20
  import { z } from 'zod';
@@ -467,6 +466,8 @@ function useSearchParams() {
467
466
  const adapter = useNavigationAdapter();
468
467
  return adapter.useSearchParams();
469
468
  }
469
+
470
+ // src/core/InsforgeManager.ts
470
471
  var InsforgeManager = class _InsforgeManager {
471
472
  // Static private instance
472
473
  static instance = null;
@@ -482,7 +483,7 @@ var InsforgeManager = class _InsforgeManager {
482
483
  // Private constructor (prevents external instantiation)
483
484
  constructor(config) {
484
485
  this.config = config;
485
- this.sdk = createClient({ baseUrl: config.baseUrl });
486
+ this.sdk = config.client;
486
487
  this.user = void 0;
487
488
  this.isLoaded = false;
488
489
  }
@@ -490,6 +491,9 @@ var InsforgeManager = class _InsforgeManager {
490
491
  static getInstance(config) {
491
492
  if (typeof window !== "undefined" && _InsforgeManager.instance) {
492
493
  _InsforgeManager.instance.updateConfig(config);
494
+ if (config.client && _InsforgeManager.instance.sdk !== config.client) {
495
+ _InsforgeManager.instance.sdk = config.client;
496
+ }
493
497
  return _InsforgeManager.instance;
494
498
  }
495
499
  _InsforgeManager.instance = new _InsforgeManager(config);
@@ -567,15 +571,10 @@ var InsforgeManager = class _InsforgeManager {
567
571
  }
568
572
  const userResult = await this.sdk.auth.getCurrentUser();
569
573
  if (userResult.data) {
570
- const profile = userResult.data.user.profile;
571
- const { name, avatar_url, ...dynamicFields } = profile || {};
572
574
  const userData = {
573
575
  id: userResult.data.user.id,
574
576
  email: userResult.data.user.email,
575
- name: name || "",
576
- avatarUrl: avatar_url || "",
577
- // Store additional dynamic fields
578
- profile: Object.keys(dynamicFields).length > 0 ? dynamicFields : void 0
577
+ profile: userResult.data.user.profile
579
578
  };
580
579
  this.user = userData;
581
580
  if (this.config.onAuthChange) {
@@ -611,15 +610,10 @@ var InsforgeManager = class _InsforgeManager {
611
610
  async handleAuthSuccess(authToken, fallbackUser) {
612
611
  const userResult = await this.sdk.auth.getCurrentUser();
613
612
  if (userResult.data) {
614
- const profile = userResult.data.user.profile;
615
- const { name, avatar_url, ...dynamicFields } = profile || {};
616
613
  const userData = {
617
614
  id: userResult.data.user.id,
618
615
  email: userResult.data.user.email,
619
- name: name || "",
620
- avatarUrl: avatar_url || "",
621
- // Store additional dynamic fields
622
- profile: Object.keys(dynamicFields).length > 0 ? dynamicFields : void 0
616
+ profile: userResult.data.user.profile
623
617
  };
624
618
  this.user = userData;
625
619
  this.notifyListeners();
@@ -639,8 +633,7 @@ var InsforgeManager = class _InsforgeManager {
639
633
  const userData = {
640
634
  id: fallbackUser.id || "",
641
635
  email: fallbackUser.email || "",
642
- name: fallbackUser.name || "",
643
- avatarUrl: ""
636
+ profile: fallbackUser.profile || null
644
637
  };
645
638
  this.user = userData;
646
639
  this.notifyListeners();
@@ -661,7 +654,7 @@ var InsforgeManager = class _InsforgeManager {
661
654
  sdkResult.data.user ? {
662
655
  id: sdkResult.data.user.id,
663
656
  email: sdkResult.data.user.email,
664
- name: sdkResult.data.user.profile?.name || ""
657
+ profile: sdkResult.data.user.profile || void 0
665
658
  } : void 0
666
659
  );
667
660
  return sdkResult.data;
@@ -682,7 +675,7 @@ var InsforgeManager = class _InsforgeManager {
682
675
  sdkResult.data.user ? {
683
676
  id: sdkResult.data.user.id,
684
677
  email: sdkResult.data.user.email,
685
- name: sdkResult.data.user.profile?.name || ""
678
+ profile: sdkResult.data.user.profile || void 0
686
679
  } : void 0
687
680
  );
688
681
  }
@@ -720,26 +713,15 @@ var InsforgeManager = class _InsforgeManager {
720
713
  if (!this.user) {
721
714
  return { error: "No user signed in" };
722
715
  }
723
- const profileUpdate = {};
724
- if (data.name !== void 0) {
725
- profileUpdate.name = data.name;
726
- }
727
- if (data.avatarUrl !== void 0) {
728
- profileUpdate.avatar_url = data.avatarUrl;
716
+ if (!data) {
717
+ return { error: "No profile data provided" };
729
718
  }
730
- if (data.profile) {
731
- Object.assign(profileUpdate, data.profile);
732
- }
733
- const result = await this.sdk.auth.setProfile(profileUpdate);
719
+ const result = await this.sdk.auth.setProfile(data);
734
720
  if (result.data) {
735
721
  const updatedUser = {
736
722
  id: this.user.id,
737
723
  email: this.user.email,
738
- // Use sent value if provided, otherwise keep existing
739
- name: profileUpdate.name !== void 0 ? profileUpdate.name : this.user.name || "",
740
- avatarUrl: profileUpdate.avatar_url !== void 0 ? profileUpdate.avatar_url : this.user.avatarUrl || "",
741
- // Merge existing profile with new dynamic fields
742
- profile: data.profile ? { ...this.user.profile, ...data.profile } : this.user.profile
724
+ profile: data
743
725
  };
744
726
  this.user = updatedUser;
745
727
  if (this.config.onAuthChange) {
@@ -841,12 +823,10 @@ var InsforgeManager = class _InsforgeManager {
841
823
  return;
842
824
  }
843
825
  if (initialState.userId) {
844
- const normalizeValue = (val) => val && val !== "null" ? val : "";
845
826
  this.user = {
846
827
  id: initialState.userId,
847
- email: normalizeValue(initialState.user?.email),
848
- name: normalizeValue(initialState.user?.name),
849
- avatarUrl: normalizeValue(initialState.user?.avatarUrl)
828
+ email: initialState.user?.email || "",
829
+ profile: initialState.user?.profile || null
850
830
  };
851
831
  } else {
852
832
  this.user = null;
@@ -2190,7 +2170,7 @@ function StyleProvider({ children, nonce }) {
2190
2170
  }
2191
2171
  function InsforgeProviderCore({
2192
2172
  children,
2193
- baseUrl,
2173
+ client,
2194
2174
  afterSignInUrl = "/",
2195
2175
  onAuthChange,
2196
2176
  onSignIn,
@@ -2200,14 +2180,14 @@ function InsforgeProviderCore({
2200
2180
  }) {
2201
2181
  const manager = useMemo(
2202
2182
  () => InsforgeManager.getInstance({
2203
- baseUrl,
2183
+ client,
2204
2184
  afterSignInUrl,
2205
2185
  onAuthChange,
2206
2186
  onSignIn,
2207
2187
  onSignOut,
2208
2188
  onRefresh
2209
2189
  }),
2210
- [baseUrl, afterSignInUrl, onAuthChange, onSignIn, onSignOut, onRefresh]
2190
+ [client, afterSignInUrl, onAuthChange, onSignIn, onSignOut, onRefresh]
2211
2191
  );
2212
2192
  if (initialState) {
2213
2193
  const currentState = manager.getState();
@@ -2259,7 +2239,7 @@ function InsforgeProviderCore({
2259
2239
  loginWithOAuth: (provider, redirectTo) => manager.loginWithOAuth(provider, redirectTo),
2260
2240
  getPublicAuthConfig: () => manager.getPublicAuthConfig(),
2261
2241
  // Config
2262
- baseUrl: manager.getConfig().baseUrl,
2242
+ baseUrl: manager.getConfig().client.getHttpClient().baseUrl,
2263
2243
  afterSignInUrl: manager.getConfig().afterSignInUrl || "/"
2264
2244
  }),
2265
2245
  [state, manager]
@@ -5465,7 +5445,7 @@ var ProfileSpinner = styled.div`
5465
5445
  }
5466
5446
  `;
5467
5447
  var READ_ONLY_FIELDS = ["id", "email", "avatar_url", "created_at", "updated_at"];
5468
- var HIDDEN_FIELDS = ["id"];
5448
+ var HIDDEN_FIELDS = ["id", "avatar_url"];
5469
5449
  function formatFieldLabel(key) {
5470
5450
  return key.replace(/_/g, " ").replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase();
5471
5451
  }
@@ -5477,9 +5457,7 @@ function UserProfileModal({ onClose, onError }) {
5477
5457
  const [formData, setFormData] = useState({});
5478
5458
  useEffect(() => {
5479
5459
  if (user) {
5480
- const initialData = {
5481
- name: user.name || ""
5482
- };
5460
+ const initialData = {};
5483
5461
  if (user.profile) {
5484
5462
  Object.entries(user.profile).forEach(([key, value]) => {
5485
5463
  if (!HIDDEN_FIELDS.includes(key) && typeof value === "string") {
@@ -5492,7 +5470,7 @@ function UserProfileModal({ onClose, onError }) {
5492
5470
  }, [user]);
5493
5471
  useEffect(() => {
5494
5472
  setImageError(false);
5495
- const avatarUrl = user?.avatarUrl;
5473
+ const avatarUrl = user?.profile?.avatar_url;
5496
5474
  if (!avatarUrl) {
5497
5475
  return;
5498
5476
  }
@@ -5510,7 +5488,7 @@ function UserProfileModal({ onClose, onError }) {
5510
5488
  }
5511
5489
  };
5512
5490
  void checkImageUrl();
5513
- }, [user?.avatarUrl]);
5491
+ }, [user?.profile?.avatar_url]);
5514
5492
  const handleFieldChange = useCallback((key, value) => {
5515
5493
  setFormData((prev2) => ({
5516
5494
  ...prev2,
@@ -5523,7 +5501,9 @@ function UserProfileModal({ onClose, onError }) {
5523
5501
  try {
5524
5502
  const { name, ...dynamicFields } = formData;
5525
5503
  const updateData = {
5526
- name
5504
+ profile: {
5505
+ name
5506
+ }
5527
5507
  };
5528
5508
  if (Object.keys(dynamicFields).length > 0) {
5529
5509
  updateData.profile = dynamicFields;
@@ -5543,7 +5523,7 @@ function UserProfileModal({ onClose, onError }) {
5543
5523
  const handleCancel = useCallback(() => {
5544
5524
  if (user) {
5545
5525
  const resetData = {
5546
- name: user.name || ""
5526
+ name: user.profile?.name || ""
5547
5527
  };
5548
5528
  if (user.profile) {
5549
5529
  Object.entries(user.profile).forEach(([key, value]) => {
@@ -5580,12 +5560,12 @@ function UserProfileModal({ onClose, onError }) {
5580
5560
  if (!isLoaded || !user) {
5581
5561
  return null;
5582
5562
  }
5583
- const initials = user.name ? user.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
5563
+ const initials = user.profile?.name ? user.profile.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
5584
5564
  const fields = [];
5585
5565
  fields.push({ key: "email", value: user.email, readOnly: true });
5586
5566
  fields.push({
5587
5567
  key: "name",
5588
- value: isEditing ? formData.name || "" : user.name || "",
5568
+ value: isEditing ? formData.name || "" : user.profile?.name || "",
5589
5569
  readOnly: false
5590
5570
  });
5591
5571
  if (user.profile) {
@@ -5605,11 +5585,11 @@ function UserProfileModal({ onClose, onError }) {
5605
5585
  /* @__PURE__ */ jsx(ProfileModalCloseButton, { onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx(X, {}) })
5606
5586
  ] }),
5607
5587
  /* @__PURE__ */ jsxs(ProfileModalBody, { children: [
5608
- /* @__PURE__ */ jsx(ProfileAvatarSection, { children: /* @__PURE__ */ jsx(ProfileAvatar, { children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsx(
5588
+ /* @__PURE__ */ jsx(ProfileAvatarSection, { children: /* @__PURE__ */ jsx(ProfileAvatar, { children: user.profile?.avatar_url && !imageError ? /* @__PURE__ */ jsx(
5609
5589
  ProfileAvatarImage,
5610
5590
  {
5611
- src: user.avatarUrl,
5612
- alt: user.name || user.email,
5591
+ src: user.profile.avatar_url,
5592
+ alt: user.profile?.name || user.email,
5613
5593
  onError: () => setImageError(true)
5614
5594
  }
5615
5595
  ) : initials }) }),
@@ -5628,7 +5608,7 @@ function UserProfileModal({ onClose, onError }) {
5628
5608
  ] }),
5629
5609
  /* @__PURE__ */ jsx(ProfileModalFooter, { children: isEditing ? /* @__PURE__ */ jsxs(Fragment, { children: [
5630
5610
  /* @__PURE__ */ jsx(ProfileButton, { onClick: handleCancel, disabled: isSaving, children: "Cancel" }),
5631
- /* @__PURE__ */ jsxs(ProfileButton, { $primary: true, onClick: handleSave, disabled: isSaving, children: [
5611
+ /* @__PURE__ */ jsxs(ProfileButton, { $primary: true, onClick: () => void handleSave(), disabled: isSaving, children: [
5632
5612
  isSaving && /* @__PURE__ */ jsx(ProfileSpinner, {}),
5633
5613
  isSaving ? "Saving..." : "Save"
5634
5614
  ] })
@@ -5651,7 +5631,7 @@ function UserButton({
5651
5631
  const menuRef = useRef(null);
5652
5632
  useEffect(() => {
5653
5633
  setImageError(false);
5654
- const avatarUrl = user?.avatarUrl;
5634
+ const avatarUrl = user?.profile?.avatar_url;
5655
5635
  if (!avatarUrl) {
5656
5636
  return;
5657
5637
  }
@@ -5672,7 +5652,7 @@ function UserButton({
5672
5652
  }
5673
5653
  };
5674
5654
  void checkImageUrl();
5675
- }, [user?.avatarUrl]);
5655
+ }, [user?.profile?.avatar_url]);
5676
5656
  useEffect(() => {
5677
5657
  if (isOpen && dropdownRef.current) {
5678
5658
  const buttonRect = dropdownRef.current.getBoundingClientRect();
@@ -5716,7 +5696,7 @@ function UserButton({
5716
5696
  if (!user) {
5717
5697
  return null;
5718
5698
  }
5719
- const initials = user.name ? user.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
5699
+ const initials = user.profile?.name ? user.profile.name.charAt(0).toUpperCase() : user.email.split("@")[0].slice(0, 2).toUpperCase();
5720
5700
  return /* @__PURE__ */ jsxs(UserButtonContainer, { ref: dropdownRef, children: [
5721
5701
  /* @__PURE__ */ jsxs(
5722
5702
  UserButtonButton,
@@ -5726,16 +5706,16 @@ function UserButton({
5726
5706
  "aria-expanded": isOpen,
5727
5707
  "aria-haspopup": "true",
5728
5708
  children: [
5729
- /* @__PURE__ */ jsx(UserButtonAvatar, { children: user.avatarUrl && !imageError ? /* @__PURE__ */ jsx(
5709
+ /* @__PURE__ */ jsx(UserButtonAvatar, { children: user.profile?.avatar_url && !imageError ? /* @__PURE__ */ jsx(
5730
5710
  UserButtonAvatarImage,
5731
5711
  {
5732
- src: user.avatarUrl,
5712
+ src: user.profile.avatar_url,
5733
5713
  alt: user.email,
5734
5714
  onError: () => setImageError(true)
5735
5715
  }
5736
5716
  ) : /* @__PURE__ */ jsx(UserButtonAvatarInitials, { children: initials }) }),
5737
5717
  mode === "detailed" && /* @__PURE__ */ jsxs(UserButtonInfo, { children: [
5738
- user.name && /* @__PURE__ */ jsx(UserButtonName, { children: user.name }),
5718
+ user.profile?.name && /* @__PURE__ */ jsx(UserButtonName, { children: user.profile.name }),
5739
5719
  /* @__PURE__ */ jsx(UserButtonEmail, { children: user.email })
5740
5720
  ] })
5741
5721
  ]
@@ -5760,13 +5740,7 @@ function UserButton({
5760
5740
  "Sign out"
5761
5741
  ] }) })
5762
5742
  ] }),
5763
- showProfileModal && /* @__PURE__ */ jsx(
5764
- UserProfileModal,
5765
- {
5766
- onClose: () => setShowProfileModal(false),
5767
- onError: onProfileError
5768
- }
5769
- )
5743
+ showProfileModal && /* @__PURE__ */ jsx(UserProfileModal, { onClose: () => setShowProfileModal(false), onError: onProfileError })
5770
5744
  ] });
5771
5745
  }
5772
5746
  function Protect({