@atlasauth/svelte 0.1.5 → 0.2.1
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/accessors.d.ts +3 -3
- package/dist/accessors.js +2 -2
- package/dist/appearance.d.ts +27 -2
- package/dist/appearance.js +35 -0
- package/dist/components/AtlasProvider.svelte +21 -4
- package/dist/context.d.ts +8 -3
- package/dist/context.js +20 -3
- package/package.json +5 -4
package/dist/accessors.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Readable } from 'svelte/store';
|
|
2
|
-
import { type FlowState, type ProviderToken } from '@atlasauth/js';
|
|
2
|
+
import { type FlowState, type ProviderToken, type SignOutOptions } from '@atlasauth/js';
|
|
3
3
|
import { type AuthStatus } from './context';
|
|
4
4
|
import { type ProtectCondition } from './protect';
|
|
5
5
|
import type { AtlasOrganizationMembership, AtlasSession, AtlasUser } from './types';
|
|
@@ -48,7 +48,7 @@ export interface UseAuth {
|
|
|
48
48
|
getToken(): Promise<string | null>;
|
|
49
49
|
/** §6.6 the user's own live access token at a connected social provider. */
|
|
50
50
|
getProviderToken(provider: string): Promise<ProviderToken | null>;
|
|
51
|
-
signOut(): Promise<void>;
|
|
51
|
+
signOut(options?: SignOutOptions): Promise<void>;
|
|
52
52
|
/** Mirrors `<Protect>`, for logic that is not a render decision. */
|
|
53
53
|
has(condition: ProtectCondition): boolean;
|
|
54
54
|
}
|
|
@@ -64,7 +64,7 @@ export declare function getOrganization(): Readable<UseOrganization>;
|
|
|
64
64
|
/** Refresh-if-stale, then hand over the JWT. The `useAuth().getToken` shortcut. */
|
|
65
65
|
export declare function getToken(): Promise<string | null>;
|
|
66
66
|
/** Revoke the session and drop all in-memory state. */
|
|
67
|
-
export declare function signOut(): Promise<void>;
|
|
67
|
+
export declare function signOut(options?: SignOutOptions): Promise<void>;
|
|
68
68
|
/**
|
|
69
69
|
* A running sign-in / sign-up attempt: a reactive `state` store plus `submit`.
|
|
70
70
|
*
|
package/dist/accessors.js
CHANGED
|
@@ -54,8 +54,8 @@ export function getToken() {
|
|
|
54
54
|
return useAtlas().getToken();
|
|
55
55
|
}
|
|
56
56
|
/** Revoke the session and drop all in-memory state. */
|
|
57
|
-
export function signOut() {
|
|
58
|
-
return useAtlas().signOut();
|
|
57
|
+
export function signOut(options) {
|
|
58
|
+
return useAtlas().signOut(options);
|
|
59
59
|
}
|
|
60
60
|
function createFlow() {
|
|
61
61
|
const atlas = useAtlas();
|
package/dist/appearance.d.ts
CHANGED
|
@@ -17,6 +17,9 @@
|
|
|
17
17
|
* replacement is a support burden where every override starts by rebuilding the
|
|
18
18
|
* component's base styles from scratch.
|
|
19
19
|
*/
|
|
20
|
+
import { type AppearanceRender, type DesignAppearance, type DesignWarn, type InstanceDesign } from '@atlasauth/design/runtime';
|
|
21
|
+
export { instanceDesignFrom } from '@atlasauth/design/runtime';
|
|
22
|
+
export type { AppearanceRender, AtlasDesign, InstanceDesign, PresetId } from '@atlasauth/design/runtime';
|
|
20
23
|
export interface DesignTokens {
|
|
21
24
|
colorPrimary?: string;
|
|
22
25
|
colorText?: string;
|
|
@@ -29,9 +32,13 @@ export interface DesignTokens {
|
|
|
29
32
|
}
|
|
30
33
|
/** Every element a customer may target. Named for what it IS, not where it sits. */
|
|
31
34
|
export type ElementKey = 'root' | 'card' | 'headerTitle' | 'headerSubtitle' | 'formField' | 'formFieldLabel' | 'formFieldInput' | 'formFieldError' | 'formButtonPrimary' | 'formButtonSecondary' | 'socialButton' | 'dividerText' | 'footerAction' | 'avatar' | 'menu' | 'menuItem' | 'badge';
|
|
32
|
-
export interface Appearance {
|
|
33
|
-
/** A prebuilt theme to start from. */
|
|
35
|
+
export interface Appearance extends DesignAppearance {
|
|
36
|
+
/** A prebuilt token theme to start from (pre-design-system themes). */
|
|
34
37
|
baseTheme?: keyof typeof THEMES;
|
|
38
|
+
/**
|
|
39
|
+
* Legacy design tokens. Without a design they set the `--atlas-*` variables
|
|
40
|
+
* exactly as before; with one they map onto it.
|
|
41
|
+
*/
|
|
35
42
|
variables?: DesignTokens;
|
|
36
43
|
elements?: Partial<Record<ElementKey, string>>;
|
|
37
44
|
}
|
|
@@ -83,3 +90,21 @@ export declare function cssVariables(tokens: Required<DesignTokens>): Record<str
|
|
|
83
90
|
* specificity, which is the behaviour anyone writing Tailwind expects.
|
|
84
91
|
*/
|
|
85
92
|
export declare function classFor(element: ElementKey, appearance: Appearance | undefined, base: string): string;
|
|
93
|
+
/**
|
|
94
|
+
* The legacy tokens the developer chose EXPLICITLY: a non-default `baseTheme`
|
|
95
|
+
* plus `variables`. Only these map onto a design — the token defaults must not
|
|
96
|
+
* overwrite the dashboard design.
|
|
97
|
+
*/
|
|
98
|
+
export declare function explicitTokens(appearance?: Appearance): DesignTokens;
|
|
99
|
+
/**
|
|
100
|
+
* Turn an `appearance` (+ the instance's dashboard design from the Frontend
|
|
101
|
+
* API) into root attributes and a stylesheet — the same semantics as
|
|
102
|
+
* `@atlasauth/react`. Precedence, lowest first: dashboard design < `preset` <
|
|
103
|
+
* `variables` (and a non-default `baseTheme`) < `design`. Without a dashboard
|
|
104
|
+
* design and without `preset`/`design`, the output is exactly the
|
|
105
|
+
* pre-design-system one: the token variables, no stylesheet, no attributes.
|
|
106
|
+
*/
|
|
107
|
+
export declare function renderAppearance(appearance: Appearance | undefined, instanceDesign: InstanceDesign | null | undefined, options?: {
|
|
108
|
+
frontendApi?: string;
|
|
109
|
+
warn?: DesignWarn;
|
|
110
|
+
}): AppearanceRender;
|
package/dist/appearance.js
CHANGED
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
* replacement is a support burden where every override starts by rebuilding the
|
|
18
18
|
* component's base styles from scratch.
|
|
19
19
|
*/
|
|
20
|
+
import { renderDesignAppearance, } from '@atlasauth/design/runtime';
|
|
21
|
+
export { instanceDesignFrom } from '@atlasauth/design/runtime';
|
|
20
22
|
export const DEFAULT_TOKENS = {
|
|
21
23
|
colorPrimary: '#5b5bd6',
|
|
22
24
|
colorText: '#1c1c1f',
|
|
@@ -89,3 +91,36 @@ export function classFor(element, appearance, base) {
|
|
|
89
91
|
const override = appearance?.elements?.[element];
|
|
90
92
|
return override ? `${base} ${override}` : base;
|
|
91
93
|
}
|
|
94
|
+
// ---- the design system ---------------------------------------------------------
|
|
95
|
+
/**
|
|
96
|
+
* The legacy tokens the developer chose EXPLICITLY: a non-default `baseTheme`
|
|
97
|
+
* plus `variables`. Only these map onto a design — the token defaults must not
|
|
98
|
+
* overwrite the dashboard design.
|
|
99
|
+
*/
|
|
100
|
+
export function explicitTokens(appearance) {
|
|
101
|
+
const out = {};
|
|
102
|
+
if (appearance?.baseTheme && appearance.baseTheme !== 'default') {
|
|
103
|
+
Object.assign(out, THEMES[appearance.baseTheme]);
|
|
104
|
+
}
|
|
105
|
+
for (const [key, value] of Object.entries(appearance?.variables ?? {})) {
|
|
106
|
+
if (value !== undefined)
|
|
107
|
+
out[key] = value;
|
|
108
|
+
}
|
|
109
|
+
return out;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Turn an `appearance` (+ the instance's dashboard design from the Frontend
|
|
113
|
+
* API) into root attributes and a stylesheet — the same semantics as
|
|
114
|
+
* `@atlasauth/react`. Precedence, lowest first: dashboard design < `preset` <
|
|
115
|
+
* `variables` (and a non-default `baseTheme`) < `design`. Without a dashboard
|
|
116
|
+
* design and without `preset`/`design`, the output is exactly the
|
|
117
|
+
* pre-design-system one: the token variables, no stylesheet, no attributes.
|
|
118
|
+
*/
|
|
119
|
+
export function renderAppearance(appearance, instanceDesign, options = {}) {
|
|
120
|
+
return renderDesignAppearance(appearance, instanceDesign, {
|
|
121
|
+
tokens: explicitTokens(appearance),
|
|
122
|
+
legacyStyle: () => cssVariables(resolveTokens(appearance)),
|
|
123
|
+
frontendApi: options.frontendApi,
|
|
124
|
+
warn: options.warn,
|
|
125
|
+
});
|
|
126
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script>import { onDestroy, onMount } from "svelte";
|
|
2
2
|
import { initAtlas } from "../context";
|
|
3
|
-
import {
|
|
3
|
+
import { renderAppearance } from "../appearance";
|
|
4
4
|
export let publishableKey;
|
|
5
5
|
export let frontendApi = void 0;
|
|
6
6
|
export let appearance = void 0;
|
|
@@ -13,11 +13,28 @@ const client = initAtlas({
|
|
|
13
13
|
localization,
|
|
14
14
|
fetchImpl
|
|
15
15
|
});
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
let instanceDesign = null;
|
|
17
|
+
$: rendered = renderAppearance(appearance, instanceDesign, { frontendApi });
|
|
18
|
+
$: style = Object.entries(rendered.style).map(([name, value]) => `${name}: ${value}`).join("; ");
|
|
19
|
+
$: designStyle = rendered.css ? `<style data-atlas-design="${rendered.key}">${rendered.css}</style>` : "";
|
|
20
|
+
onMount(() => {
|
|
21
|
+
void client.boot();
|
|
22
|
+
if (appearance?.instanceDesign !== false) {
|
|
23
|
+
void client.loadInstanceDesign().then((design) => {
|
|
24
|
+
if (design) instanceDesign = design;
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
});
|
|
18
28
|
onDestroy(() => client.destroy());
|
|
19
29
|
</script>
|
|
20
30
|
|
|
21
|
-
<
|
|
31
|
+
<svelte:head>
|
|
32
|
+
{@html designStyle}
|
|
33
|
+
{#each rendered.fontStylesheets as href (href)}
|
|
34
|
+
<link rel="stylesheet" {href} data-atlas-font="" />
|
|
35
|
+
{/each}
|
|
36
|
+
</svelte:head>
|
|
37
|
+
|
|
38
|
+
<div class="atlas-root" {style} {...rendered.attributes}>
|
|
22
39
|
<slot />
|
|
23
40
|
</div>
|
package/dist/context.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Readable } from 'svelte/store';
|
|
2
|
-
import { type ProviderToken } from '@atlasauth/js';
|
|
2
|
+
import { type ProviderToken, type SignOutOptions } from '@atlasauth/js';
|
|
3
3
|
import { type Catalog } from './i18n';
|
|
4
|
-
import type
|
|
4
|
+
import { type Appearance, type InstanceDesign } from './appearance';
|
|
5
5
|
import type { AtlasOrganizationMembership, AtlasSession, AtlasUser, SessionClaims } from './types';
|
|
6
6
|
/**
|
|
7
7
|
* §10.1 the Svelte peer of React's `<AtlasProvider>`.
|
|
@@ -71,7 +71,7 @@ export interface AtlasClient extends AtlasStores {
|
|
|
71
71
|
* exposed; the server refreshes a stale token on read.
|
|
72
72
|
*/
|
|
73
73
|
getProviderToken(provider: string): Promise<ProviderToken | null>;
|
|
74
|
-
signOut(): Promise<void>;
|
|
74
|
+
signOut(options?: SignOutOptions): Promise<void>;
|
|
75
75
|
setActiveOrganization(organizationId: string | null): Promise<void>;
|
|
76
76
|
reload(): Promise<void>;
|
|
77
77
|
/**
|
|
@@ -80,6 +80,11 @@ export interface AtlasClient extends AtlasStores {
|
|
|
80
80
|
* `<AtlasProvider>` also calls it in `onMount`, and a second call is a no-op.
|
|
81
81
|
*/
|
|
82
82
|
boot(): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* The design configured in the Atlas dashboard (`GET /v1/appearance`), or null
|
|
85
|
+
* when there is none or it cannot be read. `<AtlasProvider>` applies it.
|
|
86
|
+
*/
|
|
87
|
+
loadInstanceDesign(): Promise<InstanceDesign | null>;
|
|
83
88
|
/** Cancel the scheduled refresh — call from a component's `onDestroy`. */
|
|
84
89
|
destroy(): void;
|
|
85
90
|
}
|
package/dist/context.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { getContext, setContext } from 'svelte';
|
|
2
2
|
import { derived, get, writable } from 'svelte/store';
|
|
3
|
-
import { FapiClient, TokenCache, getProviderToken as fetchProviderToken, msUntilRefresh, readExpiry, readRedirectResult, stripRedirectParams, } from '@atlasauth/js';
|
|
3
|
+
import { FapiClient, TokenCache, getProviderToken as fetchProviderToken, msUntilRefresh, readExpiry, readRedirectResult, stripRedirectParams, runFrontChannelLogoutFromResponse, } from '@atlasauth/js';
|
|
4
4
|
import { EN_US, withFallback } from './i18n';
|
|
5
|
+
import { instanceDesignFrom } from './appearance';
|
|
5
6
|
/** The context key. A `Symbol` so it cannot collide with an app's own context. */
|
|
6
7
|
export const ATLAS_KEY = Symbol('atlas');
|
|
7
8
|
function decodeClaims(jwt) {
|
|
@@ -147,10 +148,16 @@ export function createAtlasClient(options) {
|
|
|
147
148
|
function getProviderToken(provider) {
|
|
148
149
|
return fetchProviderToken(fapiClient, provider);
|
|
149
150
|
}
|
|
150
|
-
async function signOut() {
|
|
151
|
+
async function signOut(options) {
|
|
151
152
|
const current = cache.peek();
|
|
152
153
|
if (current) {
|
|
153
|
-
await call(`/v1/client/sessions/${current.sessionId}/revoke`, {
|
|
154
|
+
const revoked = await call(`/v1/client/sessions/${current.sessionId}/revoke`, {
|
|
155
|
+
method: 'POST',
|
|
156
|
+
}).catch(() => undefined);
|
|
157
|
+
// OIDC Front-Channel Logout: let the apps signed in through this session
|
|
158
|
+
// clear theirs in this browser (hidden iframes, capped at 5 s). Best-effort.
|
|
159
|
+
if (options?.frontchannel !== false)
|
|
160
|
+
await runFrontChannelLogoutFromResponse(revoked);
|
|
154
161
|
}
|
|
155
162
|
if (timer)
|
|
156
163
|
clearTimeout(timer);
|
|
@@ -196,6 +203,15 @@ export function createAtlasClient(options) {
|
|
|
196
203
|
}
|
|
197
204
|
await reload();
|
|
198
205
|
}
|
|
206
|
+
async function loadInstanceDesign() {
|
|
207
|
+
try {
|
|
208
|
+
const response = await call('/v1/appearance');
|
|
209
|
+
return response.ok ? instanceDesignFrom(await response.json()) : null;
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
199
215
|
function destroy() {
|
|
200
216
|
if (timer)
|
|
201
217
|
clearTimeout(timer);
|
|
@@ -222,6 +238,7 @@ export function createAtlasClient(options) {
|
|
|
222
238
|
setActiveOrganization,
|
|
223
239
|
reload,
|
|
224
240
|
boot,
|
|
241
|
+
loadInstanceDesign,
|
|
225
242
|
destroy,
|
|
226
243
|
};
|
|
227
244
|
// Kick off the browser boot immediately unless the caller opts out. Guarded to
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlasauth/svelte",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"svelte": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -21,9 +21,10 @@
|
|
|
21
21
|
"./package.json": "./package.json"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@atlasauth/
|
|
25
|
-
"@atlasauth/
|
|
26
|
-
"@atlasauth/
|
|
24
|
+
"@atlasauth/backend": "0.5.0",
|
|
25
|
+
"@atlasauth/authz": "0.1.1",
|
|
26
|
+
"@atlasauth/js": "0.5.0",
|
|
27
|
+
"@atlasauth/design": "0.1.0"
|
|
27
28
|
},
|
|
28
29
|
"peerDependencies": {
|
|
29
30
|
"svelte": ">=4",
|