@atproto/oauth-provider-ui 0.0.2 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. package/dist/authorization-page-Cms-rcBA.js +3 -0
  2. package/dist/authorization-page-Cms-rcBA.js.map +1 -0
  3. package/dist/{assets/bundle-manifest.json → bundle-manifest.json} +197 -197
  4. package/dist/error-page-DC6Vc-cv.js +2 -0
  5. package/dist/error-page-DC6Vc-cv.js.map +1 -0
  6. package/dist/error-view-CRGNTAn2.css +1 -0
  7. package/dist/error-view-MVy7C9l0.js +59 -0
  8. package/dist/error-view-MVy7C9l0.js.map +1 -0
  9. package/dist/index-CHPoD7Rp.js +20 -0
  10. package/dist/index-CHPoD7Rp.js.map +1 -0
  11. package/dist/messages-B0mgsxS-.js +2 -0
  12. package/dist/messages-B0mgsxS-.js.map +1 -0
  13. package/dist/messages-B5g8Fkio.js +2 -0
  14. package/dist/messages-B5g8Fkio.js.map +1 -0
  15. package/dist/messages-BCMss-Kt.js +2 -0
  16. package/dist/messages-BCMss-Kt.js.map +1 -0
  17. package/dist/messages-BGUrKgyK.js +2 -0
  18. package/dist/messages-BGUrKgyK.js.map +1 -0
  19. package/dist/messages-BjxAnLDp.js +2 -0
  20. package/dist/messages-BjxAnLDp.js.map +1 -0
  21. package/dist/messages-Bjysz3rI.js +2 -0
  22. package/dist/messages-Bjysz3rI.js.map +1 -0
  23. package/dist/messages-BvvEr3UX.js +2 -0
  24. package/dist/messages-BvvEr3UX.js.map +1 -0
  25. package/dist/messages-Bz6JOhJf.js +2 -0
  26. package/dist/messages-Bz6JOhJf.js.map +1 -0
  27. package/dist/messages-BzL3D1EU.js +2 -0
  28. package/dist/messages-BzL3D1EU.js.map +1 -0
  29. package/dist/messages-CAvN5UoW.js +2 -0
  30. package/dist/messages-CAvN5UoW.js.map +1 -0
  31. package/dist/messages-CEmswT1Q.js +2 -0
  32. package/dist/messages-CEmswT1Q.js.map +1 -0
  33. package/dist/messages-CHYqz0q6.js +2 -0
  34. package/dist/messages-CHYqz0q6.js.map +1 -0
  35. package/dist/messages-CRmpdijj.js +2 -0
  36. package/dist/messages-CRmpdijj.js.map +1 -0
  37. package/dist/messages-Cdb79R6S.js +2 -0
  38. package/dist/messages-Cdb79R6S.js.map +1 -0
  39. package/dist/messages-ChkJ_0WT.js +2 -0
  40. package/dist/messages-ChkJ_0WT.js.map +1 -0
  41. package/dist/messages-CqiEX6JJ.js +2 -0
  42. package/dist/messages-CqiEX6JJ.js.map +1 -0
  43. package/dist/messages-CxkHjJSR.js +2 -0
  44. package/dist/messages-CxkHjJSR.js.map +1 -0
  45. package/dist/messages-D0-cWoJ9.js +2 -0
  46. package/dist/messages-D0-cWoJ9.js.map +1 -0
  47. package/dist/messages-D2MnAxYY.js +2 -0
  48. package/dist/messages-D2MnAxYY.js.map +1 -0
  49. package/dist/messages-D5TZVsui.js +2 -0
  50. package/dist/messages-D5TZVsui.js.map +1 -0
  51. package/dist/messages-DBdV4-iw.js +2 -0
  52. package/dist/messages-DBdV4-iw.js.map +1 -0
  53. package/dist/messages-DEK3zybC.js +2 -0
  54. package/dist/messages-DEK3zybC.js.map +1 -0
  55. package/dist/messages-DGSM5jkd.js +2 -0
  56. package/dist/messages-DGSM5jkd.js.map +1 -0
  57. package/dist/messages-DJgAnSTQ.js +2 -0
  58. package/dist/messages-DJgAnSTQ.js.map +1 -0
  59. package/dist/messages-DK7O7sb_.js +2 -0
  60. package/dist/messages-DK7O7sb_.js.map +1 -0
  61. package/dist/messages-DRp7qc3j.js +2 -0
  62. package/dist/messages-DRp7qc3j.js.map +1 -0
  63. package/dist/messages-DT6xRw0m.js +2 -0
  64. package/dist/messages-DT6xRw0m.js.map +1 -0
  65. package/dist/messages-LnzLtU0L.js +2 -0
  66. package/dist/messages-LnzLtU0L.js.map +1 -0
  67. package/dist/messages-_Nk2qNGw.js +2 -0
  68. package/dist/messages-_Nk2qNGw.js.map +1 -0
  69. package/dist/messages-eHH6nZyF.js +2 -0
  70. package/dist/messages-eHH6nZyF.js.map +1 -0
  71. package/dist/messages-iNw8zY2C.js +2 -0
  72. package/dist/messages-iNw8zY2C.js.map +1 -0
  73. package/dist/messages-ipc0L8yF.js +2 -0
  74. package/dist/messages-ipc0L8yF.js.map +1 -0
  75. package/dist/messages-j7LsWm2F.js +2 -0
  76. package/dist/messages-j7LsWm2F.js.map +1 -0
  77. package/dist/messages-mgE_5UEw.js +2 -0
  78. package/dist/messages-mgE_5UEw.js.map +1 -0
  79. package/dist/messages-oRd-J5--.js +2 -0
  80. package/dist/messages-oRd-J5--.js.map +1 -0
  81. package/hydration-data.d.ts +42 -0
  82. package/package.json +30 -37
  83. package/.linguirc +0 -57
  84. package/CHANGELOG.md +0 -7
  85. package/CONTRIBUTING.md +0 -6
  86. package/dist/assets/COdVzed-.css +0 -3
  87. package/dist/assets/COdVzed-.js +0 -100
  88. package/dist/assets/COdVzed-.js.map +0 -1
  89. package/dist/assets/Cqnfnbvc.js +0 -6
  90. package/dist/assets/Cqnfnbvc.js.map +0 -1
  91. package/dist/assets/error-view-Bu4y7Nd8.js +0 -208
  92. package/dist/assets/error-view-Bu4y7Nd8.js.map +0 -1
  93. package/dist/assets/index-DXlCRM6V.js +0 -36
  94. package/dist/assets/index-DXlCRM6V.js.map +0 -1
  95. package/dist/assets/messages-2GoTm2qL.js +0 -4
  96. package/dist/assets/messages-2GoTm2qL.js.map +0 -1
  97. package/dist/assets/messages-6Cn2Jbhw.js +0 -4
  98. package/dist/assets/messages-6Cn2Jbhw.js.map +0 -1
  99. package/dist/assets/messages-75hFgOK2.js +0 -4
  100. package/dist/assets/messages-75hFgOK2.js.map +0 -1
  101. package/dist/assets/messages-B3OK4k0O.js +0 -4
  102. package/dist/assets/messages-B3OK4k0O.js.map +0 -1
  103. package/dist/assets/messages-BNXlPzKV.js +0 -4
  104. package/dist/assets/messages-BNXlPzKV.js.map +0 -1
  105. package/dist/assets/messages-BUygB8mD.js +0 -4
  106. package/dist/assets/messages-BUygB8mD.js.map +0 -1
  107. package/dist/assets/messages-BVPPcwNr.js +0 -4
  108. package/dist/assets/messages-BVPPcwNr.js.map +0 -1
  109. package/dist/assets/messages-BbbWUQS8.js +0 -4
  110. package/dist/assets/messages-BbbWUQS8.js.map +0 -1
  111. package/dist/assets/messages-BibKCYyW.js +0 -4
  112. package/dist/assets/messages-BibKCYyW.js.map +0 -1
  113. package/dist/assets/messages-BlPrr9_7.js +0 -4
  114. package/dist/assets/messages-BlPrr9_7.js.map +0 -1
  115. package/dist/assets/messages-ByVCw40U.js +0 -4
  116. package/dist/assets/messages-ByVCw40U.js.map +0 -1
  117. package/dist/assets/messages-C5DU1neP.js +0 -4
  118. package/dist/assets/messages-C5DU1neP.js.map +0 -1
  119. package/dist/assets/messages-C6IgUtbX.js +0 -4
  120. package/dist/assets/messages-C6IgUtbX.js.map +0 -1
  121. package/dist/assets/messages-C92Zzt2o.js +0 -4
  122. package/dist/assets/messages-C92Zzt2o.js.map +0 -1
  123. package/dist/assets/messages-CGZqYT14.js +0 -4
  124. package/dist/assets/messages-CGZqYT14.js.map +0 -1
  125. package/dist/assets/messages-CGlsy4wt.js +0 -4
  126. package/dist/assets/messages-CGlsy4wt.js.map +0 -1
  127. package/dist/assets/messages-CPT1nd0u.js +0 -4
  128. package/dist/assets/messages-CPT1nd0u.js.map +0 -1
  129. package/dist/assets/messages-CTTdXyw_.js +0 -4
  130. package/dist/assets/messages-CTTdXyw_.js.map +0 -1
  131. package/dist/assets/messages-ChK_C_Pj.js +0 -4
  132. package/dist/assets/messages-ChK_C_Pj.js.map +0 -1
  133. package/dist/assets/messages-CjJbk7Uf.js +0 -4
  134. package/dist/assets/messages-CjJbk7Uf.js.map +0 -1
  135. package/dist/assets/messages-CoiLjLYO.js +0 -4
  136. package/dist/assets/messages-CoiLjLYO.js.map +0 -1
  137. package/dist/assets/messages-Cwx6B4Ti.js +0 -4
  138. package/dist/assets/messages-Cwx6B4Ti.js.map +0 -1
  139. package/dist/assets/messages-D0uXAp_H.js +0 -4
  140. package/dist/assets/messages-D0uXAp_H.js.map +0 -1
  141. package/dist/assets/messages-DG0_arU0.js +0 -4
  142. package/dist/assets/messages-DG0_arU0.js.map +0 -1
  143. package/dist/assets/messages-DOXFJh9K.js +0 -4
  144. package/dist/assets/messages-DOXFJh9K.js.map +0 -1
  145. package/dist/assets/messages-DPK7nOoC.js +0 -4
  146. package/dist/assets/messages-DPK7nOoC.js.map +0 -1
  147. package/dist/assets/messages-Duccgtu0.js +0 -4
  148. package/dist/assets/messages-Duccgtu0.js.map +0 -1
  149. package/dist/assets/messages-DxTqgsHq.js +0 -4
  150. package/dist/assets/messages-DxTqgsHq.js.map +0 -1
  151. package/dist/assets/messages-E5_lTg7A.js +0 -4
  152. package/dist/assets/messages-E5_lTg7A.js.map +0 -1
  153. package/dist/assets/messages-UhunAjh1.js +0 -4
  154. package/dist/assets/messages-UhunAjh1.js.map +0 -1
  155. package/dist/assets/messages-Xg_3YLGw.js +0 -4
  156. package/dist/assets/messages-Xg_3YLGw.js.map +0 -1
  157. package/dist/assets/messages-iliBQHY2.js +0 -4
  158. package/dist/assets/messages-iliBQHY2.js.map +0 -1
  159. package/dist/assets/messages-lRprpIl-.js +0 -4
  160. package/dist/assets/messages-lRprpIl-.js.map +0 -1
  161. package/dist/assets/messages-pbPHQbz1.js +0 -4
  162. package/dist/assets/messages-pbPHQbz1.js.map +0 -1
  163. package/dist/assets/messages-q-O7ZQGs.js +0 -4
  164. package/dist/assets/messages-q-O7ZQGs.js.map +0 -1
  165. package/dist/lib/index.d.ts +0 -19
  166. package/dist/lib/index.d.ts.map +0 -1
  167. package/dist/lib/index.js +0 -47
  168. package/dist/lib/index.js.map +0 -1
  169. package/dist/tsconfig.backend.tsbuildinfo +0 -1
  170. package/lib/index.ts +0 -72
  171. package/rollup.config.js +0 -102
  172. package/src/authorization-page.html +0 -183
  173. package/src/authorization-page.tsx +0 -55
  174. package/src/backend-data.ts +0 -35
  175. package/src/components/forms/button-toggle-visibility.tsx +0 -43
  176. package/src/components/forms/button.tsx +0 -60
  177. package/src/components/forms/fieldset.tsx +0 -55
  178. package/src/components/forms/form-card-async.tsx +0 -103
  179. package/src/components/forms/form-card.tsx +0 -49
  180. package/src/components/forms/input-checkbox.tsx +0 -78
  181. package/src/components/forms/input-container.tsx +0 -107
  182. package/src/components/forms/input-email-address.tsx +0 -65
  183. package/src/components/forms/input-new-password.tsx +0 -62
  184. package/src/components/forms/input-password.tsx +0 -87
  185. package/src/components/forms/input-text.tsx +0 -82
  186. package/src/components/forms/input-token.tsx +0 -94
  187. package/src/components/forms/wizard-card.tsx +0 -116
  188. package/src/components/layouts/layout-title-page.tsx +0 -77
  189. package/src/components/layouts/layout-welcome.tsx +0 -73
  190. package/src/components/utils/account-identifier.tsx +0 -23
  191. package/src/components/utils/account-image.tsx +0 -33
  192. package/src/components/utils/admonition.tsx +0 -52
  193. package/src/components/utils/client-name.tsx +0 -45
  194. package/src/components/utils/error-card.tsx +0 -93
  195. package/src/components/utils/error-message.tsx +0 -88
  196. package/src/components/utils/help-card.tsx +0 -46
  197. package/src/components/utils/icons.tsx +0 -88
  198. package/src/components/utils/link-anchor.tsx +0 -28
  199. package/src/components/utils/link-title.tsx +0 -26
  200. package/src/components/utils/multi-lang-string.tsx +0 -56
  201. package/src/components/utils/password-strength-label.tsx +0 -37
  202. package/src/components/utils/password-strength-meter.tsx +0 -58
  203. package/src/components/utils/url-viewer.tsx +0 -73
  204. package/src/cookies.ts +0 -11
  205. package/src/error-page.html +0 -125
  206. package/src/error-page.tsx +0 -29
  207. package/src/hooks/use-api.ts +0 -182
  208. package/src/hooks/use-async-action.ts +0 -120
  209. package/src/hooks/use-bound-dispatch.ts +0 -5
  210. package/src/hooks/use-browser-color-scheme.ts +0 -31
  211. package/src/hooks/use-csrf-token.ts +0 -5
  212. package/src/hooks/use-random-string.ts +0 -37
  213. package/src/hooks/use-stepper.ts +0 -87
  214. package/src/index.html +0 -13
  215. package/src/lib/api.ts +0 -234
  216. package/src/lib/backend-data.ts +0 -6
  217. package/src/lib/clsx.ts +0 -6
  218. package/src/lib/json-client.ts +0 -97
  219. package/src/lib/password.ts +0 -98
  220. package/src/lib/ref.ts +0 -17
  221. package/src/lib/util.ts +0 -13
  222. package/src/locales/an/messages.po +0 -487
  223. package/src/locales/ast/messages.po +0 -487
  224. package/src/locales/ca/messages.po +0 -487
  225. package/src/locales/da/messages.po +0 -487
  226. package/src/locales/de/messages.po +0 -487
  227. package/src/locales/el/messages.po +0 -487
  228. package/src/locales/en/messages.po +0 -487
  229. package/src/locales/en-GB/messages.po +0 -487
  230. package/src/locales/es/messages.po +0 -487
  231. package/src/locales/eu/messages.po +0 -487
  232. package/src/locales/fi/messages.po +0 -487
  233. package/src/locales/fr/messages.po +0 -487
  234. package/src/locales/ga/messages.po +0 -487
  235. package/src/locales/gl/messages.po +0 -487
  236. package/src/locales/hi/messages.po +0 -487
  237. package/src/locales/hu/messages.po +0 -487
  238. package/src/locales/ia/messages.po +0 -487
  239. package/src/locales/id/messages.po +0 -487
  240. package/src/locales/it/messages.po +0 -487
  241. package/src/locales/ja/messages.po +0 -487
  242. package/src/locales/km/messages.po +0 -487
  243. package/src/locales/ko/messages.po +0 -487
  244. package/src/locales/load.ts +0 -8
  245. package/src/locales/locale-context.ts +0 -19
  246. package/src/locales/locale-provider.tsx +0 -112
  247. package/src/locales/locale-selector.tsx +0 -58
  248. package/src/locales/locales.ts +0 -168
  249. package/src/locales/ne/messages.po +0 -487
  250. package/src/locales/nl/messages.po +0 -487
  251. package/src/locales/pl/messages.po +0 -487
  252. package/src/locales/pt-BR/messages.po +0 -487
  253. package/src/locales/ro/messages.po +0 -487
  254. package/src/locales/ru/messages.po +0 -487
  255. package/src/locales/sv/messages.po +0 -487
  256. package/src/locales/th/messages.po +0 -487
  257. package/src/locales/tr/messages.po +0 -487
  258. package/src/locales/uk/messages.po +0 -487
  259. package/src/locales/vi/messages.po +0 -487
  260. package/src/locales/zh-CN/messages.po +0 -487
  261. package/src/locales/zh-HK/messages.po +0 -487
  262. package/src/locales/zh-TW/messages.po +0 -487
  263. package/src/styles.css +0 -33
  264. package/src/views/authorize/accept/accept-form.tsx +0 -150
  265. package/src/views/authorize/accept/accept-view.tsx +0 -70
  266. package/src/views/authorize/authorize-view.tsx +0 -183
  267. package/src/views/authorize/reset-password/reset-password-confirm-form.tsx +0 -88
  268. package/src/views/authorize/reset-password/reset-password-request-form.tsx +0 -80
  269. package/src/views/authorize/reset-password/reset-password-view.tsx +0 -127
  270. package/src/views/authorize/sign-in/sign-in-form.tsx +0 -242
  271. package/src/views/authorize/sign-in/sign-in-picker.tsx +0 -116
  272. package/src/views/authorize/sign-in/sign-in-view.tsx +0 -145
  273. package/src/views/authorize/sign-up/sign-up-account-form.tsx +0 -142
  274. package/src/views/authorize/sign-up/sign-up-disclaimer.tsx +0 -51
  275. package/src/views/authorize/sign-up/sign-up-handle-form.tsx +0 -287
  276. package/src/views/authorize/sign-up/sign-up-hcaptcha-form.tsx +0 -108
  277. package/src/views/authorize/sign-up/sign-up-view.tsx +0 -158
  278. package/src/views/authorize/welcome/welcome-view.tsx +0 -56
  279. package/src/views/error/error-view.tsx +0 -31
  280. package/tailwind.config.js +0 -31
  281. package/tsconfig.backend.json +0 -8
  282. package/tsconfig.frontend.json +0 -10
  283. package/tsconfig.frontend.tsbuildinfo +0 -1
  284. package/tsconfig.json +0 -8
  285. package/tsconfig.tools.json +0 -8
  286. package/tsconfig.tools.tsbuildinfo +0 -1
  287. package/vite.config.mjs +0 -16
