Compare commits
185 Commits
@nhost/rea
...
@nhost/rea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c8c8948755 | ||
|
|
17e9e5899e | ||
|
|
bd22c48131 | ||
|
|
89a239ff3a | ||
|
|
0131886011 | ||
|
|
340c014fe8 | ||
|
|
bc9c8b9456 | ||
|
|
c22b2621ba | ||
|
|
726746c4d3 | ||
|
|
c431570783 | ||
|
|
445d8ef449 | ||
|
|
0f4ea18e42 | ||
|
|
dae7c5d517 | ||
|
|
f673adea00 | ||
|
|
1c6f1e3b33 | ||
|
|
d1365ea516 | ||
|
|
72dbba7881 | ||
|
|
a3f3991d5a | ||
|
|
c71fe2cf72 | ||
|
|
24c5ed3ea4 | ||
|
|
2d9145f918 | ||
|
|
9a0ab5b887 | ||
|
|
1ddf704c5b | ||
|
|
6f4ee845c6 | ||
|
|
0368663dea | ||
|
|
76ce7d7b6e | ||
|
|
538bfbcb3e | ||
|
|
07b35d1e5f | ||
|
|
2200a0ed07 | ||
|
|
df23d97126 | ||
|
|
104f149369 | ||
|
|
01228583a0 | ||
|
|
93309dd851 | ||
|
|
2cc18dcb51 | ||
|
|
3b48a62790 | ||
|
|
8897dec056 | ||
|
|
324dda8309 | ||
|
|
95f62bed07 | ||
|
|
0e4d8ff118 | ||
|
|
baec5bada7 | ||
|
|
4e56cfc628 | ||
|
|
54bc91923f | ||
|
|
77b12feb95 | ||
|
|
32d4670bbb | ||
|
|
1dc09942d2 | ||
|
|
3343a36358 | ||
|
|
b755e9086c | ||
|
|
48866d0ee1 | ||
|
|
5b3b76bd41 | ||
|
|
7f7e7ea7d4 | ||
|
|
aaaf2dc9c5 | ||
|
|
fa9c1ea28c | ||
|
|
87eda76e2b | ||
|
|
8a596f2a9e | ||
|
|
d6d2381598 | ||
|
|
284ef7e7f2 | ||
|
|
6d5c202da9 | ||
|
|
6f0ac5706c | ||
|
|
9342937440 | ||
|
|
e89cd4e262 | ||
|
|
a05438352b | ||
|
|
78437959bb | ||
|
|
e1a7433adb | ||
|
|
e23cf74975 | ||
|
|
a3d01c4fad | ||
|
|
4cdcef9ef5 | ||
|
|
df894ef7e2 | ||
|
|
f7dd6a9fc6 | ||
|
|
2949ff0f62 | ||
|
|
1527b0a455 | ||
|
|
375e53a3f0 | ||
|
|
96e3ca5a32 | ||
|
|
0e570df9c5 | ||
|
|
1f4c67283e | ||
|
|
fc1c4861a3 | ||
|
|
74feaf6add | ||
|
|
8cd97206cc | ||
|
|
02197639f2 | ||
|
|
38b594aef9 | ||
|
|
f3a8886cd0 | ||
|
|
8d76cf8d40 | ||
|
|
3e1fb974e4 | ||
|
|
f74871d872 | ||
|
|
3f26056688 | ||
|
|
6a7801be93 | ||
|
|
7bc5bb857c | ||
|
|
c957039d75 | ||
|
|
96c4032424 | ||
|
|
ec70126b56 | ||
|
|
86b9f9040c | ||
|
|
222f03725b | ||
|
|
10b786e5c6 | ||
|
|
aa8ae88d12 | ||
|
|
0f2c86b41a | ||
|
|
a4c76892dd | ||
|
|
00d278b2cc | ||
|
|
cb6b5faeb9 | ||
|
|
7c4c847b91 | ||
|
|
908887d8c5 | ||
|
|
a2d67bc2db | ||
|
|
1a6cd78254 | ||
|
|
6500629c4b | ||
|
|
add3c2c10e | ||
|
|
dd29b06260 | ||
|
|
490cb25a0f | ||
|
|
0df0dd741e | ||
|
|
2172946879 | ||
|
|
40e50f0e75 | ||
|
|
65cf0888b5 | ||
|
|
21833019ca | ||
|
|
b3171ba3e9 | ||
|
|
6f01f19d02 | ||
|
|
ce92b01eac | ||
|
|
e24a177434 | ||
|
|
56a52b6d48 | ||
|
|
92bfa8c723 | ||
|
|
2a52aaa4a6 | ||
|
|
8280a3e9d8 | ||
|
|
523f60bf68 | ||
|
|
19b11d4084 | ||
|
|
805bae1507 | ||
|
|
f6c014c06f | ||
|
|
c5794f4596 | ||
|
|
fc28817380 | ||
|
|
80bbd3a165 | ||
|
|
7a10617a72 | ||
|
|
f0b6dca1a5 | ||
|
|
5db20adc34 | ||
|
|
12dc41a517 | ||
|
|
768fd56891 | ||
|
|
8a508cb1cc | ||
|
|
34f6a8eef4 | ||
|
|
c9d2d31a9b | ||
|
|
68fb23a361 | ||
|
|
476139e528 | ||
|
|
6a850818a0 | ||
|
|
3970dbba0d | ||
|
|
8ee2166f0d | ||
|
|
e13500a185 | ||
|
|
411f574a51 | ||
|
|
7fc91b992e | ||
|
|
b840012be0 | ||
|
|
645c51a9dc | ||
|
|
0ce6f05539 | ||
|
|
8b1188af53 | ||
|
|
12b01f8dee | ||
|
|
60f4faf409 | ||
|
|
528dff3f1b | ||
|
|
d429fb4a3e | ||
|
|
816c916709 | ||
|
|
b7a2b8b537 | ||
|
|
261d8cf434 | ||
|
|
41f49bde76 | ||
|
|
65f685bdb2 | ||
|
|
f52a7f4aac | ||
|
|
e71b9903d9 | ||
|
|
325fd08aef | ||
|
|
3888704464 | ||
|
|
38e8a10a29 | ||
|
|
d8545eae12 | ||
|
|
3d5bfd87d2 | ||
|
|
e66c5626bd | ||
|
|
a227c6561e | ||
|
|
e885c159df | ||
|
|
09fcb74bef | ||
|
|
a089197197 | ||
|
|
34f843875b | ||
|
|
ca278a8c39 | ||
|
|
75603786e0 | ||
|
|
4e4e699b94 | ||
|
|
da31fa9fba | ||
|
|
95e2afaf47 | ||
|
|
958a56dde9 | ||
|
|
74cb15930e | ||
|
|
aa37a98424 | ||
|
|
11cbdda3a5 | ||
|
|
6d1f4adf10 | ||
|
|
ddbc50c15e | ||
|
|
b2cbf570a3 | ||
|
|
22b8e65031 | ||
|
|
63c94d2036 | ||
|
|
010df48c1e | ||
|
|
fdc11db93d | ||
|
|
cb4749f168 | ||
|
|
46a8fcf471 |
18
.github/CODEOWNERS
vendored
18
.github/CODEOWNERS
vendored
@@ -1,14 +1,14 @@
|
||||
# Documentation
|
||||
# https://help.github.com/en/articles/about-code-owners
|
||||
|
||||
/packages @plmercereau @szilarddoro
|
||||
/packages @szilarddoro
|
||||
/packages/docgen @szilarddoro
|
||||
/integrations/stripe-graphql-js @elitan
|
||||
/.github @plmercereau
|
||||
/dashboard/ @szilarddoro @guicurcio
|
||||
/docs/ @guicurcio @elitan
|
||||
/config/ @plmercereau @szilarddoro
|
||||
/examples/ @plmercereau
|
||||
/examples/codegen-react-apollo @elitan @plmercereau
|
||||
/examples/codegen-react-query @elitan @plmercereau
|
||||
/examples/react-apollo-crm @elitan @plmercereau
|
||||
/.github @szilarddoro
|
||||
/dashboard/ @szilarddoro
|
||||
/docs/ @elitan
|
||||
/config/ @szilarddoro
|
||||
/examples/ @szilarddoro
|
||||
/examples/codegen-react-apollo @elitan @szilarddoro
|
||||
/examples/codegen-react-query @elitan @szilarddoro
|
||||
/examples/react-apollo-crm @elitan @szilarddoro
|
||||
|
||||
@@ -40,14 +40,14 @@ runs:
|
||||
- shell: bash
|
||||
name: Build packages
|
||||
if: ${{ inputs.BUILD == 'all' }}
|
||||
run: pnpm build:all
|
||||
run: pnpm run build:all
|
||||
env:
|
||||
TURBO_TOKEN: ${{ inputs.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ inputs.TURBO_TEAM }}
|
||||
- shell: bash
|
||||
name: Build everything in the monorepo
|
||||
if: ${{ inputs.BUILD == 'default' }}
|
||||
run: pnpm build
|
||||
run: pnpm run build
|
||||
env:
|
||||
TURBO_TOKEN: ${{ inputs.TURBO_TOKEN }}
|
||||
TURBO_TEAM: ${{ inputs.TURBO_TEAM }}
|
||||
|
||||
3
.github/workflows/ci.yaml
vendored
3
.github/workflows/ci.yaml
vendored
@@ -8,7 +8,6 @@ on:
|
||||
- '**.md'
|
||||
- 'LICENSE'
|
||||
pull_request:
|
||||
branches: [main]
|
||||
types: [opened, synchronize]
|
||||
paths-ignore:
|
||||
- 'assets/**'
|
||||
@@ -56,7 +55,7 @@ jobs:
|
||||
| xargs -I@ realpath --relative-to=$PWD @ \
|
||||
| xargs -I@ jq "if (.scripts.e2e | length) != 0 then {name: .name, path: \"@\"} else null end" @/package.json \
|
||||
| awk "!/null/" \
|
||||
| jq -c --slurp)
|
||||
| jq -c --slurp 'map(select(length > 0))')
|
||||
echo "matrix=$PACKAGES" >> $GITHUB_OUTPUT
|
||||
outputs:
|
||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||
|
||||
@@ -45,6 +45,9 @@
|
||||
"@nhost/docgen": [
|
||||
"../packages/docgen/src/index.ts"
|
||||
],
|
||||
"@nhost/graphql-js": [
|
||||
"../packages/graphql-js/src/index.ts"
|
||||
],
|
||||
"@nhost/hasura-auth-js": [
|
||||
"../packages/hasura-auth-js/src/index.ts"
|
||||
],
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import replace from '@rollup/plugin-replace'
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import dts from 'vite-plugin-dts'
|
||||
import tsconfigPaths from 'vite-tsconfig-paths'
|
||||
@@ -61,7 +60,6 @@ export default defineConfig({
|
||||
'@apollo/client/utilities': '@apollo/client/utilities',
|
||||
'graphql-ws': 'graphql-ws',
|
||||
xstate: 'xstate',
|
||||
axios: 'axios',
|
||||
'js-cookie': 'Cookies',
|
||||
react: 'React',
|
||||
'react-dom': 'ReactDOM',
|
||||
|
||||
@@ -1,5 +1,65 @@
|
||||
# @nhost/dashboard
|
||||
|
||||
## 0.11.18
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/react-apollo@5.0.5
|
||||
- @nhost/nextjs@1.13.10
|
||||
|
||||
## 0.11.17
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- f673adea: fix(dashboard): set correct Content-Type for user creation
|
||||
- 445d8ef4: chore(deps): bump `@nhost/react-apollo` to 5.0.4
|
||||
- 445d8ef4: chore(deps): bump `@nhost/nextjs` to 1.13.9
|
||||
- 0368663d: fix(dashboard): allow permission editing for auth and storage schemas
|
||||
- Updated dependencies [445d8ef4]
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/react-apollo@5.0.4
|
||||
- @nhost/nextjs@1.13.9
|
||||
|
||||
## 0.11.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- b755e908: fix(dashboard): use correct date for last seen
|
||||
- 2d9145f9: chore(deps): revert GraphQL client
|
||||
- 1ddf704c: fix(dashboard): don't show false positive message for failed user creation
|
||||
- @nhost/react-apollo@5.0.3
|
||||
- @nhost/nextjs@1.13.8
|
||||
|
||||
## 0.11.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react-apollo@5.0.2
|
||||
- @nhost/nextjs@1.13.7
|
||||
|
||||
## 0.11.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2cc18dcb: fix(dashboard): prevent permission editor dropdown from being always open
|
||||
|
||||
## 0.11.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 3343a363: chore(dashboard): bump `@testing-library/react` to v14 and `@testing-library/dom` to v9
|
||||
- @nhost/react-apollo@5.0.1
|
||||
- @nhost/nextjs@1.13.6
|
||||
|
||||
## 0.11.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 87eda76e: chore(dashboard): bump `@types/react` to v18.0.28 and `@types/react-dom` to v18.0.11
|
||||
- 6f0ac570: feat(dashboard): show dashboard version in account menu
|
||||
|
||||
## 0.11.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -2,6 +2,7 @@ const path = require('path');
|
||||
const withBundleAnalyzer = require('@next/bundle-analyzer')({
|
||||
enabled: process.env.ANALYZE === 'true',
|
||||
});
|
||||
const { version } = require('./package.json');
|
||||
|
||||
module.exports = withBundleAnalyzer({
|
||||
reactStrictMode: true,
|
||||
@@ -10,6 +11,9 @@ module.exports = withBundleAnalyzer({
|
||||
experimental: {
|
||||
outputFileTracingRoot: path.join(__dirname, '../../'),
|
||||
},
|
||||
publicRuntimeConfig: {
|
||||
version,
|
||||
},
|
||||
eslint: {
|
||||
dirs: ['src'],
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/dashboard",
|
||||
"version": "0.11.11",
|
||||
"version": "0.11.18",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
@@ -44,7 +44,6 @@
|
||||
"@tanstack/react-table": "^8.5.30",
|
||||
"@tanstack/react-virtual": "^3.0.0-beta.23",
|
||||
"analytics-node": "^6.2.0",
|
||||
"axios": "^0.27.2",
|
||||
"bcryptjs": "^2.4.3",
|
||||
"clsx": "^1.2.1",
|
||||
"cross-fetch": "^3.1.5",
|
||||
@@ -98,15 +97,15 @@
|
||||
"@storybook/manager-webpack5": "^6.5.14",
|
||||
"@storybook/react": "^6.5.14",
|
||||
"@storybook/testing-library": "^0.0.13",
|
||||
"@testing-library/dom": "^8.19.0",
|
||||
"@testing-library/dom": "^9.0.0",
|
||||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.4.0",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@types/lodash.debounce": "^4.0.7",
|
||||
"@types/node": "^16.11.7",
|
||||
"@types/pluralize": "^0.0.29",
|
||||
"@types/react": "18.0.25",
|
||||
"@types/react-dom": "18.0.10",
|
||||
"@types/react": "18.0.28",
|
||||
"@types/react-dom": "18.0.11",
|
||||
"@types/react-table": "^7.7.12",
|
||||
"@types/testing-library__jest-dom": "^5.14.5",
|
||||
"@types/validator": "^13.7.10",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 210 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 176 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 168 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 140 KiB |
@@ -1,6 +0,0 @@
|
||||
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="200" height="200" fill="white" fill-opacity="0.15"/>
|
||||
<rect width="200" height="200" fill="#263245" fill-opacity="0.08"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M71 84C71 67.9837 83.9837 55 100 55C116.016 55 129 67.9837 129 84C129 100.016 116.016 113 100 113C83.9837 113 71 100.016 71 84ZM100 49C80.67 49 65 64.67 65 84C65 97.6014 72.7585 109.391 84.0914 115.184C79.3584 116.509 74.7892 118.425 70.496 120.903C61.5257 126.08 54.0757 133.527 48.8946 142.495C48.0657 143.929 48.5568 145.764 49.9914 146.593C51.4261 147.422 53.261 146.931 54.0898 145.496C58.7443 137.44 65.4368 130.75 73.4952 126.099C81.5536 121.448 90.694 119 99.9982 119C109.302 119 118.443 121.449 126.501 126.1C134.559 130.751 141.252 137.441 145.906 145.497C146.735 146.932 148.57 147.423 150.004 146.594C151.439 145.765 151.93 143.93 151.101 142.496C145.92 133.527 138.471 126.081 129.5 120.903C125.208 118.426 120.639 116.509 115.907 115.185C127.241 109.392 135 97.6021 135 84C135 64.67 119.33 49 100 49Z" fill="white" fill-opacity="0.15"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M71 84C71 67.9837 83.9837 55 100 55C116.016 55 129 67.9837 129 84C129 100.016 116.016 113 100 113C83.9837 113 71 100.016 71 84ZM100 49C80.67 49 65 64.67 65 84C65 97.6014 72.7585 109.391 84.0914 115.184C79.3584 116.509 74.7892 118.425 70.496 120.903C61.5257 126.08 54.0757 133.527 48.8946 142.495C48.0657 143.929 48.5568 145.764 49.9914 146.593C51.4261 147.422 53.261 146.931 54.0898 145.496C58.7443 137.44 65.4368 130.75 73.4952 126.099C81.5536 121.448 90.694 119 99.9982 119C109.302 119 118.443 121.449 126.501 126.1C134.559 130.751 141.252 137.441 145.906 145.497C146.735 146.932 148.57 147.423 150.004 146.594C151.439 145.765 151.93 143.93 151.101 142.496C145.92 133.527 138.471 126.081 129.5 120.903C125.208 118.426 120.639 116.509 115.907 115.185C127.241 109.392 135 97.6021 135 84C135 64.67 119.33 49 100 49Z" fill="#263245" fill-opacity="0.25"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.0 KiB |
@@ -52,7 +52,9 @@ function ControlledAutocomplete(
|
||||
|
||||
return (
|
||||
<Autocomplete
|
||||
inputValue={typeof field.value === 'string' ? field.value : undefined}
|
||||
inputValue={
|
||||
typeof field.value !== 'object' ? field.value.toString() : undefined
|
||||
}
|
||||
{...props}
|
||||
{...field}
|
||||
ref={mergeRefs([field.ref, ref])}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import Breadcrumbs from '@/components/common/Breadcrumbs';
|
||||
import FeedbackForm from '@/components/common/FeedbackForm';
|
||||
import LocalAccountMenu from '@/components/common/LocalAccountMenu';
|
||||
import Logo from '@/components/common/Logo';
|
||||
import MobileNav from '@/components/common/MobileNav';
|
||||
import NavLink from '@/components/common/NavLink';
|
||||
import ThemeSwitcher from '@/components/common/ThemeSwitcher';
|
||||
import { AccountMenu } from '@/components/dashboard/AccountMenu';
|
||||
import useIsPlatform from '@/hooks/common/useIsPlatform';
|
||||
import Box from '@/ui/v2/Box';
|
||||
@@ -73,7 +73,7 @@ export default function Header({ className, ...props }: HeaderProps) {
|
||||
Docs
|
||||
</NavLink>
|
||||
|
||||
{isPlatform ? <AccountMenu /> : <ThemeSwitcher className="w-52" />}
|
||||
{isPlatform ? <AccountMenu /> : <LocalAccountMenu />}
|
||||
</div>
|
||||
|
||||
<MobileNav className="sm:hidden" />
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import ThemeSwitcher from '@/components/common/ThemeSwitcher';
|
||||
import { Dropdown } from '@/ui/v2/Dropdown';
|
||||
import IconButton from '@/ui/v2/IconButton';
|
||||
import UserIcon from '@/ui/v2/icons/UserIcon';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import getConfig from 'next/config';
|
||||
|
||||
export default function LocalAccountMenu() {
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
return (
|
||||
<Dropdown.Root className="justify-self-center">
|
||||
<Dropdown.Trigger hideChevron asChild>
|
||||
<IconButton
|
||||
variant="borderless"
|
||||
color="secondary"
|
||||
className="h-7 w-7 rounded-full"
|
||||
sx={{
|
||||
backgroundColor: (theme) => `${theme.palette.grey[300]} !important`,
|
||||
}}
|
||||
>
|
||||
<UserIcon className="h-4 w-4" />
|
||||
</IconButton>
|
||||
</Dropdown.Trigger>
|
||||
|
||||
<Dropdown.Content
|
||||
PaperProps={{
|
||||
className: 'mt-1 p-6 grid grid-flow-row gap-4 w-full max-w-xs',
|
||||
}}
|
||||
>
|
||||
<ThemeSwitcher label="Theme" />
|
||||
|
||||
<Text className="text-center text-xs" color="disabled">
|
||||
Dashboard Version: {publicRuntimeConfig?.version || 'n/a'}
|
||||
</Text>
|
||||
</Dropdown.Content>
|
||||
</Dropdown.Root>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { default } from './LocalAccountMenu';
|
||||
@@ -20,6 +20,7 @@ import type { ListItemButtonProps } from '@/ui/v2/ListItem';
|
||||
import { ListItem } from '@/ui/v2/ListItem';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import { useSignOut } from '@nhost/nextjs';
|
||||
import getConfig from 'next/config';
|
||||
import { useRouter } from 'next/router';
|
||||
import type { ReactNode } from 'react';
|
||||
import { cloneElement, Fragment, isValidElement, useState } from 'react';
|
||||
@@ -89,6 +90,7 @@ export default function MobileNav({ className, ...props }: MobileNavProps) {
|
||||
const { signOut } = useSignOut();
|
||||
const { setUserContext } = useUserDataContext();
|
||||
const router = useRouter();
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -256,6 +258,10 @@ export default function MobileNav({ className, ...props }: MobileNavProps) {
|
||||
</ListItem.Button>
|
||||
</ListItem.Root>
|
||||
</List>
|
||||
|
||||
<Text className="text-center text-xs" color="secondary">
|
||||
Dashboard Version: {publicRuntimeConfig?.version || 'n/a'}
|
||||
</Text>
|
||||
</section>
|
||||
)}
|
||||
</Drawer>
|
||||
|
||||
@@ -21,6 +21,13 @@ export default function ThemeSwitcher({
|
||||
|
||||
onChange?.(event, value);
|
||||
}}
|
||||
slotProps={{
|
||||
listbox: { className: 'min-w-0 w-full' },
|
||||
popper: {
|
||||
disablePortal: false,
|
||||
className: 'z-[10000] w-[270px] w-full',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Option value="light">Light</Option>
|
||||
<Option value="dark">Dark</Option>
|
||||
|
||||
@@ -10,6 +10,7 @@ import Text from '@/ui/v2/Text';
|
||||
import { nhost } from '@/utils/nhost';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { useUserData } from '@nhost/nextjs';
|
||||
import getConfig from 'next/config';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useEffect, useState } from 'react';
|
||||
|
||||
@@ -24,23 +25,10 @@ function AccountMenuContent({
|
||||
const router = useRouter();
|
||||
const client = useApolloClient();
|
||||
const { handleClose } = useDropdown();
|
||||
const { publicRuntimeConfig } = getConfig();
|
||||
|
||||
return (
|
||||
<Box className="relative grid w-account grid-flow-row gap-5 p-6">
|
||||
<Button
|
||||
variant="borderless"
|
||||
color="secondary"
|
||||
className="absolute top-6 right-4 grid grid-flow-col items-center gap-px self-start font-medium"
|
||||
onClick={async () => {
|
||||
await nhost.auth.signOut();
|
||||
router.push('/signin');
|
||||
await client.resetStore();
|
||||
}}
|
||||
endIcon={<PowerIcon className="mr-1 h-4 w-4" />}
|
||||
>
|
||||
Sign Out
|
||||
</Button>
|
||||
|
||||
<Box className="relative grid w-full grid-flow-row gap-5 p-6">
|
||||
<div className="grid grid-flow-row justify-center">
|
||||
<Avatar
|
||||
className="mx-auto mb-2 h-16 w-16 rounded-full"
|
||||
@@ -72,9 +60,26 @@ function AccountMenuContent({
|
||||
<Button color="error" disabled>
|
||||
Remove Account
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
onClick={async () => {
|
||||
await nhost.auth.signOut();
|
||||
router.push('/signin');
|
||||
await client.resetStore();
|
||||
}}
|
||||
endIcon={<PowerIcon className="mr-1 h-4 w-4" />}
|
||||
>
|
||||
Sign Out
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<ThemeSwitcher label="Theme" fullWidth />
|
||||
<ThemeSwitcher label="Theme" />
|
||||
|
||||
<Text className="text-center text-xs" color="disabled">
|
||||
Dashboard Version: {publicRuntimeConfig?.version || 'n/a'}
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
@@ -107,7 +112,7 @@ export function AccountMenu() {
|
||||
/>
|
||||
</Dropdown.Trigger>
|
||||
|
||||
<Dropdown.Content PaperProps={{ className: 'mt-1' }}>
|
||||
<Dropdown.Content PaperProps={{ className: 'mt-1 max-w-xs w-full' }}>
|
||||
<AccountMenuContent
|
||||
onChangePasswordClick={() => setChangePasswordModal(true)}
|
||||
/>
|
||||
|
||||
@@ -328,53 +328,50 @@ function DataBrowserSidebarContent({
|
||||
className="group"
|
||||
key={tablePath}
|
||||
secondaryAction={
|
||||
!isSelectedSchemaLocked && (
|
||||
<Dropdown.Root
|
||||
id="table-management-menu"
|
||||
onOpen={() => setSidebarMenuTable(tablePath)}
|
||||
onClose={() => setSidebarMenuTable(undefined)}
|
||||
<Dropdown.Root
|
||||
id="table-management-menu"
|
||||
onOpen={() => setSidebarMenuTable(tablePath)}
|
||||
onClose={() => setSidebarMenuTable(undefined)}
|
||||
>
|
||||
<Dropdown.Trigger
|
||||
asChild
|
||||
hideChevron
|
||||
disabled={tablePath === removableTable}
|
||||
>
|
||||
<Dropdown.Trigger
|
||||
asChild
|
||||
hideChevron
|
||||
disabled={tablePath === removableTable}
|
||||
<IconButton
|
||||
variant="borderless"
|
||||
color={isSelected ? 'primary' : 'secondary'}
|
||||
className={twMerge(
|
||||
!isSelected &&
|
||||
'opacity-0 group-focus-within:opacity-100 group-hover:opacity-100 group-active:opacity-100',
|
||||
)}
|
||||
>
|
||||
<IconButton
|
||||
variant="borderless"
|
||||
color={isSelected ? 'primary' : 'secondary'}
|
||||
className={twMerge(
|
||||
!isSelected &&
|
||||
'opacity-0 group-focus-within:opacity-100 group-hover:opacity-100 group-active:opacity-100',
|
||||
)}
|
||||
<DotsHorizontalIcon />
|
||||
</IconButton>
|
||||
</Dropdown.Trigger>
|
||||
|
||||
<Dropdown.Content menu PaperProps={{ className: 'w-52' }}>
|
||||
{isGitHubConnected ? (
|
||||
<Dropdown.Item
|
||||
className="grid grid-flow-col items-center gap-2 p-2 text-sm+ font-medium"
|
||||
onClick={() =>
|
||||
handleEditPermissionClick(
|
||||
table.table_schema,
|
||||
table.table_name,
|
||||
true,
|
||||
)
|
||||
}
|
||||
>
|
||||
<DotsHorizontalIcon />
|
||||
</IconButton>
|
||||
</Dropdown.Trigger>
|
||||
<UsersIcon
|
||||
className="h-4 w-4"
|
||||
sx={{ color: 'text.secondary' }}
|
||||
/>
|
||||
|
||||
<Dropdown.Content
|
||||
menu
|
||||
PaperProps={{ className: 'w-52' }}
|
||||
>
|
||||
{isGitHubConnected ? (
|
||||
<Dropdown.Item
|
||||
className="grid grid-flow-col items-center gap-2 p-2 text-sm+ font-medium"
|
||||
onClick={() =>
|
||||
handleEditPermissionClick(
|
||||
table.table_schema,
|
||||
table.table_name,
|
||||
true,
|
||||
)
|
||||
}
|
||||
>
|
||||
<UsersIcon
|
||||
className="h-4 w-4"
|
||||
sx={{ color: 'text.secondary' }}
|
||||
/>
|
||||
|
||||
<span>View Permissions</span>
|
||||
</Dropdown.Item>
|
||||
) : (
|
||||
[
|
||||
<span>View Permissions</span>
|
||||
</Dropdown.Item>
|
||||
) : (
|
||||
[
|
||||
!isSelectedSchemaLocked && (
|
||||
<Dropdown.Item
|
||||
key="edit-table"
|
||||
className="grid grid-flow-col items-center gap-2 p-2 text-sm+ font-medium"
|
||||
@@ -400,32 +397,38 @@ function DataBrowserSidebarContent({
|
||||
/>
|
||||
|
||||
<span>Edit Table</span>
|
||||
</Dropdown.Item>,
|
||||
</Dropdown.Item>
|
||||
),
|
||||
!isSelectedSchemaLocked && (
|
||||
<Divider
|
||||
key="edit-table-separator"
|
||||
component="li"
|
||||
/>,
|
||||
<Dropdown.Item
|
||||
key="edit-permissions"
|
||||
className="grid grid-flow-col items-center gap-2 p-2 text-sm+ font-medium"
|
||||
onClick={() =>
|
||||
handleEditPermissionClick(
|
||||
table.table_schema,
|
||||
table.table_name,
|
||||
)
|
||||
}
|
||||
>
|
||||
<UsersIcon
|
||||
className="h-4 w-4"
|
||||
sx={{ color: 'text.secondary' }}
|
||||
/>
|
||||
/>
|
||||
),
|
||||
<Dropdown.Item
|
||||
key="edit-permissions"
|
||||
className="grid grid-flow-col items-center gap-2 p-2 text-sm+ font-medium"
|
||||
onClick={() =>
|
||||
handleEditPermissionClick(
|
||||
table.table_schema,
|
||||
table.table_name,
|
||||
)
|
||||
}
|
||||
>
|
||||
<UsersIcon
|
||||
className="h-4 w-4"
|
||||
sx={{ color: 'text.secondary' }}
|
||||
/>
|
||||
|
||||
<span>Edit Permissions</span>
|
||||
</Dropdown.Item>,
|
||||
<span>Edit Permissions</span>
|
||||
</Dropdown.Item>,
|
||||
!isSelectedSchemaLocked && (
|
||||
<Divider
|
||||
key="edit-permissions-separator"
|
||||
component="li"
|
||||
/>,
|
||||
/>
|
||||
),
|
||||
!isSelectedSchemaLocked && (
|
||||
<Dropdown.Item
|
||||
key="delete-table"
|
||||
className="grid grid-flow-col items-center gap-2 p-2 text-sm+ font-medium"
|
||||
@@ -443,12 +446,12 @@ function DataBrowserSidebarContent({
|
||||
/>
|
||||
|
||||
<span>Delete Table</span>
|
||||
</Dropdown.Item>,
|
||||
]
|
||||
)}
|
||||
</Dropdown.Content>
|
||||
</Dropdown.Root>
|
||||
)
|
||||
</Dropdown.Item>
|
||||
),
|
||||
]
|
||||
)}
|
||||
</Dropdown.Content>
|
||||
</Dropdown.Root>
|
||||
}
|
||||
>
|
||||
<ListItem.Button
|
||||
|
||||
@@ -245,7 +245,7 @@ export default function RolePermissionEditorForm({
|
||||
: permission?.check,
|
||||
backend_only: values.backendOnly,
|
||||
computed_fields:
|
||||
permission?.computed_fields.length > 0
|
||||
permission?.computed_fields?.length > 0
|
||||
? permission?.computed_fields
|
||||
: null,
|
||||
},
|
||||
|
||||
@@ -6,6 +6,7 @@ import Input from '@/ui/v2/Input';
|
||||
import Radio from '@/ui/v2/Radio';
|
||||
import RadioGroup from '@/ui/v2/RadioGroup';
|
||||
import Text from '@/ui/v2/Text';
|
||||
import type { FocusEvent } from 'react';
|
||||
import { useState } from 'react';
|
||||
import { useFormContext } from 'react-hook-form';
|
||||
import PermissionSettingsSection from './PermissionSettingsSection';
|
||||
@@ -130,7 +131,13 @@ export default function RowPermissionsSection({
|
||||
|
||||
{action === 'select' && (
|
||||
<Input
|
||||
{...register('limit')}
|
||||
{...register('limit', {
|
||||
onBlur: (event: FocusEvent<HTMLInputElement>) => {
|
||||
if (!event.target.value) {
|
||||
setValue('limit', null);
|
||||
}
|
||||
},
|
||||
})}
|
||||
disabled={disabled}
|
||||
id="limit"
|
||||
type="number"
|
||||
|
||||
@@ -43,7 +43,10 @@ const baseValidationSchema = Yup.object().shape({
|
||||
});
|
||||
|
||||
const selectValidationSchema = baseValidationSchema.shape({
|
||||
limit: Yup.number().min(0, 'Limit must not be negative.').nullable(true),
|
||||
limit: Yup.number()
|
||||
.label('Limit')
|
||||
.min(0, 'Limit must not be negative.')
|
||||
.nullable(true),
|
||||
allowAggregations: Yup.boolean().nullable(true),
|
||||
queryRootFields: Yup.array().of(Yup.string()).nullable(true),
|
||||
subscriptionRootFields: Yup.array().of(Yup.string()).nullable(true),
|
||||
|
||||
@@ -6,6 +6,7 @@ import ColumnAutocomplete from '@/components/dataBrowser/ColumnAutocomplete';
|
||||
import { useCurrentWorkspaceAndApplication } from '@/hooks/useCurrentWorkspaceAndApplication';
|
||||
import type { HasuraOperator } from '@/types/dataBrowser';
|
||||
import ActivityIndicator from '@/ui/v2/ActivityIndicator';
|
||||
import type { AutocompleteOption } from '@/ui/v2/Autocomplete';
|
||||
import type { InputProps } from '@/ui/v2/Input';
|
||||
import { inputClasses } from '@/ui/v2/Input';
|
||||
import Option from '@/ui/v2/Option';
|
||||
@@ -211,12 +212,13 @@ export default function RuleValueInput({
|
||||
<ControlledAutocomplete
|
||||
disabled={disabled}
|
||||
freeSolo={!isHasuraInput}
|
||||
autoSelect={!isHasuraInput}
|
||||
autoHighlight={isHasuraInput}
|
||||
open
|
||||
isOptionEqualToValue={(option, value) => {
|
||||
if (typeof value === 'string') {
|
||||
return option.value.toLowerCase() === (value as string).toLowerCase();
|
||||
isOptionEqualToValue={(
|
||||
option,
|
||||
value: string | number | AutocompleteOption<string>,
|
||||
) => {
|
||||
if (typeof value !== 'object') {
|
||||
return option.value.toLowerCase() === value?.toString().toLowerCase();
|
||||
}
|
||||
|
||||
return option.value.toLowerCase() === value.value.toLowerCase();
|
||||
|
||||
@@ -277,7 +277,7 @@ export default function FilesDataGrid(props: FilesDataGridProps) {
|
||||
}
|
||||
|
||||
if (fileError) {
|
||||
throw fileError;
|
||||
throw new Error(fileError.message);
|
||||
}
|
||||
|
||||
triggerToast(`File has been uploaded successfully (${fileMetadata?.id})`);
|
||||
|
||||
@@ -58,16 +58,19 @@ export function InviteAnnounce() {
|
||||
error: null,
|
||||
loading: true,
|
||||
});
|
||||
const res = await nhost.functions.call('/accept-workspace-invite', {
|
||||
workspaceMemberInviteId: invite.id,
|
||||
isAccepted: true,
|
||||
});
|
||||
const { res, error: acceptError } = await nhost.functions.call(
|
||||
'/accept-workspace-invite',
|
||||
{
|
||||
workspaceMemberInviteId: invite.id,
|
||||
isAccepted: true,
|
||||
},
|
||||
);
|
||||
|
||||
if (res?.res?.status !== 200) {
|
||||
if (res?.status !== 200) {
|
||||
triggerToast('An error occurred when trying to accept the invitation.');
|
||||
|
||||
return setSubmitState({
|
||||
error: res.error,
|
||||
error: new Error(acceptError.message),
|
||||
loading: false,
|
||||
});
|
||||
}
|
||||
@@ -90,7 +93,7 @@ export function InviteAnnounce() {
|
||||
error: null,
|
||||
});
|
||||
|
||||
const res = await nhost.functions.call(
|
||||
const { error: ignoreError } = await nhost.functions.call(
|
||||
'/accept-workspace-invite',
|
||||
{
|
||||
workspaceMemberInviteId: inviteId,
|
||||
@@ -99,12 +102,12 @@ export function InviteAnnounce() {
|
||||
{ useAxios: false },
|
||||
);
|
||||
|
||||
if (res?.error) {
|
||||
if (ignoreError) {
|
||||
triggerToast('An error occurred when trying to ignore the invitation.');
|
||||
|
||||
setIgnoreState({
|
||||
loading: false,
|
||||
error: new Error(res.error.message),
|
||||
error: new Error(ignoreError.message),
|
||||
});
|
||||
|
||||
return;
|
||||
|
||||
@@ -107,7 +107,7 @@ export default function SystemEnvironmentVariableSettings() {
|
||||
),
|
||||
},
|
||||
{ key: 'NHOST_AUTH_URL', value: appClient.auth.url },
|
||||
{ key: 'NHOST_GRAPHQL_URL', value: appClient.graphql.url },
|
||||
{ key: 'NHOST_GRAPHQL_URL', value: appClient.graphql.httpUrl },
|
||||
{ key: 'NHOST_STORAGE_URL', value: appClient.storage.url },
|
||||
{ key: 'NHOST_FUNCTIONS_URL', value: appClient.functions.url },
|
||||
];
|
||||
|
||||
@@ -222,9 +222,9 @@ function Autocomplete(
|
||||
inputValue: inputValue || '',
|
||||
getOptionLabel: props.getOptionLabel
|
||||
? props.getOptionLabel
|
||||
: (option) => {
|
||||
if (typeof option === 'string') {
|
||||
return option;
|
||||
: (option: string | number | AutocompleteOption<string>) => {
|
||||
if (typeof option !== 'object') {
|
||||
return option.toString();
|
||||
}
|
||||
|
||||
return option.label ?? option.dropdownLabel;
|
||||
@@ -284,33 +284,46 @@ function Autocomplete(
|
||||
}}
|
||||
PopperComponent={AutocompletePopper}
|
||||
popupIcon={<ChevronDownIcon sx={{ width: 12, height: 12 }} />}
|
||||
getOptionLabel={(option) => {
|
||||
if (typeof option === 'string') {
|
||||
return option;
|
||||
getOptionLabel={(
|
||||
option: string | number | AutocompleteOption<string>,
|
||||
) => {
|
||||
if (!option) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (typeof option !== 'object') {
|
||||
return option.toString();
|
||||
}
|
||||
|
||||
return option.label ?? option.dropdownLabel;
|
||||
}}
|
||||
isOptionEqualToValue={(option, value) => {
|
||||
isOptionEqualToValue={(
|
||||
option,
|
||||
value: string | number | AutocompleteOption<string>,
|
||||
) => {
|
||||
if (!value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
return option.value === value;
|
||||
if (typeof value !== 'object') {
|
||||
return option.value.toString() === value.toString();
|
||||
}
|
||||
|
||||
return option.value === value.value && option.custom === value.custom;
|
||||
}}
|
||||
renderTags={(value, getTagProps) =>
|
||||
value.map((option, index) => (
|
||||
<StyledTag
|
||||
deleteIcon={<XIcon />}
|
||||
size="small"
|
||||
label={typeof option === 'string' ? option : option.value}
|
||||
{...getTagProps({ index })}
|
||||
/>
|
||||
))
|
||||
value.map(
|
||||
(option: string | number | AutocompleteOption<string>, index) => (
|
||||
<StyledTag
|
||||
deleteIcon={<XIcon />}
|
||||
size="small"
|
||||
label={
|
||||
typeof option !== 'object' ? option.toString() : option.value
|
||||
}
|
||||
{...getTagProps({ index })}
|
||||
/>
|
||||
),
|
||||
)
|
||||
}
|
||||
renderGroup={({ group, key, children }) =>
|
||||
group ? (
|
||||
@@ -323,9 +336,12 @@ function Autocomplete(
|
||||
<div key={key}>{children}</div>
|
||||
)
|
||||
}
|
||||
renderOption={(optionProps, option) => {
|
||||
if (typeof option === 'string') {
|
||||
return <OptionBase {...optionProps}>{option}</OptionBase>;
|
||||
renderOption={(
|
||||
optionProps,
|
||||
option: string | number | AutocompleteOption<string>,
|
||||
) => {
|
||||
if (typeof option !== 'object') {
|
||||
return <OptionBase {...optionProps}>{option.toString()}</OptionBase>;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -40,7 +40,7 @@ const StyledMenu = styled(MaterialMenu)(({ theme }) => ({
|
||||
borderColor:
|
||||
theme.palette.mode === 'dark'
|
||||
? `${theme.palette.grey[400]} !important`
|
||||
: 'none',
|
||||
: 'transparent',
|
||||
boxShadow:
|
||||
theme.palette.mode === 'light'
|
||||
? '0px 4px 10px rgba(33, 50, 75, 0.25)'
|
||||
|
||||
@@ -12,6 +12,7 @@ export interface OptionProps<TValue extends {}>
|
||||
|
||||
const StyledOption = styled(OptionUnstyled)(({ theme }) => ({
|
||||
transition: theme.transitions.create(['background-color']),
|
||||
color: theme.palette.text.primary,
|
||||
[`&.${optionUnstyledClasses.selected}`]: {
|
||||
backgroundColor:
|
||||
theme.palette.mode === 'dark'
|
||||
|
||||
@@ -53,7 +53,7 @@ const StyledListbox = styled('ul')(({ theme }) => ({
|
||||
? `1px solid ${theme.palette.grey[300]}`
|
||||
: 'none',
|
||||
borderWidth: theme.palette.mode === 'dark' ? 1 : 0,
|
||||
borderColor: theme.palette.mode === 'dark' ? 'grey.400' : 'none',
|
||||
borderColor: theme.palette.mode === 'dark' ? theme.palette.grey[400] : 'none',
|
||||
'&:focus': {
|
||||
outline: 'none',
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ import Input from '@/ui/v2/Input';
|
||||
import generateAppServiceUrl from '@/utils/common/generateAppServiceUrl';
|
||||
import { getToastStyleProps } from '@/utils/settings/settingsConstants';
|
||||
import { yupResolver } from '@hookform/resolvers/yup';
|
||||
import axios from 'axios';
|
||||
import fetch from 'cross-fetch';
|
||||
import { useState } from 'react';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { toast } from 'react-hot-toast';
|
||||
@@ -79,28 +79,37 @@ export default function CreateUserForm({
|
||||
|
||||
try {
|
||||
await toast.promise(
|
||||
axios.post(signUpUrl, {
|
||||
email,
|
||||
password,
|
||||
fetch(signUpUrl, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password }),
|
||||
}).then(async (res) => {
|
||||
const data = await res.json();
|
||||
|
||||
if (res.ok) {
|
||||
return data;
|
||||
}
|
||||
|
||||
if (res.status === 409) {
|
||||
setError('email', { message: data?.message });
|
||||
}
|
||||
|
||||
throw new Error(data?.message || 'Something went wrong.');
|
||||
}),
|
||||
{
|
||||
loading: 'Creating user...',
|
||||
success: 'User created successfully.',
|
||||
error: 'An error occurred while trying to create the user.',
|
||||
error: (arg) =>
|
||||
arg?.message
|
||||
? `Error: ${arg.message}`
|
||||
: 'An error occurred while trying to create the user.',
|
||||
},
|
||||
getToastStyleProps(),
|
||||
);
|
||||
|
||||
onSuccess?.();
|
||||
} catch (error) {
|
||||
if (error.response?.status === 409) {
|
||||
setError('email', {
|
||||
message: error.response.data.message,
|
||||
});
|
||||
return;
|
||||
}
|
||||
setCreateUserFormError(
|
||||
new Error(error.response.data.message || 'Something went wrong.'),
|
||||
);
|
||||
} catch {
|
||||
// Note: Error is already handled by toast.promise
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +146,7 @@ export default function CreateUserForm({
|
||||
{createUserFormError && (
|
||||
<Alert
|
||||
severity="error"
|
||||
className="grid items-center justify-between grid-flow-col px-4 py-3"
|
||||
className="grid grid-flow-col items-center justify-between px-4 py-3"
|
||||
>
|
||||
<span className="text-left">
|
||||
<strong>Error:</strong> {createUserFormError.message}
|
||||
|
||||
@@ -268,7 +268,7 @@ export default function EditUserForm({
|
||||
Created At
|
||||
</InputLabel>
|
||||
<Text className="col-span-3 font-medium">
|
||||
{format(new Date(user.createdAt), 'yyyy-MM-dd hh:mm:ss')}
|
||||
{format(new Date(user.createdAt), 'yyyy-MM-dd HH:mm:ss')}
|
||||
</Text>
|
||||
|
||||
<InputLabel as="h3" className="col-span-1 self-center ">
|
||||
@@ -276,7 +276,7 @@ export default function EditUserForm({
|
||||
</InputLabel>
|
||||
<Text className="col-span-3 font-medium">
|
||||
{user.lastSeen
|
||||
? `${format(new Date(user.lastSeen), 'yyyy-mm-dd hh:mm:ss')}`
|
||||
? `${format(new Date(user.lastSeen), 'yyyy-MM-dd HH:mm:ss')}`
|
||||
: '-'}
|
||||
</Text>
|
||||
</Box>
|
||||
|
||||
@@ -28,7 +28,7 @@ The GraphQL API is available at `https://[subdomain].graphql.[region].nhost.run/
|
||||
|
||||
## GraphQL Clients for JavaScript
|
||||
|
||||
The [Nhost JavaScript client](/reference/javascript) comes with a simple [GraphQL client](/reference/javascript/nhost-js/graphql) that works well for the backend or simple applications.
|
||||
The [Nhost JavaScript client](/reference/javascript) comes with a simple [GraphQL client](/reference/javascript/graphql) that works well for the backend or simple applications.
|
||||
|
||||
When building more complex frontend applications, we recommend using a more advanced GraphQL client such as:
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ In this section:
|
||||
- [Overview](/reference/javascript)
|
||||
- [Authentication](/reference/javascript/auth)
|
||||
- [Storage](/reference/javascript/storage)
|
||||
- [Functions](/reference/javascript/nhost-js/functions)
|
||||
- [GraphQL](/reference/javascript/nhost-js/graphql)
|
||||
- [Functions](/reference/javascript/functions)
|
||||
- [GraphQL](/reference/javascript/graphql)
|
||||
|
||||
### React
|
||||
|
||||
|
||||
60
docs/docs/reference/javascript/functions/content/01-call.mdx
Normal file
60
docs/docs/reference/javascript/functions/content/01-call.mdx
Normal file
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: call()
|
||||
sidebar_label: call()
|
||||
slug: /reference/javascript/functions/call
|
||||
description: Use `nhost.functions.call` to call (sending a POST request to) a serverless function.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/nhost-js/src/clients/functions/index.ts#L55
|
||||
---
|
||||
|
||||
# `call()`
|
||||
|
||||
## Overload 1 of 2
|
||||
|
||||
Use `nhost.functions.call` to call (sending a POST request to) a serverless function.
|
||||
|
||||
:::caution Deprecated
|
||||
Axios will be replaced by cross-fetch in the near future. Only the headers configuration will be kept.
|
||||
:::
|
||||
|
||||
### Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">url</span>** <span className="optional-status">required</span> <code>string</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">data</span>** <span className="optional-status">optional</span> <code>D</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">config</span>** <span className="optional-status">optional</span> <code>AxiosRequestConfig<any> & { useAxios: "true" } & [`NhostFunctionCallConfig`](/reference/javascript/functions/types/nhost-function-call-config) & { useAxios: "true" }</code>
|
||||
|
||||
---
|
||||
|
||||
## Overload 2 of 2
|
||||
|
||||
Use `nhost.functions.call` to call (sending a POST request to) a serverless function.
|
||||
|
||||
```ts
|
||||
await nhost.functions.call('send-welcome-email', {
|
||||
email: 'joe@example.com',
|
||||
name: 'Joe Doe'
|
||||
})
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">url</span>** <span className="optional-status">required</span> <code>string</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">data</span>** <span className="optional-status">required</span> <code>D</code>
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">config</span>** <span className="optional-status">optional</span> <code>[`NhostFunctionCallConfig`](/reference/javascript/functions/types/nhost-function-call-config) & { useAxios: "false" }</code>
|
||||
|
||||
---
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
title: setAccessToken()
|
||||
sidebar_label: setAccessToken()
|
||||
slug: /reference/javascript/functions/set-access-token
|
||||
description: Use `nhost.functions.setAccessToken` to a set an access token to be used in subsequent functions requests. Note that if you're signin in users with `nhost.auth.signIn()` the access token will be set automatically.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/nhost-js/src/clients/functions/index.ts#L155
|
||||
---
|
||||
|
||||
# `setAccessToken()`
|
||||
|
||||
Use `nhost.functions.setAccessToken` to a set an access token to be used in subsequent functions requests. Note that if you're signin in users with `nhost.auth.signIn()` the access token will be set automatically.
|
||||
|
||||
```ts
|
||||
nhost.functions.setAccessToken('some-access-token')
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">accessToken</span>** <span className="optional-status">required</span> <code>undefined | string</code>
|
||||
|
||||
---
|
||||
22
docs/docs/reference/javascript/functions/index.mdx
Normal file
22
docs/docs/reference/javascript/functions/index.mdx
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: NhostFunctionsClient
|
||||
sidebar_label: Functions
|
||||
description: No description provided.
|
||||
slug: /reference/javascript/functions
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/docs/docs/reference/javascript/functions/index.mdx
|
||||
---
|
||||
|
||||
# `NhostFunctionsClient`
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`NhostFunctionsConstructorParams`](/reference/javascript/functions/types/nhost-functions-constructor-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :--------------------------------------------------------------------------------------------- | :------------------ | :------: | :---------------------------------------------------------------------------------------- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>url</span> | <code>string</code> | ✔️ | Serverless Functions endpoint. |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>adminSecret</span> | <code>string</code> | | Admin secret. When set, it is sent as an `x-hasura-admin-secret` header for all requests. |
|
||||
|
||||
---
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: NhostFunctionCallConfig
|
||||
sidebar_label: NhostFunctionCallConfig
|
||||
description: Subset of RequestInit parameters that are supported by the functions client
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/nhost-js/src/clients/functions/types.ts#L41
|
||||
---
|
||||
|
||||
# `NhostFunctionCallConfig`
|
||||
|
||||
Subset of RequestInit parameters that are supported by the functions client
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">headers</span>** <span className="optional-status">optional</span> <code>Record<string, string></code>
|
||||
|
||||
---
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
title: NhostFunctionCallResponse
|
||||
sidebar_label: NhostFunctionCallResponse
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/nhost-js/src/clients/functions/types.ts#L15
|
||||
---
|
||||
|
||||
# `NhostFunctionCallResponse`
|
||||
|
||||
```ts
|
||||
type NhostFunctionCallResponse =
|
||||
| { res: { data: T; status: number; statusText: string }; error: null }
|
||||
| { res: null; error: ErrorPayload }
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
---
|
||||
title: NhostFunctionsConstructorParams
|
||||
sidebar_label: NhostFunctionsConstructorParams
|
||||
description: No description provided.
|
||||
displayed_sidebar: referenceSidebar
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/nhost-js/src/clients/functions/types.ts#L4
|
||||
---
|
||||
|
||||
# `NhostFunctionsConstructorParams`
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">url</span>** <span className="optional-status">required</span> <code>string</code>
|
||||
|
||||
Serverless Functions endpoint.
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">adminSecret</span>** <span className="optional-status">optional</span> <code>string</code>
|
||||
|
||||
Admin secret. When set, it is sent as an `x-hasura-admin-secret` header for all requests.
|
||||
|
||||
---
|
||||
@@ -10,12 +10,12 @@ The Nhost JavaScript client is the primary way of interacting with your Nhost pr
|
||||
|
||||
- [Authentication](/reference/javascript/auth)
|
||||
- [Storage](/reference/javascript/storage)
|
||||
- [Functions](/reference/javascript/nhost-js/functions)
|
||||
- [GraphQL](/reference/javascript/nhost-js/graphql)
|
||||
- [Functions](/reference/javascript/functions)
|
||||
- [GraphQL](/reference/javascript/graphql)
|
||||
|
||||
## Installation
|
||||
|
||||
Install the the Nhost client together with GraphQL:
|
||||
Install the Nhost client together with GraphQL:
|
||||
|
||||
<Tabs groupId="package-manager">
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
@@ -111,12 +111,12 @@ const sidebars = {
|
||||
label: 'Functions',
|
||||
link: {
|
||||
type: 'doc',
|
||||
id: 'reference/docgen/javascript/nhost-js/content/nhost-functions-client/index'
|
||||
id: 'reference/javascript/functions/index'
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'reference/docgen/javascript/nhost-js/content/nhost-functions-client/content'
|
||||
dirName: 'reference/javascript/functions/content'
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -125,12 +125,12 @@ const sidebars = {
|
||||
label: 'GraphQL',
|
||||
link: {
|
||||
type: 'doc',
|
||||
id: 'reference/docgen/javascript/nhost-js/content/nhost-graphql-client/index'
|
||||
id: 'reference/docgen/javascript/graphql/content/nhost-graphql-client/index'
|
||||
},
|
||||
items: [
|
||||
{
|
||||
type: 'autogenerated',
|
||||
dirName: 'reference/docgen/javascript/nhost-js/content/nhost-graphql-client/content'
|
||||
dirName: 'reference/docgen/javascript/graphql/content/nhost-graphql-client/content'
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
# @nhost-examples/codegen-react-apollo
|
||||
|
||||
## 0.1.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/react-apollo@5.0.5
|
||||
- @nhost/react@2.0.4
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 445d8ef4: chore(deps): bump `@nhost/react` to 2.0.3
|
||||
- 445d8ef4: chore(deps): bump `@nhost/react-apollo` to 5.0.4
|
||||
- Updated dependencies [445d8ef4]
|
||||
- Updated dependencies [445d8ef4]
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/react-apollo@5.0.4
|
||||
- @nhost/react@2.0.3
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/codegen-react-apollo",
|
||||
"version": "0.1.5",
|
||||
"version": "0.1.7",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"codegen": "graphql-codegen",
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @nhost-examples/codegen-react-query
|
||||
|
||||
## 0.1.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/react@2.0.4
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 445d8ef4: chore(deps): bump `@nhost/react` to 2.0.3
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/react@2.0.3
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/codegen-react-query",
|
||||
"version": "0.1.5",
|
||||
"version": "0.1.7",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"codegen": "graphql-codegen",
|
||||
|
||||
@@ -1,5 +1,24 @@
|
||||
# @nhost-examples/react-urql
|
||||
|
||||
## 0.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/react-urql@2.0.4
|
||||
- @nhost/react@2.0.4
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 445d8ef4: chore(deps): bump `@nhost/react` to 2.0.3
|
||||
- Updated dependencies [445d8ef4]
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/react-urql@2.0.3
|
||||
- @nhost/react@2.0.3
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/codegen-react-urql",
|
||||
"private": true,
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.4",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @nhost-examples/docker-compose
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
|
||||
## 0.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/docker-compose",
|
||||
"version": "0.0.4",
|
||||
"version": "0.0.5",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"e2e": "vitest run"
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @nhost-examples/multi-tenant-one-to-many
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/nhost-js@2.0.4
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 445d8ef4: chore(deps): bump `@nhost/nhost-js` version to 2.0.3
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/nhost-js@2.0.3
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/multi-tenant-one-to-many",
|
||||
"private": true,
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.3",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {},
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# @nhost-examples/nextjs
|
||||
|
||||
## 0.1.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/react-apollo@5.0.5
|
||||
- @nhost/nextjs@1.13.10
|
||||
- @nhost/react@2.0.4
|
||||
|
||||
## 0.1.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 445d8ef4: chore(deps): bump `@nhost/react` to 2.0.3
|
||||
- 445d8ef4: chore(deps): bump `@nhost/react-apollo` to 5.0.4
|
||||
- 445d8ef4: chore(deps): bump `@nhost/nextjs` to 1.13.9
|
||||
- Updated dependencies [445d8ef4]
|
||||
- Updated dependencies [445d8ef4]
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/react-apollo@5.0.4
|
||||
- @nhost/nextjs@1.13.9
|
||||
- @nhost/react@2.0.3
|
||||
|
||||
## 0.1.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -18,6 +18,7 @@ export function authProtected(Comp) {
|
||||
if (isLoading) {
|
||||
return <div>Loading...</div>
|
||||
}
|
||||
|
||||
return <Comp {...props} />
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/nextjs",
|
||||
"version": "0.1.5",
|
||||
"version": "0.1.7",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
@@ -35,8 +35,8 @@
|
||||
"@types/react": "18.0.25",
|
||||
"@xstate/inspect": "^0.6.2",
|
||||
"eslint-config-next": "12.0.10",
|
||||
"typescript": "4.5.5",
|
||||
"typescript": "^4.8.2",
|
||||
"ws": "^8.8.1",
|
||||
"xstate": "^4.33.5"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,26 @@
|
||||
# @nhost-examples/react-apollo
|
||||
|
||||
## 0.1.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/react-apollo@5.0.5
|
||||
- @nhost/react@2.0.4
|
||||
|
||||
## 0.1.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 445d8ef4: chore(deps): bump `@nhost/react` to 2.0.3
|
||||
- 445d8ef4: chore(deps): bump `@nhost/react-apollo` to 5.0.4
|
||||
- Updated dependencies [445d8ef4]
|
||||
- Updated dependencies [445d8ef4]
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/react-apollo@5.0.4
|
||||
- @nhost/react@2.0.3
|
||||
|
||||
## 0.1.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/react-apollo",
|
||||
"version": "0.1.7",
|
||||
"version": "0.1.9",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@apollo/client": "^3.6.9",
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# @nhost-examples/react-gqty
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/react@2.0.4
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 445d8ef4: chore(deps): bump `@nhost/react` to 2.0.3
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/react@2.0.3
|
||||
|
||||
## 0.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/react-gqty",
|
||||
"private": true,
|
||||
"version": "0.0.4",
|
||||
"version": "0.0.6",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
||||
7
examples/seed-data-storage/CHANGELOG.md
Normal file
7
examples/seed-data-storage/CHANGELOG.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# @nhost-examples/seed-data-storage
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/seed-data-storage",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"scripts": {
|
||||
"seed-storage": "./seed-storage.sh"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @nhost-examples/serverless-functions
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/stripe-graphql-js@1.0.2
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"name": "@nhost-examples/serverless-functions",
|
||||
"private": true,
|
||||
"version": "0.0.6",
|
||||
"version": "0.0.7",
|
||||
"devDependencies": {
|
||||
"@types/express": "^4.17.13"
|
||||
},
|
||||
"dependencies": {
|
||||
"@graphql-yoga/node": "^2.13.13",
|
||||
"@nhost/stripe-graphql-js": "^1.0.1",
|
||||
"@nhost/stripe-graphql-js": "^1.0.2",
|
||||
"@pothos/core": "^3.21.0",
|
||||
"cross-fetch": "^3.1.5",
|
||||
"graphql": "15.7.2",
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @nhost-examples/vue-apollo
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/apollo@5.0.4
|
||||
- @nhost/vue@1.13.10
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 445d8ef4: chore(deps): bump `@nhost/apollo` to 5.0.3
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/apollo@5.0.3
|
||||
- @nhost/vue@1.13.9
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "@nhost-examples/vue-apollo",
|
||||
"private": true,
|
||||
"version": "0.0.5",
|
||||
"version": "0.0.7",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc --noEmit && vite build",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"prettier": "prettier --check src/",
|
||||
"prettier:fix": "prettier --write src/",
|
||||
@@ -34,7 +34,7 @@
|
||||
"@vitejs/plugin-vue": "^4.0.0",
|
||||
"@xstate/inspect": "^0.6.2",
|
||||
"sass": "1.32.0",
|
||||
"typescript": "^4.8.4",
|
||||
"typescript": "4.9.4",
|
||||
"vite": "^4.0.2",
|
||||
"vue-tsc": "^0.38.9"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# @nhost-examples/vue-quickstart
|
||||
|
||||
## 0.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/apollo@5.0.4
|
||||
- @nhost/vue@1.13.10
|
||||
|
||||
## 0.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 445d8ef4: chore(deps): bump `@nhost/apollo` to 5.0.3
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/apollo@5.0.3
|
||||
- @nhost/vue@1.13.9
|
||||
|
||||
## 0.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost-examples/vue-quickstart",
|
||||
"version": "0.0.4",
|
||||
"version": "0.0.6",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "vite build",
|
||||
|
||||
@@ -1,5 +1,44 @@
|
||||
# @nhost/apollo
|
||||
|
||||
## 5.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/nhost-js@2.0.4
|
||||
|
||||
## 5.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 445d8ef4: chore(deps): bump `@nhost/nhost-js` version to 2.0.3
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/nhost-js@2.0.3
|
||||
|
||||
## 5.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2d9145f9]
|
||||
- @nhost/nhost-js@2.0.2
|
||||
|
||||
## 5.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@2.0.1
|
||||
|
||||
## 5.0.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [c9d2d31a]
|
||||
- Updated dependencies [80bbd3a1]
|
||||
- Updated dependencies [80bbd3a1]
|
||||
- Updated dependencies [2949ff0f]
|
||||
- @nhost/nhost-js@2.0.0
|
||||
|
||||
## 4.13.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/apollo",
|
||||
"version": "4.13.4",
|
||||
"version": "5.0.4",
|
||||
"description": "Nhost Apollo Client library",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @nhost/google-translation
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/google-translation",
|
||||
"version": "0.0.2",
|
||||
"version": "0.0.3",
|
||||
"description": "Google Translation GraphQL API",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,47 @@
|
||||
# @nhost/react-apollo
|
||||
|
||||
## 5.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/apollo@5.0.4
|
||||
- @nhost/react@2.0.4
|
||||
|
||||
## 5.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 445d8ef4: chore(deps): bump `@nhost/react` to 2.0.3
|
||||
- 445d8ef4: chore(deps): bump `@nhost/apollo` to 5.0.3
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/apollo@5.0.3
|
||||
- @nhost/react@2.0.3
|
||||
|
||||
## 5.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@5.0.2
|
||||
- @nhost/react@2.0.2
|
||||
|
||||
## 5.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/apollo@5.0.1
|
||||
- @nhost/react@2.0.1
|
||||
|
||||
## 5.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [19b11d40]
|
||||
- Updated dependencies [19b11d40]
|
||||
- @nhost/react@2.0.0
|
||||
- @nhost/apollo@5.0.0
|
||||
|
||||
## 4.13.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/react-apollo",
|
||||
"version": "4.13.5",
|
||||
"version": "5.0.5",
|
||||
"description": "Nhost React Apollo client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,41 @@
|
||||
# @nhost/react-urql
|
||||
|
||||
## 2.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
- Updated dependencies [01318860]
|
||||
- @nhost/react@2.0.4
|
||||
|
||||
## 2.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 445d8ef4: chore(deps): bump `@nhost/react` to 2.0.3
|
||||
- Updated dependencies [445d8ef4]
|
||||
- @nhost/react@2.0.3
|
||||
|
||||
## 2.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@2.0.2
|
||||
|
||||
## 2.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/react@2.0.1
|
||||
|
||||
## 2.0.0
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [19b11d40]
|
||||
- Updated dependencies [19b11d40]
|
||||
- @nhost/react@2.0.0
|
||||
|
||||
## 1.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/react-urql",
|
||||
"version": "1.0.5",
|
||||
"version": "2.0.4",
|
||||
"description": "Nhost React URQL client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @nhost/stripe-graphql-js
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 01318860: fix(nhost-js): use correct URL for functions requests
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/stripe-graphql-js",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"description": "Stripe GraphQL API",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
|
||||
9
packages/graphql-js/.eslintrc.js
Normal file
9
packages/graphql-js/.eslintrc.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const base = require('../../config/.eslintrc.js')
|
||||
module.exports = {
|
||||
...base,
|
||||
parserOptions: {
|
||||
project: 'tsconfig.json',
|
||||
tsconfigRootDir: __dirname
|
||||
},
|
||||
ignorePatterns: [...base.ignorePatterns, 'functions/**/*.ts']
|
||||
}
|
||||
14
packages/graphql-js/CHANGELOG.md
Normal file
14
packages/graphql-js/CHANGELOG.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# @nhost/graphql-js
|
||||
|
||||
## 0.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2d9145f9: chore(deps): revert GraphQL client
|
||||
|
||||
## 0.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2200a0ed: Correct type inference on snake case operations
|
||||
- 3b48a627: Improve readme instructions
|
||||
16
packages/graphql-js/README.md
Normal file
16
packages/graphql-js/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
<h1 align="center">@nhost/graphql-js</h1>
|
||||
<h2 align="center">Nhost GraphQL client</h2>
|
||||
|
||||
<p align="center">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@nhost/graphql-js">
|
||||
<img alt="npm" src="https://img.shields.io/npm/dm/@nhost/graphql-js">
|
||||
<a href="LICENSE">
|
||||
<img src="https://img.shields.io/badge/license-MIT-yellow.svg" alt="license: MIT" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
Nhost GraphQL client.
|
||||
|
||||
## Documentation
|
||||
|
||||
[https://docs.nhost.io/reference/javascript/graphql](https://docs.nhost.io/reference/javascript/graphql)
|
||||
10
packages/graphql-js/graphql.docgen.json
Normal file
10
packages/graphql-js/graphql.docgen.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"title": "GraphQL",
|
||||
"path": "./.docgen/graphql.json",
|
||||
"output": "../../docs/docs/reference/docgen/javascript/graphql",
|
||||
"root": "reference/docgen/javascript/graphql",
|
||||
"slug": "/reference/javascript/graphql",
|
||||
"sidebarConfig": "referenceSidebar",
|
||||
"baseEditUrl": "https://github.com/nhost/nhost/edit/main/packages",
|
||||
"cleanup": true
|
||||
}
|
||||
@@ -7,8 +7,8 @@
|
||||
"sort": [
|
||||
"source-order"
|
||||
],
|
||||
"json": "./.docgen/nhost-js.json",
|
||||
"name": "Nhost JS",
|
||||
"json": "./.docgen/graphql.json",
|
||||
"name": "GraphQL",
|
||||
"readme": "none",
|
||||
"githubPages": false,
|
||||
"cleanOutputDir": false,
|
||||
@@ -26,6 +26,9 @@
|
||||
"@nhost/hasura-storage-js": [
|
||||
"../hasura-storage-js/src/index.ts"
|
||||
],
|
||||
"@nhost/graphql-js": [
|
||||
"../graphql-js/src/index.ts"
|
||||
],
|
||||
"@nhost/nextjs": [
|
||||
"../nextjs/src/index.ts"
|
||||
],
|
||||
65
packages/graphql-js/package.json
Normal file
65
packages/graphql-js/package.json
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "@nhost/graphql-js",
|
||||
"version": "0.0.3",
|
||||
"description": "Nhost GraphQL client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
"nhost",
|
||||
"hasura",
|
||||
"graphql"
|
||||
],
|
||||
"author": "Nhost",
|
||||
"homepage": "https://nhost.io",
|
||||
"bugs": "https://github.com/nhost/nhost/issues",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nhost/nhost.git"
|
||||
},
|
||||
"main": "dist/index.cjs.js",
|
||||
"module": "dist/index.esm.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"source": "src/index.ts",
|
||||
"files": [
|
||||
"dist",
|
||||
"umd",
|
||||
"README.md"
|
||||
],
|
||||
"exports": {
|
||||
"./package.json": "./package.json",
|
||||
".": {
|
||||
"import": {
|
||||
"node": "./dist/index.cjs.js",
|
||||
"default": "./dist/index.esm.js"
|
||||
},
|
||||
"require": "./dist/index.cjs.js"
|
||||
}
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite build",
|
||||
"build": "run-p build:lib build:umd",
|
||||
"build:lib": "vite build",
|
||||
"build:umd": "vite build --config ../../config/vite.lib.umd.config.js",
|
||||
"prettier": "prettier --check src/",
|
||||
"prettier:fix": "prettier --write src/",
|
||||
"lint": "eslint . --ext .ts,.tsx",
|
||||
"lint:fix": "eslint . --ext .ts,.tsx --fix",
|
||||
"verify": "run-p prettier lint",
|
||||
"verify:fix": "run-p prettier:fix lint:fix",
|
||||
"typedoc": "typedoc --options ./graphql.typedoc.json --tsconfig ./typedoc.tsconfig.json",
|
||||
"docgen": "pnpm typedoc && docgen --config ./graphql.docgen.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@graphql-typed-document-node/core": "^3.1.1",
|
||||
"cross-fetch": "^3.1.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphql": "^14.0.0 || ^15.0.0 || ^16.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nhost/docgen": "workspace:*",
|
||||
"graphql": "16.6.0"
|
||||
}
|
||||
}
|
||||
205
packages/graphql-js/src/client.ts
Normal file
205
packages/graphql-js/src/client.ts
Normal file
@@ -0,0 +1,205 @@
|
||||
import { TypedDocumentNode } from '@graphql-typed-document-node/core'
|
||||
import fetch from 'cross-fetch'
|
||||
import { parseRequestArgs } from './parse-args'
|
||||
import { resolveRequestDocument } from './resolve-request-document'
|
||||
import {
|
||||
NhostGraphqlConstructorParams,
|
||||
NhostGraphqlRequestConfig,
|
||||
NhostGraphqlRequestResponse,
|
||||
RemoveIndex,
|
||||
RequestDocument,
|
||||
RequestOptions,
|
||||
Variables
|
||||
} from './types'
|
||||
|
||||
/**
|
||||
* @alias GraphQL
|
||||
*/
|
||||
export class NhostGraphqlClient {
|
||||
readonly _url: string
|
||||
private accessToken: string | null
|
||||
private adminSecret?: string
|
||||
|
||||
constructor(params: NhostGraphqlConstructorParams) {
|
||||
const { url, adminSecret } = params
|
||||
|
||||
this._url = url
|
||||
this.accessToken = null
|
||||
this.adminSecret = adminSecret
|
||||
}
|
||||
|
||||
/**
|
||||
* Use `nhost.graphql.request` to send a GraphQL request. For more serious GraphQL usage we recommend using a GraphQL client such as Apollo Client (https://www.apollographql.com/docs/react).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const CUSTOMERS = gql`
|
||||
* query {
|
||||
* customers {
|
||||
* id
|
||||
* name
|
||||
* }
|
||||
* }
|
||||
* `
|
||||
* const { data, error } = await nhost.graphql.request(CUSTOMERS)
|
||||
* ```
|
||||
*
|
||||
* @docs https://docs.nhost.io/reference/javascript/graphql/request
|
||||
*/
|
||||
request<T = any, V = Variables>(
|
||||
document: RequestDocument | TypedDocumentNode<T, V>,
|
||||
...variablesAndRequestHeaders: V extends Record<any, never>
|
||||
? [variables?: V, config?: NhostGraphqlRequestConfig]
|
||||
: keyof RemoveIndex<V> extends never
|
||||
? [variables?: V, config?: NhostGraphqlRequestConfig]
|
||||
: [variables: V, config?: NhostGraphqlRequestConfig]
|
||||
): Promise<NhostGraphqlRequestResponse<T>>
|
||||
async request<T = any, V extends Variables = Variables>(
|
||||
options: RequestOptions<V, T>
|
||||
): Promise<NhostGraphqlRequestResponse<T>>
|
||||
async request<T = any, V extends Variables = Variables>(
|
||||
documentOrOptions: RequestDocument | TypedDocumentNode<T, V> | RequestOptions<V>,
|
||||
...variablesAndRequestHeaders: V extends Record<any, never>
|
||||
? [variables?: V, config?: NhostGraphqlRequestConfig]
|
||||
: keyof RemoveIndex<V> extends never
|
||||
? [variables?: V, config?: NhostGraphqlRequestConfig]
|
||||
: [variables: V, config?: NhostGraphqlRequestConfig]
|
||||
): Promise<NhostGraphqlRequestResponse<T>> {
|
||||
const [variables, config] = variablesAndRequestHeaders
|
||||
const requestOptions = parseRequestArgs(documentOrOptions, variables, config)
|
||||
|
||||
const { headers, ...otherOptions } = config || {}
|
||||
const { query, operationName } = resolveRequestDocument(requestOptions.document)
|
||||
try {
|
||||
const response = await fetch(this.httpUrl, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
operationName,
|
||||
query,
|
||||
variables
|
||||
}),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
...this.generateAccessTokenHeaders(),
|
||||
...headers
|
||||
},
|
||||
...otherOptions
|
||||
})
|
||||
if (!response.ok) {
|
||||
return {
|
||||
data: null,
|
||||
error: {
|
||||
error: response.statusText,
|
||||
message: response.statusText,
|
||||
status: response.status
|
||||
}
|
||||
}
|
||||
}
|
||||
const { data, errors } = await response.json()
|
||||
|
||||
if (errors) {
|
||||
return {
|
||||
data: null,
|
||||
error: errors
|
||||
}
|
||||
}
|
||||
if (typeof data !== 'object' || Array.isArray(data) || data === null) {
|
||||
return {
|
||||
data: null,
|
||||
error: {
|
||||
error: 'invalid-response',
|
||||
message: 'incorrect response data from GraphQL server',
|
||||
status: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return { data, error: null }
|
||||
} catch (e) {
|
||||
const error = e as Error
|
||||
return {
|
||||
data: null,
|
||||
error: {
|
||||
message: error.message,
|
||||
status: error.name === 'AbortError' ? 0 : 500,
|
||||
error: error.name === 'AbortError' ? 'abort-error' : 'unknown'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use `nhost.graphql.httpUrl` to get the GraphQL HTTP URL.
|
||||
* @example
|
||||
* ```ts
|
||||
* const url = nhost.graphql.httpUrl;
|
||||
* ```
|
||||
*
|
||||
* @docs https://docs.nhost.io/reference/javascript/graphql/get-http-url
|
||||
*/
|
||||
get httpUrl(): string {
|
||||
return this._url
|
||||
}
|
||||
|
||||
/**
|
||||
* Use `nhost.graphql.wsUrl` to get the GraphQL WebSocket URL.
|
||||
* @example
|
||||
* ```ts
|
||||
* const url = nhost.graphql.wsUrl;
|
||||
* ```
|
||||
*
|
||||
* @docs https://docs.nhost.io/reference/javascript/graphql/get-ws-url
|
||||
*/
|
||||
get wsUrl(): string {
|
||||
return this._url.replace(/^(http)(s?):\/\//, 'ws$2://')
|
||||
}
|
||||
|
||||
/**
|
||||
* Use `nhost.graphql.url` to get the GraphQL URL.
|
||||
* @deprecated Use `nhost.graphql.httpUrl` and `nhost.graphql.wsUrl` instead.
|
||||
*/
|
||||
get url(): string {
|
||||
return this._url
|
||||
}
|
||||
|
||||
/**
|
||||
* Use `nhost.graphql.getUrl()` to get the GraphQL URL.
|
||||
* @deprecated Use `nhost.graphql.httpUrl` and `nhost.graphql.wsUrl` instead.
|
||||
*/
|
||||
getUrl(): string {
|
||||
return this._url
|
||||
}
|
||||
|
||||
/**
|
||||
* Use `nhost.graphql.setAccessToken` to a set an access token to be used in subsequent graphql requests. Note that if you're signin in users with `nhost.auth.signIn()` the access token will be set automatically.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* nhost.graphql.setAccessToken('some-access-token')
|
||||
* ```
|
||||
*
|
||||
* @docs https://docs.nhost.io/reference/javascript/graphql/set-access-token
|
||||
*/
|
||||
setAccessToken(accessToken: string | undefined) {
|
||||
if (!accessToken) {
|
||||
this.accessToken = null
|
||||
return
|
||||
}
|
||||
|
||||
this.accessToken = accessToken
|
||||
}
|
||||
|
||||
private generateAccessTokenHeaders(): NhostGraphqlRequestConfig['headers'] {
|
||||
if (this.adminSecret) {
|
||||
return {
|
||||
'x-hasura-admin-secret': this.adminSecret
|
||||
}
|
||||
}
|
||||
if (this.accessToken) {
|
||||
return {
|
||||
Authorization: `Bearer ${this.accessToken}`
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
}
|
||||
1
packages/graphql-js/src/index.ts
Normal file
1
packages/graphql-js/src/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './client'
|
||||
17
packages/graphql-js/src/parse-args.ts
Normal file
17
packages/graphql-js/src/parse-args.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { RequestDocument, RequestOptions, Variables } from './types'
|
||||
|
||||
export function parseRequestArgs<V extends Variables = Variables>(
|
||||
documentOrOptions: RequestDocument | RequestOptions<V>,
|
||||
variables?: V,
|
||||
config?: RequestInit
|
||||
): RequestOptions<V> {
|
||||
return (
|
||||
(documentOrOptions as RequestOptions<V>).document
|
||||
? documentOrOptions
|
||||
: {
|
||||
document: documentOrOptions,
|
||||
variables,
|
||||
config
|
||||
}
|
||||
) as RequestOptions<V>
|
||||
}
|
||||
42
packages/graphql-js/src/resolve-request-document.ts
Normal file
42
packages/graphql-js/src/resolve-request-document.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { DocumentNode, OperationDefinitionNode, parse, print } from 'graphql'
|
||||
import { RequestDocument } from './types'
|
||||
|
||||
/**
|
||||
* helpers
|
||||
*/
|
||||
|
||||
function extractOperationName(document: DocumentNode): string | undefined {
|
||||
let operationName = undefined
|
||||
|
||||
const operationDefinitions = document.definitions.filter(
|
||||
(definition) => definition.kind === 'OperationDefinition'
|
||||
) as OperationDefinitionNode[]
|
||||
|
||||
if (operationDefinitions.length === 1) {
|
||||
operationName = operationDefinitions[0].name?.value
|
||||
}
|
||||
|
||||
return operationName
|
||||
}
|
||||
|
||||
export function resolveRequestDocument(document: RequestDocument): {
|
||||
query: string
|
||||
operationName?: string
|
||||
} {
|
||||
if (typeof document === 'string') {
|
||||
let operationName = undefined
|
||||
|
||||
try {
|
||||
const parsedDocument = parse(document)
|
||||
operationName = extractOperationName(parsedDocument)
|
||||
} catch (err) {
|
||||
// Failed parsing the document, the operationName will be undefined
|
||||
}
|
||||
|
||||
return { query: document, operationName }
|
||||
}
|
||||
|
||||
const operationName = extractOperationName(document)
|
||||
|
||||
return { query: print(document), operationName }
|
||||
}
|
||||
52
packages/graphql-js/src/types.ts
Normal file
52
packages/graphql-js/src/types.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
import { TypedDocumentNode } from '@graphql-typed-document-node/core'
|
||||
import { DocumentNode, GraphQLError } from 'graphql'
|
||||
|
||||
// TODO shared with other packages
|
||||
export type ErrorPayload = {
|
||||
error: string
|
||||
status: number
|
||||
message: string
|
||||
}
|
||||
|
||||
export type RequestOptions<V extends Variables = Variables, T = any> = NhostGraphqlRequestConfig & {
|
||||
document: RequestDocument | TypedDocumentNode<T, V>
|
||||
} & (V extends Record<any, never>
|
||||
? { variables?: V }
|
||||
: keyof RemoveIndex<V> extends never
|
||||
? { variables?: V }
|
||||
: { variables: V })
|
||||
export type Variables = { [key: string]: any }
|
||||
|
||||
export type RequestDocument = string | DocumentNode
|
||||
|
||||
export type RemoveIndex<T> = {
|
||||
[K in keyof T as string extends K ? never : number extends K ? never : K]: T[K]
|
||||
}
|
||||
|
||||
export interface NhostGraphqlConstructorParams {
|
||||
/**
|
||||
* GraphQL endpoint.
|
||||
*/
|
||||
url: string
|
||||
/**
|
||||
* Admin secret. When set, it is sent as an `x-hasura-admin-secret` header for all requests.
|
||||
*/
|
||||
adminSecret?: string
|
||||
}
|
||||
|
||||
export type NhostGraphqlRequestResponse<T = unknown> =
|
||||
| {
|
||||
data: null
|
||||
error: GraphQLError[] | ErrorPayload
|
||||
}
|
||||
| {
|
||||
data: T
|
||||
error: null
|
||||
}
|
||||
|
||||
/** Subset of RequestInit parameters that are supported by the graphql client */
|
||||
export interface NhostGraphqlRequestConfig {
|
||||
headers?: Record<string, string>
|
||||
/** @deprecated Axios has been replaced by cross-fetch. You should now remove this option. */
|
||||
useAxios?: false
|
||||
}
|
||||
4
packages/graphql-js/tsconfig.json
Normal file
4
packages/graphql-js/tsconfig.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"extends": "../../config/tsconfig.base.json",
|
||||
"include": ["src"]
|
||||
}
|
||||
7
packages/graphql-js/tsconfig.test.json
Normal file
7
packages/graphql-js/tsconfig.test.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"include": [
|
||||
"tests/types"
|
||||
]
|
||||
}
|
||||
13
packages/graphql-js/vite.config.e2e.js
Normal file
13
packages/graphql-js/vite.config.e2e.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
import baseConfig from '../../config/vite.lib.config'
|
||||
|
||||
export default defineConfig({
|
||||
...baseConfig,
|
||||
test: {
|
||||
...(baseConfig.test || {}),
|
||||
include: [`tests/e2e/**/*.{spec,test}.{ts,tsx}`],
|
||||
testTimeout: 30000,
|
||||
environment: 'node'
|
||||
}
|
||||
})
|
||||
5
packages/graphql-js/vite.config.js
Normal file
5
packages/graphql-js/vite.config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
import baseConfig from '../../config/vite.lib.config'
|
||||
|
||||
export default defineConfig(baseConfig)
|
||||
13
packages/graphql-js/vite.config.unit.js
Normal file
13
packages/graphql-js/vite.config.unit.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
import baseConfig from '../../config/vite.lib.config'
|
||||
|
||||
export default defineConfig({
|
||||
...baseConfig,
|
||||
test: {
|
||||
...(baseConfig.test || {}),
|
||||
include: [`tests/unit/**/*.{spec,test}.{ts,tsx}`],
|
||||
testTimeout: 30000,
|
||||
environment: 'node'
|
||||
}
|
||||
})
|
||||
@@ -1,5 +1,41 @@
|
||||
# @nhost/hasura-auth-js
|
||||
|
||||
## 2.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- 19b11d40: Remove the deprecated `AuthCookieClient` and `AuthClientSSR` constructors
|
||||
|
||||
Use the `clientStorageType` option instead:
|
||||
|
||||
```ts
|
||||
const nhost = new NhostClient({ clientStorageType: 'cookie' })
|
||||
```
|
||||
|
||||
- 19b11d40: Remove the deprecated `nhost.auth.getJWTToken` method
|
||||
|
||||
Use `nhost.auth.getAccessToken()` instead.
|
||||
|
||||
- 19b11d40: Remove the deprecated `autoLogin` option
|
||||
|
||||
Use `autoSignIn` instead:
|
||||
|
||||
```ts
|
||||
const nhost = new NhostClient({ autoSignIn: true })
|
||||
```
|
||||
|
||||
- 19b11d40: Remove the deprecated `clientStorageGetter` and `clientStorageSetter` options
|
||||
|
||||
Use `clientStorageType` and `clientStorage` instead:
|
||||
|
||||
```ts
|
||||
const nhost = new NhostClient({ clientStorageType: 'custom', clientStorage: TODO })
|
||||
```
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 80bbd3a1: Replace `axios` by `cross-fetch`
|
||||
|
||||
## 1.12.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { faker } from '@faker-js/faker'
|
||||
import axios from 'axios'
|
||||
import fetch from 'cross-fetch'
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
|
||||
import { auth, getHtmlLink, mailhog } from './helpers'
|
||||
|
||||
describe('emails', () => {
|
||||
@@ -22,10 +21,11 @@ describe('emails', () => {
|
||||
const verifyEmailLink = await getHtmlLink(email, 'verifyEmail')
|
||||
|
||||
// verify email
|
||||
await axios.get(verifyEmailLink, {
|
||||
maxRedirects: 0,
|
||||
validateStatus: (status) => status === 302
|
||||
})
|
||||
try {
|
||||
await fetch(verifyEmailLink, { method: 'GET', redirect: 'follow' })
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
const signInA = await auth.signIn({
|
||||
email,
|
||||
@@ -46,10 +46,11 @@ describe('emails', () => {
|
||||
const changeEmailLink = await getHtmlLink(email, 'emailConfirmChange')
|
||||
|
||||
// verify email
|
||||
await axios.get(changeEmailLink, {
|
||||
maxRedirects: 0,
|
||||
validateStatus: (status) => status === 302
|
||||
})
|
||||
try {
|
||||
await fetch(changeEmailLink, { method: 'GET', redirect: 'follow' })
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
})
|
||||
|
||||
it('reset email verification', async () => {
|
||||
@@ -71,28 +72,21 @@ describe('emails', () => {
|
||||
expect(signInA.error).toBeTruthy()
|
||||
expect(signInA.session).toBeNull()
|
||||
|
||||
await mailhog.deleteAll()
|
||||
|
||||
await auth.sendVerificationEmail({ email })
|
||||
|
||||
// make sure onle a single message exists
|
||||
const messages = await mailhog.messages()
|
||||
|
||||
if (!messages) {
|
||||
throw new Error('no messages')
|
||||
}
|
||||
|
||||
expect(messages.count).toBe(1)
|
||||
const message = await mailhog.latestTo(email)
|
||||
expect(message?.subject).toBe('Verify your email')
|
||||
|
||||
// test email link
|
||||
// get verify email link
|
||||
const verifyEmailLink = await getHtmlLink(email, 'verifyEmail')
|
||||
|
||||
// verify email
|
||||
await axios.get(verifyEmailLink, {
|
||||
maxRedirects: 0,
|
||||
validateStatus: (status) => status === 302
|
||||
})
|
||||
try {
|
||||
await fetch(verifyEmailLink, { method: 'GET', redirect: 'follow' })
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// sign in should work
|
||||
const signInB = await auth.signIn({
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import axios from 'axios'
|
||||
import { load } from 'cheerio'
|
||||
import fetch from 'cross-fetch'
|
||||
import createMailhogClient from 'mailhog'
|
||||
import { expect } from 'vitest'
|
||||
|
||||
import { HasuraAuthClient, SignUpParams } from '../src'
|
||||
|
||||
const AUTH_BACKEND_URL = 'http://localhost:1337/v1/auth'
|
||||
@@ -43,11 +42,11 @@ export const signUpAndVerifyUser = async (params: SignUpParams) => {
|
||||
// get verify email link
|
||||
const verifyEmailLink = await getHtmlLink(email, 'verifyEmail')
|
||||
|
||||
// verify email
|
||||
await axios.get(verifyEmailLink, {
|
||||
maxRedirects: 0,
|
||||
validateStatus: (status) => status === 302
|
||||
})
|
||||
try {
|
||||
await fetch(verifyEmailLink, { method: 'GET', redirect: 'follow' })
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
export const signUpAndInUser = async (params: SignUpParams) => {
|
||||
@@ -60,10 +59,11 @@ export const signUpAndInUser = async (params: SignUpParams) => {
|
||||
const verifyEmailLink = await getHtmlLink(email, 'verifyEmail')
|
||||
|
||||
// verify email
|
||||
await axios.get(verifyEmailLink, {
|
||||
maxRedirects: 0,
|
||||
validateStatus: (status) => status === 302
|
||||
})
|
||||
try {
|
||||
await fetch(verifyEmailLink, { method: 'GET', redirect: 'follow' })
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// sign in
|
||||
const { session, error } = await auth.signIn({ email, password })
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user