1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-11-20 12:02:22 +03:00

Confirm destructive actions (#1759)

Co-authored-by: Quentin Gliech <quenting@element.io>
This commit is contained in:
Kerry
2023-09-15 00:35:09 +12:00
committed by GitHub
parent aa5b91f3de
commit e19002a0ca
19 changed files with 3316 additions and 6172 deletions

View File

@@ -10,6 +10,7 @@
"dependencies": { "dependencies": {
"@emotion/react": "^11.11.1", "@emotion/react": "^11.11.1",
"@fontsource/inter": "^5.0.8", "@fontsource/inter": "^5.0.8",
"@radix-ui/react-alert-dialog": "^1.0.4",
"@types/ua-parser-js": "^0.7.37", "@types/ua-parser-js": "^0.7.37",
"@urql/core": "^4.1.2", "@urql/core": "^4.1.2",
"@urql/devtools": "^2.0.3", "@urql/devtools": "^2.0.3",
@@ -5592,6 +5593,34 @@
"@babel/runtime": "^7.13.10" "@babel/runtime": "^7.13.10"
} }
}, },
"node_modules/@radix-ui/react-alert-dialog": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.0.4.tgz",
"integrity": "sha512-jbfBCRlKYlhbitueOAv7z74PXYeIQmWpKwm3jllsdkw7fGWNkxqP3v0nY9WmOzcPqpQuoorNtvViBgL46n5gVg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-dialog": "1.0.4",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-slot": "1.0.2"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-arrow": { "node_modules/@radix-ui/react-arrow": {
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.0.3.tgz",
@@ -5676,6 +5705,66 @@
} }
} }
}, },
"node_modules/@radix-ui/react-dialog": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.4.tgz",
"integrity": "sha512-hJtRy/jPULGQZceSAP2Re6/4NpKo8im6V8P2hUqZsdFiSL8l35kYsw3qbRI6Ay5mQd2+wlLqje770eq+RJ3yZg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "1.0.1",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-context": "1.0.1",
"@radix-ui/react-dismissable-layer": "1.0.4",
"@radix-ui/react-focus-guards": "1.0.1",
"@radix-ui/react-focus-scope": "1.0.3",
"@radix-ui/react-id": "1.0.1",
"@radix-ui/react-portal": "1.0.3",
"@radix-ui/react-presence": "1.0.1",
"@radix-ui/react-primitive": "1.0.3",
"@radix-ui/react-slot": "1.0.2",
"@radix-ui/react-use-controllable-state": "1.0.1",
"aria-hidden": "^1.1.1",
"react-remove-scroll": "2.5.5"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-presence": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.1.tgz",
"integrity": "sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.1",
"@radix-ui/react-use-layout-effect": "1.0.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0",
"react-dom": "^16.8 || ^17.0 || ^18.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-direction": { "node_modules/@radix-ui/react-direction": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.1.tgz",
@@ -5725,7 +5814,6 @@
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.1.tgz",
"integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==", "integrity": "sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==",
"dev": true,
"dependencies": { "dependencies": {
"@babel/runtime": "^7.13.10" "@babel/runtime": "^7.13.10"
}, },
@@ -5743,7 +5831,6 @@
"version": "1.0.3", "version": "1.0.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.3.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.3.tgz",
"integrity": "sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ==", "integrity": "sha512-upXdPfqI4islj2CslyfUBNlaJCPybbqRHAi1KER7Isel9Q2AtSJ0zRBZv8mWQiFXD2nyAJ4BhC3yXgZ6kMBSrQ==",
"dev": true,
"dependencies": { "dependencies": {
"@babel/runtime": "^7.13.10", "@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "1.0.1", "@radix-ui/react-compose-refs": "1.0.1",

View File

@@ -17,6 +17,7 @@
"dependencies": { "dependencies": {
"@emotion/react": "^11.11.1", "@emotion/react": "^11.11.1",
"@fontsource/inter": "^5.0.8", "@fontsource/inter": "^5.0.8",
"@radix-ui/react-alert-dialog": "^1.0.4",
"@types/ua-parser-js": "^0.7.37", "@types/ua-parser-js": "^0.7.37",
"@urql/core": "^4.1.2", "@urql/core": "^4.1.2",
"@urql/devtools": "^2.0.3", "@urql/devtools": "^2.0.3",

View File

@@ -12,10 +12,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// @vitest-environment happy-dom
import { create } from "react-test-renderer"; import { create } from "react-test-renderer";
import { describe, expect, it, vi } from "vitest"; import { describe, expect, it, vi } from "vitest";
import { FragmentType } from "../gql/fragment-masking"; import { FragmentType } from "../gql/fragment-masking";
import { WithLocation } from "../test-utils/WithLocation";
import CompatSession, { COMPAT_SESSION_FRAGMENT } from "./CompatSession"; import CompatSession, { COMPAT_SESSION_FRAGMENT } from "./CompatSession";
import DateTime from "./DateTime"; import DateTime from "./DateTime";
@@ -42,7 +45,11 @@ describe("<CompatSession />", () => {
const finishedAt = "2023-06-29T03:35:19.451292+00:00"; const finishedAt = "2023-06-29T03:35:19.451292+00:00";
it("renders an active session", () => { it("renders an active session", () => {
const component = create(<CompatSession session={session} />); const component = create(
<WithLocation>
<CompatSession session={session} />
</WithLocation>,
);
expect(component.toJSON()).toMatchSnapshot(); expect(component.toJSON()).toMatchSnapshot();
}); });
@@ -51,7 +58,11 @@ describe("<CompatSession />", () => {
...session, ...session,
finishedAt, finishedAt,
}; };
const component = create(<CompatSession session={finishedSession} />); const component = create(
<WithLocation>
<CompatSession session={finishedSession} />
</WithLocation>,
);
expect(component.toJSON()).toMatchSnapshot(); expect(component.toJSON()).toMatchSnapshot();
}); });
}); });

View File

@@ -0,0 +1,42 @@
/* Copyright 2023 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
.buttons {
display: flex;
flex-direction: row;
justify-content: flex-end;
gap: var(--cpd-space-2x);
}
.overlay {
position: fixed;
inset: 0;
background-color: #666;
opacity: 0.4;
}
.content {
position: fixed;
margin: auto;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/* less than the magic 378 content width set in Layout */
width: 300px;
padding: var(--cpd-space-4x);
border-radius: var(--cpd-space-2x);
background-color: var(--cpd-color-bg-canvas-default);
border: 1px solid var(--cpd-color-border-interactive-primary);
}

View File

