@molecule/app-react 1.0.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 (131) hide show
  1. package/LICENSE +115 -0
  2. package/README.md +2645 -0
  3. package/dist/agent-identity.d.ts +40 -0
  4. package/dist/agent-identity.d.ts.map +1 -0
  5. package/dist/agent-identity.js +31 -0
  6. package/dist/agent-identity.js.map +1 -0
  7. package/dist/contexts.d.ts +69 -0
  8. package/dist/contexts.d.ts.map +1 -0
  9. package/dist/contexts.js +70 -0
  10. package/dist/contexts.js.map +1 -0
  11. package/dist/hooks/index.d.ts +32 -0
  12. package/dist/hooks/index.d.ts.map +1 -0
  13. package/dist/hooks/index.js +32 -0
  14. package/dist/hooks/index.js.map +1 -0
  15. package/dist/hooks/useAIModels.d.ts +48 -0
  16. package/dist/hooks/useAIModels.d.ts.map +1 -0
  17. package/dist/hooks/useAIModels.js +145 -0
  18. package/dist/hooks/useAIModels.js.map +1 -0
  19. package/dist/hooks/useAsyncState.d.ts +41 -0
  20. package/dist/hooks/useAsyncState.d.ts.map +1 -0
  21. package/dist/hooks/useAsyncState.js +77 -0
  22. package/dist/hooks/useAsyncState.js.map +1 -0
  23. package/dist/hooks/useAuth.d.ts +43 -0
  24. package/dist/hooks/useAuth.d.ts.map +1 -0
  25. package/dist/hooks/useAuth.js +106 -0
  26. package/dist/hooks/useAuth.js.map +1 -0
  27. package/dist/hooks/useCapacitorApp.d.ts +35 -0
  28. package/dist/hooks/useCapacitorApp.d.ts.map +1 -0
  29. package/dist/hooks/useCapacitorApp.js +61 -0
  30. package/dist/hooks/useCapacitorApp.js.map +1 -0
  31. package/dist/hooks/useChangePassword.d.ts +34 -0
  32. package/dist/hooks/useChangePassword.d.ts.map +1 -0
  33. package/dist/hooks/useChangePassword.js +37 -0
  34. package/dist/hooks/useChangePassword.js.map +1 -0
  35. package/dist/hooks/useChat.d.ts +30 -0
  36. package/dist/hooks/useChat.d.ts.map +1 -0
  37. package/dist/hooks/useChat.js +1510 -0
  38. package/dist/hooks/useChat.js.map +1 -0
  39. package/dist/hooks/useDevice.d.ts +39 -0
  40. package/dist/hooks/useDevice.d.ts.map +1 -0
  41. package/dist/hooks/useDevice.js +41 -0
  42. package/dist/hooks/useDevice.js.map +1 -0
  43. package/dist/hooks/useEditor.d.ts +20 -0
  44. package/dist/hooks/useEditor.d.ts.map +1 -0
  45. package/dist/hooks/useEditor.js +98 -0
  46. package/dist/hooks/useEditor.js.map +1 -0
  47. package/dist/hooks/useForm.d.ts +87 -0
  48. package/dist/hooks/useForm.d.ts.map +1 -0
  49. package/dist/hooks/useForm.js +148 -0
  50. package/dist/hooks/useForm.js.map +1 -0
  51. package/dist/hooks/useHttp.d.ts +103 -0
  52. package/dist/hooks/useHttp.d.ts.map +1 -0
  53. package/dist/hooks/useHttp.js +161 -0
  54. package/dist/hooks/useHttp.js.map +1 -0
  55. package/dist/hooks/useLogger.d.ts +68 -0
  56. package/dist/hooks/useLogger.d.ts.map +1 -0
  57. package/dist/hooks/useLogger.js +95 -0
  58. package/dist/hooks/useLogger.js.map +1 -0
  59. package/dist/hooks/useLogin.d.ts +35 -0
  60. package/dist/hooks/useLogin.d.ts.map +1 -0
  61. package/dist/hooks/useLogin.js +37 -0
  62. package/dist/hooks/useLogin.js.map +1 -0
  63. package/dist/hooks/useOAuth.d.ts +83 -0
  64. package/dist/hooks/useOAuth.d.ts.map +1 -0
  65. package/dist/hooks/useOAuth.js +348 -0
  66. package/dist/hooks/useOAuth.js.map +1 -0
  67. package/dist/hooks/usePasswordReset.d.ts +43 -0
  68. package/dist/hooks/usePasswordReset.d.ts.map +1 -0
  69. package/dist/hooks/usePasswordReset.js +50 -0
  70. package/dist/hooks/usePasswordReset.js.map +1 -0
  71. package/dist/hooks/usePlatform.d.ts +38 -0
  72. package/dist/hooks/usePlatform.d.ts.map +1 -0
  73. package/dist/hooks/usePlatform.js +40 -0
  74. package/dist/hooks/usePlatform.js.map +1 -0
  75. package/dist/hooks/usePreview.d.ts +20 -0
  76. package/dist/hooks/usePreview.d.ts.map +1 -0
  77. package/dist/hooks/usePreview.js +62 -0
  78. package/dist/hooks/usePreview.js.map +1 -0
  79. package/dist/hooks/usePromise.d.ts +39 -0
  80. package/dist/hooks/usePromise.d.ts.map +1 -0
  81. package/dist/hooks/usePromise.js +92 -0
  82. package/dist/hooks/usePromise.js.map +1 -0
  83. package/dist/hooks/usePush.d.ts +50 -0
  84. package/dist/hooks/usePush.d.ts.map +1 -0
  85. package/dist/hooks/usePush.js +89 -0
  86. package/dist/hooks/usePush.js.map +1 -0
  87. package/dist/hooks/useRouter.d.ts +65 -0
  88. package/dist/hooks/useRouter.d.ts.map +1 -0
  89. package/dist/hooks/useRouter.js +120 -0
  90. package/dist/hooks/useRouter.js.map +1 -0
  91. package/dist/hooks/useSignup.d.ts +35 -0
  92. package/dist/hooks/useSignup.d.ts.map +1 -0
  93. package/dist/hooks/useSignup.js +37 -0
  94. package/dist/hooks/useSignup.js.map +1 -0
  95. package/dist/hooks/useStorage.d.ts +72 -0
  96. package/dist/hooks/useStorage.d.ts.map +1 -0
  97. package/dist/hooks/useStorage.js +144 -0
  98. package/dist/hooks/useStorage.js.map +1 -0
  99. package/dist/hooks/useStore.d.ts +51 -0
  100. package/dist/hooks/useStore.d.ts.map +1 -0
  101. package/dist/hooks/useStore.js +86 -0
  102. package/dist/hooks/useStore.js.map +1 -0
  103. package/dist/hooks/useTheme.d.ts +50 -0
  104. package/dist/hooks/useTheme.d.ts.map +1 -0
  105. package/dist/hooks/useTheme.js +135 -0
  106. package/dist/hooks/useTheme.js.map +1 -0
  107. package/dist/hooks/useTranslation.d.ts +69 -0
  108. package/dist/hooks/useTranslation.d.ts.map +1 -0
  109. package/dist/hooks/useTranslation.js +131 -0
  110. package/dist/hooks/useTranslation.js.map +1 -0
  111. package/dist/hooks/useVersion.d.ts +41 -0
  112. package/dist/hooks/useVersion.d.ts.map +1 -0
  113. package/dist/hooks/useVersion.js +73 -0
  114. package/dist/hooks/useVersion.js.map +1 -0
  115. package/dist/hooks/useWorkspace.d.ts +18 -0
  116. package/dist/hooks/useWorkspace.d.ts.map +1 -0
  117. package/dist/hooks/useWorkspace.js +67 -0
  118. package/dist/hooks/useWorkspace.js.map +1 -0
  119. package/dist/index.d.ts +80 -0
  120. package/dist/index.d.ts.map +1 -0
  121. package/dist/index.js +80 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/providers.d.ts +189 -0
  124. package/dist/providers.d.ts.map +1 -0
  125. package/dist/providers.js +248 -0
  126. package/dist/providers.js.map +1 -0
  127. package/dist/types.d.ts +381 -0
  128. package/dist/types.d.ts.map +1 -0
  129. package/dist/types.js +7 -0
  130. package/dist/types.js.map +1 -0
  131. package/package.json +82 -0
@@ -0,0 +1,348 @@
1
+ /**
2
+ * React hook for OAuth authentication.
3
+ *
4
+ * Supports two initiation modes that share ONE callback path:
5
+ * - {@link UseOAuthReturn.redirect} — full-page redirect (the default; unchanged).
6
+ * - {@link UseOAuthReturn.loginViaPopup} — opens the provider in a popup so the
7
+ * opener page never navigates (used by in-app auth modals). On completion the
8
+ * popup relays the result to the opener via a STRICTLY-validated `postMessage`
9
+ * and closes itself; the opener establishes the session in place.
10
+ *
11
+ * Security model for the popup relay (see inline notes at each gate):
12
+ * - The popup posts ONLY to its own origin (`targetOrigin = location.origin`),
13
+ * never `'*'`, so the bearer token can never be delivered to another origin.
14
+ * - The opener accepts a result ONLY when ALL hold: `event.origin === location.origin`,
15
+ * `event.source === thePopupWindowWeOpened`, and `event.data.type` matches our
16
+ * private message type. Anything else is ignored — a forged cross-origin (or
17
+ * wrong-window) message cannot inject a session.
18
+ * - The popup-relay path is gated on `window.name === OAUTH_POPUP_WINDOW_NAME`
19
+ * AND `window.opener`, so an ordinary full-page callback is completely
20
+ * unaffected (it still establishes the session inline as before).
21
+ * - The opener tears down its listener + timers on result, on user-close, and on
22
+ * a hard timeout, so no stale handler lingers.
23
+ *
24
+ * @module
25
+ */
26
+ import { useCallback, useEffect, useMemo, useRef } from 'react';
27
+ import { useAuthClient } from './useAuth.js';
28
+ /**
29
+ * `window.open` name for the OAuth popup. The callback page relays its result to
30
+ * the opener ONLY when its own `window.name` equals this AND `window.opener`
31
+ * exists — so a normal (full-page) callback never takes the relay path.
32
+ */
33
+ const OAUTH_POPUP_WINDOW_NAME = 'molecule-oauth-popup';
34
+ /** Private `postMessage` type for the popup→opener result relay. */
35
+ const OAUTH_RESULT_MESSAGE_TYPE = 'molecule:oauth-result';
36
+ /** Hard cap on how long the opener waits for the popup before giving up. */
37
+ const OAUTH_POPUP_TIMEOUT_MS = 5 * 60 * 1000;
38
+ /**
39
+ * Hook for OAuth authentication.
40
+ *
41
+ * Reads OAuth configuration from the provided config and provides
42
+ * helpers to build OAuth URLs and start a login (full-page or popup).
43
+ * Automatically handles OAuth callbacks by detecting `code` and `state`
44
+ * URL parameters and exchanging them for a session — and, when the callback is
45
+ * running inside a popup we opened, relaying the result to the opener instead.
46
+ *
47
+ * @param config - Optional OAuth configuration override.
48
+ * @param config.baseURL - Base URL for the API server (e.g. "https://api.example.com").
49
+ * @param config.oauthProviders - List of supported OAuth provider names (e.g. ["google", "github"]).
50
+ * @param config.oauthEndpoint - Path prefix for OAuth routes (defaults to "/oauth").
51
+ * @param config.loginEndpoint - Path for the OAuth login POST endpoint (defaults to "/users/log-in/oauth").
52
+ * @param config.onSuccess - Callback after successful OAuth login.
53
+ * @param config.onError - Callback on OAuth login failure.
54
+ *
55
+ * @example
56
+ * ```tsx
57
+ * const { providers, redirect, loginViaPopup } = useOAuth()
58
+ *
59
+ * return (
60
+ * <div>
61
+ * {providers.map(provider => (
62
+ * <button key={provider} onClick={() => loginViaPopup(provider)}>
63
+ * Login with {provider}
64
+ * </button>
65
+ * ))}
66
+ * </div>
67
+ * )
68
+ * ```
69
+ * @returns OAuth helpers: providers, getOAuthUrl, redirect, and loginViaPopup.
70
+ */
71
+ export function useOAuth(config) {
72
+ const authClient = useAuthClient();
73
+ const providers = useMemo(() => config?.oauthProviders ?? [], [config?.oauthProviders]);
74
+ const baseURL = config?.baseURL ?? '';
75
+ const oauthEndpoint = config?.oauthEndpoint ?? '/oauth';
76
+ const loginEndpoint = config?.loginEndpoint ?? '/users/log-in/oauth';
77
+ const getOAuthUrl = useCallback((provider) => {
78
+ // Encode the provider as a single path segment so a (future) caller passing an
79
+ // untrusted value can never inject a path/query/scheme into the opened URL —
80
+ // defense-in-depth on top of the upstream static provider allowlist. Plain
81
+ // provider names ('github', 'google') pass through unchanged.
82
+ return `${baseURL}${oauthEndpoint}/${encodeURIComponent(provider)}`;
83
+ }, [baseURL, oauthEndpoint]);
84
+ /** Stash which provider initiated the flow so the callback knows it's ours. */
85
+ const stashProvider = (provider) => {
86
+ try {
87
+ sessionStorage.setItem('oauth_provider', provider);
88
+ }
89
+ catch (_error) {
90
+ /* SSR-safe — sessionStorage is unavailable in SSR/sandboxed environments */
91
+ }
92
+ };
93
+ /**
94
+ * Append the current page's PATH as `redirect_to` so the api's initiation
95
+ * endpoint (`GET /users/oauth/:provider`) builds a provider `redirect_uri`
96
+ * that lands the callback back on THIS page — the one with `useOAuth`
97
+ * mounted (e.g. `/login`) — instead of the app root, where nothing may be
98
+ * listening for the `code` param. Path only (no origin/query): the server
99
+ * validates it as a same-origin absolute path, so it can never become an
100
+ * open redirect. Servers that predate the param simply ignore it.
101
+ */
102
+ const withReturnPath = (url) => {
103
+ const path = typeof window !== 'undefined' ? window.location.pathname : '';
104
+ if (!path || path === '/')
105
+ return url;
106
+ return `${url}${url.includes('?') ? '&' : '?'}redirect_to=${encodeURIComponent(path)}`;
107
+ };
108
+ /**
109
+ * Establish the authenticated session from an exchange result: seed the access
110
+ * token + user and let `initialize()` flip `authenticated`. Mirrors what
111
+ * `authClient.login()` does for password login. Returns whether a user was set
112
+ * (a result with no user is not a real session).
113
+ */
114
+ const establishSession = useCallback(async (token, user) => {
115
+ // Seed the token via the auth client's configured token storage adapter
116
+ // (in-memory by default) — NOT localStorage directly. Writing the bearer
117
+ // token to localStorage violates the in-memory-default storage contract and
118
+ // makes it JS-readable (XSS-exfiltratable). [P5FE-31 secure-by-default]
119
+ if (token)
120
+ authClient.setAccessToken(token);
121
+ if (user && typeof user === 'object') {
122
+ authClient.setUser(user);
123
+ await authClient.initialize();
124
+ return true;
125
+ }
126
+ return false;
127
+ }, [authClient]);
128
+ const redirect = useCallback((provider) => {
129
+ stashProvider(provider);
130
+ window.location.href = withReturnPath(getOAuthUrl(provider));
131
+ }, [getOAuthUrl]);
132
+ // The currently-open OAuth popup, so a second click focuses it instead of
133
+ // stacking a second flow (the relay gates already fail safe, but one window is
134
+ // cleaner and avoids an orphaned listener until the timeout reaps it).
135
+ const activePopupRef = useRef(null);
136
+ const loginViaPopup = useCallback((provider) => {
137
+ // A flow is already open — focus it rather than starting another.
138
+ if (activePopupRef.current && !activePopupRef.current.closed) {
139
+ try {
140
+ activePopupRef.current.focus();
141
+ }
142
+ catch (_error) {
143
+ /* best-effort focus */
144
+ }
145
+ return;
146
+ }
147
+ stashProvider(provider);
148
+ const url = withReturnPath(getOAuthUrl(provider));
149
+ // A named popup. We intentionally do NOT pass `noopener` — the popup needs
150
+ // `window.opener` to relay its result back. The window only ever navigates
151
+ // to OUR api → the trusted provider → OUR origin, so this is the standard
152
+ // OAuth-popup trade-off (a malicious *provider* could touch `window.opener`,
153
+ // which is out of scope; we don't open attacker-controlled URLs here).
154
+ const features = 'popup=yes,width=520,height=680,menubar=no,toolbar=no,location=yes';
155
+ const popup = window.open(url, OAUTH_POPUP_WINDOW_NAME, features);
156
+ // Popup blocked (or unavailable) → fall back to a full-page redirect so login
157
+ // still works. No listener is registered in this branch.
158
+ if (!popup) {
159
+ window.location.href = url;
160
+ return;
161
+ }
162
+ activePopupRef.current = popup;
163
+ let settled = false;
164
+ const timers = {};
165
+ const cleanup = () => {
166
+ window.removeEventListener('message', onMessage);
167
+ if (timers.closed)
168
+ clearInterval(timers.closed);
169
+ if (timers.timeout)
170
+ clearTimeout(timers.timeout);
171
+ if (activePopupRef.current === popup)
172
+ activePopupRef.current = null;
173
+ };
174
+ const onMessage = (event) => {
175
+ // SECURITY — accept the result ONLY from our own origin, ONLY from the exact
176
+ // popup window we opened, and ONLY when it carries our private type. Any one
177
+ // failing means a forged / unrelated message: ignore it silently. This is
178
+ // what prevents a malicious page from injecting a session.
179
+ if (event.origin !== window.location.origin)
180
+ return;
181
+ if (event.source !== popup)
182
+ return;
183
+ const data = event.data;
184
+ if (!data || typeof data !== 'object' || data.type !== OAUTH_RESULT_MESSAGE_TYPE)
185
+ return;
186
+ if (settled)
187
+ return;
188
+ settled = true;
189
+ cleanup();
190
+ try {
191
+ popup.close();
192
+ }
193
+ catch (_error) {
194
+ /* already closed — nothing to do */
195
+ }
196
+ if (data.ok) {
197
+ void establishSession(data.token, data.user).then((ok) => {
198
+ if (ok)
199
+ config?.onSuccess?.();
200
+ else
201
+ config?.onError?.('OAuth login failed');
202
+ });
203
+ }
204
+ else {
205
+ config?.onError?.(typeof data.error === 'string' ? data.error : 'OAuth login failed');
206
+ }
207
+ };
208
+ window.addEventListener('message', onMessage);
209
+ // The user closed the popup without completing — silently stop waiting (no
210
+ // error toast for a deliberate cancel) and release the listener.
211
+ timers.closed = setInterval(() => {
212
+ if (popup.closed && !settled) {
213
+ settled = true;
214
+ cleanup();
215
+ }
216
+ }, 500);
217
+ // Hard safety timeout so a wedged popup never leaks a listener forever.
218
+ timers.timeout = setTimeout(() => {
219
+ if (!settled) {
220
+ settled = true;
221
+ cleanup();
222
+ try {
223
+ popup.close();
224
+ }
225
+ catch (_error) {
226
+ /* best-effort */
227
+ }
228
+ }
229
+ }, OAUTH_POPUP_TIMEOUT_MS);
230
+ }, [getOAuthUrl, establishSession, config]);
231
+ // Handle OAuth callback — detect code + state in URL params
232
+ useEffect(() => {
233
+ const params = new URLSearchParams(window.location.search);
234
+ const code = params.get('code');
235
+ const state = params.get('state');
236
+ if (!code)
237
+ return;
238
+ // Retrieve the provider that initiated the flow
239
+ let provider = null;
240
+ try {
241
+ provider = sessionStorage.getItem('oauth_provider');
242
+ }
243
+ catch (_error) {
244
+ /* SSR-safe — sessionStorage is unavailable in SSR/sandboxed environments */
245
+ }
246
+ if (!provider)
247
+ return;
248
+ // Are we the OAuth popup we opened? Relay the result to the opener instead of
249
+ // establishing the session in this (about-to-close) window. Gated on BOTH the
250
+ // window name AND window.opener so a normal full-page callback never relays.
251
+ const inPopup = typeof window !== 'undefined' && !!window.opener && window.name === OAUTH_POPUP_WINDOW_NAME;
252
+ // Clean up URL (remove code/state params) and sessionStorage
253
+ const cleanUrl = new URL(window.location.href);
254
+ cleanUrl.searchParams.delete('code');
255
+ cleanUrl.searchParams.delete('state');
256
+ window.history.replaceState({}, '', cleanUrl.toString());
257
+ try {
258
+ sessionStorage.removeItem('oauth_provider');
259
+ }
260
+ catch (_error) {
261
+ /* SSR-safe — sessionStorage is unavailable in SSR/sandboxed environments */
262
+ }
263
+ /** Relay a result to the opener (popup path) — origin-pinned, never `'*'`. */
264
+ const relayToOpener = (message) => {
265
+ try {
266
+ // targetOrigin is our OWN origin: the browser delivers the message (and the
267
+ // token it carries) ONLY if the opener is still on this origin. Never '*'.
268
+ window.opener?.postMessage(message, window.location.origin);
269
+ }
270
+ catch (_error) {
271
+ /* opener gone / cross-origin — the opener's close-poll will recover */
272
+ }
273
+ try {
274
+ window.close();
275
+ }
276
+ catch (_error) {
277
+ /* best-effort */
278
+ }
279
+ };
280
+ // Exchange code for session
281
+ const exchangeCode = async () => {
282
+ try {
283
+ const response = await fetch(`${baseURL}${loginEndpoint}`, {
284
+ method: 'POST',
285
+ headers: { 'Content-Type': 'application/json' },
286
+ credentials: 'include', // Send cookies (oauth_state) for state validation
287
+ body: JSON.stringify({
288
+ server: provider,
289
+ code,
290
+ state: state || undefined,
291
+ redirect_uri: window.location.origin,
292
+ }),
293
+ });
294
+ if (!response.ok) {
295
+ const data = await response.json().catch(() => ({ error: 'OAuth login failed' }));
296
+ const error = data.error || 'OAuth login failed';
297
+ if (inPopup) {
298
+ relayToOpener({ type: OAUTH_RESULT_MESSAGE_TYPE, ok: false, error });
299
+ return;
300
+ }
301
+ config?.onError?.(error);
302
+ return;
303
+ }
304
+ const data = await response.json().catch(() => null);
305
+ // Store the token from the response
306
+ const authHeader = response.headers.get('authorization') || response.headers.get('set-authorization');
307
+ const token = authHeader ? authHeader.replace('Bearer ', '') : null;
308
+ // The authenticated user is `props` (molecule resource convention) or `user`
309
+ // (generic AuthResult). OAuth issues no refresh token, so we carry the token +
310
+ // user to whoever will own the session.
311
+ const user = data && typeof data === 'object'
312
+ ? (data.props ??
313
+ data.user ??
314
+ null)
315
+ : null;
316
+ if (inPopup) {
317
+ // Relay to the opener — it (same origin) establishes the session in place.
318
+ // Do NOT establish it here; this window is about to close.
319
+ relayToOpener({ type: OAUTH_RESULT_MESSAGE_TYPE, ok: true, token, user });
320
+ return;
321
+ }
322
+ // Full-page callback: establish the session here, then fire onSuccess —
323
+ // unchanged behavior.
324
+ const ok = await establishSession(token, user);
325
+ if (ok)
326
+ config?.onSuccess?.();
327
+ else
328
+ config?.onError?.('OAuth login failed');
329
+ }
330
+ catch (err) {
331
+ const error = err instanceof Error ? err.message : 'OAuth login failed';
332
+ if (inPopup) {
333
+ relayToOpener({ type: OAUTH_RESULT_MESSAGE_TYPE, ok: false, error });
334
+ return;
335
+ }
336
+ config?.onError?.(error);
337
+ }
338
+ };
339
+ exchangeCode();
340
+ }, [baseURL, loginEndpoint, config, establishSession]);
341
+ return {
342
+ providers,
343
+ getOAuthUrl,
344
+ redirect,
345
+ loginViaPopup,
346
+ };
347
+ }
348
+ //# sourceMappingURL=useOAuth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOAuth.js","sourceRoot":"","sources":["../../src/hooks/useOAuth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * React hook for password reset with async state tracking.
3
+ *
4
+ * @module
5
+ */
6
+ import type { PasswordResetConfirm, PasswordResetRequest } from '@molecule/app-auth';
7
+ import { type UsePromiseState } from './usePromise.js';
8
+ /**
9
+ * Return type for usePasswordReset hook.
10
+ */
11
+ export interface UsePasswordResetReturn {
12
+ requestStatus: UsePromiseState<void>['status'];
13
+ requestError: UsePromiseState<void>['error'];
14
+ confirmStatus: UsePromiseState<void>['status'];
15
+ confirmError: UsePromiseState<void>['error'];
16
+ requestReset: (data: PasswordResetRequest) => Promise<void>;
17
+ confirmReset: (data: PasswordResetConfirm) => Promise<void>;
18
+ reset: () => void;
19
+ }
20
+ /**
21
+ * Hook for password reset flow with async state tracking.
22
+ *
23
+ * Provides separate tracking for the request and confirm steps.
24
+ *
25
+ * @returns Password reset state and actions
26
+ *
27
+ * @example
28
+ * ```tsx
29
+ * const { requestStatus, requestError, requestReset, confirmReset } = usePasswordReset()
30
+ *
31
+ * // Step 1: Request reset
32
+ * <button onClick={() => requestReset({ email })} disabled={requestStatus === 'pending'}>
33
+ * Send Reset Email
34
+ * </button>
35
+ *
36
+ * // Step 2: Confirm reset
37
+ * <button onClick={() => confirmReset({ token, password })}>
38
+ * Set New Password
39
+ * </button>
40
+ * ```
41
+ */
42
+ export declare function usePasswordReset(): UsePasswordResetReturn;
43
+ //# sourceMappingURL=usePasswordReset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePasswordReset.d.ts","sourceRoot":"","sources":["../../src/hooks/usePasswordReset.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAGpF,OAAO,EAAc,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAElE;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAA;IAC9C,YAAY,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAA;IAC5C,aAAa,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAA;IAC9C,YAAY,EAAE,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAA;IAC5C,YAAY,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3D,YAAY,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3D,KAAK,EAAE,MAAM,IAAI,CAAA;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,IAAI,sBAAsB,CA4BzD"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * React hook for password reset with async state tracking.
3
+ *
4
+ * @module
5
+ */
6
+ import { useCallback } from 'react';
7
+ import { useAuthClient } from './useAuth.js';
8
+ import { usePromise } from './usePromise.js';
9
+ /**
10
+ * Hook for password reset flow with async state tracking.
11
+ *
12
+ * Provides separate tracking for the request and confirm steps.
13
+ *
14
+ * @returns Password reset state and actions
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * const { requestStatus, requestError, requestReset, confirmReset } = usePasswordReset()
19
+ *
20
+ * // Step 1: Request reset
21
+ * <button onClick={() => requestReset({ email })} disabled={requestStatus === 'pending'}>
22
+ * Send Reset Email
23
+ * </button>
24
+ *
25
+ * // Step 2: Confirm reset
26
+ * <button onClick={() => confirmReset({ token, password })}>
27
+ * Set New Password
28
+ * </button>
29
+ * ```
30
+ */
31
+ export function usePasswordReset() {
32
+ const client = useAuthClient();
33
+ const requestFn = useCallback((data) => client.requestPasswordReset(data), [client]);
34
+ const confirmFn = useCallback((data) => client.confirmPasswordReset(data), [client]);
35
+ const [requestState, requestCall] = usePromise(requestFn);
36
+ const [confirmState, confirmCall] = usePromise(confirmFn);
37
+ return {
38
+ requestStatus: requestState.status,
39
+ requestError: requestState.error,
40
+ confirmStatus: confirmState.status,
41
+ confirmError: confirmState.error,
42
+ requestReset: requestCall,
43
+ confirmReset: confirmCall,
44
+ reset: () => {
45
+ requestState.reset();
46
+ confirmState.reset();
47
+ },
48
+ };
49
+ }
50
+ //# sourceMappingURL=usePasswordReset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePasswordReset.js","sourceRoot":"","sources":["../../src/hooks/usePasswordReset.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AAInC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,UAAU,EAAwB,MAAM,iBAAiB,CAAA;AAelE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAAG,aAAa,EAAE,CAAA;IAE9B,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,IAA0B,EAAE,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,EACjE,CAAC,MAAM,CAAC,CACT,CAAA;IAED,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,IAA0B,EAAE,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,IAAI,CAAC,EACjE,CAAC,MAAM,CAAC,CACT,CAAA;IAED,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,CAAA;IACzD,MAAM,CAAC,YAAY,EAAE,WAAW,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,CAAA;IAEzD,OAAO;QACL,aAAa,EAAE,YAAY,CAAC,MAAM;QAClC,YAAY,EAAE,YAAY,CAAC,KAAK;QAChC,aAAa,EAAE,YAAY,CAAC,MAAM;QAClC,YAAY,EAAE,YAAY,CAAC,KAAK;QAChC,YAAY,EAAE,WAAW;QACzB,YAAY,EAAE,WAAW;QACzB,KAAK,EAAE,GAAG,EAAE;YACV,YAAY,CAAC,KAAK,EAAE,CAAA;YACpB,YAAY,CAAC,KAAK,EAAE,CAAA;QACtB,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * React hook for platform detection.
3
+ *
4
+ * @module
5
+ */
6
+ import type { Platform } from '@molecule/app-platform';
7
+ /**
8
+ * Hook return type.
9
+ */
10
+ export interface UsePlatformResult {
11
+ platform: Platform;
12
+ isNative: boolean;
13
+ isMobile: boolean;
14
+ isDesktop: boolean;
15
+ isWeb: boolean;
16
+ isDevelopment: boolean;
17
+ isProduction: boolean;
18
+ isPlatform: (...platforms: Platform[]) => boolean;
19
+ }
20
+ /**
21
+ * Hook for platform detection.
22
+ *
23
+ * Uses module-level functions — platform is a singleton, not context-provided.
24
+ * Platform info is static and doesn't change at runtime, so this uses `useMemo`.
25
+ *
26
+ * @returns Platform information and utility methods
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * const { isWeb, isMobile, isPlatform } = usePlatform()
31
+ *
32
+ * if (isPlatform('ios', 'android')) {
33
+ * return <NativeLayout />
34
+ * }
35
+ * ```
36
+ */
37
+ export declare function usePlatform(): UsePlatformResult;
38
+ //# sourceMappingURL=usePlatform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePlatform.d.ts","sourceRoot":"","sources":["../../src/hooks/usePlatform.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,wBAAwB,CAAA;AAGpE;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,SAAS,EAAE,OAAO,CAAA;IAClB,KAAK,EAAE,OAAO,CAAA;IACd,aAAa,EAAE,OAAO,CAAA;IACtB,YAAY,EAAE,OAAO,CAAA;IACrB,UAAU,EAAE,CAAC,GAAG,SAAS,EAAE,QAAQ,EAAE,KAAK,OAAO,CAAA;CAClD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,IAAI,iBAAiB,CAe/C"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * React hook for platform detection.
3
+ *
4
+ * @module
5
+ */
6
+ import { useMemo } from 'react';
7
+ import { isPlatform, platform } from '@molecule/app-platform';
8
+ /**
9
+ * Hook for platform detection.
10
+ *
11
+ * Uses module-level functions — platform is a singleton, not context-provided.
12
+ * Platform info is static and doesn't change at runtime, so this uses `useMemo`.
13
+ *
14
+ * @returns Platform information and utility methods
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * const { isWeb, isMobile, isPlatform } = usePlatform()
19
+ *
20
+ * if (isPlatform('ios', 'android')) {
21
+ * return <NativeLayout />
22
+ * }
23
+ * ```
24
+ */
25
+ export function usePlatform() {
26
+ return useMemo(() => {
27
+ const info = platform();
28
+ return {
29
+ platform: info.platform,
30
+ isNative: info.isNative,
31
+ isMobile: info.isMobile,
32
+ isDesktop: info.isDesktop,
33
+ isWeb: info.isWeb,
34
+ isDevelopment: info.isDevelopment,
35
+ isProduction: info.isProduction,
36
+ isPlatform: (...platforms) => isPlatform(...platforms),
37
+ };
38
+ }, []);
39
+ }
40
+ //# sourceMappingURL=usePlatform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePlatform.js","sourceRoot":"","sources":["../../src/hooks/usePlatform.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAG/B,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AAgB7D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,IAAI,GAAiB,QAAQ,EAAE,CAAA;QAErC,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,UAAU,EAAE,CAAC,GAAG,SAAqB,EAAE,EAAE,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;SACnE,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;AACR,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * React hook for live preview provider.
3
+ *
4
+ * @module
5
+ */
6
+ import type { PreviewProvider } from '@molecule/app-live-preview';
7
+ import type { UsePreviewResult } from '../types.js';
8
+ /**
9
+ * Access the preview provider from context.
10
+ * @returns The PreviewProvider instance from the nearest PreviewContext.
11
+ * @throws {Error} If called outside a PreviewProvider.
12
+ */
13
+ export declare function usePreviewProvider(): PreviewProvider;
14
+ /**
15
+ * Hook for live preview management.
16
+ *
17
+ * @returns Preview state and controls: state (url, isLoading, device, error, isConnected), setUrl, refresh, setDevice, and openExternal.
18
+ */
19
+ export declare function usePreview(): UsePreviewResult;
20
+ //# sourceMappingURL=usePreview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePreview.d.ts","sourceRoot":"","sources":["../../src/hooks/usePreview.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAe,eAAe,EAAgB,MAAM,4BAA4B,CAAA;AAG5F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAEnD;;;;GAIG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CAUpD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,gBAAgB,CA8C7C"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * React hook for live preview provider.
3
+ *
4
+ * @module
5
+ */
6
+ import { useCallback, useContext, useRef, useSyncExternalStore } from 'react';
7
+ import { t } from '@molecule/app-i18n';
8
+ import { PreviewContext } from '../contexts.js';
9
+ /**
10
+ * Access the preview provider from context.
11
+ * @returns The PreviewProvider instance from the nearest PreviewContext.
12
+ * @throws {Error} If called outside a PreviewProvider.
13
+ */
14
+ export function usePreviewProvider() {
15
+ const provider = useContext(PreviewContext);
16
+ if (!provider) {
17
+ throw new Error(t('react.error.usePreviewOutsideProvider', undefined, {
18
+ defaultValue: 'usePreviewProvider must be used within a PreviewProvider',
19
+ }));
20
+ }
21
+ return provider;
22
+ }
23
+ /**
24
+ * Hook for live preview management.
25
+ *
26
+ * @returns Preview state and controls: state (url, isLoading, device, error, isConnected), setUrl, refresh, setDevice, and openExternal.
27
+ */
28
+ export function usePreview() {
29
+ const provider = usePreviewProvider();
30
+ const cachedRef = useRef(null);
31
+ const getSnapshot = useCallback(() => {
32
+ const next = provider.getState();
33
+ const prev = cachedRef.current;
34
+ if (prev &&
35
+ prev.url === next.url &&
36
+ prev.currentUrl === next.currentUrl &&
37
+ prev.isLoading === next.isLoading &&
38
+ prev.device === next.device &&
39
+ prev.error === next.error &&
40
+ prev.isConnected === next.isConnected &&
41
+ prev.canGoBack === next.canGoBack &&
42
+ prev.canGoForward === next.canGoForward &&
43
+ prev.loadNonce === next.loadNonce) {
44
+ return prev;
45
+ }
46
+ cachedRef.current = next;
47
+ return next;
48
+ }, [provider]);
49
+ const subscribe = useCallback((onStoreChange) => {
50
+ return provider.subscribe(() => onStoreChange());
51
+ }, [provider]);
52
+ const state = useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
53
+ const setUrl = useCallback((url) => provider.setUrl(url), [provider]);
54
+ const refresh = useCallback(() => provider.refresh(), [provider]);
55
+ const setDevice = useCallback((device) => provider.setDevice(device), [provider]);
56
+ const openExternal = useCallback(() => provider.openExternal(), [provider]);
57
+ const recordNavigation = useCallback((url, isReplace) => provider.recordNavigation(url, isReplace), [provider]);
58
+ const back = useCallback(() => provider.back(), [provider]);
59
+ const forward = useCallback(() => provider.forward(), [provider]);
60
+ return { state, setUrl, refresh, setDevice, openExternal, recordNavigation, back, forward };
61
+ }
62
+ //# sourceMappingURL=usePreview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePreview.js","sourceRoot":"","sources":["../../src/hooks/usePreview.ts"],"names":[],"mappings":"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"}