Compare commits
68 Commits
@nhost/rea
...
@nhost/apo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
809a2d35f8 | ||
|
|
e17ec7fce7 | ||
|
|
241175b158 | ||
|
|
51ceaf2696 | ||
|
|
490b77cde4 | ||
|
|
7fea29a8b4 | ||
|
|
1a34e011ad | ||
|
|
395839f449 | ||
|
|
399009d66a | ||
|
|
12eb236c4a | ||
|
|
2218e5cd5b | ||
|
|
2dcf1b38c6 | ||
|
|
ad49c92879 | ||
|
|
13dd57eeb4 | ||
|
|
1345741b11 | ||
|
|
511615f176 | ||
|
|
1198c201f1 | ||
|
|
f9b81a2ae9 | ||
|
|
dff0894f37 | ||
|
|
80f3645d57 | ||
|
|
7ddb9a654e | ||
|
|
71f3be15d8 | ||
|
|
96a9070836 | ||
|
|
329e5a91b9 | ||
|
|
6d559d6e23 | ||
|
|
f4f1450d06 | ||
|
|
a1eea9df7d | ||
|
|
26f2b665e6 | ||
|
|
224a5cc805 | ||
|
|
59125b3c77 | ||
|
|
5b69e3efd8 | ||
|
|
c9a444d048 | ||
|
|
2eeac45718 | ||
|
|
fe8ca8aba6 | ||
|
|
086ee46b08 | ||
|
|
203bc97f51 | ||
|
|
b24af44aac | ||
|
|
cdaa6d4e73 | ||
|
|
09e2c8f5c7 | ||
|
|
4581677830 | ||
|
|
7bfa6c9f93 | ||
|
|
80ef430d70 | ||
|
|
bad8af0fd1 | ||
|
|
69caa34c43 | ||
|
|
1d898e2893 | ||
|
|
e87621cbde | ||
|
|
0d6fc42158 | ||
|
|
f6fbee6b13 | ||
|
|
1230b72222 | ||
|
|
a6120bf366 | ||
|
|
b23dc058a6 | ||
|
|
ad0dda7493 | ||
|
|
4063507d59 | ||
|
|
85439307a9 | ||
|
|
0d8baa4065 | ||
|
|
4bca94425e | ||
|
|
9f948385c0 | ||
|
|
294c504b61 | ||
|
|
1469ec2969 | ||
|
|
726c33d1b2 | ||
|
|
11b9cfbc0d | ||
|
|
79aaa91e67 | ||
|
|
df4d24320a | ||
|
|
baa3ef794e | ||
|
|
da7ffbe523 | ||
|
|
3ca70554c8 | ||
|
|
077b200510 | ||
|
|
2f220db84a |
@@ -25,6 +25,7 @@ module.exports = {
|
||||
'error',
|
||||
{ allowArrowFunctions: true, allowFunctions: true },
|
||||
],
|
||||
'import/no-named-as-default': 'off',
|
||||
'import/prefer-default-export': 'off',
|
||||
'import/no-extraneous-dependencies': ['error', { devDependencies: true }],
|
||||
curly: ['error', 'all'],
|
||||
|
||||
@@ -1,5 +1,27 @@
|
||||
# @nhost/dashboard
|
||||
|
||||
## 0.16.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 399009d6: fix(gql): don't enter an infinite loop when fetching remote app data
|
||||
- 329e5a91: fix(deployments): use the same sorting of deployments everywhere
|
||||
- 6d559d6e: chore(settings): add under the hood improvements to the settings page
|
||||
- 12eb236c: chore(deps): bump `prettier-plugin-tailwindcss` to `v0.3.0`
|
||||
- f9b81a2a: chore(deps): bump `turbo` to `v1.9.8`
|
||||
- 1345741b: fix(projects): don't redirect to 404 on project creation
|
||||
- Updated dependencies [7fea29a8]
|
||||
- @nhost/react-apollo@5.0.23
|
||||
- @nhost/nextjs@1.13.25
|
||||
|
||||
## 0.16.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 1230b722: fix(projects): don't redirect to 404 on when the project is renamed
|
||||
- @nhost/react-apollo@5.0.22
|
||||
- @nhost/nextjs@1.13.24
|
||||
|
||||
## 0.16.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -3,7 +3,7 @@ RUN apk add --no-cache libc6-compat
|
||||
RUN apk update
|
||||
WORKDIR /app
|
||||
|
||||
RUN yarn global add turbo@1.9.3
|
||||
RUN yarn global add turbo@1.9.8
|
||||
COPY . .
|
||||
RUN turbo prune --scope="@nhost/dashboard" --docker
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/dashboard",
|
||||
"version": "0.16.10",
|
||||
"version": "0.16.12",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
@@ -15,7 +15,7 @@
|
||||
"format": "prettier --write \"src/**/*.{js,ts,tsx,jsx,json,md}\" --plugin-search-dir=.",
|
||||
"storybook": "start-storybook -p 6006 -s public",
|
||||
"build-storybook": "build-storybook",
|
||||
"e2e": "npx playwright@1.31.2 install --with-deps && playwright test"
|
||||
"e2e": "npx playwright@1.33.0 install --with-deps && playwright test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.7.10",
|
||||
@@ -88,7 +88,7 @@
|
||||
"@graphql-codegen/typescript-operations": "^3.0.0",
|
||||
"@graphql-codegen/typescript-react-apollo": "^3.3.1",
|
||||
"@next/bundle-analyzer": "^12.3.1",
|
||||
"@playwright/test": "^1.31.2",
|
||||
"@playwright/test": "^1.33.0",
|
||||
"@storybook/addon-actions": "^6.5.14",
|
||||
"@storybook/addon-essentials": "^6.5.14",
|
||||
"@storybook/addon-interactions": "^6.5.14",
|
||||
@@ -137,7 +137,7 @@
|
||||
"postcss": "^8.4.19",
|
||||
"prettier": "^2.7.1",
|
||||
"prettier-plugin-organize-imports": "^3.2.0",
|
||||
"prettier-plugin-tailwindcss": "^0.2.0",
|
||||
"prettier-plugin-tailwindcss": "^0.3.0",
|
||||
"react-date-fns-hooks": "^0.9.4",
|
||||
"require-from-string": "^2.0.2",
|
||||
"snake-case": "^3.0.4",
|
||||
|
||||
@@ -114,6 +114,9 @@ export default function AppDeployments(props: AppDeploymentsProps) {
|
||||
const { deployments } = deploymentPageData || { deployments: [] };
|
||||
const { deployments: scheduledOrPendingDeployments } =
|
||||
scheduledOrPendingDeploymentsData || { deployments: [] };
|
||||
const isDeploymentInProgress = deployments?.some((deployment) =>
|
||||
['PENDING', 'SCHEDULED'].includes(deployment.deploymentStatus),
|
||||
);
|
||||
|
||||
const latestDeployment = latestDeploymentData?.deployments[0];
|
||||
const latestLiveDeployment = latestLiveDeploymentData?.deployments[0];
|
||||
@@ -135,7 +138,10 @@ export default function AppDeployments(props: AppDeploymentsProps) {
|
||||
deployment={deployment}
|
||||
isLive={liveDeploymentId === deployment.id}
|
||||
showRedeploy={latestDeployment.id === deployment.id}
|
||||
disableRedeploy={scheduledOrPendingDeployments?.length > 0}
|
||||
disableRedeploy={
|
||||
scheduledOrPendingDeployments?.length > 0 ||
|
||||
isDeploymentInProgress
|
||||
}
|
||||
/>
|
||||
|
||||
{index !== deployments.length - 1 && <Divider component="li" />}
|
||||
|
||||
@@ -21,8 +21,6 @@ import { discordAnnounce } from '@/utils/discordAnnounce';
|
||||
import { getPreviousApplicationState } from '@/utils/getPreviousApplicationState';
|
||||
import { getApplicationStatusString } from '@/utils/helpers';
|
||||
import { triggerToast } from '@/utils/toast';
|
||||
import { updateOwnCache } from '@/utils/updateOwnCache';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { useUserData } from '@nhost/nextjs';
|
||||
import Image from 'next/image';
|
||||
import { useState } from 'react';
|
||||
@@ -32,7 +30,11 @@ import { RemoveApplicationModal } from './RemoveApplicationModal';
|
||||
import { StagingMetadata } from './StagingMetadata';
|
||||
|
||||
export default function ApplicationErrored() {
|
||||
const { currentWorkspace, currentProject } = useCurrentWorkspaceAndProject();
|
||||
const {
|
||||
currentWorkspace,
|
||||
currentProject,
|
||||
refetch: refetchProject,
|
||||
} = useCurrentWorkspaceAndProject();
|
||||
const [changingApplicationStateLoading, setChangingApplicationStateLoading] =
|
||||
useState(false);
|
||||
|
||||
@@ -54,7 +56,6 @@ export default function ApplicationErrored() {
|
||||
const [showRecreateModal, setShowRecreateModal] = useState(false);
|
||||
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
||||
const [insertApp] = useInsertApplicationMutation();
|
||||
const client = useApolloClient();
|
||||
const { currentDate } = useCurrentDate();
|
||||
const user = useUserData();
|
||||
const isOwner = useIsCurrentUserOwner();
|
||||
@@ -94,7 +95,7 @@ export default function ApplicationErrored() {
|
||||
});
|
||||
discordAnnounce(`Recreating: ${currentProject?.name} (${user.email})`);
|
||||
triggerToast(`Recreating ${currentProject?.name} `);
|
||||
await updateOwnCache(client);
|
||||
await refetchProject();
|
||||
} catch (e) {
|
||||
triggerToast(`Error trying to recreate: ${currentProject?.name}`);
|
||||
}
|
||||
|
||||
@@ -18,18 +18,14 @@ import { toast } from 'react-hot-toast';
|
||||
export default function ApplicationInfo() {
|
||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||
const [deleteApplication] = useDeleteApplicationMutation({
|
||||
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||
refetchQueries: [{ query: GetAllWorkspacesAndProjectsDocument }],
|
||||
});
|
||||
const router = useRouter();
|
||||
|
||||
async function handleClickRemove() {
|
||||
try {
|
||||
await toast.promise(
|
||||
deleteApplication({
|
||||
variables: {
|
||||
appId: currentProject.id,
|
||||
},
|
||||
}),
|
||||
deleteApplication({ variables: { appId: currentProject.id } }),
|
||||
{
|
||||
loading: 'Deleting project...',
|
||||
success: 'The project has been deleted successfully.',
|
||||
|
||||
@@ -35,7 +35,7 @@ export default function ApplicationPaused() {
|
||||
const [showDeletingModal, setShowDeletingModal] = useState(false);
|
||||
const [unpauseApplication, { loading: changingApplicationStateLoading }] =
|
||||
useUnpauseApplicationMutation({
|
||||
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||
refetchQueries: [{ query: GetAllWorkspacesAndProjectsDocument }],
|
||||
});
|
||||
|
||||
const { data, loading } = useGetFreeAndActiveProjectsQuery({
|
||||
|
||||
@@ -46,7 +46,7 @@ export function RemoveApplicationModal({
|
||||
className,
|
||||
}: RemoveApplicationModalProps) {
|
||||
const [deleteApplication] = useDeleteApplicationMutation({
|
||||
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||
refetchQueries: [{ query: GetAllWorkspacesAndProjectsDocument }],
|
||||
});
|
||||
const [loadingRemove, setLoadingRemove] = useState(false);
|
||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||
|
||||
@@ -8,8 +8,6 @@ import Button from '@/ui/v2/Button';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import { discordAnnounce } from '@/utils/discordAnnounce';
|
||||
import { triggerToast } from '@/utils/toast';
|
||||
import { updateOwnCache } from '@/utils/updateOwnCache';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { ErrorBoundary } from 'react-error-boundary';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import { RepoAndBranch } from './RepoAndBranch';
|
||||
@@ -27,12 +25,11 @@ export function EditRepositorySettingsModal({
|
||||
const isNotCompleted = !watch('productionBranch') || !watch('repoBaseFolder');
|
||||
const { closeAlertDialog } = useDialog();
|
||||
|
||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||
const { currentProject, refetch: refetchProject } =
|
||||
useCurrentWorkspaceAndProject();
|
||||
|
||||
const [updateApp, { loading }] = useUpdateApplicationMutation();
|
||||
|
||||
const client = useApolloClient();
|
||||
|
||||
const handleEditGitHubIntegration = async (
|
||||
data: EditRepositorySettingsFormData,
|
||||
) => {
|
||||
@@ -60,7 +57,8 @@ export function EditRepositorySettingsModal({
|
||||
});
|
||||
}
|
||||
|
||||
await updateOwnCache(client);
|
||||
await refetchProject();
|
||||
|
||||
if (close) {
|
||||
close();
|
||||
} else {
|
||||
|
||||
@@ -5,16 +5,20 @@ import { Avatar } from '@/ui/Avatar';
|
||||
import type { DeploymentStatus } from '@/ui/StatusCircle';
|
||||
import { StatusCircle } from '@/ui/StatusCircle';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Chip from '@/ui/v2/Chip';
|
||||
import { Chip } from '@/ui/v2/Chip';
|
||||
import { ListItem } from '@/ui/v2/ListItem';
|
||||
import Tooltip from '@/ui/v2/Tooltip';
|
||||
import { Tooltip } from '@/ui/v2/Tooltip';
|
||||
import ArrowCounterclockwiseIcon from '@/ui/v2/icons/ArrowCounterclockwiseIcon';
|
||||
import ChevronRightIcon from '@/ui/v2/icons/ChevronRightIcon';
|
||||
import type { DeploymentRowFragment } from '@/utils/__generated__/graphql';
|
||||
import { useInsertDeploymentMutation } from '@/utils/__generated__/graphql';
|
||||
import {
|
||||
GetAllWorkspacesAndProjectsDocument,
|
||||
useInsertDeploymentMutation,
|
||||
} from '@/utils/__generated__/graphql';
|
||||
import getServerError from '@/utils/settings/getServerError';
|
||||
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
||||
import { formatDistanceToNowStrict, parseISO } from 'date-fns';
|
||||
import type { MouseEvent } from 'react';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
@@ -52,9 +56,39 @@ export default function DeploymentListItem({
|
||||
})
|
||||
: '';
|
||||
|
||||
const [insertDeployment, { loading }] = useInsertDeploymentMutation();
|
||||
const [insertDeployment, { loading }] = useInsertDeploymentMutation({
|
||||
refetchQueries: [{ query: GetAllWorkspacesAndProjectsDocument }],
|
||||
});
|
||||
const { commitMessage } = deployment;
|
||||
|
||||
async function redeployDeployment(event: MouseEvent<HTMLButtonElement>) {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
const insertDeploymentPromise = insertDeployment({
|
||||
variables: {
|
||||
object: {
|
||||
appId: currentProject?.id,
|
||||
commitMessage: deployment.commitMessage,
|
||||
commitSHA: deployment.commitSHA,
|
||||
commitUserAvatarUrl: deployment.commitUserAvatarUrl,
|
||||
commitUserName: deployment.commitUserName,
|
||||
deploymentStatus: 'SCHEDULED',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await toast.promise(
|
||||
insertDeploymentPromise,
|
||||
{
|
||||
loading: 'Scheduling deployment...',
|
||||
success: 'Deployment has been scheduled successfully.',
|
||||
error: getServerError('An error occurred when scheduling deployment.'),
|
||||
},
|
||||
getToastStyleProps(),
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ListItem.Root>
|
||||
<ListItem.Button
|
||||
@@ -88,7 +122,7 @@ export default function DeploymentListItem({
|
||||
{showRedeploy && (
|
||||
<Tooltip
|
||||
title={
|
||||
!disableRedeploy && !loading
|
||||
disableRedeploy || loading
|
||||
? 'Deployments cannot be re-triggered when a deployment is in progress.'
|
||||
: ''
|
||||
}
|
||||
@@ -100,35 +134,7 @@ export default function DeploymentListItem({
|
||||
size="small"
|
||||
color="secondary"
|
||||
variant="outlined"
|
||||
onClick={async (event) => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
|
||||
const insertDeploymentPromise = insertDeployment({
|
||||
variables: {
|
||||
object: {
|
||||
appId: currentProject?.id,
|
||||
commitMessage: deployment.commitMessage,
|
||||
commitSHA: deployment.commitSHA,
|
||||
commitUserAvatarUrl: deployment.commitUserAvatarUrl,
|
||||
commitUserName: deployment.commitUserName,
|
||||
deploymentStatus: 'SCHEDULED',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await toast.promise(
|
||||
insertDeploymentPromise,
|
||||
{
|
||||
loading: 'Scheduling deployment...',
|
||||
success: 'Deployment has been scheduled successfully.',
|
||||
error: getServerError(
|
||||
'An error occurred when scheduling deployment.',
|
||||
),
|
||||
},
|
||||
getToastStyleProps(),
|
||||
);
|
||||
}}
|
||||
onClick={redeployDeployment}
|
||||
startIcon={
|
||||
<ArrowCounterclockwiseIcon className={twMerge('h-4 w-4')} />
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import Button from '@/ui/v2/Button';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import { nhost } from '@/utils/nhost';
|
||||
import { triggerToast } from '@/utils/toast';
|
||||
import { updateOwnCache } from '@/utils/updateOwnCache';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { alpha } from '@mui/system';
|
||||
import { useUserData } from '@nhost/nextjs';
|
||||
@@ -28,13 +27,18 @@ export function InviteAnnounce() {
|
||||
useSubmitState();
|
||||
|
||||
// @FIX: We probably don't want to poll every ten seconds for possible invites. (We can change later depending on how it works in production.) Maybe just on the workspace page?
|
||||
const { data, loading, error, refetch, startPolling } =
|
||||
useGetWorkspaceMemberInvitesToManageQuery({
|
||||
variables: {
|
||||
userId: user?.id,
|
||||
},
|
||||
skip: !isPlatform || !user,
|
||||
});
|
||||
const {
|
||||
data,
|
||||
loading,
|
||||
error,
|
||||
refetch: refetchInvitations,
|
||||
startPolling,
|
||||
} = useGetWorkspaceMemberInvitesToManageQuery({
|
||||
variables: {
|
||||
userId: user?.id,
|
||||
},
|
||||
skip: !isPlatform || !user,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
startPolling(15000);
|
||||
@@ -79,9 +83,14 @@ export function InviteAnnounce() {
|
||||
});
|
||||
}
|
||||
|
||||
await updateOwnCache(client);
|
||||
await client.refetchQueries({
|
||||
include: [
|
||||
GetAllWorkspacesAndProjectsDocument,
|
||||
GetWorkspaceMemberInvitesToManageDocument,
|
||||
],
|
||||
});
|
||||
await router.push(`/${invite.workspace.slug}`);
|
||||
await refetch();
|
||||
await refetchInvitations();
|
||||
triggerToast('Workspace invite accepted');
|
||||
return setSubmitState({
|
||||
error: null,
|
||||
|
||||
@@ -207,19 +207,6 @@ export default function WorkspaceAndProjectList({
|
||||
</div>
|
||||
))}
|
||||
</Box>
|
||||
|
||||
<Text className="font-medium" color="secondary">
|
||||
Looking for your old apps? They're still on{' '}
|
||||
<Link
|
||||
href="https://console.nhost.io"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
underline="always"
|
||||
>
|
||||
console.nhost.io
|
||||
</Link>{' '}
|
||||
during this beta.
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -119,6 +119,9 @@ function OverviewDeploymentList() {
|
||||
const liveDeploymentId = getLastLiveDeployment(deployments);
|
||||
const { deployments: scheduledOrPendingDeployments } =
|
||||
scheduledOrPendingDeploymentsData || { deployments: [] };
|
||||
const isDeploymentInProgress = deployments?.some((deployment) =>
|
||||
['PENDING', 'SCHEDULED'].includes(deployment.deploymentStatus),
|
||||
);
|
||||
|
||||
return (
|
||||
<List
|
||||
@@ -131,7 +134,10 @@ function OverviewDeploymentList() {
|
||||
deployment={deployment}
|
||||
isLive={deployment.id === liveDeploymentId}
|
||||
showRedeploy={index === 0}
|
||||
disableRedeploy={scheduledOrPendingDeployments?.length > 0}
|
||||
disableRedeploy={
|
||||
scheduledOrPendingDeployments?.length > 0 ||
|
||||
isDeploymentInProgress
|
||||
}
|
||||
/>
|
||||
|
||||
{index !== deployments.length - 1 && <Divider component="li" />}
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './BaseDirectorySettings';
|
||||
export { default } from './BaseDirectorySettings';
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './DeploymentBranchSettings';
|
||||
export { default } from './DeploymentBranchSettings';
|
||||
@@ -1,2 +1,2 @@
|
||||
export * from './Chip';
|
||||
export { default } from './Chip';
|
||||
export { default as Chip, default } from './Chip';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export * from './Tooltip';
|
||||
export { default } from './Tooltip';
|
||||
export { default as Tooltip, default } from './Tooltip';
|
||||
export * from './useTooltip';
|
||||
export { default as useTooltip } from './useTooltip';
|
||||
|
||||
@@ -4,6 +4,7 @@ import { ApplicationStatus } from '@/types/application';
|
||||
import { GetWorkspaceAndProjectDocument } from '@/utils/__generated__/graphql';
|
||||
import { getHasuraAdminSecret } from '@/utils/env';
|
||||
import { useNhostClient, useUserData } from '@nhost/nextjs';
|
||||
import type { RefetchOptions } from '@tanstack/react-query';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useMemo } from 'react';
|
||||
@@ -28,7 +29,7 @@ export interface UseCurrentWorkspaceAndProjectReturnType {
|
||||
/**
|
||||
* Refetch the query.
|
||||
*/
|
||||
refetch: (options?: any) => Promise<any>;
|
||||
refetch: (options?: RefetchOptions) => Promise<any>;
|
||||
}
|
||||
|
||||
export default function useCurrentWorkspaceAndProject(): UseCurrentWorkspaceAndProjectReturnType {
|
||||
@@ -49,7 +50,7 @@ export default function useCurrentWorkspaceAndProject(): UseCurrentWorkspaceAndP
|
||||
isFetching,
|
||||
refetch,
|
||||
} = useQuery(
|
||||
['currentWorkspaceAndProject', workspaceSlug],
|
||||
['currentWorkspaceAndProject', workspaceSlug, appSlug],
|
||||
() =>
|
||||
client.graphql.request<{
|
||||
workspaces: Workspace[];
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './BaseDirectorySettings';
|
||||
export { default as BaseDirectorySettings } from './BaseDirectorySettings';
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './DeploymentBranchSettings';
|
||||
export { default as DeploymentBranchSettings } from './DeploymentBranchSettings';
|
||||
@@ -0,0 +1,86 @@
|
||||
import useGitHubModal from '@/components/applications/github/useGitHubModal';
|
||||
import { useDialog } from '@/components/common/DialogProvider';
|
||||
import GithubIcon from '@/components/icons/GithubIcon';
|
||||
import SettingsContainer from '@/components/settings/SettingsContainer';
|
||||
import { useUI } from '@/context/UIContext';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Text from '@/ui/v2/Text/Text';
|
||||
import { useUpdateApplicationMutation } from '@/utils/__generated__/graphql';
|
||||
import { triggerToast } from '@/utils/toast';
|
||||
|
||||
export default function GitConnectionSettings() {
|
||||
const { maintenanceActive } = useUI();
|
||||
const { currentProject, refetch } = useCurrentWorkspaceAndProject();
|
||||
const [updateApp] = useUpdateApplicationMutation();
|
||||
const { openAlertDialog } = useDialog();
|
||||
const { openGitHubModal } = useGitHubModal();
|
||||
|
||||
function handleConnect() {
|
||||
openAlertDialog({
|
||||
title: 'Disconnect GitHub Repository',
|
||||
payload: (
|
||||
<p>
|
||||
Are you sure you want to disconnect{' '}
|
||||
<b>{currentProject.githubRepository.fullName}</b>?
|
||||
</p>
|
||||
),
|
||||
props: {
|
||||
primaryButtonText: 'Disconnect GitHub Repository',
|
||||
primaryButtonColor: 'error',
|
||||
onPrimaryAction: async () => {
|
||||
await updateApp({
|
||||
variables: {
|
||||
appId: currentProject.id,
|
||||
app: {
|
||||
githubRepositoryId: null,
|
||||
},
|
||||
},
|
||||
});
|
||||
triggerToast(
|
||||
`Successfully disconnected GitHub repository from ${currentProject.name}.`,
|
||||
);
|
||||
await refetch();
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingsContainer
|
||||
title="Git Repository"
|
||||
description="Create Deployments for commits pushed to your Git repository."
|
||||
docsLink="https://docs.nhost.io/platform/github-integration"
|
||||
slotProps={{ submitButton: { className: 'hidden' } }}
|
||||
className="grid grid-cols-5"
|
||||
>
|
||||
{!currentProject.githubRepository ? (
|
||||
<Button
|
||||
onClick={openGitHubModal}
|
||||
className="col-span-5 grid grid-flow-col gap-1.5 xs:col-span-3 lg:col-span-2"
|
||||
startIcon={<GithubIcon className="h-4 w-4 self-center" />}
|
||||
disabled={maintenanceActive}
|
||||
>
|
||||
Connect to GitHub
|
||||
</Button>
|
||||
) : (
|
||||
<Box className="col-span-5 flex flex-row place-content-between items-center rounded-lg border px-4 py-4">
|
||||
<div className="ml-2 flex flex-row">
|
||||
<GithubIcon className="mr-1.5 h-7 w-7 self-center" />
|
||||
<Text className="self-center font-normal">
|
||||
{currentProject.githubRepository.fullName}
|
||||
</Text>
|
||||
</div>
|
||||
<Button
|
||||
disabled={maintenanceActive}
|
||||
variant="borderless"
|
||||
onClick={handleConnect}
|
||||
>
|
||||
Disconnect
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</SettingsContainer>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default as GitConnectionSettings } from './GitConnectionSettings';
|
||||
@@ -20,7 +20,7 @@ subscription ScheduledOrPendingDeploymentsSub($appId: uuid!) {
|
||||
subscription LatestLiveDeploymentSub($appId: uuid!) {
|
||||
deployments(
|
||||
where: { deploymentStatus: { _eq: "DEPLOYED" }, appId: { _eq: $appId } }
|
||||
order_by: { deploymentEndedAt: desc }
|
||||
order_by: { deploymentStartedAt: desc }
|
||||
limit: 1
|
||||
offset: 0
|
||||
) {
|
||||
|
||||
@@ -48,7 +48,7 @@ fragment Project on apps {
|
||||
githubRepository {
|
||||
fullName
|
||||
}
|
||||
deployments(limit: 4, order_by: { deploymentEndedAt: desc }) {
|
||||
deployments(limit: 4, order_by: { deploymentStartedAt: desc }) {
|
||||
id
|
||||
commitSHA
|
||||
commitMessage
|
||||
|
||||
@@ -10,20 +10,21 @@ import { useMemo } from 'react';
|
||||
*/
|
||||
export function useRemoteApplicationGQLClient() {
|
||||
const { currentProject, loading } = useCurrentWorkspaceAndProject();
|
||||
const serviceUrl = generateAppServiceUrl(
|
||||
currentProject?.subdomain,
|
||||
currentProject?.region,
|
||||
'graphql',
|
||||
);
|
||||
|
||||
const userApplicationClient = useMemo(() => {
|
||||
if (loading) {
|
||||
if (loading || !serviceUrl) {
|
||||
return new ApolloClient({ cache: new InMemoryCache() });
|
||||
}
|
||||
|
||||
return new ApolloClient({
|
||||
cache: new InMemoryCache(),
|
||||
link: new HttpLink({
|
||||
uri: generateAppServiceUrl(
|
||||
currentProject?.subdomain,
|
||||
currentProject?.region,
|
||||
'graphql',
|
||||
),
|
||||
uri: serviceUrl,
|
||||
headers: {
|
||||
'x-hasura-admin-secret':
|
||||
process.env.NEXT_PUBLIC_ENV === 'dev'
|
||||
@@ -32,12 +33,7 @@ export function useRemoteApplicationGQLClient() {
|
||||
},
|
||||
}),
|
||||
});
|
||||
}, [
|
||||
loading,
|
||||
currentProject?.subdomain,
|
||||
currentProject?.region,
|
||||
currentProject?.config?.hasura.adminSecret,
|
||||
]);
|
||||
}, [loading, serviceUrl, currentProject?.config?.hasura.adminSecret]);
|
||||
|
||||
return userApplicationClient;
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@ import {
|
||||
usePauseApplicationMutation,
|
||||
useUpdateApplicationMutation,
|
||||
} from '@/generated/graphql';
|
||||
import ActivityIndicator from '@/ui/v2/ActivityIndicator';
|
||||
import Input from '@/ui/v2/Input';
|
||||
import { discordAnnounce } from '@/utils/discordAnnounce';
|
||||
import { slugifyString } from '@/utils/helpers';
|
||||
import getServerError from '@/utils/settings/getServerError';
|
||||
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { useRouter } from 'next/router';
|
||||
import type { ReactElement } from 'react';
|
||||
@@ -38,18 +38,22 @@ export type ProjectNameValidationSchema = Yup.InferType<
|
||||
>;
|
||||
|
||||
export default function SettingsGeneralPage() {
|
||||
const { currentWorkspace, currentProject } = useCurrentWorkspaceAndProject();
|
||||
const {
|
||||
currentWorkspace,
|
||||
currentProject,
|
||||
loading,
|
||||
refetch: refetchWorkspaceAndProject,
|
||||
} = useCurrentWorkspaceAndProject();
|
||||
const isOwner = useIsCurrentUserOwner();
|
||||
const { openDialog, openAlertDialog, closeDialog } = useDialog();
|
||||
const [updateApp] = useUpdateApplicationMutation();
|
||||
const client = useApolloClient();
|
||||
const [pauseApplication] = usePauseApplicationMutation({
|
||||
variables: { appId: currentProject?.id },
|
||||
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||
refetchQueries: [{ query: GetAllWorkspacesAndProjectsDocument }],
|
||||
});
|
||||
const [deleteApplication] = useDeleteApplicationMutation({
|
||||
variables: { appId: currentProject?.id },
|
||||
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||
refetchQueries: [{ query: GetAllWorkspacesAndProjectsDocument }],
|
||||
});
|
||||
const router = useRouter();
|
||||
const { maintenanceActive } = useUI();
|
||||
@@ -98,7 +102,7 @@ export default function SettingsGeneralPage() {
|
||||
});
|
||||
|
||||
try {
|
||||
await toast.promise(
|
||||
const { data: updateAppData } = await toast.promise(
|
||||
updateAppMutation,
|
||||
{
|
||||
loading: `Project name is being updated...`,
|
||||
@@ -109,24 +113,24 @@ export default function SettingsGeneralPage() {
|
||||
},
|
||||
getToastStyleProps(),
|
||||
);
|
||||
|
||||
const updateAppResult = updateAppData?.updateApp;
|
||||
|
||||
if (!updateAppResult) {
|
||||
await discordAnnounce('Failed to update project name.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
form.reset(undefined, { keepValues: true, keepDirty: false });
|
||||
|
||||
await refetchWorkspaceAndProject();
|
||||
await router.replace(
|
||||
`/${currentWorkspace.slug}/${updateAppResult.slug}/settings/general`,
|
||||
);
|
||||
} catch {
|
||||
// Note: The toast will handle the error.
|
||||
}
|
||||
|
||||
try {
|
||||
form.reset(undefined, { keepValues: true, keepDirty: false });
|
||||
await router.push(
|
||||
`/${currentWorkspace.slug}/${newProjectSlug}/settings/general`,
|
||||
);
|
||||
await client.refetchQueries({
|
||||
include: [GetAllWorkspacesAndProjectsDocument],
|
||||
});
|
||||
} catch (error) {
|
||||
await discordAnnounce(
|
||||
error.message ||
|
||||
'An error occurred while trying to update application cache.',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function handleDeleteApplication() {
|
||||
@@ -161,6 +165,10 @@ export default function SettingsGeneralPage() {
|
||||
await router.push('/');
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return <ActivityIndicator label="Loading project..." />;
|
||||
}
|
||||
|
||||
return (
|
||||
<Container
|
||||
className="grid max-w-5xl grid-flow-row gap-8 bg-transparent"
|
||||
@@ -195,7 +203,7 @@ export default function SettingsGeneralPage() {
|
||||
</Form>
|
||||
</FormProvider>
|
||||
|
||||
{currentProject.plan.isFree && (
|
||||
{currentProject?.plan.isFree && (
|
||||
<SettingsContainer
|
||||
title="Pause Project"
|
||||
description="While your project is paused, it will not be accessible. You can wake it up anytime after."
|
||||
|
||||
@@ -1,104 +1,23 @@
|
||||
import useGitHubModal from '@/components/applications/github/useGitHubModal';
|
||||
import { useDialog } from '@/components/common/DialogProvider';
|
||||
import GithubIcon from '@/components/icons/GithubIcon';
|
||||
import Container from '@/components/layout/Container';
|
||||
import SettingsContainer from '@/components/settings/SettingsContainer';
|
||||
import SettingsLayout from '@/components/settings/SettingsLayout';
|
||||
import BaseDirectorySettings from '@/components/settings/git/BaseDirectorySettings';
|
||||
import DeploymentBranchSettings from '@/components/settings/git/DeploymentBranchSettings';
|
||||
import { useUI } from '@/context/UIContext';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useUpdateApplicationMutation } from '@/generated/graphql';
|
||||
import Box from '@/ui/v2/Box';
|
||||
import Button from '@/ui/v2/Button';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import { triggerToast } from '@/utils/toast';
|
||||
import { updateOwnCache } from '@/utils/updateOwnCache';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { BaseDirectorySettings } from '@/features/projects/settings/git/components/BaseDirectorySettings';
|
||||
import { DeploymentBranchSettings } from '@/features/projects/settings/git/components/DeploymentBranchSettings';
|
||||
import { GitConnectionSettings } from '@/features/projects/settings/git/components/GitConnectionSettings';
|
||||
import type { ReactElement } from 'react';
|
||||
|
||||
export default function SettingsGitPage() {
|
||||
const { maintenanceActive } = useUI();
|
||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||
const { openGitHubModal } = useGitHubModal();
|
||||
const { openAlertDialog } = useDialog();
|
||||
const client = useApolloClient();
|
||||
|
||||
const [updateApp] = useUpdateApplicationMutation();
|
||||
|
||||
export default function GitSettingsPage() {
|
||||
return (
|
||||
<Container
|
||||
className="grid max-w-5xl grid-flow-row gap-y-6 bg-transparent"
|
||||
rootClassName="bg-transparent"
|
||||
>
|
||||
<SettingsContainer
|
||||
title="Git Repository"
|
||||
description="Create Deployments for commits pushed to your Git repository."
|
||||
docsLink="https://docs.nhost.io/platform/github-integration"
|
||||
slotProps={{ submitButton: { className: 'hidden' } }}
|
||||
className="grid grid-cols-5"
|
||||
>
|
||||
{!currentProject.githubRepository ? (
|
||||
<Button
|
||||
onClick={openGitHubModal}
|
||||
className="col-span-5 grid grid-flow-col gap-1.5 xs:col-span-3 lg:col-span-2"
|
||||
startIcon={<GithubIcon className="h-4 w-4 self-center" />}
|
||||
disabled={maintenanceActive}
|
||||
>
|
||||
Connect to GitHub
|
||||
</Button>
|
||||
) : (
|
||||
<Box className="col-span-5 flex flex-row place-content-between items-center rounded-lg border px-4 py-4">
|
||||
<div className="ml-2 flex flex-row">
|
||||
<GithubIcon className="mr-1.5 h-7 w-7 self-center" />
|
||||
<Text className="self-center font-normal">
|
||||
{currentProject.githubRepository.fullName}
|
||||
</Text>
|
||||
</div>
|
||||
<Button
|
||||
disabled={maintenanceActive}
|
||||
variant="borderless"
|
||||
onClick={() => {
|
||||
openAlertDialog({
|
||||
title: 'Disconnect GitHub Repository',
|
||||
payload: (
|
||||
<p>
|
||||
Are you sure you want to disconnect{' '}
|
||||
<b>{currentProject.githubRepository.fullName}</b>?
|
||||
</p>
|
||||
),
|
||||
props: {
|
||||
primaryButtonText: 'Disconnect GitHub Repository',
|
||||
primaryButtonColor: 'error',
|
||||
onPrimaryAction: async () => {
|
||||
await updateApp({
|
||||
variables: {
|
||||
appId: currentProject.id,
|
||||
app: {
|
||||
githubRepositoryId: null,
|
||||
},
|
||||
},
|
||||
});
|
||||
triggerToast(
|
||||
`Successfully disconnected GitHub repository from ${currentProject.name}.`,
|
||||
);
|
||||
await updateOwnCache(client);
|
||||
},
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
Disconnect
|
||||
</Button>
|
||||
</Box>
|
||||
)}
|
||||
</SettingsContainer>
|
||||
<GitConnectionSettings />
|
||||
<DeploymentBranchSettings />
|
||||
<BaseDirectorySettings />
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
SettingsGitPage.getLayout = function getLayout(page: ReactElement) {
|
||||
GitSettingsPage.getLayout = function getLayout(page: ReactElement) {
|
||||
return <SettingsLayout>{page}</SettingsLayout>;
|
||||
};
|
||||
|
||||
@@ -81,12 +81,6 @@ export default function IndexPage() {
|
||||
</Button>
|
||||
</NavLink>
|
||||
</div>
|
||||
<div>
|
||||
<Text className="mt-9 opacity-70" sx={{ color: 'common.white' }}>
|
||||
Looking for your old apps? They're still on
|
||||
console.nhost.io during this beta.
|
||||
</Text>
|
||||
</div>
|
||||
</div>
|
||||
</Box>
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ export function NewProjectPageContent({
|
||||
const { submitState, setSubmitState } = useSubmitState();
|
||||
|
||||
const [insertApp] = useInsertApplicationMutation({
|
||||
refetchQueries: [GetAllWorkspacesAndProjectsDocument],
|
||||
refetchQueries: [{ query: GetAllWorkspacesAndProjectsDocument }],
|
||||
});
|
||||
|
||||
// options
|
||||
|
||||
350
dashboard/src/utils/__generated__/graphql.ts
generated
350
dashboard/src/utils/__generated__/graphql.ts
generated
@@ -3563,6 +3563,183 @@ export type AuthProviders_Updates = {
|
||||
where: AuthProviders_Bool_Exp;
|
||||
};
|
||||
|
||||
/** columns and relationships of "auth.refresh_token_types" */
|
||||
export type AuthRefreshTokenTypes = {
|
||||
__typename?: 'authRefreshTokenTypes';
|
||||
comment?: Maybe<Scalars['String']>;
|
||||
/** An array relationship */
|
||||
refreshTokens: Array<AuthRefreshTokens>;
|
||||
/** An aggregate relationship */
|
||||
refreshTokens_aggregate: AuthRefreshTokens_Aggregate;
|
||||
value: Scalars['String'];
|
||||
};
|
||||
|
||||
|
||||
/** columns and relationships of "auth.refresh_token_types" */
|
||||
export type AuthRefreshTokenTypesRefreshTokensArgs = {
|
||||
distinct_on?: InputMaybe<Array<AuthRefreshTokens_Select_Column>>;
|
||||
limit?: InputMaybe<Scalars['Int']>;
|
||||
offset?: InputMaybe<Scalars['Int']>;
|
||||
order_by?: InputMaybe<Array<AuthRefreshTokens_Order_By>>;
|
||||
where?: InputMaybe<AuthRefreshTokens_Bool_Exp>;
|
||||
};
|
||||
|
||||
|
||||
/** columns and relationships of "auth.refresh_token_types" */
|
||||
export type AuthRefreshTokenTypesRefreshTokens_AggregateArgs = {
|
||||
distinct_on?: InputMaybe<Array<AuthRefreshTokens_Select_Column>>;
|
||||
limit?: InputMaybe<Scalars['Int']>;
|
||||
offset?: InputMaybe<Scalars['Int']>;
|
||||
order_by?: InputMaybe<Array<AuthRefreshTokens_Order_By>>;
|
||||
where?: InputMaybe<AuthRefreshTokens_Bool_Exp>;
|
||||
};
|
||||
|
||||
/** aggregated selection of "auth.refresh_token_types" */
|
||||
export type AuthRefreshTokenTypes_Aggregate = {
|
||||
__typename?: 'authRefreshTokenTypes_aggregate';
|
||||
aggregate?: Maybe<AuthRefreshTokenTypes_Aggregate_Fields>;
|
||||
nodes: Array<AuthRefreshTokenTypes>;
|
||||
};
|
||||
|
||||
/** aggregate fields of "auth.refresh_token_types" */
|
||||
export type AuthRefreshTokenTypes_Aggregate_Fields = {
|
||||
__typename?: 'authRefreshTokenTypes_aggregate_fields';
|
||||
count: Scalars['Int'];
|
||||
max?: Maybe<AuthRefreshTokenTypes_Max_Fields>;
|
||||
min?: Maybe<AuthRefreshTokenTypes_Min_Fields>;
|
||||
};
|
||||
|
||||
|
||||
/** aggregate fields of "auth.refresh_token_types" */
|
||||
export type AuthRefreshTokenTypes_Aggregate_FieldsCountArgs = {
|
||||
columns?: InputMaybe<Array<AuthRefreshTokenTypes_Select_Column>>;
|
||||
distinct?: InputMaybe<Scalars['Boolean']>;
|
||||
};
|
||||
|
||||
/** Boolean expression to filter rows from the table "auth.refresh_token_types". All fields are combined with a logical 'AND'. */
|
||||
export type AuthRefreshTokenTypes_Bool_Exp = {
|
||||
_and?: InputMaybe<Array<AuthRefreshTokenTypes_Bool_Exp>>;
|
||||
_not?: InputMaybe<AuthRefreshTokenTypes_Bool_Exp>;
|
||||
_or?: InputMaybe<Array<AuthRefreshTokenTypes_Bool_Exp>>;
|
||||
comment?: InputMaybe<String_Comparison_Exp>;
|
||||
refreshTokens?: InputMaybe<AuthRefreshTokens_Bool_Exp>;
|
||||
refreshTokens_aggregate?: InputMaybe<AuthRefreshTokens_Aggregate_Bool_Exp>;
|
||||
value?: InputMaybe<String_Comparison_Exp>;
|
||||
};
|
||||
|
||||
/** unique or primary key constraints on table "auth.refresh_token_types" */
|
||||
export enum AuthRefreshTokenTypes_Constraint {
|
||||
/** unique or primary key constraint on columns "value" */
|
||||
RefreshTokenTypesPkey = 'refresh_token_types_pkey'
|
||||
}
|
||||
|
||||
export enum AuthRefreshTokenTypes_Enum {
|
||||
/** Personal access token */
|
||||
Pat = 'pat',
|
||||
/** Regular refresh token */
|
||||
Regular = 'regular'
|
||||
}
|
||||
|
||||
/** Boolean expression to compare columns of type "authRefreshTokenTypes_enum". All fields are combined with logical 'AND'. */
|
||||
export type AuthRefreshTokenTypes_Enum_Comparison_Exp = {
|
||||
_eq?: InputMaybe<AuthRefreshTokenTypes_Enum>;
|
||||
_in?: InputMaybe<Array<AuthRefreshTokenTypes_Enum>>;
|
||||
_is_null?: InputMaybe<Scalars['Boolean']>;
|
||||
_neq?: InputMaybe<AuthRefreshTokenTypes_Enum>;
|
||||
_nin?: InputMaybe<Array<AuthRefreshTokenTypes_Enum>>;
|
||||
};
|
||||
|
||||
/** input type for inserting data into table "auth.refresh_token_types" */
|
||||
export type AuthRefreshTokenTypes_Insert_Input = {
|
||||
comment?: InputMaybe<Scalars['String']>;
|
||||
refreshTokens?: InputMaybe<AuthRefreshTokens_Arr_Rel_Insert_Input>;
|
||||
value?: InputMaybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
/** aggregate max on columns */
|
||||
export type AuthRefreshTokenTypes_Max_Fields = {
|
||||
__typename?: 'authRefreshTokenTypes_max_fields';
|
||||
comment?: Maybe<Scalars['String']>;
|
||||
value?: Maybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
/** aggregate min on columns */
|
||||
export type AuthRefreshTokenTypes_Min_Fields = {
|
||||
__typename?: 'authRefreshTokenTypes_min_fields';
|
||||
comment?: Maybe<Scalars['String']>;
|
||||
value?: Maybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
/** response of any mutation on the table "auth.refresh_token_types" */
|
||||
export type AuthRefreshTokenTypes_Mutation_Response = {
|
||||
__typename?: 'authRefreshTokenTypes_mutation_response';
|
||||
/** number of rows affected by the mutation */
|
||||
affected_rows: Scalars['Int'];
|
||||
/** data from the rows affected by the mutation */
|
||||
returning: Array<AuthRefreshTokenTypes>;
|
||||
};
|
||||
|
||||
/** on_conflict condition type for table "auth.refresh_token_types" */
|
||||
export type AuthRefreshTokenTypes_On_Conflict = {
|
||||
constraint: AuthRefreshTokenTypes_Constraint;
|
||||
update_columns?: Array<AuthRefreshTokenTypes_Update_Column>;
|
||||
where?: InputMaybe<AuthRefreshTokenTypes_Bool_Exp>;
|
||||
};
|
||||
|
||||
/** Ordering options when selecting data from "auth.refresh_token_types". */
|
||||
export type AuthRefreshTokenTypes_Order_By = {
|
||||
comment?: InputMaybe<Order_By>;
|
||||
refreshTokens_aggregate?: InputMaybe<AuthRefreshTokens_Aggregate_Order_By>;
|
||||
value?: InputMaybe<Order_By>;
|
||||
};
|
||||
|
||||
/** primary key columns input for table: auth.refresh_token_types */
|
||||
export type AuthRefreshTokenTypes_Pk_Columns_Input = {
|
||||
value: Scalars['String'];
|
||||
};
|
||||
|
||||
/** select columns of table "auth.refresh_token_types" */
|
||||
export enum AuthRefreshTokenTypes_Select_Column {
|
||||
/** column name */
|
||||
Comment = 'comment',
|
||||
/** column name */
|
||||
Value = 'value'
|
||||
}
|
||||
|
||||
/** input type for updating data in table "auth.refresh_token_types" */
|
||||
export type AuthRefreshTokenTypes_Set_Input = {
|
||||
comment?: InputMaybe<Scalars['String']>;
|
||||
value?: InputMaybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
/** Streaming cursor of the table "authRefreshTokenTypes" */
|
||||
export type AuthRefreshTokenTypes_Stream_Cursor_Input = {
|
||||
/** Stream column input with initial value */
|
||||
initial_value: AuthRefreshTokenTypes_Stream_Cursor_Value_Input;
|
||||
/** cursor ordering */
|
||||
ordering?: InputMaybe<Cursor_Ordering>;
|
||||
};
|
||||
|
||||
/** Initial value of the column from where the streaming should start */
|
||||
export type AuthRefreshTokenTypes_Stream_Cursor_Value_Input = {
|
||||
comment?: InputMaybe<Scalars['String']>;
|
||||
value?: InputMaybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
/** update columns of table "auth.refresh_token_types" */
|
||||
export enum AuthRefreshTokenTypes_Update_Column {
|
||||
/** column name */
|
||||
Comment = 'comment',
|
||||
/** column name */
|
||||
Value = 'value'
|
||||
}
|
||||
|
||||
export type AuthRefreshTokenTypes_Updates = {
|
||||
/** sets the columns of the filtered rows to the given values */
|
||||
_set?: InputMaybe<AuthRefreshTokenTypes_Set_Input>;
|
||||
where: AuthRefreshTokenTypes_Bool_Exp;
|
||||
};
|
||||
|
||||
/** User refresh tokens. Hasura auth uses them to rotate new access tokens as long as the refresh token is not expired. Don't modify its structure as Hasura Auth relies on it to function properly. */
|
||||
export type AuthRefreshTokens = {
|
||||
__typename?: 'authRefreshTokens';
|
||||
@@ -3570,9 +3747,9 @@ export type AuthRefreshTokens = {
|
||||
expiresAt: Scalars['timestamptz'];
|
||||
id: Scalars['uuid'];
|
||||
metadata?: Maybe<Scalars['jsonb']>;
|
||||
refreshToken?: Maybe<Scalars['uuid']>;
|
||||
refreshTokenHash?: Maybe<Scalars['String']>;
|
||||
type: Scalars['String'];
|
||||
refresh_token?: Maybe<Scalars['uuid']>;
|
||||
type: AuthRefreshTokenTypes_Enum;
|
||||
/** An object relationship */
|
||||
user: Users;
|
||||
userId: Scalars['uuid'];
|
||||
@@ -3645,9 +3822,9 @@ export type AuthRefreshTokens_Bool_Exp = {
|
||||
expiresAt?: InputMaybe<Timestamptz_Comparison_Exp>;
|
||||
id?: InputMaybe<Uuid_Comparison_Exp>;
|
||||
metadata?: InputMaybe<Jsonb_Comparison_Exp>;
|
||||
refreshToken?: InputMaybe<Uuid_Comparison_Exp>;
|
||||
refreshTokenHash?: InputMaybe<String_Comparison_Exp>;
|
||||
type?: InputMaybe<String_Comparison_Exp>;
|
||||
refresh_token?: InputMaybe<Uuid_Comparison_Exp>;
|
||||
type?: InputMaybe<AuthRefreshTokenTypes_Enum_Comparison_Exp>;
|
||||
user?: InputMaybe<Users_Bool_Exp>;
|
||||
userId?: InputMaybe<Uuid_Comparison_Exp>;
|
||||
};
|
||||
@@ -3679,9 +3856,9 @@ export type AuthRefreshTokens_Insert_Input = {
|
||||
expiresAt?: InputMaybe<Scalars['timestamptz']>;
|
||||
id?: InputMaybe<Scalars['uuid']>;
|
||||
metadata?: InputMaybe<Scalars['jsonb']>;
|
||||
refreshToken?: InputMaybe<Scalars['uuid']>;
|
||||
refreshTokenHash?: InputMaybe<Scalars['String']>;
|
||||
type?: InputMaybe<Scalars['String']>;
|
||||
refresh_token?: InputMaybe<Scalars['uuid']>;
|
||||
type?: InputMaybe<AuthRefreshTokenTypes_Enum>;
|
||||
user?: InputMaybe<Users_Obj_Rel_Insert_Input>;
|
||||
userId?: InputMaybe<Scalars['uuid']>;
|
||||
};
|
||||
@@ -3692,9 +3869,8 @@ export type AuthRefreshTokens_Max_Fields = {
|
||||
createdAt?: Maybe<Scalars['timestamptz']>;
|
||||
expiresAt?: Maybe<Scalars['timestamptz']>;
|
||||
id?: Maybe<Scalars['uuid']>;
|
||||
refreshToken?: Maybe<Scalars['uuid']>;
|
||||
refreshTokenHash?: Maybe<Scalars['String']>;
|
||||
type?: Maybe<Scalars['String']>;
|
||||
refresh_token?: Maybe<Scalars['uuid']>;
|
||||
userId?: Maybe<Scalars['uuid']>;
|
||||
};
|
||||
|
||||
@@ -3703,9 +3879,8 @@ export type AuthRefreshTokens_Max_Order_By = {
|
||||
createdAt?: InputMaybe<Order_By>;
|
||||
expiresAt?: InputMaybe<Order_By>;
|
||||
id?: InputMaybe<Order_By>;
|
||||
refreshToken?: InputMaybe<Order_By>;
|
||||
refreshTokenHash?: InputMaybe<Order_By>;
|
||||
type?: InputMaybe<Order_By>;
|
||||
refresh_token?: InputMaybe<Order_By>;
|
||||
userId?: InputMaybe<Order_By>;
|
||||
};
|
||||
|
||||
@@ -3715,9 +3890,8 @@ export type AuthRefreshTokens_Min_Fields = {
|
||||
createdAt?: Maybe<Scalars['timestamptz']>;
|
||||
expiresAt?: Maybe<Scalars['timestamptz']>;
|
||||
id?: Maybe<Scalars['uuid']>;
|
||||
refreshToken?: Maybe<Scalars['uuid']>;
|
||||
refreshTokenHash?: Maybe<Scalars['String']>;
|
||||
type?: Maybe<Scalars['String']>;
|
||||
refresh_token?: Maybe<Scalars['uuid']>;
|
||||
userId?: Maybe<Scalars['uuid']>;
|
||||
};
|
||||
|
||||
@@ -3726,9 +3900,8 @@ export type AuthRefreshTokens_Min_Order_By = {
|
||||
createdAt?: InputMaybe<Order_By>;
|
||||
expiresAt?: InputMaybe<Order_By>;
|
||||
id?: InputMaybe<Order_By>;
|
||||
refreshToken?: InputMaybe<Order_By>;
|
||||
refreshTokenHash?: InputMaybe<Order_By>;
|
||||
type?: InputMaybe<Order_By>;
|
||||
refresh_token?: InputMaybe<Order_By>;
|
||||
userId?: InputMaybe<Order_By>;
|
||||
};
|
||||
|
||||
@@ -3754,8 +3927,8 @@ export type AuthRefreshTokens_Order_By = {
|
||||
expiresAt?: InputMaybe<Order_By>;
|
||||
id?: InputMaybe<Order_By>;
|
||||
metadata?: InputMaybe<Order_By>;
|
||||
refreshToken?: InputMaybe<Order_By>;
|
||||
refreshTokenHash?: InputMaybe<Order_By>;
|
||||
refresh_token?: InputMaybe<Order_By>;
|
||||
type?: InputMaybe<Order_By>;
|
||||
user?: InputMaybe<Users_Order_By>;
|
||||
userId?: InputMaybe<Order_By>;
|
||||
@@ -3782,10 +3955,10 @@ export enum AuthRefreshTokens_Select_Column {
|
||||
/** column name */
|
||||
Metadata = 'metadata',
|
||||
/** column name */
|
||||
RefreshToken = 'refreshToken',
|
||||
/** column name */
|
||||
RefreshTokenHash = 'refreshTokenHash',
|
||||
/** column name */
|
||||
RefreshToken = 'refresh_token',
|
||||
/** column name */
|
||||
Type = 'type',
|
||||
/** column name */
|
||||
UserId = 'userId'
|
||||
@@ -3797,9 +3970,9 @@ export type AuthRefreshTokens_Set_Input = {
|
||||
expiresAt?: InputMaybe<Scalars['timestamptz']>;
|
||||
id?: InputMaybe<Scalars['uuid']>;
|
||||
metadata?: InputMaybe<Scalars['jsonb']>;
|
||||
refreshToken?: InputMaybe<Scalars['uuid']>;
|
||||
refreshTokenHash?: InputMaybe<Scalars['String']>;
|
||||
type?: InputMaybe<Scalars['String']>;
|
||||
refresh_token?: InputMaybe<Scalars['uuid']>;
|
||||
type?: InputMaybe<AuthRefreshTokenTypes_Enum>;
|
||||
userId?: InputMaybe<Scalars['uuid']>;
|
||||
};
|
||||
|
||||
@@ -3817,9 +3990,9 @@ export type AuthRefreshTokens_Stream_Cursor_Value_Input = {
|
||||
expiresAt?: InputMaybe<Scalars['timestamptz']>;
|
||||
id?: InputMaybe<Scalars['uuid']>;
|
||||
metadata?: InputMaybe<Scalars['jsonb']>;
|
||||
refreshToken?: InputMaybe<Scalars['uuid']>;
|
||||
refreshTokenHash?: InputMaybe<Scalars['String']>;
|
||||
type?: InputMaybe<Scalars['String']>;
|
||||
refresh_token?: InputMaybe<Scalars['uuid']>;
|
||||
type?: InputMaybe<AuthRefreshTokenTypes_Enum>;
|
||||
userId?: InputMaybe<Scalars['uuid']>;
|
||||
};
|
||||
|
||||
@@ -3834,10 +4007,10 @@ export enum AuthRefreshTokens_Update_Column {
|
||||
/** column name */
|
||||
Metadata = 'metadata',
|
||||
/** column name */
|
||||
RefreshToken = 'refreshToken',
|
||||
/** column name */
|
||||
RefreshTokenHash = 'refreshTokenHash',
|
||||
/** column name */
|
||||
RefreshToken = 'refresh_token',
|
||||
/** column name */
|
||||
Type = 'type',
|
||||
/** column name */
|
||||
UserId = 'userId'
|
||||
@@ -9883,6 +10056,10 @@ export type Mutation_Root = {
|
||||
deleteAuthProviders?: Maybe<AuthProviders_Mutation_Response>;
|
||||
/** delete single row from the table: "auth.refresh_tokens" */
|
||||
deleteAuthRefreshToken?: Maybe<AuthRefreshTokens>;
|
||||
/** delete single row from the table: "auth.refresh_token_types" */
|
||||
deleteAuthRefreshTokenType?: Maybe<AuthRefreshTokenTypes>;
|
||||
/** delete data from the table: "auth.refresh_token_types" */
|
||||
deleteAuthRefreshTokenTypes?: Maybe<AuthRefreshTokenTypes_Mutation_Response>;
|
||||
/** delete data from the table: "auth.refresh_tokens" */
|
||||
deleteAuthRefreshTokens?: Maybe<AuthRefreshTokens_Mutation_Response>;
|
||||
/** delete single row from the table: "auth.roles" */
|
||||
@@ -10013,6 +10190,10 @@ export type Mutation_Root = {
|
||||
insertAuthProviders?: Maybe<AuthProviders_Mutation_Response>;
|
||||
/** insert a single row into the table: "auth.refresh_tokens" */
|
||||
insertAuthRefreshToken?: Maybe<AuthRefreshTokens>;
|
||||
/** insert a single row into the table: "auth.refresh_token_types" */
|
||||
insertAuthRefreshTokenType?: Maybe<AuthRefreshTokenTypes>;
|
||||
/** insert data into the table: "auth.refresh_token_types" */
|
||||
insertAuthRefreshTokenTypes?: Maybe<AuthRefreshTokenTypes_Mutation_Response>;
|
||||
/** insert data into the table: "auth.refresh_tokens" */
|
||||
insertAuthRefreshTokens?: Maybe<AuthRefreshTokens_Mutation_Response>;
|
||||
/** insert a single row into the table: "auth.roles" */
|
||||
@@ -10148,6 +10329,10 @@ export type Mutation_Root = {
|
||||
updateAuthProviders?: Maybe<AuthProviders_Mutation_Response>;
|
||||
/** update single row of the table: "auth.refresh_tokens" */
|
||||
updateAuthRefreshToken?: Maybe<AuthRefreshTokens>;
|
||||
/** update single row of the table: "auth.refresh_token_types" */
|
||||
updateAuthRefreshTokenType?: Maybe<AuthRefreshTokenTypes>;
|
||||
/** update data of the table: "auth.refresh_token_types" */
|
||||
updateAuthRefreshTokenTypes?: Maybe<AuthRefreshTokenTypes_Mutation_Response>;
|
||||
/** update data of the table: "auth.refresh_tokens" */
|
||||
updateAuthRefreshTokens?: Maybe<AuthRefreshTokens_Mutation_Response>;
|
||||
/** update single row of the table: "auth.roles" */
|
||||
@@ -10247,6 +10432,8 @@ export type Mutation_Root = {
|
||||
update_authProviderRequests_many?: Maybe<Array<Maybe<AuthProviderRequests_Mutation_Response>>>;
|
||||
/** update multiples rows of table: "auth.providers" */
|
||||
update_authProviders_many?: Maybe<Array<Maybe<AuthProviders_Mutation_Response>>>;
|
||||
/** update multiples rows of table: "auth.refresh_token_types" */
|
||||
update_authRefreshTokenTypes_many?: Maybe<Array<Maybe<AuthRefreshTokenTypes_Mutation_Response>>>;
|
||||
/** update multiples rows of table: "auth.refresh_tokens" */
|
||||
update_authRefreshTokens_many?: Maybe<Array<Maybe<AuthRefreshTokens_Mutation_Response>>>;
|
||||
/** update multiples rows of table: "auth.roles" */
|
||||
@@ -10479,6 +10666,18 @@ export type Mutation_RootDeleteAuthRefreshTokenArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootDeleteAuthRefreshTokenTypeArgs = {
|
||||
value: Scalars['String'];
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootDeleteAuthRefreshTokenTypesArgs = {
|
||||
where: AuthRefreshTokenTypes_Bool_Exp;
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootDeleteAuthRefreshTokensArgs = {
|
||||
where: AuthRefreshTokens_Bool_Exp;
|
||||
@@ -10887,6 +11086,20 @@ export type Mutation_RootInsertAuthRefreshTokenArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootInsertAuthRefreshTokenTypeArgs = {
|
||||
object: AuthRefreshTokenTypes_Insert_Input;
|
||||
on_conflict?: InputMaybe<AuthRefreshTokenTypes_On_Conflict>;
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootInsertAuthRefreshTokenTypesArgs = {
|
||||
objects: Array<AuthRefreshTokenTypes_Insert_Input>;
|
||||
on_conflict?: InputMaybe<AuthRefreshTokenTypes_On_Conflict>;
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootInsertAuthRefreshTokensArgs = {
|
||||
objects: Array<AuthRefreshTokens_Insert_Input>;
|
||||
@@ -11410,6 +11623,20 @@ export type Mutation_RootUpdateAuthRefreshTokenArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootUpdateAuthRefreshTokenTypeArgs = {
|
||||
_set?: InputMaybe<AuthRefreshTokenTypes_Set_Input>;
|
||||
pk_columns: AuthRefreshTokenTypes_Pk_Columns_Input;
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootUpdateAuthRefreshTokenTypesArgs = {
|
||||
_set?: InputMaybe<AuthRefreshTokenTypes_Set_Input>;
|
||||
where: AuthRefreshTokenTypes_Bool_Exp;
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootUpdateAuthRefreshTokensArgs = {
|
||||
_append?: InputMaybe<AuthRefreshTokens_Append_Input>;
|
||||
@@ -11803,6 +12030,12 @@ export type Mutation_RootUpdate_AuthProviders_ManyArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootUpdate_AuthRefreshTokenTypes_ManyArgs = {
|
||||
updates: Array<AuthRefreshTokenTypes_Updates>;
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootUpdate_AuthRefreshTokens_ManyArgs = {
|
||||
updates: Array<AuthRefreshTokens_Updates>;
|
||||
@@ -13181,6 +13414,12 @@ export type Query_Root = {
|
||||
authProvidersAggregate: AuthProviders_Aggregate;
|
||||
/** fetch data from the table: "auth.refresh_tokens" using primary key columns */
|
||||
authRefreshToken?: Maybe<AuthRefreshTokens>;
|
||||
/** fetch data from the table: "auth.refresh_token_types" using primary key columns */
|
||||
authRefreshTokenType?: Maybe<AuthRefreshTokenTypes>;
|
||||
/** fetch data from the table: "auth.refresh_token_types" */
|
||||
authRefreshTokenTypes: Array<AuthRefreshTokenTypes>;
|
||||
/** fetch aggregated fields from the table: "auth.refresh_token_types" */
|
||||
authRefreshTokenTypesAggregate: AuthRefreshTokenTypes_Aggregate;
|
||||
/** fetch data from the table: "auth.refresh_tokens" */
|
||||
authRefreshTokens: Array<AuthRefreshTokens>;
|
||||
/** fetch aggregated fields from the table: "auth.refresh_tokens" */
|
||||
@@ -13513,6 +13752,29 @@ export type Query_RootAuthRefreshTokenArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type Query_RootAuthRefreshTokenTypeArgs = {
|
||||
value: Scalars['String'];
|
||||
};
|
||||
|
||||
|
||||
export type Query_RootAuthRefreshTokenTypesArgs = {
|
||||
distinct_on?: InputMaybe<Array<AuthRefreshTokenTypes_Select_Column>>;
|
||||
limit?: InputMaybe<Scalars['Int']>;
|
||||
offset?: InputMaybe<Scalars['Int']>;
|
||||
order_by?: InputMaybe<Array<AuthRefreshTokenTypes_Order_By>>;
|
||||
where?: InputMaybe<AuthRefreshTokenTypes_Bool_Exp>;
|
||||
};
|
||||
|
||||
|
||||
export type Query_RootAuthRefreshTokenTypesAggregateArgs = {
|
||||
distinct_on?: InputMaybe<Array<AuthRefreshTokenTypes_Select_Column>>;
|
||||
limit?: InputMaybe<Scalars['Int']>;
|
||||
offset?: InputMaybe<Scalars['Int']>;
|
||||
order_by?: InputMaybe<Array<AuthRefreshTokenTypes_Order_By>>;
|
||||
where?: InputMaybe<AuthRefreshTokenTypes_Bool_Exp>;
|
||||
};
|
||||
|
||||
|
||||
export type Query_RootAuthRefreshTokensArgs = {
|
||||
distinct_on?: InputMaybe<Array<AuthRefreshTokens_Select_Column>>;
|
||||
limit?: InputMaybe<Scalars['Int']>;
|
||||
@@ -15174,6 +15436,14 @@ export type Subscription_Root = {
|
||||
authProviders_stream: Array<AuthProviders>;
|
||||
/** fetch data from the table: "auth.refresh_tokens" using primary key columns */
|
||||
authRefreshToken?: Maybe<AuthRefreshTokens>;
|
||||
/** fetch data from the table: "auth.refresh_token_types" using primary key columns */
|
||||
authRefreshTokenType?: Maybe<AuthRefreshTokenTypes>;
|
||||
/** fetch data from the table: "auth.refresh_token_types" */
|
||||
authRefreshTokenTypes: Array<AuthRefreshTokenTypes>;
|
||||
/** fetch aggregated fields from the table: "auth.refresh_token_types" */
|
||||
authRefreshTokenTypesAggregate: AuthRefreshTokenTypes_Aggregate;
|
||||
/** fetch data from the table in a streaming manner: "auth.refresh_token_types" */
|
||||
authRefreshTokenTypes_stream: Array<AuthRefreshTokenTypes>;
|
||||
/** fetch data from the table: "auth.refresh_tokens" */
|
||||
authRefreshTokens: Array<AuthRefreshTokens>;
|
||||
/** fetch aggregated fields from the table: "auth.refresh_tokens" */
|
||||
@@ -15575,6 +15845,36 @@ export type Subscription_RootAuthRefreshTokenArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type Subscription_RootAuthRefreshTokenTypeArgs = {
|
||||
value: Scalars['String'];
|
||||
};
|
||||
|
||||
|
||||
export type Subscription_RootAuthRefreshTokenTypesArgs = {
|
||||
distinct_on?: InputMaybe<Array<AuthRefreshTokenTypes_Select_Column>>;
|
||||
limit?: InputMaybe<Scalars['Int']>;
|
||||
offset?: InputMaybe<Scalars['Int']>;
|
||||
order_by?: InputMaybe<Array<AuthRefreshTokenTypes_Order_By>>;
|
||||
where?: InputMaybe<AuthRefreshTokenTypes_Bool_Exp>;
|
||||
};
|
||||
|
||||
|
||||
export type Subscription_RootAuthRefreshTokenTypesAggregateArgs = {
|
||||
distinct_on?: InputMaybe<Array<AuthRefreshTokenTypes_Select_Column>>;
|
||||
limit?: InputMaybe<Scalars['Int']>;
|
||||
offset?: InputMaybe<Scalars['Int']>;
|
||||
order_by?: InputMaybe<Array<AuthRefreshTokenTypes_Order_By>>;
|
||||
where?: InputMaybe<AuthRefreshTokenTypes_Bool_Exp>;
|
||||
};
|
||||
|
||||
|
||||
export type Subscription_RootAuthRefreshTokenTypes_StreamArgs = {
|
||||
batch_size: Scalars['Int'];
|
||||
cursor: Array<InputMaybe<AuthRefreshTokenTypes_Stream_Cursor_Input>>;
|
||||
where?: InputMaybe<AuthRefreshTokenTypes_Bool_Exp>;
|
||||
};
|
||||
|
||||
|
||||
export type Subscription_RootAuthRefreshTokensArgs = {
|
||||
distinct_on?: InputMaybe<Array<AuthRefreshTokens_Select_Column>>;
|
||||
limit?: InputMaybe<Scalars['Int']>;
|
||||
@@ -19324,7 +19624,7 @@ export const ProjectFragmentDoc = gql`
|
||||
githubRepository {
|
||||
fullName
|
||||
}
|
||||
deployments(limit: 4, order_by: {deploymentEndedAt: desc}) {
|
||||
deployments(limit: 4, order_by: {deploymentStartedAt: desc}) {
|
||||
id
|
||||
commitSHA
|
||||
commitMessage
|
||||
@@ -20708,7 +21008,7 @@ export const LatestLiveDeploymentSubDocument = gql`
|
||||
subscription LatestLiveDeploymentSub($appId: uuid!) {
|
||||
deployments(
|
||||
where: {deploymentStatus: {_eq: "DEPLOYED"}, appId: {_eq: $appId}}
|
||||
order_by: {deploymentEndedAt: desc}
|
||||
order_by: {deploymentStartedAt: desc}
|
||||
limit: 1
|
||||
offset: 0
|
||||
) {
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
import type { ApolloClient, ApolloQueryResult } from '@apollo/client';
|
||||
import { GetAllWorkspacesAndProjectsDocument } from './__generated__/graphql';
|
||||
|
||||
/**
|
||||
* This function will refetch the main query we use for the cache
|
||||
* of the user's workspaces and applications.
|
||||
* @param client The apollo client instance.
|
||||
*/
|
||||
export async function updateOwnCache(
|
||||
client: ApolloClient<any>,
|
||||
): Promise<ApolloQueryResult<any>[]> {
|
||||
return client.refetchQueries({
|
||||
include: [GetAllWorkspacesAndProjectsDocument],
|
||||
});
|
||||
}
|
||||
|
||||
export default updateOwnCache;
|
||||
@@ -1,5 +1,11 @@
|
||||
# @nhost/docs
|
||||
|
||||
## 0.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 203bc97f: feat(pat): add support for personal access tokens
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Sign In with Personal Access Tokens
|
||||
sidebar_label: Personal Access Tokens
|
||||
slug: /authentication/sign-in-with-personal-access-tokens
|
||||
---
|
||||
|
||||
Nhost allows you to sign in users with personal access tokens (PAT) which is a way to sign in users without an email address or password.
|
||||
|
||||
## Configuration
|
||||
|
||||
:::info
|
||||
Personal Access Tokens can only be created through Hasura Auth or the [Nhost JavaScript SDK](/reference/javascript) at the moment.
|
||||
:::
|
||||
|
||||
## Create a Personal Access Token
|
||||
|
||||
Users must be signed in to create a personal access token. Once a user is signed in, they can create a personal access token.
|
||||
|
||||
**Example:** Create a personal access token:
|
||||
|
||||
```tsx
|
||||
const expiresAt = new Date(Date.now() + 1000 * 60 * 60 * 24 * 30) // 30 days
|
||||
const metadata = { name: 'Example PAT' } // Optional metadata
|
||||
|
||||
const { data, error } = await nhost.auth.createPAT(expiresAt, metadata)
|
||||
|
||||
// Something unexpected happened
|
||||
if (error) {
|
||||
console.error(error)
|
||||
return
|
||||
}
|
||||
|
||||
console.log(data.id) // The personal access token ID (can be used to delete the token later)
|
||||
console.log(data.personalAccessToken) // The personal access token
|
||||
```
|
||||
|
||||
Users can create multiple personal access tokens. Each token can have a different expiration date and metadata.
|
||||
|
||||
## Sign In
|
||||
|
||||
Once a user has created a personal access token, they can use it to sign in.
|
||||
|
||||
**Example:** Sign in with a personal access token:
|
||||
|
||||
```tsx
|
||||
const { error, session } = await nhost.auth.signInPAT('<personal-access-token>')
|
||||
|
||||
// Something unexpected happened
|
||||
if (error) {
|
||||
console.log(error)
|
||||
return
|
||||
}
|
||||
|
||||
// User is signed in
|
||||
console.log(session.user)
|
||||
```
|
||||
|
||||
## List or Remove Personal Access Tokens
|
||||
|
||||
To list and remove personal access tokens, use GraphQL and set permissions on the `auth.refresh_tokens` table:
|
||||
|
||||
**Example:** Get all personal access tokens for a user:
|
||||
|
||||
```graphql
|
||||
query personalAccessTokens($userId: uuid!) {
|
||||
authRefreshTokens(where: { _and: [{ userId: { _eq: $userId } }, { type: { _eq: pat } }] }) {
|
||||
id
|
||||
expiresAt
|
||||
metadata
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Example:** Remove a personal access token:
|
||||
|
||||
```graphql
|
||||
mutation removePersonalAccessToken($id: uuid!) {
|
||||
deleteAuthRefreshToken(id: $id) {
|
||||
id
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/docs",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
@@ -16,9 +16,9 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@algolia/client-search": "^4.9.1",
|
||||
"@docusaurus/core": "2.4.0",
|
||||
"@docusaurus/plugin-sitemap": "2.4.0",
|
||||
"@docusaurus/preset-classic": "2.4.0",
|
||||
"@docusaurus/core": "2.4.1",
|
||||
"@docusaurus/plugin-sitemap": "2.4.1",
|
||||
"@docusaurus/preset-classic": "2.4.1",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"clsx": "^1.2.1",
|
||||
"docusaurus-plugin-image-zoom": "^0.1.1",
|
||||
@@ -30,7 +30,7 @@
|
||||
"unist-util-visit": "^2.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/module-type-aliases": "2.4.0",
|
||||
"@docusaurus/module-type-aliases": "2.4.1",
|
||||
"@tsconfig/docusaurus": "^1.0.6",
|
||||
"typescript": "^4.8.4"
|
||||
},
|
||||
|
||||
3
examples/cli/.env.example
Normal file
3
examples/cli/.env.example
Normal file
@@ -0,0 +1,3 @@
|
||||
NHOST_ACCOUNT_PAT=34f74930-09c0-4af5-a8d5-28fad78e3414
|
||||
NHOST_ACCOUNT_EMAIL=cli@nhost.io
|
||||
NHOST_ACCOUNT_PASSWORD=Admin1234!
|
||||
5
examples/cli/.gitignore
vendored
Normal file
5
examples/cli/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.nhost
|
||||
web/node_modules
|
||||
node_modules
|
||||
functions/node_modules
|
||||
.env
|
||||
9
examples/cli/CHANGELOG.md
Normal file
9
examples/cli/CHANGELOG.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# @nhost-examples/cli
|
||||
|
||||
## 0.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 203bc97f: feat(pat): add support for personal access tokens
|
||||
- Updated dependencies [7fea29a8]
|
||||
- @nhost/nhost-js@2.2.5
|
||||
109
examples/cli/README.md
Normal file
109
examples/cli/README.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Node.js CLI tool example with Personal Access Tokens
|
||||
|
||||
Todo app that shows how to use:
|
||||
|
||||
- [Nhost](https://nhost.io/)
|
||||
- [Node.js](https://nodejs.org/en/)
|
||||
- Personal Access Tokens
|
||||
|
||||
## Get Started
|
||||
|
||||
There is a migration script that creates a service account. The credentials of
|
||||
this account are used to authenticate the CLI tool.
|
||||
|
||||
By default these credentials are used:
|
||||
|
||||
Email address: `cli@nhost.io`
|
||||
Password: `Admin1234!`
|
||||
|
||||
1. Clone the repository
|
||||
|
||||
```sh
|
||||
git clone https://github.com/nhost/nhost
|
||||
cd nhost
|
||||
```
|
||||
|
||||
2. Install dependencies
|
||||
|
||||
```sh
|
||||
pnpm install
|
||||
```
|
||||
|
||||
3. Start the Nhost backend
|
||||
|
||||
```sh
|
||||
nhost up
|
||||
```
|
||||
|
||||
4. Run the help command to see the available commands
|
||||
|
||||
```sh
|
||||
pnpm start --help
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Credentials can be provided through the command line or by using environment
|
||||
variables. Create a `.env` file in the root folder of the example. See `.env.example`
|
||||
for an example configuration.
|
||||
|
||||
You can specify the following environment variables:
|
||||
|
||||
- `NHOST_ACCOUNT_PAT` - The personal access token of the service account. If provided, the email address and password will be ignored.
|
||||
- `NHOST_ACCOUNT_EMAIL` - The email address of the service account.
|
||||
- `NHOST_ACCOUNT_PASSWORD` - The password of the service account.
|
||||
|
||||
> If email and password are provided, the CLI tool will sign in first to create a personal access token for the account. This token will then be used to authenticate and make requests to the Nhost backend as the service account without having to provide the email address and password. Make sure to copy the token from the output and use it in the `NHOST_ACCOUNT_PAT` environment variable later.
|
||||
|
||||
## Commands
|
||||
|
||||
Environment variables should be placed in a `.env` file in the root folder of
|
||||
the example. See `.env.example` for an example configuration.
|
||||
|
||||
### Use an existing personal access token to authenticate
|
||||
|
||||
```sh
|
||||
pnpm start --token <personal-access-token>
|
||||
```
|
||||
|
||||
or using environment variables:
|
||||
|
||||
```sh
|
||||
NHOST_ACCOUNT_PAT=<personal-access-token> pnpm start
|
||||
```
|
||||
|
||||
### Create a new personal access token
|
||||
|
||||
```sh
|
||||
pnpm start --email cli@nhost.io --password Admin1234! --create-token --expires-at 2040-01-01 --token-name "CLI Token"
|
||||
```
|
||||
|
||||
or using environment variables:
|
||||
|
||||
```sh
|
||||
NHOST_ACCOUNT_EMAIL=cli@nhost.io NHOST_ACCOUNT_PASSWORD=Admin1234! pnpm start --create-token --expires-at 2040-01-01 --token-name "CLI Token"
|
||||
```
|
||||
|
||||
### Create a new book
|
||||
|
||||
```sh
|
||||
pnpm start --token <personal-access-token> --create-book <title>
|
||||
```
|
||||
|
||||
or using environment variables:
|
||||
|
||||
```sh
|
||||
NHOST_ACCOUNT_PAT=<personal-access-token> pnpm start --create-book <title>
|
||||
```
|
||||
|
||||
### Delete a book
|
||||
|
||||
```sh
|
||||
pnpm start --token <personal-access-token> --delete-book <id>
|
||||
```
|
||||
|
||||
or using environment variables:
|
||||
|
||||
```sh
|
||||
NHOST_ACCOUNT_PAT=<personal-access-token> pnpm start --delete-book <id>
|
||||
```
|
||||
139
examples/cli/nhost/config.yaml
Normal file
139
examples/cli/nhost/config.yaml
Normal file
@@ -0,0 +1,139 @@
|
||||
metadata_directory: metadata
|
||||
services:
|
||||
auth:
|
||||
image: nhost/hasura-auth:0.20.0
|
||||
hasura:
|
||||
environment:
|
||||
hasura_graphql_enable_remote_schema_permissions: true
|
||||
minio:
|
||||
environment:
|
||||
minio_root_password: minioaccesskey123123
|
||||
minio_root_user: minioaccesskey123123
|
||||
postgres:
|
||||
environment:
|
||||
postgres_password: postgres
|
||||
postgres_user: postgres
|
||||
auth:
|
||||
access_control:
|
||||
email:
|
||||
allowed_email_domains: ''
|
||||
allowed_emails: ''
|
||||
blocked_email_domains: ''
|
||||
blocked_emails: ''
|
||||
url:
|
||||
allowed_redirect_urls: ''
|
||||
anonymous_users_enabled: false
|
||||
client_url: http://localhost:3000
|
||||
disable_new_users: false
|
||||
email:
|
||||
enabled: false
|
||||
passwordless:
|
||||
enabled: false
|
||||
signin_email_verified_required: false
|
||||
template_fetch_url: ''
|
||||
gravatar:
|
||||
default: ''
|
||||
enabled: true
|
||||
rating: ''
|
||||
locale:
|
||||
allowed: en
|
||||
default: en
|
||||
password:
|
||||
hibp_enabled: false
|
||||
min_length: 3
|
||||
provider:
|
||||
apple:
|
||||
client_id: ''
|
||||
enabled: false
|
||||
key_id: ''
|
||||
private_key: ''
|
||||
scope: name,email
|
||||
team_id: ''
|
||||
bitbucket:
|
||||
client_id: ''
|
||||
client_secret: ''
|
||||
enabled: false
|
||||
facebook:
|
||||
client_id: ''
|
||||
client_secret: ''
|
||||
enabled: false
|
||||
scope: email,photos,displayName
|
||||
github:
|
||||
client_id: ''
|
||||
client_secret: ''
|
||||
enabled: false
|
||||
scope: user:email
|
||||
token_url: ''
|
||||
user_profile_url: ''
|
||||
gitlab:
|
||||
base_url: ''
|
||||
client_id: ''
|
||||
client_secret: ''
|
||||
enabled: false
|
||||
scope: read_user
|
||||
google:
|
||||
client_id: ''
|
||||
client_secret: ''
|
||||
enabled: false
|
||||
scope: email,profile
|
||||
linkedin:
|
||||
client_id: ''
|
||||
client_secret: ''
|
||||
enabled: false
|
||||
scope: r_emailaddress,r_liteprofile
|
||||
spotify:
|
||||
client_id: ''
|
||||
client_secret: ''
|
||||
enabled: false
|
||||
scope: user-read-email,user-read-private
|
||||
strava:
|
||||
client_id: ''
|
||||
client_secret: ''
|
||||
enabled: false
|
||||
twilio:
|
||||
account_sid: ''
|
||||
auth_token: ''
|
||||
enabled: false
|
||||
messaging_service_id: ''
|
||||
twitter:
|
||||
consumer_key: ''
|
||||
consumer_secret: ''
|
||||
enabled: false
|
||||
windows_live:
|
||||
client_id: ''
|
||||
client_secret: ''
|
||||
enabled: false
|
||||
scope: wl.basic,wl.emails,wl.contacts_emails
|
||||
sms:
|
||||
enabled: false
|
||||
passwordless:
|
||||
enabled: false
|
||||
provider:
|
||||
twilio:
|
||||
account_sid: ''
|
||||
auth_token: ''
|
||||
from: ''
|
||||
messaging_service_id: ''
|
||||
smtp:
|
||||
host: mailhog
|
||||
method: ''
|
||||
pass: password
|
||||
port: 1025
|
||||
secure: false
|
||||
sender: hasura-auth@example.com
|
||||
user: user
|
||||
token:
|
||||
access:
|
||||
expires_in: 900
|
||||
refresh:
|
||||
expires_in: 43200
|
||||
user:
|
||||
allowed_roles: user,me
|
||||
default_allowed_roles: user,me
|
||||
default_role: user
|
||||
mfa:
|
||||
enabled: false
|
||||
issuer: nhost
|
||||
storage:
|
||||
force_download_for_content_types: text/html,application/javascript
|
||||
version: 3
|
||||
18
examples/cli/nhost/emails/bg/email-confirm-change/body.html
Normal file
18
examples/cli/nhost/emails/bg/email-confirm-change/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Потвърдете смяната на вашия имейл</h2>
|
||||
<p>Използвайте посочения линк, за да повърдите смяната на имейл:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Смени имейл
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Потвърждение за смяна на имейл
|
||||
18
examples/cli/nhost/emails/bg/email-verify/body.html
Normal file
18
examples/cli/nhost/emails/bg/email-verify/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Потвърдете вашия имейл</h2>
|
||||
<p>Използвайте посочения линк, за да потвърдите вашия имейл:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Потвърдете имейл
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1
examples/cli/nhost/emails/bg/email-verify/subject.txt
Normal file
1
examples/cli/nhost/emails/bg/email-verify/subject.txt
Normal file
@@ -0,0 +1 @@
|
||||
Потвърждаване на имейл
|
||||
18
examples/cli/nhost/emails/bg/password-reset/body.html
Normal file
18
examples/cli/nhost/emails/bg/password-reset/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Смяна на парола</h2>
|
||||
<p>Използвайте посочения линк, за да смените вашата парола:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Смяна на парола
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1
examples/cli/nhost/emails/bg/password-reset/subject.txt
Normal file
1
examples/cli/nhost/emails/bg/password-reset/subject.txt
Normal file
@@ -0,0 +1 @@
|
||||
Смяна на парола
|
||||
@@ -0,0 +1 @@
|
||||
Вашият код е ${code}.
|
||||
18
examples/cli/nhost/emails/bg/signin-passwordless/body.html
Normal file
18
examples/cli/nhost/emails/bg/signin-passwordless/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Магически линк за вход</h2>
|
||||
<p>Използвайте посочения линк за защитен и бърз вход:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Вход
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Магически линк за вход
|
||||
18
examples/cli/nhost/emails/cs/email-confirm-change/body.html
Normal file
18
examples/cli/nhost/emails/cs/email-confirm-change/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Potvrzení změny emailové adresy</h2>
|
||||
<p>Použijte tento odkaz k potvrzení změny emailové adresy:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Změnit email
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Změna vaší emailové adresy
|
||||
18
examples/cli/nhost/emails/cs/email-verify/body.html
Normal file
18
examples/cli/nhost/emails/cs/email-verify/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Ověření emailové adresy</h2>
|
||||
<p>Použijte tento odkaz k ověření vaší emailové adresy:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Ověřit emailovou adresu
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1
examples/cli/nhost/emails/cs/email-verify/subject.txt
Normal file
1
examples/cli/nhost/emails/cs/email-verify/subject.txt
Normal file
@@ -0,0 +1 @@
|
||||
Ověření vaší emailové adresy
|
||||
18
examples/cli/nhost/emails/cs/password-reset/body.html
Normal file
18
examples/cli/nhost/emails/cs/password-reset/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Obnova hesla</h2>
|
||||
<p>Použijte tento odkaz k obnovení vašeho hesla:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Obnova hesla
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1
examples/cli/nhost/emails/cs/password-reset/subject.txt
Normal file
1
examples/cli/nhost/emails/cs/password-reset/subject.txt
Normal file
@@ -0,0 +1 @@
|
||||
Obnova hesla
|
||||
@@ -0,0 +1 @@
|
||||
Váš kód je ${code}.
|
||||
18
examples/cli/nhost/emails/cs/signin-passwordless/body.html
Normal file
18
examples/cli/nhost/emails/cs/signin-passwordless/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Magický odkaz</h2>
|
||||
<p>Použijte tento odkaz k bezpečnému přihlášení:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Přihlášení
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Bezpečný odkaz k přihlášení
|
||||
18
examples/cli/nhost/emails/en/email-confirm-change/body.html
Normal file
18
examples/cli/nhost/emails/en/email-confirm-change/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Confirm Email Change</h2>
|
||||
<p>Use this link to confirm changing email:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Change email
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Change your email address
|
||||
18
examples/cli/nhost/emails/en/email-verify/body.html
Normal file
18
examples/cli/nhost/emails/en/email-verify/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Verify Email</h2>
|
||||
<p>Use this link to verify your email:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Verify Email
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1
examples/cli/nhost/emails/en/email-verify/subject.txt
Normal file
1
examples/cli/nhost/emails/en/email-verify/subject.txt
Normal file
@@ -0,0 +1 @@
|
||||
Verify your email
|
||||
18
examples/cli/nhost/emails/en/password-reset/body.html
Normal file
18
examples/cli/nhost/emails/en/password-reset/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Reset Password</h2>
|
||||
<p>Use this link to reset your password:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Reset password
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1
examples/cli/nhost/emails/en/password-reset/subject.txt
Normal file
1
examples/cli/nhost/emails/en/password-reset/subject.txt
Normal file
@@ -0,0 +1 @@
|
||||
Reset your password
|
||||
@@ -0,0 +1 @@
|
||||
Your code is ${code}.
|
||||
18
examples/cli/nhost/emails/en/signin-passwordless/body.html
Normal file
18
examples/cli/nhost/emails/en/signin-passwordless/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Magic Link</h2>
|
||||
<p>Use this link to securely sign in:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Sign In
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Secure sign-in link
|
||||
18
examples/cli/nhost/emails/es/email-confirm-change/body.html
Normal file
18
examples/cli/nhost/emails/es/email-confirm-change/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Confirmar cambio de correo electrónico</h2>
|
||||
<p>Utiliza el siguiente enlace para confirmar el cambio de correo:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Cambiar correo electrónico
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Cambiar dirección de correo electrónico
|
||||
18
examples/cli/nhost/emails/es/email-verify/body.html
Normal file
18
examples/cli/nhost/emails/es/email-verify/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Verificar correo electrónico</h2>
|
||||
<p>Utilza el siguiente enlace para verificar tu correo:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Verificar correo electrónico
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1
examples/cli/nhost/emails/es/email-verify/subject.txt
Normal file
1
examples/cli/nhost/emails/es/email-verify/subject.txt
Normal file
@@ -0,0 +1 @@
|
||||
Verifica tu correo electrónico
|
||||
18
examples/cli/nhost/emails/es/password-reset/body.html
Normal file
18
examples/cli/nhost/emails/es/password-reset/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Recuperar contraseña</h2>
|
||||
<p>Utiliza el siguiente enlace para recuperar tu contraseña:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Recuperar contraseña
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1
examples/cli/nhost/emails/es/password-reset/subject.txt
Normal file
1
examples/cli/nhost/emails/es/password-reset/subject.txt
Normal file
@@ -0,0 +1 @@
|
||||
Recuperar contraseña
|
||||
@@ -0,0 +1 @@
|
||||
Tu código es ${code}.
|
||||
18
examples/cli/nhost/emails/es/signin-passwordless/body.html
Normal file
18
examples/cli/nhost/emails/es/signin-passwordless/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Enlace mágico</h2>
|
||||
<p>Utiliza este enlace para iniciar sesión de forma segura:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Iniciar sesión
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Enlace de acceso seguro
|
||||
18
examples/cli/nhost/emails/fr/email-confirm-change/body.html
Normal file
18
examples/cli/nhost/emails/fr/email-confirm-change/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Confirmer changement de courriel</h2>
|
||||
<p>Utilisez ce lien pour confirmer le changement de courriel:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Changer courriel
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Changez votre adresse courriel
|
||||
18
examples/cli/nhost/emails/fr/email-verify/body.html
Normal file
18
examples/cli/nhost/emails/fr/email-verify/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Vérifiez votre courriel</h2>
|
||||
<p>Utilisez ce lien pour vérifier votre courriel:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Vérifier courriel
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1
examples/cli/nhost/emails/fr/email-verify/subject.txt
Normal file
1
examples/cli/nhost/emails/fr/email-verify/subject.txt
Normal file
@@ -0,0 +1 @@
|
||||
Vérifier votre courriel
|
||||
18
examples/cli/nhost/emails/fr/password-reset/body.html
Normal file
18
examples/cli/nhost/emails/fr/password-reset/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Réinitializer votre mot de passe</h2>
|
||||
<p>Utilisez ce lien pour réinitializer votre mot de passe:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Réinitializer mot de passe
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
1
examples/cli/nhost/emails/fr/password-reset/subject.txt
Normal file
1
examples/cli/nhost/emails/fr/password-reset/subject.txt
Normal file
@@ -0,0 +1 @@
|
||||
Réinitialiser votre mot de passe
|
||||
@@ -0,0 +1 @@
|
||||
Votre code est ${code}.
|
||||
18
examples/cli/nhost/emails/fr/signin-passwordless/body.html
Normal file
18
examples/cli/nhost/emails/fr/signin-passwordless/body.html
Normal file
@@ -0,0 +1,18 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h2>Lien magique</h2>
|
||||
<p>Utilisez ce lien pour vous connecter de façon sécuritaire:</p>
|
||||
<p>
|
||||
<a href="${link}">
|
||||
Connexion
|
||||
</a>
|
||||
</p>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1 @@
|
||||
Lien de connexion sécurisé
|
||||
0
examples/cli/nhost/metadata/actions.graphql
Normal file
0
examples/cli/nhost/metadata/actions.graphql
Normal file
6
examples/cli/nhost/metadata/actions.yaml
Normal file
6
examples/cli/nhost/metadata/actions.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
actions: []
|
||||
custom_types:
|
||||
enums: []
|
||||
input_objects: []
|
||||
objects: []
|
||||
scalars: []
|
||||
1
examples/cli/nhost/metadata/allow_list.yaml
Normal file
1
examples/cli/nhost/metadata/allow_list.yaml
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
1
examples/cli/nhost/metadata/api_limits.yaml
Normal file
1
examples/cli/nhost/metadata/api_limits.yaml
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
examples/cli/nhost/metadata/cron_triggers.yaml
Normal file
1
examples/cli/nhost/metadata/cron_triggers.yaml
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
14
examples/cli/nhost/metadata/databases/databases.yaml
Normal file
14
examples/cli/nhost/metadata/databases/databases.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
- name: default
|
||||
kind: postgres
|
||||
configuration:
|
||||
connection_info:
|
||||
database_url:
|
||||
from_env: HASURA_GRAPHQL_DATABASE_URL
|
||||
isolation_level: read-committed
|
||||
pool_settings:
|
||||
connection_lifetime: 600
|
||||
idle_timeout: 180
|
||||
max_connections: 50
|
||||
retries: 20
|
||||
use_prepared_statements: true
|
||||
tables: "!include default/tables/tables.yaml"
|
||||
@@ -0,0 +1,23 @@
|
||||
table:
|
||||
name: provider_requests
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
id:
|
||||
custom_name: id
|
||||
options:
|
||||
custom_name: options
|
||||
custom_column_names:
|
||||
id: id
|
||||
options: options
|
||||
custom_name: authProviderRequests
|
||||
custom_root_fields:
|
||||
delete: deleteAuthProviderRequests
|
||||
delete_by_pk: deleteAuthProviderRequest
|
||||
insert: insertAuthProviderRequests
|
||||
insert_one: insertAuthProviderRequest
|
||||
select: authProviderRequests
|
||||
select_aggregate: authProviderRequestsAggregate
|
||||
select_by_pk: authProviderRequest
|
||||
update: updateAuthProviderRequests
|
||||
update_by_pk: updateAuthProviderRequest
|
||||
@@ -0,0 +1,28 @@
|
||||
table:
|
||||
name: providers
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
id:
|
||||
custom_name: id
|
||||
custom_column_names:
|
||||
id: id
|
||||
custom_name: authProviders
|
||||
custom_root_fields:
|
||||
delete: deleteAuthProviders
|
||||
delete_by_pk: deleteAuthProvider
|
||||
insert: insertAuthProviders
|
||||
insert_one: insertAuthProvider
|
||||
select: authProviders
|
||||
select_aggregate: authProvidersAggregate
|
||||
select_by_pk: authProvider
|
||||
update: updateAuthProviders
|
||||
update_by_pk: updateAuthProvider
|
||||
array_relationships:
|
||||
- name: userProviders
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: provider_id
|
||||
table:
|
||||
name: user_providers
|
||||
schema: auth
|
||||
@@ -0,0 +1,26 @@
|
||||
table:
|
||||
name: refresh_token_types
|
||||
schema: auth
|
||||
is_enum: true
|
||||
configuration:
|
||||
column_config: {}
|
||||
custom_column_names: {}
|
||||
custom_name: authRefreshTokenTypes
|
||||
custom_root_fields:
|
||||
delete: deleteAuthRefreshTokenTypes
|
||||
delete_by_pk: deleteAuthRefreshTokenType
|
||||
insert: insertAuthRefreshTokenTypes
|
||||
insert_one: insertAuthRefreshTokenType
|
||||
select: authRefreshTokenTypes
|
||||
select_aggregate: authRefreshTokenTypesAggregate
|
||||
select_by_pk: authRefreshTokenType
|
||||
update: updateAuthRefreshTokenTypes
|
||||
update_by_pk: updateAuthRefreshTokenType
|
||||
array_relationships:
|
||||
- name: refreshTokens
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: type
|
||||
table:
|
||||
name: refresh_tokens
|
||||
schema: auth
|
||||
@@ -0,0 +1,61 @@
|
||||
table:
|
||||
name: refresh_tokens
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
created_at:
|
||||
custom_name: createdAt
|
||||
expires_at:
|
||||
custom_name: expiresAt
|
||||
refresh_token_hash:
|
||||
custom_name: refreshTokenHash
|
||||
type:
|
||||
custom_name: type
|
||||
user_id:
|
||||
custom_name: userId
|
||||
custom_column_names:
|
||||
created_at: createdAt
|
||||
expires_at: expiresAt
|
||||
refresh_token_hash: refreshTokenHash
|
||||
type: type
|
||||
user_id: userId
|
||||
custom_name: authRefreshTokens
|
||||
custom_root_fields:
|
||||
delete: deleteAuthRefreshTokens
|
||||
delete_by_pk: deleteAuthRefreshToken
|
||||
insert: insertAuthRefreshTokens
|
||||
insert_one: insertAuthRefreshToken
|
||||
select: authRefreshTokens
|
||||
select_aggregate: authRefreshTokensAggregate
|
||||
select_by_pk: authRefreshToken
|
||||
update: updateAuthRefreshTokens
|
||||
update_by_pk: updateAuthRefreshToken
|
||||
object_relationships:
|
||||
- name: refreshTokenType
|
||||
using:
|
||||
foreign_key_constraint_on: type
|
||||
- name: user
|
||||
using:
|
||||
foreign_key_constraint_on: user_id
|
||||
select_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
columns:
|
||||
- id
|
||||
- created_at
|
||||
- expires_at
|
||||
- metadata
|
||||
- type
|
||||
- user_id
|
||||
filter:
|
||||
user_id:
|
||||
_eq: X-Hasura-User-Id
|
||||
delete_permissions:
|
||||
- role: user
|
||||
permission:
|
||||
filter:
|
||||
_and:
|
||||
- user_id:
|
||||
_eq: X-Hasura-User-Id
|
||||
- type:
|
||||
_eq: pat
|
||||
@@ -0,0 +1,35 @@
|
||||
table:
|
||||
name: roles
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
role:
|
||||
custom_name: role
|
||||
custom_column_names:
|
||||
role: role
|
||||
custom_name: authRoles
|
||||
custom_root_fields:
|
||||
delete: deleteAuthRoles
|
||||
delete_by_pk: deleteAuthRole
|
||||
insert: insertAuthRoles
|
||||
insert_one: insertAuthRole
|
||||
select: authRoles
|
||||
select_aggregate: authRolesAggregate
|
||||
select_by_pk: authRole
|
||||
update: updateAuthRoles
|
||||
update_by_pk: updateAuthRole
|
||||
array_relationships:
|
||||
- name: userRoles
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: role
|
||||
table:
|
||||
name: user_roles
|
||||
schema: auth
|
||||
- name: usersByDefaultRole
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: default_role
|
||||
table:
|
||||
name: users
|
||||
schema: auth
|
||||
@@ -0,0 +1,48 @@
|
||||
table:
|
||||
name: user_providers
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
access_token:
|
||||
custom_name: accessToken
|
||||
created_at:
|
||||
custom_name: createdAt
|
||||
id:
|
||||
custom_name: id
|
||||
provider_id:
|
||||
custom_name: providerId
|
||||
provider_user_id:
|
||||
custom_name: providerUserId
|
||||
refresh_token:
|
||||
custom_name: refreshToken
|
||||
updated_at:
|
||||
custom_name: updatedAt
|
||||
user_id:
|
||||
custom_name: userId
|
||||
custom_column_names:
|
||||
access_token: accessToken
|
||||
created_at: createdAt
|
||||
id: id
|
||||
provider_id: providerId
|
||||
provider_user_id: providerUserId
|
||||
refresh_token: refreshToken
|
||||
updated_at: updatedAt
|
||||
user_id: userId
|
||||
custom_name: authUserProviders
|
||||
custom_root_fields:
|
||||
delete: deleteAuthUserProviders
|
||||
delete_by_pk: deleteAuthUserProvider
|
||||
insert: insertAuthUserProviders
|
||||
insert_one: insertAuthUserProvider
|
||||
select: authUserProviders
|
||||
select_aggregate: authUserProvidersAggregate
|
||||
select_by_pk: authUserProvider
|
||||
update: updateAuthUserProviders
|
||||
update_by_pk: updateAuthUserProvider
|
||||
object_relationships:
|
||||
- name: provider
|
||||
using:
|
||||
foreign_key_constraint_on: provider_id
|
||||
- name: user
|
||||
using:
|
||||
foreign_key_constraint_on: user_id
|
||||
@@ -0,0 +1,36 @@
|
||||
table:
|
||||
name: user_roles
|
||||
schema: auth
|
||||
configuration:
|
||||
column_config:
|
||||
created_at:
|
||||
custom_name: createdAt
|
||||
id:
|
||||
custom_name: id
|
||||
role:
|
||||
custom_name: role
|
||||
user_id:
|
||||
custom_name: userId
|
||||
custom_column_names:
|
||||
created_at: createdAt
|
||||
id: id
|
||||
role: role
|
||||
user_id: userId
|
||||
custom_name: authUserRoles
|
||||
custom_root_fields:
|
||||
delete: deleteAuthUserRoles
|
||||
delete_by_pk: deleteAuthUserRole
|
||||
insert: insertAuthUserRoles
|
||||
insert_one: insertAuthUserRole
|
||||
select: authUserRoles
|
||||
select_aggregate: authUserRolesAggregate
|
||||
select_by_pk: authUserRole
|
||||
update: updateAuthUserRoles
|
||||
update_by_pk: updateAuthUserRole
|
||||
object_relationships:
|
||||
- name: roleByRole
|
||||
using:
|
||||
foreign_key_constraint_on: role
|
||||
- name: user
|
||||
using:
|
||||
foreign_key_constraint_on: user_id
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user