@@ -0,0 +1,167 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// @vitest-environment happy-dom
import { render, cleanup, screen, fireEvent } from "@testing-library/react";
import { describe, expect, it, afterEach, vi } from "vitest";
import ConfirmationModal from "./ConfirmationModal";
describe("<ConfirmationModal />", () => {
afterEach(cleanup);
const trigger = <button>Open modal</button>;
it("does not render a closed modal", () => {
const onConfirm = vi.fn();
const onDeny = vi.fn();
render(
<ConfirmationModal
onConfirm={onConfirm}
onDeny={onDeny}
className="test"
trigger={trigger}
title="Are you sure?"
>
Some extra information.
</ConfirmationModal>,
);
expect(screen.getByText("Open modal")).toBeTruthy();
expect(screen.queryByRole("alertdialog")).toBeFalsy();
});
it("opens modal on clicking trigger", () => {
const onConfirm = vi.fn();
const onDeny = vi.fn();
render(
<ConfirmationModal
onConfirm={onConfirm}
onDeny={onDeny}
className="test"
trigger={trigger}
title="Are you sure?"
>
Some extra information.
</ConfirmationModal>,
);
fireEvent.click(screen.getByText("Open modal"));
expect(screen.getByRole("alertdialog")).toMatchSnapshot();
});
it("renders an undeniable modal", () => {
const onConfirm = vi.fn();
const onDeny = undefined;
render(
<ConfirmationModal
onConfirm={onConfirm}
onDeny={onDeny}
className="test"
trigger={trigger}
title="Are you sure?"
>
Some extra information.
</ConfirmationModal>,
);
fireEvent.click(screen.getByText("Open modal"));
// no cancel button without onDeny
expect(screen.queryByText("Cancel")).toBeFalsy();
});
it("calls onConfirm on confirmation", () => {
const onConfirm = vi.fn();
const onDeny = vi.fn();
render(
<ConfirmationModal
onConfirm={onConfirm}
onDeny={onDeny}
className="test"
trigger={trigger}
title="Are you sure?"
>
Some extra information.
</ConfirmationModal>,
);
fireEvent.click(screen.getByText("Open modal"));
fireEvent.click(screen.getByText("Continue"));
expect(onConfirm).toHaveBeenCalled();
// dialog closed
expect(screen.queryByRole("alertdialog")).toBeFalsy();
});
it("calls onDeny on cancel click", () => {
const onConfirm = vi.fn();
const onDeny = vi.fn();
render(
<ConfirmationModal
onConfirm={onConfirm}
onDeny={onDeny}
className="test"
trigger={trigger}
title="Are you sure?"
>
Some extra information.
</ConfirmationModal>,
);
fireEvent.click(screen.getByText("Open modal"));
fireEvent.click(screen.getByText("Cancel"));
expect(onDeny).toHaveBeenCalled();
// dialog closed
expect(screen.queryByRole("alertdialog")).toBeFalsy();
});
it("calls onDeny on closing modal via Esc", () => {
const onConfirm = vi.fn();
const onDeny = vi.fn();
render(
<ConfirmationModal
onConfirm={onConfirm}
onDeny={onDeny}
className="test"
trigger={trigger}
title="Are you sure?"
>
Some extra information.
</ConfirmationModal>,
);
fireEvent.click(screen.getByText("Open modal"));
fireEvent.keyDown(screen.getByRole("alertdialog"), {
key: "Escape",
code: "Escape",
keyCode: 27,
});
expect(onDeny).toHaveBeenCalled();
// dialog closed
expect(screen.queryByRole("alertdialog")).toBeFalsy();
});
});

View File

@@ -0,0 +1,106 @@
// Copyright 2023 The Matrix.org Foundation C.I.C.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import {
Root,
Portal,
Overlay,
Content,
Trigger,
Title,
Description,
Action,
Cancel,
} from "@radix-ui/react-alert-dialog";
import { Button } from "@vector-im/compound-web";
import classNames from "classnames";
import { ReactNode, useState } from "react";
import styles from "./ConfirmationModal.module.css";
type Props = {
onConfirm: () => void;
onDeny?: () => void;
title?: ReactNode | string;
// element used to trigger opening of modal
trigger: ReactNode;
className?: string;
};
/**
* Generic confirmation modal
* controls its own open state
* calls onDeny on cancel, esc, or overlay click
* calls onConfirm on confirm click
*/
const ConfirmationModal: React.FC<React.PropsWithChildren<Props>> = ({
onConfirm,
onDeny,
className,
children,
trigger,
title,
}) => {
const [isOpen, setIsOpen] = useState(false);
const onClose = (callback?: () => void) => (): void => {
setIsOpen(false);
callback?.();
};
// radix's autofocus doesn't work for some reason
// maybe https://www.radix-ui.com/primitives/docs/guides/composition#your-component-must-forward-ref
// when this is replaced with compound's own/wrapped dialog this should be fixed
// until then, focus the cancel button for a deniable modal
// and continue button otherwise
const onOpenAutoFocus = (e: Event): void => {
const focusButtonKind = onDeny ? "tertiary" : "destructive";
(e.target as Element)
?.querySelector<HTMLButtonElement>(
`button[data-kind="${focusButtonKind}"]`,
)
?.focus();
};
return (
<Root open={isOpen} onOpenChange={setIsOpen}>
<Trigger asChild>{trigger}</Trigger>
<Portal>
<Overlay className={styles.overlay} onClick={onClose(onDeny)} />
<Content
className={classNames(styles.content, className)}
onEscapeKeyDown={onClose(onDeny)}
onOpenAutoFocus={onOpenAutoFocus}
>
<Title>{title}</Title>
<Description>{children}</Description>
<div className={styles.buttons}>
{onDeny && (
<Cancel asChild>
<Button kind="tertiary" size="sm" onClick={onClose(onDeny)}>
Cancel
</Button>
</Cancel>
)}
<Action asChild>
<Button kind="destructive" size="sm" onClick={onClose(onConfirm)}>
Continue
</Button>
</Action>
</div>
</Content>
</Portal>
</Root>
);
};
export default ConfirmationModal;

View File

@@ -0,0 +1,49 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`<ConfirmationModal /> > opens modal on clicking trigger 1`] = `
<div
aria-describedby="radix-:r5:"
aria-labelledby="radix-:r4:"
class="_content_6bc2cb test"
data-state="open"
id="radix-:r3:"
role="alertdialog"
style="pointer-events: auto;"
tabindex="-1"
>
<h2
id="radix-:r4:"
>
Are you sure?
</h2>
<p
id="radix-:r5:"
>
Some extra information.
</p>
<div
class="_buttons_6bc2cb"
>
<button
class="_button_1raud_17"
data-kind="tertiary"
data-size="sm"
role="button"
tabindex="0"
type="button"
>
Cancel
</button>
<button
class="_button_1raud_17"
data-kind="destructive"
data-size="sm"
role="button"
tabindex="0"
type="button"
>
Continue
</button>
</div>
</div>
`;

View File

@@ -12,10 +12,13 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
// @vitest-environment happy-dom
import { create } from "react-test-renderer"; import { create } from "react-test-renderer";
import { describe, expect, it, vi } from "vitest"; import { describe, expect, it, vi } from "vitest";
import { FragmentType } from "../gql/fragment-masking"; import { FragmentType } from "../gql/fragment-masking";
import { WithLocation } from "../test-utils/WithLocation";
import DateTime from "./DateTime"; import DateTime from "./DateTime";
import OAuth2Session, { OAUTH2_SESSION_FRAGMENT } from "./OAuth2Session"; import OAuth2Session, { OAUTH2_SESSION_FRAGMENT } from "./OAuth2Session";
@@ -47,7 +50,11 @@ describe("<OAuth2Session />", () => {
const finishedAt = "2023-06-29T03:35:19.451292+00:00"; const finishedAt = "2023-06-29T03:35:19.451292+00:00";
it("renders an active session", () => { it("renders an active session", () => {
const component = create(<OAuth2Session {...defaultProps} />); const component = create(
<WithLocation>
<OAuth2Session {...defaultProps} />
</WithLocation>,
);
expect(component.toJSON()).toMatchSnapshot(); expect(component.toJSON()).toMatchSnapshot();
}); });
@@ -56,7 +63,11 @@ describe("<OAuth2Session />", () => {
...defaultProps.session, ...defaultProps.session,
finishedAt, finishedAt,
}; };
const component = create(<OAuth2Session session={finishedSession} />); const component = create(
<WithLocation>
<OAuth2Session session={finishedSession} />
</WithLocation>,
);
expect(component.toJSON()).toMatchSnapshot(); expect(component.toJSON()).toMatchSnapshot();
}); });
}); });

View File

