@supatype/react-auth 0.1.0-alpha.10

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.
@@ -0,0 +1,4 @@
1
+
2
+ > @supatype/react-auth@0.1.0-alpha.10 build /home/runner/work/supatype/supatype/packages/react-auth
3
+ > tsc
4
+
@@ -0,0 +1,12 @@
1
+
2
+ > @supatype/react-auth@0.1.0-alpha.10 test /home/runner/work/supatype/supatype/packages/react-auth
3
+ > vitest run --passWithNoTests
4
+
5
+
6
+  RUN  v4.0.18 /home/runner/work/supatype/supatype/packages/react-auth
7
+
8
+ No test files found, exiting with code 0
9
+
10
+ include: **/*.{test,spec}.?(c|m)[jt]s?(x)
11
+ exclude: **/node_modules/**, **/.git/**
12
+
@@ -0,0 +1,4 @@
1
+
2
+ > @supatype/react-auth@0.1.0-alpha.10 typecheck /home/runner/work/supatype/supatype/packages/react-auth
3
+ > tsc --noEmit
4
+
@@ -0,0 +1,33 @@
1
+ import React from "react";
2
+ import type { Session, SupatypeError } from "@supatype/client";
3
+ export interface LoginFormLabels {
4
+ title?: string | undefined;
5
+ email?: string | undefined;
6
+ password?: string | undefined;
7
+ submit?: string | undefined;
8
+ errorPrefix?: string | undefined;
9
+ }
10
+ export interface LoginFormProps {
11
+ /** Called with the new session after a successful sign-in. */
12
+ onSuccess?: ((session: Session) => void) | undefined;
13
+ /** Called with the error returned by the auth service. */
14
+ onError?: ((error: SupatypeError) => void) | undefined;
15
+ /** CSS class applied to the outermost <form> element. */
16
+ className?: string | undefined;
17
+ /** Override display labels. */
18
+ labels?: LoginFormLabels | undefined;
19
+ }
20
+ /**
21
+ * A minimal, accessible login form that integrates with `useAuth()`.
22
+ * Must be rendered inside a `<SupatypeProvider>`.
23
+ *
24
+ * @example
25
+ * ```tsx
26
+ * <LoginForm
27
+ * onSuccess={(session) => router.push('/dashboard')}
28
+ * onError={(err) => console.error(err.message)}
29
+ * />
30
+ * ```
31
+ */
32
+ export declare function LoginForm({ onSuccess, onError, className, labels }: LoginFormProps): React.ReactElement;
33
+ //# sourceMappingURL=LoginForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoginForm.d.ts","sourceRoot":"","sources":["../src/LoginForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmC,MAAM,OAAO,CAAA;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAG9D,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACpD,0DAA0D;IAC1D,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACtD,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,+BAA+B;IAC/B,MAAM,CAAC,EAAE,eAAe,GAAG,SAAS,CAAA;CACrC;AAUD;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,cAAc,GAAG,KAAK,CAAC,YAAY,CAoEvG"}
@@ -0,0 +1,51 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { useAuth } from "@supatype/react";
4
+ const DEFAULT_LABELS = {
5
+ title: "Sign in",
6
+ email: "Email address",
7
+ password: "Password",
8
+ submit: "Sign in",
9
+ errorPrefix: "",
10
+ };
11
+ /**
12
+ * A minimal, accessible login form that integrates with `useAuth()`.
13
+ * Must be rendered inside a `<SupatypeProvider>`.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * <LoginForm
18
+ * onSuccess={(session) => router.push('/dashboard')}
19
+ * onError={(err) => console.error(err.message)}
20
+ * />
21
+ * ```
22
+ */
23
+ export function LoginForm({ onSuccess, onError, className, labels }) {
24
+ const { signIn } = useAuth();
25
+ const l = { ...DEFAULT_LABELS, ...labels };
26
+ const [email, setEmail] = useState("");
27
+ const [password, setPassword] = useState("");
28
+ const [loading, setLoading] = useState(false);
29
+ const [errorMessage, setErrorMessage] = useState(null);
30
+ async function handleSubmit(e) {
31
+ e.preventDefault();
32
+ setErrorMessage(null);
33
+ setLoading(true);
34
+ try {
35
+ const { data, error } = await signIn({ email, password });
36
+ if (error !== null) {
37
+ const msg = `${l.errorPrefix}${error.message}`;
38
+ setErrorMessage(msg);
39
+ onError?.(error);
40
+ }
41
+ else if (data.session !== null) {
42
+ onSuccess?.(data.session);
43
+ }
44
+ }
45
+ finally {
46
+ setLoading(false);
47
+ }
48
+ }
49
+ return (_jsxs("form", { onSubmit: (e) => { void handleSubmit(e); }, className: className, noValidate: true, children: [_jsx("h2", { children: l.title }), errorMessage !== null && (_jsx("p", { role: "alert", "aria-live": "polite", style: { color: "red" }, children: errorMessage })), _jsxs("div", { children: [_jsx("label", { htmlFor: "st-login-email", children: l.email }), _jsx("input", { id: "st-login-email", type: "email", autoComplete: "email", required: true, value: email, onChange: (e) => setEmail(e.target.value), disabled: loading })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "st-login-password", children: l.password }), _jsx("input", { id: "st-login-password", type: "password", autoComplete: "current-password", required: true, value: password, onChange: (e) => setPassword(e.target.value), disabled: loading })] }), _jsx("button", { type: "submit", disabled: loading, children: loading ? "Signing in…" : l.submit })] }));
50
+ }
51
+ //# sourceMappingURL=LoginForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoginForm.js","sourceRoot":"","sources":["../src/LoginForm.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * OAuthButton component — Gap Appendices task 12
3
+ *
4
+ * Renders a styled sign-in button for an OAuth provider.
5
+ * Handles the full OAuth flow via `useAuth().signInWithOAuth()`.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * <OAuthButton provider="github" />
10
+ * <OAuthButton provider="google" redirectTo="/dashboard" />
11
+ * <OAuthButton provider="apple" className="dark-btn">Sign in with Apple</OAuthButton>
12
+ * ```
13
+ */
14
+ import React, { type ReactNode } from "react";
15
+ export interface OAuthButtonProps {
16
+ /** OAuth provider name (e.g. "github", "google", "apple"). */
17
+ provider: string;
18
+ /** URL to redirect to after successful authentication. */
19
+ redirectTo?: string | undefined;
20
+ /** CSS class applied to the button element. */
21
+ className?: string | undefined;
22
+ /** Override the button content. Defaults to "Sign in with {Provider}". */
23
+ children?: ReactNode | undefined;
24
+ /** Called when the OAuth flow errors. */
25
+ onError?: ((error: {
26
+ message: string;
27
+ }) => void) | undefined;
28
+ /** Whether to open the OAuth URL in a popup instead of redirect. */
29
+ popup?: boolean | undefined;
30
+ /** Button disabled state. */
31
+ disabled?: boolean | undefined;
32
+ }
33
+ /**
34
+ * A pre-styled OAuth sign-in button with provider logo.
35
+ *
36
+ * Must be rendered inside a `<SupatypeProvider>`.
37
+ */
38
+ export declare function OAuthButton({ provider, redirectTo, className, children, onError, popup, disabled, }: OAuthButtonProps): React.ReactElement;
39
+ //# sourceMappingURL=OAuthButton.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuthButton.d.ts","sourceRoot":"","sources":["../src/OAuthButton.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,EAAY,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAGvD,MAAM,WAAW,gBAAgB;IAC/B,8DAA8D;IAC9D,QAAQ,EAAE,MAAM,CAAA;IAChB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC/B,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,CAAA;IAChC,yCAAyC;IACzC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC5D,oEAAoE;IACpE,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC3B,6BAA6B;IAC7B,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAC/B;AAiBD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,UAAU,EACV,SAAS,EACT,QAAQ,EACR,OAAO,EACP,KAAK,EACL,QAAQ,GACT,EAAE,gBAAgB,GAAG,KAAK,CAAC,YAAY,CA8EvC"}
@@ -0,0 +1,86 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ /**
3
+ * OAuthButton component — Gap Appendices task 12
4
+ *
5
+ * Renders a styled sign-in button for an OAuth provider.
6
+ * Handles the full OAuth flow via `useAuth().signInWithOAuth()`.
7
+ *
8
+ * @example
9
+ * ```tsx
10
+ * <OAuthButton provider="github" />
11
+ * <OAuthButton provider="google" redirectTo="/dashboard" />
12
+ * <OAuthButton provider="apple" className="dark-btn">Sign in with Apple</OAuthButton>
13
+ * ```
14
+ */
15
+ import { useState } from "react";
16
+ import { useAuth } from "@supatype/react";
17
+ /** Capitalise the first letter of a string. */
18
+ function capitalize(s) {
19
+ return s.charAt(0).toUpperCase() + s.slice(1);
20
+ }
21
+ /** Provider logo SVGs (inline to avoid external dependencies). */
22
+ const PROVIDER_ICONS = {
23
+ github: '<svg viewBox="0 0 16 16" width="20" height="20" fill="currentColor"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/></svg>',
24
+ google: '<svg viewBox="0 0 24 24" width="20" height="20"><path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 01-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z"/><path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/><path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/><path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/></svg>',
25
+ apple: '<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.53-3.23 0-1.44.62-2.2.44-3.06-.4C3.79 16.17 4.36 9.33 8.93 9.07c1.23.07 2.09.72 2.81.77.99-.2 1.94-.78 3.01-.7 1.28.1 2.24.6 2.87 1.52-2.63 1.57-2 5.07.63 6.06-.5 1.3-.99 2.58-2.19 3.56zM12.03 9c-.12-2.08 1.55-3.82 3.47-3.97.26 2.29-2.07 4.01-3.47 3.97z"/></svg>',
26
+ };
27
+ /**
28
+ * A pre-styled OAuth sign-in button with provider logo.
29
+ *
30
+ * Must be rendered inside a `<SupatypeProvider>`.
31
+ */
32
+ export function OAuthButton({ provider, redirectTo, className, children, onError, popup, disabled, }) {
33
+ const { signInWithOAuth } = useAuth();
34
+ const [loading, setLoading] = useState(false);
35
+ const providerName = capitalize(provider);
36
+ const iconSvg = PROVIDER_ICONS[provider.toLowerCase()];
37
+ async function handleClick() {
38
+ setLoading(true);
39
+ try {
40
+ const { data, error } = await signInWithOAuth({
41
+ provider,
42
+ ...(redirectTo !== undefined && { options: { redirectTo } }),
43
+ });
44
+ if (error !== null) {
45
+ onError?.(error);
46
+ return;
47
+ }
48
+ if (data.url) {
49
+ if (popup === true) {
50
+ const width = 500;
51
+ const height = 700;
52
+ const left = window.screenX + (window.outerWidth - width) / 2;
53
+ const top = window.screenY + (window.outerHeight - height) / 2;
54
+ window.open(data.url, `supatype-oauth-${provider}`, `width=${width},height=${height},left=${left},top=${top}`);
55
+ }
56
+ else {
57
+ window.location.href = data.url;
58
+ }
59
+ }
60
+ }
61
+ catch (err) {
62
+ onError?.({ message: err instanceof Error ? err.message : "OAuth failed" });
63
+ }
64
+ finally {
65
+ setLoading(false);
66
+ }
67
+ }
68
+ const defaultStyle = {
69
+ display: "inline-flex",
70
+ alignItems: "center",
71
+ gap: "8px",
72
+ padding: "10px 16px",
73
+ border: "1px solid #d1d5db",
74
+ borderRadius: "6px",
75
+ backgroundColor: "#fff",
76
+ color: "#374151",
77
+ fontSize: "14px",
78
+ fontWeight: 500,
79
+ cursor: disabled === true || loading ? "not-allowed" : "pointer",
80
+ opacity: disabled === true || loading ? 0.6 : 1,
81
+ transition: "background-color 0.15s, border-color 0.15s",
82
+ lineHeight: 1,
83
+ };
84
+ return (_jsxs("button", { type: "button", className: className, style: className !== undefined ? undefined : defaultStyle, onClick: () => { void handleClick(); }, disabled: disabled === true || loading, "aria-label": `Sign in with ${providerName}`, children: [iconSvg !== undefined && (_jsx("span", { "aria-hidden": "true", dangerouslySetInnerHTML: { __html: iconSvg }, style: { display: "inline-flex", alignItems: "center" } })), children ?? (loading ? `Connecting to ${providerName}…` : `Sign in with ${providerName}`)] }));
85
+ }
86
+ //# sourceMappingURL=OAuthButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OAuthButton.js","sourceRoot":"","sources":["../src/OAuthButton.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import React from "react";
2
+ import type { Session, SupatypeError } from "@supatype/client";
3
+ export interface SignUpFormLabels {
4
+ title?: string | undefined;
5
+ email?: string | undefined;
6
+ password?: string | undefined;
7
+ submit?: string | undefined;
8
+ successMessage?: string | undefined;
9
+ }
10
+ export interface SignUpFormProps {
11
+ /** Called with the new session after a successful sign-up (or null if email confirmation is required). */
12
+ onSuccess?: ((session: Session | null) => void) | undefined;
13
+ /** Called with the error returned by the auth service. */
14
+ onError?: ((error: SupatypeError) => void) | undefined;
15
+ /** CSS class applied to the outermost <form> element. */
16
+ className?: string | undefined;
17
+ /** Override display labels. */
18
+ labels?: SignUpFormLabels | undefined;
19
+ /**
20
+ * Additional metadata stored on the user's `user_metadata`.
21
+ * Merge with any custom fields collected in the form.
22
+ */
23
+ metadata?: Record<string, unknown> | undefined;
24
+ }
25
+ /**
26
+ * A minimal, accessible sign-up form that integrates with `useAuth()`.
27
+ * Must be rendered inside a `<SupatypeProvider>`.
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * <SignUpForm
32
+ * onSuccess={(session) => {
33
+ * if (session) router.push('/dashboard')
34
+ * // else: show "check your email" state (email confirmation required)
35
+ * }}
36
+ * />
37
+ * ```
38
+ */
39
+ export declare function SignUpForm({ onSuccess, onError, className, labels, metadata }: SignUpFormProps): React.ReactElement;
40
+ //# sourceMappingURL=SignUpForm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignUpForm.d.ts","sourceRoot":"","sources":["../src/SignUpForm.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmC,MAAM,OAAO,CAAA;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAG9D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC7B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,0GAA0G;IAC1G,SAAS,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IAC3D,0DAA0D;IAC1D,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC,GAAG,SAAS,CAAA;IACtD,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IAC9B,+BAA+B;IAC/B,MAAM,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAA;IACrC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;CAC/C;AAUD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,UAAU,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,eAAe,GAAG,KAAK,CAAC,YAAY,CAqFnH"}
@@ -0,0 +1,64 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState } from "react";
3
+ import { useAuth } from "@supatype/react";
4
+ const DEFAULT_LABELS = {
5
+ title: "Create account",
6
+ email: "Email address",
7
+ password: "Password",
8
+ submit: "Create account",
9
+ successMessage: "Check your email to confirm your account.",
10
+ };
11
+ /**
12
+ * A minimal, accessible sign-up form that integrates with `useAuth()`.
13
+ * Must be rendered inside a `<SupatypeProvider>`.
14
+ *
15
+ * @example
16
+ * ```tsx
17
+ * <SignUpForm
18
+ * onSuccess={(session) => {
19
+ * if (session) router.push('/dashboard')
20
+ * // else: show "check your email" state (email confirmation required)
21
+ * }}
22
+ * />
23
+ * ```
24
+ */
25
+ export function SignUpForm({ onSuccess, onError, className, labels, metadata }) {
26
+ const { signUp } = useAuth();
27
+ const l = { ...DEFAULT_LABELS, ...labels };
28
+ const [email, setEmail] = useState("");
29
+ const [password, setPassword] = useState("");
30
+ const [loading, setLoading] = useState(false);
31
+ const [errorMessage, setErrorMessage] = useState(null);
32
+ const [confirmed, setConfirmed] = useState(false);
33
+ async function handleSubmit(e) {
34
+ e.preventDefault();
35
+ setErrorMessage(null);
36
+ setLoading(true);
37
+ try {
38
+ const { data, error } = await signUp({
39
+ email,
40
+ password,
41
+ ...(metadata !== undefined && { options: { data: metadata } }),
42
+ });
43
+ if (error !== null) {
44
+ setErrorMessage(error.message);
45
+ onError?.(error);
46
+ }
47
+ else {
48
+ if (data.session === null) {
49
+ // Email confirmation required
50
+ setConfirmed(true);
51
+ }
52
+ onSuccess?.(data.session);
53
+ }
54
+ }
55
+ finally {
56
+ setLoading(false);
57
+ }
58
+ }
59
+ if (confirmed) {
60
+ return (_jsx("p", { role: "status", "aria-live": "polite", children: l.successMessage }));
61
+ }
62
+ return (_jsxs("form", { onSubmit: (e) => { void handleSubmit(e); }, className: className, noValidate: true, children: [_jsx("h2", { children: l.title }), errorMessage !== null && (_jsx("p", { role: "alert", "aria-live": "polite", style: { color: "red" }, children: errorMessage })), _jsxs("div", { children: [_jsx("label", { htmlFor: "st-signup-email", children: l.email }), _jsx("input", { id: "st-signup-email", type: "email", autoComplete: "email", required: true, value: email, onChange: (e) => setEmail(e.target.value), disabled: loading })] }), _jsxs("div", { children: [_jsx("label", { htmlFor: "st-signup-password", children: l.password }), _jsx("input", { id: "st-signup-password", type: "password", autoComplete: "new-password", required: true, minLength: 8, value: password, onChange: (e) => setPassword(e.target.value), disabled: loading })] }), _jsx("button", { type: "submit", disabled: loading, children: loading ? "Creating account…" : l.submit })] }));
63
+ }
64
+ //# sourceMappingURL=SignUpForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignUpForm.js","sourceRoot":"","sources":["../src/SignUpForm.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export { LoginForm } from "./LoginForm.js";
2
+ export type { LoginFormProps, LoginFormLabels } from "./LoginForm.js";
3
+ export { SignUpForm } from "./SignUpForm.js";
4
+ export type { SignUpFormProps, SignUpFormLabels } from "./SignUpForm.js";
5
+ export { OAuthButton } from "./OAuthButton.js";
6
+ export type { OAuthButtonProps } from "./OAuthButton.js";
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAErE,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,YAAY,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAExE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { LoginForm } from "./LoginForm.js";
2
+ export { SignUpForm } from "./SignUpForm.js";
3
+ export { OAuthButton } from "./OAuthButton.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG1C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAG5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA"}
package/package.json ADDED
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "@supatype/react-auth",
3
+ "version": "0.1.0-alpha.10",
4
+ "description": "Pre-built authentication UI components for Supatype",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "types": "./dist/index.d.ts"
12
+ }
13
+ },
14
+ "dependencies": {
15
+ "@supatype/client": "0.1.0-alpha.10",
16
+ "@supatype/react": "0.1.0-alpha.10"
17
+ },
18
+ "peerDependencies": {
19
+ "react": ">=18"
20
+ },
21
+ "devDependencies": {
22
+ "@types/react": "^18",
23
+ "react": "^18",
24
+ "typescript": "^5",
25
+ "vitest": "^4.0.18"
26
+ },
27
+ "scripts": {
28
+ "build": "tsc",
29
+ "dev": "tsc --watch",
30
+ "typecheck": "tsc --noEmit",
31
+ "test": "vitest run --passWithNoTests",
32
+ "clean": "rm -rf dist *.tsbuildinfo"
33
+ }
34
+ }
@@ -0,0 +1,112 @@
1
+ import React, { useState, type FormEvent } from "react"
2
+ import type { Session, SupatypeError } from "@supatype/client"
3
+ import { useAuth } from "@supatype/react"
4
+
5
+ export interface LoginFormLabels {
6
+ title?: string | undefined
7
+ email?: string | undefined
8
+ password?: string | undefined
9
+ submit?: string | undefined
10
+ errorPrefix?: string | undefined
11
+ }
12
+
13
+ export interface LoginFormProps {
14
+ /** Called with the new session after a successful sign-in. */
15
+ onSuccess?: ((session: Session) => void) | undefined
16
+ /** Called with the error returned by the auth service. */
17
+ onError?: ((error: SupatypeError) => void) | undefined
18
+ /** CSS class applied to the outermost <form> element. */
19
+ className?: string | undefined
20
+ /** Override display labels. */
21
+ labels?: LoginFormLabels | undefined
22
+ }
23
+
24
+ const DEFAULT_LABELS: Required<LoginFormLabels> = {
25
+ title: "Sign in",
26
+ email: "Email address",
27
+ password: "Password",
28
+ submit: "Sign in",
29
+ errorPrefix: "",
30
+ }
31
+
32
+ /**
33
+ * A minimal, accessible login form that integrates with `useAuth()`.
34
+ * Must be rendered inside a `<SupatypeProvider>`.
35
+ *
36
+ * @example
37
+ * ```tsx
38
+ * <LoginForm
39
+ * onSuccess={(session) => router.push('/dashboard')}
40
+ * onError={(err) => console.error(err.message)}
41
+ * />
42
+ * ```
43
+ */
44
+ export function LoginForm({ onSuccess, onError, className, labels }: LoginFormProps): React.ReactElement {
45
+ const { signIn } = useAuth()
46
+ const l = { ...DEFAULT_LABELS, ...labels }
47
+
48
+ const [email, setEmail] = useState("")
49
+ const [password, setPassword] = useState("")
50
+ const [loading, setLoading] = useState(false)
51
+ const [errorMessage, setErrorMessage] = useState<string | null>(null)
52
+
53
+ async function handleSubmit(e: FormEvent<HTMLFormElement>): Promise<void> {
54
+ e.preventDefault()
55
+ setErrorMessage(null)
56
+ setLoading(true)
57
+ try {
58
+ const { data, error } = await signIn({ email, password })
59
+ if (error !== null) {
60
+ const msg = `${l.errorPrefix}${error.message}`
61
+ setErrorMessage(msg)
62
+ onError?.(error)
63
+ } else if (data.session !== null) {
64
+ onSuccess?.(data.session)
65
+ }
66
+ } finally {
67
+ setLoading(false)
68
+ }
69
+ }
70
+
71
+ return (
72
+ <form onSubmit={(e) => { void handleSubmit(e) }} className={className} noValidate>
73
+ <h2>{l.title}</h2>
74
+
75
+ {errorMessage !== null && (
76
+ <p role="alert" aria-live="polite" style={{ color: "red" }}>
77
+ {errorMessage}
78
+ </p>
79
+ )}
80
+
81
+ <div>
82
+ <label htmlFor="st-login-email">{l.email}</label>
83
+ <input
84
+ id="st-login-email"
85
+ type="email"
86
+ autoComplete="email"
87
+ required
88
+ value={email}
89
+ onChange={(e) => setEmail(e.target.value)}
90
+ disabled={loading}
91
+ />
92
+ </div>
93
+
94
+ <div>
95
+ <label htmlFor="st-login-password">{l.password}</label>
96
+ <input
97
+ id="st-login-password"
98
+ type="password"
99
+ autoComplete="current-password"
100
+ required
101
+ value={password}
102
+ onChange={(e) => setPassword(e.target.value)}
103
+ disabled={loading}
104
+ />
105
+ </div>
106
+
107
+ <button type="submit" disabled={loading}>
108
+ {loading ? "Signing in…" : l.submit}
109
+ </button>
110
+ </form>
111
+ )
112
+ }
@@ -0,0 +1,141 @@
1
+ /**
2
+ * OAuthButton component — Gap Appendices task 12
3
+ *
4
+ * Renders a styled sign-in button for an OAuth provider.
5
+ * Handles the full OAuth flow via `useAuth().signInWithOAuth()`.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * <OAuthButton provider="github" />
10
+ * <OAuthButton provider="google" redirectTo="/dashboard" />
11
+ * <OAuthButton provider="apple" className="dark-btn">Sign in with Apple</OAuthButton>
12
+ * ```
13
+ */
14
+
15
+ import React, { useState, type ReactNode } from "react"
16
+ import { useAuth } from "@supatype/react"
17
+
18
+ export interface OAuthButtonProps {
19
+ /** OAuth provider name (e.g. "github", "google", "apple"). */
20
+ provider: string
21
+ /** URL to redirect to after successful authentication. */
22
+ redirectTo?: string | undefined
23
+ /** CSS class applied to the button element. */
24
+ className?: string | undefined
25
+ /** Override the button content. Defaults to "Sign in with {Provider}". */
26
+ children?: ReactNode | undefined
27
+ /** Called when the OAuth flow errors. */
28
+ onError?: ((error: { message: string }) => void) | undefined
29
+ /** Whether to open the OAuth URL in a popup instead of redirect. */
30
+ popup?: boolean | undefined
31
+ /** Button disabled state. */
32
+ disabled?: boolean | undefined
33
+ }
34
+
35
+ /** Capitalise the first letter of a string. */
36
+ function capitalize(s: string): string {
37
+ return s.charAt(0).toUpperCase() + s.slice(1)
38
+ }
39
+
40
+ /** Provider logo SVGs (inline to avoid external dependencies). */
41
+ const PROVIDER_ICONS: Record<string, string> = {
42
+ github:
43
+ '<svg viewBox="0 0 16 16" width="20" height="20" fill="currentColor"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"/></svg>',
44
+ google:
45
+ '<svg viewBox="0 0 24 24" width="20" height="20"><path fill="#4285F4" d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 01-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z"/><path fill="#34A853" d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"/><path fill="#FBBC05" d="M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"/><path fill="#EA4335" d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"/></svg>',
46
+ apple:
47
+ '<svg viewBox="0 0 24 24" width="20" height="20" fill="currentColor"><path d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.53-3.23 0-1.44.62-2.2.44-3.06-.4C3.79 16.17 4.36 9.33 8.93 9.07c1.23.07 2.09.72 2.81.77.99-.2 1.94-.78 3.01-.7 1.28.1 2.24.6 2.87 1.52-2.63 1.57-2 5.07.63 6.06-.5 1.3-.99 2.58-2.19 3.56zM12.03 9c-.12-2.08 1.55-3.82 3.47-3.97.26 2.29-2.07 4.01-3.47 3.97z"/></svg>',
48
+ }
49
+
50
+ /**
51
+ * A pre-styled OAuth sign-in button with provider logo.
52
+ *
53
+ * Must be rendered inside a `<SupatypeProvider>`.
54
+ */
55
+ export function OAuthButton({
56
+ provider,
57
+ redirectTo,
58
+ className,
59
+ children,
60
+ onError,
61
+ popup,
62
+ disabled,
63
+ }: OAuthButtonProps): React.ReactElement {
64
+ const { signInWithOAuth } = useAuth()
65
+ const [loading, setLoading] = useState(false)
66
+
67
+ const providerName = capitalize(provider)
68
+ const iconSvg = PROVIDER_ICONS[provider.toLowerCase()]
69
+
70
+ async function handleClick(): Promise<void> {
71
+ setLoading(true)
72
+ try {
73
+ const { data, error } = await signInWithOAuth({
74
+ provider,
75
+ ...(redirectTo !== undefined && { options: { redirectTo } }),
76
+ })
77
+
78
+ if (error !== null) {
79
+ onError?.(error)
80
+ return
81
+ }
82
+
83
+ if (data.url) {
84
+ if (popup === true) {
85
+ const width = 500
86
+ const height = 700
87
+ const left = window.screenX + (window.outerWidth - width) / 2
88
+ const top = window.screenY + (window.outerHeight - height) / 2
89
+ window.open(
90
+ data.url,
91
+ `supatype-oauth-${provider}`,
92
+ `width=${width},height=${height},left=${left},top=${top}`,
93
+ )
94
+ } else {
95
+ window.location.href = data.url
96
+ }
97
+ }
98
+ } catch (err) {
99
+ onError?.({ message: err instanceof Error ? err.message : "OAuth failed" })
100
+ } finally {
101
+ setLoading(false)
102
+ }
103
+ }
104
+
105
+ const defaultStyle: React.CSSProperties = {
106
+ display: "inline-flex",
107
+ alignItems: "center",
108
+ gap: "8px",
109
+ padding: "10px 16px",
110
+ border: "1px solid #d1d5db",
111
+ borderRadius: "6px",
112
+ backgroundColor: "#fff",
113
+ color: "#374151",
114
+ fontSize: "14px",
115
+ fontWeight: 500,
116
+ cursor: disabled === true || loading ? "not-allowed" : "pointer",
117
+ opacity: disabled === true || loading ? 0.6 : 1,
118
+ transition: "background-color 0.15s, border-color 0.15s",
119
+ lineHeight: 1,
120
+ }
121
+
122
+ return (
123
+ <button
124
+ type="button"
125
+ className={className}
126
+ style={className !== undefined ? undefined : defaultStyle}
127
+ onClick={() => { void handleClick() }}
128
+ disabled={disabled === true || loading}
129
+ aria-label={`Sign in with ${providerName}`}
130
+ >
131
+ {iconSvg !== undefined && (
132
+ <span
133
+ aria-hidden="true"
134
+ dangerouslySetInnerHTML={{ __html: iconSvg }}
135
+ style={{ display: "inline-flex", alignItems: "center" }}
136
+ />
137
+ )}
138
+ {children ?? (loading ? `Connecting to ${providerName}…` : `Sign in with ${providerName}`)}
139
+ </button>
140
+ )
141
+ }
@@ -0,0 +1,136 @@
1
+ import React, { useState, type FormEvent } from "react"
2
+ import type { Session, SupatypeError } from "@supatype/client"
3
+ import { useAuth } from "@supatype/react"
4
+
5
+ export interface SignUpFormLabels {
6
+ title?: string | undefined
7
+ email?: string | undefined
8
+ password?: string | undefined
9
+ submit?: string | undefined
10
+ successMessage?: string | undefined
11
+ }
12
+
13
+ export interface SignUpFormProps {
14
+ /** Called with the new session after a successful sign-up (or null if email confirmation is required). */
15
+ onSuccess?: ((session: Session | null) => void) | undefined
16
+ /** Called with the error returned by the auth service. */
17
+ onError?: ((error: SupatypeError) => void) | undefined
18
+ /** CSS class applied to the outermost <form> element. */
19
+ className?: string | undefined
20
+ /** Override display labels. */
21
+ labels?: SignUpFormLabels | undefined
22
+ /**
23
+ * Additional metadata stored on the user's `user_metadata`.
24
+ * Merge with any custom fields collected in the form.
25
+ */
26
+ metadata?: Record<string, unknown> | undefined
27
+ }
28
+
29
+ const DEFAULT_LABELS: Required<SignUpFormLabels> = {
30
+ title: "Create account",
31
+ email: "Email address",
32
+ password: "Password",
33
+ submit: "Create account",
34
+ successMessage: "Check your email to confirm your account.",
35
+ }
36
+
37
+ /**
38
+ * A minimal, accessible sign-up form that integrates with `useAuth()`.
39
+ * Must be rendered inside a `<SupatypeProvider>`.
40
+ *
41
+ * @example
42
+ * ```tsx
43
+ * <SignUpForm
44
+ * onSuccess={(session) => {
45
+ * if (session) router.push('/dashboard')
46
+ * // else: show "check your email" state (email confirmation required)
47
+ * }}
48
+ * />
49
+ * ```
50
+ */
51
+ export function SignUpForm({ onSuccess, onError, className, labels, metadata }: SignUpFormProps): React.ReactElement {
52
+ const { signUp } = useAuth()
53
+ const l = { ...DEFAULT_LABELS, ...labels }
54
+
55
+ const [email, setEmail] = useState("")
56
+ const [password, setPassword] = useState("")
57
+ const [loading, setLoading] = useState(false)
58
+ const [errorMessage, setErrorMessage] = useState<string | null>(null)
59
+ const [confirmed, setConfirmed] = useState(false)
60
+
61
+ async function handleSubmit(e: FormEvent<HTMLFormElement>): Promise<void> {
62
+ e.preventDefault()
63
+ setErrorMessage(null)
64
+ setLoading(true)
65
+ try {
66
+ const { data, error } = await signUp({
67
+ email,
68
+ password,
69
+ ...(metadata !== undefined && { options: { data: metadata } }),
70
+ })
71
+ if (error !== null) {
72
+ setErrorMessage(error.message)
73
+ onError?.(error)
74
+ } else {
75
+ if (data.session === null) {
76
+ // Email confirmation required
77
+ setConfirmed(true)
78
+ }
79
+ onSuccess?.(data.session)
80
+ }
81
+ } finally {
82
+ setLoading(false)
83
+ }
84
+ }
85
+
86
+ if (confirmed) {
87
+ return (
88
+ <p role="status" aria-live="polite">
89
+ {l.successMessage}
90
+ </p>
91
+ )
92
+ }
93
+
94
+ return (
95
+ <form onSubmit={(e) => { void handleSubmit(e) }} className={className} noValidate>
96
+ <h2>{l.title}</h2>
97
+
98
+ {errorMessage !== null && (
99
+ <p role="alert" aria-live="polite" style={{ color: "red" }}>
100
+ {errorMessage}
101
+ </p>
102
+ )}
103
+
104
+ <div>
105
+ <label htmlFor="st-signup-email">{l.email}</label>
106
+ <input
107
+ id="st-signup-email"
108
+ type="email"
109
+ autoComplete="email"
110
+ required
111
+ value={email}
112
+ onChange={(e) => setEmail(e.target.value)}
113
+ disabled={loading}
114
+ />
115
+ </div>
116
+
117
+ <div>
118
+ <label htmlFor="st-signup-password">{l.password}</label>
119
+ <input
120
+ id="st-signup-password"
121
+ type="password"
122
+ autoComplete="new-password"
123
+ required
124
+ minLength={8}
125
+ value={password}
126
+ onChange={(e) => setPassword(e.target.value)}
127
+ disabled={loading}
128
+ />
129
+ </div>
130
+
131
+ <button type="submit" disabled={loading}>
132
+ {loading ? "Creating account…" : l.submit}
133
+ </button>
134
+ </form>
135
+ )
136
+ }
package/src/index.ts ADDED
@@ -0,0 +1,8 @@
1
+ export { LoginForm } from "./LoginForm.js"
2
+ export type { LoginFormProps, LoginFormLabels } from "./LoginForm.js"
3
+
4
+ export { SignUpForm } from "./SignUpForm.js"
5
+ export type { SignUpFormProps, SignUpFormLabels } from "./SignUpForm.js"
6
+
7
+ export { OAuthButton } from "./OAuthButton.js"
8
+ export type { OAuthButtonProps } from "./OAuthButton.js"
package/tsconfig.json ADDED
@@ -0,0 +1,15 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist",
5
+ "rootDir": "src",
6
+ "composite": true,
7
+ "lib": ["ES2022", "DOM"],
8
+ "jsx": "react-jsx"
9
+ },
10
+ "include": ["src"],
11
+ "references": [
12
+ { "path": "../client" },
13
+ { "path": "../react" }
14
+ ]
15
+ }
@@ -0,0 +1 @@
1
+ {"fileNames":["../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es5.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.dom.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.core.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.collection.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.generator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.iterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.proxy.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.reflect.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.array.include.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2016.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2018.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.symbol.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2019.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.bigint.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.date.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2020.number.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.promise.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.weakref.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2021.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.array.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.error.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.intl.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.object.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.string.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.es2022.regexp.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.d.ts","../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/lib.decorators.legacy.d.ts","../../node_modules/.pnpm/@types+react@18.3.28/node_modules/@types/react/global.d.ts","../../node_modules/.pnpm/csstype@3.2.3/node_modules/csstype/index.d.ts","../../node_modules/.pnpm/@types+prop-types@15.7.15/node_modules/@types/prop-types/index.d.ts","../../node_modules/.pnpm/@types+react@18.3.28/node_modules/@types/react/index.d.ts","../../node_modules/.pnpm/@types+react@18.3.28/node_modules/@types/react/jsx-runtime.d.ts","../client/dist/types.d.ts","../client/dist/auth.d.ts","../client/dist/query.d.ts","../client/dist/storage.d.ts","../client/dist/realtime.d.ts","../client/dist/errors.d.ts","../client/dist/fetch-with-retry.d.ts","../client/dist/retry.d.ts","../client/dist/error-codes-doc.d.ts","../client/dist/serverless-docs.d.ts","../client/dist/index.d.ts","../react/dist/context.d.ts","../react/dist/useAuth.d.ts","../react/dist/useQuery.d.ts","../react/dist/useMutation.d.ts","../react/dist/useSubscription.d.ts","../react/dist/useLivePreview.d.ts","../react/dist/useFunction.d.ts","../common/dist/richtext.d.ts","../react/dist/RichText.d.ts","../react/dist/index.d.ts","./src/LoginForm.tsx","./src/OAuthButton.tsx","./src/SignUpForm.tsx","./src/index.ts"],"fileIdsList":[[59,60,61],[62],[64],[64,65,66,67,68,69,70,71,72,73],[70],[62,63,74,84],[62,63,84],[63,85,86,87],[82],[62,74],[75,76,77,78,79,80,81,83],[74]],"fileInfos":[{"version":"c430d44666289dae81f30fa7b2edebf186ecc91a2d4c71266ea6ae76388792e1","affectsGlobalScope":true,"impliedFormat":1},{"version":"45b7ab580deca34ae9729e97c13cfd999df04416a79116c3bfb483804f85ded4","impliedFormat":1},{"version":"3facaf05f0c5fc569c5649dd359892c98a85557e3e0c847964caeb67076f4d75","impliedFormat":1},{"version":"e44bb8bbac7f10ecc786703fe0a6a4b952189f908707980ba8f3c8975a760962","impliedFormat":1},{"version":"5e1c4c362065a6b95ff952c0eab010f04dcd2c3494e813b493ecfd4fcb9fc0d8","impliedFormat":1},{"version":"68d73b4a11549f9c0b7d352d10e91e5dca8faa3322bfb77b661839c42b1ddec7","impliedFormat":1},{"version":"5efce4fc3c29ea84e8928f97adec086e3dc876365e0982cc8479a07954a3efd4","impliedFormat":1},{"version":"feecb1be483ed332fad555aff858affd90a48ab19ba7272ee084704eb7167569","impliedFormat":1},{"version":"ee7bad0c15b58988daa84371e0b89d313b762ab83cb5b31b8a2d1162e8eb41c2","impliedFormat":1},{"version":"080941d9f9ff9307f7e27a83bcd888b7c8270716c39af943532438932ec1d0b9","affectsGlobalScope":true,"impliedFormat":1},{"version":"c57796738e7f83dbc4b8e65132f11a377649c00dd3eee333f672b8f0a6bea671","affectsGlobalScope":true,"impliedFormat":1},{"version":"dc2df20b1bcdc8c2d34af4926e2c3ab15ffe1160a63e58b7e09833f616efff44","affectsGlobalScope":true,"impliedFormat":1},{"version":"515d0b7b9bea2e31ea4ec968e9edd2c39d3eebf4a2d5cbd04e88639819ae3b71","affectsGlobalScope":true,"impliedFormat":1},{"version":"0559b1f683ac7505ae451f9a96ce4c3c92bdc71411651ca6ddb0e88baaaad6a3","affectsGlobalScope":true,"impliedFormat":1},{"version":"0dc1e7ceda9b8b9b455c3a2d67b0412feab00bd2f66656cd8850e8831b08b537","affectsGlobalScope":true,"impliedFormat":1},{"version":"ce691fb9e5c64efb9547083e4a34091bcbe5bdb41027e310ebba8f7d96a98671","affectsGlobalScope":true,"impliedFormat":1},{"version":"8d697a2a929a5fcb38b7a65594020fcef05ec1630804a33748829c5ff53640d0","affectsGlobalScope":true,"impliedFormat":1},{"version":"4ff2a353abf8a80ee399af572debb8faab2d33ad38c4b4474cff7f26e7653b8d","affectsGlobalScope":true,"impliedFormat":1},{"version":"fb0f136d372979348d59b3f5020b4cdb81b5504192b1cacff5d1fbba29378aa1","affectsGlobalScope":true,"impliedFormat":1},{"version":"d15bea3d62cbbdb9797079416b8ac375ae99162a7fba5de2c6c505446486ac0a","affectsGlobalScope":true,"impliedFormat":1},{"version":"68d18b664c9d32a7336a70235958b8997ebc1c3b8505f4f1ae2b7e7753b87618","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb3d66c8327153d8fa7dd03f9c58d351107fe824c79e9b56b462935176cdf12a","affectsGlobalScope":true,"impliedFormat":1},{"version":"38f0219c9e23c915ef9790ab1d680440d95419ad264816fa15009a8851e79119","affectsGlobalScope":true,"impliedFormat":1},{"version":"69ab18c3b76cd9b1be3d188eaf8bba06112ebbe2f47f6c322b5105a6fbc45a2e","affectsGlobalScope":true,"impliedFormat":1},{"version":"a680117f487a4d2f30ea46f1b4b7f58bef1480456e18ba53ee85c2746eeca012","affectsGlobalScope":true,"impliedFormat":1},{"version":"2f11ff796926e0832f9ae148008138ad583bd181899ab7dd768a2666700b1893","affectsGlobalScope":true,"impliedFormat":1},{"version":"4de680d5bb41c17f7f68e0419412ca23c98d5749dcaaea1896172f06435891fc","affectsGlobalScope":true,"impliedFormat":1},{"version":"954296b30da6d508a104a3a0b5d96b76495c709785c1d11610908e63481ee667","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac9538681b19688c8eae65811b329d3744af679e0bdfa5d842d0e32524c73e1c","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a969edff4bd52585473d24995c5ef223f6652d6ef46193309b3921d65dd4376","affectsGlobalScope":true,"impliedFormat":1},{"version":"9e9fbd7030c440b33d021da145d3232984c8bb7916f277e8ffd3dc2e3eae2bdb","affectsGlobalScope":true,"impliedFormat":1},{"version":"811ec78f7fefcabbda4bfa93b3eb67d9ae166ef95f9bff989d964061cbf81a0c","affectsGlobalScope":true,"impliedFormat":1},{"version":"717937616a17072082152a2ef351cb51f98802fb4b2fdabd32399843875974ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"d7e7d9b7b50e5f22c915b525acc5a49a7a6584cf8f62d0569e557c5cfc4b2ac2","affectsGlobalScope":true,"impliedFormat":1},{"version":"71c37f4c9543f31dfced6c7840e068c5a5aacb7b89111a4364b1d5276b852557","affectsGlobalScope":true,"impliedFormat":1},{"version":"576711e016cf4f1804676043e6a0a5414252560eb57de9faceee34d79798c850","affectsGlobalScope":true,"impliedFormat":1},{"version":"89c1b1281ba7b8a96efc676b11b264de7a8374c5ea1e6617f11880a13fc56dc6","affectsGlobalScope":true,"impliedFormat":1},{"version":"74f7fa2d027d5b33eb0471c8e82a6c87216223181ec31247c357a3e8e2fddc5b","affectsGlobalScope":true,"impliedFormat":1},{"version":"d6d7ae4d1f1f3772e2a3cde568ed08991a8ae34a080ff1151af28b7f798e22ca","affectsGlobalScope":true,"impliedFormat":1},{"version":"063600664504610fe3e99b717a1223f8b1900087fab0b4cad1496a114744f8df","affectsGlobalScope":true,"impliedFormat":1},{"version":"934019d7e3c81950f9a8426d093458b65d5aff2c7c1511233c0fd5b941e608ab","affectsGlobalScope":true,"impliedFormat":1},{"version":"52ada8e0b6e0482b728070b7639ee42e83a9b1c22d205992756fe020fd9f4a47","affectsGlobalScope":true,"impliedFormat":1},{"version":"3bdefe1bfd4d6dee0e26f928f93ccc128f1b64d5d501ff4a8cf3c6371200e5e6","affectsGlobalScope":true,"impliedFormat":1},{"version":"59fb2c069260b4ba00b5643b907ef5d5341b167e7d1dbf58dfd895658bda2867","affectsGlobalScope":true,"impliedFormat":1},{"version":"639e512c0dfc3fad96a84caad71b8834d66329a1f28dc95e3946c9b58176c73a","affectsGlobalScope":true,"impliedFormat":1},{"version":"368af93f74c9c932edd84c58883e736c9e3d53cec1fe24c0b0ff451f529ceab1","affectsGlobalScope":true,"impliedFormat":1},{"version":"af3dd424cf267428f30ccfc376f47a2c0114546b55c44d8c0f1d57d841e28d74","affectsGlobalScope":true,"impliedFormat":1},{"version":"995c005ab91a498455ea8dfb63aa9f83fa2ea793c3d8aa344be4a1678d06d399","affectsGlobalScope":true,"impliedFormat":1},{"version":"959d36cddf5e7d572a65045b876f2956c973a586da58e5d26cde519184fd9b8a","affectsGlobalScope":true,"impliedFormat":1},{"version":"965f36eae237dd74e6cca203a43e9ca801ce38824ead814728a2807b1910117d","affectsGlobalScope":true,"impliedFormat":1},{"version":"3925a6c820dcb1a06506c90b1577db1fdbf7705d65b62b99dce4be75c637e26b","affectsGlobalScope":true,"impliedFormat":1},{"version":"0a3d63ef2b853447ec4f749d3f368ce642264246e02911fcb1590d8c161b8005","affectsGlobalScope":true,"impliedFormat":1},{"version":"8cdf8847677ac7d20486e54dd3fcf09eda95812ac8ace44b4418da1bbbab6eb8","affectsGlobalScope":true,"impliedFormat":1},{"version":"8444af78980e3b20b49324f4a16ba35024fef3ee069a0eb67616ea6ca821c47a","affectsGlobalScope":true,"impliedFormat":1},{"version":"3287d9d085fbd618c3971944b65b4be57859f5415f495b33a6adc994edd2f004","affectsGlobalScope":true,"impliedFormat":1},{"version":"b4b67b1a91182421f5df999988c690f14d813b9850b40acd06ed44691f6727ad","affectsGlobalScope":true,"impliedFormat":1},{"version":"8e7f8264d0fb4c5339605a15daadb037bf238c10b654bb3eee14208f860a32ea","affectsGlobalScope":true,"impliedFormat":1},{"version":"782dec38049b92d4e85c1585fbea5474a219c6984a35b004963b00beb1aab538","affectsGlobalScope":true,"impliedFormat":1},{"version":"eb5b19b86227ace1d29ea4cf81387279d04bb34051e944bc53df69f58914b788","affectsGlobalScope":true,"impliedFormat":1},{"version":"ac51dd7d31333793807a6abaa5ae168512b6131bd41d9c5b98477fc3b7800f9f","impliedFormat":1},{"version":"87d9d29dbc745f182683f63187bf3d53fd8673e5fca38ad5eaab69798ed29fbc","impliedFormat":1},{"version":"035312d4945d13efa134ae482f6dc56a1a9346f7ac3be7ccbad5741058ce87f3","affectsGlobalScope":true,"impliedFormat":1},{"version":"42c169fb8c2d42f4f668c624a9a11e719d5d07dacbebb63cbcf7ef365b0a75b3","impliedFormat":1},{"version":"d3ed160939e7f93a97a35a37c42cad50799885f564a7b3957c9e9f1221ced9e7","impliedFormat":99},{"version":"d58e244c6d3aa676939aaa26e7bc5c6de22e408c195f69ee118eddd68377d17c","impliedFormat":99},{"version":"20fac2f073582881eeccdd3b04819084684fd296f3d6a0fa53e48ed3de83d35a","impliedFormat":99},{"version":"e5363db20ce3327d96a0e8c9a326259764eaf94e2b34eee3c74e5e6a988e5532","impliedFormat":99},{"version":"00f9fbcf8c7f9957b087eb4922fc153085c112d7f386c2cc211995a47fe7e07e","impliedFormat":99},{"version":"1600ade5611547c843e1da83f4180fa9d63e76f86503ac94e10ae55d87bfda02","impliedFormat":99},{"version":"ccbb4f957666793ea28e67b0748ba838841e641330b661bae31a5974612c73fd","impliedFormat":99},{"version":"9143a4409f10ae9f6362706e00e3b7ed082d4b2af0125aab31ecd30a6fefab13","impliedFormat":99},{"version":"6c9f37788061375db19a85ad684e2e08c5d0517200fae8479226ed1e82034ed1","impliedFormat":99},{"version":"e0856e33bfa821d4ab90b555ec6311122f178620eceb8effcaf6344abdb0bb75","impliedFormat":99},{"version":"509349be18cb0f2a92947dca43f5cd0af31ba579ebf8c75d2d2abb48a82f9042","impliedFormat":99},{"version":"60bc45a46375841866b4be2088eac855464111191416c247c2bf0d30be66d579","impliedFormat":99},{"version":"4806daa9b45e8a9f5ac373ae533468e87591e97445cc4fa97266464683d25e02","impliedFormat":99},{"version":"8263b5606f7be5da380c3e951af1b87ea8ce184e01a51ee4ff359de371a6944f","impliedFormat":99},{"version":"cdb119723adb015f336be9ac2b0e556986daa627979b18afb342c529c344c5df","impliedFormat":99},{"version":"8f1b82dc11ef7b941afd66bee1345889e8ebe1ad543327f7bd1f8820f70b50d3","impliedFormat":99},{"version":"be76a7e39d655a7cdc290b5e448be812a5b1b63f230edbf311ee93c256bd98e3","impliedFormat":99},{"version":"8aa85b87712861a0e0e686d40b1fddb1777000e2454c0d253d1fe632291e2383","impliedFormat":99},{"version":"7bbe9cbb32187cf2a13609fc52dee76a1410d6370bbe631ac10ae84cc0b9d2ce","impliedFormat":99},{"version":"a506ed055c8889bcf3935d785c3dc7585751be923f1741cc0e95a84922d21aeb","impliedFormat":99},{"version":"1e0d0a9cc354e824e91947a00dbbdb5edb03aa92f7cccd772fe64526698cf462","impliedFormat":99},{"version":"17e8f5961eb42d3c1da6145f6946c4a8aaf5d9a9803070462a35622e2d4581e0","signature":"3a9db083ad448d8b26148581656b584fda330c606dcf1672f946fa0c1fa1b7f4","impliedFormat":99},{"version":"58adb1e9ebd5af37422e980aac20230b93bd5ad57343342dad1ac6996fdcb0f9","signature":"669ddace1dcb6f35e6021e0a6cc8f35a96d9bc660ab3ec102d63d21286d17531","impliedFormat":99},{"version":"6df49eec5a9e73e0043f3cd71051cd5c04082dbb2cda020bdc875567a279e964","signature":"25dba25444cb8a21e4cc65550ab00f9656fb6d867fe5764851c175645a38c61e","impliedFormat":99},{"version":"5678c4f29219aa20a0a273ce455dafc32bea2e736be25bea153e8a10ec22a1c5","signature":"eb3cad4617b598ef006bd718ec11994d67127f2e569a3843b14c63d06b23b4fa","impliedFormat":99}],"root":[[85,88]],"options":{"composite":true,"declaration":true,"declarationMap":true,"esModuleInterop":true,"exactOptionalPropertyTypes":true,"jsx":4,"module":199,"noUncheckedIndexedAccess":true,"outDir":"./dist","rootDir":"./src","skipLibCheck":true,"sourceMap":true,"strict":true,"target":9},"referencedMap":[[62,1],[63,2],[65,3],[74,4],[66,3],[71,5],[67,3],[85,6],[86,7],[87,6],[88,8],[83,9],[75,10],[84,11],[76,12],[81,12],[78,12],[77,12],[79,12]],"latestChangedDtsFile":"./dist/index.d.ts","version":"5.9.3"}