Compare commits
19 Commits
@nhost/nex
...
@nhost/rea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7163854767 | ||
|
|
66bd4504d7 | ||
|
|
a03fb2cf82 | ||
|
|
87a37cfc08 | ||
|
|
6fb0cc27aa | ||
|
|
2c33051f83 | ||
|
|
a9413af6e0 | ||
|
|
f4f0353f2e | ||
|
|
defffd8bc4 | ||
|
|
614c20cbbf | ||
|
|
aef4a0a4fc | ||
|
|
d0c9f4cd17 | ||
|
|
e2646cab55 | ||
|
|
d5077c7ca4 | ||
|
|
c6d5c5cc8c | ||
|
|
f1d9b472d1 | ||
|
|
c6dc7f44df | ||
|
|
3cea460c36 | ||
|
|
4c351714f5 |
@@ -1,5 +1,41 @@
|
||||
# @nhost/dashboard
|
||||
|
||||
## 1.16.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 87a37cf: fix: remove unnecessary isPlatform check from verify button disable logic on custom domains
|
||||
- @nhost/react-apollo@12.0.2
|
||||
- @nhost/nextjs@2.1.16
|
||||
|
||||
## 1.16.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a9413af: fix: update `GetAllWorkspacesAndProjects` query polling to use exponential backoff
|
||||
- @nhost/react-apollo@12.0.1
|
||||
- @nhost/nextjs@2.1.15
|
||||
|
||||
## 1.16.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react-apollo@12.0.0
|
||||
- @nhost/nextjs@2.1.14
|
||||
|
||||
## 1.16.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- c6d5c5c: feat: add toggle switch to enable/disable public access in the database settings
|
||||
|
||||
## 1.15.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react-apollo@11.0.4
|
||||
- @nhost/nextjs@2.1.13
|
||||
|
||||
## 1.15.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/dashboard",
|
||||
"version": "1.15.1",
|
||||
"version": "1.16.3",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import { ApplyLocalSettingsDialog } from '@/components/common/ApplyLocalSettingsDialog';
|
||||
import { useDialog } from '@/components/common/DialogProvider';
|
||||
import { useUI } from '@/components/common/UIProvider';
|
||||
import { Form } from '@/components/form/Form';
|
||||
import { SettingsContainer } from '@/components/layout/SettingsContainer';
|
||||
import { ActivityIndicator } from '@/components/ui/v2/ActivityIndicator';
|
||||
import { Alert } from '@/components/ui/v2/Alert';
|
||||
@@ -7,11 +11,32 @@ import type { InputProps } from '@/components/ui/v2/Input';
|
||||
import { Input } from '@/components/ui/v2/Input';
|
||||
import { InputAdornment } from '@/components/ui/v2/InputAdornment';
|
||||
import { useCurrentWorkspaceAndProject } from '@/features/projects/common/hooks/useCurrentWorkspaceAndProject';
|
||||
import { useIsPlatform } from '@/features/projects/common/hooks/useIsPlatform';
|
||||
import { generateAppServiceUrl } from '@/features/projects/common/utils/generateAppServiceUrl';
|
||||
import { useLocalMimirClient } from '@/hooks/useLocalMimirClient';
|
||||
import { copy } from '@/utils/copy';
|
||||
import { useGetPostgresSettingsQuery } from '@/utils/__generated__/graphql';
|
||||
import { execPromiseWithErrorToast } from '@/utils/execPromiseWithErrorToast';
|
||||
import {
|
||||
useGetPostgresSettingsQuery,
|
||||
useUpdateConfigMutation,
|
||||
} from '@/utils/__generated__/graphql';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import * as Yup from 'yup';
|
||||
|
||||
const databasePublicAccessValidationSchema = Yup.object({
|
||||
enablePublicAccess: Yup.bool(),
|
||||
});
|
||||
|
||||
type DatabasePublicAccessFormValues = Yup.InferType<
|
||||
typeof databasePublicAccessValidationSchema
|
||||
>;
|
||||
|
||||
export default function DatabaseConnectionInfo() {
|
||||
const { openDialog } = useDialog();
|
||||
const isPlatform = useIsPlatform();
|
||||
const { maintenanceActive } = useUI();
|
||||
const localMimirClient = useLocalMimirClient();
|
||||
const { currentProject } = useCurrentWorkspaceAndProject();
|
||||
|
||||
const { data, loading, error } = useGetPostgresSettingsQuery({
|
||||
@@ -19,6 +44,61 @@ export default function DatabaseConnectionInfo() {
|
||||
fetchPolicy: 'cache-only',
|
||||
});
|
||||
|
||||
const [updateConfig] = useUpdateConfigMutation({
|
||||
...(!isPlatform ? { client: localMimirClient } : {}),
|
||||
});
|
||||
|
||||
const enablePublicAccess =
|
||||
!!data?.config?.postgres?.resources?.enablePublicAccess;
|
||||
|
||||
const form = useForm<DatabasePublicAccessFormValues>({
|
||||
reValidateMode: 'onSubmit',
|
||||
defaultValues: {
|
||||
enablePublicAccess,
|
||||
},
|
||||
resolver: yupResolver(databasePublicAccessValidationSchema),
|
||||
});
|
||||
|
||||
async function handleSubmit(formValues: DatabasePublicAccessFormValues) {
|
||||
const updateConfigPromise = updateConfig({
|
||||
variables: {
|
||||
appId: currentProject.id,
|
||||
config: {
|
||||
postgres: {
|
||||
resources: {
|
||||
enablePublicAccess: formValues.enablePublicAccess,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
await execPromiseWithErrorToast(
|
||||
async () => {
|
||||
await updateConfigPromise;
|
||||
form.reset(formValues);
|
||||
|
||||
if (!isPlatform) {
|
||||
openDialog({
|
||||
title: 'Apply your changes',
|
||||
component: <ApplyLocalSettingsDialog />,
|
||||
props: {
|
||||
PaperProps: {
|
||||
className: 'max-w-2xl',
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
{
|
||||
loadingMessage: 'Database settings are being updated...',
|
||||
successMessage: 'Database settings have been updated successfully.',
|
||||
errorMessage:
|
||||
"An error occurred while trying to update the project's database settings.",
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<ActivityIndicator
|
||||
@@ -76,49 +156,72 @@ export default function DatabaseConnectionInfo() {
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<SettingsContainer
|
||||
title="Connection Info"
|
||||
description="Connect directly to the Postgres database with this information."
|
||||
slotProps={{ footer: { className: 'hidden' } }}
|
||||
className="grid grid-cols-6 gap-4 pb-2"
|
||||
>
|
||||
{settingsDatabaseCustomInputs.map(
|
||||
({ name, label, className, value: inputValue }) => (
|
||||
<Input
|
||||
key={name}
|
||||
label={label}
|
||||
required
|
||||
disabled
|
||||
value={inputValue}
|
||||
className={className}
|
||||
slotProps={{ inputRoot: { className: '!pr-8 truncate' } }}
|
||||
fullWidth
|
||||
hideEmptyHelperText
|
||||
endAdornment={
|
||||
<InputAdornment position="end" className="absolute right-2">
|
||||
<Button
|
||||
sx={{ minWidth: 0, padding: 0 }}
|
||||
color="secondary"
|
||||
variant="borderless"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
copy(inputValue as string, `${label}`);
|
||||
}}
|
||||
>
|
||||
<CopyIcon className="h-4 w-4" />
|
||||
</Button>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
const { formState } = form;
|
||||
|
||||
<Alert severity="info" className="col-span-6 text-left">
|
||||
To connect to the Postgres database directly, generate a new password,
|
||||
securely save it, and then modify your connection string with the newly
|
||||
created password.
|
||||
</Alert>
|
||||
</SettingsContainer>
|
||||
return (
|
||||
<FormProvider {...form}>
|
||||
<Form onSubmit={handleSubmit}>
|
||||
<SettingsContainer
|
||||
title="Public access"
|
||||
description={
|
||||
enablePublicAccess
|
||||
? 'Connect directly to the Postgres database with this information.'
|
||||
: 'Enable public access to your Postgres database.'
|
||||
}
|
||||
slotProps={{
|
||||
submitButton: {
|
||||
disabled: !formState.isDirty || maintenanceActive,
|
||||
loading: formState.isSubmitting,
|
||||
},
|
||||
}}
|
||||
className="grid grid-cols-6 gap-4 pb-2"
|
||||
switchId="enablePublicAccess"
|
||||
showSwitch
|
||||
>
|
||||
{enablePublicAccess && (
|
||||
<>
|
||||
{settingsDatabaseCustomInputs.map(
|
||||
({ name, label, className, value: inputValue }) => (
|
||||
<Input
|
||||
key={name}
|
||||
label={label}
|
||||
required
|
||||
disabled
|
||||
value={inputValue}
|
||||
className={className}
|
||||
slotProps={{ inputRoot: { className: '!pr-8 truncate' } }}
|
||||
fullWidth
|
||||
hideEmptyHelperText
|
||||
endAdornment={
|
||||
<InputAdornment
|
||||
position="end"
|
||||
className="absolute right-2"
|
||||
>
|
||||
<Button
|
||||
sx={{ minWidth: 0, padding: 0 }}
|
||||
color="secondary"
|
||||
variant="borderless"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
copy(inputValue as string, `${label}`);
|
||||
}}
|
||||
>
|
||||
<CopyIcon className="w-4 h-4" />
|
||||
</Button>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
),
|
||||
)}
|
||||
<Alert severity="info" className="col-span-6 text-left">
|
||||
To connect to the Postgres database directly, generate a new
|
||||
password, securely save it, and then modify your connection
|
||||
string with the newly created password.
|
||||
</Alert>
|
||||
</>
|
||||
)}
|
||||
</SettingsContainer>
|
||||
</Form>
|
||||
</FormProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ query GetPostgresSettings($appId: uuid!) {
|
||||
storage {
|
||||
capacity
|
||||
}
|
||||
enablePublicAccess
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import { useGetAnnouncementsQuery } from '@/utils/__generated__/graphql';
|
||||
import formatDistance from 'date-fns/formatDistance';
|
||||
|
||||
export default function Announcements() {
|
||||
const { data, loading, error } = useGetAnnouncementsQuery();
|
||||
const { data, loading, error } = useGetAnnouncementsQuery({
|
||||
fetchPolicy: 'cache-first',
|
||||
});
|
||||
|
||||
const announcements = data?.announcements || [];
|
||||
|
||||
|
||||
@@ -131,7 +131,7 @@ export default function VerifyDomain({
|
||||
</div>
|
||||
{isPlatform ? (
|
||||
<Button
|
||||
disabled={loading || !hostname || isPlatform}
|
||||
disabled={loading || !hostname}
|
||||
onClick={handleVerifyDomain}
|
||||
className="mt-4 sm:absolute sm:bottom-0 sm:right-0 sm:mt-0"
|
||||
>
|
||||
|
||||
@@ -6,6 +6,7 @@ mutation UpdateConfig($appId: uuid!, $config: ConfigConfigUpdateInput!) {
|
||||
storage {
|
||||
capacity
|
||||
}
|
||||
enablePublicAccess
|
||||
}
|
||||
}
|
||||
ai {
|
||||
|
||||
@@ -7,41 +7,55 @@ import { Button } from '@/components/ui/v2/Button';
|
||||
import { Text } from '@/components/ui/v2/Text';
|
||||
import { WorkspaceAndProjectList } from '@/features/projects/common/components/WorkspaceAndProjectList';
|
||||
import { WorkspaceSidebar } from '@/features/projects/common/components/WorkspaceSidebar';
|
||||
import { useGetAllWorkspacesAndProjectsQuery } from '@/utils/__generated__/graphql';
|
||||
import {
|
||||
useGetAllWorkspacesAndProjectsQuery,
|
||||
type GetAllWorkspacesAndProjectsQuery,
|
||||
} from '@/utils/__generated__/graphql';
|
||||
import { NetworkStatus } from '@apollo/client';
|
||||
import { darken } from '@mui/system';
|
||||
import { useUserData } from '@nhost/nextjs';
|
||||
import NavLink from 'next/link';
|
||||
import type { ReactElement } from 'react';
|
||||
import { useEffect } from 'react';
|
||||
import { useState, type ReactElement } from 'react';
|
||||
|
||||
export default function IndexPage() {
|
||||
const user = useUserData();
|
||||
const { data, loading, startPolling, stopPolling } =
|
||||
const [, setPollInterval] = useState(1_000);
|
||||
|
||||
// keep polling for workspaces until there is a workspace available.
|
||||
// We do this because when a user signs up a workspace is created automatically
|
||||
// and the serverless function can take some time to complete.
|
||||
const { data, startPolling, stopPolling, networkStatus } =
|
||||
useGetAllWorkspacesAndProjectsQuery({
|
||||
skip: !user,
|
||||
notifyOnNetworkStatusChange: true,
|
||||
onError: () => {
|
||||
// When there's an error (graphql, network error) apply an exponential backoff strategy
|
||||
setPollInterval((prevInterval) => {
|
||||
const newInterval = Math.min(60_000, prevInterval * 2);
|
||||
startPolling(newInterval);
|
||||
return newInterval;
|
||||
});
|
||||
},
|
||||
onCompleted: (queryData: GetAllWorkspacesAndProjectsQuery) => {
|
||||
if (!queryData?.workspaces.length) {
|
||||
setPollInterval(1000);
|
||||
startPolling(1000);
|
||||
} else {
|
||||
setPollInterval(0);
|
||||
stopPolling();
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// keep showing loading indicator while polling
|
||||
const loading = networkStatus === NetworkStatus.loading;
|
||||
|
||||
const numberOfProjects = data?.workspaces.reduce(
|
||||
(projectCount, currentWorkspace) =>
|
||||
projectCount + currentWorkspace.projects.length,
|
||||
0,
|
||||
);
|
||||
|
||||
// keep polling for workspaces until there is a workspace available.
|
||||
// We do this because when a user signs up a workspace is created automatically
|
||||
// and the serverless function can take some time to complete.
|
||||
useEffect(() => {
|
||||
startPolling(1000);
|
||||
}, [startPolling]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!data?.workspaces.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
stopPolling();
|
||||
}, [data?.workspaces, stopPolling]);
|
||||
|
||||
if ((!data && loading) || !user) {
|
||||
return <LoadingScreen />;
|
||||
}
|
||||
|
||||
53
dashboard/src/utils/__generated__/graphql.ts
generated
53
dashboard/src/utils/__generated__/graphql.ts
generated
@@ -1804,6 +1804,7 @@ export type ConfigPostgresInsertInput = {
|
||||
export type ConfigPostgresResources = {
|
||||
__typename?: 'ConfigPostgresResources';
|
||||
compute?: Maybe<ConfigResourcesCompute>;
|
||||
enablePublicAccess?: Maybe<Scalars['Boolean']>;
|
||||
networking?: Maybe<ConfigNetworking>;
|
||||
/** Number of replicas for a service */
|
||||
replicas?: Maybe<Scalars['ConfigUint8']>;
|
||||
@@ -1815,6 +1816,7 @@ export type ConfigPostgresResourcesComparisonExp = {
|
||||
_not?: InputMaybe<ConfigPostgresResourcesComparisonExp>;
|
||||
_or?: InputMaybe<Array<ConfigPostgresResourcesComparisonExp>>;
|
||||
compute?: InputMaybe<ConfigResourcesComputeComparisonExp>;
|
||||
enablePublicAccess?: InputMaybe<ConfigBooleanComparisonExp>;
|
||||
networking?: InputMaybe<ConfigNetworkingComparisonExp>;
|
||||
replicas?: InputMaybe<ConfigUint8ComparisonExp>;
|
||||
storage?: InputMaybe<ConfigPostgresStorageComparisonExp>;
|
||||
@@ -1822,6 +1824,7 @@ export type ConfigPostgresResourcesComparisonExp = {
|
||||
|
||||
export type ConfigPostgresResourcesInsertInput = {
|
||||
compute?: InputMaybe<ConfigResourcesComputeInsertInput>;
|
||||
enablePublicAccess?: InputMaybe<Scalars['Boolean']>;
|
||||
networking?: InputMaybe<ConfigNetworkingInsertInput>;
|
||||
replicas?: InputMaybe<Scalars['ConfigUint8']>;
|
||||
storage?: InputMaybe<ConfigPostgresStorageInsertInput>;
|
||||
@@ -1829,6 +1832,7 @@ export type ConfigPostgresResourcesInsertInput = {
|
||||
|
||||
export type ConfigPostgresResourcesUpdateInput = {
|
||||
compute?: InputMaybe<ConfigResourcesComputeUpdateInput>;
|
||||
enablePublicAccess?: InputMaybe<Scalars['Boolean']>;
|
||||
networking?: InputMaybe<ConfigNetworkingUpdateInput>;
|
||||
replicas?: InputMaybe<Scalars['ConfigUint8']>;
|
||||
storage?: InputMaybe<ConfigPostgresStorageUpdateInput>;
|
||||
@@ -2526,6 +2530,7 @@ export type ConfigSystemConfigPostgres = {
|
||||
database: Scalars['String'];
|
||||
disk?: Maybe<ConfigSystemConfigPostgresDisk>;
|
||||
enabled?: Maybe<Scalars['Boolean']>;
|
||||
majorVersion?: Maybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
export type ConfigSystemConfigPostgresComparisonExp = {
|
||||
@@ -2536,6 +2541,7 @@ export type ConfigSystemConfigPostgresComparisonExp = {
|
||||
database?: InputMaybe<ConfigStringComparisonExp>;
|
||||
disk?: InputMaybe<ConfigSystemConfigPostgresDiskComparisonExp>;
|
||||
enabled?: InputMaybe<ConfigBooleanComparisonExp>;
|
||||
majorVersion?: InputMaybe<ConfigStringComparisonExp>;
|
||||
};
|
||||
|
||||
export type ConfigSystemConfigPostgresConnectionString = {
|
||||
@@ -2599,6 +2605,7 @@ export type ConfigSystemConfigPostgresInsertInput = {
|
||||
database: Scalars['String'];
|
||||
disk?: InputMaybe<ConfigSystemConfigPostgresDiskInsertInput>;
|
||||
enabled?: InputMaybe<Scalars['Boolean']>;
|
||||
majorVersion?: InputMaybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
export type ConfigSystemConfigPostgresUpdateInput = {
|
||||
@@ -2606,6 +2613,7 @@ export type ConfigSystemConfigPostgresUpdateInput = {
|
||||
database?: InputMaybe<Scalars['String']>;
|
||||
disk?: InputMaybe<ConfigSystemConfigPostgresDiskUpdateInput>;
|
||||
enabled?: InputMaybe<Scalars['Boolean']>;
|
||||
majorVersion?: InputMaybe<Scalars['String']>;
|
||||
};
|
||||
|
||||
export type ConfigSystemConfigUpdateInput = {
|
||||
@@ -2687,14 +2695,6 @@ export type Metrics = {
|
||||
value: Scalars['float64'];
|
||||
};
|
||||
|
||||
export type StatsDailyLiveFreeApps = {
|
||||
__typename?: 'StatsDailyLiveFreeApps';
|
||||
avg: Scalars['Int'];
|
||||
max: Scalars['Int'];
|
||||
min: Scalars['Int'];
|
||||
raw: Array<Scalars['Int']>;
|
||||
};
|
||||
|
||||
export type StatsLiveApps = {
|
||||
__typename?: 'StatsLiveApps';
|
||||
appID: Array<Scalars['uuid']>;
|
||||
@@ -11826,6 +11826,7 @@ export type Mutation_Root = {
|
||||
billingUpdatePersistentVolume: Scalars['Boolean'];
|
||||
billingUpdateReports: Scalars['Boolean'];
|
||||
billingUploadReports: Scalars['Boolean'];
|
||||
changeDatabaseVersion: Scalars['Boolean'];
|
||||
/** delete single row from the table: "apps" */
|
||||
deleteApp?: Maybe<Apps>;
|
||||
/** delete single row from the table: "app_states" */
|
||||
@@ -12511,6 +12512,14 @@ export type Mutation_RootBillingUpdateReportsArgs = {
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootChangeDatabaseVersionArgs = {
|
||||
appID: Scalars['uuid'];
|
||||
force?: InputMaybe<Scalars['Boolean']>;
|
||||
version: Scalars['String'];
|
||||
};
|
||||
|
||||
|
||||
/** mutation root */
|
||||
export type Mutation_RootDeleteAppArgs = {
|
||||
id: Scalars['uuid'];
|
||||
@@ -16016,12 +16025,6 @@ export type Query_Root = {
|
||||
softwareVersions: Array<Software_Versions>;
|
||||
/** fetch aggregated fields from the table: "software_versions" */
|
||||
softwareVersionsAggregate: Software_Versions_Aggregate;
|
||||
/**
|
||||
* Returns the per-day number of free live apps in the given time range, as well as the min, max and avg.
|
||||
*
|
||||
* Requests that returned a 4xx or 5xx status code are not counted as live traffic.
|
||||
*/
|
||||
statsDailyLiveFreeApps: StatsDailyLiveFreeApps;
|
||||
/**
|
||||
* Returns lists of apps that have some live traffic in the give time range.
|
||||
* From defaults to 24 hours ago and to defaults to now.
|
||||
@@ -16031,6 +16034,8 @@ export type Query_Root = {
|
||||
statsLiveApps: StatsLiveApps;
|
||||
systemConfig?: Maybe<ConfigSystemConfig>;
|
||||
systemConfigs: Array<ConfigAppSystemConfig>;
|
||||
/** Returns system logs for a given application */
|
||||
systemLogs: Array<Log>;
|
||||
/** fetch data from the table: "auth.users" using primary key columns */
|
||||
user?: Maybe<Users>;
|
||||
/** fetch data from the table: "auth.users" */
|
||||
@@ -17079,12 +17084,6 @@ export type Query_RootSoftwareVersionsAggregateArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type Query_RootStatsDailyLiveFreeAppsArgs = {
|
||||
from?: InputMaybe<Scalars['Timestamp']>;
|
||||
to?: InputMaybe<Scalars['Timestamp']>;
|
||||
};
|
||||
|
||||
|
||||
export type Query_RootStatsLiveAppsArgs = {
|
||||
from?: InputMaybe<Scalars['Timestamp']>;
|
||||
to?: InputMaybe<Scalars['Timestamp']>;
|
||||
@@ -17101,6 +17100,14 @@ export type Query_RootSystemConfigsArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type Query_RootSystemLogsArgs = {
|
||||
action: Scalars['String'];
|
||||
appID: Scalars['String'];
|
||||
from?: InputMaybe<Scalars['Timestamp']>;
|
||||
to?: InputMaybe<Scalars['Timestamp']>;
|
||||
};
|
||||
|
||||
|
||||
export type Query_RootUserArgs = {
|
||||
id: Scalars['uuid'];
|
||||
};
|
||||
@@ -22690,7 +22697,7 @@ export type GetPostgresSettingsQueryVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type GetPostgresSettingsQuery = { __typename?: 'query_root', systemConfig?: { __typename?: 'ConfigSystemConfig', postgres: { __typename?: 'ConfigSystemConfigPostgres', database: string } } | null, config?: { __typename: 'ConfigConfig', id: 'ConfigConfig', postgres?: { __typename?: 'ConfigPostgres', version?: string | null, resources?: { __typename?: 'ConfigPostgresResources', storage?: { __typename?: 'ConfigPostgresStorage', capacity: any } | null } | null } | null } | null };
|
||||
export type GetPostgresSettingsQuery = { __typename?: 'query_root', systemConfig?: { __typename?: 'ConfigSystemConfig', postgres: { __typename?: 'ConfigSystemConfigPostgres', database: string } } | null, config?: { __typename: 'ConfigConfig', id: 'ConfigConfig', postgres?: { __typename?: 'ConfigPostgres', version?: string | null, resources?: { __typename?: 'ConfigPostgresResources', enablePublicAccess?: boolean | null, storage?: { __typename?: 'ConfigPostgresStorage', capacity: any } | null } | null } | null } | null };
|
||||
|
||||
export type ResetDatabasePasswordMutationVariables = Exact<{
|
||||
appId: Scalars['String'];
|
||||
@@ -22922,7 +22929,7 @@ export type UpdateConfigMutationVariables = Exact<{
|
||||
}>;
|
||||
|
||||
|
||||
export type UpdateConfigMutation = { __typename?: 'mutation_root', updateConfig: { __typename?: 'ConfigConfig', id: 'ConfigConfig', postgres?: { __typename?: 'ConfigPostgres', resources?: { __typename?: 'ConfigPostgresResources', storage?: { __typename?: 'ConfigPostgresStorage', capacity: any } | null } | null } | null, ai?: { __typename?: 'ConfigAI', version?: string | null, webhookSecret: string, autoEmbeddings?: { __typename?: 'ConfigAIAutoEmbeddings', synchPeriodMinutes?: any | null } | null, openai: { __typename?: 'ConfigAIOpenai', organization?: string | null, apiKey: string }, resources: { __typename?: 'ConfigAIResources', compute: { __typename?: 'ConfigComputeResources', cpu: any, memory: any } } } | null } };
|
||||
export type UpdateConfigMutation = { __typename?: 'mutation_root', updateConfig: { __typename?: 'ConfigConfig', id: 'ConfigConfig', postgres?: { __typename?: 'ConfigPostgres', resources?: { __typename?: 'ConfigPostgresResources', enablePublicAccess?: boolean | null, storage?: { __typename?: 'ConfigPostgresStorage', capacity: any } | null } | null } | null, ai?: { __typename?: 'ConfigAI', version?: string | null, webhookSecret: string, autoEmbeddings?: { __typename?: 'ConfigAIAutoEmbeddings', synchPeriodMinutes?: any | null } | null, openai: { __typename?: 'ConfigAIOpenai', organization?: string | null, apiKey: string }, resources: { __typename?: 'ConfigAIResources', compute: { __typename?: 'ConfigComputeResources', cpu: any, memory: any } } } | null } };
|
||||
|
||||
export type UnpauseApplicationMutationVariables = Exact<{
|
||||
appId: Scalars['uuid'];
|
||||
@@ -24065,6 +24072,7 @@ export const GetPostgresSettingsDocument = gql`
|
||||
storage {
|
||||
capacity
|
||||
}
|
||||
enablePublicAccess
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25428,6 +25436,7 @@ export const UpdateConfigDocument = gql`
|
||||
storage {
|
||||
capacity
|
||||
}
|
||||
enablePublicAccess
|
||||
}
|
||||
}
|
||||
ai {
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# @nhost/docs
|
||||
|
||||
## 2.13.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 6fb0cc2: fix: minor improvements to compute resources' docs
|
||||
- 66bd450: chore: various improvements
|
||||
|
||||
## 2.12.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- d5077c7: feat: added docs about how to connect to postgres
|
||||
|
||||
## 2.11.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- c6dc7f4: chore: docs: add Nhost client reference
|
||||
|
||||
## 2.10.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
176
docs/guides/auth/custom-jwts.mdx
Normal file
176
docs/guides/auth/custom-jwts.mdx
Normal file
@@ -0,0 +1,176 @@
|
||||
---
|
||||
title: Custom JWTs
|
||||
description: Creating custom JWTs
|
||||
icon: ghost
|
||||
---
|
||||
|
||||
In some cases it is necessary to act on behalf of a user. While the Auth service doesn't allow that it is not difficult to implement such functionality as a serverless function. Below you can find an example of a function that can generate a valid access token for your application with customized values. For details read the docstring in the function itself.
|
||||
|
||||
Feel free to adapt to your needs.
|
||||
|
||||
### Dependencies
|
||||
|
||||
```
|
||||
npm install jsonwebtoken
|
||||
```
|
||||
|
||||
### Function
|
||||
|
||||
Create a file under `functions` (for instance `/functions/custom-jwts.ts`), with the following contents:
|
||||
|
||||
```js
|
||||
import { Request, Response } from 'express'
|
||||
import process from 'process'
|
||||
import jwt from 'jsonwebtoken'
|
||||
|
||||
// function to extract jwt from the request
|
||||
const getJwt = (req: Request): string | null => {
|
||||
const authHeader = req.headers.authorization
|
||||
if (!authHeader) {
|
||||
return null
|
||||
}
|
||||
|
||||
const parts = authHeader.split(' ')
|
||||
if (parts.length !== 2) {
|
||||
return null
|
||||
}
|
||||
|
||||
const [scheme, token] = parts
|
||||
if (!/^Bearer$/i.test(scheme)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return token
|
||||
}
|
||||
|
||||
// validate jwt token is valid and caller is either an admin or an operator
|
||||
const jwtIsAuthorized = (req: Request, key: string): string => {
|
||||
const token = getJwt(req)
|
||||
if (!token) {
|
||||
return ""
|
||||
}
|
||||
|
||||
try {
|
||||
const decoded = jwt.verify(token, key)
|
||||
|
||||
const claims = decoded['https://hasura.io/jwt/claims']
|
||||
if ( !claims || !claims['x-hasura-allowed-roles'] ) {
|
||||
return ""
|
||||
}
|
||||
|
||||
if (
|
||||
claims['x-hasura-allowed-roles'].includes('admin') ||
|
||||
claims['x-hasura-allowed-roles'].includes('operator')
|
||||
) {
|
||||
return decoded.sub
|
||||
}
|
||||
|
||||
return ""
|
||||
} catch (e) {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
This is a sample function that generates a JWT token to impersonate users.
|
||||
|
||||
Authorization:
|
||||
|
||||
- send a valid JWT token with the request. The token should have the `admin` or `operator` role.
|
||||
- send the `x-hasura-admin-secret` header with the request
|
||||
|
||||
Body:
|
||||
|
||||
A json object with the following keys:
|
||||
|
||||
- `userId` (string): the user id for which the token is generated
|
||||
- `defaultRole` (string): the default role for the userId
|
||||
- `allowedRoles` (array of strings): the roles that the userId can assume
|
||||
|
||||
Returns:
|
||||
|
||||
A json object with the following keys:
|
||||
|
||||
- `accessToken` (string) - The generated access token
|
||||
|
||||
|
||||
In addition to the typical JWT claims generated by Nhost, the token generated by this function will have the following claims:
|
||||
|
||||
- `x-hasura-on-behalf-of`: the user id of the caller or `admin` if the caller used the `x-hasura-admin-secret` header
|
||||
|
||||
You are free to modify this function to suit your needs.
|
||||
*/
|
||||
export default (req: Request, res: Response) => {
|
||||
let authorizedCaller = ""
|
||||
if (req.headers['x-hasura-admin-secret'] === process.env.HASURA_GRAPHQL_ADMIN_SECRET) {
|
||||
authorizedCaller = "admin"
|
||||
}
|
||||
|
||||
const jwtSecret = JSON.parse(process.env.NHOST_JWT_SECRET)
|
||||
if (!authorizedCaller) {
|
||||
authorizedCaller = jwtIsAuthorized(req, jwtSecret.key)
|
||||
}
|
||||
|
||||
if (!authorizedCaller) {
|
||||
return res.status(401).json({ message: 'Unauthorized' })
|
||||
}
|
||||
|
||||
// extract from json in the body
|
||||
const {userId, defaultRole, allowedRoles} = req.body
|
||||
if (!userId || !defaultRole || !allowedRoles) {
|
||||
return res.status(400).json({ message: 'Bad request' })
|
||||
}
|
||||
|
||||
let token = jwt.sign({
|
||||
"exp": Math.floor(Date.now() / 1000) + 60 * 60, // 1 hour
|
||||
"https://hasura.io/jwt/claims": {
|
||||
"x-hasura-allowed-roles": allowedRoles,
|
||||
"x-hasura-default-role": defaultRole,
|
||||
"x-hasura-user-id": userId,
|
||||
"x-hasura-user-is-anonymous": "false",
|
||||
"x-hasura-on-behalf-of": authorizedCaller
|
||||
},
|
||||
"iat": Math.floor(Date.now() / 1000),
|
||||
"iss": "custom-lambda",
|
||||
"sub": userId,
|
||||
}, jwtSecret.key);
|
||||
|
||||
res.status(200).json(
|
||||
{
|
||||
accessToken: token,
|
||||
},
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
Now you can call it like:
|
||||
|
||||
```
|
||||
curl -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "x-hasura-admin-secret: nhost-admin-secret" \
|
||||
-d '{"userId": "FFAB5354-C5EB-42C1-8BC3-AD21D2297883", "defaultRole": "user", "allowedRoles": ["user", "me"]}' \
|
||||
https://local.functions.nhost.run/v1/custom-jwt
|
||||
{"accessToken":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3MTcxNDIyMTMsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9jbGFpbXMiOnsieC1oYXN1cmEtYWxsb3dlZC1yb2xlcyI6WyJ1c2VyIiwibWUiXSwieC1oYXN1cmEtZGVmYXVsdC1yb2xlIjoidXNlciIsIngtaGFzdXJhLXVzZXItaWQiOiJGRkFCNTM1NC1DNUVCLTQyQzEtOEJDMy1BRDIxRDIyOTc4ODMiLCJ4LWhhc3VyYS11c2VyLWlzLWFub255bW91cyI6ImZhbHNlIiwieC1oYXN1cmEtb24tYmVoYWxmLW9mIjoiYWRtaW4ifSwiaWF0IjoxNzE3MTM4NjEzLCJpc3MiOiJjdXN0b20tbGFtYmRhIiwic3ViIjoiRkZBQjUzNTQtQzVFQi00MkMxLThCQzMtQUQyMUQyMjk3ODgzIn0.bRhzJvXMdkQA8aXPH95uMT17WHED2rSRq3gE21Vp3Ak"}
|
||||
```
|
||||
|
||||
The new token should be a valid token for your application with the custom values requested:
|
||||
|
||||
```json
|
||||
{
|
||||
"exp": 1717141288,
|
||||
"https://hasura.io/jwt/claims": {
|
||||
"x-hasura-allowed-roles": [
|
||||
"a",
|
||||
"b"
|
||||
],
|
||||
"x-hasura-default-role": "user",
|
||||
"x-hasura-user-id": "FFAB5354-C5EB-42C1-8BC3-AD21D2297883",
|
||||
"x-hasura-user-is-anonymous": "false",
|
||||
"x-hasura-on-behalf-of": "admin"
|
||||
},
|
||||
"iat": 1717137688,
|
||||
"iss": "custom-lambda",
|
||||
"sub": "FFAB5354-C5EB-42C1-8BC3-AD21D2297883"
|
||||
}
|
||||
```
|
||||
@@ -93,3 +93,7 @@ nhost.auth.signIn({
|
||||
provider: 'apple'
|
||||
})
|
||||
```
|
||||
|
||||
<Note>
|
||||
To use your own domain for the callback URL refer to the [custom domains](/platform/custom-domains) documentation.
|
||||
</Note>
|
||||
|
||||
@@ -41,3 +41,7 @@ nhost.auth.signIn({
|
||||
provider: 'discord'
|
||||
})
|
||||
```
|
||||
|
||||
<Note>
|
||||
To use your own domain for the callback URL refer to the [custom domains](/platform/custom-domains) documentation.
|
||||
</Note>
|
||||
|
||||
@@ -64,3 +64,7 @@ nhost.auth.signIn({
|
||||
provider: 'facebook'
|
||||
})
|
||||
```
|
||||
|
||||
<Note>
|
||||
To use your own domain for the callback URL refer to the [custom domains](/platform/custom-domains) documentation.
|
||||
</Note>
|
||||
|
||||
@@ -49,3 +49,7 @@ nhost.auth.signIn({
|
||||
provider: "github",
|
||||
});
|
||||
```
|
||||
|
||||
<Note>
|
||||
To use your own domain for the callback URL refer to the [custom domains](/platform/custom-domains) documentation.
|
||||
</Note>
|
||||
|
||||
@@ -73,3 +73,7 @@ nhost.auth.signIn({
|
||||
provider: 'google'
|
||||
})
|
||||
```
|
||||
|
||||
<Note>
|
||||
To use your own domain for the callback URL refer to the [custom domains](/platform/custom-domains) documentation.
|
||||
</Note>
|
||||
|
||||
@@ -64,3 +64,7 @@ nhost.auth.signIn({
|
||||
provider: 'linkedin'
|
||||
})
|
||||
```
|
||||
|
||||
<Note>
|
||||
To use your own domain for the callback URL refer to the [custom domains](/platform/custom-domains) documentation.
|
||||
</Note>
|
||||
|
||||
@@ -49,3 +49,7 @@ nhost.auth.signIn({
|
||||
provider: 'spotify'
|
||||
})
|
||||
```
|
||||
|
||||
<Note>
|
||||
To use your own domain for the callback URL refer to the [custom domains](/platform/custom-domains) documentation.
|
||||
</Note>
|
||||
|
||||
@@ -43,3 +43,7 @@ nhost.auth.signIn({
|
||||
provider: 'twitch'
|
||||
})
|
||||
```
|
||||
|
||||
<Note>
|
||||
To use your own domain for the callback URL refer to the [custom domains](/platform/custom-domains) documentation.
|
||||
</Note>
|
||||
|
||||
@@ -63,3 +63,7 @@ nhost.auth.signIn({
|
||||
provider: 'workos'
|
||||
})
|
||||
```
|
||||
|
||||
<Note>
|
||||
To use your own domain for the callback URL refer to the [custom domains](/platform/custom-domains) documentation.
|
||||
</Note>
|
||||
|
||||
43
docs/guides/database/access.mdx
Normal file
43
docs/guides/database/access.mdx
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
title: Accessing the Database
|
||||
description: How to access the database directly using the connection string
|
||||
icon: key
|
||||
---
|
||||
|
||||
In most cases you will not need to access the database directly, choosing to interact with the data via the Graphql API, however, if you need direct access to postgres you can access it via the connection string.
|
||||
|
||||
|
||||
# Nhost Run
|
||||
|
||||
You can find details on how to connect to the database from an [Nhost Run](/product/run) service [here](/guides/run/networking#connecting-to-the-nhost-stack). If you don't know the password you can set a new password in the dashboard:
|
||||
|
||||
**Project Dashboard -> Settings -> Database**
|
||||
|
||||

|
||||
|
||||
# Public Access
|
||||
|
||||
For security reasons, by default your database won't be accessible online. If you need to access it directly from the Internet, first you will need to enable public access (enabling public access will also show the connection details):
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Dashboard">
|
||||
**Project Dashboard -> Settings -> Database**
|
||||
|
||||

|
||||
|
||||
</Tab>
|
||||
<Tab title="Config">
|
||||
```toml
|
||||
[postgres.resources]
|
||||
enablePublicAccess = true
|
||||
```
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
<Note>
|
||||
Public access to your database utilizes [pgbouncer](http://www.pgbouncer.org). As this pooler is shared infrastructure the pooler will still be available even if your database has no public access configured. The pooler will simply not have access to your database.
|
||||
</Note>
|
||||
|
||||
# Functions
|
||||
|
||||
[Functions](/product/functions) run on a separate network, which means in order to access the database you will first need to [make it public](#public-access).
|
||||
@@ -16,7 +16,7 @@ In case your Postgres service is not meeting your performance expectations, you
|
||||
|
||||
4. Evaluate the usage of indexes in your database. Identify queries that could benefit from additional indexes and strategically add them to improve query performance.
|
||||
|
||||
5. Increase the disk size to increase [disk performance](/platform/compute-resources#disk-performance). Keep in mind increasing the disk size isn't reversible and increasing the memory of the service may yield better results. This is mostly useful when your data is very volatile and the postgres cache can't work effectively. Only attempt to increase disk for performance reasons if your reads and writes are very high and increasing memory isn't effective.
|
||||
5. If the problem is related to IOPS, consider increasing [disk performance](/platform/compute-resources#disk-performance).
|
||||
|
||||
By implementing these steps, you can effectively address performance concerns and enhance the overall performance of your Postgres service.
|
||||
|
||||
|
||||
BIN
docs/images/guides/database/access/public.png
Normal file
BIN
docs/images/guides/database/access/public.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 426 KiB |
BIN
docs/images/guides/database/access/reset.png
Normal file
BIN
docs/images/guides/database/access/reset.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 382 KiB |
BIN
docs/images/platform/compute-resources/guaranteed-resources.png
Normal file
BIN
docs/images/platform/compute-resources/guaranteed-resources.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 233 KiB |
BIN
docs/images/platform/compute-resources/resource-utilization.png
Normal file
BIN
docs/images/platform/compute-resources/resource-utilization.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 241 KiB After Width: | Height: | Size: 241 KiB |
@@ -96,7 +96,7 @@
|
||||
},
|
||||
{
|
||||
"group": "Database",
|
||||
"pages": ["guides/database/configuring-postgres", "guides/database/extensions", "guides/database/performance"]
|
||||
"pages": ["guides/database/configuring-postgres", "guides/database/access", "guides/database/extensions", "guides/database/performance"]
|
||||
},
|
||||
{
|
||||
"group": "AI",
|
||||
@@ -134,7 +134,8 @@
|
||||
"guides/auth/sign-in-phone-number",
|
||||
"guides/auth/sign-in-webauthn",
|
||||
"guides/auth/elevated-permissions",
|
||||
"guides/auth/email-templates"
|
||||
"guides/auth/email-templates",
|
||||
"guides/auth/custom-jwts"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -298,6 +299,10 @@
|
||||
"group": "JavaScript",
|
||||
"icon": "js",
|
||||
"pages": [
|
||||
{
|
||||
"group": "nhost-js",
|
||||
"pages": ["reference/javascript/nhost-js/nhost-client", "reference/javascript/nhost-js/set-role", "reference/javascript/nhost-js/unset-role"]
|
||||
},
|
||||
{
|
||||
"group": "Auth",
|
||||
"pages": [
|
||||
@@ -338,7 +343,10 @@
|
||||
"reference/javascript/storage/get-public-url",
|
||||
"reference/javascript/storage/delete",
|
||||
"reference/javascript/storage/set-access-token",
|
||||
"reference/javascript/storage/set-admin-secret"
|
||||
"reference/javascript/storage/set-admin-secret",
|
||||
"reference/javascript/storage/set-headers",
|
||||
"reference/javascript/storage/unset-headers",
|
||||
"reference/javascript/storage/get-headers"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -347,7 +355,10 @@
|
||||
"reference/javascript/graphql/nhost-graphql-client",
|
||||
"reference/javascript/graphql/get-url",
|
||||
"reference/javascript/graphql/set-access-token",
|
||||
"reference/javascript/graphql/request"
|
||||
"reference/javascript/graphql/request",
|
||||
"reference/javascript/graphql/set-headers",
|
||||
"reference/javascript/graphql/unset-headers",
|
||||
"reference/javascript/graphql/get-headers"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/docs",
|
||||
"version": "2.10.3",
|
||||
"version": "2.13.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "mintlify dev"
|
||||
|
||||
@@ -72,6 +72,28 @@ To setup dedicated resources for your project, you can either use the Dashboard
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Bursting with Dedicated Compute
|
||||
|
||||
When using dedicated compute we allow your application to use more than its alloted CPU resources if those resources are available. This means what we are calling dedicated compute is, in fact, guaranteed compute. For instance:
|
||||
|
||||
<div align="center">
|
||||
<img width="300" src="/images/platform/compute-resources/guaranteed-resources.png" alt="resource allocation" />
|
||||
</div>
|
||||
|
||||
In the graph above we can see three applications assigned to the same node, each with its own dedicated compute (the solid lines block). However, all applications are allowed to use the non-solid region of compute as long as the rest of the projects are not using it:
|
||||
|
||||
<div align="center">
|
||||
<img width="300" src="/images/platform/compute-resources/resource-utilization.png" alt="resource utilization" />
|
||||
</div>
|
||||
|
||||
Above we can see three different scenarios:
|
||||
|
||||
- In scenario A the green application is barely using its alloted CPU so if the other applications need it, they can borrow it.
|
||||
- Similarly, in scenario B the green application can borrow resources if it needs it from other applications if those aren't using them.
|
||||
- In the case all applications need to use all of their resources, nobody can steal from each other as resources are guaranteed per application.
|
||||
|
||||
This borrowing of resources is convenient in case of short and unexpected bursts, however, as those are not guaranteed you shouldn't rely on them for sustained usage.
|
||||
|
||||
## Disk Performance
|
||||
|
||||
By default disks are provisioned with a capacity for 3000 IOPS and 125 Mbps of throughput. If you need higher performance don't hesitate to contact us.
|
||||
|
||||
@@ -18,7 +18,7 @@ The following examples assume we are configuring custom domains at `*.custom-dom
|
||||
1. Add a CNAME record in your DNS provider for each of the services you want a custom domain for, and click "Verify". The verification might take a few seconds to succeed.
|
||||
2. Once the verification succeeds, click "Save" to update your project.
|
||||
|
||||

|
||||

|
||||
|
||||
</Tab>
|
||||
|
||||
@@ -62,3 +62,16 @@ fqdn = ['my-service.custom-domain.com']
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
|
||||
<Note>
|
||||
After configuring your custom domains don't forget to update your Nhost client to make use of them. For instance, when using our [SDK](/reference/javascript/nhost-js/nhost-client):
|
||||
|
||||
```js
|
||||
const nhost = new NhostClient({
|
||||
authUrl: 'https://auth.custom-domain.com/v1',
|
||||
storageUrl: 'https://subdomain.storage.region.nhost.run/v1',
|
||||
graphqlUrl: 'https://hasura.custom-domain.com/v1/graphql',
|
||||
functionsUrl: 'https://functions.custom-domain.com/v1'
|
||||
})
|
||||
```
|
||||
</Note>
|
||||
|
||||
10
docs/reference/javascript/graphql/get-headers.mdx
Normal file
10
docs/reference/javascript/graphql/get-headers.mdx
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: getHeaders()
|
||||
sidebarTitle: getHeaders()
|
||||
---
|
||||
|
||||
Use `nhost.graphql.getHeaders` to get the global headers sent with all graphql requests
|
||||
|
||||
```ts
|
||||
nhost.graphql.getHeaders()
|
||||
```
|
||||
20
docs/reference/javascript/graphql/set-headers.mdx
Normal file
20
docs/reference/javascript/graphql/set-headers.mdx
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
title: setHeaders()
|
||||
sidebarTitle: setHeaders()
|
||||
---
|
||||
|
||||
Use `nhost.graphql.setHeaders` to set global headers to be sent in all subsequent graphql requests
|
||||
|
||||
```ts
|
||||
nhost.graphql.setHeaders({
|
||||
'x-hasura-role': 'admin'
|
||||
})
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">headers</span>** <span className="optional-status">optional</span> <code>Record<string, string></code>
|
||||
|
||||
---
|
||||
11
docs/reference/javascript/graphql/unset-headers.mdx
Normal file
11
docs/reference/javascript/graphql/unset-headers.mdx
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: unsetHeaders()
|
||||
sidebarTitle: unsetHeaders()
|
||||
---
|
||||
|
||||
Use `nhost.graphql.unsetHeaders` to remove global headers sent with all requests, except for the role header to preserve
|
||||
the role set by 'setRole' method.
|
||||
|
||||
```ts
|
||||
nhost.graphql.unsetHeaders()
|
||||
```
|
||||
51
docs/reference/javascript/nhost-js/nhost-client.mdx
Normal file
51
docs/reference/javascript/nhost-js/nhost-client.mdx
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: NhostClient
|
||||
description: The Nhost client is the entry point to Nhost services.
|
||||
---
|
||||
|
||||
# `NhostClient`
|
||||
|
||||
```ts
|
||||
// Create a new Nhost client from subdomain and region.
|
||||
const nhost = new NhostClient({ subdomain, region })
|
||||
```
|
||||
|
||||
```ts
|
||||
// Create a new Nhost client from individual service URLs (custom domains, self-hosting, etc).
|
||||
const nhost = new NhostClient({
|
||||
authUrl: 'my-auth-service-url',
|
||||
storageUrl: 'my-storage-service-url',
|
||||
graphqlUrl: 'my-graphql-service-url',
|
||||
functionsUrl: 'my-functions-service-url'
|
||||
})
|
||||
```
|
||||
|
||||
```ts
|
||||
// Create a new Nhost client for local development.
|
||||
const nhost = new NhostClient({ subdomain: 'local' })
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">\_\_namedParameters</span>** <span className="optional-status">required</span> [`NhostClientConstructorParams`](/reference/javascript/nhost-js/types/nhost-client-constructor-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------ | :------: | :--------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>adminSecret</span> | <code>string</code> | | When set, the admin secret is sent as a header, `x-hasura-admin-secret`, for all requests to GraphQL, Storage, and Serverless Functions. |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>functionsUrl</span> | <code>string</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>storageUrl</span> | <code>string</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>graphqlUrl</span> | <code>string</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>authUrl</span> | <code>string</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>region</span> | <code>string</code> | | Project region (e.g. `eu-central-1`) Project region is not required during local development (when `subdomain` is `localhost`) |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>subdomain</span> | <code>string</code> | | Project subdomain (e.g. `ieingiwnginwnfnegqwvdqwdwq`) Use `localhost` during local development |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>devTools</span> | <code>boolean</code> | | Activate devTools e.g. the ability to connect to the xstate inspector |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>autoSignIn</span> | <code>boolean</code> | | When set to true, will parse the url on startup to check if it contains a refresh token to start the session with |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>autoRefreshToken</span> | <code>boolean</code> | | When set to true, will automatically refresh token before it expires |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>clientStorage</span> | [`ClientStorage`](/reference/javascript/nhost-js/types/client-storage) | | Object where the refresh token will be persisted and read locally. |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>clientStorageType</span> | [`ClientStorageType`](/reference/javascript/nhost-js/types/client-storage-type) | | Define a way to get information about the refresh token and its exipration date. |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>refreshIntervalTime</span> | <code>number</code> | | Time interval until token refreshes, in seconds |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>start</span> | <code>boolean</code> | | |
|
||||
|
||||
---
|
||||
29
docs/reference/javascript/nhost-js/set-role.mdx
Normal file
29
docs/reference/javascript/nhost-js/set-role.mdx
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: setRole()
|
||||
sidebarTitle: setRole()
|
||||
---
|
||||
|
||||
Use `nhost.setRole` to set the user role for all subsequent GraphQL, storage, and functions calls.
|
||||
Underneath, this method sets the `x-hasura-role` header on the graphql, storage,
|
||||
and functions clients.
|
||||
|
||||
```ts
|
||||
nhost.graphql.setHeaders({ 'x-hasura-role': role })
|
||||
nhost.storage.setHeaders({ 'x-hasura-role': role })
|
||||
nhost.functions.setHeaders({ 'x-hasura-role': role })
|
||||
```
|
||||
|
||||
Note: Exercise caution when mixing the use of `setRole` along with `setHeaders` when setting the
|
||||
`x-hasura-role` header, as the last call will override any previous ones.
|
||||
|
||||
```ts
|
||||
nhost.setRole('admin')
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">role</span>** <span className="optional-status">required</span> <code>string</code>
|
||||
|
||||
---
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: ClientStorageType
|
||||
sidebarTitle: ClientStorageType
|
||||
description: No description provided.
|
||||
---
|
||||
|
||||
# `ClientStorageType`
|
||||
|
||||
```ts
|
||||
type ClientStorageType =
|
||||
| 'capacitor'
|
||||
| 'custom'
|
||||
| 'expo-secure-storage'
|
||||
| 'localStorage'
|
||||
| 'react-native'
|
||||
| 'web'
|
||||
| 'cookie'
|
||||
```
|
||||
55
docs/reference/javascript/nhost-js/types/client-storage.mdx
Normal file
55
docs/reference/javascript/nhost-js/types/client-storage.mdx
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
title: ClientStorage
|
||||
sidebarTitle: ClientStorage
|
||||
description: No description provided.
|
||||
---
|
||||
|
||||
# `ClientStorage`
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">customSet</span>** <span className="optional-status">optional</span> <code>(key: string, value: null | string) => void | Promise<void></code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">customGet</span>** <span className="optional-status">optional</span> <code>(key: string) => null | string | Promise<null | string></code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">deleteItemAsync</span>** <span className="optional-status">optional</span> <code>(key: string) => void</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">getItemAsync</span>** <span className="optional-status">optional</span> <code>(key: string) => any</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">setItemAsync</span>** <span className="optional-status">optional</span> <code>(key: string, value: string) => void</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">remove</span>** <span className="optional-status">optional</span> <code>(options: { key: string }) => void</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">get</span>** <span className="optional-status">optional</span> <code>(options: { key: string }) => any</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">set</span>** <span className="optional-status">optional</span> <code>(options: { key: string, value: string }) => void</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">removeItem</span>** <span className="optional-status">optional</span> <code>(key: string) => void</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">getItem</span>** <span className="optional-status">optional</span> <code>(key: string) => any</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">setItem</span>** <span className="optional-status">optional</span> <code>(\_key: string, \_value: string) => void</code>
|
||||
|
||||
---
|
||||
@@ -0,0 +1,118 @@
|
||||
---
|
||||
title: NhostClientConstructorParams
|
||||
sidebarTitle: NhostClientConstructorParams
|
||||
description: No description provided.
|
||||
---
|
||||
|
||||
# `NhostClientConstructorParams`
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">start</span>** <span className="optional-status">optional</span> <code>boolean</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">refreshIntervalTime</span>** <span className="optional-status">optional</span> <code>number</code>
|
||||
|
||||
Time interval until token refreshes, in seconds
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">clientStorageType</span>** <span className="optional-status">optional</span> [`ClientStorageType`](/reference/javascript/nhost-js/types/client-storage-type)
|
||||
|
||||
Define a way to get information about the refresh token and its exipration date.
|
||||
|
||||
**`@default`**
|
||||
|
||||
`web`
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">clientStorage</span>** <span className="optional-status">optional</span> [`ClientStorage`](/reference/javascript/nhost-js/types/client-storage)
|
||||
|
||||
Object where the refresh token will be persisted and read locally.
|
||||
|
||||
Recommended values:
|
||||
|
||||
- `'web'` and `'cookies'`: no value is required
|
||||
- `'react-native'`: `import Storage from @react-native-async-storage/async-storage`
|
||||
- `'cookies'`: `localStorage`
|
||||
- `'custom'`: an object that defines the following methods:
|
||||
- `setItem` or `setItemAsync`
|
||||
- `getItem` or `getItemAsync`
|
||||
- `removeItem`
|
||||
- `'capacitor'`: `import { Storage } from @capacitor/storage`
|
||||
- `'expo-secure-store'`: `import * as SecureStore from 'expo-secure-store'`
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :-------------------------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">clientStorage.</span>setItem</span> | <code>(\_key: string, \_value: string) => void</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">clientStorage.</span>getItem</span> | <code>(key: string) => any</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">clientStorage.</span>removeItem</span> | <code>(key: string) => void</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">clientStorage.</span>set</span> | <code>(options: { key: string, value: string }) => void</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">clientStorage.</span>get</span> | <code>(options: { key: string }) => any</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">clientStorage.</span>remove</span> | <code>(options: { key: string }) => void</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">clientStorage.</span>setItemAsync</span> | <code>(key: string, value: string) => void</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">clientStorage.</span>getItemAsync</span> | <code>(key: string) => any</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">clientStorage.</span>deleteItemAsync</span> | <code>(key: string) => void</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">clientStorage.</span>customGet</span> | <code>(key: string) => null | string | Promise<null | string></code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">clientStorage.</span>customSet</span> | <code>(key: string, value: null | string) => void | Promise<void></code> | | |
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">autoRefreshToken</span>** <span className="optional-status">optional</span> <code>boolean</code>
|
||||
|
||||
When set to true, will automatically refresh token before it expires
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">autoSignIn</span>** <span className="optional-status">optional</span> <code>boolean</code>
|
||||
|
||||
When set to true, will parse the url on startup to check if it contains a refresh token to start the session with
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">devTools</span>** <span className="optional-status">optional</span> <code>boolean</code>
|
||||
|
||||
Activate devTools e.g. the ability to connect to the xstate inspector
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">subdomain</span>** <span className="optional-status">optional</span> <code>string</code>
|
||||
|
||||
Project subdomain (e.g. `ieingiwnginwnfnegqwvdqwdwq`)
|
||||
Use `localhost` during local development
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">region</span>** <span className="optional-status">optional</span> <code>string</code>
|
||||
|
||||
Project region (e.g. `eu-central-1`)
|
||||
Project region is not required during local development (when `subdomain` is `localhost`)
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">authUrl</span>** <span className="optional-status">optional</span> <code>string</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">graphqlUrl</span>** <span className="optional-status">optional</span> <code>string</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">storageUrl</span>** <span className="optional-status">optional</span> <code>string</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">functionsUrl</span>** <span className="optional-status">optional</span> <code>string</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">adminSecret</span>** <span className="optional-status">optional</span> <code>string</code>
|
||||
|
||||
When set, the admin secret is sent as a header, `x-hasura-admin-secret`,
|
||||
for all requests to GraphQL, Storage, and Serverless Functions.
|
||||
|
||||
---
|
||||
14
docs/reference/javascript/nhost-js/unset-role.mdx
Normal file
14
docs/reference/javascript/nhost-js/unset-role.mdx
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
title: unsetRole()
|
||||
sidebarTitle: unsetRole()
|
||||
---
|
||||
|
||||
Use `nhost.unsetRole` to unset the user role for all subsequent graphql, storage and functions calls.
|
||||
Underneath, this method removes the `x-hasura-role` header from the graphql, storage and functions clients.
|
||||
|
||||
Note: Exercise caution when mixing the use of `unsetRole` along with `setHeaders` when setting the
|
||||
`x-hasura-role` header, as the last call will override any previous ones.
|
||||
|
||||
```ts
|
||||
nhost.unsetRole()
|
||||
```
|
||||
@@ -22,6 +22,6 @@ const { file, error } = await nhost.storage.download({ fileId: '<File-ID>' })
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>quality</span> | <code>number</code> | | Image quality, between 1 and 100, 100 being the best quality |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>height</span> | <code>number</code> | | Image height, in pixels |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>width</span> | <code>number</code> | | Image width, in pixels |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>headers</span> | <code>Record<string, string></code> | | Optional headers to be sent with the request |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>headers</span> | <code>Record<string, string></code> | | |
|
||||
|
||||
---
|
||||
|
||||
10
docs/reference/javascript/storage/get-headers.mdx
Normal file
10
docs/reference/javascript/storage/get-headers.mdx
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: getHeaders()
|
||||
sidebarTitle: getHeaders()
|
||||
---
|
||||
|
||||
Use `nhost.storage.getHeaders` to get global headers sent with all storage requests.
|
||||
|
||||
```ts
|
||||
nhost.storage.getHeaders()
|
||||
```
|
||||
@@ -24,12 +24,13 @@ console.log('expiration: ', presignedUrl.expiration)
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`StorageGetPresignedUrlParams`](/reference/javascript/storage/types/storage-get-presigned-url-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :----------------------------------------------------------------------------------------- | :------------------ | :------: | :----------------------------------------------------------- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>fileId</span> | <code>string</code> | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>blur</span> | <code>number</code> | | Image blur, between 0 and 100 |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>quality</span> | <code>number</code> | | Image quality, between 1 and 100, 100 being the best quality |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>height</span> | <code>number</code> | | Image height, in pixels |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>width</span> | <code>number</code> | | Image width, in pixels |
|
||||
| Property | Type | Required | Notes |
|
||||
| :----------------------------------------------------------------------------------------- | :---------------------------------------- | :------: | :----------------------------------------------------------- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>fileId</span> | <code>string</code> | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>blur</span> | <code>number</code> | | Image blur, between 0 and 100 |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>quality</span> | <code>number</code> | | Image quality, between 1 and 100, 100 being the best quality |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>height</span> | <code>number</code> | | Image height, in pixels |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>width</span> | <code>number</code> | | Image width, in pixels |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>headers</span> | <code>Record<string, string></code> | | |
|
||||
|
||||
---
|
||||
|
||||
22
docs/reference/javascript/storage/set-headers.mdx
Normal file
22
docs/reference/javascript/storage/set-headers.mdx
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: setHeaders()
|
||||
sidebarTitle: setHeaders()
|
||||
---
|
||||
|
||||
Use `nhost.storage.setHeaders` to set global headers to be sent for all subsequent storage requests.
|
||||
|
||||
```ts
|
||||
nhost.storage.setHeaders({
|
||||
'x-hasura-role': 'admin'
|
||||
})
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">headers</span>** <span className="optional-status">optional</span> <code>Record<string, string></code>
|
||||
|
||||
key value headers object
|
||||
|
||||
---
|
||||
@@ -10,6 +10,10 @@ description: No description provided.
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">headers</span>** <span className="optional-status">optional</span> <code>Record<string, string></code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">fileId</span>** <span className="optional-status">required</span> <code>string</code>
|
||||
|
||||
---
|
||||
|
||||
@@ -10,6 +10,10 @@ description: No description provided.
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">headers</span>** <span className="optional-status">optional</span> <code>Record<string, string></code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">fileId</span>** <span className="optional-status">required</span> <code>string</code>
|
||||
|
||||
---
|
||||
|
||||
@@ -40,6 +40,4 @@ Image width, in pixels
|
||||
|
||||
**<span className="parameter-name">headers</span>** <span className="optional-status">optional</span> <code>Record<string, string></code>
|
||||
|
||||
Optional headers to be sent with the request
|
||||
|
||||
---
|
||||
|
||||
@@ -37,3 +37,7 @@ Image height, in pixels
|
||||
Image width, in pixels
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">headers</span>** <span className="optional-status">optional</span> <code>Record<string, string></code>
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: StorageHeadersParam
|
||||
sidebarTitle: StorageHeadersParam
|
||||
description: No description provided.
|
||||
---
|
||||
|
||||
# `StorageHeadersParam`
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">headers</span>** <span className="optional-status">optional</span> <code>Record<string, string></code>
|
||||
|
||||
---
|
||||
@@ -25,3 +25,7 @@ description: No description provided.
|
||||
**<span className="parameter-name">id</span>** <span className="optional-status">optional</span> <code>string</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">headers</span>** <span className="optional-status">optional</span> <code>Record<string, string></code>
|
||||
|
||||
---
|
||||
|
||||
@@ -14,10 +14,10 @@ description: No description provided.
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">headers</span>** <span className="optional-status">optional</span> <code>Record<string, string></code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">bucketId</span>** <span className="optional-status">optional</span> <code>string</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">headers</span>** <span className="optional-status">optional</span> <code>Record<string, string></code>
|
||||
|
||||
---
|
||||
|
||||
10
docs/reference/javascript/storage/unset-headers.mdx
Normal file
10
docs/reference/javascript/storage/unset-headers.mdx
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: unsetHeaders()
|
||||
sidebarTitle: unsetHeaders()
|
||||
---
|
||||
|
||||
Use `nhost.storage.unsetHeaders` to remove the global headers sent for all subsequent storage requests.
|
||||
|
||||
```ts
|
||||
nhost.storage.unsetHeaders()
|
||||
```
|
||||
@@ -19,12 +19,13 @@ If no `bucketId` is specified the bucket `default` is used.
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`StorageUploadFileParams`](/reference/javascript/storage/types/storage-upload-file-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------ | :------------------ | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>file</span> | <code>File</code> | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>bucketId</span> | <code>string</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>name</span> | <code>string</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>id</span> | <code>string</code> | | |
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------ | :---------------------------------------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>file</span> | <code>File</code> | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>bucketId</span> | <code>string</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>name</span> | <code>string</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>id</span> | <code>string</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>headers</span> | <code>Record<string, string></code> | | |
|
||||
|
||||
---
|
||||
|
||||
@@ -64,7 +65,7 @@ await storage.upload({
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------ | :---------------------------------------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>formData</span> | <code>FormData | FormData</code> | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>headers</span> | <code>Record<string, string></code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>bucketId</span> | <code>string</code> | | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>headers</span> | <code>Record<string, string></code> | | |
|
||||
|
||||
---
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# @nhost-examples/cli
|
||||
|
||||
## 0.3.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.5
|
||||
|
||||
## 0.3.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.4
|
||||
|
||||
## 0.3.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.3
|
||||
|
||||
## 0.3.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4c35171]
|
||||
- Updated dependencies [3cea460]
|
||||
- @nhost/nhost-js@3.1.2
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/cli",
|
||||
"version": "0.3.3",
|
||||
"version": "0.3.7",
|
||||
"main": "src/index.mjs",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
# @nhost-examples/codegen-react-apollo
|
||||
|
||||
## 0.4.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.2
|
||||
- @nhost/react-apollo@12.0.2
|
||||
|
||||
## 0.4.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.1
|
||||
- @nhost/react-apollo@12.0.1
|
||||
|
||||
## 0.4.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d0c9f4c]
|
||||
- @nhost/react@3.5.0
|
||||
- @nhost/react-apollo@12.0.0
|
||||
|
||||
## 0.4.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.4.4
|
||||
- @nhost/react-apollo@11.0.4
|
||||
|
||||
## 0.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/codegen-react-apollo",
|
||||
"version": "0.4.3",
|
||||
"version": "0.4.7",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"codegen": "graphql-codegen",
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
# @nhost-examples/codegen-react-query
|
||||
|
||||
## 0.4.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.2
|
||||
|
||||
## 0.4.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.1
|
||||
|
||||
## 0.4.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d0c9f4c]
|
||||
- @nhost/react@3.5.0
|
||||
|
||||
## 0.4.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.4.4
|
||||
|
||||
## 0.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/codegen-react-query",
|
||||
"version": "0.4.3",
|
||||
"version": "0.4.7",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"codegen": "graphql-codegen",
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
# @nhost-examples/react-urql
|
||||
|
||||
## 0.3.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.2
|
||||
- @nhost/react-urql@9.0.2
|
||||
|
||||
## 0.3.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.1
|
||||
- @nhost/react-urql@9.0.1
|
||||
|
||||
## 0.3.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d0c9f4c]
|
||||
- @nhost/react@3.5.0
|
||||
- @nhost/react-urql@9.0.0
|
||||
|
||||
## 0.3.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.4.4
|
||||
- @nhost/react-urql@8.0.4
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/codegen-react-urql",
|
||||
"private": true,
|
||||
"version": "0.3.3",
|
||||
"version": "0.3.7",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# @nhost-examples/multi-tenant-one-to-many
|
||||
|
||||
## 2.2.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.5
|
||||
|
||||
## 2.2.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.4
|
||||
|
||||
## 2.2.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.3
|
||||
|
||||
## 2.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4c35171]
|
||||
- Updated dependencies [3cea460]
|
||||
- @nhost/nhost-js@3.1.2
|
||||
|
||||
## 2.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/multi-tenant-one-to-many",
|
||||
"private": true,
|
||||
"version": "2.2.3",
|
||||
"version": "2.2.7",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {},
|
||||
|
||||
@@ -1,5 +1,38 @@
|
||||
# @nhost-examples/nextjs
|
||||
|
||||
## 0.3.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.2
|
||||
- @nhost/react-apollo@12.0.2
|
||||
- @nhost/nextjs@2.1.16
|
||||
|
||||
## 0.3.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.1
|
||||
- @nhost/react-apollo@12.0.1
|
||||
- @nhost/nextjs@2.1.15
|
||||
|
||||
## 0.3.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d0c9f4c]
|
||||
- @nhost/react@3.5.0
|
||||
- @nhost/react-apollo@12.0.0
|
||||
- @nhost/nextjs@2.1.14
|
||||
|
||||
## 0.3.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.4.4
|
||||
- @nhost/react-apollo@11.0.4
|
||||
- @nhost/nextjs@2.1.13
|
||||
|
||||
## 0.3.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/nextjs",
|
||||
"version": "0.3.3",
|
||||
"version": "0.3.7",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# @nhost-examples/node-storage
|
||||
|
||||
## 0.2.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.5
|
||||
|
||||
## 0.2.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.4
|
||||
|
||||
## 0.2.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.3
|
||||
|
||||
## 0.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4c35171]
|
||||
- Updated dependencies [3cea460]
|
||||
- @nhost/nhost-js@3.1.2
|
||||
|
||||
## 0.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/node-storage",
|
||||
"version": "0.2.3",
|
||||
"version": "0.2.7",
|
||||
"private": true,
|
||||
"description": "This is an example of how to use the Storage with Node.js",
|
||||
"main": "src/index.mjs",
|
||||
|
||||
@@ -1,5 +1,31 @@
|
||||
# @nhost-examples/nextjs-server-components
|
||||
|
||||
## 0.4.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.5
|
||||
|
||||
## 0.4.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.4
|
||||
|
||||
## 0.4.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.3
|
||||
|
||||
## 0.4.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4c35171]
|
||||
- Updated dependencies [3cea460]
|
||||
- @nhost/nhost-js@3.1.2
|
||||
|
||||
## 0.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/nextjs-server-components",
|
||||
"version": "0.4.3",
|
||||
"version": "0.4.7",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# @nhost-examples/react-apollo
|
||||
|
||||
## 0.8.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.2
|
||||
- @nhost/react-apollo@12.0.2
|
||||
|
||||
## 0.8.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.1
|
||||
- @nhost/react-apollo@12.0.1
|
||||
|
||||
## 0.8.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- aef4a0a: fix: resolve e2e test issues
|
||||
- Updated dependencies [d0c9f4c]
|
||||
- @nhost/react@3.5.0
|
||||
- @nhost/react-apollo@12.0.0
|
||||
|
||||
## 0.8.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.4.4
|
||||
- @nhost/react-apollo@11.0.4
|
||||
|
||||
## 0.8.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -119,7 +119,7 @@ export async function verifyMagicLink({
|
||||
|
||||
await page
|
||||
.frameLocator('#preview-html')
|
||||
.getByRole('link', { name: /sign in/i })
|
||||
.getByRole('link', { name: /verify email/i })
|
||||
.click()
|
||||
|
||||
const authenticatedPage = await authenticatedPagePromise
|
||||
@@ -154,7 +154,7 @@ export async function resetPassword({
|
||||
|
||||
await page
|
||||
.frameLocator('#preview-html')
|
||||
.getByRole('link', { name: /reset password/i })
|
||||
.getByRole('link', { name: /verify email/i })
|
||||
.click()
|
||||
|
||||
const authenticatedPage = await authenticatedPagePromise
|
||||
|
||||
@@ -1,12 +1,38 @@
|
||||
[
|
||||
{
|
||||
"value": "disabled",
|
||||
"op": "replace",
|
||||
"path": "/auth/method/webauthn/relyingParty/origins/0",
|
||||
"value": "http://localhost:3000"
|
||||
"path": "/auth/elevatedPrivileges/mode"
|
||||
},
|
||||
{
|
||||
"op": "remove",
|
||||
"path": "/auth/method/oauth/apple/clientId"
|
||||
},
|
||||
{
|
||||
"value": false,
|
||||
"op": "replace",
|
||||
"path": "/auth/redirections/clientUrl",
|
||||
"value": "http://localhost:3000"
|
||||
"path": "/auth/method/oauth/apple/enabled"
|
||||
},
|
||||
{
|
||||
"op": "remove",
|
||||
"path": "/auth/method/oauth/apple/keyId"
|
||||
},
|
||||
{
|
||||
"op": "remove",
|
||||
"path": "/auth/method/oauth/apple/privateKey"
|
||||
},
|
||||
{
|
||||
"op": "remove",
|
||||
"path": "/auth/method/oauth/apple/teamId"
|
||||
},
|
||||
{
|
||||
"value": "http://localhost:3000",
|
||||
"op": "replace",
|
||||
"path": "/auth/method/webauthn/relyingParty/origins/0"
|
||||
},
|
||||
{
|
||||
"value": "http://localhost:3000",
|
||||
"op": "replace",
|
||||
"path": "/auth/redirections/clientUrl"
|
||||
}
|
||||
]
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/react-apollo",
|
||||
"version": "0.8.3",
|
||||
"version": "0.8.7",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.9.9",
|
||||
@@ -22,9 +22,9 @@
|
||||
"scripts": {
|
||||
"dev": "vite --host localhost --port 3000",
|
||||
"generate": "graphql-codegen --config graphql.config.yaml",
|
||||
"install-browsers": "pnpm dlx playwright@1.31.0 install --with-deps",
|
||||
"install-browsers": "pnpm playwright install && pnpm playwright install-deps",
|
||||
"e2e": "pnpm e2e:start-backend && pnpm e2e:test",
|
||||
"e2e:test": "pnpm install-browsers && pnpm dlx playwright@1.31.0 test; nhost down",
|
||||
"e2e:test": "pnpm install-browsers && pnpm playwright test",
|
||||
"e2e:start-backend": "cp .secrets.example .secrets && nhost up",
|
||||
"e2e:start-ui": "run-s build preview",
|
||||
"build": "vite build",
|
||||
@@ -52,7 +52,7 @@
|
||||
"@faker-js/faker": "^7.6.0",
|
||||
"@graphql-codegen/cli": "^5.0.2",
|
||||
"@nuintun/qrcode": "^3.4.0",
|
||||
"@playwright/test": "1.31.0",
|
||||
"@playwright/test": "1.41.0",
|
||||
"@types/pngjs": "^6.0.4",
|
||||
"@types/react": "^18.2.73",
|
||||
"@types/react-dom": "^18.2.23",
|
||||
|
||||
4
examples/react-apollo/pnpm-lock.yaml
generated
4
examples/react-apollo/pnpm-lock.yaml
generated
@@ -1241,7 +1241,7 @@ packages:
|
||||
'@simplewebauthn/browser': 6.2.2
|
||||
fetch-ponyfill: 7.1.0
|
||||
js-cookie: 3.0.5
|
||||
jwt-decode: 3.1.2
|
||||
jwt-decode: 4.0.0
|
||||
xstate: 4.38.3
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
@@ -1299,7 +1299,7 @@ packages:
|
||||
dependencies:
|
||||
'@nhost/nhost-js': 3.0.2(graphql@16.8.1)
|
||||
'@xstate/react': 3.2.2(@types/react@18.2.48)(react@18.2.0)(xstate@4.38.3)
|
||||
jwt-decode: 3.1.2
|
||||
jwt-decode: 4.0.0
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
xstate: 4.38.3
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
# @nhost-examples/react-gqty
|
||||
|
||||
## 1.2.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.2
|
||||
|
||||
## 1.2.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.1
|
||||
|
||||
## 1.2.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d0c9f4c]
|
||||
- @nhost/react@3.5.0
|
||||
|
||||
## 1.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.4.4
|
||||
|
||||
## 1.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/react-gqty",
|
||||
"private": true,
|
||||
"version": "1.2.3",
|
||||
"version": "1.2.7",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
@@ -1,5 +1,40 @@
|
||||
# @nhost-examples/vue-apollo
|
||||
|
||||
## 0.6.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.5
|
||||
- @nhost/apollo@7.1.2
|
||||
- @nhost/vue@2.6.2
|
||||
|
||||
## 0.6.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.4
|
||||
- @nhost/apollo@7.1.1
|
||||
- @nhost/vue@2.6.1
|
||||
|
||||
## 0.6.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d0c9f4c]
|
||||
- @nhost/apollo@7.1.0
|
||||
- @nhost/vue@2.6.0
|
||||
- @nhost/nhost-js@3.1.3
|
||||
|
||||
## 0.6.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4c35171]
|
||||
- Updated dependencies [3cea460]
|
||||
- @nhost/nhost-js@3.1.2
|
||||
- @nhost/apollo@7.0.2
|
||||
- @nhost/vue@2.5.4
|
||||
|
||||
## 0.6.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/vue-apollo",
|
||||
"private": true,
|
||||
"version": "0.6.3",
|
||||
"version": "0.6.7",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vite build",
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
# @nhost-examples/vue-quickstart
|
||||
|
||||
## 0.2.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@7.1.2
|
||||
- @nhost/vue@2.6.2
|
||||
|
||||
## 0.2.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@7.1.1
|
||||
- @nhost/vue@2.6.1
|
||||
|
||||
## 0.2.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d0c9f4c]
|
||||
- @nhost/apollo@7.1.0
|
||||
- @nhost/vue@2.6.0
|
||||
|
||||
## 0.2.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@7.0.2
|
||||
- @nhost/vue@2.5.4
|
||||
|
||||
## 0.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/vue-quickstart",
|
||||
"version": "0.2.3",
|
||||
"version": "0.2.7",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
|
||||
24
flake.lock
generated
24
flake.lock
generated
@@ -5,11 +5,11 @@
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1705309234,
|
||||
"narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=",
|
||||
"lastModified": 1710146030,
|
||||
"narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26",
|
||||
"rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -20,11 +20,11 @@
|
||||
},
|
||||
"nix-filter": {
|
||||
"locked": {
|
||||
"lastModified": 1705332318,
|
||||
"narHash": "sha256-kcw1yFeJe9N4PjQji9ZeX47jg0p9A0DuU4djKvg1a7I=",
|
||||
"lastModified": 1710156097,
|
||||
"narHash": "sha256-1Wvk8UP7PXdf8bCCaEoMnOT1qe5/Duqgj+rL8sRQsSM=",
|
||||
"owner": "numtide",
|
||||
"repo": "nix-filter",
|
||||
"rev": "3449dc925982ad46246cfc36469baf66e1b64f17",
|
||||
"rev": "3342559a24e85fc164b295c3444e8a139924675b",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -40,11 +40,11 @@
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1709722688,
|
||||
"narHash": "sha256-ng5a9klcxohFhs9xfNAcZWTveM4SlMWoRoWDYyXoECE=",
|
||||
"lastModified": 1716813459,
|
||||
"narHash": "sha256-kPV0JcxBO3krxLeGEAsk5tZ7GUo+DStD2Cg78iGm4v0=",
|
||||
"owner": "nhost",
|
||||
"repo": "nixops",
|
||||
"rev": "919e405ab485c099a42d44a2936cab2d3b1bd444",
|
||||
"rev": "981affa7a17fd064bb5096ccfec8ddd98b115ef5",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -55,11 +55,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1708943256,
|
||||
"narHash": "sha256-K9VeHrhXsigdhNMZ8hqAk7jtRy4ollqhkYYNZqbfssg=",
|
||||
"lastModified": 1716715802,
|
||||
"narHash": "sha256-usk0vE7VlxPX8jOavrtpOqphdfqEQpf9lgedlY/r66c=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "fcea2b6260dd566c28c894b4207a5f2b56c2cba3",
|
||||
"rev": "e2dd4e18cc1c7314e24154331bae07df76eb582f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# @nhost/apollo
|
||||
|
||||
## 7.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.5
|
||||
|
||||
## 7.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.4
|
||||
|
||||
## 7.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- d0c9f4c: fix: replace `jose` with `jwt-decode` version 4.0.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@3.1.3
|
||||
|
||||
## 7.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [4c35171]
|
||||
- Updated dependencies [3cea460]
|
||||
- @nhost/nhost-js@3.1.2
|
||||
|
||||
## 7.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/apollo",
|
||||
"version": "7.0.1",
|
||||
"version": "7.1.2",
|
||||
"description": "Nhost Apollo Client library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -66,7 +66,7 @@
|
||||
"dependencies": {
|
||||
"graphql": "16.8.1",
|
||||
"graphql-ws": "^5.16.0",
|
||||
"jwt-decode": "^3.1.2"
|
||||
"jwt-decode": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@apollo/client": "^3.9.9",
|
||||
|
||||
@@ -12,7 +12,7 @@ import { setContext } from '@apollo/client/link/context'
|
||||
import { GraphQLWsLink } from '@apollo/client/link/subscriptions'
|
||||
import { getMainDefinition } from '@apollo/client/utilities'
|
||||
import { AuthContext, NhostClient } from '@nhost/nhost-js'
|
||||
import jwtDecode, { JwtPayload } from 'jwt-decode'
|
||||
import { jwtDecode, JwtPayload } from 'jwt-decode'
|
||||
|
||||
import { createRestartableClient } from './ws'
|
||||
const isBrowser = typeof window !== 'undefined'
|
||||
@@ -67,7 +67,7 @@ export const createApolloClient = ({
|
||||
const marginInSeconds = 3
|
||||
const marginInMilliseconds = marginInSeconds * 1000
|
||||
|
||||
let decodedToken: JwtPayload = jwtDecode(accessToken.value)
|
||||
let decodedToken = jwtDecode(accessToken.value) as JwtPayload
|
||||
return decodedToken.exp! * 1000 > Date.now() - marginInMilliseconds
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
# @nhost/react-apollo
|
||||
|
||||
## 12.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@7.1.2
|
||||
- @nhost/react@3.5.2
|
||||
|
||||
## 12.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@7.1.1
|
||||
- @nhost/react@3.5.1
|
||||
|
||||
## 12.0.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d0c9f4c]
|
||||
- @nhost/apollo@7.1.0
|
||||
- @nhost/react@3.5.0
|
||||
|
||||
## 11.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@7.0.2
|
||||
- @nhost/react@3.4.4
|
||||
|
||||
## 11.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/react-apollo",
|
||||
"version": "11.0.3",
|
||||
"version": "12.0.2",
|
||||
"description": "Nhost React Apollo client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
# @nhost/react-urql
|
||||
|
||||
## 9.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.2
|
||||
|
||||
## 9.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.1
|
||||
|
||||
## 9.0.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d0c9f4c]
|
||||
- @nhost/react@3.5.0
|
||||
|
||||
## 8.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.4.4
|
||||
|
||||
## 8.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/react-urql",
|
||||
"version": "8.0.3",
|
||||
"version": "9.0.2",
|
||||
"description": "Nhost React URQL client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @nhost/graphql-js
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- d0c9f4c: fix: replace `jose` with `jwt-decode` version 4.0.0
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/graphql-js",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"description": "Nhost GraphQL client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -54,14 +54,16 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"base-64": "^1.0.0",
|
||||
"isomorphic-unfetch": "^3.1.0",
|
||||
"jose": "^5.2.3"
|
||||
"jwt-decode": "^4.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nhost/docgen": "workspace:*",
|
||||
"@types/base-64": "^1.0.2",
|
||||
"graphql": "16.8.1"
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
Variables
|
||||
} from './types'
|
||||
|
||||
import * as jose from 'jose'
|
||||
import { jwtDecode, JwtPayload } from 'jwt-decode'
|
||||
|
||||
/**
|
||||
* @alias GraphQL
|
||||
@@ -37,7 +37,7 @@ export class NhostGraphqlClient {
|
||||
}
|
||||
|
||||
try {
|
||||
const decodedToken = jose.decodeJwt<jose.JWTPayload>(this.accessToken)
|
||||
const decodedToken = jwtDecode(this.accessToken) as JwtPayload
|
||||
return decodedToken.exp != null && decodedToken.exp * 1000 > Date.now()
|
||||
} catch (error) {
|
||||
console.error('Error decoding token:', error)
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# @nhost/hasura-auth-js
|
||||
|
||||
## 2.5.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a03fb2c: fix: deep clone machine context to prevent mutations in nested objects during initial session setup
|
||||
|
||||
## 2.5.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f4f0353: fix: improve environment/browser detection to support React Native
|
||||
- defffd8: fix: resolve issue where `/token` endpoint is called with an empty token during sign-in
|
||||
|
||||
## 2.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- d0c9f4c: fix: replace `jose` with `jwt-decode` version 4.0.0
|
||||
|
||||
## 2.4.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/hasura-auth-js",
|
||||
"version": "2.4.2",
|
||||
"version": "2.5.2",
|
||||
"description": "Hasura-auth client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -66,8 +66,8 @@
|
||||
"dependencies": {
|
||||
"@simplewebauthn/browser": "^9.0.1",
|
||||
"fetch-ponyfill": "^7.1.0",
|
||||
"jose": "^5.2.3",
|
||||
"js-cookie": "^3.0.5",
|
||||
"jwt-decode": "^4.0.0",
|
||||
"xstate": "^4.38.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as jose from 'jose'
|
||||
import { jwtDecode } from 'jwt-decode'
|
||||
import { interpret } from 'xstate'
|
||||
import {
|
||||
EMAIL_NEEDS_VERIFICATION,
|
||||
@@ -664,7 +664,7 @@ export class HasuraAuthClient {
|
||||
public getDecodedAccessToken(): JWTClaims | null {
|
||||
const jwt = this.getAccessToken()
|
||||
if (!jwt) return null
|
||||
return jose.decodeJwt<JWTClaims>(jwt)
|
||||
return jwtDecode<JWTClaims>(jwt)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { interpret } from 'xstate'
|
||||
import { AuthInterpreter, AuthMachine, AuthMachineOptions, createAuthMachine } from './machines'
|
||||
import {
|
||||
AuthContext,
|
||||
AuthInterpreter,
|
||||
AuthMachine,
|
||||
AuthMachineOptions,
|
||||
createAuthMachine
|
||||
} from './machines'
|
||||
import { NhostSession } from './types'
|
||||
import { isBrowser } from './utils'
|
||||
|
||||
@@ -60,8 +66,8 @@ export class AuthClient {
|
||||
|
||||
if (type === 'broadcast_token') {
|
||||
const existingToken = this.interpreter?.getSnapshot().context.refreshToken.value
|
||||
if (this.interpreter && payload.token.data !== existingToken) {
|
||||
this.interpreter.send('TRY_TOKEN', { token: payload.token.data })
|
||||
if (this.interpreter && payload.token && payload.token !== existingToken) {
|
||||
this.interpreter.send('TRY_TOKEN', { token: payload.token })
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -87,7 +93,17 @@ export class AuthClient {
|
||||
initialSession,
|
||||
interpreter
|
||||
}: { interpreter?: AuthInterpreter; initialSession?: NhostSession; devTools?: boolean } = {}) {
|
||||
const context = { ...this.machine.context }
|
||||
// Create a deep copy of the machine context to ensure that nested objects (such as accessToken and refreshToken) are not mutated in the original context.
|
||||
const context: AuthContext = {
|
||||
...this.machine.context,
|
||||
accessToken: {
|
||||
...this.machine.context.accessToken
|
||||
},
|
||||
refreshToken: {
|
||||
...this.machine.context.refreshToken
|
||||
}
|
||||
}
|
||||
|
||||
if (initialSession) {
|
||||
context.user = initialSession.user
|
||||
context.refreshToken.value = initialSession.refreshToken ?? null
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export const isBrowser = () => typeof window !== 'undefined'
|
||||
export const isBrowser = () =>
|
||||
typeof window !== 'undefined' && typeof window.location !== 'undefined'
|
||||
|
||||
@@ -1,5 +1,30 @@
|
||||
# @nhost/nextjs
|
||||
|
||||
## 2.1.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.2
|
||||
|
||||
## 2.1.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.5.1
|
||||
|
||||
## 2.1.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d0c9f4c]
|
||||
- @nhost/react@3.5.0
|
||||
|
||||
## 2.1.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@3.4.4
|
||||
|
||||
## 2.1.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/nextjs",
|
||||
"version": "2.1.12",
|
||||
"version": "2.1.16",
|
||||
"description": "Nhost NextJS library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,35 @@
|
||||
# @nhost/nhost-js
|
||||
|
||||
## 3.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [a03fb2c]
|
||||
- @nhost/hasura-auth-js@2.5.2
|
||||
|
||||
## 3.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [f4f0353]
|
||||
- Updated dependencies [defffd8]
|
||||
- @nhost/hasura-auth-js@2.5.1
|
||||
|
||||
## 3.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [d0c9f4c]
|
||||
- @nhost/hasura-auth-js@2.5.0
|
||||
- @nhost/graphql-js@0.3.0
|
||||
|
||||
## 3.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 4c35171: fix: update docstring to correctly reflect usage of nhost.unsetRole method
|
||||
- 3cea460: chore: update docs links for nhost-js setRole and unsetRole methods
|
||||
|
||||
## 3.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/nhost-js",
|
||||
"version": "3.1.1",
|
||||
"version": "3.1.5",
|
||||
"description": "Nhost JavaScript SDK",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user