@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.
- package/dist/authorization-page-Cms-rcBA.js +3 -0
- package/dist/authorization-page-Cms-rcBA.js.map +1 -0
- package/dist/{assets/bundle-manifest.json → bundle-manifest.json} +197 -197
- package/dist/error-page-DC6Vc-cv.js +2 -0
- package/dist/error-page-DC6Vc-cv.js.map +1 -0
- package/dist/error-view-CRGNTAn2.css +1 -0
- package/dist/error-view-MVy7C9l0.js +59 -0
- package/dist/error-view-MVy7C9l0.js.map +1 -0
- package/dist/index-CHPoD7Rp.js +20 -0
- package/dist/index-CHPoD7Rp.js.map +1 -0
- package/dist/messages-B0mgsxS-.js +2 -0
- package/dist/messages-B0mgsxS-.js.map +1 -0
- package/dist/messages-B5g8Fkio.js +2 -0
- package/dist/messages-B5g8Fkio.js.map +1 -0
- package/dist/messages-BCMss-Kt.js +2 -0
- package/dist/messages-BCMss-Kt.js.map +1 -0
- package/dist/messages-BGUrKgyK.js +2 -0
- package/dist/messages-BGUrKgyK.js.map +1 -0
- package/dist/messages-BjxAnLDp.js +2 -0
- package/dist/messages-BjxAnLDp.js.map +1 -0
- package/dist/messages-Bjysz3rI.js +2 -0
- package/dist/messages-Bjysz3rI.js.map +1 -0
- package/dist/messages-BvvEr3UX.js +2 -0
- package/dist/messages-BvvEr3UX.js.map +1 -0
- package/dist/messages-Bz6JOhJf.js +2 -0
- package/dist/messages-Bz6JOhJf.js.map +1 -0
- package/dist/messages-BzL3D1EU.js +2 -0
- package/dist/messages-BzL3D1EU.js.map +1 -0
- package/dist/messages-CAvN5UoW.js +2 -0
- package/dist/messages-CAvN5UoW.js.map +1 -0
- package/dist/messages-CEmswT1Q.js +2 -0
- package/dist/messages-CEmswT1Q.js.map +1 -0
- package/dist/messages-CHYqz0q6.js +2 -0
- package/dist/messages-CHYqz0q6.js.map +1 -0
- package/dist/messages-CRmpdijj.js +2 -0
- package/dist/messages-CRmpdijj.js.map +1 -0
- package/dist/messages-Cdb79R6S.js +2 -0
- package/dist/messages-Cdb79R6S.js.map +1 -0
- package/dist/messages-ChkJ_0WT.js +2 -0
- package/dist/messages-ChkJ_0WT.js.map +1 -0
- package/dist/messages-CqiEX6JJ.js +2 -0
- package/dist/messages-CqiEX6JJ.js.map +1 -0
- package/dist/messages-CxkHjJSR.js +2 -0
- package/dist/messages-CxkHjJSR.js.map +1 -0
- package/dist/messages-D0-cWoJ9.js +2 -0
- package/dist/messages-D0-cWoJ9.js.map +1 -0
- package/dist/messages-D2MnAxYY.js +2 -0
- package/dist/messages-D2MnAxYY.js.map +1 -0
- package/dist/messages-D5TZVsui.js +2 -0
- package/dist/messages-D5TZVsui.js.map +1 -0
- package/dist/messages-DBdV4-iw.js +2 -0
- package/dist/messages-DBdV4-iw.js.map +1 -0
- package/dist/messages-DEK3zybC.js +2 -0
- package/dist/messages-DEK3zybC.js.map +1 -0
- package/dist/messages-DGSM5jkd.js +2 -0
- package/dist/messages-DGSM5jkd.js.map +1 -0
- package/dist/messages-DJgAnSTQ.js +2 -0
- package/dist/messages-DJgAnSTQ.js.map +1 -0
- package/dist/messages-DK7O7sb_.js +2 -0
- package/dist/messages-DK7O7sb_.js.map +1 -0
- package/dist/messages-DRp7qc3j.js +2 -0
- package/dist/messages-DRp7qc3j.js.map +1 -0
- package/dist/messages-DT6xRw0m.js +2 -0
- package/dist/messages-DT6xRw0m.js.map +1 -0
- package/dist/messages-LnzLtU0L.js +2 -0
- package/dist/messages-LnzLtU0L.js.map +1 -0
- package/dist/messages-_Nk2qNGw.js +2 -0
- package/dist/messages-_Nk2qNGw.js.map +1 -0
- package/dist/messages-eHH6nZyF.js +2 -0
- package/dist/messages-eHH6nZyF.js.map +1 -0
- package/dist/messages-iNw8zY2C.js +2 -0
- package/dist/messages-iNw8zY2C.js.map +1 -0
- package/dist/messages-ipc0L8yF.js +2 -0
- package/dist/messages-ipc0L8yF.js.map +1 -0
- package/dist/messages-j7LsWm2F.js +2 -0
- package/dist/messages-j7LsWm2F.js.map +1 -0
- package/dist/messages-mgE_5UEw.js +2 -0
- package/dist/messages-mgE_5UEw.js.map +1 -0
- package/dist/messages-oRd-J5--.js +2 -0
- package/dist/messages-oRd-J5--.js.map +1 -0
- package/hydration-data.d.ts +42 -0
- package/package.json +30 -37
- package/.linguirc +0 -57
- package/CHANGELOG.md +0 -7
- package/CONTRIBUTING.md +0 -6
- package/dist/assets/COdVzed-.css +0 -3
- package/dist/assets/COdVzed-.js +0 -100
- package/dist/assets/COdVzed-.js.map +0 -1
- package/dist/assets/Cqnfnbvc.js +0 -6
- package/dist/assets/Cqnfnbvc.js.map +0 -1
- package/dist/assets/error-view-Bu4y7Nd8.js +0 -208
- package/dist/assets/error-view-Bu4y7Nd8.js.map +0 -1
- package/dist/assets/index-DXlCRM6V.js +0 -36
- package/dist/assets/index-DXlCRM6V.js.map +0 -1
- package/dist/assets/messages-2GoTm2qL.js +0 -4
- package/dist/assets/messages-2GoTm2qL.js.map +0 -1
- package/dist/assets/messages-6Cn2Jbhw.js +0 -4
- package/dist/assets/messages-6Cn2Jbhw.js.map +0 -1
- package/dist/assets/messages-75hFgOK2.js +0 -4
- package/dist/assets/messages-75hFgOK2.js.map +0 -1
- package/dist/assets/messages-B3OK4k0O.js +0 -4
- package/dist/assets/messages-B3OK4k0O.js.map +0 -1
- package/dist/assets/messages-BNXlPzKV.js +0 -4
- package/dist/assets/messages-BNXlPzKV.js.map +0 -1
- package/dist/assets/messages-BUygB8mD.js +0 -4
- package/dist/assets/messages-BUygB8mD.js.map +0 -1
- package/dist/assets/messages-BVPPcwNr.js +0 -4
- package/dist/assets/messages-BVPPcwNr.js.map +0 -1
- package/dist/assets/messages-BbbWUQS8.js +0 -4
- package/dist/assets/messages-BbbWUQS8.js.map +0 -1
- package/dist/assets/messages-BibKCYyW.js +0 -4
- package/dist/assets/messages-BibKCYyW.js.map +0 -1
- package/dist/assets/messages-BlPrr9_7.js +0 -4
- package/dist/assets/messages-BlPrr9_7.js.map +0 -1
- package/dist/assets/messages-ByVCw40U.js +0 -4
- package/dist/assets/messages-ByVCw40U.js.map +0 -1
- package/dist/assets/messages-C5DU1neP.js +0 -4
- package/dist/assets/messages-C5DU1neP.js.map +0 -1
- package/dist/assets/messages-C6IgUtbX.js +0 -4
- package/dist/assets/messages-C6IgUtbX.js.map +0 -1
- package/dist/assets/messages-C92Zzt2o.js +0 -4
- package/dist/assets/messages-C92Zzt2o.js.map +0 -1
- package/dist/assets/messages-CGZqYT14.js +0 -4
- package/dist/assets/messages-CGZqYT14.js.map +0 -1
- package/dist/assets/messages-CGlsy4wt.js +0 -4
- package/dist/assets/messages-CGlsy4wt.js.map +0 -1
- package/dist/assets/messages-CPT1nd0u.js +0 -4
- package/dist/assets/messages-CPT1nd0u.js.map +0 -1
- package/dist/assets/messages-CTTdXyw_.js +0 -4
- package/dist/assets/messages-CTTdXyw_.js.map +0 -1
- package/dist/assets/messages-ChK_C_Pj.js +0 -4
- package/dist/assets/messages-ChK_C_Pj.js.map +0 -1
- package/dist/assets/messages-CjJbk7Uf.js +0 -4
- package/dist/assets/messages-CjJbk7Uf.js.map +0 -1
- package/dist/assets/messages-CoiLjLYO.js +0 -4
- package/dist/assets/messages-CoiLjLYO.js.map +0 -1
- package/dist/assets/messages-Cwx6B4Ti.js +0 -4
- package/dist/assets/messages-Cwx6B4Ti.js.map +0 -1
- package/dist/assets/messages-D0uXAp_H.js +0 -4
- package/dist/assets/messages-D0uXAp_H.js.map +0 -1
- package/dist/assets/messages-DG0_arU0.js +0 -4
- package/dist/assets/messages-DG0_arU0.js.map +0 -1
- package/dist/assets/messages-DOXFJh9K.js +0 -4
- package/dist/assets/messages-DOXFJh9K.js.map +0 -1
- package/dist/assets/messages-DPK7nOoC.js +0 -4
- package/dist/assets/messages-DPK7nOoC.js.map +0 -1
- package/dist/assets/messages-Duccgtu0.js +0 -4
- package/dist/assets/messages-Duccgtu0.js.map +0 -1
- package/dist/assets/messages-DxTqgsHq.js +0 -4
- package/dist/assets/messages-DxTqgsHq.js.map +0 -1
- package/dist/assets/messages-E5_lTg7A.js +0 -4
- package/dist/assets/messages-E5_lTg7A.js.map +0 -1
- package/dist/assets/messages-UhunAjh1.js +0 -4
- package/dist/assets/messages-UhunAjh1.js.map +0 -1
- package/dist/assets/messages-Xg_3YLGw.js +0 -4
- package/dist/assets/messages-Xg_3YLGw.js.map +0 -1
- package/dist/assets/messages-iliBQHY2.js +0 -4
- package/dist/assets/messages-iliBQHY2.js.map +0 -1
- package/dist/assets/messages-lRprpIl-.js +0 -4
- package/dist/assets/messages-lRprpIl-.js.map +0 -1
- package/dist/assets/messages-pbPHQbz1.js +0 -4
- package/dist/assets/messages-pbPHQbz1.js.map +0 -1
- package/dist/assets/messages-q-O7ZQGs.js +0 -4
- package/dist/assets/messages-q-O7ZQGs.js.map +0 -1
- package/dist/lib/index.d.ts +0 -19
- package/dist/lib/index.d.ts.map +0 -1
- package/dist/lib/index.js +0 -47
- package/dist/lib/index.js.map +0 -1
- package/dist/tsconfig.backend.tsbuildinfo +0 -1
- package/lib/index.ts +0 -72
- package/rollup.config.js +0 -102
- package/src/authorization-page.html +0 -183
- package/src/authorization-page.tsx +0 -55
- package/src/backend-data.ts +0 -35
- package/src/components/forms/button-toggle-visibility.tsx +0 -43
- package/src/components/forms/button.tsx +0 -60
- package/src/components/forms/fieldset.tsx +0 -55
- package/src/components/forms/form-card-async.tsx +0 -103
- package/src/components/forms/form-card.tsx +0 -49
- package/src/components/forms/input-checkbox.tsx +0 -78
- package/src/components/forms/input-container.tsx +0 -107
- package/src/components/forms/input-email-address.tsx +0 -65
- package/src/components/forms/input-new-password.tsx +0 -62
- package/src/components/forms/input-password.tsx +0 -87
- package/src/components/forms/input-text.tsx +0 -82
- package/src/components/forms/input-token.tsx +0 -94
- package/src/components/forms/wizard-card.tsx +0 -116
- package/src/components/layouts/layout-title-page.tsx +0 -77
- package/src/components/layouts/layout-welcome.tsx +0 -73
- package/src/components/utils/account-identifier.tsx +0 -23
- package/src/components/utils/account-image.tsx +0 -33
- package/src/components/utils/admonition.tsx +0 -52
- package/src/components/utils/client-name.tsx +0 -45
- package/src/components/utils/error-card.tsx +0 -93
- package/src/components/utils/error-message.tsx +0 -88
- package/src/components/utils/help-card.tsx +0 -46
- package/src/components/utils/icons.tsx +0 -88
- package/src/components/utils/link-anchor.tsx +0 -28
- package/src/components/utils/link-title.tsx +0 -26
- package/src/components/utils/multi-lang-string.tsx +0 -56
- package/src/components/utils/password-strength-label.tsx +0 -37
- package/src/components/utils/password-strength-meter.tsx +0 -58
- package/src/components/utils/url-viewer.tsx +0 -73
- package/src/cookies.ts +0 -11
- package/src/error-page.html +0 -125
- package/src/error-page.tsx +0 -29
- package/src/hooks/use-api.ts +0 -182
- package/src/hooks/use-async-action.ts +0 -120
- package/src/hooks/use-bound-dispatch.ts +0 -5
- package/src/hooks/use-browser-color-scheme.ts +0 -31
- package/src/hooks/use-csrf-token.ts +0 -5
- package/src/hooks/use-random-string.ts +0 -37
- package/src/hooks/use-stepper.ts +0 -87
- package/src/index.html +0 -13
- package/src/lib/api.ts +0 -234
- package/src/lib/backend-data.ts +0 -6
- package/src/lib/clsx.ts +0 -6
- package/src/lib/json-client.ts +0 -97
- package/src/lib/password.ts +0 -98
- package/src/lib/ref.ts +0 -17
- package/src/lib/util.ts +0 -13
- package/src/locales/an/messages.po +0 -487
- package/src/locales/ast/messages.po +0 -487
- package/src/locales/ca/messages.po +0 -487
- package/src/locales/da/messages.po +0 -487
- package/src/locales/de/messages.po +0 -487
- package/src/locales/el/messages.po +0 -487
- package/src/locales/en/messages.po +0 -487
- package/src/locales/en-GB/messages.po +0 -487
- package/src/locales/es/messages.po +0 -487
- package/src/locales/eu/messages.po +0 -487
- package/src/locales/fi/messages.po +0 -487
- package/src/locales/fr/messages.po +0 -487
- package/src/locales/ga/messages.po +0 -487
- package/src/locales/gl/messages.po +0 -487
- package/src/locales/hi/messages.po +0 -487
- package/src/locales/hu/messages.po +0 -487
- package/src/locales/ia/messages.po +0 -487
- package/src/locales/id/messages.po +0 -487
- package/src/locales/it/messages.po +0 -487
- package/src/locales/ja/messages.po +0 -487
- package/src/locales/km/messages.po +0 -487
- package/src/locales/ko/messages.po +0 -487
- package/src/locales/load.ts +0 -8
- package/src/locales/locale-context.ts +0 -19
- package/src/locales/locale-provider.tsx +0 -112
- package/src/locales/locale-selector.tsx +0 -58
- package/src/locales/locales.ts +0 -168
- package/src/locales/ne/messages.po +0 -487
- package/src/locales/nl/messages.po +0 -487
- package/src/locales/pl/messages.po +0 -487
- package/src/locales/pt-BR/messages.po +0 -487
- package/src/locales/ro/messages.po +0 -487
- package/src/locales/ru/messages.po +0 -487
- package/src/locales/sv/messages.po +0 -487
- package/src/locales/th/messages.po +0 -487
- package/src/locales/tr/messages.po +0 -487
- package/src/locales/uk/messages.po +0 -487
- package/src/locales/vi/messages.po +0 -487
- package/src/locales/zh-CN/messages.po +0 -487
- package/src/locales/zh-HK/messages.po +0 -487
- package/src/locales/zh-TW/messages.po +0 -487
- package/src/styles.css +0 -33
- package/src/views/authorize/accept/accept-form.tsx +0 -150
- package/src/views/authorize/accept/accept-view.tsx +0 -70
- package/src/views/authorize/authorize-view.tsx +0 -183
- package/src/views/authorize/reset-password/reset-password-confirm-form.tsx +0 -88
- package/src/views/authorize/reset-password/reset-password-request-form.tsx +0 -80
- package/src/views/authorize/reset-password/reset-password-view.tsx +0 -127
- package/src/views/authorize/sign-in/sign-in-form.tsx +0 -242
- package/src/views/authorize/sign-in/sign-in-picker.tsx +0 -116
- package/src/views/authorize/sign-in/sign-in-view.tsx +0 -145
- package/src/views/authorize/sign-up/sign-up-account-form.tsx +0 -142
- package/src/views/authorize/sign-up/sign-up-disclaimer.tsx +0 -51
- package/src/views/authorize/sign-up/sign-up-handle-form.tsx +0 -287
- package/src/views/authorize/sign-up/sign-up-hcaptcha-form.tsx +0 -108
- package/src/views/authorize/sign-up/sign-up-view.tsx +0 -158
- package/src/views/authorize/welcome/welcome-view.tsx +0 -56
- package/src/views/error/error-view.tsx +0 -31
- package/tailwind.config.js +0 -31
- package/tsconfig.backend.json +0 -8
- package/tsconfig.frontend.json +0 -10
- package/tsconfig.frontend.tsbuildinfo +0 -1
- package/tsconfig.json +0 -8
- package/tsconfig.tools.json +0 -8
- package/tsconfig.tools.tsbuildinfo +0 -1
- package/vite.config.mjs +0 -16
package/src/hooks/use-api.ts
DELETED
|
@@ -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,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,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
|
-
}
|
package/src/hooks/use-stepper.ts
DELETED
|
@@ -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>
|