@vertz/ui 0.2.15 → 0.2.17
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/README.md +49 -0
- package/dist/shared/{chunk-dksg08fq.js → chunk-07bh4m1e.js} +1 -1
- package/dist/shared/chunk-14eqne2a.js +10 -0
- package/dist/shared/{chunk-nn9v1zmk.js → chunk-2wtb9x81.js} +83 -20
- package/dist/shared/{chunk-8hsz5y4a.js → chunk-4fwcwxn6.js} +14 -4
- package/dist/shared/{chunk-4txc67nd.js → chunk-6jyt4ycw.js} +67 -2
- package/dist/shared/{chunk-83g4h38e.js → chunk-6wd36w21.js} +1 -0
- package/dist/shared/{chunk-h89w580h.js → chunk-afawz764.js} +1 -1
- package/dist/shared/{chunk-1wby7nex.js → chunk-dhehvmj0.js} +161 -9
- package/dist/shared/{chunk-wymw818z.js → chunk-fkbgbf3n.js} +48 -9
- package/dist/shared/{chunk-hw67ckr3.js → chunk-fs3eec4b.js} +230 -19
- package/dist/shared/{chunk-5dbq8jp9.js → chunk-j09yyh34.js} +72 -6
- package/dist/shared/chunk-mtsvrj9e.js +23 -0
- package/dist/shared/{chunk-j6qyxfdc.js → chunk-vndfjfdy.js} +3 -3
- package/dist/src/auth/public.d.ts +40 -24
- package/dist/src/auth/public.js +110 -52
- package/dist/src/css/public.d.ts +110 -2
- package/dist/src/css/public.js +8 -4
- package/dist/src/form/public.d.ts +29 -6
- package/dist/src/form/public.js +2 -2
- package/dist/src/index.d.ts +284 -13
- package/dist/src/index.js +160 -14
- package/dist/src/internals.d.ts +168 -5
- package/dist/src/internals.js +14 -8
- package/dist/src/jsx-runtime/index.d.ts +5 -0
- package/dist/src/jsx-runtime/index.js +8 -1
- package/dist/src/query/public.js +4 -3
- package/dist/src/router/public.d.ts +17 -4
- package/dist/src/router/public.js +16 -11
- package/dist/src/test/index.d.ts +5 -0
- package/dist/src/test/index.js +4 -3
- package/package.json +3 -3
- package/reactivity.json +1 -11
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
useContext
|
|
4
|
+
} from "./chunk-4fwcwxn6.js";
|
|
5
|
+
|
|
6
|
+
// src/router/router-context.ts
|
|
7
|
+
var RouterContext = createContext(undefined, "@vertz/ui::RouterContext");
|
|
8
|
+
function useRouter() {
|
|
9
|
+
const router = useContext(RouterContext);
|
|
10
|
+
if (!router) {
|
|
11
|
+
throw new Error("useRouter() must be called within RouterContext.Provider");
|
|
12
|
+
}
|
|
13
|
+
return router;
|
|
14
|
+
}
|
|
15
|
+
function useParams() {
|
|
16
|
+
const router = useContext(RouterContext);
|
|
17
|
+
if (!router) {
|
|
18
|
+
throw new Error("useParams() must be called within RouterContext.Provider");
|
|
19
|
+
}
|
|
20
|
+
return router.current?.parsedParams ?? router.current?.params ?? {};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { RouterContext, useRouter, useParams };
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
getAdapter,
|
|
8
8
|
isRenderNode
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-afawz764.js";
|
|
10
10
|
import {
|
|
11
11
|
domEffect
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-4fwcwxn6.js";
|
|
13
13
|
|
|
14
14
|
// src/hydrate/hydration-context.ts
|
|
15
15
|
var isHydrating = false;
|
|
@@ -371,4 +371,4 @@ function __exitChildren() {
|
|
|
371
371
|
}
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
-
export { startHydration, endHydration, getIsHydrating, claimText, claimComment, __text, __child, __insert, __element, __append, __staticText, __enterChildren, __exitChildren };
|
|
374
|
+
export { startHydration, endHydration, getIsHydrating, claimElement, claimText, claimComment, enterChildren, exitChildren, __text, __child, __insert, __element, __append, __staticText, __enterChildren, __exitChildren };
|
|
@@ -114,6 +114,13 @@ declare const AccessContext: Context<AccessContextValue>;
|
|
|
114
114
|
*/
|
|
115
115
|
declare function useAccessContext(): UnwrapSignals<AccessContextValue>;
|
|
116
116
|
/**
|
|
117
|
+
* Entitlement registry — augmented by @vertz/codegen to narrow entitlement strings.
|
|
118
|
+
* When empty (no codegen), Entitlement falls back to `string`.
|
|
119
|
+
*/
|
|
120
|
+
interface EntitlementRegistry {}
|
|
121
|
+
/** Entitlement type — narrows to literal union when codegen populates EntitlementRegistry. */
|
|
122
|
+
type Entitlement = keyof EntitlementRegistry extends never ? string : Extract<keyof EntitlementRegistry, string>;
|
|
123
|
+
/**
|
|
117
124
|
* Check if the current user has a specific entitlement.
|
|
118
125
|
*
|
|
119
126
|
* Must be called in the component body (like query()/form()).
|
|
@@ -126,15 +133,9 @@ declare function useAccessContext(): UnwrapSignals<AccessContextValue>;
|
|
|
126
133
|
* @param entitlement - The entitlement to check
|
|
127
134
|
* @param entity - Optional entity with pre-computed `__access` metadata
|
|
128
135
|
*/
|
|
129
|
-
declare function can(entitlement:
|
|
136
|
+
declare function can(entitlement: Entitlement, entity?: {
|
|
130
137
|
__access?: Record<string, AccessCheckData>;
|
|
131
138
|
}): AccessCheck;
|
|
132
|
-
/**
|
|
133
|
-
* Access Event Client — WebSocket client for real-time access invalidation.
|
|
134
|
-
*
|
|
135
|
-
* Connects to the access event WebSocket endpoint, handles reconnection
|
|
136
|
-
* with exponential backoff, and delivers parsed events to the caller.
|
|
137
|
-
*/
|
|
138
139
|
/** Client-side access events (no orgId/userId — server scopes the broadcast) */
|
|
139
140
|
type ClientAccessEvent = {
|
|
140
141
|
type: "access:flag_toggled";
|
|
@@ -178,16 +179,6 @@ interface AccessEventClient {
|
|
|
178
179
|
dispose(): void;
|
|
179
180
|
}
|
|
180
181
|
declare function createAccessEventClient(options: AccessEventClientOptions): AccessEventClient;
|
|
181
|
-
interface AccessGateProps {
|
|
182
|
-
fallback?: () => unknown;
|
|
183
|
-
children: (() => unknown) | unknown;
|
|
184
|
-
}
|
|
185
|
-
/**
|
|
186
|
-
* Gate component that blocks children while the access set is loading.
|
|
187
|
-
* Use this to prevent flicker on initial render when access data
|
|
188
|
-
* hasn't been hydrated yet.
|
|
189
|
-
*/
|
|
190
|
-
declare function AccessGate({ fallback, children }: AccessGateProps): ReadonlySignal<unknown> | unknown;
|
|
191
182
|
import { Result } from "@vertz/fetch";
|
|
192
183
|
/**
|
|
193
184
|
* Minimal schema interface compatible with @vertz/schema.
|
|
@@ -263,6 +254,15 @@ interface ResetInput {
|
|
|
263
254
|
token: string;
|
|
264
255
|
password: string;
|
|
265
256
|
}
|
|
257
|
+
interface SignOutOptions {
|
|
258
|
+
/** Path to navigate to after sign-out completes. Uses SPA navigation (replace). */
|
|
259
|
+
redirectTo?: string;
|
|
260
|
+
}
|
|
261
|
+
interface OAuthProviderInfo {
|
|
262
|
+
id: string;
|
|
263
|
+
name: string;
|
|
264
|
+
authUrl: string;
|
|
265
|
+
}
|
|
266
266
|
interface AuthResponse {
|
|
267
267
|
user: User;
|
|
268
268
|
expiresAt: number;
|
|
@@ -275,11 +275,12 @@ interface AuthContextValue {
|
|
|
275
275
|
error: Signal<AuthClientError | null>;
|
|
276
276
|
signIn: SdkMethodWithMeta<SignInInput, AuthResponse>;
|
|
277
277
|
signUp: SdkMethodWithMeta<SignUpInput, AuthResponse>;
|
|
278
|
-
signOut: () => Promise<void>;
|
|
278
|
+
signOut: (options?: SignOutOptions) => Promise<void>;
|
|
279
279
|
refresh: () => Promise<void>;
|
|
280
280
|
mfaChallenge: SdkMethodWithMeta<MfaInput, AuthResponse>;
|
|
281
281
|
forgotPassword: SdkMethodWithMeta<ForgotInput, void>;
|
|
282
282
|
resetPassword: SdkMethodWithMeta<ResetInput, void>;
|
|
283
|
+
providers: Signal<OAuthProviderInfo[]>;
|
|
283
284
|
}
|
|
284
285
|
declare const AuthContext: Context<AuthContextValue>;
|
|
285
286
|
declare function useAuth(): UnwrapSignals<AuthContextValue>;
|
|
@@ -295,11 +296,6 @@ interface AuthProviderProps {
|
|
|
295
296
|
children: (() => unknown) | unknown;
|
|
296
297
|
}
|
|
297
298
|
declare function AuthProvider({ basePath, accessControl, accessEvents, accessEventsUrl, flagEntitlementMap, children }: AuthProviderProps): HTMLElement;
|
|
298
|
-
interface AuthGateProps {
|
|
299
|
-
fallback?: () => unknown;
|
|
300
|
-
children: (() => unknown) | unknown;
|
|
301
|
-
}
|
|
302
|
-
declare function AuthGate({ fallback, children }: AuthGateProps): ReadonlySignal<unknown> | unknown;
|
|
303
299
|
/**
|
|
304
300
|
* Create an AccessContextValue for use with AccessContext.Provider.
|
|
305
301
|
* Hydrates from `window.__VERTZ_ACCESS_SET__` when available (SSR).
|
|
@@ -313,4 +309,24 @@ declare function AuthGate({ fallback, children }: AuthGateProps): ReadonlySignal
|
|
|
313
309
|
* ```
|
|
314
310
|
*/
|
|
315
311
|
declare function createAccessProvider(): AccessContextValue;
|
|
316
|
-
|
|
312
|
+
/**
|
|
313
|
+
* Get an SVG icon string for a provider.
|
|
314
|
+
* Returns the built-in icon for known providers, or a generic fallback for unknown.
|
|
315
|
+
*/
|
|
316
|
+
declare function getProviderIcon(providerId: string, size: number): string;
|
|
317
|
+
/**
|
|
318
|
+
* Get a display name for a user with a fallback chain.
|
|
319
|
+
* Chain: user.name (if string & non-empty) → user.email → fallback (default: 'Unknown')
|
|
320
|
+
*/
|
|
321
|
+
declare function getUserDisplayName(user: User | null | undefined, fallback?: string): string;
|
|
322
|
+
/**
|
|
323
|
+
* Get initials from a user's name or email (max 2 characters).
|
|
324
|
+
* Chain: first + last word initials from name → first char of email → '?'
|
|
325
|
+
*/
|
|
326
|
+
declare function getUserInitials(user: User | null | undefined): string;
|
|
327
|
+
/**
|
|
328
|
+
* Default user silhouette icon for avatar fallbacks.
|
|
329
|
+
* Returns an inline SVG string — no external requests, works in SSR.
|
|
330
|
+
*/
|
|
331
|
+
declare function getUserIcon(size: number): string;
|
|
332
|
+
export { useAuth, useAccessContext, getUserInitials, getUserIcon, getUserDisplayName, getProviderIcon, createAccessProvider, createAccessEventClient, can, User, SignUpInput, SignOutOptions, SignInInput, ResetInput, OAuthProviderInfo, MfaInput, ForgotInput, EntitlementRegistry, Entitlement, DenialReason, DenialMeta, ClientAccessEvent, AuthStatus, AuthResponse, AuthProviderProps, AuthProvider, AuthErrorCode, AuthContextValue, AuthContext, AuthClientError, AccessSet, AccessEventClientOptions, AccessEventClient, AccessContextValue, AccessContext, AccessCheckData, AccessCheck };
|
package/dist/src/auth/public.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RouterContext
|
|
3
|
+
} from "../../shared/chunk-mtsvrj9e.js";
|
|
4
|
+
import {
|
|
5
|
+
isBrowser
|
|
6
|
+
} from "../../shared/chunk-14eqne2a.js";
|
|
1
7
|
import {
|
|
2
8
|
_tryOnCleanup,
|
|
3
9
|
computed,
|
|
4
10
|
createContext,
|
|
11
|
+
getSSRContext,
|
|
5
12
|
signal,
|
|
6
13
|
useContext
|
|
7
|
-
} from "../../shared/chunk-
|
|
14
|
+
} from "../../shared/chunk-4fwcwxn6.js";
|
|
8
15
|
|
|
9
16
|
// src/auth/access-context.ts
|
|
10
17
|
var AccessContext = createContext(undefined, "@vertz/ui::AccessContext");
|
|
@@ -69,7 +76,7 @@ function createAccessEventClient(options) {
|
|
|
69
76
|
function getUrl() {
|
|
70
77
|
if (options.url)
|
|
71
78
|
return options.url;
|
|
72
|
-
if (
|
|
79
|
+
if (isBrowser()) {
|
|
73
80
|
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
|
|
74
81
|
return `${protocol}//${window.location.host}/api/auth/access-events`;
|
|
75
82
|
}
|
|
@@ -139,26 +146,6 @@ function createAccessEventClient(options) {
|
|
|
139
146
|
}
|
|
140
147
|
return { connect, disconnect, dispose };
|
|
141
148
|
}
|
|
142
|
-
// src/auth/access-gate.ts
|
|
143
|
-
function AccessGate({
|
|
144
|
-
fallback,
|
|
145
|
-
children
|
|
146
|
-
}) {
|
|
147
|
-
const ctx = useContext(AccessContext);
|
|
148
|
-
if (!ctx) {
|
|
149
|
-
return typeof children === "function" ? children() : children;
|
|
150
|
-
}
|
|
151
|
-
const isLoaded = computed(() => {
|
|
152
|
-
const set = ctx.accessSet;
|
|
153
|
-
return set !== null;
|
|
154
|
-
});
|
|
155
|
-
return computed(() => {
|
|
156
|
-
if (isLoaded.value) {
|
|
157
|
-
return typeof children === "function" ? children() : children;
|
|
158
|
-
}
|
|
159
|
-
return fallback ? fallback() : null;
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
149
|
// src/auth/access-event-handler.ts
|
|
163
150
|
function handleAccessEvent(accessSet, event, flagEntitlementMap) {
|
|
164
151
|
const current = accessSet.value;
|
|
@@ -454,7 +441,7 @@ function createTokenRefresh({ onRefresh }) {
|
|
|
454
441
|
pendingOfflineRefresh = false;
|
|
455
442
|
}
|
|
456
443
|
let visibilityHandler;
|
|
457
|
-
if (
|
|
444
|
+
if (isBrowser()) {
|
|
458
445
|
visibilityHandler = () => {
|
|
459
446
|
if (document.visibilityState === "hidden") {
|
|
460
447
|
clearTimer();
|
|
@@ -465,7 +452,7 @@ function createTokenRefresh({ onRefresh }) {
|
|
|
465
452
|
document.addEventListener("visibilitychange", visibilityHandler);
|
|
466
453
|
}
|
|
467
454
|
let onlineHandler;
|
|
468
|
-
if (
|
|
455
|
+
if (isBrowser()) {
|
|
469
456
|
onlineHandler = () => {
|
|
470
457
|
if (pendingOfflineRefresh) {
|
|
471
458
|
pendingOfflineRefresh = false;
|
|
@@ -476,10 +463,10 @@ function createTokenRefresh({ onRefresh }) {
|
|
|
476
463
|
}
|
|
477
464
|
function dispose() {
|
|
478
465
|
cancel();
|
|
479
|
-
if (visibilityHandler &&
|
|
466
|
+
if (visibilityHandler && isBrowser()) {
|
|
480
467
|
document.removeEventListener("visibilitychange", visibilityHandler);
|
|
481
468
|
}
|
|
482
|
-
if (onlineHandler &&
|
|
469
|
+
if (onlineHandler && isBrowser()) {
|
|
483
470
|
window.removeEventListener("online", onlineHandler);
|
|
484
471
|
}
|
|
485
472
|
}
|
|
@@ -502,9 +489,19 @@ function AuthProvider({
|
|
|
502
489
|
flagEntitlementMap,
|
|
503
490
|
children
|
|
504
491
|
}) {
|
|
492
|
+
const router = useContext(RouterContext);
|
|
505
493
|
const userSignal = signal(null);
|
|
506
494
|
const statusSignal = signal("idle");
|
|
507
495
|
const errorSignal = signal(null);
|
|
496
|
+
const providersSignal = signal([]);
|
|
497
|
+
if (isBrowser()) {
|
|
498
|
+
setTimeout(() => {
|
|
499
|
+
fetch(`${basePath}/providers`).then((res) => res.ok ? res.json() : []).then((data) => {
|
|
500
|
+
providersSignal.value = data;
|
|
501
|
+
}).catch(() => {});
|
|
502
|
+
}, 0);
|
|
503
|
+
}
|
|
504
|
+
let deferredRefreshTimer = null;
|
|
508
505
|
const isAuthenticated = computed(() => statusSignal.value === "authenticated");
|
|
509
506
|
const isLoading = computed(() => statusSignal.value === "loading");
|
|
510
507
|
const accessSetSignal = accessControl ? signal(null) : null;
|
|
@@ -565,6 +562,10 @@ function AuthProvider({
|
|
|
565
562
|
onSuccess: handleAuthSuccess
|
|
566
563
|
});
|
|
567
564
|
const signIn = Object.assign(async (body) => {
|
|
565
|
+
if (deferredRefreshTimer) {
|
|
566
|
+
clearTimeout(deferredRefreshTimer);
|
|
567
|
+
deferredRefreshTimer = null;
|
|
568
|
+
}
|
|
568
569
|
statusSignal.value = "loading";
|
|
569
570
|
errorSignal.value = null;
|
|
570
571
|
const result = await signInMethod(body);
|
|
@@ -585,6 +586,10 @@ function AuthProvider({
|
|
|
585
586
|
onSuccess: handleAuthSuccess
|
|
586
587
|
});
|
|
587
588
|
const signUp = Object.assign(async (body) => {
|
|
589
|
+
if (deferredRefreshTimer) {
|
|
590
|
+
clearTimeout(deferredRefreshTimer);
|
|
591
|
+
deferredRefreshTimer = null;
|
|
592
|
+
}
|
|
588
593
|
statusSignal.value = "loading";
|
|
589
594
|
errorSignal.value = null;
|
|
590
595
|
const result = await signUpMethod(body);
|
|
@@ -645,7 +650,7 @@ function AuthProvider({
|
|
|
645
650
|
method: resetPasswordMethod.method,
|
|
646
651
|
meta: resetPasswordMethod.meta
|
|
647
652
|
});
|
|
648
|
-
const signOut = async () => {
|
|
653
|
+
const signOut = async (options) => {
|
|
649
654
|
tokenRefresh.cancel();
|
|
650
655
|
try {
|
|
651
656
|
await fetch(`${basePath}/signout`, {
|
|
@@ -658,9 +663,16 @@ function AuthProvider({
|
|
|
658
663
|
statusSignal.value = "unauthenticated";
|
|
659
664
|
errorSignal.value = null;
|
|
660
665
|
clearAccessSet();
|
|
661
|
-
if (
|
|
666
|
+
if (isBrowser()) {
|
|
662
667
|
delete window.__VERTZ_SESSION__;
|
|
663
668
|
}
|
|
669
|
+
if (options?.redirectTo) {
|
|
670
|
+
if (router) {
|
|
671
|
+
router.navigate({ to: options.redirectTo, replace: true }).catch(() => {});
|
|
672
|
+
} else if (typeof console !== "undefined") {
|
|
673
|
+
console.warn("[vertz] signOut({ redirectTo }) was called but no RouterContext is available. Navigation was skipped.");
|
|
674
|
+
}
|
|
675
|
+
}
|
|
664
676
|
};
|
|
665
677
|
let refreshInFlight = null;
|
|
666
678
|
const doRefresh = async () => {
|
|
@@ -730,9 +742,10 @@ function AuthProvider({
|
|
|
730
742
|
refresh,
|
|
731
743
|
mfaChallenge,
|
|
732
744
|
forgotPassword,
|
|
733
|
-
resetPassword
|
|
745
|
+
resetPassword,
|
|
746
|
+
providers: providersSignal
|
|
734
747
|
};
|
|
735
|
-
if (
|
|
748
|
+
if (isBrowser()) {
|
|
736
749
|
if (window.__VERTZ_SESSION__?.user) {
|
|
737
750
|
const session = window.__VERTZ_SESSION__;
|
|
738
751
|
userSignal.value = session.user;
|
|
@@ -741,11 +754,24 @@ function AuthProvider({
|
|
|
741
754
|
tokenRefresh.schedule(session.expiresAt);
|
|
742
755
|
}
|
|
743
756
|
} else {
|
|
744
|
-
|
|
757
|
+
deferredRefreshTimer = setTimeout(() => {
|
|
758
|
+
deferredRefreshTimer = null;
|
|
759
|
+
refresh();
|
|
760
|
+
}, 0);
|
|
761
|
+
}
|
|
762
|
+
} else {
|
|
763
|
+
const ssrCtx = getSSRContext();
|
|
764
|
+
if (ssrCtx?.ssrAuth) {
|
|
765
|
+
if (ssrCtx.ssrAuth.status === "authenticated") {
|
|
766
|
+
userSignal.value = ssrCtx.ssrAuth.user;
|
|
767
|
+
statusSignal.value = "authenticated";
|
|
768
|
+
} else {
|
|
769
|
+
statusSignal.value = "unauthenticated";
|
|
770
|
+
}
|
|
745
771
|
}
|
|
746
772
|
}
|
|
747
773
|
if (accessControl && accessSetSignal && accessLoadingSignal) {
|
|
748
|
-
if (
|
|
774
|
+
if (isBrowser() && window.__VERTZ_ACCESS_SET__ && typeof window.__VERTZ_ACCESS_SET__.entitlements === "object" && window.__VERTZ_ACCESS_SET__.entitlements !== null) {
|
|
749
775
|
accessSetSignal.value = window.__VERTZ_ACCESS_SET__;
|
|
750
776
|
accessLoadingSignal.value = false;
|
|
751
777
|
}
|
|
@@ -760,42 +786,74 @@ function AuthProvider({
|
|
|
760
786
|
}
|
|
761
787
|
return AuthContext.Provider({ value: contextValue, children });
|
|
762
788
|
}
|
|
763
|
-
// src/auth/auth-gate.ts
|
|
764
|
-
function AuthGate({ fallback, children }) {
|
|
765
|
-
const ctx = useContext(AuthContext);
|
|
766
|
-
if (!ctx) {
|
|
767
|
-
return typeof children === "function" ? children() : children;
|
|
768
|
-
}
|
|
769
|
-
const isResolved = computed(() => {
|
|
770
|
-
const status = ctx.status;
|
|
771
|
-
return status !== "idle" && status !== "loading";
|
|
772
|
-
});
|
|
773
|
-
return computed(() => {
|
|
774
|
-
if (isResolved.value) {
|
|
775
|
-
return typeof children === "function" ? children() : children;
|
|
776
|
-
}
|
|
777
|
-
return fallback ? fallback() : null;
|
|
778
|
-
});
|
|
779
|
-
}
|
|
780
789
|
// src/auth/create-access-provider.ts
|
|
781
790
|
function createAccessProvider() {
|
|
782
791
|
const accessSet = signal(null);
|
|
783
792
|
const loading = signal(true);
|
|
784
|
-
if (
|
|
793
|
+
if (isBrowser() && window.__VERTZ_ACCESS_SET__ && typeof window.__VERTZ_ACCESS_SET__.entitlements === "object" && window.__VERTZ_ACCESS_SET__.entitlements !== null) {
|
|
785
794
|
accessSet.value = window.__VERTZ_ACCESS_SET__;
|
|
786
795
|
loading.value = false;
|
|
787
796
|
}
|
|
788
797
|
return { accessSet, loading };
|
|
789
798
|
}
|
|
799
|
+
// src/auth/provider-icons.ts
|
|
800
|
+
var icons = {
|
|
801
|
+
github: (size) => `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12Z"/></svg>`,
|
|
802
|
+
google: (size) => `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24"><path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1Z"/><path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23Z"/><path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62Z"/><path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53Z"/></svg>`,
|
|
803
|
+
discord: (size) => `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="currentColor"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03ZM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418Zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418Z"/></svg>`,
|
|
804
|
+
apple: (size) => `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="currentColor"><path d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09ZM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.32 2.32-1.55 4.25-3.74 4.25Z"/></svg>`,
|
|
805
|
+
microsoft: (size) => `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24"><rect fill="#F25022" x="1" y="1" width="10" height="10"/><rect fill="#7FBA00" x="13" y="1" width="10" height="10"/><rect fill="#00A4EF" x="1" y="13" width="10" height="10"/><rect fill="#FFB900" x="13" y="13" width="10" height="10"/></svg>`,
|
|
806
|
+
twitter: (size) => `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>`
|
|
807
|
+
};
|
|
808
|
+
function fallbackIcon(size) {
|
|
809
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg>`;
|
|
810
|
+
}
|
|
811
|
+
function getProviderIcon(providerId, size) {
|
|
812
|
+
const iconFn = icons[providerId];
|
|
813
|
+
return iconFn ? iconFn(size) : fallbackIcon(size);
|
|
814
|
+
}
|
|
815
|
+
// src/auth/user-display.ts
|
|
816
|
+
function getUserDisplayName(user, fallback = "Unknown") {
|
|
817
|
+
if (!user)
|
|
818
|
+
return fallback;
|
|
819
|
+
const name = user.name;
|
|
820
|
+
if (typeof name === "string" && name.trim().length > 0)
|
|
821
|
+
return name.trim();
|
|
822
|
+
if (user.email)
|
|
823
|
+
return user.email;
|
|
824
|
+
return fallback;
|
|
825
|
+
}
|
|
826
|
+
function getUserInitials(user) {
|
|
827
|
+
if (!user)
|
|
828
|
+
return "?";
|
|
829
|
+
const name = user.name;
|
|
830
|
+
if (typeof name === "string" && name.trim().length > 0) {
|
|
831
|
+
const words = name.trim().split(/\s+/);
|
|
832
|
+
const first = words[0] ?? "";
|
|
833
|
+
const last = words[words.length - 1] ?? "";
|
|
834
|
+
if (words.length === 1 || !last)
|
|
835
|
+
return first.charAt(0).toUpperCase() || "?";
|
|
836
|
+
return (first.charAt(0) + last.charAt(0)).toUpperCase();
|
|
837
|
+
}
|
|
838
|
+
if (user.email && user.email.length > 0)
|
|
839
|
+
return user.email.charAt(0).toUpperCase();
|
|
840
|
+
return "?";
|
|
841
|
+
}
|
|
842
|
+
// src/auth/user-icon.ts
|
|
843
|
+
function getUserIcon(size) {
|
|
844
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>`;
|
|
845
|
+
}
|
|
790
846
|
export {
|
|
791
847
|
useAuth,
|
|
792
848
|
useAccessContext,
|
|
849
|
+
getUserInitials,
|
|
850
|
+
getUserIcon,
|
|
851
|
+
getUserDisplayName,
|
|
852
|
+
getProviderIcon,
|
|
793
853
|
createAccessProvider,
|
|
794
854
|
createAccessEventClient,
|
|
795
855
|
can,
|
|
796
856
|
AuthProvider,
|
|
797
|
-
AuthGate,
|
|
798
857
|
AuthContext,
|
|
799
|
-
AccessGate,
|
|
800
858
|
AccessContext
|
|
801
859
|
};
|
package/dist/src/css/public.d.ts
CHANGED
|
@@ -27,6 +27,101 @@ type CSSOutput<T extends CSSInput = CSSInput> = { readonly [K in keyof T & strin
|
|
|
27
27
|
* @returns Object with block names as keys (class name strings) and non-enumerable `css` property.
|
|
28
28
|
*/
|
|
29
29
|
declare function css<T extends CSSInput>(input: T & { [K in keyof T & "css"]? : never }, filePath?: string): CSSOutput<T>;
|
|
30
|
+
interface FontSrc {
|
|
31
|
+
path: string;
|
|
32
|
+
weight?: string | number;
|
|
33
|
+
style?: "normal" | "italic";
|
|
34
|
+
}
|
|
35
|
+
type FallbackFontName = "Arial" | "Times New Roman" | "Courier New";
|
|
36
|
+
interface FontFallbackMetrics {
|
|
37
|
+
/** CSS ascent-override value, e.g., '94.52%' */
|
|
38
|
+
ascentOverride: string;
|
|
39
|
+
/** CSS descent-override value, e.g., '24.60%' */
|
|
40
|
+
descentOverride: string;
|
|
41
|
+
/** CSS line-gap-override value, e.g., '0.00%' */
|
|
42
|
+
lineGapOverride: string;
|
|
43
|
+
/** CSS size-adjust value, e.g., '104.88%' */
|
|
44
|
+
sizeAdjust: string;
|
|
45
|
+
/** System font used as fallback base. */
|
|
46
|
+
fallbackFont: FallbackFontName;
|
|
47
|
+
}
|
|
48
|
+
interface CompileFontsOptions {
|
|
49
|
+
/** Pre-computed fallback metrics per font key. Provided by @vertz/ui-server at build/SSR time. */
|
|
50
|
+
fallbackMetrics?: Record<string, FontFallbackMetrics>;
|
|
51
|
+
}
|
|
52
|
+
interface FontOptions {
|
|
53
|
+
/** Font weight: '100..1000' (variable) or 400 (fixed). */
|
|
54
|
+
weight: string | number;
|
|
55
|
+
/** Font style. @default 'normal' */
|
|
56
|
+
style?: "normal" | "italic";
|
|
57
|
+
/** Font-display strategy. @default 'swap' */
|
|
58
|
+
display?: "auto" | "block" | "swap" | "fallback" | "optional";
|
|
59
|
+
/** URL path(s) for local/self-hosted fonts. */
|
|
60
|
+
src?: string | FontSrc[];
|
|
61
|
+
/** Fallback font stack. */
|
|
62
|
+
fallback?: string[];
|
|
63
|
+
/** Font subsets (metadata only — subsetting is deferred to a future phase). @default ['latin'] */
|
|
64
|
+
subsets?: string[];
|
|
65
|
+
/** Unicode range for subsetting. */
|
|
66
|
+
unicodeRange?: string;
|
|
67
|
+
/**
|
|
68
|
+
* Control automatic fallback font metric adjustment for zero-CLS font loading.
|
|
69
|
+
* - true: auto-detect fallback base from `fallback` array (default)
|
|
70
|
+
* - false: disable
|
|
71
|
+
* - 'Arial' | 'Times New Roman' | 'Courier New': explicit base
|
|
72
|
+
* @default true
|
|
73
|
+
*/
|
|
74
|
+
adjustFontFallback?: boolean | FallbackFontName;
|
|
75
|
+
}
|
|
76
|
+
type FontStyle = "normal" | "italic";
|
|
77
|
+
type FontDisplay = "auto" | "block" | "swap" | "fallback" | "optional";
|
|
78
|
+
interface FontDescriptor {
|
|
79
|
+
readonly __brand: "FontDescriptor";
|
|
80
|
+
readonly family: string;
|
|
81
|
+
readonly weight: string;
|
|
82
|
+
readonly style: FontStyle;
|
|
83
|
+
readonly display: FontDisplay;
|
|
84
|
+
readonly src?: string | FontSrc[];
|
|
85
|
+
readonly fallback: string[];
|
|
86
|
+
readonly subsets: string[];
|
|
87
|
+
readonly unicodeRange?: string;
|
|
88
|
+
readonly adjustFontFallback: boolean | FallbackFontName;
|
|
89
|
+
}
|
|
90
|
+
/** Structured description of a resource to preload. */
|
|
91
|
+
interface PreloadItem {
|
|
92
|
+
href: string;
|
|
93
|
+
as: "font" | "image" | "style" | "script";
|
|
94
|
+
type?: string;
|
|
95
|
+
crossorigin?: boolean;
|
|
96
|
+
}
|
|
97
|
+
interface CompiledFonts {
|
|
98
|
+
/** @font-face declarations. */
|
|
99
|
+
fontFaceCss: string;
|
|
100
|
+
/** :root { --font-<key>: ...; } block (for standalone use). */
|
|
101
|
+
cssVarsCss: string;
|
|
102
|
+
/** Individual CSS var lines (e.g., ' --font-sans: ...;') for merging into an existing :root. */
|
|
103
|
+
cssVarLines: string[];
|
|
104
|
+
/** <link rel="preload"> HTML tags for font files. */
|
|
105
|
+
preloadTags: string;
|
|
106
|
+
/** Structured preload data for generating HTTP Link headers. */
|
|
107
|
+
preloadItems: PreloadItem[];
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Create a font descriptor for use in theme definitions.
|
|
111
|
+
*
|
|
112
|
+
* @param family - The font family name (e.g., 'DM Sans').
|
|
113
|
+
* @param options - Font configuration.
|
|
114
|
+
* @returns A FontDescriptor.
|
|
115
|
+
*/
|
|
116
|
+
declare function font(family: string, options: FontOptions): FontDescriptor;
|
|
117
|
+
/**
|
|
118
|
+
* Compile font descriptors into CSS and preload tags.
|
|
119
|
+
*
|
|
120
|
+
* @param fonts - A map of token key → FontDescriptor.
|
|
121
|
+
* @param options - Optional compilation settings (e.g., pre-computed fallback metrics).
|
|
122
|
+
* @returns Compiled @font-face CSS, CSS var lines, and preload link tags.
|
|
123
|
+
*/
|
|
124
|
+
declare function compileFonts(fonts: Record<string, FontDescriptor>, options?: CompileFontsOptions): CompiledFonts;
|
|
30
125
|
/** Input to globalCss(): selector → property-value map. */
|
|
31
126
|
type GlobalCSSInput = Record<string, Record<string, string>>;
|
|
32
127
|
/** Output of globalCss(): extracted CSS string. */
|
|
@@ -65,6 +160,8 @@ interface ThemeInput {
|
|
|
65
160
|
colors: ColorTokens;
|
|
66
161
|
/** Spacing scale tokens. */
|
|
67
162
|
spacing?: SpacingTokens;
|
|
163
|
+
/** Font descriptors keyed by token name (e.g., sans, mono, display). */
|
|
164
|
+
fonts?: Record<string, FontDescriptor>;
|
|
68
165
|
}
|
|
69
166
|
/** The structured theme object returned by defineTheme(). */
|
|
70
167
|
interface Theme {
|
|
@@ -72,6 +169,8 @@ interface Theme {
|
|
|
72
169
|
colors: ColorTokens;
|
|
73
170
|
/** Spacing scale tokens. */
|
|
74
171
|
spacing?: SpacingTokens;
|
|
172
|
+
/** Font descriptors keyed by token name. */
|
|
173
|
+
fonts?: Record<string, FontDescriptor>;
|
|
75
174
|
}
|
|
76
175
|
/** Output of compileTheme(). */
|
|
77
176
|
interface CompiledTheme {
|
|
@@ -79,6 +178,15 @@ interface CompiledTheme {
|
|
|
79
178
|
css: string;
|
|
80
179
|
/** Flat list of token dot-paths (e.g., 'primary.500', 'background'). */
|
|
81
180
|
tokens: string[];
|
|
181
|
+
/** Font preload link tags for injection into <head>. */
|
|
182
|
+
preloadTags: string;
|
|
183
|
+
/** Structured preload data for generating HTTP Link headers. */
|
|
184
|
+
preloadItems: PreloadItem[];
|
|
185
|
+
}
|
|
186
|
+
/** Options for compileTheme(). */
|
|
187
|
+
interface CompileThemeOptions {
|
|
188
|
+
/** Pre-computed font fallback metrics for zero-CLS font loading. */
|
|
189
|
+
fallbackMetrics?: CompileFontsOptions["fallbackMetrics"];
|
|
82
190
|
}
|
|
83
191
|
/**
|
|
84
192
|
* Define a theme with raw and contextual design tokens.
|
|
@@ -97,7 +205,7 @@ declare function defineTheme(input: ThemeInput): Theme;
|
|
|
97
205
|
* @param theme - A theme object from defineTheme().
|
|
98
206
|
* @returns Compiled CSS and token list.
|
|
99
207
|
*/
|
|
100
|
-
declare function compileTheme(theme: Theme): CompiledTheme;
|
|
208
|
+
declare function compileTheme(theme: Theme, options?: CompileThemeOptions): CompiledTheme;
|
|
101
209
|
/** A child node: either a DOM Node or a string (text content). */
|
|
102
210
|
type ThemeChild = Node | string;
|
|
103
211
|
/** Props for ThemeProvider. */
|
|
@@ -151,4 +259,4 @@ interface VariantFunction<V extends VariantDefinitions> {
|
|
|
151
259
|
* @returns A function that accepts variant props and returns a className string.
|
|
152
260
|
*/
|
|
153
261
|
declare function variants<V extends VariantDefinitions>(config: VariantsConfig<V>): VariantFunction<V>;
|
|
154
|
-
export { variants, s, globalCss, defineTheme, css, compileTheme, VariantsConfig, VariantProps, VariantFunction, ThemeProviderProps, ThemeProvider, ThemeInput, Theme, StyleEntry, GlobalCSSOutput, GlobalCSSInput, CompiledTheme, CSSOutput, CSSInput };
|
|
262
|
+
export { variants, s, globalCss, font, defineTheme, css, compileTheme, compileFonts, VariantsConfig, VariantProps, VariantFunction, ThemeProviderProps, ThemeProvider, ThemeInput, Theme, StyleEntry, PreloadItem, GlobalCSSOutput, GlobalCSSInput, FontSrc, FontOptions, FontFallbackMetrics, FontDescriptor, FallbackFontName, CompiledTheme, CompiledFonts, CompileThemeOptions, CompileFontsOptions, CSSOutput, CSSInput };
|
package/dist/src/css/public.js
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
import {
|
|
2
2
|
ThemeProvider,
|
|
3
|
+
compileFonts,
|
|
3
4
|
compileTheme,
|
|
4
5
|
css,
|
|
5
6
|
defineTheme,
|
|
7
|
+
font,
|
|
6
8
|
globalCss,
|
|
7
9
|
s,
|
|
8
10
|
variants
|
|
9
|
-
} from "../../shared/chunk-
|
|
10
|
-
import"../../shared/chunk-
|
|
11
|
+
} from "../../shared/chunk-dhehvmj0.js";
|
|
12
|
+
import"../../shared/chunk-vndfjfdy.js";
|
|
11
13
|
import"../../shared/chunk-prj7nm08.js";
|
|
12
|
-
import"../../shared/chunk-
|
|
13
|
-
import"../../shared/chunk-
|
|
14
|
+
import"../../shared/chunk-afawz764.js";
|
|
15
|
+
import"../../shared/chunk-4fwcwxn6.js";
|
|
14
16
|
export {
|
|
15
17
|
variants,
|
|
16
18
|
s,
|
|
17
19
|
globalCss,
|
|
20
|
+
font,
|
|
18
21
|
defineTheme,
|
|
19
22
|
css,
|
|
20
23
|
compileTheme,
|
|
24
|
+
compileFonts,
|
|
21
25
|
ThemeProvider
|
|
22
26
|
};
|