@almadar/shell-web 0.0.0-stage → 0.1.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.
- package/bundling.d.mts +18 -0
- package/bundling.mjs +28 -0
- package/dist/ArbitraryClassCompiler-Mzabq-UB.d.ts +100 -0
- package/dist/AvlGlyph-JKJOAH23.js +6 -0
- package/dist/AvlStateMachine-PI4YGREK.js +8 -0
- package/dist/AvlTransitionDetail-ZH7V24UG.js +12 -0
- package/dist/AvlTransitionExplainer-ZSRT7L6Y.js +13 -0
- package/dist/BehaviorValueFrame-6RUJXT4A.js +29 -0
- package/dist/BehaviorValueFrame-SSEMEBTG.css +1756 -0
- package/dist/BehaviorView-RFEE5J6E.js +10 -0
- package/dist/Canvas3DHost-_Y-5uLM_.d.ts +552 -0
- package/dist/EventBusProvider-CVwjkV_2.d.ts +284 -0
- package/dist/FileTree-BCFnBEuQ.d.ts +254 -0
- package/dist/FlowCanvas-3JRMNJLV.css +1756 -0
- package/dist/FlowCanvas-STDC4OWK.js +27 -0
- package/dist/GameAudioProvider-Cm9BnvmP.d.ts +93 -0
- package/dist/KaTeX_AMS-Regular-CYEKBG2K.woff +0 -0
- package/dist/KaTeX_AMS-Regular-JKX5W2C4.ttf +0 -0
- package/dist/KaTeX_AMS-Regular-U6PRYMIZ.woff2 +0 -0
- package/dist/KaTeX_Caligraphic-Bold-5QL5CMTE.woff2 +0 -0
- package/dist/KaTeX_Caligraphic-Bold-WZ3QSGD3.woff +0 -0
- package/dist/KaTeX_Caligraphic-Bold-ZTS3R3HK.ttf +0 -0
- package/dist/KaTeX_Caligraphic-Regular-3LKEU76G.woff +0 -0
- package/dist/KaTeX_Caligraphic-Regular-A7XRTZ5Q.ttf +0 -0
- package/dist/KaTeX_Caligraphic-Regular-KX5MEWCF.woff2 +0 -0
- package/dist/KaTeX_Fraktur-Bold-2QVFK6NQ.woff2 +0 -0
- package/dist/KaTeX_Fraktur-Bold-T4SWXBMT.woff +0 -0
- package/dist/KaTeX_Fraktur-Bold-WGHVTYOR.ttf +0 -0
- package/dist/KaTeX_Fraktur-Regular-2PEIFJSJ.woff2 +0 -0
- package/dist/KaTeX_Fraktur-Regular-5U4OPH2X.ttf +0 -0
- package/dist/KaTeX_Fraktur-Regular-PQMHCIK6.woff +0 -0
- package/dist/KaTeX_Main-Bold-2GA4IZIN.woff +0 -0
- package/dist/KaTeX_Main-Bold-W5FBVCZM.ttf +0 -0
- package/dist/KaTeX_Main-Bold-YP5VVQRP.woff2 +0 -0
- package/dist/KaTeX_Main-BoldItalic-4P4C7HJH.woff +0 -0
- package/dist/KaTeX_Main-BoldItalic-N4V3DX7S.woff2 +0 -0
- package/dist/KaTeX_Main-BoldItalic-ODMLBJJQ.ttf +0 -0
- package/dist/KaTeX_Main-Italic-I43T2HSR.ttf +0 -0
- package/dist/KaTeX_Main-Italic-RELBIK7M.woff2 +0 -0
- package/dist/KaTeX_Main-Italic-SASNQFN2.woff +0 -0
- package/dist/KaTeX_Main-Regular-ARRPAO67.woff2 +0 -0
- package/dist/KaTeX_Main-Regular-P5I74A2A.woff +0 -0
- package/dist/KaTeX_Main-Regular-W74P5G27.ttf +0 -0
- package/dist/KaTeX_Math-BoldItalic-6EBV3DK5.woff +0 -0
- package/dist/KaTeX_Math-BoldItalic-K4WTGH3J.woff2 +0 -0
- package/dist/KaTeX_Math-BoldItalic-VB447A4D.ttf +0 -0
- package/dist/KaTeX_Math-Italic-6KGCHLFN.woff2 +0 -0
- package/dist/KaTeX_Math-Italic-KKK3USB2.woff +0 -0
- package/dist/KaTeX_Math-Italic-SON4MRCA.ttf +0 -0
- package/dist/KaTeX_SansSerif-Bold-RRNVJFFW.woff2 +0 -0
- package/dist/KaTeX_SansSerif-Bold-STQ6RXC7.ttf +0 -0
- package/dist/KaTeX_SansSerif-Bold-X5M5EMOD.woff +0 -0
- package/dist/KaTeX_SansSerif-Italic-HMPFTM52.woff2 +0 -0
- package/dist/KaTeX_SansSerif-Italic-PSN4QKYX.woff +0 -0
- package/dist/KaTeX_SansSerif-Italic-WTBAZBGY.ttf +0 -0
- package/dist/KaTeX_SansSerif-Regular-2TL3USAE.ttf +0 -0
- package/dist/KaTeX_SansSerif-Regular-OQCII6EP.woff +0 -0
- package/dist/KaTeX_SansSerif-Regular-XIQ62X4E.woff2 +0 -0
- package/dist/KaTeX_Script-Regular-72OLXYNA.ttf +0 -0
- package/dist/KaTeX_Script-Regular-A5IFOEBS.woff +0 -0
- package/dist/KaTeX_Script-Regular-APUWIHLP.woff2 +0 -0
- package/dist/KaTeX_Size1-Regular-4HRHTS65.woff +0 -0
- package/dist/KaTeX_Size1-Regular-5LRUTBFT.woff2 +0 -0
- package/dist/KaTeX_Size1-Regular-7K6AASVL.ttf +0 -0
- package/dist/KaTeX_Size2-Regular-222HN3GT.ttf +0 -0
- package/dist/KaTeX_Size2-Regular-K5ZHAIS6.woff +0 -0
- package/dist/KaTeX_Size2-Regular-LELKET5D.woff2 +0 -0
- package/dist/KaTeX_Size3-Regular-TLFPAHDE.woff +0 -0
- package/dist/KaTeX_Size3-Regular-UFCO6WCA.ttf +0 -0
- package/dist/KaTeX_Size3-Regular-WQRQ47UD.woff2 +0 -0
- package/dist/KaTeX_Size4-Regular-7PGNVPQK.ttf +0 -0
- package/dist/KaTeX_Size4-Regular-CDMV7U5C.woff2 +0 -0
- package/dist/KaTeX_Size4-Regular-PKMWZHNC.woff +0 -0
- package/dist/KaTeX_Typewriter-Regular-3F5K6SQ6.ttf +0 -0
- package/dist/KaTeX_Typewriter-Regular-MJMFSK64.woff +0 -0
- package/dist/KaTeX_Typewriter-Regular-VBYJ4NRC.woff2 +0 -0
- package/dist/KernelEngineContext-BOCQoFwk.d.ts +43 -0
- package/dist/LayersPanel-BBQ54IVG.js +7 -0
- package/dist/ModuleCard-3TT2X7IW.js +7 -0
- package/dist/OrbInspector-K6T6O7GI.js +27 -0
- package/dist/OrbInspector-MHLJ6OEE.css +1756 -0
- package/dist/Select-mDZIwNqN.d.ts +199 -0
- package/dist/ServerBridge-Cm1On51b.d.ts +233 -0
- package/dist/ThemeContext-DJmO59xd.d.ts +147 -0
- package/dist/TraitValueFrame-2PJGLLVI.js +28 -0
- package/dist/TraitValueFrame-4G3KOUBR.css +1756 -0
- package/dist/UISlotContext-Dl_ewwCI.d.ts +79 -0
- package/dist/UISlotRenderer-JKFSX24W.js +27 -0
- package/dist/UISlotRenderer-KVFO6J7R.css +1756 -0
- package/dist/UserContext-DqWeZkUZ.d.ts +100 -0
- package/dist/auth/browser/index.d.ts +2 -0
- package/dist/auth/browser/index.js +1 -0
- package/dist/auth/react/index.d.ts +49 -0
- package/dist/auth/react/index.js +119 -0
- package/dist/avl/index.css +1756 -0
- package/dist/avl/index.d.ts +2238 -0
- package/dist/avl/index.js +2693 -0
- package/dist/avl-3d-context-BIRKWpaL.d.ts +204 -0
- package/dist/avl-schema-parser-CtJxJ9KU.d.ts +132 -0
- package/dist/avl-zoom-state-CKMVuBFg.d.ts +17 -0
- package/dist/chunk-2PY54Z44.js +227 -0
- package/dist/chunk-2QOH2HWM.js +95 -0
- package/dist/chunk-3BBUBJFF.js +339 -0
- package/dist/chunk-42FY4RYA.js +191 -0
- package/dist/chunk-5QTYQTPS.js +15 -0
- package/dist/chunk-6P3MWXYE.js +440 -0
- package/dist/chunk-73SRAB4P.js +1053 -0
- package/dist/chunk-A2LR6VQQ.js +349 -0
- package/dist/chunk-AILY3XPS.js +562 -0
- package/dist/chunk-B4BU77LT.js +432 -0
- package/dist/chunk-DFNZUYX4.js +378 -0
- package/dist/chunk-DJ433ET5.js +1327 -0
- package/dist/chunk-DLZF4PVE.js +24 -0
- package/dist/chunk-DYEKAA4L.js +787 -0
- package/dist/chunk-DZ42OJQC.js +176 -0
- package/dist/chunk-EOWMARUB.js +16 -0
- package/dist/chunk-EQAMU2ZC.js +14 -0
- package/dist/chunk-FAJDTHWC.js +98 -0
- package/dist/chunk-FIW6WN23.js +508 -0
- package/dist/chunk-FP3WIKTC.js +303 -0
- package/dist/chunk-G7DCAZ22.js +19 -0
- package/dist/chunk-GAR5TQ5B.js +199 -0
- package/dist/chunk-GKIFONTE.js +131 -0
- package/dist/chunk-GYTPOFVC.js +47155 -0
- package/dist/chunk-KVQS4GXU.js +328 -0
- package/dist/chunk-L2DEKY4J.js +97 -0
- package/dist/chunk-L677XGY3.js +701 -0
- package/dist/chunk-MBQAMMSE.js +11877 -0
- package/dist/chunk-P4LNHAFI.js +1051 -0
- package/dist/chunk-P4ZFUQFF.js +93 -0
- package/dist/chunk-PC7K4SK7.js +1384 -0
- package/dist/chunk-R5O5AUPI.js +573 -0
- package/dist/chunk-SGM3FASH.js +672 -0
- package/dist/chunk-SJGJJKBY.js +502 -0
- package/dist/chunk-TESBIVUA.js +11 -0
- package/dist/chunk-TZZBINQY.js +82 -0
- package/dist/chunk-U6QRZASX.js +280 -0
- package/dist/chunk-VFF5OO47.js +319 -0
- package/dist/chunk-YDNJLLG6.js +516 -0
- package/dist/chunk-YHMRX6YA.js +455 -0
- package/dist/chunk-ZO6MXAS3.js +69 -0
- package/dist/components/index.css +1756 -0
- package/dist/components/index.d.ts +11093 -0
- package/dist/components/index.js +1110 -0
- package/dist/context/index.d.ts +9 -0
- package/dist/context/index.js +7 -0
- package/dist/core.d.ts +2523 -0
- package/dist/core.js +2 -0
- package/dist/design-classes/index.cjs +429 -0
- package/dist/design-classes/index.d.cts +165 -0
- package/dist/design-classes/index.d.ts +165 -0
- package/dist/design-classes/index.js +397 -0
- package/dist/emojiItems-QGSNAABW.js +20 -0
- package/dist/fx-CmQjnHmT.d.ts +371 -0
- package/dist/hooks/index.d.ts +936 -0
- package/dist/hooks/index.js +7 -0
- package/dist/index.d.ts +486 -0
- package/dist/index.js +38 -0
- package/dist/katexPlugin-FA7NX4PE.css +1161 -0
- package/dist/katexPlugin-NCDKOOQY.js +2 -0
- package/dist/kernel-client-ZH4PSMCN.js +367 -0
- package/dist/kernel-wire-B4S8pnP3.d.ts +65 -0
- package/dist/lib/index.d.ts +602 -0
- package/dist/lib/index.js +1288 -0
- package/dist/paintDispatch-ChW5mVuK.d.ts +698 -0
- package/dist/parseLessonSegments-GpCeMrb2.d.ts +334 -0
- package/dist/perf-CKiBKbkw.d.ts +22 -0
- package/dist/perf-Dr28-AgT.d.ts +57 -0
- package/dist/prism-AIWGN2X5.js +134 -0
- package/dist/providers/index.css +1756 -0
- package/dist/providers/index.d.ts +340 -0
- package/dist/providers/index.js +30 -0
- package/dist/renderer/index.d.ts +467 -0
- package/dist/renderer/index.js +3 -0
- package/dist/runtime/index.css +1756 -0
- package/dist/runtime/index.d.ts +440 -0
- package/dist/runtime/index.js +31 -0
- package/dist/slot-host-CPzrxLo9.d.ts +48 -0
- package/dist/ssr/index.cjs +7631 -0
- package/dist/ssr/index.d.cts +487 -0
- package/dist/ssr/index.d.ts +487 -0
- package/dist/ssr/index.js +7599 -0
- package/dist/storage/browser/index.d.ts +1 -0
- package/dist/storage/browser/index.js +1 -0
- package/dist/test-support.d.ts +35 -0
- package/dist/test-support.js +114 -0
- package/dist/themeTokens-CRd8AEDF.d.ts +125 -0
- package/dist/three/index.css +503 -0
- package/dist/three/index.d.ts +1185 -0
- package/dist/three/index.js +3896 -0
- package/dist/useKeyboardRouter-Dsq553Ur.d.ts +42 -0
- package/dist/useUISlots-CiobNFGb.d.ts +211 -0
- package/dist/verification-C5pTeMJv.d.ts +66 -0
- package/dist/verificationRegistry-CabxhfTv.d.ts +122 -0
- package/dist/wrapCallbackForEvent-B9QLbhxX.d.ts +19 -0
- package/index.css +199 -0
- package/package.json +269 -3
- package/src/core/locales/ar.json +1263 -0
- package/src/core/locales/en.json +1263 -0
- package/src/core/locales/index.ts +54 -0
- package/src/core/locales/sl.json +1263 -0
- package/src/core/tokens/native-tokens.json +369 -0
- package/tailwind-compile.cjs +29 -0
- package/tailwind-preset.cjs +991 -0
- package/themes/_base.css +451 -0
- package/themes/_contract.md +307 -0
- package/themes/_fonts-kenney.css +11 -0
- package/themes/_fonts.css +12 -0
- package/themes/_foundation.css +105 -0
- package/themes/_head.css +22 -0
- package/themes/_presets.css +67 -0
- package/themes/almadar-heritage.css +455 -0
- package/themes/almadar-website.css +269 -0
- package/themes/almadar.css +269 -0
- package/themes/aqua.css +455 -0
- package/themes/arabesque.css +459 -0
- package/themes/art-deco.css +457 -0
- package/themes/art-nouveau.css +459 -0
- package/themes/atelier.css +463 -0
- package/themes/bauhaus.css +461 -0
- package/themes/bloomberg-dense.css +463 -0
- package/themes/blueprint.css +457 -0
- package/themes/clay.css +449 -0
- package/themes/comic.css +453 -0
- package/themes/constructivist.css +457 -0
- package/themes/corporate.css +449 -0
- package/themes/cyberpunk.css +453 -0
- package/themes/frutiger-aero.css +458 -0
- package/themes/game-adventure.css +201 -0
- package/themes/game-rpg.css +203 -0
- package/themes/game-sci-fi.css +201 -0
- package/themes/game-ui-pack.css +200 -0
- package/themes/gazette.css +449 -0
- package/themes/glass.css +457 -0
- package/themes/gothic.css +453 -0
- package/themes/index.css +21 -0
- package/themes/ink-wash.css +459 -0
- package/themes/kawaii.css +459 -0
- package/themes/kflow.css +310 -0
- package/themes/kiosk.css +449 -0
- package/themes/linear-clean.css +463 -0
- package/themes/luxury.css +451 -0
- package/themes/mac-classic.css +455 -0
- package/themes/material.css +463 -0
- package/themes/memphis.css +453 -0
- package/themes/mid-century.css +455 -0
- package/themes/minimalist.css +449 -0
- package/themes/mudcloth.css +459 -0
- package/themes/nata.css +310 -0
- package/themes/neon.css +453 -0
- package/themes/neumorphic.css +451 -0
- package/themes/newsprint.css +455 -0
- package/themes/notion-editorial.css +463 -0
- package/themes/orb.css +465 -0
- package/themes/pixel.css +449 -0
- package/themes/prism.css +309 -0
- package/themes/rawi.css +310 -0
- package/themes/retro.css +452 -0
- package/themes/risograph.css +463 -0
- package/themes/scandi.css +469 -0
- package/themes/sketch.css +455 -0
- package/themes/solarpunk.css +469 -0
- package/themes/steampunk.css +451 -0
- package/themes/swiss.css +455 -0
- package/themes/terminal.css +466 -0
- package/themes/trait-wars.css +487 -0
- package/themes/ukiyo-e.css +459 -0
- package/themes/vaporwave.css +455 -0
- package/themes/victorian.css +453 -0
- package/themes/wabi-sabi.css +459 -0
- package/themes/win95.css +455 -0
- package/themes/wireframe.css +439 -0
- package/themes/zine.css +455 -0
- package/README.md +0 -3
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { UserContext as UserContext$1, FieldValue } from '@almadar/core';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* UserContext
|
|
6
|
+
*
|
|
7
|
+
* React context for providing user data throughout the application.
|
|
8
|
+
* Enables @user bindings in S-expressions for role-based UI and permissions.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* ```tsx
|
|
12
|
+
* // In App.tsx or layout
|
|
13
|
+
* <UserProvider user={{ id: '123', role: 'admin', permissions: ['read', 'write'] }}>
|
|
14
|
+
* <App />
|
|
15
|
+
* </UserProvider>
|
|
16
|
+
*
|
|
17
|
+
* // In components - access via hook
|
|
18
|
+
* const { user, hasRole, hasPermission } = useUser();
|
|
19
|
+
* if (hasRole('admin')) { ... }
|
|
20
|
+
* if (hasPermission('delete')) { ... }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* @packageDocumentation
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* User data for `@user` bindings — the canonical `UserContext` from
|
|
28
|
+
* `@almadar/core`, kept under this name for existing consumers. Declaring the
|
|
29
|
+
* shape locally let it drift from the type both execution paths resolve against.
|
|
30
|
+
*/
|
|
31
|
+
type UserData = UserContext$1;
|
|
32
|
+
/**
|
|
33
|
+
* User context value.
|
|
34
|
+
*/
|
|
35
|
+
interface UserContextValue {
|
|
36
|
+
/** Current user data (null if not logged in) */
|
|
37
|
+
user: UserData | null;
|
|
38
|
+
/** Check if user is logged in */
|
|
39
|
+
isLoggedIn: boolean;
|
|
40
|
+
/** Check if user has a specific role */
|
|
41
|
+
hasRole: (role: string) => boolean;
|
|
42
|
+
/** Check if user has a specific permission */
|
|
43
|
+
hasPermission: (permission: string) => boolean;
|
|
44
|
+
/** Check if user has any of the specified roles */
|
|
45
|
+
hasAnyRole: (roles: string[]) => boolean;
|
|
46
|
+
/** Check if user has all of the specified permissions */
|
|
47
|
+
hasAllPermissions: (permissions: string[]) => boolean;
|
|
48
|
+
/** Get a user field by path (for @user.field bindings) */
|
|
49
|
+
getUserField: (path: string) => FieldValue | undefined;
|
|
50
|
+
}
|
|
51
|
+
declare const UserContext: React__default.Context<UserContextValue | null>;
|
|
52
|
+
interface UserProviderProps {
|
|
53
|
+
/** User data (null if not logged in) */
|
|
54
|
+
user?: UserData | null;
|
|
55
|
+
/** Children to render */
|
|
56
|
+
children: React__default.ReactNode;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Provider component that provides user context to the application.
|
|
60
|
+
*
|
|
61
|
+
* Provides RBAC helpers and field access for @user bindings.
|
|
62
|
+
*/
|
|
63
|
+
declare function UserProvider({ user, children, }: UserProviderProps): React__default.ReactElement;
|
|
64
|
+
/**
|
|
65
|
+
* Hook to access the user context.
|
|
66
|
+
*
|
|
67
|
+
* Returns default values if used outside of UserProvider (for resilience).
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```tsx
|
|
71
|
+
* function AdminPanel() {
|
|
72
|
+
* const { user, hasRole, hasPermission } = useUser();
|
|
73
|
+
*
|
|
74
|
+
* if (!hasRole('admin') && !hasPermission('admin:access')) {
|
|
75
|
+
* return <AccessDenied />;
|
|
76
|
+
* }
|
|
77
|
+
*
|
|
78
|
+
* return <div>Welcome, {user?.name}</div>;
|
|
79
|
+
* }
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
declare function useUser(): UserContextValue;
|
|
83
|
+
/**
|
|
84
|
+
* Hook to check if user has a specific role.
|
|
85
|
+
* Convenience wrapper around useUser().hasRole().
|
|
86
|
+
*/
|
|
87
|
+
declare function useHasRole(role: string): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Hook to check if user has a specific permission.
|
|
90
|
+
* Convenience wrapper around useUser().hasPermission().
|
|
91
|
+
*/
|
|
92
|
+
declare function useHasPermission(permission: string): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Hook to get user data for @user bindings in S-expressions.
|
|
95
|
+
* Returns the user data object compatible with EvaluationContext.user
|
|
96
|
+
*/
|
|
97
|
+
declare function useUserForEvaluation(): UserData | undefined;
|
|
98
|
+
|
|
99
|
+
export { UserContext as U, UserProvider as c, useHasRole as e, useUser as f, useUserForEvaluation as g, useHasPermission as u };
|
|
100
|
+
export type { UserContextValue as a, UserData as b, UserProviderProps as d };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from '@almadar/shell-browser/auth';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ReactNode, ReactElement } from 'react';
|
|
2
|
+
import { ViewerAuthority, UserContext } from '@almadar/core';
|
|
3
|
+
import { BrowserAuth, SignedInUser } from '@almadar/shell-browser/auth';
|
|
4
|
+
export { BrowserAuth, SignedInUser } from '@almadar/shell-browser/auth';
|
|
5
|
+
|
|
6
|
+
/** The provider's resolved viewer authority — `@almadar/core`'s {@link ViewerAuthority}. */
|
|
7
|
+
type AuthAuthority = ViewerAuthority;
|
|
8
|
+
interface AuthContextValue {
|
|
9
|
+
/** The sign-in surface, or null when the app has no auth configured. */
|
|
10
|
+
auth: BrowserAuth | null;
|
|
11
|
+
user: SignedInUser | null;
|
|
12
|
+
authority: AuthAuthority;
|
|
13
|
+
/** An interactive auth action (or the initial connect) is in flight. */
|
|
14
|
+
loading: boolean;
|
|
15
|
+
/** The last interactive action's failure; a valid session survives it. */
|
|
16
|
+
error: string | null;
|
|
17
|
+
clearError(): void;
|
|
18
|
+
signInWithGoogle(): Promise<void>;
|
|
19
|
+
signInWithEmail(email: string, password: string): Promise<void>;
|
|
20
|
+
signUpWithEmail(email: string, password: string, displayName?: string): Promise<void>;
|
|
21
|
+
sendSignInLinkToEmail(email: string, returnUrl: string): Promise<void>;
|
|
22
|
+
isSignInWithEmailLink(link: string): boolean;
|
|
23
|
+
signInWithEmailLink(email: string, link: string): Promise<void>;
|
|
24
|
+
signInWithCustomToken(customToken: string): Promise<void>;
|
|
25
|
+
signOut(): Promise<void>;
|
|
26
|
+
}
|
|
27
|
+
interface AuthProviderProps {
|
|
28
|
+
/** Connects the app's sign-in surface; resolves null when the app has no auth configured. */
|
|
29
|
+
connect: () => Promise<BrowserAuth | null>;
|
|
30
|
+
children: ReactNode;
|
|
31
|
+
}
|
|
32
|
+
declare function AuthProvider({ connect, children }: AuthProviderProps): ReactElement;
|
|
33
|
+
/** The provider's value, or undefined outside an AuthProvider (an app with no sign-in surface). */
|
|
34
|
+
declare function useOptionalAuth(): AuthContextValue | undefined;
|
|
35
|
+
declare function useAuth(): AuthContextValue;
|
|
36
|
+
interface DevPersonas {
|
|
37
|
+
/** The app's `[identity]` rows; empty when the server offers no dev personas (no Auth emulator). */
|
|
38
|
+
personas: UserContext[];
|
|
39
|
+
signInAs(id: string): Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The dev persona roster a program's `std-dev-personas` hooks offer (`personas`, `persona-sign-in`; they
|
|
43
|
+
* answer only while the server runs on the Auth emulator), and sign-in as one of them: a real emulated
|
|
44
|
+
* user, so `@user` resolves as in production.
|
|
45
|
+
*/
|
|
46
|
+
declare function useDevPersonas(apiBase: string): DevPersonas;
|
|
47
|
+
|
|
48
|
+
export { AuthProvider, useAuth, useDevPersonas, useOptionalAuth };
|
|
49
|
+
export type { AuthAuthority, AuthContextValue, AuthProviderProps, DevPersonas };
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import '../../chunk-G7DCAZ22.js';
|
|
2
|
+
import { createContext, useState, useEffect, useCallback, useMemo, useContext } from 'react';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { FieldValueSchema } from '@almadar/core';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
var AuthContext = createContext(void 0);
|
|
8
|
+
var NOT_CONFIGURED = "Sign-in is not configured for this app";
|
|
9
|
+
function AuthProvider({ connect, children }) {
|
|
10
|
+
const [auth, setAuth] = useState(null);
|
|
11
|
+
const [user, setUser] = useState(null);
|
|
12
|
+
const [authority, setAuthority] = useState("pending");
|
|
13
|
+
const [loading, setLoading] = useState(true);
|
|
14
|
+
const [error, setError] = useState(null);
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
let unsubscribe;
|
|
17
|
+
let cancelled = false;
|
|
18
|
+
connect().then((connected) => {
|
|
19
|
+
if (cancelled) return;
|
|
20
|
+
setAuth(connected);
|
|
21
|
+
if (connected === null) {
|
|
22
|
+
setAuthority("unavailable");
|
|
23
|
+
setLoading(false);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
unsubscribe = connected.onUserChanged(
|
|
27
|
+
(next) => {
|
|
28
|
+
setUser(next);
|
|
29
|
+
setAuthority(next === null ? "anonymous" : "authenticated");
|
|
30
|
+
setLoading(false);
|
|
31
|
+
},
|
|
32
|
+
(err) => {
|
|
33
|
+
setUser(null);
|
|
34
|
+
setAuthority("failed");
|
|
35
|
+
setError(err.message);
|
|
36
|
+
setLoading(false);
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
}).catch((err) => {
|
|
40
|
+
if (cancelled) return;
|
|
41
|
+
setAuthority("failed");
|
|
42
|
+
setError(err.message);
|
|
43
|
+
setLoading(false);
|
|
44
|
+
});
|
|
45
|
+
return () => {
|
|
46
|
+
cancelled = true;
|
|
47
|
+
unsubscribe?.();
|
|
48
|
+
};
|
|
49
|
+
}, [connect]);
|
|
50
|
+
const run = useCallback(async (action) => {
|
|
51
|
+
if (auth === null) {
|
|
52
|
+
setError(NOT_CONFIGURED);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
setLoading(true);
|
|
56
|
+
setError(null);
|
|
57
|
+
try {
|
|
58
|
+
await action(auth);
|
|
59
|
+
} catch (err) {
|
|
60
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
61
|
+
} finally {
|
|
62
|
+
setLoading(false);
|
|
63
|
+
}
|
|
64
|
+
}, [auth]);
|
|
65
|
+
const value = useMemo(() => ({
|
|
66
|
+
auth,
|
|
67
|
+
user,
|
|
68
|
+
authority,
|
|
69
|
+
loading,
|
|
70
|
+
error,
|
|
71
|
+
clearError: () => setError(null),
|
|
72
|
+
signInWithGoogle: () => run((a) => a.signInWithGoogle()),
|
|
73
|
+
signInWithEmail: (email, password) => run((a) => a.signInWithEmail(email, password)),
|
|
74
|
+
signUpWithEmail: (email, password, displayName) => run((a) => a.signUpWithEmail(email, password, displayName)),
|
|
75
|
+
sendSignInLinkToEmail: (email, returnUrl) => run((a) => a.sendSignInLinkToEmail(email, returnUrl)),
|
|
76
|
+
isSignInWithEmailLink: (link) => auth?.isSignInWithEmailLink(link) ?? false,
|
|
77
|
+
signInWithEmailLink: (email, link) => run((a) => a.signInWithEmailLink(email, link)),
|
|
78
|
+
signInWithCustomToken: (customToken) => run((a) => a.signInWithCustomToken(customToken)),
|
|
79
|
+
signOut: () => run((a) => a.signOut())
|
|
80
|
+
}), [auth, user, authority, loading, error, run]);
|
|
81
|
+
return /* @__PURE__ */ jsx(AuthContext.Provider, { value, children });
|
|
82
|
+
}
|
|
83
|
+
function useOptionalAuth() {
|
|
84
|
+
return useContext(AuthContext);
|
|
85
|
+
}
|
|
86
|
+
function useAuth() {
|
|
87
|
+
const value = useContext(AuthContext);
|
|
88
|
+
if (value === void 0) throw new Error("useAuth must be used within an AuthProvider");
|
|
89
|
+
return value;
|
|
90
|
+
}
|
|
91
|
+
var PersonasSchema = z.object({
|
|
92
|
+
success: z.literal(true),
|
|
93
|
+
personas: z.array(z.object({ id: z.string() }).catchall(FieldValueSchema.optional()))
|
|
94
|
+
});
|
|
95
|
+
var SignInSchema = z.object({ success: z.literal(true), customToken: z.string() });
|
|
96
|
+
function useDevPersonas(apiBase) {
|
|
97
|
+
const { signInWithCustomToken } = useAuth();
|
|
98
|
+
const [personas, setPersonas] = useState([]);
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
let cancelled = false;
|
|
101
|
+
void fetch(`${apiBase}/api/hooks/personas`, { method: "POST", headers: { "Content-Type": "application/json" }, body: "{}" }).then(async (res) => res.ok ? PersonasSchema.parse(await res.json()).personas : []).then((list) => {
|
|
102
|
+
if (!cancelled) setPersonas(list);
|
|
103
|
+
});
|
|
104
|
+
return () => {
|
|
105
|
+
cancelled = true;
|
|
106
|
+
};
|
|
107
|
+
}, [apiBase]);
|
|
108
|
+
const signInAs = useCallback(async (id) => {
|
|
109
|
+
const res = await fetch(`${apiBase}/api/hooks/persona-sign-in`, {
|
|
110
|
+
method: "POST",
|
|
111
|
+
headers: { "Content-Type": "application/json" },
|
|
112
|
+
body: JSON.stringify({ id })
|
|
113
|
+
});
|
|
114
|
+
await signInWithCustomToken(SignInSchema.parse(await res.json()).customToken);
|
|
115
|
+
}, [apiBase, signInWithCustomToken]);
|
|
116
|
+
return { personas, signInAs };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export { AuthProvider, useAuth, useDevPersonas, useOptionalAuth };
|