@nebulr-group/bridge-svelte 0.3.0-beta.0 → 0.3.0-beta.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/client/components/sdk-auth/LoginForm.svelte +19 -1
- package/dist/client/components/sdk-auth/LoginForm.svelte.d.ts +7 -0
- package/dist/client/components/sdk-auth/SsoButton.svelte +10 -1
- package/dist/client/components/sdk-auth/SsoButton.svelte.d.ts +8 -0
- package/dist/core/bridge-instance.d.ts +10 -0
- package/dist/core/bridge-instance.js +39 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
4
|
import type { AppConfig, FederationConnection } from '@thebridge/auth-core';
|
|
5
5
|
import { onMount } from 'svelte';
|
|
6
|
-
import { getBridgeAuth, authState, appConfigStore } from '../../../core/bridge-instance.js';
|
|
6
|
+
import { getBridgeAuth, authState, appConfigStore, ensureAppConfig } from '../../../core/bridge-instance.js';
|
|
7
7
|
import { getConfig } from '../../stores/config.store.js';
|
|
8
8
|
import AuthFormWrapper from './shared/AuthFormWrapper.svelte';
|
|
9
9
|
import Spinner from './shared/Spinner.svelte';
|
|
@@ -33,6 +33,13 @@
|
|
|
33
33
|
onSsoClick?: (connectionType: string) => void;
|
|
34
34
|
heading?: string;
|
|
35
35
|
ssoConnections?: FederationConnection[];
|
|
36
|
+
/**
|
|
37
|
+
* SSO kickoff strategy for the built-in SsoButtons.
|
|
38
|
+
* - 'redirect' (default): full-page navigation to the federation endpoint.
|
|
39
|
+
* - 'popup': opens window.open and resolves via postMessage.
|
|
40
|
+
* Ignored when `onSsoClick` is provided (the caller handles the click).
|
|
41
|
+
*/
|
|
42
|
+
ssoMode?: 'redirect' | 'popup';
|
|
36
43
|
footer?: Snippet;
|
|
37
44
|
}
|
|
38
45
|
|
|
@@ -48,6 +55,7 @@
|
|
|
48
55
|
onSsoClick,
|
|
49
56
|
heading = '',
|
|
50
57
|
ssoConnections = [],
|
|
58
|
+
ssoMode = 'redirect',
|
|
51
59
|
footer,
|
|
52
60
|
class: className,
|
|
53
61
|
style,
|
|
@@ -164,6 +172,15 @@
|
|
|
164
172
|
|
|
165
173
|
onMount(async () => {
|
|
166
174
|
if (typeof window === 'undefined') return;
|
|
175
|
+
|
|
176
|
+
// Ensure the anonymous app config is loaded. `initBridge()` kicks off the
|
|
177
|
+
// same fetch on startup, but LoginForm can mount before that promise
|
|
178
|
+
// settles (slow network, failed init, etc.), so we call it again here.
|
|
179
|
+
// `ensureAppConfig()` is idempotent and logs errors — the store update
|
|
180
|
+
// triggers reactivity and the SSO buttons / magic-link / passkey toggles
|
|
181
|
+
// render when it resolves.
|
|
182
|
+
void ensureAppConfig();
|
|
183
|
+
|
|
167
184
|
const params = new URLSearchParams(window.location.search);
|
|
168
185
|
const magicToken = params.get('bridge_magic_link_token');
|
|
169
186
|
if (!magicToken) return;
|
|
@@ -391,6 +408,7 @@
|
|
|
391
408
|
{:else}
|
|
392
409
|
<SsoButton
|
|
393
410
|
connection={conn}
|
|
411
|
+
mode={ssoMode}
|
|
394
412
|
onSuccess={onLogin}
|
|
395
413
|
onError={onError}
|
|
396
414
|
class="bridge-btn bridge-btn-secondary bridge-sso-btn"
|
|
@@ -18,6 +18,13 @@ interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
|
18
18
|
onSsoClick?: (connectionType: string) => void;
|
|
19
19
|
heading?: string;
|
|
20
20
|
ssoConnections?: FederationConnection[];
|
|
21
|
+
/**
|
|
22
|
+
* SSO kickoff strategy for the built-in SsoButtons.
|
|
23
|
+
* - 'redirect' (default): full-page navigation to the federation endpoint.
|
|
24
|
+
* - 'popup': opens window.open and resolves via postMessage.
|
|
25
|
+
* Ignored when `onSsoClick` is provided (the caller handles the click).
|
|
26
|
+
*/
|
|
27
|
+
ssoMode?: 'redirect' | 'popup';
|
|
21
28
|
footer?: Snippet;
|
|
22
29
|
}
|
|
23
30
|
declare const LoginForm: import("svelte").Component<Props, {}, "">;
|
|
@@ -8,6 +8,14 @@
|
|
|
8
8
|
interface Props extends HTMLButtonAttributes {
|
|
9
9
|
connection: FederationConnection;
|
|
10
10
|
label?: string;
|
|
11
|
+
/**
|
|
12
|
+
* SSO kickoff strategy.
|
|
13
|
+
* - 'redirect' (default): full-page navigation to the federation endpoint,
|
|
14
|
+
* provider returns via the normal OAuth callback chain.
|
|
15
|
+
* - 'popup': opens window.open and resolves via postMessage — useful for
|
|
16
|
+
* embedded widgets that must not unload the host page.
|
|
17
|
+
*/
|
|
18
|
+
mode?: 'redirect' | 'popup';
|
|
11
19
|
onSuccess?: () => void;
|
|
12
20
|
onError?: (error: Error) => void;
|
|
13
21
|
icon?: Snippet;
|
|
@@ -16,6 +24,7 @@
|
|
|
16
24
|
let {
|
|
17
25
|
connection,
|
|
18
26
|
label,
|
|
27
|
+
mode = 'redirect',
|
|
19
28
|
onSuccess,
|
|
20
29
|
onError,
|
|
21
30
|
icon,
|
|
@@ -31,7 +40,7 @@
|
|
|
31
40
|
if (loading) return;
|
|
32
41
|
loading = true;
|
|
33
42
|
try {
|
|
34
|
-
const result = await getBridgeAuth().startSsoLogin(connection.type);
|
|
43
|
+
const result = await getBridgeAuth().startSsoLogin(connection.type, { mode });
|
|
35
44
|
if (result.type === 'auth_success') {
|
|
36
45
|
onSuccess?.();
|
|
37
46
|
} else if (result.type === 'auth_error') {
|
|
@@ -4,6 +4,14 @@ import type { FederationConnection } from '@thebridge/auth-core';
|
|
|
4
4
|
interface Props extends HTMLButtonAttributes {
|
|
5
5
|
connection: FederationConnection;
|
|
6
6
|
label?: string;
|
|
7
|
+
/**
|
|
8
|
+
* SSO kickoff strategy.
|
|
9
|
+
* - 'redirect' (default): full-page navigation to the federation endpoint,
|
|
10
|
+
* provider returns via the normal OAuth callback chain.
|
|
11
|
+
* - 'popup': opens window.open and resolves via postMessage — useful for
|
|
12
|
+
* embedded widgets that must not unload the host page.
|
|
13
|
+
*/
|
|
14
|
+
mode?: 'redirect' | 'popup';
|
|
7
15
|
onSuccess?: () => void;
|
|
8
16
|
onError?: (error: Error) => void;
|
|
9
17
|
icon?: Snippet;
|
|
@@ -8,6 +8,16 @@
|
|
|
8
8
|
import { BridgeAuth, type AppConfig, type AuthState, type BridgeAuthConfig, type Plan, type Profile, type SubscriptionStatus, type TenantUser, type TokenSet } from '@nebulr-group/bridge-auth-core';
|
|
9
9
|
import { type Readable, type Writable } from 'svelte/store';
|
|
10
10
|
export declare function initBridge(config: BridgeAuthConfig): BridgeAuth;
|
|
11
|
+
/**
|
|
12
|
+
* Load the anonymous app config into `appConfigStore` if it isn't already.
|
|
13
|
+
*
|
|
14
|
+
* Idempotent: concurrent callers share the in-flight fetch, and once the
|
|
15
|
+
* store holds a value this function resolves immediately.
|
|
16
|
+
*
|
|
17
|
+
* Resolves with the loaded config on success or `null` on failure (the
|
|
18
|
+
* fetch error is logged — it is not silently swallowed).
|
|
19
|
+
*/
|
|
20
|
+
export declare function ensureAppConfig(): Promise<AppConfig | null>;
|
|
11
21
|
export declare function getBridgeAuth(): BridgeAuth;
|
|
12
22
|
export declare function markReady(): void;
|
|
13
23
|
export declare function waitForBridge(): Promise<void>;
|
|
@@ -28,6 +28,12 @@ let _resolveReady = null;
|
|
|
28
28
|
const _readyPromise = new Promise((resolve) => {
|
|
29
29
|
_resolveReady = resolve;
|
|
30
30
|
});
|
|
31
|
+
// ── App config load gate ───────────────────────────────────────────────────────
|
|
32
|
+
//
|
|
33
|
+
// The anonymous app config drives SSO button visibility, signup/magic-link
|
|
34
|
+
// toggles, etc. on LoginForm. We cache the in-flight fetch so concurrent
|
|
35
|
+
// callers share a single network request and can await the result.
|
|
36
|
+
let _appConfigPromise = null;
|
|
31
37
|
// ── Init / access ──────────────────────────────────────────────────────────────
|
|
32
38
|
export function initBridge(config) {
|
|
33
39
|
if (_instance) {
|
|
@@ -78,11 +84,42 @@ export function initBridge(config) {
|
|
|
78
84
|
_instance.on('auth:error', (err) => {
|
|
79
85
|
_error.set(err.message);
|
|
80
86
|
});
|
|
81
|
-
// Load app config anonymously (drives SSO buttons etc.)
|
|
82
|
-
|
|
87
|
+
// Load app config anonymously (drives SSO buttons, signup toggle, etc.).
|
|
88
|
+
// Cached in `_appConfigPromise` so LoginForm (and others) can await the
|
|
89
|
+
// result via `ensureAppConfig()` instead of racing the store update.
|
|
90
|
+
void ensureAppConfig();
|
|
83
91
|
logger.debug('[bridge-instance] initialized');
|
|
84
92
|
return _instance;
|
|
85
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Load the anonymous app config into `appConfigStore` if it isn't already.
|
|
96
|
+
*
|
|
97
|
+
* Idempotent: concurrent callers share the in-flight fetch, and once the
|
|
98
|
+
* store holds a value this function resolves immediately.
|
|
99
|
+
*
|
|
100
|
+
* Resolves with the loaded config on success or `null` on failure (the
|
|
101
|
+
* fetch error is logged — it is not silently swallowed).
|
|
102
|
+
*/
|
|
103
|
+
export function ensureAppConfig() {
|
|
104
|
+
const existing = get(_appConfig);
|
|
105
|
+
if (existing)
|
|
106
|
+
return Promise.resolve(existing);
|
|
107
|
+
if (_appConfigPromise)
|
|
108
|
+
return _appConfigPromise;
|
|
109
|
+
_appConfigPromise = getBridgeAuth()
|
|
110
|
+
.getAppConfig()
|
|
111
|
+
.then((cfg) => {
|
|
112
|
+
_appConfig.set(cfg);
|
|
113
|
+
return cfg;
|
|
114
|
+
})
|
|
115
|
+
.catch((err) => {
|
|
116
|
+
logger.warn('[bridge-instance] getAppConfig failed:', err);
|
|
117
|
+
// Allow a later call to retry
|
|
118
|
+
_appConfigPromise = null;
|
|
119
|
+
return null;
|
|
120
|
+
});
|
|
121
|
+
return _appConfigPromise;
|
|
122
|
+
}
|
|
86
123
|
export function getBridgeAuth() {
|
|
87
124
|
if (!_instance) {
|
|
88
125
|
throw new Error('BridgeAuth not initialized. Call initBridge() first (via bridgeConfig.initConfig).');
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from './client/BridgeBootstrap.js';
|
|
2
2
|
export * from './client/stores/config.store.js';
|
|
3
|
-
export { initBridge, getBridgeAuth, markReady, waitForBridge, auth, tokenStore, isAuthenticated, isLoading, authError, authState, isOnboarded, hasMultiTenantAccess, tenantUsersStore, profileStore, flagsStore, bridgeReadyStore, appConfigStore, subscriptionStore, loadSubscription, } from './core/bridge-instance.js';
|
|
3
|
+
export { initBridge, getBridgeAuth, markReady, waitForBridge, auth, tokenStore, isAuthenticated, isLoading, authError, authState, isOnboarded, hasMultiTenantAccess, tenantUsersStore, profileStore, flagsStore, bridgeReadyStore, appConfigStore, ensureAppConfig, subscriptionStore, loadSubscription, } from './core/bridge-instance.js';
|
|
4
4
|
export { default as BridgeBootstrap, default as BridgeProvider } from './client/BridgeBootstrap.svelte';
|
|
5
5
|
export { default as ApiTokenManagement } from './client/components/developer/ApiTokenManagement.svelte';
|
|
6
6
|
export { default as FeatureFlag } from './client/components/FeatureFlag.svelte';
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
export * from './client/BridgeBootstrap.js';
|
|
3
3
|
export * from './client/stores/config.store.js';
|
|
4
4
|
// Bridge instance (singleton + Svelte stores)
|
|
5
|
-
export { initBridge, getBridgeAuth, markReady, waitForBridge, auth, tokenStore, isAuthenticated, isLoading, authError, authState, isOnboarded, hasMultiTenantAccess, tenantUsersStore, profileStore, flagsStore, bridgeReadyStore, appConfigStore, subscriptionStore, loadSubscription, } from './core/bridge-instance.js';
|
|
5
|
+
export { initBridge, getBridgeAuth, markReady, waitForBridge, auth, tokenStore, isAuthenticated, isLoading, authError, authState, isOnboarded, hasMultiTenantAccess, tenantUsersStore, profileStore, flagsStore, bridgeReadyStore, appConfigStore, ensureAppConfig, subscriptionStore, loadSubscription, } from './core/bridge-instance.js';
|
|
6
6
|
// Components (Svelte components must have `export default`)
|
|
7
7
|
export { default as BridgeBootstrap, default as BridgeProvider } from './client/BridgeBootstrap.svelte';
|
|
8
8
|
export { default as ApiTokenManagement } from './client/components/developer/ApiTokenManagement.svelte';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nebulr-group/bridge-svelte",
|
|
3
|
-
"version": "0.3.0-beta.
|
|
3
|
+
"version": "0.3.0-beta.2",
|
|
4
4
|
"description": "Bridge Svelte library, This library helps you to add bridge authentication and feature flags, and payments to your svelte application.",
|
|
5
5
|
"author": "Iman Pouya",
|
|
6
6
|
"license": "MIT",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
}
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@nebulr-group/bridge-auth-core": "
|
|
63
|
+
"@nebulr-group/bridge-auth-core": "0.1.0-beta.2"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
66
|
"@sveltejs/kit": "^2.16.0",
|