@@ -1,182 +0,0 @@
1
- import { useLingui } from '@lingui/react/macro'
2
- import { useCallback, useMemo, useState } from 'react'
3
- import { useErrorBoundary } from 'react-error-boundary'
4
- import type {
5
- Account,
6
- ConfirmResetPasswordData,
7
- InitiatePasswordResetData,
8
- Session,
9
- SignInData,
10
- SignUpData,
11
- VerifyHandleAvailabilityData,
12
- } from '@atproto/oauth-provider-api'
13
- import { AcceptData, Api, UnknownRequestUriError } from '../lib/api.ts'
14
- import { upsert } from '../lib/util.ts'
15
- import { useCsrfToken } from './use-csrf-token.ts'
16
-
17
- /**
18
- * Any function wrapped with this helper will automatically show the error
19
- * boundary when an `UnknownRequestUriError` is thrown. This typically happens
20
- * in development, or if the user left its browser session open for a (very)
21
- * long time.
22
- *
23
- * @note Requires an error boundary to be present in the component tree.
24
- */
25
- function useSafeCallback<F extends (...a: any) => any>(fn: F, deps: unknown[]) {
26
- const { showBoundary } = useErrorBoundary<UnknownRequestUriError>()
27
-
28
- return useCallback(
29
- async (...args: Parameters<F>): Promise<Awaited<ReturnType<F>>> => {
30
- try {
31
- return await fn(...args)
32
- } catch (error) {
33
- if (error instanceof UnknownRequestUriError) showBoundary(error)
34
- throw error
35
- }
36
- },
37
- deps.concat(showBoundary),
38
- )
39
- }
40
-
41
- export type UseApiOptions = {
42
- requestUri: string
43
- sessions?: readonly Session[]
44
- newSessionsRequireConsent?: boolean
45
- onRedirected?: () => void
46
- }
47
-
48
- export function useApi({
49
- requestUri,
50
- sessions: sessionsInit = [],
51
- newSessionsRequireConsent = true,
52
- onRedirected,
53
- }: UseApiOptions) {
54
- const csrfToken = useCsrfToken(`csrf-${requestUri}`)
55
- if (!csrfToken) throw new Error('CSRF token is missing')
56
-
57
- const api = useMemo(() => new Api(csrfToken), [csrfToken])
58
- const [sessions, setSessions] = useState(sessionsInit)
59
-
60
- const { i18n } = useLingui()
61
- const { locale } = i18n
62
-
63
- const selectSub = useCallback(
64
- (sub: string | null) => {
65
- setSessions((sessions) =>
66
- sub === (sessions.find((s) => s.selected)?.account.sub || null)
67
- ? sessions
68
- : sessions.map((s) => ({ ...s, selected: s.account.sub === sub })),
69
- )
70
- },
71
- [setSessions],
72
- )
73
-
74
- const upsertSession = useCallback(
75
- ({
76
- account,
77
- consentRequired,
78
- }: {
79
- account: Account
80
- consentRequired: boolean
81
- }) => {
82
- const session: Session = {
83
- account,
84
- selected: true,
85
- loginRequired: false,
86
- consentRequired: newSessionsRequireConsent || consentRequired,
87
- }
88
-
89
- setSessions((sessions) =>
90
- upsert(sessions, session, (s) => s.account.sub === account.sub).map(
91
- // Make sure to de-select any other selected session
92
- (s) => (s === session || !s.selected ? s : { ...s, selected: false }),
93
- ),
94
- )
95
- },
96
- [setSessions, newSessionsRequireConsent],
97
- )
98
-
99
- const performRedirect = useCallback(
100
- (url: URL) => {
101
- window.location.href = String(url)
102
- if (onRedirected) setTimeout(onRedirected)
103
- },
104
- [onRedirected],
105
- )
106
-
107
- const doSignIn = useSafeCallback(
108
- async (data: Omit<SignInData, 'locale'>, signal?: AbortSignal) => {
109
- const response = await api.fetch(
110
- '/sign-in',
111
- { ...data, locale },
112
- { signal },
113
- )
114
- upsertSession(response)
115
- },
116
- [api, locale, upsertSession],
117
- )
118
-
119
- const doInitiatePasswordReset = useSafeCallback(
120
- async (
121
- data: Omit<InitiatePasswordResetData, 'locale'>,
122
- signal?: AbortSignal,
123
- ) => {
124
- await api.fetch(
125
- '/reset-password-request',
126
- { ...data, locale },
127
- { signal },
128
- )
129
- },
130
- [api, locale],
131
- )
132
-
133
- const doConfirmResetPassword = useSafeCallback(
134
- async (data: ConfirmResetPasswordData, signal?: AbortSignal) => {
135
- await api.fetch('/reset-password-confirm', data, { signal })
136
- },
137
- [api],
138
- )
139
-
140
- const doValidateNewHandle = useSafeCallback(
141
- async (data: VerifyHandleAvailabilityData, signal?: AbortSignal) => {
142
- await api.fetch('/verify-handle-availability', data, { signal })
143
- },
144
- [api],
145
- )
146
-
147
- const doSignUp = useSafeCallback(
148
- async (data: Omit<SignUpData, 'locale'>, signal?: AbortSignal) => {
149
- const response = await api.fetch(
150
- '/sign-up',
151
- { ...data, locale },
152
- { signal },
153
- )
154
- upsertSession(response)
155
- },
156
- [api, locale, upsertSession],
157
- )
158
-
159
- const doAccept = useSafeCallback(
160
- async (data: AcceptData) => {
161
- performRedirect(api.buildAcceptUrl(data))
162
- },
163
- [api, performRedirect],
164
- )
165
-
166
- const doReject = useSafeCallback(async () => {
167
- performRedirect(api.buildRejectUrl())
168
- }, [api, performRedirect])
169
-
170
- return {
171
- sessions,
172
- selectSub,
173
-
174
- doSignIn,
175
- doInitiatePasswordReset,
176
- doConfirmResetPassword,
177
- doValidateNewHandle,
178
- doSignUp,
179
- doAccept,
180
- doReject,
181
- }
182
- }
@@ -1,120 +0,0 @@
1
- import {
2
- ForwardedRef,
3
- useCallback,
4
- useEffect,
5
- useImperativeHandle,
6
- useRef,
7
- useState,
8
- } from 'react'
9
-
10
- export type AsyncActionController = {
11
- reset: () => void
12
- }
13
-
14
- export type UseAsyncActionOptions = {
15
- ref?: ForwardedRef<AsyncActionController>
16
- onLoading?: (loading: boolean) => void
17
- onError?: (error: Error | undefined) => void
18
- }
19
-
20
- export function useAsyncAction(
21
- fn: (signal: AbortSignal) => void | PromiseLike<void>,
22
- { ref, onLoading, onError }: UseAsyncActionOptions = {},
23
- ) {
24
- const [loading, setLoading] = useState(false)
25
- const [error, setError] = useState<Error | undefined>()
26
-
27
- const doSetError = useCallback(
28
- (error: Error | undefined) => {
29
- setError(error)
30
- onError?.(error)
31
- },
32
- [onError],
33
- )
34
-
35
- const doSetLoading = useCallback(
36
- (loading: boolean) => {
37
- setLoading(loading)
38
- onLoading?.(loading)
39
- },
40
- [onLoading],
41
- )
42
-
43
- const controllerRef = useRef<AbortController>(null)
44
-
45
- const resetRef = useRef<() => void>(null)
46
- useEffect(() => {
47
- resetRef.current = () => {
48
- controllerRef.current?.abort()
49
- controllerRef.current = null
50
- doSetError(undefined)
51
- doSetLoading(false)
52
- }
53
- return () => {
54
- resetRef.current = null
55
- }
56
- }, [doSetError, doSetLoading])
57
-
58
- useImperativeHandle(
59
- ref,
60
- (): AsyncActionController => ({
61
- reset: () => resetRef.current?.(),
62
- }),
63
- [],
64
- )
65
-
66
- // Cancel pending action when unmounted
67
- useEffect(() => {
68
- return () => {
69
- controllerRef.current?.abort()
70
- controllerRef.current = null
71
- }
72
- }, [])
73
-
74
- const run = useCallback(async (): Promise<void> => {
75
- // Cancel previous run
76
- controllerRef.current?.abort()
77
-
78
- doSetLoading(true)
79
- doSetError(undefined)
80
-
81
- const controller = new AbortController()
82
- const { signal } = controller
83
-
84
- controllerRef.current = controller
85
-
86
- try {
87
- await fn(signal)
88
- } catch (err) {
89
- if (controller === controllerRef.current) {
90
- doSetError(err instanceof Error ? err : new Error(String(err)))
91
- } else {
92
- if (!isAbortReason(signal, err)) {
93
- console.warn('Async action error after abort', err)
94
- }
95
- }
96
- } finally {
97
- if (controller === controllerRef.current) {
98
- controllerRef.current = null
99
- doSetLoading(false)
100
- }
101
-
102
- controller.abort()
103
- }
104
- }, [fn, doSetLoading, doSetError])
105
-
106
- return {
107
- loading,
108
- error,
109
- run,
110
- }
111
- }
112
-
113
- function isAbortReason(signal: AbortSignal, err: unknown): boolean {
114
- return (
115
- signal.aborted &&
116
- (signal.reason === err ||
117
- signal.reason === err?.['cause'] ||
118
- (err instanceof DOMException && err.name === 'AbortError'))
119
- )
120
- }
@@ -1,5 +0,0 @@
1
- import { Dispatch, useCallback } from 'react'
2
-
3
- export function useBoundDispatch<A>(dispatch: Dispatch<A>, value: A) {
4
- return useCallback(() => dispatch(value), [dispatch, value])
5
- }
@@ -1,31 +0,0 @@
1
- import { useEffect, useState } from 'react'
2
-
3
- const query =
4
- typeof window === 'undefined'
5
- ? null
6
- : window.matchMedia('(prefers-color-scheme: dark)')
7
-
8
- export function useBrowserColorScheme() {
9
- const [theme, setTheme] = useState<'light' | 'dark'>(
10
- query?.matches ? 'dark' : 'light',
11
- )
12
-
13
- useEffect(() => {
14
- if (!query) return
15
-
16
- const listener = () => {
17
- setTheme(query.matches ? 'dark' : 'light')
18
- }
19
-
20
- query.addEventListener('change', listener)
21
-
22
- return () => {
23
- query.removeEventListener('change', listener)
24
- }
25
-
26
- // @NOTE "query" is a global constant and does not need to be part of the
27
- // array bellow:
28
- }, [])
29
-
30
- return theme
31
- }
@@ -1,5 +0,0 @@
1
- import { cookies } from '../cookies.ts'
2
-
3
- export function useCsrfToken(cookieName: string) {
4
- return cookies[cookieName]
5
- }
@@ -1,37 +0,0 @@
1
- import { useEffect, useState } from 'react'
2
-
3
- export const UPPER = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
4
- export const LOWER = UPPER.toLowerCase() as Lowercase<typeof UPPER>
5
- export const DIGITS = '0123456789'
6
-
7
- export const ALPHANUMERIC = `${UPPER}${LOWER}${DIGITS}` as const
8
-
9
- export type UseRandomStringOptions = BuildRandomStringOptions & {
10
- prefix?: string
11
- suffix?: string
12
- }
13
-
14
- export function useRandomString(options?: UseRandomStringOptions) {
15
- const [state, setState] = useState(() => buildRandomString(options))
16
- useEffect(() => {
17
- setState(buildRandomString(options))
18
- }, [options?.length, options?.alphabet])
19
-
20
- return `${options?.prefix ?? ''}${state}${options?.suffix ?? ''}`
21
- }
22
-
23
- type BuildRandomStringOptions = {
24
- length?: number
25
- alphabet?: string
26
- }
27
-
28
- function buildRandomString({
29
- length = 16,
30
- alphabet = ALPHANUMERIC,
31
- }: BuildRandomStringOptions = {}) {
32
- return Array.from({ length }, () => getRandomCharFrom(alphabet)).join('')
33
- }
34
-
35
- function getRandomCharFrom(alphabet: string) {
36
- return alphabet.charAt((Math.random() * alphabet.length) | 0)
37
- }
@@ -1,87 +0,0 @@
1
- import { useCallback, useEffect, useState } from 'react'
2
-
3
- export type DisabledStep = false | null | undefined
4
- export type Step = {
5
- invalid: boolean
6
- }
7
-
8
- const isEnabled = <S extends Step | DisabledStep>(
9
- s: S,
10
- ): s is S extends DisabledStep ? never : S => s != null && s !== false
11
- const isRequired = <S extends Step | DisabledStep>(
12
- s: S,
13
- ): s is S extends DisabledStep ? never : S & { invalid: true } =>
14
- isEnabled(s) && s.invalid === true
15
- const isCompleted = <S extends Step | DisabledStep>(
16
- s: S,
17
- ): s is S extends DisabledStep ? S : S & { invalid: false } =>
18
- !isEnabled(s) || s.invalid === false
19
-
20
- export function useStepper<const S extends Step>(
21
- steps: readonly (S | DisabledStep)[],
22
- ) {
23
- const firstIdx = steps.findIndex(isEnabled)
24
- const lastIdx = steps.findLastIndex(isEnabled)
25
- const requiredIdx = steps.findIndex(isRequired)
26
-
27
- const [currentIdx, setCurrentIdx] = useState<number>(firstIdx)
28
-
29
- const to = useCallback(
30
- (idx: number) => {
31
- if (idx !== -1 && steps[idx]) {
32
- setCurrentIdx(idx)
33
- return true
34
- } else {
35
- return false
36
- }
37
- },
38
- [steps.map(isEnabled).join()],
39
- )
40
-
41
- const prevIdx = steps.findLastIndex((s, i) => isEnabled(s) && i < currentIdx)
42
- const nextIdx = steps.findIndex((s, i) => isEnabled(s) && i > currentIdx)
43
-
44
- const toFirst = useCallback(() => to(firstIdx), [to, firstIdx])
45
- const toLast = useCallback(() => to(lastIdx), [to, lastIdx])
46
- const toPrev = useCallback(() => to(prevIdx), [to, prevIdx])
47
- const toNext = useCallback(() => to(nextIdx), [to, nextIdx])
48
- const toRequired = useCallback(() => to(requiredIdx), [to, requiredIdx])
49
-
50
- // Step number in user friendly terms (accounting for disabled steps)
51
- const currentPosition =
52
- currentIdx +
53
- // use "1 indexed position" (for user friendliness):
54
- 1 +
55
- // Adjust the position by counting the number of disabled steps before the
56
- // current step (if any):
57
- steps.reduce(
58
- (acc, s, i) => (i >= currentIdx || isEnabled(s) ? acc : acc - 1),
59
- 0,
60
- )
61
-
62
- const count = steps.filter(isEnabled).length
63
- const completed = steps.every(isCompleted)
64
-
65
- const current =
66
- currentIdx === -1 || !steps[currentIdx] ? undefined : steps[currentIdx]
67
-
68
- // Fool-proof (reset current step in case the current step becomes disabled)
69
- const broken = currentIdx === -1
70
- useEffect(() => {
71
- if (broken) toFirst()
72
- }, [broken])
73
-
74
- return {
75
- current,
76
- currentPosition,
77
- count,
78
- completed,
79
- atFirst: currentPosition === 1,
80
- atLast: currentPosition === count,
81
- toFirst,
82
- toLast,
83
- toPrev,
84
- toNext,
85
- toRequired,
86
- }
87
- }
package/src/index.html DELETED
@@ -1,13 +0,0 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>OAuth mock pages</title>
7
- </head>
8
- <body>
9
- <a href="authorization-page.html">authorization-page</a>
10
- <br />
11
- <a href="error-page.html">error-page</a>
12
- </body>
13
- </html>