@nebulr-group/bridge-svelte 0.2.0 → 0.3.0-beta.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.
Files changed (84) hide show
  1. package/dist/auth/route-guard.d.ts +2 -32
  2. package/dist/auth/route-guard.js +16 -96
  3. package/dist/client/BridgeBootstrap.d.ts +6 -3
  4. package/dist/client/BridgeBootstrap.js +35 -30
  5. package/dist/client/BridgeBootstrap.svelte +14 -12
  6. package/dist/client/components/ProfileName.svelte +18 -0
  7. package/dist/client/components/ProfileName.svelte.d.ts +6 -0
  8. package/dist/client/components/developer/ApiTokenManagement.svelte +365 -0
  9. package/dist/client/components/developer/ApiTokenManagement.svelte.d.ts +6 -0
  10. package/dist/client/components/sdk-auth/ForgotPassword.svelte +170 -0
  11. package/dist/client/components/sdk-auth/ForgotPassword.svelte.d.ts +10 -0
  12. package/dist/client/components/sdk-auth/LoginForm.svelte +414 -0
  13. package/dist/client/components/sdk-auth/LoginForm.svelte.d.ts +25 -0
  14. package/dist/client/components/sdk-auth/MagicLink.svelte +92 -0
  15. package/dist/client/components/sdk-auth/MagicLink.svelte.d.ts +9 -0
  16. package/dist/client/components/sdk-auth/MfaChallenge.svelte +150 -0
  17. package/dist/client/components/sdk-auth/MfaChallenge.svelte.d.ts +9 -0
  18. package/dist/client/components/sdk-auth/MfaSetup.svelte +182 -0
  19. package/dist/client/components/sdk-auth/MfaSetup.svelte.d.ts +8 -0
  20. package/dist/client/components/sdk-auth/PasskeyLogin.svelte +99 -0
  21. package/dist/client/components/sdk-auth/PasskeyLogin.svelte.d.ts +10 -0
  22. package/dist/client/components/sdk-auth/PasskeyRequestSetupLink.svelte +83 -0
  23. package/dist/client/components/sdk-auth/PasskeyRequestSetupLink.svelte.d.ts +7 -0
  24. package/dist/client/components/sdk-auth/PasskeySetup.svelte +151 -0
  25. package/dist/client/components/sdk-auth/PasskeySetup.svelte.d.ts +11 -0
  26. package/dist/client/components/sdk-auth/SignupForm.svelte +119 -0
  27. package/dist/client/components/sdk-auth/SignupForm.svelte.d.ts +14 -0
  28. package/dist/client/components/sdk-auth/SsoButton.svelte +70 -0
  29. package/dist/client/components/sdk-auth/SsoButton.svelte.d.ts +13 -0
  30. package/dist/client/components/sdk-auth/SsoProviderIcon.svelte +56 -0
  31. package/dist/client/components/sdk-auth/SsoProviderIcon.svelte.d.ts +7 -0
  32. package/dist/client/components/sdk-auth/TenantSelector.svelte +83 -0
  33. package/dist/client/components/sdk-auth/TenantSelector.svelte.d.ts +11 -0
  34. package/dist/client/components/sdk-auth/WorkspaceSelector.svelte +109 -0
  35. package/dist/client/components/sdk-auth/WorkspaceSelector.svelte.d.ts +16 -0
  36. package/dist/client/components/sdk-auth/shared/Alert.svelte +17 -0
  37. package/dist/client/components/sdk-auth/shared/Alert.svelte.d.ts +9 -0
  38. package/dist/client/components/sdk-auth/shared/AuthFormWrapper.svelte +23 -0
  39. package/dist/client/components/sdk-auth/shared/AuthFormWrapper.svelte.d.ts +10 -0
  40. package/dist/client/components/sdk-auth/shared/Spinner.svelte +16 -0
  41. package/dist/client/components/sdk-auth/shared/Spinner.svelte.d.ts +7 -0
  42. package/dist/client/components/subscription/PlanSelector.svelte +204 -0
  43. package/dist/client/components/subscription/PlanSelector.svelte.d.ts +22 -0
  44. package/dist/client/components/team/TeamAddUserDialog.svelte +125 -0
  45. package/dist/client/components/team/TeamAddUserDialog.svelte.d.ts +17 -0
  46. package/dist/client/components/team/TeamConfirmDialog.svelte +80 -0
  47. package/dist/client/components/team/TeamConfirmDialog.svelte.d.ts +21 -0
  48. package/dist/client/components/team/TeamEditUserDialog.svelte +131 -0
  49. package/dist/client/components/team/TeamEditUserDialog.svelte.d.ts +19 -0
  50. package/dist/client/components/team/TeamManagementPanel.svelte +72 -0
  51. package/dist/client/components/team/TeamManagementPanel.svelte.d.ts +20 -0
  52. package/dist/client/components/team/TeamProfileForm.svelte +129 -0
  53. package/dist/client/components/team/TeamProfileForm.svelte.d.ts +7 -0
  54. package/dist/client/components/team/TeamUserActionsMenu.svelte +63 -0
  55. package/dist/client/components/team/TeamUserActionsMenu.svelte.d.ts +9 -0
  56. package/dist/client/components/team/TeamUserList.svelte +226 -0
  57. package/dist/client/components/team/TeamUserList.svelte.d.ts +7 -0
  58. package/dist/client/components/team/TeamWorkspaceForm.svelte +134 -0
  59. package/dist/client/components/team/TeamWorkspaceForm.svelte.d.ts +7 -0
  60. package/dist/client/stores/config.store.js +8 -5
  61. package/dist/client/utils/cn.d.ts +1 -0
  62. package/dist/client/utils/cn.js +3 -0
  63. package/dist/core/bridge-instance.d.ts +52 -0
  64. package/dist/core/bridge-instance.js +160 -0
  65. package/dist/index.d.ts +26 -6
  66. package/dist/index.js +26 -7
  67. package/dist/shared/feature-flag.js +6 -60
  68. package/dist/shared/logger.d.ts +1 -0
  69. package/dist/shared/logger.js +7 -13
  70. package/dist/shared/profile.d.ts +13 -42
  71. package/dist/shared/profile.js +19 -95
  72. package/dist/shared/types/config.d.ts +8 -13
  73. package/dist/styles.css +1089 -0
  74. package/package.json +60 -37
  75. package/dist/client/components/auth/Login.svelte +0 -20
  76. package/dist/client/components/auth/Login.svelte.d.ts +0 -18
  77. package/dist/client/components/team/TeamManagement.svelte +0 -139
  78. package/dist/client/components/team/TeamManagement.svelte.d.ts +0 -3
  79. package/dist/client/stores/profile.store.d.ts +0 -10
  80. package/dist/client/stores/profile.store.js +0 -29
  81. package/dist/shared/services/auth.service.d.ts +0 -24
  82. package/dist/shared/services/auth.service.js +0 -241
  83. package/dist/shared/services/plan.service.d.ts +0 -7
  84. package/dist/shared/services/plan.service.js +0 -90
@@ -0,0 +1,20 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type Tab = {
4
+ id: 'users' | 'profile' | 'workspace';
5
+ label: string;
6
+ };
7
+ interface Props extends HTMLAttributes<HTMLDivElement> {
8
+ defaultTab?: 'users' | 'profile' | 'workspace';
9
+ showProfileTab?: boolean;
10
+ showWorkspaceTab?: boolean;
11
+ onError?: (error: Error) => void;
12
+ tabBar?: Snippet<[{
13
+ tabs: Tab[];
14
+ activeTab: string;
15
+ setTab: (id: string) => void;
16
+ }]>;
17
+ }
18
+ declare const TeamManagementPanel: import("svelte").Component<Props, {}, "">;
19
+ type TeamManagementPanel = ReturnType<typeof TeamManagementPanel>;
20
+ export default TeamManagementPanel;
@@ -0,0 +1,129 @@
1
+ <script lang="ts">
2
+ import type { TeamProfile } from '@thebridge/auth-core';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import { onMount } from 'svelte';
5
+ import { getBridgeAuth } from '../../../core/bridge-instance.js';
6
+ import Alert from '../sdk-auth/shared/Alert.svelte';
7
+ import Spinner from '../sdk-auth/shared/Spinner.svelte';
8
+
9
+ interface Props extends HTMLAttributes<HTMLDivElement> {
10
+ onError?: (error: Error) => void;
11
+ }
12
+
13
+ let {
14
+ onError,
15
+ class: className,
16
+ style,
17
+ ...rest
18
+ }: Props = $props();
19
+
20
+ let profile = $state<TeamProfile | null>(null);
21
+ let firstName = $state('');
22
+ let lastName = $state('');
23
+ let loading = $state(true);
24
+ let saving = $state(false);
25
+ let error = $state<string | null>(null);
26
+ let success = $state<string | null>(null);
27
+
28
+ onMount(() => {
29
+ loadProfile();
30
+ });
31
+
32
+ async function loadProfile() {
33
+ loading = true;
34
+ error = null;
35
+ try {
36
+ const bridge = getBridgeAuth();
37
+ profile = await bridge.team.getProfile();
38
+ firstName = profile.firstName ?? '';
39
+ lastName = profile.lastName ?? '';
40
+ } catch (err) {
41
+ const e = err instanceof Error ? err : new Error('Failed to load profile');
42
+ error = e.message;
43
+ onError?.(e);
44
+ } finally {
45
+ loading = false;
46
+ }
47
+ }
48
+
49
+ async function handleSubmit() {
50
+ saving = true;
51
+ error = null;
52
+ success = null;
53
+ try {
54
+ const bridge = getBridgeAuth();
55
+ profile = await bridge.team.updateProfile({ firstName, lastName });
56
+ success = 'Profile updated successfully.';
57
+ } catch (err) {
58
+ const e = err instanceof Error ? err : new Error('Failed to update profile');
59
+ error = e.message;
60
+ onError?.(e);
61
+ } finally {
62
+ saving = false;
63
+ }
64
+ }
65
+ </script>
66
+
67
+ <div class={className} {style} data-bridge-team-profile {...rest}>
68
+ <h3 class="bridge-team-section-title">My Profile</h3>
69
+
70
+ {#if loading}
71
+ <div class="bridge-team-loading">
72
+ <Spinner size={32} />
73
+ <span>Loading profile...</span>
74
+ </div>
75
+ {:else}
76
+ {#if error}
77
+ <div class="bridge-team-alert"><Alert variant="error">{error}</Alert></div>
78
+ {/if}
79
+ {#if success}
80
+ <div class="bridge-team-alert"><Alert variant="success">{success}</Alert></div>
81
+ {/if}
82
+
83
+ <form class="bridge-team-form" onsubmit={(e) => { e.preventDefault(); handleSubmit(); }}>
84
+ <div class="bridge-team-form-group">
85
+ <label for="bridge-profile-email">Email</label>
86
+ <input id="bridge-profile-email" type="email" value={profile?.email ?? ''} disabled />
87
+ </div>
88
+
89
+ <div class="bridge-team-form-row">
90
+ <div class="bridge-team-form-group">
91
+ <label for="bridge-profile-first-name">First Name</label>
92
+ <input
93
+ id="bridge-profile-first-name"
94
+ type="text"
95
+ bind:value={firstName}
96
+ disabled={saving}
97
+ />
98
+ </div>
99
+
100
+ <div class="bridge-team-form-group">
101
+ <label for="bridge-profile-last-name">Last Name</label>
102
+ <input
103
+ id="bridge-profile-last-name"
104
+ type="text"
105
+ bind:value={lastName}
106
+ disabled={saving}
107
+ />
108
+ </div>
109
+ </div>
110
+
111
+ {#if profile?.role}
112
+ <div class="bridge-team-form-group">
113
+ <label>Role</label>
114
+ <div class="bridge-team-readonly">{profile.role}</div>
115
+ </div>
116
+ {/if}
117
+
118
+ <div class="bridge-team-form-actions">
119
+ <button
120
+ type="submit"
121
+ class="bridge-btn bridge-btn-primary"
122
+ disabled={saving}
123
+ >
124
+ {saving ? 'Saving...' : 'Save Changes'}
125
+ </button>
126
+ </div>
127
+ </form>
128
+ {/if}
129
+ </div>
@@ -0,0 +1,7 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ interface Props extends HTMLAttributes<HTMLDivElement> {
3
+ onError?: (error: Error) => void;
4
+ }
5
+ declare const TeamProfileForm: import("svelte").Component<Props, {}, "">;
6
+ type TeamProfileForm = ReturnType<typeof TeamProfileForm>;
7
+ export default TeamProfileForm;
@@ -0,0 +1,63 @@
1
+ <script lang="ts">
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+
4
+ interface Props extends HTMLAttributes<HTMLDivElement> {
5
+ onedit?: () => void;
6
+ onresetpassword?: () => void;
7
+ ondelete?: () => void;
8
+ }
9
+
10
+ let {
11
+ onedit,
12
+ onresetpassword,
13
+ ondelete,
14
+ class: className,
15
+ style,
16
+ ...rest
17
+ }: Props = $props();
18
+
19
+ let isOpen = $state(false);
20
+ let menuEl: HTMLDivElement | undefined = $state();
21
+
22
+ function toggle(e: MouseEvent) {
23
+ e.stopPropagation();
24
+ isOpen = !isOpen;
25
+ }
26
+
27
+ function handleAction(fn?: () => void) {
28
+ isOpen = false;
29
+ fn?.();
30
+ }
31
+
32
+ function handleClickOutside(e: MouseEvent) {
33
+ if (isOpen && menuEl && !menuEl.contains(e.target as Node)) {
34
+ isOpen = false;
35
+ }
36
+ }
37
+ </script>
38
+
39
+ <svelte:document onclick={handleClickOutside} />
40
+
41
+ <div class={className} {style} data-bridge-team-actions bind:this={menuEl} {...rest}>
42
+ <button class="bridge-team-actions-trigger" onclick={toggle} aria-label="Actions">
43
+ <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
44
+ <circle cx="8" cy="3" r="1.5" />
45
+ <circle cx="8" cy="8" r="1.5" />
46
+ <circle cx="8" cy="13" r="1.5" />
47
+ </svg>
48
+ </button>
49
+
50
+ {#if isOpen}
51
+ <div class="bridge-team-actions-menu">
52
+ <button class="bridge-team-actions-item" onclick={() => handleAction(onedit)}>
53
+ Edit
54
+ </button>
55
+ <button class="bridge-team-actions-item" onclick={() => handleAction(onresetpassword)}>
56
+ Reset Password
57
+ </button>
58
+ <button class="bridge-team-actions-item bridge-team-actions-item--danger" onclick={() => handleAction(ondelete)}>
59
+ Delete
60
+ </button>
61
+ </div>
62
+ {/if}
63
+ </div>
@@ -0,0 +1,9 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ interface Props extends HTMLAttributes<HTMLDivElement> {
3
+ onedit?: () => void;
4
+ onresetpassword?: () => void;
5
+ ondelete?: () => void;
6
+ }
7
+ declare const TeamUserActionsMenu: import("svelte").Component<Props, {}, "">;
8
+ type TeamUserActionsMenu = ReturnType<typeof TeamUserActionsMenu>;
9
+ export default TeamUserActionsMenu;
@@ -0,0 +1,226 @@
1
+ <script lang="ts">
2
+ import type { TeamUser } from '@thebridge/auth-core';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import { onMount } from 'svelte';
5
+ import { getBridgeAuth } from '../../../core/bridge-instance.js';
6
+ import Alert from '../sdk-auth/shared/Alert.svelte';
7
+ import Spinner from '../sdk-auth/shared/Spinner.svelte';
8
+ import TeamAddUserDialog from './TeamAddUserDialog.svelte';
9
+ import TeamConfirmDialog from './TeamConfirmDialog.svelte';
10
+ import TeamEditUserDialog from './TeamEditUserDialog.svelte';
11
+ import TeamUserActionsMenu from './TeamUserActionsMenu.svelte';
12
+
13
+ interface Props extends HTMLAttributes<HTMLDivElement> {
14
+ onError?: (error: Error) => void;
15
+ }
16
+
17
+ let {
18
+ onError,
19
+ class: className,
20
+ style,
21
+ ...rest
22
+ }: Props = $props();
23
+
24
+ let users = $state<TeamUser[]>([]);
25
+ let roles = $state<string[]>([]);
26
+ let mfaEnabled = $state(false);
27
+ let loading = $state(true);
28
+ let error = $state<string | null>(null);
29
+
30
+ // Dialog states
31
+ let showAddDialog = $state(false);
32
+ let showEditDialog = $state(false);
33
+ let editingUser = $state<TeamUser | null>(null);
34
+ let showDeleteConfirm = $state(false);
35
+ let showResetConfirm = $state(false);
36
+ let deletingUser = $state<TeamUser | null>(null);
37
+ let resettingUser = $state<TeamUser | null>(null);
38
+ let actionLoading = $state(false);
39
+
40
+ onMount(() => {
41
+ loadData();
42
+ });
43
+
44
+ async function loadData() {
45
+ loading = true;
46
+ error = null;
47
+ try {
48
+ const bridge = getBridgeAuth();
49
+ const [userResult, rolesResult] = await Promise.all([
50
+ bridge.team.listUsers(),
51
+ bridge.team.listUserRoles(),
52
+ ]);
53
+ users = userResult.users;
54
+ mfaEnabled = userResult.mfaEnabled;
55
+ roles = rolesResult;
56
+ } catch (err) {
57
+ const e = err instanceof Error ? err : new Error('Failed to load users');
58
+ error = e.message;
59
+ onError?.(e);
60
+ } finally {
61
+ loading = false;
62
+ }
63
+ }
64
+
65
+ function openEdit(user: TeamUser) {
66
+ editingUser = user;
67
+ showEditDialog = true;
68
+ }
69
+
70
+ function openDelete(user: TeamUser) {
71
+ deletingUser = user;
72
+ showDeleteConfirm = true;
73
+ }
74
+
75
+ function openResetPassword(user: TeamUser) {
76
+ resettingUser = user;
77
+ showResetConfirm = true;
78
+ }
79
+
80
+ function handleUsersAdded(added: TeamUser[]) {
81
+ users = [...users, ...added];
82
+ }
83
+
84
+ function handleUserUpdated(updated: TeamUser) {
85
+ users = users.map((u) => (u.id === updated.id ? updated : u));
86
+ }
87
+
88
+ async function handleDeleteConfirm() {
89
+ if (!deletingUser) return;
90
+ actionLoading = true;
91
+ try {
92
+ const bridge = getBridgeAuth();
93
+ await bridge.team.deleteUser(deletingUser.id);
94
+ users = users.filter((u) => u.id !== deletingUser!.id);
95
+ showDeleteConfirm = false;
96
+ deletingUser = null;
97
+ } catch (err) {
98
+ const e = err instanceof Error ? err : new Error('Failed to delete user');
99
+ onError?.(e);
100
+ } finally {
101
+ actionLoading = false;
102
+ }
103
+ }
104
+
105
+ async function handleResetConfirm() {
106
+ if (!resettingUser) return;
107
+ actionLoading = true;
108
+ try {
109
+ const bridge = getBridgeAuth();
110
+ await bridge.team.sendPasswordResetLink(resettingUser.id);
111
+ showResetConfirm = false;
112
+ resettingUser = null;
113
+ } catch (err) {
114
+ const e = err instanceof Error ? err : new Error('Failed to send reset link');
115
+ onError?.(e);
116
+ } finally {
117
+ actionLoading = false;
118
+ }
119
+ }
120
+ </script>
121
+
122
+ <div class={className} {style} data-bridge-team-users {...rest}>
123
+ <div class="bridge-team-users-header">
124
+ <h3 class="bridge-team-users-title">Team Members</h3>
125
+ <button class="bridge-btn bridge-btn-primary" onclick={() => (showAddDialog = true)}>
126
+ Add Member
127
+ </button>
128
+ </div>
129
+
130
+ {#if loading}
131
+ <div class="bridge-team-loading">
132
+ <Spinner size={32} />
133
+ <span>Loading team members...</span>
134
+ </div>
135
+ {:else if error}
136
+ <Alert variant="error">{error}</Alert>
137
+ {:else if users.length === 0}
138
+ <div class="bridge-team-empty">
139
+ <p>No team members yet.</p>
140
+ <button class="bridge-btn bridge-btn-primary" onclick={() => (showAddDialog = true)}>
141
+ Add your first team member
142
+ </button>
143
+ </div>
144
+ {:else}
145
+ <div class="bridge-team-table-wrapper">
146
+ <table class="bridge-team-table">
147
+ <thead>
148
+ <tr>
149
+ <th>User</th>
150
+ <th>Role</th>
151
+ <th>Status</th>
152
+ <th></th>
153
+ </tr>
154
+ </thead>
155
+ <tbody>
156
+ {#each users as user (user.id)}
157
+ <tr>
158
+ <td>
159
+ <div class="bridge-team-user-cell">
160
+ <div class="bridge-team-user-name">
161
+ {user.fullName || user.username || user.email}
162
+ </div>
163
+ <div class="bridge-team-user-email">{user.email}</div>
164
+ </div>
165
+ </td>
166
+ <td>
167
+ <span class="bridge-team-badge">{user.role ?? '—'}</span>
168
+ </td>
169
+ <td>
170
+ <span
171
+ class="bridge-team-status"
172
+ data-state={user.enabled ? 'active' : 'disabled'}
173
+ >
174
+ {user.enabled ? 'Active' : 'Disabled'}
175
+ </span>
176
+ </td>
177
+ <td class="bridge-team-actions-cell">
178
+ <TeamUserActionsMenu
179
+ onedit={() => openEdit(user)}
180
+ onresetpassword={() => openResetPassword(user)}
181
+ ondelete={() => openDelete(user)}
182
+ />
183
+ </td>
184
+ </tr>
185
+ {/each}
186
+ </tbody>
187
+ </table>
188
+ </div>
189
+ {/if}
190
+ </div>
191
+
192
+ <TeamAddUserDialog
193
+ open={showAddDialog}
194
+ onclose={() => (showAddDialog = false)}
195
+ onadded={handleUsersAdded}
196
+ />
197
+
198
+ <TeamEditUserDialog
199
+ open={showEditDialog}
200
+ user={editingUser}
201
+ {roles}
202
+ onclose={() => { showEditDialog = false; editingUser = null; }}
203
+ onupdated={handleUserUpdated}
204
+ />
205
+
206
+ <TeamConfirmDialog
207
+ open={showDeleteConfirm}
208
+ title="Delete User"
209
+ message="Are you sure you want to delete {deletingUser?.email ?? 'this user'}? This action cannot be undone."
210
+ confirmLabel="Delete"
211
+ variant="danger"
212
+ loading={actionLoading}
213
+ onconfirm={handleDeleteConfirm}
214
+ oncancel={() => { showDeleteConfirm = false; deletingUser = null; }}
215
+ />
216
+
217
+ <TeamConfirmDialog
218
+ open={showResetConfirm}
219
+ title="Reset Password"
220
+ message="Send a password reset link to {resettingUser?.email ?? 'this user'}?"
221
+ confirmLabel="Send Reset Link"
222
+ variant="default"
223
+ loading={actionLoading}
224
+ onconfirm={handleResetConfirm}
225
+ oncancel={() => { showResetConfirm = false; resettingUser = null; }}
226
+ />
@@ -0,0 +1,7 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ interface Props extends HTMLAttributes<HTMLDivElement> {
3
+ onError?: (error: Error) => void;
4
+ }
5
+ declare const TeamUserList: import("svelte").Component<Props, {}, "">;
6
+ type TeamUserList = ReturnType<typeof TeamUserList>;
7
+ export default TeamUserList;
@@ -0,0 +1,134 @@
1
+ <script lang="ts">
2
+ import type { TeamWorkspace } from '@thebridge/auth-core';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import { onMount } from 'svelte';
5
+ import { getBridgeAuth } from '../../../core/bridge-instance.js';
6
+ import Alert from '../sdk-auth/shared/Alert.svelte';
7
+ import Spinner from '../sdk-auth/shared/Spinner.svelte';
8
+
9
+ interface Props extends HTMLAttributes<HTMLDivElement> {
10
+ onError?: (error: Error) => void;
11
+ }
12
+
13
+ let {
14
+ onError,
15
+ class: className,
16
+ style,
17
+ ...rest
18
+ }: Props = $props();
19
+
20
+ let workspace = $state<TeamWorkspace | null>(null);
21
+ let name = $state('');
22
+ let locale = $state('');
23
+ let loading = $state(true);
24
+ let saving = $state(false);
25
+ let error = $state<string | null>(null);
26
+ let success = $state<string | null>(null);
27
+
28
+ onMount(() => {
29
+ loadWorkspace();
30
+ });
31
+
32
+ async function loadWorkspace() {
33
+ loading = true;
34
+ error = null;
35
+ try {
36
+ const bridge = getBridgeAuth();
37
+ workspace = await bridge.team.getWorkspace();
38
+ name = workspace.name ?? '';
39
+ locale = workspace.locale ?? '';
40
+ } catch (err) {
41
+ const e = err instanceof Error ? err : new Error('Failed to load workspace');
42
+ error = e.message;
43
+ onError?.(e);
44
+ } finally {
45
+ loading = false;
46
+ }
47
+ }
48
+
49
+ async function handleSubmit() {
50
+ saving = true;
51
+ error = null;
52
+ success = null;
53
+ try {
54
+ const bridge = getBridgeAuth();
55
+ await bridge.team.updateWorkspace({ name, locale });
56
+ success = 'Workspace updated successfully.';
57
+ } catch (err) {
58
+ const e = err instanceof Error ? err : new Error('Failed to update workspace');
59
+ error = e.message;
60
+ onError?.(e);
61
+ } finally {
62
+ saving = false;
63
+ }
64
+ }
65
+ </script>
66
+
67
+ <div class={className} {style} data-bridge-team-workspace {...rest}>
68
+ <h3 class="bridge-team-section-title">Workspace Settings</h3>
69
+
70
+ {#if loading}
71
+ <div class="bridge-team-loading">
72
+ <Spinner size={32} />
73
+ <span>Loading workspace...</span>
74
+ </div>
75
+ {:else}
76
+ {#if error}
77
+ <div class="bridge-team-alert"><Alert variant="error">{error}</Alert></div>
78
+ {/if}
79
+ {#if success}
80
+ <div class="bridge-team-alert"><Alert variant="success">{success}</Alert></div>
81
+ {/if}
82
+
83
+ {#if workspace?.logo}
84
+ <div class="bridge-team-logo">
85
+ <img src={workspace.logo} alt="{workspace.name} logo" />
86
+ </div>
87
+ {/if}
88
+
89
+ <form class="bridge-team-form" onsubmit={(e) => { e.preventDefault(); handleSubmit(); }}>
90
+ <div class="bridge-team-form-group">
91
+ <label for="bridge-workspace-name">Workspace Name</label>
92
+ <input
93
+ id="bridge-workspace-name"
94
+ type="text"
95
+ bind:value={name}
96
+ disabled={saving}
97
+ />
98
+ </div>
99
+
100
+ <div class="bridge-team-form-group">
101
+ <label for="bridge-workspace-locale">Locale</label>
102
+ <input
103
+ id="bridge-workspace-locale"
104
+ type="text"
105
+ bind:value={locale}
106
+ placeholder="en"
107
+ disabled={saving}
108
+ />
109
+ </div>
110
+
111
+ {#if workspace?.plan}
112
+ <div class="bridge-team-form-group">
113
+ <label>Current Plan</label>
114
+ <div class="bridge-team-readonly">{workspace.plan}</div>
115
+ </div>
116
+ {/if}
117
+
118
+ <div class="bridge-team-form-group">
119
+ <label>MFA</label>
120
+ <div class="bridge-team-readonly">{workspace?.mfa ? 'Enabled' : 'Disabled'}</div>
121
+ </div>
122
+
123
+ <div class="bridge-team-form-actions">
124
+ <button
125
+ type="submit"
126
+ class="bridge-btn bridge-btn-primary"
127
+ disabled={saving}
128
+ >
129
+ {saving ? 'Saving...' : 'Save Changes'}
130
+ </button>
131
+ </div>
132
+ </form>
133
+ {/if}
134
+ </div>
@@ -0,0 +1,7 @@
1
+ import type { HTMLAttributes } from 'svelte/elements';
2
+ interface Props extends HTMLAttributes<HTMLDivElement> {
3
+ onError?: (error: Error) => void;
4
+ }
5
+ declare const TeamWorkspaceForm: import("svelte").Component<Props, {}, "">;
6
+ type TeamWorkspaceForm = ReturnType<typeof TeamWorkspaceForm>;
7
+ export default TeamWorkspaceForm;
@@ -1,12 +1,11 @@
1
1
  // src/lib/config/bridgeConfig.ts
2
2
  import { derived, writable } from 'svelte/store';
3
- import { logger } from '../../shared/logger.js';
3
+ import { initBridge } from '../../core/bridge-instance.js';
4
+ import { logger, setLoggerDebug } from '../../shared/logger.js';
4
5
  const DEFAULT_CONFIG = {
5
- authBaseUrl: 'https://api.thebridge.dev/auth',
6
- teamManagementUrl: 'https://api.thebridge.dev/cloud-views/user-management-portal/users',
7
- cloudViewsUrl: 'https://api.thebridge.dev/cloud-views',
6
+ apiBaseUrl: 'https://api.thebridge.dev',
8
7
  defaultRedirectRoute: '/',
9
- loginRoute: '/login',
8
+ signupRoute: '/auth/signup',
10
9
  debug: false
11
10
  };
12
11
  const { subscribe, set, update } = writable({
@@ -37,6 +36,10 @@ export const bridgeConfig = {
37
36
  else if (!merged.callbackUrl && defaultCallback) {
38
37
  merged.callbackUrl = defaultCallback;
39
38
  }
39
+ // Initialize logger debug mode before anything else
40
+ setLoggerDebug(!!merged.debug);
41
+ // Initialize the singleton BridgeAuth instance
42
+ initBridge(merged);
40
43
  // Set bridge full config and mark it as loaded
41
44
  set({
42
45
  config: merged,
@@ -0,0 +1 @@
1
+ export declare function cn(...classes: (string | undefined | null | false)[]): string;
@@ -0,0 +1,3 @@
1
+ export function cn(...classes) {
2
+ return classes.filter(Boolean).join(' ');
3
+ }