@@ -15,6 +15,7 @@
import { Button } from "@vector-im/compound-web"; import { Button } from "@vector-im/compound-web";
import { useState } from "react"; import { useState } from "react";
import ConfirmationModal from "../ConfirmationModal/ConfirmationModal";
import LoadingSpinner from "../LoadingSpinner/LoadingSpinner"; import LoadingSpinner from "../LoadingSpinner/LoadingSpinner";
/** /**
@@ -25,7 +26,8 @@ const EndSessionButton: React.FC<{ endSession: () => Promise<void> }> = ({
endSession, endSession,
}) => { }) => {
const [inProgress, setInProgress] = useState(false); const [inProgress, setInProgress] = useState(false);
const onClick = async (): Promise<void> => {
const onConfirm = async (): Promise<void> => {
setInProgress(true); setInProgress(true);
try { try {
await endSession(); await endSession();
@@ -34,15 +36,23 @@ const EndSessionButton: React.FC<{ endSession: () => Promise<void> }> = ({
} }
setInProgress(false); setInProgress(false);
}; };
// NOOP so we render cancel button
const onDeny = (): void => {};
return ( return (
<Button <>
kind="destructive" <ConfirmationModal
size="sm" onDeny={onDeny}
onClick={onClick} onConfirm={onConfirm}
disabled={inProgress} title="Are you sure you want to end this session?"
> trigger={
<Button kind="destructive" size="sm" disabled={inProgress}>
{inProgress && <LoadingSpinner inline />}End session {inProgress && <LoadingSpinner inline />}End session
</Button> </Button>
}
/>
</>
); );
}; };

View File

@@ -144,11 +144,16 @@ exports[`<CompatSessionDetail> > renders a compatability session details 1`] = `
</ul> </ul>
</div> </div>
<button <button
aria-controls="radix-:r0:"
aria-expanded="false"
aria-haspopup="dialog"
class="_button_1raud_17" class="_button_1raud_17"
data-kind="destructive" data-kind="destructive"
data-size="sm" data-size="sm"
data-state="closed"
role="button" role="button"
tabindex="0" tabindex="0"
type="button"
> >
End session End session
</button> </button>
@@ -251,11 +256,16 @@ exports[`<CompatSessionDetail> > renders a compatability session without an ssoL
</ul> </ul>
</div> </div>
<button <button
aria-controls="radix-:r3:"
aria-expanded="false"
aria-haspopup="dialog"
class="_button_1raud_17" class="_button_1raud_17"
data-kind="destructive" data-kind="destructive"
data-size="sm" data-size="sm"
data-state="closed"
role="button" role="button"
tabindex="0" tabindex="0"
type="button"
> >
End session End session
</button> </button>

View File

@@ -190,11 +190,16 @@ exports[`<OAuth2SessionDetail> > renders session details 1`] = `
</ul> </ul>
</div> </div>
<button <button
aria-controls="radix-:r0:"
aria-expanded="false"
aria-haspopup="dialog"
class="_button_1raud_17" class="_button_1raud_17"
data-kind="destructive" data-kind="destructive"
data-size="sm" data-size="sm"
data-state="closed"
role="button" role="button"
tabindex="0" tabindex="0"
type="button"
> >
End session End session
</button> </button>

View File

@@ -17,10 +17,11 @@ import { Body } from "@vector-im/compound-web";
import { atom, useSetAtom } from "jotai"; import { atom, useSetAtom } from "jotai";
import { atomFamily } from "jotai/utils"; import { atomFamily } from "jotai/utils";
import { atomWithMutation } from "jotai-urql"; import { atomWithMutation } from "jotai-urql";
import { useTransition } from "react"; import { useTransition, ComponentProps } from "react";
import { FragmentType, graphql, useFragment } from "../../gql"; import { FragmentType, graphql, useFragment } from "../../gql";
import { Link } from "../../routing"; import { Link } from "../../routing";
import ConfirmationModal from "../ConfirmationModal/ConfirmationModal";
import styles from "./UserEmail.module.css"; import styles from "./UserEmail.module.css";
@@ -99,6 +100,29 @@ const DeleteButton: React.FC<{ disabled?: boolean; onClick?: () => void }> = ({
</button> </button>
); );
const DeleteButtonWithConfirmation: React.FC<
ComponentProps<typeof DeleteButton>
> = ({ onClick, ...rest }) => {
const onConfirm = (): void => {
onClick?.();
};
// NOOP function, otherwise we dont render a cancel button
const onDeny = (): void => {};
return (
<>
<ConfirmationModal
trigger={<DeleteButton {...rest} />}
onDeny={onDeny}
onConfirm={onConfirm}
>
<Body>Are you sure you want to remove this email?</Body>
</ConfirmationModal>
</>
);
};
const UserEmail: React.FC<{ const UserEmail: React.FC<{
email: FragmentType<typeof FRAGMENT>; email: FragmentType<typeof FRAGMENT>;
onRemove?: () => void; onRemove?: () => void;
@@ -135,7 +159,10 @@ const UserEmail: React.FC<{
<div className={styles.userEmailLine}> <div className={styles.userEmailLine}>
<div className={styles.userEmailField}>{data.email}</div> <div className={styles.userEmailField}>{data.email}</div>
<DeleteButton disabled={isPrimary || pending} onClick={onRemoveClick} /> <DeleteButtonWithConfirmation
disabled={isPrimary || pending}
onClick={onRemoveClick}
/>
</div> </div>
{data.confirmedAt && !isPrimary && ( {data.confirmedAt && !isPrimary && (
<button <button

View File

@@ -84,13 +84,18 @@ exports[`<CompatSession /> > renders an active session 1`] = `
className="_sessionActions_634806" className="_sessionActions_634806"
> >
<button <button
aria-controls="radix-:r0:"
aria-expanded={false}
aria-haspopup="dialog"
className="_button_1raud_17" className="_button_1raud_17"
data-kind="destructive" data-kind="destructive"
data-size="sm" data-size="sm"
data-state="closed"
disabled={false} disabled={false}
onClick={[Function]} onClick={[Function]}
role="button" role="button"
tabIndex={0} tabIndex={0}
type="button"
> >
End session End session
</button> </button>

View File

@@ -84,13 +84,18 @@ exports[`<OAuth2Session /> > renders an active session 1`] = `
className="_sessionActions_634806" className="_sessionActions_634806"
> >
<button <button
aria-controls="radix-:r0:"
aria-expanded={false}
aria-haspopup="dialog"
className="_button_1raud_17" className="_button_1raud_17"
data-kind="destructive" data-kind="destructive"
data-size="sm" data-size="sm"
data-state="closed"
disabled={false} disabled={false}
onClick={[Function]} onClick={[Function]}
role="button" role="button"
tabIndex={0} tabIndex={0}
type="button"
> >
End session End session
</button> </button>

View File

@@ -1,17 +1,15 @@
import { import { ResultOf, DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core';
ResultOf, import { FragmentDefinitionNode } from 'graphql';
DocumentTypeDecoration, import { Incremental } from './graphql';
TypedDocumentNode,
} from "@graphql-typed-document-node/core";
import { FragmentDefinitionNode } from "graphql";
import { Incremental } from "./graphql";
export type FragmentType<
TDocumentType extends DocumentTypeDecoration<any, any>, export type FragmentType<TDocumentType extends DocumentTypeDecoration<any, any>> = TDocumentType extends DocumentTypeDecoration<
> = TDocumentType extends DocumentTypeDecoration<infer TType, any> infer TType,
? [TType] extends [{ " $fragmentName"?: infer TKey }] any
>
? [TType] extends [{ ' $fragmentName'?: infer TKey }]
? TKey extends string ? TKey extends string
? { " $fragmentRefs"?: { [key in TKey]: TType } } ? { ' $fragmentRefs'?: { [key in TKey]: TType } }
: never : never
: never : never
: never; : never;
@@ -19,67 +17,50 @@ export type FragmentType<
// return non-nullable if `fragmentType` is non-nullable // return non-nullable if `fragmentType` is non-nullable
export function useFragment<TType>( export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>, _documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>, fragmentType: FragmentType<DocumentTypeDecoration<TType, any>>
): TType; ): TType;
// return nullable if `fragmentType` is nullable // return nullable if `fragmentType` is nullable
export function useFragment<TType>( export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>, _documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | null | undefined
| FragmentType<DocumentTypeDecoration<TType, any>>
| null
| undefined,
): TType | null | undefined; ): TType | null | undefined;
// return array of non-nullable if `fragmentType` is array of non-nullable // return array of non-nullable if `fragmentType` is array of non-nullable
export function useFragment<TType>( export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>, _documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>, fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
): ReadonlyArray<TType>; ): ReadonlyArray<TType>;
// return array of nullable if `fragmentType` is array of nullable // return array of nullable if `fragmentType` is array of nullable
export function useFragment<TType>( export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>, _documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: fragmentType: ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
| ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
| null
| undefined,
): ReadonlyArray<TType> | null | undefined; ): ReadonlyArray<TType> | null | undefined;
export function useFragment<TType>( export function useFragment<TType>(
_documentNode: DocumentTypeDecoration<TType, any>, _documentNode: DocumentTypeDecoration<TType, any>,
fragmentType: fragmentType: FragmentType<DocumentTypeDecoration<TType, any>> | ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>> | null | undefined
| FragmentType<DocumentTypeDecoration<TType, any>>
| ReadonlyArray<FragmentType<DocumentTypeDecoration<TType, any>>>
| null
| undefined,
): TType | ReadonlyArray<TType> | null | undefined { ): TType | ReadonlyArray<TType> | null | undefined {
return fragmentType as any; return fragmentType as any;
} }
export function makeFragmentData< export function makeFragmentData<
F extends DocumentTypeDecoration<any, any>, F extends DocumentTypeDecoration<any, any>,
FT extends ResultOf<F>, FT extends ResultOf<F>
>(data: FT, _fragment: F): FragmentType<F> { >(data: FT, _fragment: F): FragmentType<F> {
return data as FragmentType<F>; return data as FragmentType<F>;
} }
export function isFragmentReady<TQuery, TFrag>( export function isFragmentReady<TQuery, TFrag>(
queryNode: DocumentTypeDecoration<TQuery, any>, queryNode: DocumentTypeDecoration<TQuery, any>,
fragmentNode: TypedDocumentNode<TFrag>, fragmentNode: TypedDocumentNode<TFrag>,
data: data: FragmentType<TypedDocumentNode<Incremental<TFrag>, any>> | null | undefined
| FragmentType<TypedDocumentNode<Incremental<TFrag>, any>>
| null
| undefined,
): data is FragmentType<typeof fragmentNode> { ): data is FragmentType<typeof fragmentNode> {
const deferredFields = ( const deferredFields = (queryNode as { __meta__?: { deferredFields: Record<string, (keyof TFrag)[]> } }).__meta__
queryNode as { ?.deferredFields;
__meta__?: { deferredFields: Record<string, (keyof TFrag)[]> };
}
).__meta__?.deferredFields;
if (!deferredFields) return true; if (!deferredFields) return true;
const fragDef = fragmentNode.definitions[0] as const fragDef = fragmentNode.definitions[0] as FragmentDefinitionNode | undefined;
| FragmentDefinitionNode
| undefined;
const fragName = fragDef?.name?.value; const fragName = fragDef?.name?.value;
const fields = (fragName && deferredFields[fragName]) || []; const fields = (fragName && deferredFields[fragName]) || [];
return fields.length > 0 && fields.every((field) => data && field in data); return fields.length > 0 && fields.every(field => data && field in data);
} }

View File

@@ -1,6 +1,6 @@
/* eslint-disable */ /* eslint-disable */
import * as types from "./graphql"; import * as types from './graphql';
import { TypedDocumentNode as DocumentNode } from "@graphql-typed-document-node/core"; import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core';
/** /**
* Map of all GraphQL operations in the project. * Map of all GraphQL operations in the project.
@@ -13,68 +13,37 @@ import { TypedDocumentNode as DocumentNode } from "@graphql-typed-document-node/
* Therefore it is highly recommended to use the babel or swc plugin for production. * Therefore it is highly recommended to use the babel or swc plugin for production.
*/ */
const documents = { const documents = {
"\n query CurrentViewerQuery {\n viewer {\n __typename\n ... on User {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n": "\n query CurrentViewerQuery {\n viewer {\n __typename\n ... on User {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n": types.CurrentViewerQueryDocument,
types.CurrentViewerQueryDocument, "\n query CurrentViewerSessionQuery {\n viewerSession {\n __typename\n ... on BrowserSession {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n": types.CurrentViewerSessionQueryDocument,
"\n query CurrentViewerSessionQuery {\n viewerSession {\n __typename\n ... on BrowserSession {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n": "\n fragment BrowserSession_session on BrowserSession {\n id\n createdAt\n finishedAt\n userAgent\n lastAuthentication {\n id\n createdAt\n }\n }\n": types.BrowserSession_SessionFragmentDoc,
types.CurrentViewerSessionQueryDocument, "\n mutation EndBrowserSession($id: ID!) {\n endBrowserSession(input: { browserSessionId: $id }) {\n status\n browserSession {\n id\n ...BrowserSession_session\n }\n }\n }\n": types.EndBrowserSessionDocument,
"\n fragment BrowserSession_session on BrowserSession {\n id\n createdAt\n finishedAt\n userAgent\n lastAuthentication {\n id\n createdAt\n }\n }\n": "\n query BrowserSessionList(\n $userId: ID!\n $state: BrowserSessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n browserSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n totalCount\n\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n": types.BrowserSessionListDocument,
types.BrowserSession_SessionFragmentDoc, "\n fragment OAuth2Client_detail on Oauth2Client {\n id\n clientId\n clientName\n clientUri\n logoUri\n tosUri\n policyUri\n redirectUris\n }\n": types.OAuth2Client_DetailFragmentDoc,
"\n mutation EndBrowserSession($id: ID!) {\n endBrowserSession(input: { browserSessionId: $id }) {\n status\n browserSession {\n id\n ...BrowserSession_session\n }\n }\n }\n": "\n fragment CompatSession_session on CompatSession {\n id\n createdAt\n deviceId\n finishedAt\n ssoLogin {\n id\n redirectUri\n }\n }\n": types.CompatSession_SessionFragmentDoc,
types.EndBrowserSessionDocument, "\n mutation EndCompatSession($id: ID!) {\n endCompatSession(input: { compatSessionId: $id }) {\n status\n compatSession {\n id\n finishedAt\n }\n }\n }\n": types.EndCompatSessionDocument,
"\n query BrowserSessionList(\n $userId: ID!\n $state: BrowserSessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n browserSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n totalCount\n\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n": "\n query CompatSessionList(\n $userId: ID!\n $state: CompatSessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n compatSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n edges {\n node {\n id\n ...CompatSession_session\n }\n }\n\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n": types.CompatSessionListDocument,
types.BrowserSessionListDocument, "\n fragment OAuth2Session_session on Oauth2Session {\n id\n scope\n createdAt\n finishedAt\n client {\n id\n clientId\n clientName\n clientUri\n logoUri\n }\n }\n": types.OAuth2Session_SessionFragmentDoc,
"\n fragment OAuth2Client_detail on Oauth2Client {\n id\n clientId\n clientName\n clientUri\n logoUri\n tosUri\n policyUri\n redirectUris\n }\n": "\n mutation EndOAuth2Session($id: ID!) {\n endOauth2Session(input: { oauth2SessionId: $id }) {\n status\n oauth2Session {\n id\n ...OAuth2Session_session\n }\n }\n }\n": types.EndOAuth2SessionDocument,
types.OAuth2Client_DetailFragmentDoc, "\n query OAuth2SessionListQuery(\n $userId: ID!\n $state: Oauth2SessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n oauth2Sessions(\n state: $state\n first: $first\n after: $after\n last: $last\n before: $before\n ) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n": types.OAuth2SessionListQueryDocument,
"\n fragment CompatSession_session on CompatSession {\n id\n createdAt\n deviceId\n finishedAt\n ssoLogin {\n id\n redirectUri\n }\n }\n": "\n query SessionQuery($userId: ID!, $deviceId: String!) {\n session(userId: $userId, deviceId: $deviceId) {\n __typename\n ...CompatSession_session\n ...OAuth2Session_session\n }\n }\n": types.SessionQueryDocument,
types.CompatSession_SessionFragmentDoc, "\n fragment UnverifiedEmailAlert on User {\n id\n unverifiedEmails: emails(first: 0, state: PENDING) {\n totalCount\n }\n }\n": types.UnverifiedEmailAlertFragmentDoc,
"\n mutation EndCompatSession($id: ID!) {\n endCompatSession(input: { compatSessionId: $id }) {\n status\n compatSession {\n id\n finishedAt\n }\n }\n }\n": "\n fragment UserEmail_email on UserEmail {\n id\n email\n confirmedAt\n }\n": types.UserEmail_EmailFragmentDoc,
types.EndCompatSessionDocument, "\n mutation RemoveEmail($id: ID!) {\n removeEmail(input: { userEmailId: $id }) {\n status\n\n user {\n id\n }\n }\n }\n": types.RemoveEmailDocument,
"\n query CompatSessionList(\n $userId: ID!\n $state: CompatSessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n compatSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n edges {\n node {\n id\n ...CompatSession_session\n }\n }\n\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n": "\n mutation SetPrimaryEmail($id: ID!) {\n setPrimaryEmail(input: { userEmailId: $id }) {\n status\n user {\n id\n primaryEmail {\n id\n }\n }\n }\n }\n": types.SetPrimaryEmailDocument,
types.CompatSessionListDocument, "\n query UserGreeting($userId: ID!) {\n user(id: $userId) {\n id\n username\n matrix {\n mxid\n displayName\n }\n }\n viewer {\n __typename\n\n ... on User {\n id\n ...UnverifiedEmailAlert\n }\n }\n }\n": types.UserGreetingDocument,
"\n fragment OAuth2Session_session on Oauth2Session {\n id\n scope\n createdAt\n finishedAt\n client {\n id\n clientId\n clientName\n clientUri\n logoUri\n }\n }\n": "\n mutation AddEmail($userId: ID!, $email: String!) {\n addEmail(input: { userId: $userId, email: $email }) {\n status\n violations\n email {\n id\n ...UserEmail_email\n }\n }\n }\n": types.AddEmailDocument,
types.OAuth2Session_SessionFragmentDoc, "\n query UserEmailListQuery(\n $userId: ID!\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n\n emails(first: $first, after: $after, last: $last, before: $before) {\n edges {\n cursor\n node {\n id\n ...UserEmail_email\n }\n }\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n": types.UserEmailListQueryDocument,
"\n mutation EndOAuth2Session($id: ID!) {\n endOauth2Session(input: { oauth2SessionId: $id }) {\n status\n oauth2Session {\n id\n ...OAuth2Session_session\n }\n }\n }\n": "\n query UserPrimaryEmail($userId: ID!) {\n user(id: $userId) {\n id\n primaryEmail {\n id\n }\n }\n }\n": types.UserPrimaryEmailDocument,
types.EndOAuth2SessionDocument, "\n mutation SetDisplayName($userId: ID!, $displayName: String) {\n setDisplayName(input: { userId: $userId, displayName: $displayName }) {\n status\n user {\n id\n matrix {\n displayName\n }\n }\n }\n }\n": types.SetDisplayNameDocument,
"\n query OAuth2SessionListQuery(\n $userId: ID!\n $state: Oauth2SessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n oauth2Sessions(\n state: $state\n first: $first\n after: $after\n last: $last\n before: $before\n ) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n": "\n fragment UserSessionsOverview_user on User {\n id\n\n primaryEmail {\n id\n ...UserEmail_email\n }\n\n confirmedEmails: emails(first: 0, state: CONFIRMED) {\n totalCount\n }\n\n browserSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n oauth2Sessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n compatSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n }\n": types.UserSessionsOverview_UserFragmentDoc,
types.OAuth2SessionListQueryDocument, "\n fragment UserEmail_verifyEmail on UserEmail {\n id\n email\n }\n": types.UserEmail_VerifyEmailFragmentDoc,
"\n query SessionQuery($userId: ID!, $deviceId: String!) {\n session(userId: $userId, deviceId: $deviceId) {\n __typename\n ...CompatSession_session\n ...OAuth2Session_session\n }\n }\n": "\n mutation VerifyEmail($id: ID!, $code: String!) {\n verifyEmail(input: { userEmailId: $id, code: $code }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n": types.VerifyEmailDocument,
types.SessionQueryDocument, "\n mutation ResendVerificationEmail($id: ID!) {\n sendVerificationEmail(input: { userEmailId: $id }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n": types.ResendVerificationEmailDocument,
"\n fragment UnverifiedEmailAlert on User {\n id\n unverifiedEmails: emails(first: 0, state: PENDING) {\n totalCount\n }\n }\n": "\n fragment BrowserSession_detail on BrowserSession {\n id\n createdAt\n finishedAt\n userAgent\n lastAuthentication {\n id\n createdAt\n }\n user {\n id\n username\n }\n }\n": types.BrowserSession_DetailFragmentDoc,
types.UnverifiedEmailAlertFragmentDoc, "\n query BrowserSessionQuery($id: ID!) {\n browserSession(id: $id) {\n id\n ...BrowserSession_detail\n }\n }\n": types.BrowserSessionQueryDocument,
"\n fragment UserEmail_email on UserEmail {\n id\n email\n confirmedAt\n }\n": "\n query OAuth2ClientQuery($id: ID!) {\n oauth2Client(id: $id) {\n ...OAuth2Client_detail\n }\n }\n": types.OAuth2ClientQueryDocument,
types.UserEmail_EmailFragmentDoc, "\n query SessionsOverviewQuery {\n viewer {\n __typename\n\n ... on User {\n id\n ...UserSessionsOverview_user\n }\n }\n }\n": types.SessionsOverviewQueryDocument,
"\n mutation RemoveEmail($id: ID!) {\n removeEmail(input: { userEmailId: $id }) {\n status\n\n user {\n id\n }\n }\n }\n": "\n query VerifyEmailQuery($id: ID!) {\n userEmail(id: $id) {\n ...UserEmail_verifyEmail\n }\n }\n": types.VerifyEmailQueryDocument,
types.RemoveEmailDocument,
"\n mutation SetPrimaryEmail($id: ID!) {\n setPrimaryEmail(input: { userEmailId: $id }) {\n status\n user {\n id\n primaryEmail {\n id\n }\n }\n }\n }\n":
types.SetPrimaryEmailDocument,
"\n query UserGreeting($userId: ID!) {\n user(id: $userId) {\n id\n username\n matrix {\n mxid\n displayName\n }\n }\n viewer {\n __typename\n\n ... on User {\n id\n ...UnverifiedEmailAlert\n }\n }\n }\n":
types.UserGreetingDocument,
"\n mutation AddEmail($userId: ID!, $email: String!) {\n addEmail(input: { userId: $userId, email: $email }) {\n status\n violations\n email {\n id\n ...UserEmail_email\n }\n }\n }\n":
types.AddEmailDocument,
"\n query UserEmailListQuery(\n $userId: ID!\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n\n emails(first: $first, after: $after, last: $last, before: $before) {\n edges {\n cursor\n node {\n id\n ...UserEmail_email\n }\n }\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n":
types.UserEmailListQueryDocument,
"\n query UserPrimaryEmail($userId: ID!) {\n user(id: $userId) {\n id\n primaryEmail {\n id\n }\n }\n }\n":
types.UserPrimaryEmailDocument,
"\n mutation SetDisplayName($userId: ID!, $displayName: String) {\n setDisplayName(input: { userId: $userId, displayName: $displayName }) {\n status\n user {\n id\n matrix {\n displayName\n }\n }\n }\n }\n":
types.SetDisplayNameDocument,
"\n fragment UserSessionsOverview_user on User {\n id\n\n primaryEmail {\n id\n ...UserEmail_email\n }\n\n confirmedEmails: emails(first: 0, state: CONFIRMED) {\n totalCount\n }\n\n browserSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n oauth2Sessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n compatSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n }\n":
types.UserSessionsOverview_UserFragmentDoc,
"\n fragment UserEmail_verifyEmail on UserEmail {\n id\n email\n }\n":
types.UserEmail_VerifyEmailFragmentDoc,
"\n mutation VerifyEmail($id: ID!, $code: String!) {\n verifyEmail(input: { userEmailId: $id, code: $code }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n":
types.VerifyEmailDocument,
"\n mutation ResendVerificationEmail($id: ID!) {\n sendVerificationEmail(input: { userEmailId: $id }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n":
types.ResendVerificationEmailDocument,
"\n fragment BrowserSession_detail on BrowserSession {\n id\n createdAt\n finishedAt\n userAgent\n lastAuthentication {\n id\n createdAt\n }\n user {\n id\n username\n }\n }\n":
types.BrowserSession_DetailFragmentDoc,
"\n query BrowserSessionQuery($id: ID!) {\n browserSession(id: $id) {\n id\n ...BrowserSession_detail\n }\n }\n":
types.BrowserSessionQueryDocument,
"\n query OAuth2ClientQuery($id: ID!) {\n oauth2Client(id: $id) {\n ...OAuth2Client_detail\n }\n }\n":
types.OAuth2ClientQueryDocument,
"\n query SessionsOverviewQuery {\n viewer {\n __typename\n\n ... on User {\n id\n ...UserSessionsOverview_user\n }\n }\n }\n":
types.SessionsOverviewQueryDocument,
"\n query VerifyEmailQuery($id: ID!) {\n userEmail(id: $id) {\n ...UserEmail_verifyEmail\n }\n }\n":
types.VerifyEmailQueryDocument,
}; };
/** /**
@@ -94,193 +63,130 @@ export function graphql(source: string): unknown;
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query CurrentViewerQuery {\n viewer {\n __typename\n ... on User {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n"): (typeof documents)["\n query CurrentViewerQuery {\n viewer {\n __typename\n ... on User {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n"];
source: "\n query CurrentViewerQuery {\n viewer {\n __typename\n ... on User {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n",
): (typeof documents)["\n query CurrentViewerQuery {\n viewer {\n __typename\n ... on User {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query CurrentViewerSessionQuery {\n viewerSession {\n __typename\n ... on BrowserSession {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n"): (typeof documents)["\n query CurrentViewerSessionQuery {\n viewerSession {\n __typename\n ... on BrowserSession {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n"];
source: "\n query CurrentViewerSessionQuery {\n viewerSession {\n __typename\n ... on BrowserSession {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n",
): (typeof documents)["\n query CurrentViewerSessionQuery {\n viewerSession {\n __typename\n ... on BrowserSession {\n id\n }\n\n ... on Anonymous {\n id\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n fragment BrowserSession_session on BrowserSession {\n id\n createdAt\n finishedAt\n userAgent\n lastAuthentication {\n id\n createdAt\n }\n }\n"): (typeof documents)["\n fragment BrowserSession_session on BrowserSession {\n id\n createdAt\n finishedAt\n userAgent\n lastAuthentication {\n id\n createdAt\n }\n }\n"];
source: "\n fragment BrowserSession_session on BrowserSession {\n id\n createdAt\n finishedAt\n userAgent\n lastAuthentication {\n id\n createdAt\n }\n }\n",
): (typeof documents)["\n fragment BrowserSession_session on BrowserSession {\n id\n createdAt\n finishedAt\n userAgent\n lastAuthentication {\n id\n createdAt\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n mutation EndBrowserSession($id: ID!) {\n endBrowserSession(input: { browserSessionId: $id }) {\n status\n browserSession {\n id\n ...BrowserSession_session\n }\n }\n }\n"): (typeof documents)["\n mutation EndBrowserSession($id: ID!) {\n endBrowserSession(input: { browserSessionId: $id }) {\n status\n browserSession {\n id\n ...BrowserSession_session\n }\n }\n }\n"];
source: "\n mutation EndBrowserSession($id: ID!) {\n endBrowserSession(input: { browserSessionId: $id }) {\n status\n browserSession {\n id\n ...BrowserSession_session\n }\n }\n }\n",
): (typeof documents)["\n mutation EndBrowserSession($id: ID!) {\n endBrowserSession(input: { browserSessionId: $id }) {\n status\n browserSession {\n id\n ...BrowserSession_session\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query BrowserSessionList(\n $userId: ID!\n $state: BrowserSessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n browserSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n totalCount\n\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"): (typeof documents)["\n query BrowserSessionList(\n $userId: ID!\n $state: BrowserSessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n browserSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n totalCount\n\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"];
source: "\n query BrowserSessionList(\n $userId: ID!\n $state: BrowserSessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n browserSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n totalCount\n\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n",
): (typeof documents)["\n query BrowserSessionList(\n $userId: ID!\n $state: BrowserSessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n browserSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n totalCount\n\n edges {\n cursor\n node {\n id\n ...BrowserSession_session\n }\n }\n\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n fragment OAuth2Client_detail on Oauth2Client {\n id\n clientId\n clientName\n clientUri\n logoUri\n tosUri\n policyUri\n redirectUris\n }\n"): (typeof documents)["\n fragment OAuth2Client_detail on Oauth2Client {\n id\n clientId\n clientName\n clientUri\n logoUri\n tosUri\n policyUri\n redirectUris\n }\n"];
source: "\n fragment OAuth2Client_detail on Oauth2Client {\n id\n clientId\n clientName\n clientUri\n logoUri\n tosUri\n policyUri\n redirectUris\n }\n",
): (typeof documents)["\n fragment OAuth2Client_detail on Oauth2Client {\n id\n clientId\n clientName\n clientUri\n logoUri\n tosUri\n policyUri\n redirectUris\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n fragment CompatSession_session on CompatSession {\n id\n createdAt\n deviceId\n finishedAt\n ssoLogin {\n id\n redirectUri\n }\n }\n"): (typeof documents)["\n fragment CompatSession_session on CompatSession {\n id\n createdAt\n deviceId\n finishedAt\n ssoLogin {\n id\n redirectUri\n }\n }\n"];
source: "\n fragment CompatSession_session on CompatSession {\n id\n createdAt\n deviceId\n finishedAt\n ssoLogin {\n id\n redirectUri\n }\n }\n",
): (typeof documents)["\n fragment CompatSession_session on CompatSession {\n id\n createdAt\n deviceId\n finishedAt\n ssoLogin {\n id\n redirectUri\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n mutation EndCompatSession($id: ID!) {\n endCompatSession(input: { compatSessionId: $id }) {\n status\n compatSession {\n id\n finishedAt\n }\n }\n }\n"): (typeof documents)["\n mutation EndCompatSession($id: ID!) {\n endCompatSession(input: { compatSessionId: $id }) {\n status\n compatSession {\n id\n finishedAt\n }\n }\n }\n"];
source: "\n mutation EndCompatSession($id: ID!) {\n endCompatSession(input: { compatSessionId: $id }) {\n status\n compatSession {\n id\n finishedAt\n }\n }\n }\n",
): (typeof documents)["\n mutation EndCompatSession($id: ID!) {\n endCompatSession(input: { compatSessionId: $id }) {\n status\n compatSession {\n id\n finishedAt\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query CompatSessionList(\n $userId: ID!\n $state: CompatSessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n compatSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n edges {\n node {\n id\n ...CompatSession_session\n }\n }\n\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"): (typeof documents)["\n query CompatSessionList(\n $userId: ID!\n $state: CompatSessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n compatSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n edges {\n node {\n id\n ...CompatSession_session\n }\n }\n\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"];
source: "\n query CompatSessionList(\n $userId: ID!\n $state: CompatSessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n compatSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n edges {\n node {\n id\n ...CompatSession_session\n }\n }\n\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n",
): (typeof documents)["\n query CompatSessionList(\n $userId: ID!\n $state: CompatSessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n compatSessions(\n first: $first\n after: $after\n last: $last\n before: $before\n state: $state\n ) {\n edges {\n node {\n id\n ...CompatSession_session\n }\n }\n\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n fragment OAuth2Session_session on Oauth2Session {\n id\n scope\n createdAt\n finishedAt\n client {\n id\n clientId\n clientName\n clientUri\n logoUri\n }\n }\n"): (typeof documents)["\n fragment OAuth2Session_session on Oauth2Session {\n id\n scope\n createdAt\n finishedAt\n client {\n id\n clientId\n clientName\n clientUri\n logoUri\n }\n }\n"];
source: "\n fragment OAuth2Session_session on Oauth2Session {\n id\n scope\n createdAt\n finishedAt\n client {\n id\n clientId\n clientName\n clientUri\n logoUri\n }\n }\n",
): (typeof documents)["\n fragment OAuth2Session_session on Oauth2Session {\n id\n scope\n createdAt\n finishedAt\n client {\n id\n clientId\n clientName\n clientUri\n logoUri\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n mutation EndOAuth2Session($id: ID!) {\n endOauth2Session(input: { oauth2SessionId: $id }) {\n status\n oauth2Session {\n id\n ...OAuth2Session_session\n }\n }\n }\n"): (typeof documents)["\n mutation EndOAuth2Session($id: ID!) {\n endOauth2Session(input: { oauth2SessionId: $id }) {\n status\n oauth2Session {\n id\n ...OAuth2Session_session\n }\n }\n }\n"];
source: "\n mutation EndOAuth2Session($id: ID!) {\n endOauth2Session(input: { oauth2SessionId: $id }) {\n status\n oauth2Session {\n id\n ...OAuth2Session_session\n }\n }\n }\n",
): (typeof documents)["\n mutation EndOAuth2Session($id: ID!) {\n endOauth2Session(input: { oauth2SessionId: $id }) {\n status\n oauth2Session {\n id\n ...OAuth2Session_session\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query OAuth2SessionListQuery(\n $userId: ID!\n $state: Oauth2SessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n oauth2Sessions(\n state: $state\n first: $first\n after: $after\n last: $last\n before: $before\n ) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"): (typeof documents)["\n query OAuth2SessionListQuery(\n $userId: ID!\n $state: Oauth2SessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n oauth2Sessions(\n state: $state\n first: $first\n after: $after\n last: $last\n before: $before\n ) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"];
source: "\n query OAuth2SessionListQuery(\n $userId: ID!\n $state: Oauth2SessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n oauth2Sessions(\n state: $state\n first: $first\n after: $after\n last: $last\n before: $before\n ) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n",
): (typeof documents)["\n query OAuth2SessionListQuery(\n $userId: ID!\n $state: Oauth2SessionState\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n oauth2Sessions(\n state: $state\n first: $first\n after: $after\n last: $last\n before: $before\n ) {\n edges {\n cursor\n node {\n id\n ...OAuth2Session_session\n }\n }\n\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query SessionQuery($userId: ID!, $deviceId: String!) {\n session(userId: $userId, deviceId: $deviceId) {\n __typename\n ...CompatSession_session\n ...OAuth2Session_session\n }\n }\n"): (typeof documents)["\n query SessionQuery($userId: ID!, $deviceId: String!) {\n session(userId: $userId, deviceId: $deviceId) {\n __typename\n ...CompatSession_session\n ...OAuth2Session_session\n }\n }\n"];
source: "\n query SessionQuery($userId: ID!, $deviceId: String!) {\n session(userId: $userId, deviceId: $deviceId) {\n __typename\n ...CompatSession_session\n ...OAuth2Session_session\n }\n }\n",
): (typeof documents)["\n query SessionQuery($userId: ID!, $deviceId: String!) {\n session(userId: $userId, deviceId: $deviceId) {\n __typename\n ...CompatSession_session\n ...OAuth2Session_session\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n fragment UnverifiedEmailAlert on User {\n id\n unverifiedEmails: emails(first: 0, state: PENDING) {\n totalCount\n }\n }\n"): (typeof documents)["\n fragment UnverifiedEmailAlert on User {\n id\n unverifiedEmails: emails(first: 0, state: PENDING) {\n totalCount\n }\n }\n"];
source: "\n fragment UnverifiedEmailAlert on User {\n id\n unverifiedEmails: emails(first: 0, state: PENDING) {\n totalCount\n }\n }\n",
): (typeof documents)["\n fragment UnverifiedEmailAlert on User {\n id\n unverifiedEmails: emails(first: 0, state: PENDING) {\n totalCount\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n fragment UserEmail_email on UserEmail {\n id\n email\n confirmedAt\n }\n"): (typeof documents)["\n fragment UserEmail_email on UserEmail {\n id\n email\n confirmedAt\n }\n"];
source: "\n fragment UserEmail_email on UserEmail {\n id\n email\n confirmedAt\n }\n",
): (typeof documents)["\n fragment UserEmail_email on UserEmail {\n id\n email\n confirmedAt\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n mutation RemoveEmail($id: ID!) {\n removeEmail(input: { userEmailId: $id }) {\n status\n\n user {\n id\n }\n }\n }\n"): (typeof documents)["\n mutation RemoveEmail($id: ID!) {\n removeEmail(input: { userEmailId: $id }) {\n status\n\n user {\n id\n }\n }\n }\n"];
source: "\n mutation RemoveEmail($id: ID!) {\n removeEmail(input: { userEmailId: $id }) {\n status\n\n user {\n id\n }\n }\n }\n",
): (typeof documents)["\n mutation RemoveEmail($id: ID!) {\n removeEmail(input: { userEmailId: $id }) {\n status\n\n user {\n id\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n mutation SetPrimaryEmail($id: ID!) {\n setPrimaryEmail(input: { userEmailId: $id }) {\n status\n user {\n id\n primaryEmail {\n id\n }\n }\n }\n }\n"): (typeof documents)["\n mutation SetPrimaryEmail($id: ID!) {\n setPrimaryEmail(input: { userEmailId: $id }) {\n status\n user {\n id\n primaryEmail {\n id\n }\n }\n }\n }\n"];
source: "\n mutation SetPrimaryEmail($id: ID!) {\n setPrimaryEmail(input: { userEmailId: $id }) {\n status\n user {\n id\n primaryEmail {\n id\n }\n }\n }\n }\n",
): (typeof documents)["\n mutation SetPrimaryEmail($id: ID!) {\n setPrimaryEmail(input: { userEmailId: $id }) {\n status\n user {\n id\n primaryEmail {\n id\n }\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query UserGreeting($userId: ID!) {\n user(id: $userId) {\n id\n username\n matrix {\n mxid\n displayName\n }\n }\n viewer {\n __typename\n\n ... on User {\n id\n ...UnverifiedEmailAlert\n }\n }\n }\n"): (typeof documents)["\n query UserGreeting($userId: ID!) {\n user(id: $userId) {\n id\n username\n matrix {\n mxid\n displayName\n }\n }\n viewer {\n __typename\n\n ... on User {\n id\n ...UnverifiedEmailAlert\n }\n }\n }\n"];
source: "\n query UserGreeting($userId: ID!) {\n user(id: $userId) {\n id\n username\n matrix {\n mxid\n displayName\n }\n }\n viewer {\n __typename\n\n ... on User {\n id\n ...UnverifiedEmailAlert\n }\n }\n }\n",
): (typeof documents)["\n query UserGreeting($userId: ID!) {\n user(id: $userId) {\n id\n username\n matrix {\n mxid\n displayName\n }\n }\n viewer {\n __typename\n\n ... on User {\n id\n ...UnverifiedEmailAlert\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n mutation AddEmail($userId: ID!, $email: String!) {\n addEmail(input: { userId: $userId, email: $email }) {\n status\n violations\n email {\n id\n ...UserEmail_email\n }\n }\n }\n"): (typeof documents)["\n mutation AddEmail($userId: ID!, $email: String!) {\n addEmail(input: { userId: $userId, email: $email }) {\n status\n violations\n email {\n id\n ...UserEmail_email\n }\n }\n }\n"];
source: "\n mutation AddEmail($userId: ID!, $email: String!) {\n addEmail(input: { userId: $userId, email: $email }) {\n status\n violations\n email {\n id\n ...UserEmail_email\n }\n }\n }\n",
): (typeof documents)["\n mutation AddEmail($userId: ID!, $email: String!) {\n addEmail(input: { userId: $userId, email: $email }) {\n status\n violations\n email {\n id\n ...UserEmail_email\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query UserEmailListQuery(\n $userId: ID!\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n\n emails(first: $first, after: $after, last: $last, before: $before) {\n edges {\n cursor\n node {\n id\n ...UserEmail_email\n }\n }\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"): (typeof documents)["\n query UserEmailListQuery(\n $userId: ID!\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n\n emails(first: $first, after: $after, last: $last, before: $before) {\n edges {\n cursor\n node {\n id\n ...UserEmail_email\n }\n }\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"];
source: "\n query UserEmailListQuery(\n $userId: ID!\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n\n emails(first: $first, after: $after, last: $last, before: $before) {\n edges {\n cursor\n node {\n id\n ...UserEmail_email\n }\n }\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n",
): (typeof documents)["\n query UserEmailListQuery(\n $userId: ID!\n $first: Int\n $after: String\n $last: Int\n $before: String\n ) {\n user(id: $userId) {\n id\n\n emails(first: $first, after: $after, last: $last, before: $before) {\n edges {\n cursor\n node {\n id\n ...UserEmail_email\n }\n }\n totalCount\n pageInfo {\n hasNextPage\n hasPreviousPage\n startCursor\n endCursor\n }\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query UserPrimaryEmail($userId: ID!) {\n user(id: $userId) {\n id\n primaryEmail {\n id\n }\n }\n }\n"): (typeof documents)["\n query UserPrimaryEmail($userId: ID!) {\n user(id: $userId) {\n id\n primaryEmail {\n id\n }\n }\n }\n"];
source: "\n query UserPrimaryEmail($userId: ID!) {\n user(id: $userId) {\n id\n primaryEmail {\n id\n }\n }\n }\n",
): (typeof documents)["\n query UserPrimaryEmail($userId: ID!) {\n user(id: $userId) {\n id\n primaryEmail {\n id\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n mutation SetDisplayName($userId: ID!, $displayName: String) {\n setDisplayName(input: { userId: $userId, displayName: $displayName }) {\n status\n user {\n id\n matrix {\n displayName\n }\n }\n }\n }\n"): (typeof documents)["\n mutation SetDisplayName($userId: ID!, $displayName: String) {\n setDisplayName(input: { userId: $userId, displayName: $displayName }) {\n status\n user {\n id\n matrix {\n displayName\n }\n }\n }\n }\n"];
source: "\n mutation SetDisplayName($userId: ID!, $displayName: String) {\n setDisplayName(input: { userId: $userId, displayName: $displayName }) {\n status\n user {\n id\n matrix {\n displayName\n }\n }\n }\n }\n",
): (typeof documents)["\n mutation SetDisplayName($userId: ID!, $displayName: String) {\n setDisplayName(input: { userId: $userId, displayName: $displayName }) {\n status\n user {\n id\n matrix {\n displayName\n }\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n fragment UserSessionsOverview_user on User {\n id\n\n primaryEmail {\n id\n ...UserEmail_email\n }\n\n confirmedEmails: emails(first: 0, state: CONFIRMED) {\n totalCount\n }\n\n browserSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n oauth2Sessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n compatSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n }\n"): (typeof documents)["\n fragment UserSessionsOverview_user on User {\n id\n\n primaryEmail {\n id\n ...UserEmail_email\n }\n\n confirmedEmails: emails(first: 0, state: CONFIRMED) {\n totalCount\n }\n\n browserSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n oauth2Sessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n compatSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n }\n"];
source: "\n fragment UserSessionsOverview_user on User {\n id\n\n primaryEmail {\n id\n ...UserEmail_email\n }\n\n confirmedEmails: emails(first: 0, state: CONFIRMED) {\n totalCount\n }\n\n browserSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n oauth2Sessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n compatSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n }\n",
): (typeof documents)["\n fragment UserSessionsOverview_user on User {\n id\n\n primaryEmail {\n id\n ...UserEmail_email\n }\n\n confirmedEmails: emails(first: 0, state: CONFIRMED) {\n totalCount\n }\n\n browserSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n oauth2Sessions(first: 0, state: ACTIVE) {\n totalCount\n }\n\n compatSessions(first: 0, state: ACTIVE) {\n totalCount\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n fragment UserEmail_verifyEmail on UserEmail {\n id\n email\n }\n"): (typeof documents)["\n fragment UserEmail_verifyEmail on UserEmail {\n id\n email\n }\n"];
source: "\n fragment UserEmail_verifyEmail on UserEmail {\n id\n email\n }\n",
): (typeof documents)["\n fragment UserEmail_verifyEmail on UserEmail {\n id\n email\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n mutation VerifyEmail($id: ID!, $code: String!) {\n verifyEmail(input: { userEmailId: $id, code: $code }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n"): (typeof documents)["\n mutation VerifyEmail($id: ID!, $code: String!) {\n verifyEmail(input: { userEmailId: $id, code: $code }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n"];
source: "\n mutation VerifyEmail($id: ID!, $code: String!) {\n verifyEmail(input: { userEmailId: $id, code: $code }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n",
): (typeof documents)["\n mutation VerifyEmail($id: ID!, $code: String!) {\n verifyEmail(input: { userEmailId: $id, code: $code }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n mutation ResendVerificationEmail($id: ID!) {\n sendVerificationEmail(input: { userEmailId: $id }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n"): (typeof documents)["\n mutation ResendVerificationEmail($id: ID!) {\n sendVerificationEmail(input: { userEmailId: $id }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n"];
source: "\n mutation ResendVerificationEmail($id: ID!) {\n sendVerificationEmail(input: { userEmailId: $id }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n",
): (typeof documents)["\n mutation ResendVerificationEmail($id: ID!) {\n sendVerificationEmail(input: { userEmailId: $id }) {\n status\n\n user {\n id\n primaryEmail {\n id\n }\n }\n\n email {\n id\n ...UserEmail_email\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n fragment BrowserSession_detail on BrowserSession {\n id\n createdAt\n finishedAt\n userAgent\n lastAuthentication {\n id\n createdAt\n }\n user {\n id\n username\n }\n }\n"): (typeof documents)["\n fragment BrowserSession_detail on BrowserSession {\n id\n createdAt\n finishedAt\n userAgent\n lastAuthentication {\n id\n createdAt\n }\n user {\n id\n username\n }\n }\n"];
source: "\n fragment BrowserSession_detail on BrowserSession {\n id\n createdAt\n finishedAt\n userAgent\n lastAuthentication {\n id\n createdAt\n }\n user {\n id\n username\n }\n }\n",
): (typeof documents)["\n fragment BrowserSession_detail on BrowserSession {\n id\n createdAt\n finishedAt\n userAgent\n lastAuthentication {\n id\n createdAt\n }\n user {\n id\n username\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query BrowserSessionQuery($id: ID!) {\n browserSession(id: $id) {\n id\n ...BrowserSession_detail\n }\n }\n"): (typeof documents)["\n query BrowserSessionQuery($id: ID!) {\n browserSession(id: $id) {\n id\n ...BrowserSession_detail\n }\n }\n"];
source: "\n query BrowserSessionQuery($id: ID!) {\n browserSession(id: $id) {\n id\n ...BrowserSession_detail\n }\n }\n",
): (typeof documents)["\n query BrowserSessionQuery($id: ID!) {\n browserSession(id: $id) {\n id\n ...BrowserSession_detail\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query OAuth2ClientQuery($id: ID!) {\n oauth2Client(id: $id) {\n ...OAuth2Client_detail\n }\n }\n"): (typeof documents)["\n query OAuth2ClientQuery($id: ID!) {\n oauth2Client(id: $id) {\n ...OAuth2Client_detail\n }\n }\n"];
source: "\n query OAuth2ClientQuery($id: ID!) {\n oauth2Client(id: $id) {\n ...OAuth2Client_detail\n }\n }\n",
): (typeof documents)["\n query OAuth2ClientQuery($id: ID!) {\n oauth2Client(id: $id) {\n ...OAuth2Client_detail\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query SessionsOverviewQuery {\n viewer {\n __typename\n\n ... on User {\n id\n ...UserSessionsOverview_user\n }\n }\n }\n"): (typeof documents)["\n query SessionsOverviewQuery {\n viewer {\n __typename\n\n ... on User {\n id\n ...UserSessionsOverview_user\n }\n }\n }\n"];
source: "\n query SessionsOverviewQuery {\n viewer {\n __typename\n\n ... on User {\n id\n ...UserSessionsOverview_user\n }\n }\n }\n",
): (typeof documents)["\n query SessionsOverviewQuery {\n viewer {\n __typename\n\n ... on User {\n id\n ...UserSessionsOverview_user\n }\n }\n }\n"];
/** /**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. * The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/ */
export function graphql( export function graphql(source: "\n query VerifyEmailQuery($id: ID!) {\n userEmail(id: $id) {\n ...UserEmail_verifyEmail\n }\n }\n"): (typeof documents)["\n query VerifyEmailQuery($id: ID!) {\n userEmail(id: $id) {\n ...UserEmail_verifyEmail\n }\n }\n"];
source: "\n query VerifyEmailQuery($id: ID!) {\n userEmail(id: $id) {\n ...UserEmail_verifyEmail\n }\n }\n",
): (typeof documents)["\n query VerifyEmailQuery($id: ID!) {\n userEmail(id: $id) {\n ...UserEmail_verifyEmail\n }\n }\n"];
export function graphql(source: string) { export function graphql(source: string) {
return (documents as any)[source] ?? {}; return (documents as any)[source] ?? {};
} }
export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = export type DocumentType<TDocumentNode extends DocumentNode<any, any>> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never;
TDocumentNode extends DocumentNode<infer TType, any> ? TType : never;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff