Compare commits
472 Commits
@nhost/rea
...
@nhost/rea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
160ebd9f04 | ||
|
|
688471faf0 | ||
|
|
f07d17a3e8 | ||
|
|
609681e741 | ||
|
|
ab8d20a354 | ||
|
|
543c85c85e | ||
|
|
4a9fbd6d84 | ||
|
|
24d45a1aed | ||
|
|
4511b7b538 | ||
|
|
cb39f3d9ab | ||
|
|
d49beb72bc | ||
|
|
d5ca9ae2c5 | ||
|
|
80eeea49be | ||
|
|
e92716097e | ||
|
|
54e11430b9 | ||
|
|
7af47ba7d2 | ||
|
|
7b624eae1c | ||
|
|
151871cedc | ||
|
|
13e4fa73d5 | ||
|
|
0b58894ef1 | ||
|
|
3ba123dbff | ||
|
|
0ffdeab89f | ||
|
|
df02e25d02 | ||
|
|
c7a407f111 | ||
|
|
91edc67a5e | ||
|
|
d1a7bd7f94 | ||
|
|
31b0830b91 | ||
|
|
7c39b14fd2 | ||
|
|
16669d98e4 | ||
|
|
0696c108eb | ||
|
|
88f8e5dbed | ||
|
|
5a288f52df | ||
|
|
f922c02c08 | ||
|
|
1abb4354e8 | ||
|
|
b3f68b8748 | ||
|
|
0ee2171754 | ||
|
|
a112a9a8ad | ||
|
|
195b8ee4b7 | ||
|
|
21a9da792f | ||
|
|
fd562b9c78 | ||
|
|
eca4ed92c1 | ||
|
|
adf4d2b997 | ||
|
|
3a724f847d | ||
|
|
99f941b060 | ||
|
|
97392e547f | ||
|
|
685e2dfccc | ||
|
|
0222d0fa22 | ||
|
|
08e7a8e23a | ||
|
|
24faf32abe | ||
|
|
8662674abe | ||
|
|
e9a01588da | ||
|
|
17e370e889 | ||
|
|
5929da369f | ||
|
|
d4450ea0e4 | ||
|
|
f5b86f5865 | ||
|
|
a6cfdb67d0 | ||
|
|
645eaf6367 | ||
|
|
5217ffa5e3 | ||
|
|
b08790b7ab | ||
|
|
5802feedec | ||
|
|
79f153e627 | ||
|
|
84c5ae1cba | ||
|
|
b5f82d9dd0 | ||
|
|
00e03d44b5 | ||
|
|
15aacc09db | ||
|
|
01b53348c4 | ||
|
|
aa770cc15a | ||
|
|
552790fe3f | ||
|
|
4d08a2c1dd | ||
|
|
ee34b9d2aa | ||
|
|
0d87c30a8e | ||
|
|
d7aaeeb8cc | ||
|
|
101f4f502d | ||
|
|
d070680abd | ||
|
|
aa16ba979b | ||
|
|
3f07c33b17 | ||
|
|
f935269a6b | ||
|
|
965f1b26b0 | ||
|
|
08394ffd01 | ||
|
|
802d095044 | ||
|
|
9340e115d1 | ||
|
|
170dbfc930 | ||
|
|
e44c4b2e93 | ||
|
|
5154d31126 | ||
|
|
f5e542e4c1 | ||
|
|
029925d88f | ||
|
|
718a4db33c | ||
|
|
5a7be0cfd4 | ||
|
|
f4dc867242 | ||
|
|
038e279660 | ||
|
|
f671a5a420 | ||
|
|
95dbfd59ee | ||
|
|
8980c99200 | ||
|
|
c0dcdb2410 | ||
|
|
1035639850 | ||
|
|
9be836b036 | ||
|
|
0e96e7329e | ||
|
|
19ccc5ab0d | ||
|
|
e094e682ce | ||
|
|
49cc3cb41b | ||
|
|
e0d81d419f | ||
|
|
74eb71f8f0 | ||
|
|
a931c15073 | ||
|
|
e04d88b034 | ||
|
|
eca552b931 | ||
|
|
ed30bdd7e1 | ||
|
|
b76bc30fe4 | ||
|
|
2b571ebf23 | ||
|
|
ebe9fb0a44 | ||
|
|
9ae5e485e6 | ||
|
|
2965a7bf5b | ||
|
|
236ce72bb3 | ||
|
|
5ad5832e41 | ||
|
|
a57825e5ad | ||
|
|
1e233b6582 | ||
|
|
9ebd014287 | ||
|
|
6ce2534a36 | ||
|
|
9f8e792f0d | ||
|
|
e1383106d9 | ||
|
|
812d7a8eae | ||
|
|
2887ce0f82 | ||
|
|
8bdfb8fcac | ||
|
|
573436dd87 | ||
|
|
c7ce66597a | ||
|
|
c82605c4e8 | ||
|
|
ef41ce8bb2 | ||
|
|
864074fba5 | ||
|
|
f58c2bb9ce | ||
|
|
4eac3101c9 | ||
|
|
80bd938336 | ||
|
|
41db6f613a | ||
|
|
ee84bfa098 | ||
|
|
ad1b7b80e2 | ||
|
|
3fcd345cff | ||
|
|
43a3f1dd46 | ||
|
|
3ec745c91e | ||
|
|
92deec4531 | ||
|
|
c7fcc9fe82 | ||
|
|
081377af6c | ||
|
|
23cb207afc | ||
|
|
62b1495a22 | ||
|
|
8a79a7102f | ||
|
|
0f55f6db9b | ||
|
|
7b16a8d790 | ||
|
|
dca8233601 | ||
|
|
a7535b260b | ||
|
|
82520963f1 | ||
|
|
722abd9a19 | ||
|
|
2aff6c0b4e | ||
|
|
e101915f60 | ||
|
|
0195143fe1 | ||
|
|
e362925041 | ||
|
|
b4f8c7457d | ||
|
|
84f1ab2f61 | ||
|
|
dee93bb873 | ||
|
|
173b587802 | ||
|
|
30ef1660b4 | ||
|
|
a613aa9f0c | ||
|
|
3c03b9b46f | ||
|
|
65a3061146 | ||
|
|
f4c2088bce | ||
|
|
d3107934b0 | ||
|
|
5ae02605b2 | ||
|
|
55864eac30 | ||
|
|
b927587d75 | ||
|
|
e63c45cdaa | ||
|
|
28494d6c1f | ||
|
|
6777738c53 | ||
|
|
34532b1a2f | ||
|
|
de3257ca7a | ||
|
|
9d32314065 | ||
|
|
9edfe408e0 | ||
|
|
0d60693c27 | ||
|
|
c159c9c98c | ||
|
|
58fa2a201c | ||
|
|
d3c7930b48 | ||
|
|
4a864a9777 | ||
|
|
50ba5fe2c8 | ||
|
|
05e0c42c82 | ||
|
|
fbc9ff32dd | ||
|
|
db4607ccac | ||
|
|
95b14557a0 | ||
|
|
8b527d0fcb | ||
|
|
67f0450dac | ||
|
|
fc50beec5e | ||
|
|
584976d1ad | ||
|
|
509ed7d864 | ||
|
|
71b92363b4 | ||
|
|
ed0de2d930 | ||
|
|
c7aa9f7ea9 | ||
|
|
3e6057b4ed | ||
|
|
f26e8c3614 | ||
|
|
a05a484426 | ||
|
|
4f0d5aa9c0 | ||
|
|
254e362e95 | ||
|
|
a2a8839694 | ||
|
|
d12667ccc5 | ||
|
|
feb55fe0ad | ||
|
|
b97c0a9c9d | ||
|
|
bb548cd108 | ||
|
|
adb30c537f | ||
|
|
d7d3e8f903 | ||
|
|
2e98934f75 | ||
|
|
8a4064e99f | ||
|
|
937e28116b | ||
|
|
8cedafc807 | ||
|
|
d885fe7b02 | ||
|
|
b0d7217276 | ||
|
|
bfba4ae7ec | ||
|
|
322b433994 | ||
|
|
6082ba6943 | ||
|
|
44b12dc0a0 | ||
|
|
1fb1d25a72 | ||
|
|
ae4e4e50f6 | ||
|
|
185f39e23f | ||
|
|
bf6ee5d360 | ||
|
|
0dd7cab3bf | ||
|
|
47c7380d89 | ||
|
|
b56162a74b | ||
|
|
1a7007d1cb | ||
|
|
05d25a54af | ||
|
|
9f8bdb504d | ||
|
|
aeb8b8afda | ||
|
|
f9e107b008 | ||
|
|
cd2594f66a | ||
|
|
c6a3e9f516 | ||
|
|
d748d82483 | ||
|
|
1bfb1e6d10 | ||
|
|
35fd7b1b7c | ||
|
|
04c1ed6955 | ||
|
|
0c591daef4 | ||
|
|
2192fdc92e | ||
|
|
eec2601a3a | ||
|
|
93eaa85b47 | ||
|
|
4c8a168c02 | ||
|
|
eb166cf5ee | ||
|
|
54e1873461 | ||
|
|
e5bc3b356c | ||
|
|
42edb74057 | ||
|
|
3ebeae9294 | ||
|
|
24189bd155 | ||
|
|
5985b18764 | ||
|
|
95efcb4de6 | ||
|
|
609d9001f5 | ||
|
|
6f5729eb45 | ||
|
|
9bc447dbff | ||
|
|
d2d0e7fced | ||
|
|
0ad654226b | ||
|
|
9d8f2dea22 | ||
|
|
f3a44931a5 | ||
|
|
1e44a14b8a | ||
|
|
1c1656441b | ||
|
|
5f68f8fe31 | ||
|
|
961103d7a5 | ||
|
|
2bebab3f8e | ||
|
|
0363abbbb1 | ||
|
|
2f3715d02a | ||
|
|
7c101e5226 | ||
|
|
ef943995e2 | ||
|
|
b6032508bc | ||
|
|
a6b00294e7 | ||
|
|
dbfc5ec220 | ||
|
|
5917eff5a6 | ||
|
|
f8ee87ad01 | ||
|
|
a7990b363f | ||
|
|
ca8ecb4b5c | ||
|
|
dfe080b8f6 | ||
|
|
069a5d4d9a | ||
|
|
c9d474ea6c | ||
|
|
2afa460263 | ||
|
|
776555bdda | ||
|
|
e0e9729884 | ||
|
|
6ffaf31af5 | ||
|
|
8ec18157bb | ||
|
|
efccd54641 | ||
|
|
396dc554d9 | ||
|
|
92f9576ca6 | ||
|
|
5cf8ace1bc | ||
|
|
cf1518ab75 | ||
|
|
b8c0dba6de | ||
|
|
116c8eba66 | ||
|
|
a9bc698dae | ||
|
|
175ab26e04 | ||
|
|
eb2d064cbe | ||
|
|
17d2c8c3d9 | ||
|
|
4e0aab1bb2 | ||
|
|
a3357265ec | ||
|
|
494d8127dc | ||
|
|
57b628a255 | ||
|
|
98b30a5c5e | ||
|
|
48afcf415d | ||
|
|
58b9488af8 | ||
|
|
e49528d43e | ||
|
|
ab0f5582e5 | ||
|
|
b499548503 | ||
|
|
fbc15cfee1 | ||
|
|
8788de83e8 | ||
|
|
1fb51a7bed | ||
|
|
365b806755 | ||
|
|
74025a2d90 | ||
|
|
ebd6f86ea3 | ||
|
|
7b23d33d9b | ||
|
|
87fc565b14 | ||
|
|
ed46a7a6f9 | ||
|
|
6749bf3486 | ||
|
|
b32c1bab39 | ||
|
|
de177710f7 | ||
|
|
eebfddb48e | ||
|
|
f5df7eaa2d | ||
|
|
0b4028b1d6 | ||
|
|
f2da21026b | ||
|
|
a8233ea621 | ||
|
|
f300d8b9f1 | ||
|
|
3b625acd96 | ||
|
|
116e23cb13 | ||
|
|
1bde3e6516 | ||
|
|
954aa43e49 | ||
|
|
de6f862c4c | ||
|
|
5025333fb4 | ||
|
|
b3991ea9d9 | ||
|
|
3674f11183 | ||
|
|
239db617f3 | ||
|
|
76b3cb4643 | ||
|
|
6d6c8b3e2e | ||
|
|
5a06ecbb10 | ||
|
|
169f163c99 | ||
|
|
5ddd7eda22 | ||
|
|
556190dfc5 | ||
|
|
00d50f404a | ||
|
|
b52b4fca2d | ||
|
|
56b1adfa81 | ||
|
|
9f55f4890e | ||
|
|
284890b437 | ||
|
|
1e3cb855f0 | ||
|
|
aaf575f0af | ||
|
|
ff3427ccdb | ||
|
|
3834d80a0a | ||
|
|
8fcc3fd560 | ||
|
|
616e320421 | ||
|
|
ff8fdc4db4 | ||
|
|
b732bc51e8 | ||
|
|
8b88d6c553 | ||
|
|
af192fbb66 | ||
|
|
b7c031d7e0 | ||
|
|
05e91d93a8 | ||
|
|
261f001a99 | ||
|
|
ddb965c7cf | ||
|
|
ff8af4912b | ||
|
|
948aebcf42 | ||
|
|
51a4d7a343 | ||
|
|
d521218146 | ||
|
|
9a1685c2eb | ||
|
|
fb8f58503f | ||
|
|
86409c2f18 | ||
|
|
f7d8c061a0 | ||
|
|
eb59a07c3f | ||
|
|
27add80f95 | ||
|
|
cc60a845f3 | ||
|
|
aeea44e4e8 | ||
|
|
d273825cee | ||
|
|
177733f4b1 | ||
|
|
efd33a7115 | ||
|
|
e4fe166992 | ||
|
|
d9f221b625 | ||
|
|
e0f5bf3396 | ||
|
|
17bd23460f | ||
|
|
52c30c25a9 | ||
|
|
989bc54544 | ||
|
|
5781cb0f9c | ||
|
|
24f9ed4c4d | ||
|
|
2b447af8a7 | ||
|
|
2485c83de3 | ||
|
|
707877477f | ||
|
|
756e1af52d | ||
|
|
7f771e2e8f | ||
|
|
a737863c2b | ||
|
|
ca2a61089a | ||
|
|
7432db0fe8 | ||
|
|
9c25e65df6 | ||
|
|
e345895fd8 | ||
|
|
cba7996dcf | ||
|
|
d7ceda6ae6 | ||
|
|
4e19b7309d | ||
|
|
de8a7d5512 | ||
|
|
69f3a84bf5 | ||
|
|
16dcd314bb | ||
|
|
7e7aa5adc4 | ||
|
|
1ed948952a | ||
|
|
55b0a8f4b9 | ||
|
|
1ce55c5568 | ||
|
|
fabd1da04c | ||
|
|
53f5226d0c | ||
|
|
e339cba384 | ||
|
|
c14d12e04d | ||
|
|
03370da2f4 | ||
|
|
87d32b2639 | ||
|
|
61b5fb549c | ||
|
|
28cd8dc5c5 | ||
|
|
fb93d8c1af | ||
|
|
f4e6aea9c1 | ||
|
|
65d61cf4b8 | ||
|
|
a8d5214b2f | ||
|
|
f9e5283fc3 | ||
|
|
d49b837abb | ||
|
|
49545c058b | ||
|
|
765340f7b2 | ||
|
|
5a212aaa12 | ||
|
|
2c3d9b11a6 | ||
|
|
79056d8b48 | ||
|
|
b1678eaad3 | ||
|
|
f1c16dba6e | ||
|
|
f86883df88 | ||
|
|
aa1fdf6c2c | ||
|
|
bebf9e1f2b | ||
|
|
2413c10283 | ||
|
|
0f7fbdab97 | ||
|
|
14e5fd63a6 | ||
|
|
2446913836 | ||
|
|
1f88a9f47a | ||
|
|
261e37cda4 | ||
|
|
5ee395ea8e | ||
|
|
e5f00394ae | ||
|
|
dd08aef4cc | ||
|
|
4ab85815a0 | ||
|
|
828633ffc9 | ||
|
|
1b0902079b | ||
|
|
7b7527a5e6 | ||
|
|
f719d47ed3 | ||
|
|
8cc88533b1 | ||
|
|
71de2bd0c5 | ||
|
|
66d204331b | ||
|
|
ee288fbc5f | ||
|
|
620566fa4d | ||
|
|
1a38b5dca3 | ||
|
|
e0bd8cf14b | ||
|
|
4ce8b88d27 | ||
|
|
28d25e46de | ||
|
|
e0cfcafead | ||
|
|
12bc30daa3 | ||
|
|
7b5f00d10e | ||
|
|
58e1485c13 | ||
|
|
1da0ff9109 | ||
|
|
a64f1c4396 | ||
|
|
75a1428114 | ||
|
|
d82d830849 | ||
|
|
2def59fc6c | ||
|
|
64ceb2c6bf | ||
|
|
3ee007620c | ||
|
|
c08230ae95 | ||
|
|
18df8921fd | ||
|
|
b9cf8172a0 | ||
|
|
32edfb4a9f | ||
|
|
848db9b672 | ||
|
|
3766921bcc | ||
|
|
5546052b2c | ||
|
|
c569b56d3d | ||
|
|
52ffa84adb | ||
|
|
b5ae438a8e | ||
|
|
fae05f7af2 | ||
|
|
380d7fc8ce | ||
|
|
94132bbc7f | ||
|
|
d87a9d7c79 | ||
|
|
be7756d4a2 | ||
|
|
ca5e335bff | ||
|
|
b9ed794f2b | ||
|
|
042dc7d27c | ||
|
|
db2df3d5b2 | ||
|
|
0b1cb628f2 | ||
|
|
912d95d153 | ||
|
|
76059f4738 | ||
|
|
011572f3ef | ||
|
|
b727b354dd |
@@ -1,50 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true,
|
||||
"node": true
|
||||
},
|
||||
"ignorePatterns": ["**/dist", "**/build", "**/.next"],
|
||||
"extends": ["react-app", "plugin:react/recommended", "plugin:react-hooks/recommended"],
|
||||
"parserOptions": {
|
||||
// "project": "./tsconfig.json"
|
||||
"project": ["packages/*/tsconfig.json", "examples/*/tsconfig.json"]
|
||||
},
|
||||
"plugins": ["react", "@typescript-eslint", "react-hooks", "simple-import-sort"],
|
||||
"rules": {
|
||||
"no-use-before-define": "off",
|
||||
"simple-import-sort/exports": "error",
|
||||
|
||||
"simple-import-sort/imports": [
|
||||
"error",
|
||||
{
|
||||
"groups": [
|
||||
// Node.js builtins. You could also generate this regex if you use a `.js` config.
|
||||
// For example: `^(${require("module").builtinModules.join("|")})(/|$)`
|
||||
[
|
||||
"^(assert|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|https|module|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|tty|url|util|vm|zlib|freelist|v8|process|async_hooks|http2|perf_hooks)(/.*|$)"
|
||||
],
|
||||
// Packages
|
||||
["^\\w"],
|
||||
// Internal packages.
|
||||
["^(@|config/)(/*|$)"],
|
||||
// Side effect imports.
|
||||
["^\\u0000"],
|
||||
// Parent imports. Put `..` last.
|
||||
["^\\.\\.(?!/?$)", "^\\.\\./?$"],
|
||||
// Other relative imports. Put same-folder imports and `.` last.
|
||||
["^\\./(?=.*/)(?!/?$)", "^\\.(?!/?$)", "^\\./?$"],
|
||||
// Style imports.
|
||||
["^.+\\.s?css$"]
|
||||
]
|
||||
}
|
||||
],
|
||||
"import/no-anonymous-default-export": [
|
||||
"error",
|
||||
{
|
||||
"allowArrowFunction": true,
|
||||
"allowAnonymousFunction": true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
const esbuild = require('esbuild')
|
||||
|
||||
// Automatically exclude all node_modules from the bundled version
|
||||
const { nodeExternalsPlugin } = require('esbuild-node-externals')
|
||||
esbuild
|
||||
.build({
|
||||
entryPoints: ['./src/index.ts'],
|
||||
outfile: 'dist/index.cjs.js',
|
||||
bundle: true,
|
||||
minify: true,
|
||||
platform: 'node',
|
||||
format: 'cjs',
|
||||
sourcemap: true,
|
||||
target: 'node14',
|
||||
plugins: [nodeExternalsPlugin()]
|
||||
})
|
||||
.catch(() => process.exit(1))
|
||||
|
||||
esbuild
|
||||
.build({
|
||||
entryPoints: ['./src/index.ts'],
|
||||
outfile: 'dist/index.es.js',
|
||||
bundle: true,
|
||||
minify: true,
|
||||
platform: 'browser',
|
||||
format: 'esm',
|
||||
sourcemap: true,
|
||||
target: 'es2019'
|
||||
})
|
||||
.catch(() => process.exit(1))
|
||||
@@ -1,7 +0,0 @@
|
||||
const base = require('./jest.config.base.js')
|
||||
|
||||
module.exports = {
|
||||
...base,
|
||||
projects: ['<rootDir>/packages/*/jest.config.js'],
|
||||
coverageDirectory: '<rootDir>/coverage/'
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import dts from 'vite-plugin-dts'
|
||||
import tsconfigPaths from 'vite-tsconfig-paths'
|
||||
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
const PWD = process.env.PWD
|
||||
const pkg = require(path.join(PWD, 'package.json'))
|
||||
|
||||
const tsEntry = path.resolve(PWD, 'src/index.ts')
|
||||
const entry = fs.existsSync(tsEntry) ? tsEntry : tsEntry.replace('.ts', '.tsx')
|
||||
|
||||
/**
|
||||
* @type {import('vite').UserConfig}
|
||||
*/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
tsconfigPaths(),
|
||||
dts({
|
||||
exclude: ['**/*.spec.ts', '**/*.test.ts', '**/tests/**'],
|
||||
afterBuild: () => {
|
||||
const types = fs.readdirSync(path.join(PWD, 'dist/src'))
|
||||
types.forEach((file) => {
|
||||
fs.renameSync(path.join(PWD, 'dist/src', file), path.join(PWD, 'dist', file))
|
||||
})
|
||||
fs.rmdirSync(path.join(PWD, 'dist/src'))
|
||||
}
|
||||
})
|
||||
],
|
||||
build: {
|
||||
lib: {
|
||||
entry,
|
||||
name: pkg.name,
|
||||
fileName: 'index'
|
||||
},
|
||||
rollupOptions: {
|
||||
external: ['react', '@nhost/react'],
|
||||
output: {
|
||||
globals: {
|
||||
react: 'react',
|
||||
'@nhost/react': '@nhost/react'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
1
.github/CODEOWNERS
vendored
1
.github/CODEOWNERS
vendored
@@ -2,6 +2,7 @@
|
||||
# https://help.github.com/en/articles/about-code-owners
|
||||
|
||||
/packages @plmercereau
|
||||
/packages/docgen @szilarddoro
|
||||
/.github/workflows @plmercereau
|
||||
/docs/ @guicurcio
|
||||
/examples/ @plmercereau @guicurcio @FuzzyReason
|
||||
|
||||
1
.github/workflows/changesets.yaml
vendored
1
.github/workflows/changesets.yaml
vendored
@@ -9,6 +9,7 @@ on:
|
||||
- 'examples/**'
|
||||
- 'assets/**'
|
||||
- '**.md'
|
||||
- '!.changeset/**'
|
||||
- 'LICENSE'
|
||||
|
||||
jobs:
|
||||
|
||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -15,11 +15,11 @@ logs/
|
||||
/.vscode/
|
||||
.eslintcache
|
||||
.yarnclean
|
||||
.husky
|
||||
|
||||
# Directories
|
||||
coverage/
|
||||
dist/
|
||||
umd/
|
||||
lib/
|
||||
node_modules/
|
||||
tmp/
|
||||
@@ -33,16 +33,15 @@ tmp/
|
||||
*.map
|
||||
todo.md
|
||||
|
||||
# Generated configs
|
||||
# Config files that are not part of the repository root anymore. Should be removed in the future.
|
||||
/.eslintignore
|
||||
/.eslintrc
|
||||
/.prettierignore
|
||||
/prettier.config.js
|
||||
/.eslintrc*
|
||||
/vite.*.js
|
||||
/jest.*.js
|
||||
/*tsconfig*.json
|
||||
/esbuild.*.js
|
||||
|
||||
!.config/**
|
||||
!config/**
|
||||
|
||||
*.tsbuildinfo
|
||||
|
||||
@@ -50,4 +49,8 @@ todo.md
|
||||
.netlify
|
||||
.monorepo-example
|
||||
|
||||
.next
|
||||
.next
|
||||
|
||||
# TypeDoc output
|
||||
|
||||
.docgen
|
||||
1
.husky/.gitignore
vendored
Normal file
1
.husky/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
_
|
||||
4
.husky/pre-commit
Executable file
4
.husky/pre-commit
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
npx lint-staged
|
||||
6
.lintstagedrc.json
Normal file
6
.lintstagedrc.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"packages/(docgen|hasura-auth-js|hasura-storage-js|nextjs|nhost-js|react|core)/src/**/*.{js,ts,jsx,tsx}": [
|
||||
"pnpm docgen",
|
||||
"git add docs"
|
||||
]
|
||||
}
|
||||
@@ -11,6 +11,11 @@ module.exports = {
|
||||
tabWidth: 2,
|
||||
trailingComma: 'none',
|
||||
useTabs: false,
|
||||
// TODO: add import sort configuration to match ESLint rules
|
||||
// plugins: ['./node_modules/@trivago/prettier-plugin-sort-imports'],
|
||||
// importOrderSeparation: true,
|
||||
// importOrderSortSpecifiers: true
|
||||
plugins: [],
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.json', '*.yaml'],
|
||||
@@ -24,6 +24,8 @@ If you find an Issue that addresses the problem you're having, please add your r
|
||||
|
||||
### Pull Requests
|
||||
|
||||
Please have a look at our [developers guide](https://github.com/nhost/nhost/blob/main/DEVELOPERS.md) to start coding!
|
||||
|
||||
PRs to our libraries are always welcome and can be a quick way to get your fix or improvement slated for the next release. In general, PRs should:
|
||||
|
||||
- Only fix/add the functionality in question **OR** address wide-spread whitespace/style issues, not both.
|
||||
|
||||
98
DEVELOPERS.md
Normal file
98
DEVELOPERS.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Developer guide
|
||||
|
||||
## Requirements
|
||||
|
||||
- We use [pnpm](https://pnpm.io/) as a package manager to speed up development and builds, and as a basis for our monorepo. You need to make sure it's installed on your machine. There are [several ways to install it](https://pnpm.io/installation), but the easiest way is with `npm`:
|
||||
|
||||
```sh
|
||||
$ npm install -g pnpm
|
||||
```
|
||||
|
||||
- Our tests and examples use the Nhost CLI, to run the backend services locally. You can follow the installation instructions in [our documentation](https://docs.nhost.io/get-started/cli-workflow/install-cli).
|
||||
|
||||
## Get started
|
||||
|
||||
### Installation
|
||||
|
||||
First, clone this repository:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/nhost/nhost
|
||||
```
|
||||
|
||||
Then, install the dependencies with `pnpm`:
|
||||
|
||||
```sh
|
||||
$ cd nhost
|
||||
$ pnpm install
|
||||
```
|
||||
|
||||
### Development
|
||||
|
||||
Although package references are correctly updated on the fly for TypeScript, example projects won't
|
||||
see the changes because they are depending on the build output. To fix this, you can run packages
|
||||
in development mode.
|
||||
|
||||
Running packages in development mode is as simple as:
|
||||
|
||||
```sh
|
||||
$ pnpm dev
|
||||
```
|
||||
|
||||
Our packages are linked together using [PNPM's workspace](https://pnpm.io/workspaces) feature. Vite automatically detects changes in the dependencies and rebuilds everything, so that the changes are immediately reflected in the other packages.
|
||||
|
||||
### Use examples
|
||||
|
||||
Examples are a great way to test your changes in practice. Make sure you've `pnpm dev` running in your terminal and then run an example.
|
||||
|
||||
Let's follow the instructions to run [react-apollo example](https://github.com/nhost/nhost/blob/main/examples/react-apollo/README.md).
|
||||
|
||||
## Run the documentation website locally
|
||||
|
||||
The easier way to contribute to our documentation is to go to the `docs` folder and follow the [instructions to start local development](https://github.com/nhost/nhost/blob/main/docs/README.md):
|
||||
|
||||
```sh
|
||||
$ cd docs
|
||||
# not necessary if you've already done this step somewhere in the repository
|
||||
$ pnpm install
|
||||
$ pnpm start
|
||||
```
|
||||
|
||||
## Run test suites
|
||||
|
||||
In order to run tests, the Nhost testing backend should be running locally. You can run it from a separate terminal:
|
||||
|
||||
```sh
|
||||
$ cd examples/testing-project
|
||||
$ nhost -d
|
||||
```
|
||||
|
||||
Once Nhost is started locally, you can run the tests with the following command from the repository root:
|
||||
|
||||
```sh
|
||||
$ pnpm test
|
||||
```
|
||||
|
||||
## Changesets
|
||||
|
||||
If you've made changes to the packages, you must describe those changes so that they can be reflected in the next release.
|
||||
We use [changesets](https://github.com/changesets/changesets) to support our versioning and release workflows. When you submit a pull request, a bot checks if some changesets are present, and if not, it directs you to add them.
|
||||
|
||||
The most comprehensive way to add a changeset is to run the following command in the repository root:
|
||||
|
||||
```sh
|
||||
$ pnpm changeset
|
||||
```
|
||||
|
||||
This will create a file in the `.changeset` directory. You can edit it to give more details about the change you just made.
|
||||
|
||||
You can take a look at the changeset documentation: [How to add a changeset](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).
|
||||
|
||||
## Committing changes
|
||||
|
||||
You'll notice that `git commit` takes a few seconds to run. We set a commit hook that scans the changes in the code, automatically generates documentation from the inline [TSDoc](https://tsdoc.org/) annotations, and adds these generated documentation files to the commit. They automatically update the [reference documentation](https://docs.nhost.io/reference).
|
||||
|
||||
<!-- ## Good practices
|
||||
- lint
|
||||
- prettier
|
||||
- documentation -->
|
||||
94
README.md
94
README.md
@@ -20,7 +20,7 @@
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
**Nhost is a open-source GraphQL backend,** built with the following things in mind:
|
||||
**Nhost is an open-source GraphQL backend,** built with the following things in mind:
|
||||
|
||||
- Open-Source
|
||||
- Developer Productivity
|
||||
@@ -98,7 +98,7 @@ Nhost is frontend agnostic, which means Nhost works with all frontend frameworks
|
||||
|
||||
Nhost libraries and tools
|
||||
|
||||
- [JavaScript/TypeScript SDK](https://docs.nhost.io/reference/sdk)
|
||||
- [JavaScript/TypeScript SDK](https://docs.nhost.io/reference/javascript)
|
||||
- [Dart and Flutter SDK](https://github.com/nhost/nhost-dart)
|
||||
- [Nhost CLI](https://docs.nhost.io/reference/cli)
|
||||
- [Nhost React](https://docs.nhost.io/reference/react)
|
||||
@@ -120,7 +120,7 @@ Here are some ways of contributing to making Nhost better:
|
||||
|
||||
- **[Try out Nhost](https://docs.nhost.io/get-started/quick-start)**, and think of ways to make the service better. Let us know here on GitHub.
|
||||
- Join our [Discord](https://discord.com/invite/9V7Qb2U) and connect with other members to share and learn from.
|
||||
- Send a pull request to any of our [open source repositories](https://github.com/nhost) on Github. Check our [contribution guide](https://github.com/nhost/nhost/blob/main/CONTRIBUTING.md) for more details about how to contribute. We're looking forward to your contribution!
|
||||
- Send a pull request to any of our [open source repositories](https://github.com/nhost) on Github. Check our [contribution guide](https://github.com/nhost/nhost/blob/main/CONTRIBUTING.md) and our [developers guide](https://github.com/nhost/nhost/blob/main/DEVELOPERS.md) for more details about how to contribute. We're looking forward to your contribution!
|
||||
|
||||
### Contributors
|
||||
|
||||
@@ -134,6 +134,13 @@ Here are some ways of contributing to making Nhost better:
|
||||
<sub><b>Pilou</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/szilarddoro">
|
||||
<img src="https://avatars.githubusercontent.com/u/310881?v=4" width="100;" alt="szilarddoro"/>
|
||||
<br />
|
||||
<sub><b>Szilárd Dóró</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/elitan">
|
||||
<img src="https://avatars.githubusercontent.com/u/331818?v=4" width="100;" alt="elitan"/>
|
||||
@@ -142,10 +149,10 @@ Here are some ways of contributing to making Nhost better:
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/szilarddoro">
|
||||
<img src="https://avatars.githubusercontent.com/u/310881?v=4" width="100;" alt="szilarddoro"/>
|
||||
<a href="https://github.com/gdangelo">
|
||||
<img src="https://avatars.githubusercontent.com/u/4352286?v=4" width="100;" alt="gdangelo"/>
|
||||
<br />
|
||||
<sub><b>Szilárd Dóró</b></sub>
|
||||
<sub><b>Grégory D'Angelo</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
@@ -161,15 +168,15 @@ Here are some ways of contributing to making Nhost better:
|
||||
<br />
|
||||
<sub><b>Subha Das</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/guicurcio">
|
||||
<img src="https://avatars.githubusercontent.com/u/20285232?v=4" width="100;" alt="guicurcio"/>
|
||||
<br />
|
||||
<sub><b>Guido Curcio</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/sebagudelo">
|
||||
<img src="https://avatars.githubusercontent.com/u/43288271?v=4" width="100;" alt="sebagudelo"/>
|
||||
@@ -184,13 +191,6 @@ Here are some ways of contributing to making Nhost better:
|
||||
<sub><b>Mrinal Wahal</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/gdangelo">
|
||||
<img src="https://avatars.githubusercontent.com/u/4352286?v=4" width="100;" alt="gdangelo"/>
|
||||
<br />
|
||||
<sub><b>Grégory D'Angelo</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/FuzzyReason">
|
||||
<img src="https://avatars.githubusercontent.com/u/62517920?v=4" width="100;" alt="FuzzyReason"/>
|
||||
@@ -213,6 +213,13 @@ Here are some ways of contributing to making Nhost better:
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/dbarrosop">
|
||||
<img src="https://avatars.githubusercontent.com/u/6246622?v=4" width="100;" alt="dbarrosop"/>
|
||||
<br />
|
||||
<sub><b>David Barroso</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/hajek-raven">
|
||||
<img src="https://avatars.githubusercontent.com/u/7288737?v=4" width="100;" alt="hajek-raven"/>
|
||||
@@ -220,6 +227,13 @@ Here are some ways of contributing to making Nhost better:
|
||||
<sub><b>Filip Hájek</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/GavanWilhite">
|
||||
<img src="https://avatars.githubusercontent.com/u/2085119?v=4" width="100;" alt="GavanWilhite"/>
|
||||
<br />
|
||||
<sub><b>Gavan Wilhite</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/jerryjappinen">
|
||||
<img src="https://avatars.githubusercontent.com/u/1101002?v=4" width="100;" alt="jerryjappinen"/>
|
||||
@@ -234,6 +248,14 @@ Here are some ways of contributing to making Nhost better:
|
||||
<sub><b>Mustafa Hanif</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/timpratim">
|
||||
<img src="https://avatars.githubusercontent.com/u/32492961?v=4" width="100;" alt="timpratim"/>
|
||||
<br />
|
||||
<sub><b>Pratim</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Savinvadim1312">
|
||||
<img src="https://avatars.githubusercontent.com/u/16936043?v=4" width="100;" alt="Savinvadim1312"/>
|
||||
@@ -254,8 +276,14 @@ Here are some ways of contributing to making Nhost better:
|
||||
<br />
|
||||
<sub><b>Anders Kjær Damgaard</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/heygambo">
|
||||
<img src="https://avatars.githubusercontent.com/u/449438?v=4" width="100;" alt="heygambo"/>
|
||||
<br />
|
||||
<sub><b>Christian Gambardella</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/rustyb">
|
||||
<img src="https://avatars.githubusercontent.com/u/53086?v=4" width="100;" alt="rustyb"/>
|
||||
@@ -269,12 +297,13 @@ Here are some ways of contributing to making Nhost better:
|
||||
<br />
|
||||
<sub><b>Dominic Garms</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/GavanWilhite">
|
||||
<img src="https://avatars.githubusercontent.com/u/2085119?v=4" width="100;" alt="GavanWilhite"/>
|
||||
<a href="https://github.com/gaurav1999">
|
||||
<img src="https://avatars.githubusercontent.com/u/20752142?v=4" width="100;" alt="gaurav1999"/>
|
||||
<br />
|
||||
<sub><b>Gavan Wilhite</b></sub>
|
||||
<sub><b>Gaurav Agrawal</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
@@ -291,6 +320,20 @@ Here are some ways of contributing to making Nhost better:
|
||||
<sub><b>Hoang Do</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/jladuval">
|
||||
<img src="https://avatars.githubusercontent.com/u/1935359?v=4" width="100;" alt="jladuval"/>
|
||||
<br />
|
||||
<sub><b>Jacob Duval</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/MarcelloTheArcane">
|
||||
<img src="https://avatars.githubusercontent.com/u/21159570?v=4" width="100;" alt="MarcelloTheArcane"/>
|
||||
<br />
|
||||
<sub><b>Max Reynolds</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/ghoshnirmalya">
|
||||
<img src="https://avatars.githubusercontent.com/u/6391763?v=4" width="100;" alt="ghoshnirmalya"/>
|
||||
@@ -299,13 +342,6 @@ Here are some ways of contributing to making Nhost better:
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/timpratim">
|
||||
<img src="https://avatars.githubusercontent.com/u/32492961?v=4" width="100;" alt="timpratim"/>
|
||||
<br />
|
||||
<sub><b>Pratim</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/quentin-decre">
|
||||
<img src="https://avatars.githubusercontent.com/u/1137511?v=4" width="100;" alt="quentin-decre"/>
|
||||
|
||||
65
config/.eslintrc.js
Normal file
65
config/.eslintrc.js
Normal file
@@ -0,0 +1,65 @@
|
||||
module.exports = {
|
||||
env: {
|
||||
browser: true,
|
||||
es6: true,
|
||||
node: true
|
||||
},
|
||||
ignorePatterns: [
|
||||
'dist',
|
||||
'umd',
|
||||
'build',
|
||||
'.next',
|
||||
'node_modules',
|
||||
'tsup.config.ts',
|
||||
'__tests__',
|
||||
'__mocks__',
|
||||
'*.test.ts',
|
||||
'*.test.tsx',
|
||||
'*.spec.ts',
|
||||
'*.spec.tsx',
|
||||
'tests/**/*.ts',
|
||||
'tests/**/*.d.ts'
|
||||
],
|
||||
extends: ['react-app', 'plugin:react/recommended', 'plugin:react-hooks/recommended'],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020,
|
||||
sourceType: 'module'
|
||||
},
|
||||
plugins: ['react', '@typescript-eslint', 'react-hooks', 'simple-import-sort'],
|
||||
rules: {
|
||||
'react/prop-types': 'off',
|
||||
'no-use-before-define': 'off',
|
||||
'simple-import-sort/exports': 'error',
|
||||
'simple-import-sort/imports': [
|
||||
'error',
|
||||
{
|
||||
groups: [
|
||||
// Node.js builtins. You could also generate this regex if you use a `.js` config.
|
||||
// For example: `^(${require("module").builtinModules.join("|")})(/|$)`
|
||||
[
|
||||
'^(assert|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|https|module|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|tty|url|util|vm|zlib|freelist|v8|process|async_hooks|http2|perf_hooks)(/.*|$)'
|
||||
],
|
||||
// Packages
|
||||
['^\\w'],
|
||||
// Internal packages.
|
||||
['^(@|config/)(/*|$)'],
|
||||
// Side effect imports.
|
||||
['^\\u0000'],
|
||||
// Parent imports. Put `..` last.
|
||||
['^\\.\\.(?!/?$)', '^\\.\\./?$'],
|
||||
// Other relative imports. Put same-folder imports and `.` last.
|
||||
['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'],
|
||||
// Style imports.
|
||||
['^.+\\.s?css$']
|
||||
]
|
||||
}
|
||||
],
|
||||
'import/no-anonymous-default-export': [
|
||||
'error',
|
||||
{
|
||||
allowArrowFunction: true,
|
||||
allowAnonymousFunction: true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ module.exports = {
|
||||
testRegex: '(/tests/.*.(test|spec)).(jsx?|tsx?)$',
|
||||
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
|
||||
collectCoverage: true,
|
||||
// coveragePathIgnorePatterns: ['(tests/.*.mock).(jsx?|tsx?)$'],
|
||||
verbose: true,
|
||||
testTimeout: 30000,
|
||||
globals: {
|
||||
15
config/jest.config.js
Normal file
15
config/jest.config.js
Normal file
@@ -0,0 +1,15 @@
|
||||
module.exports = {
|
||||
rootDir: process.cwd(),
|
||||
preset: 'ts-jest',
|
||||
collectCoverage: true,
|
||||
coverageProvider: 'v8',
|
||||
coverageDirectory: '<rootDir>/coverage',
|
||||
clearMocks: true,
|
||||
verbose: true,
|
||||
testTimeout: 30000,
|
||||
globals: {
|
||||
'ts-jest': {
|
||||
isolatedModules: true
|
||||
}
|
||||
}
|
||||
}
|
||||
8
config/react-library.tsconfig.json
Normal file
8
config/react-library.tsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"display": "React Library",
|
||||
"extends": "./tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "preserve"
|
||||
}
|
||||
}
|
||||
56
config/tsconfig.base.json
Normal file
56
config/tsconfig.base.json
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"display": "Default",
|
||||
"compilerOptions": {
|
||||
"composite": false,
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"strict": true,
|
||||
"isolatedModules": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"skipLibCheck": true,
|
||||
"moduleResolution": "node",
|
||||
"target": "ES6",
|
||||
"module": "CommonJS",
|
||||
"lib": [
|
||||
"es5",
|
||||
"dom",
|
||||
"es2015.promise",
|
||||
"es2015.symbol",
|
||||
"es2015.iterable",
|
||||
"es2015.collection",
|
||||
"es2015.symbol.wellknown",
|
||||
"es2015.core",
|
||||
"es2017.object",
|
||||
"es2017.string"
|
||||
],
|
||||
"resolveJsonModule": true,
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": true,
|
||||
"types": ["node"],
|
||||
"typeRoots": [
|
||||
"./node_modules/@types", "**/*/dist", "**/*/build", "**/*/.next", "**/*/umd"
|
||||
],
|
||||
"paths": {
|
||||
"@nhost/apollo": ["../packages/apollo/src/index.ts"],
|
||||
"@nhost/core": ["../packages/core/src/index.ts"],
|
||||
"@nhost/docgen": ["../packages/docgen/src/index.ts"],
|
||||
"@nhost/hasura-auth-js": ["../packages/hasura-auth-js/src/index.ts"],
|
||||
"@nhost/hasura-storage-js": ["../packages/hasura-storage-js/src/index.ts"],
|
||||
"@nhost/nextjs": ["../packages/nextjs/src/index.ts"],
|
||||
"@nhost/nhost-js": ["../packages/nhost-js/src/index.ts"],
|
||||
"@nhost/react": ["../packages/react/src/index.ts"],
|
||||
"@nhost/react-apollo": ["../packages/react-apollo/src/index.ts"],
|
||||
"@nhost/react-auth": ["../packages/react-auth/src/index.ts"]
|
||||
}
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"**/*/dist",
|
||||
"**/*/build",
|
||||
"**/*/.next",
|
||||
"**/*/__tests__",
|
||||
"**/*/__mocks__"
|
||||
]
|
||||
}
|
||||
71
config/vite.lib.config.js
Normal file
71
config/vite.lib.config.js
Normal file
@@ -0,0 +1,71 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import dts from 'vite-plugin-dts'
|
||||
import tsconfigPaths from 'vite-tsconfig-paths'
|
||||
|
||||
const PWD = process.env.PWD
|
||||
const pkg = require(path.join(PWD, 'package.json'))
|
||||
|
||||
const tsEntry = path.resolve(PWD, 'src/index.ts')
|
||||
const entry = fs.existsSync(tsEntry) ? tsEntry : tsEntry.replace('.ts', '.tsx')
|
||||
|
||||
const deps = [...Object.keys(Object.assign({}, pkg.peerDependencies, pkg.dependencies))]
|
||||
|
||||
export default defineConfig({
|
||||
optimizeDeps: {
|
||||
include: ['react/jsx-runtime']
|
||||
},
|
||||
plugins: [
|
||||
tsconfigPaths(),
|
||||
dts({
|
||||
exclude: ['**/*.spec.ts', '**/*.test.ts', '**/tests/**'],
|
||||
afterBuild: () => {
|
||||
const types = fs.readdirSync(path.join(PWD, 'dist/src'))
|
||||
types.forEach((file) => {
|
||||
fs.renameSync(path.join(PWD, 'dist/src', file), path.join(PWD, 'dist', file))
|
||||
})
|
||||
fs.rmdirSync(path.join(PWD, 'dist/src'))
|
||||
}
|
||||
})
|
||||
],
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
reporters: 'verbose',
|
||||
include: [`${PWD}/src/**/*.{spec,test}.{ts,tsx}`, `${PWD}/tests/**/*.{spec,test}.{ts,tsx}`],
|
||||
// Note: temporarily disabled threads, because of a bug in vitest
|
||||
// https://github.com/vitest-dev/vitest/issues/1171
|
||||
threads: false
|
||||
},
|
||||
build: {
|
||||
sourcemap: true,
|
||||
lib: {
|
||||
entry,
|
||||
name: pkg.name,
|
||||
fileName: 'index',
|
||||
formats: ['cjs', 'es']
|
||||
},
|
||||
rollupOptions: {
|
||||
external: (id) => deps.some((dep) => id.startsWith(dep)),
|
||||
output: {
|
||||
globals: {
|
||||
'graphql/language/printer': 'graphql/language/printer',
|
||||
'@apollo/client': '@apollo/client',
|
||||
'@apollo/client/link/context': '@apollo/client/link/context',
|
||||
'@apollo/client/link/subscriptions': '@apollo/client/link/subscriptions',
|
||||
'@apollo/client/utilities': '@apollo/client/utilities',
|
||||
'graphql-ws': 'graphql-ws',
|
||||
xstate: 'xstate',
|
||||
axios: 'axios',
|
||||
'js-cookie': 'Cookies',
|
||||
react: 'React',
|
||||
'react-dom': 'ReactDOM',
|
||||
'react/jsx-runtime': '_jsx',
|
||||
'@nhost/react': '@nhost/react'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
13
config/vite.lib.dev.config.js
Normal file
13
config/vite.lib.dev.config.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
import viteLibConfig from './vite.lib.config'
|
||||
|
||||
export default defineConfig({
|
||||
...viteLibConfig,
|
||||
build: {
|
||||
...viteLibConfig.build,
|
||||
watch: {
|
||||
buildDelay: 500
|
||||
}
|
||||
}
|
||||
})
|
||||
42
config/vite.lib.umd.config.js
Normal file
42
config/vite.lib.umd.config.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import dts from 'vite-plugin-dts'
|
||||
import tsconfigPaths from 'vite-tsconfig-paths'
|
||||
|
||||
import baseLibConfig from './vite.lib.config'
|
||||
|
||||
const PWD = process.env.PWD
|
||||
const pkg = require(path.join(PWD, 'package.json'))
|
||||
|
||||
const deps = [...Object.keys(Object.assign({}, pkg.peerDependencies))]
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
tsconfigPaths(),
|
||||
dts({
|
||||
exclude: ['**/*.spec.ts', '**/*.test.ts', '**/tests/**'],
|
||||
afterBuild: () => {
|
||||
const types = fs.readdirSync(path.join(PWD, 'umd/src'))
|
||||
types.forEach((file) => {
|
||||
fs.renameSync(path.join(PWD, 'umd/src', file), path.join(PWD, 'umd', file))
|
||||
})
|
||||
fs.rmdirSync(path.join(PWD, 'umd/src'))
|
||||
}
|
||||
})
|
||||
],
|
||||
build: {
|
||||
...(baseLibConfig.build || {}),
|
||||
outDir: 'umd',
|
||||
lib: {
|
||||
...(baseLibConfig.build?.lib || {}),
|
||||
fileName: pkg.name.replace(/@nhost\//g, ''),
|
||||
formats: ['umd']
|
||||
},
|
||||
rollupOptions: {
|
||||
...(baseLibConfig.build?.rollupOptions || {}),
|
||||
external: (id) => deps.some((dep) => id.startsWith(dep))
|
||||
}
|
||||
}
|
||||
})
|
||||
10
config/vite.react.config.js
Normal file
10
config/vite.react.config.js
Normal file
@@ -0,0 +1,10 @@
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
import baseLibConfig from './vite.lib.config'
|
||||
|
||||
export default defineConfig({
|
||||
...baseLibConfig,
|
||||
plugins: [react(), ...baseLibConfig.plugins]
|
||||
})
|
||||
13
config/vite.react.dev.config.js
Normal file
13
config/vite.react.dev.config.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import { defineConfig } from 'vite'
|
||||
|
||||
import viteReactConfig from './vite.react.config'
|
||||
|
||||
export default defineConfig({
|
||||
...viteReactConfig,
|
||||
build: {
|
||||
...viteReactConfig.build,
|
||||
watch: {
|
||||
buildDelay: 500
|
||||
}
|
||||
}
|
||||
})
|
||||
45
config/vite.react.umd.config.js
Normal file
45
config/vite.react.umd.config.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import dts from 'vite-plugin-dts'
|
||||
import tsconfigPaths from 'vite-tsconfig-paths'
|
||||
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
import baseLibConfig from './vite.lib.config'
|
||||
|
||||
const PWD = process.env.PWD
|
||||
const pkg = require(path.join(PWD, 'package.json'))
|
||||
|
||||
const deps = [...Object.keys(Object.assign({}, pkg.peerDependencies))]
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
react(),
|
||||
tsconfigPaths(),
|
||||
dts({
|
||||
exclude: ['**/*.spec.ts', '**/*.test.ts', '**/tests/**'],
|
||||
afterBuild: () => {
|
||||
const types = fs.readdirSync(path.join(PWD, 'umd/src'))
|
||||
types.forEach((file) => {
|
||||
fs.renameSync(path.join(PWD, 'umd/src', file), path.join(PWD, 'umd', file))
|
||||
})
|
||||
fs.rmdirSync(path.join(PWD, 'umd/src'))
|
||||
}
|
||||
})
|
||||
],
|
||||
build: {
|
||||
...(baseLibConfig.build || {}),
|
||||
outDir: 'umd',
|
||||
lib: {
|
||||
...(baseLibConfig.build?.lib || {}),
|
||||
fileName: pkg.name.replace(/@nhost\//g, ''),
|
||||
formats: ['umd']
|
||||
},
|
||||
rollupOptions: {
|
||||
...(baseLibConfig.build?.rollupOptions || {}),
|
||||
external: (id) => deps.some((dep) => id.startsWith(dep))
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -1,11 +0,0 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"printWidth": 80,
|
||||
"tabWidth": 2,
|
||||
"useTabs": false,
|
||||
"trailingComma": "all",
|
||||
"bracketSpacing": true,
|
||||
"bracketSameLine": false,
|
||||
"endOfLine": "auto",
|
||||
"semi": true
|
||||
}
|
||||
9
docs/CHANGELOG.md
Normal file
9
docs/CHANGELOG.md
Normal file
@@ -0,0 +1,9 @@
|
||||
# @nhost/docs
|
||||
|
||||
## 0.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 584976d: - publishable directory structure changes (ESM, CJS and UMD included in the output)
|
||||
- build system improvements
|
||||
- fixed some bundling concerns (https://github.com/nhost/nhost/issues/428)
|
||||
@@ -3,7 +3,7 @@ title: 'Authenticate users'
|
||||
slug: /get-started/authentication
|
||||
---
|
||||
|
||||
You defined `select` permissions for the `public` role in the previous section. You will now add `insert` and `create` permissions for authenticated users to secure your app's GraphQL API with authentication.
|
||||
In the previous section, you defined `select` permissions for the `public` role. You will now add `insert` and `select` permissions for authenticated users to secure your app's GraphQL API with authentication.
|
||||
|
||||
> Nhost's authentication service lets you deliver frictionless registration and login experiences to your users. We support most social providers and different methods such as email & password and passwordless (magic link).
|
||||
|
||||
@@ -13,13 +13,15 @@ You defined `select` permissions for the `public` role in the previous section.
|
||||
|
||||
Manually create a user by going to your app's **Users** tab (top menu) and clicking on **Add User**.
|
||||
|
||||

|
||||
<video width="99%" loop="" muted="" playsInline="" controls="true">
|
||||
<source src="/videos/add-user.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
You will now use that newly created user to make authenticated requests to the API.
|
||||
You will now use that newly created user. We'll use this newly created user to make authenticated requests to the GraphQL API.
|
||||
|
||||
---
|
||||
|
||||
## Authenticate and query data
|
||||
## Sign in and query data
|
||||
|
||||
Add the following code to sign in the new user and request the list of todos again:
|
||||
|
||||
@@ -60,9 +62,41 @@ Why is the return value `null`? Because when making GraphQL requests as an authe
|
||||
|
||||
> For authenticated requests, there is always the option to override the default `user` role with any other valid role.
|
||||
|
||||
---
|
||||
To prepare our database and GraphQL API to work for signed-in users we need to do two things:
|
||||
|
||||
## Permissions for users
|
||||
1. Add a `user_id` column to the `todos` table, so we know what todo belongs to which user.
|
||||
2. Use the `user` role instead of the `public` role for permissions.
|
||||
|
||||
## Add `user_id` column
|
||||
|
||||
Before adding the `user_id` column, let's delete all existing todos.
|
||||
|
||||
Then add the `user_id` column as a `UUID` type. Make sure that `nullable` is **not** checked. This will ensure that all todos must have a `user_id` value.
|
||||
|
||||
At last, we'll create a connection between the `todos` table and the `users` table. For that, we need to do yet another two things:
|
||||
|
||||
1. Create a Foreign Key (FK) between `todos` and `auth.users.id`.
|
||||
2. Let Hasura track the relationship between the two tables.
|
||||
|
||||
<video width="99%" loop="" muted="" playsInline="" controls="true">
|
||||
<source src="/videos/user-id-column.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
### Create FK
|
||||
|
||||
Create a FK between the `auth.users.id` column and the `public.todos.user_id` column. See video above.
|
||||
|
||||
### Track relationship
|
||||
|
||||
Click on the `public` schema and track the untracked foreign key relationship. Then click on the `auth` schema and track the relationship again. See video above.
|
||||
|
||||
We track these relationships to create the GrpahQL relationships between the `todos` table to the `users` table and the `users` table to the `todos` table.
|
||||
|
||||
Ok, our `user_id` column is added and connected correctly. Let's continue with setting permissions for signed-in users.
|
||||
|
||||
## Permissions for signed-in users
|
||||
|
||||
Let us organize the permissions so it works for signed in users too.
|
||||
|
||||
### Remove permissions for the public role
|
||||
|
||||
@@ -72,7 +106,7 @@ We won't use the `public` role anymore, so let's remove all permission for that
|
||||
|
||||
Now we'll add permissions for the `user` role.
|
||||
|
||||
> All logged-in users have the `user` role.
|
||||
> Signed-in users use the `user` role by default
|
||||
|
||||
### Insert permission
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
title: 'Metadata and Serverless Functions'
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
In the previous section, we only created a new table; `customers`. Using the CLI you can also do changes to other parts of your backend.
|
||||
|
||||
There are three things the CLI and the GitHub integration track and applies to production:
|
||||
@@ -73,20 +76,25 @@ Serverless functions are placed in the `functions/` folder of your repository. E
|
||||
|
||||
Before we create our serverless function we'll install `express`, which is a requirement for serverless functions to work.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
npm install express
|
||||
# or with yarn
|
||||
yarn add express
|
||||
npm install -d @types/node @types/express
|
||||
```
|
||||
|
||||
We'll use TypeScript so we'll install two type definitions too:
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
npm install -d @types/node @types/express
|
||||
# or with yarn
|
||||
yarn add express
|
||||
yarn add -D @types/node @types/express
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Then we'll create a file `functions/time.ts`
|
||||
|
||||
In the file `time.ts` we'll add the following code to create our serverless function:
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
title: 'JavaScript client'
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
In the previous section, you used the Hasura Console to fetch a list of todos. Now, you will write a small JavaScript client to interact and retrieve todos from your Nhost app.
|
||||
|
||||
### Frontend frameworks
|
||||
@@ -14,40 +17,36 @@ In this guide, we'll keep the example simple. We're not using a frontend framewo
|
||||
|
||||
## Setup
|
||||
|
||||
> Make sure you have [Node.js](https://nodejs.org) and [npm](https://docs.npmjs.com/getting-started) installed.
|
||||
:::info
|
||||
|
||||
Create a new folder called `nhost-todos`, and initialize a new JavaScript app there:
|
||||
Make sure you have [Node.js](https://nodejs.org) and [npm](https://docs.npmjs.com/getting-started) or [Yarn](https://classic.yarnpkg.com/lang/en/docs/install) installed.
|
||||
|
||||
Using npm package manager
|
||||
:::
|
||||
|
||||
Create a new folder called `nhost-todos`, initialize a new JavaScript app there, and install the Nhost JavaScript SDK:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
npm init -y
|
||||
npm install @nhost/nhost-js graphql
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
Using Yarn package manager
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
yarn init -y
|
||||
yarn add @nhost/nhost-js graphql
|
||||
```
|
||||
|
||||
> You might have to edit the `package.json` file and add/change the `type` object to `module` (`"type": "module"`).
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Install Nhost JavaScript SDK:
|
||||
|
||||
Using npm package manager
|
||||
|
||||
```bash
|
||||
npm install @nhost/nhost-js
|
||||
```
|
||||
|
||||
or
|
||||
Using Yarn package manager
|
||||
|
||||
```bash
|
||||
yarn add @nhost/nhost-js
|
||||
```
|
||||
:::caution attention
|
||||
You might have to edit the `package.json` file and add/change the `type` object to `module` (`"type": "module"`).
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
title: 'Set permissions'
|
||||
---
|
||||
|
||||
In the previous section, you could fetch the todos because the **admin** role is enabled by default when using Hasura Console. When building your applications, you want to define permissions using **roles** that your users can assume when making requests.
|
||||
While using the Hasura Console, you could fetch the todos because the **admin** role is enabled by default but when building your applications with a client, you want to define permissions using **roles** that your users can assume when making requests.
|
||||
|
||||
Hasura supports role-based access control. You create rules for each role, table, and operation (select, insert, update and delete) that can check dynamic session variables, like user ID.
|
||||
|
||||
|
||||
@@ -65,7 +65,9 @@ This is all we need! A new table will be created when you click **Add Table**.
|
||||
|
||||
Go to the **Insert Row** tab to add some data to your database.
|
||||
|
||||

|
||||
<video width="99%" loop="" muted="" playsInline="" controls="true">
|
||||
<source src="/videos/insert-todos.mp4" type="video/mp4" />
|
||||
</video>
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"label": "The Nhost Platform",
|
||||
"position": 1,
|
||||
"link": { "type": "generated-index", "slug": "/platform" }
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
{
|
||||
"label": "Authentication",
|
||||
"position": 4,
|
||||
"link": { "id": "platform/authentication/index", "type": "doc" }
|
||||
"position": 6
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ Nhost provides a ready-to-use authentication service, integrated with Nhost Java
|
||||
|
||||
## Getting Started
|
||||
|
||||
Sign up a user with the [Nhost JavaScript SDK](/reference/sdk):
|
||||
Sign up a user with the [Nhost JavaScript SDK](/reference/javascript):
|
||||
|
||||
```js
|
||||
import { NhostClient } from '@nhost/nhost-js';
|
||||
@@ -48,7 +48,7 @@ query {
|
||||
|
||||
Nhost authentication uses two tokens: Access tokens and refresh tokens.
|
||||
|
||||
[Nhost JavaScript SDK](/reference/sdk) automatically handles access and refresh tokens.
|
||||
[Nhost JavaScript SDK](/reference/javascript) automatically handles access and refresh tokens.
|
||||
|
||||
### Access tokens
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ To make sure we can fetch all user data (email, profile picture and name). For t
|
||||
|
||||
## Sign In users in your app
|
||||
|
||||
Use the [Nhost JavaScript client](/reference/sdk) to sign in users in your app:
|
||||
Use the [Nhost JavaScript client](/reference/javascript) to sign in users in your app:
|
||||
|
||||
```js
|
||||
nhost.auth.signIn({
|
||||
|
||||
@@ -43,7 +43,7 @@ Follow this guide to sign in users with GitHub with your Nhost App.
|
||||
|
||||
## Sign In users in your app
|
||||
|
||||
Use the [Nhost JavaScript client](/reference/sdk) to sign in users in your app:
|
||||
Use the [Nhost JavaScript client](/reference/javascript) to sign in users in your app:
|
||||
|
||||
```js
|
||||
nhost.auth.signIn({
|
||||
|
||||
@@ -23,7 +23,7 @@ You need to set client ID and client secret for each provider that you want to e
|
||||
|
||||
## Implementing sign-in experience
|
||||
|
||||
Use the [Nhost JavaScript SDK](/reference/sdk) and the `signIn()` method to implement social sign-in in your app,
|
||||
Use the [Nhost JavaScript SDK](/reference/javascript) and the `signIn()` method to implement social sign-in in your app,
|
||||
|
||||
Here's an example of how to implement sign-in with GitHub:
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ Follow this guide to sign in users with LinkedIn with your Nhost App.
|
||||
|
||||
## Sign In users in your app
|
||||
|
||||
Use the [Nhost JavaScript client](/reference/sdk) to sign in users in your app:
|
||||
Use the [Nhost JavaScript client](/reference/javascript) to sign in users in your app:
|
||||
|
||||
```js
|
||||
nhost.auth.signIn({
|
||||
|
||||
@@ -43,7 +43,7 @@ Follow this guide to sign in users with Spotify with your Nhost App.
|
||||
|
||||
## Sign In users in your app
|
||||
|
||||
Use the [Nhost JavaScript client](/reference/sdk) to sign in users in your app:
|
||||
Use the [Nhost JavaScript client](/reference/javascript) to sign in users in your app:
|
||||
|
||||
```js
|
||||
nhost.auth.signIn({
|
||||
|
||||
@@ -17,6 +17,7 @@ query {
|
||||
id
|
||||
displayName
|
||||
email
|
||||
metadata
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -29,6 +30,7 @@ query {
|
||||
id
|
||||
displayName
|
||||
email
|
||||
metadata
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -85,3 +87,8 @@ await nhost.graphql.request(
|
||||
```
|
||||
|
||||
If the request is not part of the user's roles, the request will fail.
|
||||
|
||||
---
|
||||
## Metadata
|
||||
|
||||
Custom additional user information stored in the `metadata` column. Can be any JSON object.
|
||||
|
||||
80
docs/docs/platform/cli.mdx
Normal file
80
docs/docs/platform/cli.mdx
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: 'CLI'
|
||||
sidebar_position: 11
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs'
|
||||
import TabItem from '@theme/TabItem'
|
||||
|
||||
Nhost CLI, or `nhost`, is a command-line interface that lets you run and manage Nhost apps locally on Mac, Linux and Windows (WSL2).
|
||||
|
||||
This means you get a full-featured Nhost app running locally on your machine:
|
||||
|
||||
- Postgres Database
|
||||
- Hasura GraphQL API
|
||||
- Hasura Console
|
||||
- Auth
|
||||
- Storage
|
||||
- Serverless Functions
|
||||
|
||||
This way, you can develop and test local changes before you deploy them live. The CLI automatically tracks:
|
||||
|
||||
- Postgres database migrations
|
||||
- Hasura metadata
|
||||
- Serverless functions
|
||||
|
||||
It's recommended to commit and push changes to GitHub and use the [GitHub integration](/platform/github-integration) for Nhost to automatically deploy those changes live.
|
||||
|
||||
## Installation
|
||||
|
||||
To download and install Nhost CLI, run the following command:
|
||||
|
||||
```bash
|
||||
sudo curl -L https://raw.githubusercontent.com/nhost/cli/main/get.sh | bash
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
The following dependencies are required:
|
||||
|
||||
- [Git](https://git-scm.com/downloads)
|
||||
- [Docker](https://www.docker.com/get-started) (must be running while using the CLI)
|
||||
|
||||
## Get started
|
||||
|
||||
Start by authenticating yourself to Nhost Cloud:
|
||||
|
||||
```
|
||||
nhost login
|
||||
```
|
||||
|
||||
Once signed in, you can list all your Nhost apps using:
|
||||
|
||||
```
|
||||
nhost list
|
||||
```
|
||||
|
||||
Let's start by initializing a remote Nhost app locally with the following command:
|
||||
|
||||
```
|
||||
nhost init --remote
|
||||
```
|
||||
|
||||
Pick a Nhost app to use then change the directory once the app initialization is completed:
|
||||
|
||||
```
|
||||
cd my_test_app
|
||||
```
|
||||
|
||||
Then start the Nhost app locally:
|
||||
|
||||
```
|
||||
nhost up
|
||||
```
|
||||
|
||||
Hasura Console starts automatically and your Nhost app is running locally with the backend URL: `http://localhost:1337`.
|
||||
|
||||
## What's next?
|
||||
|
||||
- Read our in-depth guide on [Get started with Nhost CLI](/platform/overview/get-started-with-nhost-cli)
|
||||
- [CLI commands reference](/reference/cli)
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"label": "Database",
|
||||
"position": 2
|
||||
"position": 4
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ Event triggers are managed in Hasura. Go to Hasura, then select **Events** in th
|
||||
|
||||

|
||||
|
||||
Nhost's [environment variables](/platform/nhost/environment-variables) can be used in event trigger headers. For example, you can attach `NHOST_WEBHOOK_SECRET` to an outgoing webhook here.
|
||||
Nhost's [environment variables](/platform/environment-variables) can be used in event trigger headers. For example, you can attach `NHOST_WEBHOOK_SECRET` to an outgoing webhook here.
|
||||
|
||||
---
|
||||
|
||||
@@ -29,6 +29,10 @@ https://[app-subdomain].nhost.run/v1/functions/my-endpoint
|
||||
|
||||
The environment variable `NHOST_BACKEND_URL` will have the correct value.
|
||||
|
||||
```bash
|
||||
{{NHOST_BACKEND_URL}}/v1/functions/my-endpoint
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Security
|
||||
@@ -39,7 +43,7 @@ In your serverless function, you need to make sure the request actually comes fr
|
||||
- Check the header in the serverless function. It should match the environment variable `NHOST_WEBHOOK_SECRET`.
|
||||
|
||||
```js
|
||||
export default function async handler(req, res) {
|
||||
export default async function handler(req, res) {
|
||||
|
||||
// Check webhook secret to make sure the request is valid
|
||||
if (
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: 'Environment variables'
|
||||
sidebar_position: 1
|
||||
sidebar_position: 9
|
||||
---
|
||||
|
||||
Environment variables are key-value pairs configured outside your source code. They are used to store environment-specific values such as API keys.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: 'GitHub integration'
|
||||
sidebar_position: 2
|
||||
sidebar_position: 10
|
||||
---
|
||||
|
||||
You can connect your Nhost app to a GitHub repository. When you do this, any updates you push to your code will automatically be deployed.
|
||||
@@ -21,7 +21,7 @@ Specifically, the following will be deployed:
|
||||
|
||||
## Workflow
|
||||
|
||||
Create a new Nhost app. Then use [Nhost CLI](/platform/nhost/local-development) to initialize your Nhost app locally.
|
||||
Create a new Nhost app. Then use [Nhost CLI](/platform/cli) to initialize your Nhost app locally.
|
||||
|
||||
The workflow is as follows:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{
|
||||
"label": "GraphQL",
|
||||
"position": 3
|
||||
"position": 5
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ To interact with the GraphQL API it's recommended to use a GraphQL client:
|
||||
- [React Query](https://react-query.tanstack.com/graphql)
|
||||
- [SWR](https://swr.vercel.app/docs/data-fetching#graphql)
|
||||
|
||||
It's also possible to use the built-in [GraphQL client](/reference/sdk/graphql) in the Nhost JavaScript client.
|
||||
It's also possible to use the built-in [GraphQL client](/reference/javascript/nhost-js/graphql) in the Nhost JavaScript client.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
title: 'The Nhost Platform'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
- [Database](/platform/database)
|
||||
- [GraphQL](/platform/graphql)
|
||||
- [Authentication](/platform/authentication)
|
||||
- [Storage](/platform/storage)
|
||||
- [Serverless Functions](/platform/serverless-functions)
|
||||
- [Nhost](/platform/nhost)
|
||||
28
docs/docs/platform/index.mdx
Normal file
28
docs/docs/platform/index.mdx
Normal file
@@ -0,0 +1,28 @@
|
||||
---
|
||||
title: 'Introduction to Nhost'
|
||||
sidebar_label: Introduction
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
Nhost is the open source GraphQL backend (Firebase Alternative) and a development platform. Nhost is doing for the backend, what [Netlify](https://netlify.com/) and [Vercel](https://vercel.com/) are doing for the frontend.
|
||||
|
||||
We provide a modern backend with the general building blocks required to build fantastic digital products.
|
||||
|
||||
We make it easy to build and deploy this backend using our platform that takes care of configuration, security, and performance. Things just works and scale automatically so you can focus on your product and on your business.
|
||||
|
||||
## Quickstart
|
||||
|
||||
Get started quickly by following one of our quickstart guides:
|
||||
|
||||
- [Next.js](/platform/quickstarts/nextjs)
|
||||
- [React](/platform/quickstarts/react)
|
||||
|
||||
## Products and features
|
||||
|
||||
Learn more about the product and features of Nhost.
|
||||
|
||||
- [Database](/platform/database)
|
||||
- [GraphQL](/platform/graphql)
|
||||
- [Authentication](/platform/authentication)
|
||||
- [Storage](/platform/storage)
|
||||
- [Serverless Functions](/platform/serverless-functions)
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"label": "Nhost",
|
||||
"position": 7
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
title: 'Overview'
|
||||
---
|
||||
|
||||
Documentation for other platform features:
|
||||
|
||||
- [Environment variables](/platform/nhost/environment-variables)
|
||||
- [GitHub integration](/platform/nhost/github-integration)
|
||||
- [Local development](/platform/nhost/local-development)
|
||||
@@ -1,72 +0,0 @@
|
||||
---
|
||||
title: 'Nhost CLI'
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
Nhost CLI lets you run Nhost's development environment locally on macOS, Linux and Windows.
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
Download and install Nhost CLI for your platform by running this command in your terminal:
|
||||
|
||||
```bash
|
||||
sudo curl -L https://raw.githubusercontent.com/nhost/cli/main/get.sh | bash
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
|
||||
- [Git](https://git-scm.com/downloads) must be installed on your system
|
||||
- [Docker](https://www.docker.com/get-started) must be installed and running when using Nhost CLI
|
||||
|
||||
### Function runtimes
|
||||
|
||||
To run serverless functions locally, you must have the appropriate runtimes installed on your machine:
|
||||
|
||||
- JavaScript and TypeScript functions: `Node.js 14.*`
|
||||
|
||||
For Node.js, you will also need to have [express](https://www.npmjs.com/package/express) installed in your repository:
|
||||
|
||||
```bash
|
||||
npm install --save-dev express @types/express
|
||||
```
|
||||
|
||||
[Read more about runtimes](/platform/serverless-functions)
|
||||
|
||||
---
|
||||
|
||||
## Windows support
|
||||
|
||||
If you have Windows Subsystem for Linux and `curl` in your Windows environment, you run the command following the instructions above. It will download the `.exe` binary to your current working directory.
|
||||
|
||||
If you do not have the above dependencies, download and install the latest release manually from [GitHub releases](https://github.com/nhost/cli/releases).
|
||||
|
||||
---
|
||||
|
||||
## Apple silicon (M1)
|
||||
|
||||
As of late 2021, Hasura does not yet have an M1 optimized version for their GraphQL engine, which Nhost depends on.
|
||||
|
||||
If you have a MacBook with an M1 chip, the CLI will automatically change the image used in `nhost/config.yaml` of your app:
|
||||
|
||||
```yml
|
||||
services:
|
||||
hasura:
|
||||
image: fedormelexin/graphql-engine-arm64
|
||||
```
|
||||
|
||||
This will run the Hasura GraphQL engine using Rosetta on your machine until an M1 optimized image is launched.
|
||||
|
||||
---
|
||||
|
||||
## Upgrading
|
||||
|
||||
If you already Nhost CLI installed, you can upgrade your installation:
|
||||
|
||||
```bash
|
||||
# sudo permissions needed
|
||||
sudo nhost upgrade
|
||||
```
|
||||
|
||||
The `upgrade` command was added in `0.5.0`.
|
||||
5
docs/docs/platform/overview/_category_.json
Normal file
5
docs/docs/platform/overview/_category_.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"label": "Overview",
|
||||
"position": 2,
|
||||
"collapsed": false
|
||||
}
|
||||
29
docs/docs/platform/overview/architecture.md
Normal file
29
docs/docs/platform/overview/architecture.md
Normal file
@@ -0,0 +1,29 @@
|
||||
---
|
||||
title: 'Architecture'
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
Nhost is a backend as a service built with open source tools to provide developers the general building blocks required to build fantastic digital apps and products.
|
||||
|
||||
Here's a diagram of the Nhost stack on a high level:
|
||||
|
||||

|
||||
|
||||
As you see in the image above, Nhost provides endpoints for:
|
||||
|
||||
- GraphQL (`/graphql`)
|
||||
- Authentication (`/auth`)
|
||||
- Storage (`/storage`)
|
||||
- Functions (`/functions`)
|
||||
|
||||
Data is stored in Postgres and files are stored in S3.
|
||||
|
||||
## Open Source
|
||||
|
||||
The open source tools used for the full Nhost stack are:
|
||||
|
||||
- Database: [Postgres](https://www.postgresql.org/)
|
||||
- GraphQL: [Hasura](https://github.com/hasura/graphql-engine)
|
||||
- Authentication: [Hasura Auth](https://github.com/nhost/hasura-auth)
|
||||
- Storage: [Hasura Storage](https://github.com/nhost/hasura-storage)
|
||||
- Functions: [Node.js](https://nodejs.org/en/)
|
||||
438
docs/docs/platform/overview/get-started-with-nhost-cli.md
Normal file
438
docs/docs/platform/overview/get-started-with-nhost-cli.md
Normal file
@@ -0,0 +1,438 @@
|
||||
---
|
||||
title: 'Get Started with Nhost CLI'
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Get started with Nhost CLI
|
||||
|
||||
Nhost's command-line interface (CLI) lets you run a complete Nhost development
|
||||
environment locally with the following services: PostgreSQL database, Hasura,
|
||||
Authentication, Storage (MinIO), Serverless Functions, and Emails (Mailhog).
|
||||
|
||||
## Installation
|
||||
|
||||
### Install the binary globally
|
||||
|
||||
To install **Nhost CLI**, run this command from any directory in your terminal:
|
||||
|
||||
```bash
|
||||
sudo curl -L https://raw.githubusercontent.com/nhost/cli/main/get.sh | bash
|
||||
```
|
||||
|
||||
On **MacOS and Linux**, this will install the **Nhost CLI** in `/usr/local/bin`.
|
||||
|
||||
If you'd prefer to install to a different location other than `/usr/local/bin`,
|
||||
set the `INSTALL_PATH` variable accordingly:
|
||||
|
||||
```bash
|
||||
sudo curl -L https://raw.githubusercontent.com/nhost/cli/main/get.sh | INSTALL_PATH=$HOME/bin bash
|
||||
```
|
||||
|
||||
On **Windows**, this will download and extract the binary `nhost.exe` available
|
||||
under `Assets` of the latest release from the GitHub release page:
|
||||
https://github.com/nhost/cli/releases.
|
||||
|
||||
You can move the executable to a different location and add the path to the
|
||||
environment variable `PATH` to make `nhost` accessible globally.
|
||||
|
||||
Finally, you can check that everything has been successfully installed by
|
||||
typing:
|
||||
|
||||
```bash
|
||||
nhost version
|
||||
```
|
||||
|
||||

|
||||
|
||||
### (Optional) Add shell completion
|
||||
|
||||
To add command auto-completion in the shell, you can run the following command:
|
||||
|
||||
```bash
|
||||
nhost completion [shell]
|
||||
```
|
||||
|
||||
This will generate the autocompletion script for `nhost` for the specified shell
|
||||
(bash, fish, PowerShell, or zsh).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
### Dependencies
|
||||
|
||||
Before using the **Nhost CLI**, make sure you have the following dependencies
|
||||
installed on your local machine:
|
||||
|
||||
- [Git](https://git-scm.com/downloads)
|
||||
- [Docker](https://www.docker.com/get-started)
|
||||
|
||||
:::caution
|
||||
Docker must be running while using Nhost CLI.
|
||||
:::
|
||||
|
||||
### Nhost CLI login
|
||||
|
||||
After installing **Nhost CLI**, you can log in to your Nhost account by running
|
||||
the following command:
|
||||
|
||||
```bash
|
||||
nhost login
|
||||
```
|
||||
|
||||
This will display a prompt for you to enter your Nhost account credentials
|
||||
(email/password).
|
||||
|
||||
:::info
|
||||
You can create a Nhost account here: [https://app.nhost.io](https://app.nhost.io/).
|
||||
:::
|
||||
|
||||

|
||||
|
||||
After successfully logging in, you are authorized to manage your Nhost projects
|
||||
using the Nhost CLI.
|
||||
|
||||
You can also log out at any time by running:
|
||||
|
||||
```bash
|
||||
nhost logout
|
||||
```
|
||||
|
||||
## Set up your project
|
||||
|
||||
### 1. Create a new Nhost app
|
||||
|
||||
First things first, we need to create a new Nhost project.
|
||||
|
||||
So, log in to your Nhost dashboard and click the **Create your first app**
|
||||
button.
|
||||
|
||||

|
||||
|
||||
Next, give your new Nhost app a name, select a geographic region for your Nhost
|
||||
services and click **Create App**.
|
||||
|
||||

|
||||
|
||||
After a few seconds, you should get a PostgreSQL database, a GraphQL API with
|
||||
Hasura, file storage, and authentication set up.
|
||||
|
||||
### 2. Create a new GitHub Repository
|
||||
|
||||
A typical workflow would also include creating a Github repository for your
|
||||
Nhost project. It will facilitate your development workflow since Nhost can
|
||||
integrate with Github to enable continuous deployment.
|
||||
|
||||
So, go to your Github account and
|
||||
[create a new repository](https://github.com/new). You can make your repository
|
||||
either public or private.
|
||||
|
||||

|
||||
|
||||
### 3. Connect Nhost project to Github
|
||||
|
||||
Finally, connect your Github repository to your Nhost project. Doing so will
|
||||
enable Nhost to deploy new versions of your project when you push automatically
|
||||
commits to your connected Git repository.
|
||||
|
||||
1. From your project workspace, click **Connect to Github**.
|
||||
|
||||

|
||||
|
||||
2. **Install the Nhost app** on your Github account.
|
||||
|
||||

|
||||
|
||||
3. **Connect** your Github repository.
|
||||
|
||||

|
||||
|
||||
## Develop locally
|
||||
|
||||
## 1. Initialize your Nhost app
|
||||
|
||||
**Nhost CLI** brings the functionality of your Nhost production environment
|
||||
directly to your local machine.
|
||||
|
||||
It provides Docker containers to run the backend services that match your
|
||||
production application in a local environment. That way, you can make changes
|
||||
and test your code locally before deploying those changes to production.
|
||||
|
||||
You can either initialize a blank Nhost app locally to start from scratch by
|
||||
running the following command:
|
||||
|
||||
```bash
|
||||
nhost init -n my-nhost-app
|
||||
```
|
||||
|
||||
And then link it to a remote app from your Nhost workspace in `app.nhost.io` by
|
||||
running the `link` command and selecting the corresponding app from the prompt:
|
||||
|
||||
```bash
|
||||
nhost link
|
||||
```
|
||||
|
||||
Or you can directly initialize a local Nhost app from one of your existing
|
||||
production apps by specifying the `--remote` flag:
|
||||
|
||||
```bash
|
||||
nhost init --remote -n my-nhost-app
|
||||
```
|
||||
|
||||
It will also prompt you to choose the remote app you'd like to use to initialize
|
||||
your local Nhost development environment.
|
||||
|
||||

|
||||
|
||||
The `init` command creates the Nhost app inside your current working directory
|
||||
within a `nhost/` folder.
|
||||
|
||||
```
|
||||
my-nhost-app/
|
||||
└─ nhost/
|
||||
├─ config.yaml
|
||||
├─ emails/
|
||||
├─ metadata/
|
||||
├─ migrations/
|
||||
└─ seeds/
|
||||
```
|
||||
|
||||
Finally, make sure to link your current working directory to your GitHub
|
||||
repository:
|
||||
|
||||
```bash
|
||||
echo "# my-nhost-app" >> README.md
|
||||
git init
|
||||
git add README.md
|
||||
git commit -m "first commit"
|
||||
git branch -M main
|
||||
git remote add origin https://github.com/[github-username]/my-nhost-app.git
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
## 2. Start a local development environment
|
||||
|
||||
To start a local development environment for your Nhost app, run the following
|
||||
command:
|
||||
|
||||
```bash
|
||||
nhost dev
|
||||
```
|
||||
|
||||
:::caution
|
||||
Make sure [Docker](https://www.docker.com/get-started) is up and running. It’s required for Nhost to work.
|
||||
:::
|
||||
|
||||
Running this command will start up all the backend services provided by Nhost.
|
||||
|
||||
It also runs a webserver to serve the Hasura console for the GraphQL engine so
|
||||
you can manage the database and try out the API.
|
||||
|
||||
The Hasura console should open automatically at
|
||||
[http://localhost:1337](http://localhost:1337/).
|
||||
|
||||

|
||||
|
||||
## 3. Make changes
|
||||
|
||||
There are three things the Nhost CLI and the GitHub integration track and apply
|
||||
to production:
|
||||
|
||||
- Database migrations
|
||||
- Hasura Metadata
|
||||
- Serverless Functions
|
||||
|
||||
:::caution
|
||||
Settings in `nhost/config.yaml` are not being applied to production. They only work locally for now.
|
||||
:::
|
||||
|
||||
### Database migrations
|
||||
|
||||
Database changes are tracked and managed through migrations.
|
||||
|
||||
:::tip
|
||||
It's important that you use the Hasura console to make database changes. Indeed, with the Hasura console, DB migration files are generated incrementally to track changes automatically for you.
|
||||
:::
|
||||
|
||||
To demonstrate how to make database changes, let's create a new table called
|
||||
`messages`, with the following columns:
|
||||
|
||||
- `id` (type UUID and default `gen_random_uuid()`),
|
||||
- `text` (type Text),
|
||||
- `authorId` (type UUID),
|
||||
- `createdAt` (type Timestamp and default `now()`)
|
||||
|
||||
In the Hasura console, head over to the **data** tab section and click on the
|
||||
PostgreSQL database (from the left side navigation) that Nhost provides us.
|
||||
|
||||
Click on the **public** schema and the **Create Table** button.
|
||||
|
||||

|
||||
|
||||
Then, enter the values for creating the `messages` table as mentioned above.
|
||||
Also, specify the `id` column as the primary key of the table, and link the
|
||||
`authorId` column to the `users.id` column using a foreign key to link the
|
||||
`users` and `messages` tables together.
|
||||
|
||||

|
||||
|
||||
Next, click on the **Add Table** button to create the table.
|
||||
|
||||
Finally, check out the `migrations/` folder in your project directory. A
|
||||
migration file has been created automatically to reflect our database changes
|
||||
and track the new table creation.
|
||||
|
||||
The migration was created under `nhost/migrations/default`:
|
||||
|
||||
```bash
|
||||
$ ls -la nhost/migrations/default
|
||||
total 0
|
||||
drwxr-xr-x 3 user staff 96 Apr 27 17:06 .
|
||||
drwxr-xr-x 3 user staff 96 Apr 27 17:06 ..
|
||||
drwxr-xr-x 4 user staff 128 Apr 27 17:06 1651071963431_create_table_public_messages
|
||||
```
|
||||
|
||||
However, note that this database migration has only been applied locally. In
|
||||
other words, the `messages` table does not (yet) exists in production.
|
||||
|
||||
To apply the local changes to production, check out the
|
||||
[Deploy your project](#deploy-your-project) section below.
|
||||
|
||||
### Hasura metadata
|
||||
|
||||
In addition to database schema changes, Nhost also tracks Hasura metadata.
|
||||
|
||||
The Hasura metadata track all the actions performed on the console, like
|
||||
tracking tables/views/functions, creating relationships, configuring
|
||||
permissions, creating event triggers, and remote schemas.
|
||||
|
||||
To demonstrate it, let's add a new permission to our `messages` table for the
|
||||
`user` role on the `insert` operation. That permission will allow users to
|
||||
create new messages.
|
||||
|
||||
So, open the permissions tab for the `messages` table, type in `user` in the
|
||||
role cell, and click the edit icon on the `insert` operation:
|
||||
|
||||

|
||||
|
||||
To restrict the users to create new messages only for themselves, specify an
|
||||
`_eq` condition between the `authorId` and the `X-Hasura-User-ID` session
|
||||
variable, which is passed with each request.
|
||||
|
||||

|
||||
|
||||
Then, select the columns the users can define through the GraphQL API, set the
|
||||
value for the `authorId` column to be equal to the `X-Hasura-User-ID` session
|
||||
variable, and click **Save Permissions**.
|
||||
|
||||

|
||||
|
||||
Finally, check out the `metadata/` folder in your project directory to confirm
|
||||
that the permission changes we did were tracked locally in your git repository.
|
||||
|
||||
In our case, those changes should be tracked in
|
||||
`nhost/metadata/databases/default/tables/public_messages.yaml`:
|
||||
|
||||
```yaml title="nhost/metadata/databases/default/tables/public_messages.yaml"
|
||||
table:
|
||||
name: messages
|
||||
schema: public
|
||||
insert_permissions:
|
||||
- permission:
|
||||
backend_only: false
|
||||
check:
|
||||
authorId:
|
||||
_eq: X-Hasura-User-Id
|
||||
columns:
|
||||
- text
|
||||
set:
|
||||
authorId: x-hasura-User-Id
|
||||
role: user
|
||||
```
|
||||
|
||||
### Serverless functions
|
||||
|
||||
Now let's create a serverless function before we push all changes to GitHub so
|
||||
Nhost can deploy them to production.
|
||||
|
||||
For this guide, let's create a simple serverless function that will return the
|
||||
current date-time when called.
|
||||
|
||||
First, make sure to install `express`, which is required for serverless
|
||||
functions to work.
|
||||
|
||||
```bash
|
||||
npm install express
|
||||
npm install -d @types/node @types/express
|
||||
```
|
||||
|
||||
Then, create a new file named `time.ts` inside the `functions/` folder of your
|
||||
working directory, and paste the following code:
|
||||
|
||||
```ts title="functions/time.ts"
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
export default (req: Request, res: Response) => {
|
||||
return res
|
||||
.status(200)
|
||||
.send(`Hello ${req.query.name}! It's now: ${new Date().toUTCString()}`);
|
||||
};
|
||||
```
|
||||
|
||||
Every JavaScript and TypeScript file inside the `functions/` folder becomes an
|
||||
API endpoint.
|
||||
|
||||
Locally, the base URL for the serverless functions is
|
||||
`http://localhost:1337/v1/functions`. Then, the endpoint for each function is
|
||||
determined by its filename or the name of its dedicated parent directory.
|
||||
|
||||
For example, the endpoint for our function is
|
||||
`http://localhost:1337/v1/functions/time`.
|
||||
|
||||
```bash
|
||||
curl http://localhost:1337/v1/functions/time\?name\=Greg
|
||||
Hello Greg! It's now: Wed, 27 Apr 2022 18:52:12 GMT
|
||||
```
|
||||
|
||||
## Deploy your project
|
||||
|
||||
To deploy your local changes to production, you can commit and push them to
|
||||
GitHub. As a result, Nhost will automatically pick up the changes in your
|
||||
repository and apply them to your associated remote Nhost project.
|
||||
|
||||
:::caution
|
||||
Make sure to [connect your Github repository](#3-connect-nhost-project-to-Github) to your Nhost project first.
|
||||
:::
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "commit message"
|
||||
git push
|
||||
```
|
||||
|
||||
To check out your deployment, head over to the **Deployments** tab in your
|
||||
[Nhost dashboard](https://app.nhost.io).
|
||||
|
||||

|
||||
|
||||
## Get help
|
||||
|
||||
To get usage tips and learn more about available commands from within Nhost CLI,
|
||||
run the following:
|
||||
|
||||
```shell
|
||||
nhost help
|
||||
```
|
||||
|
||||
For more information about a specific command, run the command with the `--help`
|
||||
flag:
|
||||
|
||||
```
|
||||
nhost init --help
|
||||
```
|
||||
|
||||
If you have additional questions or ideas for new features, you can
|
||||
[start an issue](https://github.com/nhost/cli/issues) or
|
||||
[a new discussion](https://github.com/nhost/cli/discussions/new) on Nhost CLI’s
|
||||
open-source repository. You can also
|
||||
[chat with our team](https://discord.com/invite/9V7Qb2U) on Discord.
|
||||
|
||||
We’d love to hear from you!
|
||||
5
docs/docs/platform/quickstarts/_category_.json
Normal file
5
docs/docs/platform/quickstarts/_category_.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"label": "Quickstarts",
|
||||
"position": 3,
|
||||
"collapsed": false
|
||||
}
|
||||
744
docs/docs/platform/quickstarts/nextjs.mdx
Normal file
744
docs/docs/platform/quickstarts/nextjs.mdx
Normal file
@@ -0,0 +1,744 @@
|
||||
---
|
||||
title: 'Quickstart: Next.js'
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Quickstart: Next.js
|
||||
|
||||
## Introduction
|
||||
|
||||
This quickstart guide provides the steps you need to build a simple Next.js app
|
||||
powered by Nhost for the backend. It includes:
|
||||
|
||||
- Database: [PostgreSQL](https://www.postgresql.org/)
|
||||
- Instant GraphQL API: [Hasura](https://hasura.io/)
|
||||
- Authentication: [Hasura Auth](https://github.com/nhost/hasura-auth/)
|
||||
- Storage: [Hasura Storage](https://hub.docker.com/r/nhost/hasura-storage)
|
||||
|
||||
By the end of this guide, you'll have a full-stack app that allows users to log
|
||||
in to access a protected dashboard and update their profile information.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before getting started, let's make sure that your development environment is
|
||||
ready.
|
||||
|
||||
You'll need **Node.js** version 12 or later: [install it from here](https://nodejs.org/en/).
|
||||
|
||||
## Project setup
|
||||
|
||||
### Create a new Nhost app
|
||||
|
||||
First things first, we need to create a new Nhost project.
|
||||
|
||||
So, log in to your Nhost dashboard and click the **Create your first app**
|
||||
button.
|
||||
|
||||

|
||||
|
||||
Next, give your new Nhost app a name, select a geographic region for your Nhost
|
||||
services and click **Create App**.
|
||||
|
||||

|
||||
|
||||
After a few seconds, you should get a PostgreSQL database, a GraphQL API with
|
||||
Hasura, file storage, and authentication set up.
|
||||
|
||||
:::info
|
||||
You can also connect your Nhost app to a GitHub repository. When you do this, any updates you push to your code will automatically be deployed. [Learn more](https://docs.nhost.io/platform/github-integration).
|
||||
:::
|
||||
|
||||
## Initialize the app
|
||||
|
||||
### Create a Next.js app
|
||||
|
||||
The simplest way to create a new Next.js application is by using the tool called
|
||||
`create-next-app`, which bootstraps a Next.js app for you without the hassle of
|
||||
configuring everything yourself.
|
||||
|
||||
So, open your terminal, and run the following command:
|
||||
|
||||
```bash
|
||||
npx create-next-app my-nhost-app --example "https://github.com/nhost/quickstart-nextjs"
|
||||
```
|
||||
|
||||
:::info
|
||||
This command uses an [existing template](https://github.com/nhost/quickstart-nextjs), through the `--example` flag, which already contains the React components and pages we'll use for this guide.
|
||||
:::
|
||||
|
||||
You can now `cd` into your project directory:
|
||||
|
||||
```bash
|
||||
cd my-nhost-app
|
||||
```
|
||||
|
||||
And run the development server with the following command:
|
||||
|
||||
<Tabs groupId="package-manager">
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
yarn dev
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
If everything is working fine, your Next.js development server should be running
|
||||
on port 3000. Open [http://localhost:3000](http://localhost:3000) from your
|
||||
browser to check this out.
|
||||
|
||||
### Configure Nhost with Next.js
|
||||
|
||||
To work with Nhost from within our Next.js app, we'll use the
|
||||
[Next.js SDK](https://github.com/nhost/nhost/tree/main/packages/nextjs) provided
|
||||
by Nhost. It's a wrapper around the
|
||||
[Nhost React SDK](https://github.com/nhost/nhost/tree/main/packages/react) which
|
||||
gives us a way to interact with our Nhost backend using React hooks.
|
||||
|
||||
You can install the Nhost Next.js SDK with:
|
||||
|
||||
<Tabs groupId="package-manager">
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
npm install @nhost/react @nhost/nextjs graphql
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
yarn add @nhost/react @nhost/nextjs graphql
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Next, open your `_app.js` file as we'll now configure Nhost inside our app.
|
||||
|
||||
The Nhost Next.js SDK comes with a React provider named `NhostNextProvider` that
|
||||
makes the authentication state and all the provided React hooks available in our
|
||||
application.
|
||||
|
||||
Use the following code to instantiate a new Nhost client and link it to your
|
||||
Nhost backend:
|
||||
|
||||
```jsx title="pages/_app.js"
|
||||
import { UserProvider } from '../UserProvider';
|
||||
// highlight-start
|
||||
import { NhostNextProvider, NhostClient } from '@nhost/nextjs';
|
||||
// highlight-end
|
||||
|
||||
// highlight-start
|
||||
const nhost = new NhostClient({
|
||||
backendUrl: process.env.NEXT_PUBLIC_NHOST_BACKEND_URL || '',
|
||||
});
|
||||
// highlight-end
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
return (
|
||||
{/* highlight-next-line */}
|
||||
<NhostNextProvider nhost={nhost} initial={pageProps.nhostSession}>
|
||||
<UserProvider>
|
||||
{/* ... */}
|
||||
</UserProvider>
|
||||
{/* highlight-next-line */}
|
||||
</NhostNextProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
Finally, make sure to create an environment variable named
|
||||
`NEXT_PUBLIC_NHOST_BACKEND_URL` to store your Nhost backend URL:
|
||||
|
||||
```yaml title=".env.development"
|
||||
NEXT_PUBLIC_NHOST_BACKEND_URL=YOUR_NHOST_BACKEND_URL
|
||||
```
|
||||
|
||||
You can find your Nhost backend URL for your project from [your dashboard](https://app.nhost.io) as shown below:
|
||||
|
||||

|
||||
|
||||
:::caution
|
||||
Don't forget to restart your Next.js server after saving your `.env.development`
|
||||
file to load your new environment variable.
|
||||
:::
|
||||
|
||||
## Build the app
|
||||
|
||||
### Add authentication
|
||||
|
||||
#### 1. Sign-up
|
||||
|
||||
The next step is to allow our users to authenticate into our application.
|
||||
Let's start with implementing the sign-up process.
|
||||
|
||||
For that, we'll use the `useSignUpEmailPassword` hook provided by the Nhost
|
||||
Next.js SDK within our `SignUp` component.
|
||||
|
||||
So, open up the corresponding file from your project, and use the following
|
||||
code:
|
||||
|
||||
```jsx title="components/SignUp.js"
|
||||
import styles from '../styles/components/SignUp.module.css';
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useSignUpEmailPassword } from '@nhost/nextjs';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import Input from './Input';
|
||||
import Spinner from './Spinner';
|
||||
|
||||
const SignUp = () => {
|
||||
const [firstName, setFirstName] = useState('');
|
||||
const [lastName, setLastName] = useState('');
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const {
|
||||
signUpEmailPassword,
|
||||
isLoading,
|
||||
isSuccess,
|
||||
needsEmailVerification,
|
||||
isError,
|
||||
error,
|
||||
} = useSignUpEmailPassword();
|
||||
|
||||
const handleOnSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
await signUpEmailPassword(email, password, {
|
||||
displayName: `${firstName} ${lastName}`.trim(),
|
||||
metadata: {
|
||||
firstName,
|
||||
lastName,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
if (isSuccess) {
|
||||
router.push('/');
|
||||
return null;
|
||||
}
|
||||
|
||||
const disableForm = isLoading || needsEmailVerification;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.card}>
|
||||
<div className={styles['logo-wrapper']}>
|
||||
<Image src="/logo.svg" alt="logo" layout="fill" objectFit="contain" />
|
||||
</div>
|
||||
|
||||
{needsEmailVerification ? (
|
||||
<p className={styles['verification-text']}>
|
||||
Please check your mailbox and follow the verification link to verify
|
||||
your email.
|
||||
</p>
|
||||
) : (
|
||||
<form onSubmit={handleOnSubmit} className={styles.form}>
|
||||
<div className={styles['input-group']}>
|
||||
<Input
|
||||
label="First name"
|
||||
value={firstName}
|
||||
onChange={(e) => setFirstName(e.target.value)}
|
||||
disabled={disableForm}
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
label="Last name"
|
||||
value={lastName}
|
||||
onChange={(e) => setLastName(e.target.value)}
|
||||
disabled={disableForm}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
type="email"
|
||||
label="Email address"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
disabled={disableForm}
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
type="password"
|
||||
label="Create password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
disabled={disableForm}
|
||||
required
|
||||
/>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={disableForm}
|
||||
className={styles.button}
|
||||
>
|
||||
{isLoading ? <Spinner size="sm" /> : 'Create account'}
|
||||
</button>
|
||||
|
||||
{isError ? (
|
||||
<p className={styles['error-text']}>{error?.message}</p>
|
||||
) : null}
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<p className={styles.text}>
|
||||
Already have an account?{' '}
|
||||
<Link href="/sign-in">
|
||||
<a className={styles.link}>Sign in</a>
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SignUp;
|
||||
```
|
||||
|
||||
By default, the user must verify his email address before fully signing up. You can change this setting from your Nhost dashboard.
|
||||
|
||||
#### 2. Sign-in
|
||||
|
||||
Now that new users can sign up for our application, let's see how to allow
|
||||
existing users to sign in with email and password.
|
||||
|
||||
For that, we will use the Nhost hook named `useSignInEmailPassword` inside our
|
||||
`SignIn` component the same way we did with our `SignUp` component. So, here's
|
||||
what your component should look like after applying the changes for the sign-in
|
||||
logic:
|
||||
|
||||
```jsx title="components/SignIn.js"
|
||||
import styles from '../styles/components/SignIn.module.css';
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useSignInEmailPassword } from '@nhost/nextjs';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import Input from './Input';
|
||||
import Spinner from './Spinner';
|
||||
|
||||
const SignIn = () => {
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
const {
|
||||
signInEmailPassword,
|
||||
isLoading,
|
||||
isSuccess,
|
||||
needsEmailVerification,
|
||||
isError,
|
||||
error,
|
||||
} = useSignInEmailPassword();
|
||||
|
||||
const handleOnSubmit = async (e) => {
|
||||
e.preventDefault();
|
||||
await signInEmailPassword(email, password);
|
||||
};
|
||||
|
||||
if (isSuccess) {
|
||||
router.push('/');
|
||||
return null;
|
||||
}
|
||||
|
||||
const disableForm = isLoading || needsEmailVerification;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.card}>
|
||||
<div className={styles['logo-wrapper']}>
|
||||
<Image src="/logo.svg" alt="logo" layout="fill" objectFit="contain" />
|
||||
</div>
|
||||
|
||||
{needsEmailVerification ? (
|
||||
<p className={styles['verification-text']}>
|
||||
Please check your mailbox and follow the verification link to verify
|
||||
your email.
|
||||
</p>
|
||||
) : (
|
||||
<>
|
||||
<form onSubmit={handleOnSubmit} className={styles.form}>
|
||||
<Input
|
||||
type="email"
|
||||
label="Email address"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
disabled={disableForm}
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
type="password"
|
||||
label="Password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
disabled={disableForm}
|
||||
required
|
||||
/>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={disableForm}
|
||||
className={styles.button}
|
||||
>
|
||||
{isLoading ? <Spinner size="sm" /> : 'Sign in'}
|
||||
</button>
|
||||
|
||||
{isError ? (
|
||||
<p className={styles['error-text']}>{error?.message}</p>
|
||||
) : null}
|
||||
</form>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<p className={styles.text}>
|
||||
No account yet?{' '}
|
||||
<Link href="/sign-up">
|
||||
<a className={styles.link}>Sign up</a>
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SignIn;
|
||||
```
|
||||
|
||||
#### 3. Sign-out
|
||||
|
||||
Finally, to allow the users to sign out from the app, we can use the Nhost
|
||||
`useSignOut` hook:
|
||||
|
||||
```jsx title="components/Layout.js"
|
||||
import { useSignOut } from '@nhost/nextjs';
|
||||
|
||||
const Layout = ({ children = null }) => {
|
||||
const { signOut } = useSignOut();
|
||||
|
||||
const menuItems = [
|
||||
//..
|
||||
{
|
||||
label: 'Logout',
|
||||
onClick: signOut,
|
||||
icon: LogoutIcon,
|
||||
},
|
||||
];
|
||||
|
||||
//...
|
||||
};
|
||||
```
|
||||
|
||||
### Protect routes
|
||||
|
||||
Now that we have implemented authentication, we can easily decide who can access
|
||||
certain parts of our application.
|
||||
|
||||
In our case, we'll only allow authenticated users to have access to the `/` and
|
||||
`/profile` routes. All the other users should be redirected to the `/sign-in`
|
||||
page if they try to access those routes.
|
||||
|
||||
To do so, we can check the authentication status of the current user using the
|
||||
Nhost SDK by creating a
|
||||
[high-order component](https://reactjs.org/docs/higher-order-components.html):
|
||||
|
||||
```jsx title="withAuth.js"
|
||||
import styles from './styles/pages/ProtectedRoute.module.css';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useAuthenticationStatus } from '@nhost/nextjs';
|
||||
import Spinner from './components/Spinner';
|
||||
|
||||
export default function withAuth(Component) {
|
||||
return function AuthProtected(props) {
|
||||
const router = useRouter();
|
||||
const { isLoading, isAuthenticated } = useAuthenticationStatus();
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isAuthenticated) {
|
||||
router.push('/sign-in');
|
||||
return null;
|
||||
}
|
||||
|
||||
return <Component {...props} />;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
Then, wrap our Next.js pages, `index.js` and `profile.js`, with it:
|
||||
|
||||
<Tabs
|
||||
defaultValue="index"
|
||||
values={[
|
||||
{label: 'pages/index.js', value: 'index'},
|
||||
{label: 'pages/profile.js', value: 'profile'},
|
||||
]}>
|
||||
<TabItem value="index">
|
||||
|
||||
```js
|
||||
import withAuth from '../withAuth';
|
||||
|
||||
const Home = () => {
|
||||
//...
|
||||
};
|
||||
|
||||
export default withAuth(Home);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="profile">
|
||||
|
||||
```js
|
||||
import withAuth from '../withAuth';
|
||||
|
||||
const Profile = () => {
|
||||
//...
|
||||
};
|
||||
|
||||
export default withAuth(Profile);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Retrieve user data
|
||||
|
||||
Finally, let's display the information of the authenticated user throughout his
|
||||
dashboard to make the app more personalized.
|
||||
|
||||
Getting the current authenticated user data is quite easy. We
|
||||
can use the `useUserData` hook provided by Nhost to do it.
|
||||
|
||||
So, open the `UserProvider.js` file and use this hook like so:
|
||||
|
||||
```js
|
||||
import React, { useContext } from 'react';
|
||||
// highlight-next-line
|
||||
import { useUserData } from '@nhost/nextjs';
|
||||
|
||||
const UserContext = React.createContext(null);
|
||||
|
||||
export function UserProvider({ children = null }) {
|
||||
// highlight-next-line
|
||||
const user = useUserData();
|
||||
return (
|
||||
<UserContext.Provider value={{ user }}>{children}</UserContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useUserContext() {
|
||||
return useContext(UserContext);
|
||||
}
|
||||
```
|
||||
|
||||
That's it! The JSX code for rendering the user data (email, display name, etc.)
|
||||
is already included in your components as part of the example repository you've
|
||||
bootstrapped at the beginning of this guide.
|
||||
|
||||
### Update user data
|
||||
|
||||
Nhost provides a GraphQL API through Hasura so that we can query and mutate our
|
||||
data instantly.
|
||||
|
||||
In this tutorial, we'll use the
|
||||
[Apollo GraphQL client](https://www.apollographql.com/) for interacting with
|
||||
this GraphQL API.
|
||||
|
||||
So, start by installing the following dependencies:
|
||||
|
||||
<Tabs groupId="package-manager">
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
npm install @nhost/react-apollo @apollo/client
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
yarn add @nhost/react-apollo @apollo/client
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Then, add the `NhostApolloProvider` from `@nhost/react-apollo` into your
|
||||
`_app_.js` file.
|
||||
|
||||
```jsx title="pages/_app.js"
|
||||
import { NhostApolloProvider } from '@nhost/react-apollo';
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
return (
|
||||
<NhostNextProvider nhost={nhost} initial={pageProps.nhostSession}>
|
||||
<NhostApolloProvider nhost={nhost}>{/* ... */}</NhostApolloProvider>
|
||||
</NhostNextProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
From there, we can construct our GraphQL query and use the Apollo `useMutation`
|
||||
hook to execute that query when the user submits the form from the profile page:
|
||||
|
||||
```js title="pages/profile.js"
|
||||
import { gql, useMutation } from '@apollo/client';
|
||||
import { toast } from 'react-hot-toast';
|
||||
|
||||
const UPDATE_USER_MUTATION = gql`
|
||||
mutation ($id: uuid!, $displayName: String!, $metadata: jsonb) {
|
||||
updateUser(
|
||||
pk_columns: { id: $id }
|
||||
_set: { displayName: $displayName, metadata: $metadata }
|
||||
) {
|
||||
id
|
||||
displayName
|
||||
metadata
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const Profile = () => {
|
||||
const [mutateUser, { loading: updatingProfile }] =
|
||||
useMutation(UPDATE_USER_MUTATION);
|
||||
|
||||
const updateUserProfile = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
try {
|
||||
await mutateUser({
|
||||
variables: {
|
||||
id: user.id,
|
||||
displayName: `${firstName} ${lastName}`.trim(),
|
||||
metadata: {
|
||||
firstName,
|
||||
lastName,
|
||||
},
|
||||
},
|
||||
});
|
||||
toast.success('Updated successfully', { id: 'updateProfile' });
|
||||
} catch (error) {
|
||||
toast.error('Unable to update profile', { id: 'updateProfile' });
|
||||
}
|
||||
};
|
||||
|
||||
//...
|
||||
};
|
||||
```
|
||||
|
||||
Finally, since Hasura has an **allow nothing by default** policy, and we haven't
|
||||
set any permissions yet, our GraphQL mutations would fail.
|
||||
|
||||
So, open the Hasura console from the **Data** tab of your project from [your Nhost dashboard](https://app.nhost.io/). Then, go to the **permissions** tab of the `users` table, type in `user` in the role
|
||||
cell, and click the edit icon on the `select` operation:
|
||||
|
||||

|
||||
|
||||
To restrict the user to read his data only, specify a condition with the
|
||||
user's ID and the `X-Hasura-User-ID` session variable, which is passed with each
|
||||
requests.
|
||||
|
||||

|
||||
|
||||
Next, select the columns you'd like the users to have access to, and click
|
||||
**Save Permissions**.
|
||||
|
||||

|
||||
|
||||
Repeat the same steps on the `update` operation for the `user` role to allow
|
||||
users to update their `displayName` and `metadata` only.
|
||||
|
||||
Finally, to add caching, synchronizing, and updating server state in your Next.js app, let's refactor the user data fetching by using the Apollo client and our GraphQL API instead.
|
||||
|
||||
So, first add the following GraphQL query to retrieve the current user data from the `UserProvider.js` file:
|
||||
|
||||
```js title="UserProvider.js"
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
const GET_USER_QUERY = gql`
|
||||
query GetUser($id: uuid!) {
|
||||
user(id: $id) {
|
||||
id
|
||||
email
|
||||
displayName
|
||||
metadata
|
||||
avatarUrl
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export function UserProvider() {
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
Then, replace the `useUserData` hook with the `useUserId` hook to retrieve the current user's ID only.
|
||||
|
||||
```js title="UserProvider.js"
|
||||
import { useUserId } from '@nhost/nextjs';
|
||||
|
||||
export function UserProvider() {
|
||||
const id = useUserId();
|
||||
//...
|
||||
}
|
||||
```
|
||||
|
||||
Finally, we can run our GraphQL query using the `useQuery` hook and the current user's ID.
|
||||
|
||||
```jsx title="UserProvider.js"
|
||||
// highlight-next-line
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
|
||||
export function UserProvider({ children = null }) {
|
||||
const id = useUserId();
|
||||
// highlight-start
|
||||
const { loading, error, data } = useQuery(GET_USER_QUERY, {
|
||||
variables: { id },
|
||||
});
|
||||
const user = data?.user;
|
||||
// highlight-end
|
||||
|
||||
// highlight-start
|
||||
if (error) {
|
||||
return <p>Something went wrong. Try to refresh the page.</p>;
|
||||
}
|
||||
if (loading) {
|
||||
return null;
|
||||
}
|
||||
// highlight-end
|
||||
|
||||
return (
|
||||
<UserContext.Provider value={{ user }}>{children}</UserContext.Provider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
You now have a fully functional Next.js application. Congratulations!
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Did you enjoy Nhost? Give us a star ⭐ on [Github](https://github.com/nhost/nhost). Thank you!
|
||||
- Check out our more in-depth [examples](https://github.com/nhost/nhost/tree/main/examples).
|
||||
- Build your next app with [Nhost](https://app.nhost.io/)!
|
||||
714
docs/docs/platform/quickstarts/react.mdx
Normal file
714
docs/docs/platform/quickstarts/react.mdx
Normal file
@@ -0,0 +1,714 @@
|
||||
---
|
||||
title: 'Quickstart: React'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Quickstart: React
|
||||
|
||||
## Introduction
|
||||
|
||||
This quickstart guide provides the steps you need to build a simple React app
|
||||
powered by Nhost for the backend. It includes:
|
||||
|
||||
- Database: [PostgreSQL](https://www.postgresql.org/)
|
||||
- Instant GraphQL API: [Hasura](https://hasura.io/)
|
||||
- Authentication: [Hasura Auth](https://github.com/nhost/hasura-auth/)
|
||||
- Storage: [Hasura Storage](https://hub.docker.com/r/nhost/hasura-storage)
|
||||
|
||||
By the end of this guide, you'll have a full-stack app that allows users to log
|
||||
in to access a protected dashboard and update their profile information.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before getting started, let's make sure that your development environment is
|
||||
ready.
|
||||
|
||||
You'll need **Node.js** version 14 or later: [install it from here](https://nodejs.org/en/).
|
||||
|
||||
## Project setup
|
||||
|
||||
### Create a new Nhost app
|
||||
|
||||
First things first, we need to create a new Nhost project.
|
||||
|
||||
So, log in to your Nhost dashboard and click the **Create your first app**
|
||||
button.
|
||||
|
||||

|
||||
|
||||
Next, give your new Nhost app a name, select a geographic region for your Nhost
|
||||
services and click **Create App**.
|
||||
|
||||

|
||||
|
||||
After a few seconds, you should get a PostgreSQL database, a GraphQL API with
|
||||
Hasura, file storage, and authentication set up.
|
||||
|
||||
:::info
|
||||
You can also connect your Nhost app to a GitHub repository. When you do this, any updates you push to your code will automatically be deployed. [Learn more](https://docs.nhost.io/platform/github-integration).
|
||||
:::
|
||||
|
||||
## Initialize the app
|
||||
|
||||
### Create a React app
|
||||
|
||||
The simplest way to create a new React application is by using the tool called
|
||||
`create-react-app`, which bootstraps a React app for you without the hassle of
|
||||
configuring everything yourself.
|
||||
|
||||
So, open your terminal, and run the following command:
|
||||
|
||||
```bash
|
||||
npx create-react-app my-nhost-app --template nhost-quickstart
|
||||
```
|
||||
|
||||
:::info
|
||||
This command uses an [existing template](https://github.com/nhost/cra-template-nhost-quickstart), through the `--template` flag, which already contains the React components and pages we'll use for this guide.
|
||||
:::
|
||||
|
||||
You can now `cd` into your project directory:
|
||||
|
||||
```bash
|
||||
cd my-nhost-app
|
||||
```
|
||||
|
||||
And run the development server with the following command:
|
||||
|
||||
<Tabs groupId="package-manager">
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
yarn start
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
If everything is working fine, your React development server should be running
|
||||
on port 3000. Open [http://localhost:3000](http://localhost:3000) from your
|
||||
browser to check this out.
|
||||
|
||||
### Configure Nhost with React
|
||||
|
||||
To work with Nhost from within our React app, we'll use the
|
||||
[React SDK](https://github.com/nhost/nhost/tree/main/packages/react) provided
|
||||
by Nhost. It's a wrapper around the
|
||||
[Nhost JavaScript SDK](https://github.com/nhost/nhost/tree/main/packages/nhost-js) which
|
||||
gives us a way to interact with our Nhost backend using React hooks.
|
||||
|
||||
You can install the Nhost React SDK with:
|
||||
|
||||
<Tabs groupId="package-manager">
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
npm install @nhost/react graphql
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
yarn add @nhost/react graphql
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Next, open your `App.js` file as we'll now configure Nhost inside our app.
|
||||
|
||||
The Nhost React SDK comes with a React provider named `NhostReactProvider` that
|
||||
makes the authentication state and all the provided React hooks available in our
|
||||
application.
|
||||
|
||||
Use the following code to instantiate a new Nhost client and link it to your
|
||||
Nhost backend:
|
||||
|
||||
```jsx title="src/App.js"
|
||||
import { NhostClient, NhostReactProvider } from '@nhost/react';
|
||||
|
||||
const nhost = new NhostClient({
|
||||
backendUrl: process.env.REACT_APP_NHOST_BACKEND_URL || '',
|
||||
});
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<NhostReactProvider nhost={nhost}>
|
||||
<BrowserRouter>{/* ... */}</BrowserRouter>
|
||||
</NhostReactProvider>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
Finally, make sure to create an environment variable named
|
||||
`REACT_APP_NHOST_BACKEND_URL` to store your Nhost backend URL:
|
||||
|
||||
```yaml title=".env.local"
|
||||
REACT_APP_NHOST_BACKEND_URL=YOUR_NHOST_BACKEND_URL
|
||||
```
|
||||
|
||||
You can find your Nhost backend URL for your project from [your dashboard](https://app.nhost.io) as shown below:
|
||||
|
||||

|
||||
|
||||
:::caution
|
||||
Don't forget to restart your React server after saving your `.env.local`
|
||||
file to load your new environment variable.
|
||||
:::
|
||||
|
||||
## Build the app
|
||||
|
||||
### Add authentication
|
||||
|
||||
#### 1. Sign-up
|
||||
|
||||
The next step is to allow our users to authenticate into our application.
|
||||
Let's start with implementing the sign-up process.
|
||||
|
||||
For that, we'll use the `useSignUpEmailPassword` hook provided by the Nhost
|
||||
React SDK within our `SignUp` component.
|
||||
|
||||
So, open up the corresponding file from your project, and use the following
|
||||
code:
|
||||
|
||||
```jsx title="src/components/SignUp.js"
|
||||
import styles from '../styles/components/SignUp.module.css';
|
||||
import { useState } from 'react';
|
||||
import { useSignUpEmailPassword } from '@nhost/react';
|
||||
import { Link, Navigate } from 'react-router-dom';
|
||||
import Input from './Input';
|
||||
import Spinner from './Spinner';
|
||||
|
||||
const SignUp = () => {
|
||||
const [firstName, setFirstName] = useState('');
|
||||
const [lastName, setLastName] = useState('');
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
|
||||
const {
|
||||
signUpEmailPassword,
|
||||
isLoading,
|
||||
isSuccess,
|
||||
needsEmailVerification,
|
||||
isError,
|
||||
error,
|
||||
} = useSignUpEmailPassword();
|
||||
|
||||
const handleOnSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
signUpEmailPassword(email, password, {
|
||||
displayName: `${firstName} ${lastName}`.trim(),
|
||||
metadata: {
|
||||
firstName,
|
||||
lastName,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
if (isSuccess) {
|
||||
return <Navigate to="/" replace={true} />;
|
||||
}
|
||||
|
||||
const disableForm = isLoading || needsEmailVerification;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.card}>
|
||||
<div className={styles['logo-wrapper']}>
|
||||
<img src={process.env.PUBLIC_URL + 'logo.svg'} alt="logo" />
|
||||
</div>
|
||||
|
||||
{needsEmailVerification ? (
|
||||
<p className={styles['verification-text']}>
|
||||
Please check your mailbox and follow the verification link to verify
|
||||
your email.
|
||||
</p>
|
||||
) : (
|
||||
<form onSubmit={handleOnSubmit} className={styles.form}>
|
||||
<div className={styles['input-group']}>
|
||||
<Input
|
||||
label="First name"
|
||||
value={firstName}
|
||||
onChange={(e) => setFirstName(e.target.value)}
|
||||
disabled={disableForm}
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
label="Last name"
|
||||
value={lastName}
|
||||
onChange={(e) => setLastName(e.target.value)}
|
||||
disabled={disableForm}
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
type="email"
|
||||
label="Email address"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
disabled={disableForm}
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
type="password"
|
||||
label="Create password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
disabled={disableForm}
|
||||
required
|
||||
/>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={disableForm}
|
||||
className={styles.button}
|
||||
>
|
||||
{isLoading ? <Spinner size="sm" /> : 'Create account'}
|
||||
</button>
|
||||
|
||||
{isError ? (
|
||||
<p className={styles['error-text']}>{error?.message}</p>
|
||||
) : null}
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<p className={styles.text}>
|
||||
Already have an account?{' '}
|
||||
<Link to="/sign-in" className={styles.link}>
|
||||
Sign in
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SignUp;
|
||||
```
|
||||
|
||||
By default, the user must verify his email address before fully signing up. You can change this setting from your Nhost dashboard.
|
||||
|
||||
#### 2. Sign-in
|
||||
|
||||
Now that new users can sign up for our application, let's see how to allow
|
||||
existing users to sign in with email and password.
|
||||
|
||||
For that, we will use the Nhost hook named `useSignInEmailPassword` inside our
|
||||
`SignIn` component the same way we did with our `SignUp` component. So, here's
|
||||
what your component should look like after applying the changes for the sign-in
|
||||
logic:
|
||||
|
||||
```jsx title="src/components/SignIn.js"
|
||||
import styles from '../styles/components/SignIn.module.css';
|
||||
import { useState } from 'react';
|
||||
import { useSignInEmailPassword } from '@nhost/react';
|
||||
import { Link, Navigate } from 'react-router-dom';
|
||||
import Input from './Input';
|
||||
import Spinner from './Spinner';
|
||||
|
||||
const SignIn = () => {
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
|
||||
const {
|
||||
signInEmailPassword,
|
||||
isLoading,
|
||||
isSuccess,
|
||||
needsEmailVerification,
|
||||
isError,
|
||||
error,
|
||||
} = useSignInEmailPassword();
|
||||
|
||||
const handleOnSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
signInEmailPassword(email, password);
|
||||
};
|
||||
|
||||
if (isSuccess) {
|
||||
return <Navigate to="/" replace={true} />;
|
||||
}
|
||||
|
||||
const disableForm = isLoading || needsEmailVerification;
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.card}>
|
||||
<div className={styles['logo-wrapper']}>
|
||||
<img src={process.env.PUBLIC_URL + 'logo.svg'} alt="logo" />
|
||||
</div>
|
||||
|
||||
{needsEmailVerification ? (
|
||||
<p className={styles['verification-text']}>
|
||||
Please check your mailbox and follow the verification link to verify
|
||||
your email.
|
||||
</p>
|
||||
) : (
|
||||
<form onSubmit={handleOnSubmit} className={styles.form}>
|
||||
<Input
|
||||
type="email"
|
||||
label="Email address"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
disabled={disableForm}
|
||||
required
|
||||
/>
|
||||
<Input
|
||||
type="password"
|
||||
label="Password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
disabled={disableForm}
|
||||
required
|
||||
/>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
disabled={disableForm}
|
||||
className={styles.button}
|
||||
>
|
||||
{isLoading ? <Spinner size="sm" /> : 'Sign in'}
|
||||
</button>
|
||||
|
||||
{isError ? (
|
||||
<p className={styles['error-text']}>{error?.message}</p>
|
||||
) : null}
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<p className={styles.text}>
|
||||
No account yet?{' '}
|
||||
<Link to="/sign-up" className={styles.link}>
|
||||
Sign up
|
||||
</Link>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SignIn;
|
||||
```
|
||||
|
||||
#### 3. Sign-out
|
||||
|
||||
Finally, to allow the users to sign out from the app, we can use the Nhost
|
||||
`useSignOut` hook:
|
||||
|
||||
```jsx title="src/components/Layout.js"
|
||||
import { useSignOut } from '@nhost/react';
|
||||
|
||||
const Layout = () => {
|
||||
const { signOut } = useSignOut();
|
||||
|
||||
const menuItems = [
|
||||
//..
|
||||
{
|
||||
label: 'Logout',
|
||||
onClick: signOut,
|
||||
icon: LogoutIcon,
|
||||
},
|
||||
];
|
||||
|
||||
//...
|
||||
};
|
||||
```
|
||||
|
||||
### Protect routes
|
||||
|
||||
Now that we have implemented authentication, we can easily decide who can access
|
||||
certain parts of our application.
|
||||
|
||||
In our case, we'll only allow authenticated users to have access to the `/` and
|
||||
`/profile` routes. All the other users should be redirected to the `/sign-in`
|
||||
page if they try to access those routes.
|
||||
|
||||
To do so, we can create a wrapper component (`ProtectedRoute`) to check the authentication status of the current user using the Nhost SDK:
|
||||
|
||||
```jsx title="src/components/ProtectedRoute.js"
|
||||
import styles from '../styles/components/ProtectedRoute.module.css';
|
||||
import { useAuthenticationStatus } from '@nhost/react';
|
||||
import { Navigate, useLocation } from 'react-router-dom';
|
||||
import Spinner from './Spinner';
|
||||
|
||||
const ProtectedRoute = ({ children }) => {
|
||||
const { isAuthenticated, isLoading } = useAuthenticationStatus();
|
||||
const location = useLocation();
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<Spinner />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isAuthenticated) {
|
||||
return <Navigate to="/sign-in" state={{ from: location }} replace />;
|
||||
}
|
||||
|
||||
return children;
|
||||
};
|
||||
|
||||
export default ProtectedRoute;
|
||||
```
|
||||
|
||||
Then, we can use a [layout route](https://reactrouter.com/docs/en/v6/getting-started/concepts#layout-routes) in our `App.js` file, to wrap the `ProtectedRoute` component around the routes we want to protect:
|
||||
|
||||
```jsx title="src/App.js"
|
||||
import ProtectedRoute from './components/ProtectedRoute';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<NhostReactProvider nhost={nhost}>
|
||||
<BrowserRouter>
|
||||
<Routes>
|
||||
<Route path="sign-up" element={<SignUp />} />
|
||||
<Route path="sign-in" element={<SignIn />} />
|
||||
<Route
|
||||
path="/"
|
||||
// highlight-start
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout />
|
||||
</ProtectedRoute>
|
||||
}
|
||||
// highlight-end
|
||||
>
|
||||
<Route index element={<Dashboard />} />
|
||||
<Route path="profile" element={<Profile />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</BrowserRouter>
|
||||
</NhostReactProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Retrieve user data
|
||||
|
||||
Finally, let's display the information of the authenticated user throughout his
|
||||
dashboard to make the app more personalized.
|
||||
|
||||
Getting the current authenticated user data is quite easy. Indeed, we
|
||||
can use the `useUserData` hook provided by Nhost to do it.
|
||||
|
||||
So, open the `components/Layout.js` file and use this hook like so:
|
||||
|
||||
```js
|
||||
import { useUserData } from '@nhost/react';
|
||||
|
||||
const Layout = () => {
|
||||
const user = useUserData();
|
||||
//...
|
||||
};
|
||||
```
|
||||
|
||||
That's it! The JSX code for rendering the user data (email, display name, etc.)
|
||||
is already included in your components as part of the template you've
|
||||
bootstraped at the beginning of this guide.
|
||||
|
||||
### Update user data
|
||||
|
||||
Nhost provides a GraphQL API through Hasura so that we can query and mutate our
|
||||
data instantly.
|
||||
|
||||
In this tutorial, we'll use the
|
||||
[Apollo GraphQL client](https://www.apollographql.com/) for interacting with
|
||||
this GraphQL API.
|
||||
|
||||
So, start by installing the following dependencies:
|
||||
|
||||
<Tabs groupId="package-manager">
|
||||
<TabItem value="npm" label="npm" default>
|
||||
|
||||
```bash
|
||||
npm install @nhost/react-apollo @apollo/client
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="yarn" label="Yarn">
|
||||
|
||||
```bash
|
||||
yarn add @nhost/react-apollo @apollo/client
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Then, add the `NhostApolloProvider` from `@nhost/react-apollo` into your
|
||||
`App.js` file.
|
||||
|
||||
```jsx title="src/App.js"
|
||||
import { NhostApolloProvider } from '@nhost/react-apollo';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<NhostReactProvider nhost={nhost}>
|
||||
<NhostApolloProvider nhost={nhost}>{/* ... */}</NhostApolloProvider>
|
||||
</NhostReactProvider>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
From there, we can construct our GraphQL query and use the Apollo `useMutation`
|
||||
hook to execute that query when the user submits the form from the profile page:
|
||||
|
||||
```js title="src/pages/Profile.js"
|
||||
import { gql, useMutation } from '@apollo/client';
|
||||
import { toast } from 'react-hot-toast';
|
||||
|
||||
const UPDATE_USER_MUTATION = gql`
|
||||
mutation ($id: uuid!, $displayName: String!, $metadata: jsonb) {
|
||||
updateUser(
|
||||
pk_columns: { id: $id }
|
||||
_set: { displayName: $displayName, metadata: $metadata }
|
||||
) {
|
||||
id
|
||||
displayName
|
||||
metadata
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const Profile = () => {
|
||||
const [mutateUser, { loading: updatingProfile }] =
|
||||
useMutation(UPDATE_USER_MUTATION);
|
||||
|
||||
const updateUserProfile = async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
try {
|
||||
await mutateUser({
|
||||
variables: {
|
||||
id: user.id,
|
||||
displayName: `${firstName} ${lastName}`.trim(),
|
||||
metadata: {
|
||||
firstName,
|
||||
lastName,
|
||||
},
|
||||
},
|
||||
});
|
||||
toast.success('Updated successfully', { id: 'updateProfile' });
|
||||
} catch (error) {
|
||||
toast.error('Unable to update profile', { id: 'updateProfile' });
|
||||
}
|
||||
};
|
||||
|
||||
//...
|
||||
};
|
||||
```
|
||||
|
||||
Finally, since Hasura has an **allow nothing by default** policy, and we haven't
|
||||
set any permissions yet, our GraphQL mutations would fail.
|
||||
|
||||
So, open the Hasura console from the **Data** tab of your project from [your Nhost dashboard](https://app.nhost.io/). Then, go to the **permissions** tab of the `users` table, type in `user` in the role
|
||||
cell, and click the edit icon on the `select` operation:
|
||||
|
||||

|
||||
|
||||
To restrict the user to read his own data only, specify a condition with the
|
||||
user's ID and the `X-Hasura-User-ID` session variable, which is passed with each
|
||||
requests.
|
||||
|
||||

|
||||
|
||||
Next, select the columns you'd like the users to have access to, and click
|
||||
**Save Permissions**.
|
||||
|
||||

|
||||
|
||||
Repeat the same steps on the `update` operation for the `user` role to allow
|
||||
users to update their `displayName` and `metadata` only.
|
||||
|
||||
Finally, to add caching, synchronizing, and updating server state in your React app, let's refactor the user data fetching using the Apollo client and our GraphQL API instead.
|
||||
|
||||
So, first add the following GraphQL query to retrieve the current user data from the `Layout` component:
|
||||
|
||||
```js title="src/components/Layout.js"
|
||||
import { gql } from '@apollo/client';
|
||||
|
||||
const GET_USER_QUERY = gql`
|
||||
query GetUser($id: uuid!) {
|
||||
user(id: $id) {
|
||||
id
|
||||
email
|
||||
displayName
|
||||
metadata
|
||||
avatarUrl
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const Layout = () => {
|
||||
//...
|
||||
};
|
||||
```
|
||||
|
||||
Then, replace the `useUserData` hook with the `useUserId` hook to retrieve the current user's ID.
|
||||
|
||||
```js title="src/components/Layout.js"
|
||||
import { useUserId } from '@nhost/react';
|
||||
|
||||
const Layout = () => {
|
||||
const id = useUserId();
|
||||
//...
|
||||
};
|
||||
```
|
||||
|
||||
Finally, we can run our GraphQL query using the `useQuery` hook and the current user's ID.
|
||||
|
||||
```jsx title="src/components/Layout.js"
|
||||
// highlight-next-line
|
||||
import { gql, useQuery } from '@apollo/client';
|
||||
|
||||
const Layout = () => {
|
||||
const id = useUserId();
|
||||
// highlight-start
|
||||
const { loading, error, data } = useQuery(GET_USER_QUERY, {
|
||||
variables: { id },
|
||||
});
|
||||
const user = data?.user;
|
||||
// highlight-end
|
||||
|
||||
//...
|
||||
|
||||
return (
|
||||
<div>
|
||||
<header>{/* ... */}</header>
|
||||
|
||||
<main className={styles.main}>
|
||||
<div className={styles['main-container']}>
|
||||
{/* highlight-start */}
|
||||
{error ? (
|
||||
<p>Something went wrong. Try to refresh the page.</p>
|
||||
) : !loading ? (
|
||||
<Outlet context={{ user }} />
|
||||
) : null}
|
||||
{/* highlight-end */}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
You now have a fully functional React application. Congratulations!
|
||||
|
||||
## Next Steps
|
||||
|
||||
- Did you enjoy Nhost? Give us a star ⭐ on [Github](https://github.com/nhost/nhost). Thank you!
|
||||
- Check out our more in-depth [examples](https://github.com/nhost/nhost/tree/main/examples).
|
||||
- Build your next app with [Nhost](https://app.nhost.io/)!
|
||||
105
docs/docs/platform/serverless-functions.mdx
Normal file
105
docs/docs/platform/serverless-functions.mdx
Normal file
@@ -0,0 +1,105 @@
|
||||
---
|
||||
title: 'Serverless Functions'
|
||||
sidebar_position: 8
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs'
|
||||
import TabItem from '@theme/TabItem'
|
||||
|
||||
With Nhost, you can deploy Serverless Functions to execute custom code. Each serverless function is its HTTP endpoint.
|
||||
|
||||
Serverless functions can be used to handle [event triggers](/platform/database/event-triggers), form submission, integrations (e.g. Stripe, Slack, etc), and more.
|
||||
|
||||
---
|
||||
|
||||
## Creating a Serverless Function
|
||||
|
||||
Every `.js` (JavaScript) and `.ts` (TypeScript) file in the `functions/` folder of your Nhost app is its own serverless function.
|
||||
|
||||
<Tabs groupId="language">
|
||||
<TabItem value="ts" label="TypeScript" default>
|
||||
|
||||
```ts title=functions/test.ts
|
||||
import { Request, Response } from 'express'
|
||||
|
||||
export default (req: Request, res: Response) => {
|
||||
res.status(200).send(`Hello ${req.query.name}!`)
|
||||
}
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
You **MUST** install `express` locally in the base directory of your Nhost app.
|
||||
|
||||
```bash
|
||||
npm install -d express @types/express
|
||||
# or yarn
|
||||
yarn add -d express @types/express
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="js" label="JavaScript">
|
||||
|
||||
```js title=functions/test.js
|
||||
export default (req, res) => {
|
||||
res.status(200).send(`Hello ${req.query.name}!`)
|
||||
}
|
||||
```
|
||||
|
||||
:::info
|
||||
|
||||
You **MUST** install `express` locally in the base directory of your Nhost app.
|
||||
|
||||
```bash
|
||||
npm install -d express
|
||||
# or yarn
|
||||
yarn add -d express
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Deploying Serverless Functions
|
||||
|
||||
Serverless functions are automatically deployed using Nhost's [GitHub integration](/platform/github-integration).
|
||||
|
||||
You can prepend files and folders with an underscore (`_`) to prevent them from being treated as serverless functions and be turned into HTTP endpoints. This is useful if you have, for example, a utils file (`functions/_utils.js`) or a utils folder (`functions/_utils/[multiple-files].js`).
|
||||
|
||||
## Routing
|
||||
|
||||
HTTP endpoints are automatically generated based on the file structure inside `functions/`.
|
||||
|
||||
Here's an example of four serverless functions with their files and their HTTP endpoints:
|
||||
|
||||
| File | HTTP Endpoint |
|
||||
| --------------------------- | ------------------------------------------------------------- |
|
||||
| `functions/index.js` | `https://[app-subdomain].nhost.run/v1/functions/` |
|
||||
| `functions/users/index.ts` | `https://[app-subdomain].nhost.run/v1/functions/users` |
|
||||
| `functions/users/active.ts` | `https://[app-subdomain].nhost.run/v1/functions/users/active` |
|
||||
| `functions/my-copmany.js` | `https://[app-subdomain].nhost.run/v1/functions/my-company` |
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
[Environment variables](/platform/environment-variables) are available inside your serverless functions. Both in production and when running Nhost locally using the [Nhost CLI](/platform/cli).
|
||||
|
||||
## Billing
|
||||
|
||||
Serverless functions are billed per GB-sec or GB-hour. 1 GB-hour is 3600 GB-seconds.
|
||||
|
||||
1 GB-sec is 1 function with 1 GB of RAM running for 1 second. If 1 function with 1 GB of RAM runs for 3600 seconds, that's the equivalent of 1 GB-hour.
|
||||
|
||||
All serverless functions in production are running with 128 MB of RAM.
|
||||
|
||||
## Node Version
|
||||
|
||||
All serverless functions in production are running Node.js version 14.x.
|
||||
|
||||
## Regions
|
||||
|
||||
Serverless Functions are always deployed to the same region as your app.
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"label": "Serverless Functions",
|
||||
"position": 6
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
---
|
||||
title: 'Serverless Functions'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
Nhost gives you the option to run serverless functions on the following runtimes:
|
||||
|
||||
- `Node.js 14` (Both JavaScript and Typescript)
|
||||
|
||||
---
|
||||
|
||||
## Creating functions
|
||||
|
||||
Every `.js` and `.ts` file in the `functions/` folder of your Nhost app will be exposed as an HTTP endpoint. You have to
|
||||
|
||||
```js
|
||||
// In functions/hello/[name].js
|
||||
export default (req, res) => {
|
||||
res.status(200).send(`Hello ${req.query.name}!`);
|
||||
};
|
||||
```
|
||||
|
||||
Or, if you prefer TypeScript:
|
||||
|
||||
```ts
|
||||
// In functions/hello/[name].ts
|
||||
import { Request, Response } from 'express';
|
||||
|
||||
export default (req: Request, res: Response) => {
|
||||
res.status(200).send(`Hello ${req.query.name}!`);
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Routing
|
||||
|
||||
HTTP endpoints are automatically generated based on the file structure under `functions/`.
|
||||
|
||||
As such, given this file structure:
|
||||
|
||||
```text
|
||||
functions/index.js
|
||||
functions/users/index.ts
|
||||
functions/active.ts
|
||||
functions/my-company.js
|
||||
```
|
||||
|
||||
The following endpoints will be available:
|
||||
|
||||
- https://yourappid.nhost.run/v1/functions/ from `functions/index.js`.
|
||||
- https://yourappid.nhost.run/v1/functions/users from `functions/users/index.ts`.
|
||||
- https://yourappid.nhost.run/v1/functions/users/active from `functions/users/active.ts`.
|
||||
- https://yourappid.nhost.run/v1/functions/my-company from `functions/my-company.js`.
|
||||
|
||||
If you've used Netlify or Vercel, this routing logic will be familiar to you.
|
||||
|
||||
---
|
||||
|
||||
## Infrastructure
|
||||
|
||||
Serverless Functions are deployed to AWS Lambda in the same region as your app.
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
title: 'Storage'
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
Nhost stores and serves files of any type in your backend.
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"label": "Storage",
|
||||
"position": 5
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"label": "CLI",
|
||||
"position": 4,
|
||||
"link": { "type": "generated-index", "slug": "/reference/cli" }
|
||||
}
|
||||
16
docs/docs/reference/cli/down.mdx
Normal file
16
docs/docs/reference/cli/down.mdx
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
title: 'down'
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
Delete all containers created by `nhost up`
|
||||
|
||||
```bash
|
||||
nhost down
|
||||
```
|
||||
|
||||
To delete all containers **and the local database**, append `--data` to the command.
|
||||
|
||||
```bash
|
||||
nhost down --data
|
||||
```
|
||||
22
docs/docs/reference/cli/global-flags.mdx
Normal file
22
docs/docs/reference/cli/global-flags.mdx
Normal file
@@ -0,0 +1,22 @@
|
||||
---
|
||||
title: 'Global Flags'
|
||||
sidebar_position: 9
|
||||
---
|
||||
|
||||
### `--debug`, `-d`
|
||||
|
||||
Turn on debug output.
|
||||
|
||||
```bash
|
||||
nhost up --debug
|
||||
nhost init -d
|
||||
```
|
||||
|
||||
### `--log-file`, `-f`
|
||||
|
||||
Save output to a given file.
|
||||
|
||||
```bash
|
||||
nhost up -d --log-file some-file.txt
|
||||
nhost logs -f some-file.txt
|
||||
```
|
||||
6
docs/docs/reference/cli/index.mdx
Normal file
6
docs/docs/reference/cli/index.mdx
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
title: 'CLI'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
This section is a reference for the commands available in the [Nhost CLI](/platform/cli).
|
||||
18
docs/docs/reference/cli/init.mdx
Normal file
18
docs/docs/reference/cli/init.mdx
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: 'init'
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
Intialize a local Nhost app in the current working directory.
|
||||
|
||||
```
|
||||
nhost init
|
||||
```
|
||||
|
||||
If you already have a Nhost app in Nhost Cloud you can use that app as a starting point by appending `--remote` to the command.
|
||||
|
||||
This will pull the database migrations and Hasura metadata from the Nhost Cloud app locally for you to use as a starting point.
|
||||
|
||||
```
|
||||
nhost init --remote
|
||||
```
|
||||
10
docs/docs/reference/cli/link.mdx
Normal file
10
docs/docs/reference/cli/link.mdx
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 'link'
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
Link the local Nhost app in your working directory to an app in Nhost Cloud.
|
||||
|
||||
```bash
|
||||
nhost link
|
||||
```
|
||||
10
docs/docs/reference/cli/list.mdx
Normal file
10
docs/docs/reference/cli/list.mdx
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 'list'
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
List all your Nhost apps in Nhost Cloud.
|
||||
|
||||
```bash
|
||||
nhost list
|
||||
```
|
||||
10
docs/docs/reference/cli/login.mdx
Normal file
10
docs/docs/reference/cli/login.mdx
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 'login'
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
Authenticate the CLI with your Nhost user.
|
||||
|
||||
```bash
|
||||
nhost login
|
||||
```
|
||||
10
docs/docs/reference/cli/logout.mdx
Normal file
10
docs/docs/reference/cli/logout.mdx
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 'logout'
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
Remove authentication for the CLI.
|
||||
|
||||
```bash
|
||||
nhost logout
|
||||
```
|
||||
10
docs/docs/reference/cli/logs.mdx
Normal file
10
docs/docs/reference/cli/logs.mdx
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 'logs'
|
||||
sidebar_position: 9
|
||||
---
|
||||
|
||||
Output logs of any service container
|
||||
|
||||
```bash
|
||||
nhost logs
|
||||
```
|
||||
@@ -1,97 +0,0 @@
|
||||
---
|
||||
title: 'Nhost CLI'
|
||||
---
|
||||
|
||||
Run `nhost help` in your terminal to get a detailed listing of all available commands.
|
||||
|
||||
---
|
||||
|
||||
## `nhost`
|
||||
|
||||
Run the Nhost development environment. If the current directory has not been initialized as an Nhost app, `nhost` will run you through the initialization.
|
||||
|
||||
```bash
|
||||
nhost
|
||||
```
|
||||
|
||||
### Frontend templates
|
||||
|
||||
The `nhost` command will offer you the option of cloning frontend templates for framework of your choice (Nuxt, Next.js, React).
|
||||
|
||||
The frontend template will be cloned in the `web/` directory of your app root. It will have the Nhost SDK preinstalled and configured.
|
||||
|
||||
---
|
||||
|
||||
## `nhost dev`
|
||||
|
||||
Launch the development environment for your app.
|
||||
|
||||
```bash
|
||||
nhost dev
|
||||
```
|
||||
|
||||
To trace all output and debug issues, run `nhost dev --debug`.
|
||||
|
||||
```bash
|
||||
nhost dev --debug
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## `nhost init`
|
||||
|
||||
Intialize a blank local app in current working directory:
|
||||
|
||||
```bash
|
||||
nhost init
|
||||
```
|
||||
|
||||
Or clone an existing app from [nhost.io](https://nhost.io):
|
||||
|
||||
```bash
|
||||
nhost init --remote
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## `nhost link`
|
||||
|
||||
Link the local Nhost app in your working directory to [nhost.io](https://nhost.io).
|
||||
|
||||
```bash
|
||||
nhost link
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## `nhost logs`
|
||||
|
||||
Check real-time logs of any service container
|
||||
|
||||
You can run this command in parallel, while your local environment is already running. Use `-f` to save output to a file.
|
||||
|
||||
```bash
|
||||
nhost logs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Global flags
|
||||
|
||||
Turn on debug output.
|
||||
|
||||
#### `--debug`, `-d`
|
||||
|
||||
```bash
|
||||
nhost dev --debug
|
||||
nhost init -d
|
||||
```
|
||||
|
||||
#### `--log-file`, `-f`
|
||||
|
||||
Save output to a given file.
|
||||
|
||||
```bash
|
||||
nhost dev -d --log-file some-file.txt
|
||||
nhost logs -f some-file.txt
|
||||
```
|
||||
14
docs/docs/reference/cli/up.mdx
Normal file
14
docs/docs/reference/cli/up.mdx
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
title: 'up'
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
Launch the development environment for your app. Once the environment is up, the command will:
|
||||
|
||||
- Apply database migrations.
|
||||
- Apply the Hasura metadata.
|
||||
- Apply seed data.
|
||||
|
||||
```bash
|
||||
nhost up
|
||||
```
|
||||
10
docs/docs/reference/cli/upgrade.mdx
Normal file
10
docs/docs/reference/cli/upgrade.mdx
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: 'upgrade'
|
||||
sidebar_position: 8
|
||||
---
|
||||
|
||||
Upgrade the CLI to the latest version.
|
||||
|
||||
```bash
|
||||
nhost upgrade
|
||||
```
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"label": "Auth"
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: signUp()
|
||||
sidebar_label: signUp()
|
||||
slug: /reference/javascript/auth/sign-up
|
||||
description: Use `nhost.auth.signUp` to sign up a user using email and password. If you want to sign up a user using passwordless email (Magic Link), SMS, or an OAuth provider, use the `signIn` function instead.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L93
|
||||
---
|
||||
|
||||
# `signUp()`
|
||||
|
||||
Use `nhost.auth.signUp` to sign up a user using email and password. If you want to sign up a user using passwordless email (Magic Link), SMS, or an OAuth provider, use the `signIn` function instead.
|
||||
|
||||
```ts
|
||||
nhost.auth.signUp({
|
||||
email: 'joe@example.com',
|
||||
password: 'secret-password'
|
||||
})
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`SignUpEmailPasswordParams`](/reference/docgen/javascript/auth/types/sign-up-email-password-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------ | :-------------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>password</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>email</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>options</span> | `SignUpOptions` | | |
|
||||
|
||||
---
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: signIn()
|
||||
sidebar_label: signIn()
|
||||
slug: /reference/javascript/auth/sign-in
|
||||
description: Use `nhost.auth.signIn` to sign in a user using email and password, passwordless (email or sms) or an external provider. `signIn` can be used to sign in a user in various ways depending on the parameters.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L156
|
||||
---
|
||||
|
||||
# `signIn()`
|
||||
|
||||
Use `nhost.auth.signIn` to sign in a user using email and password, passwordless (email or sms) or an external provider. `signIn` can be used to sign in a user in various ways depending on the parameters.
|
||||
|
||||
```ts
|
||||
nhost.auth.signIn({
|
||||
email: 'joe@example.com',
|
||||
password: 'secret-password'
|
||||
})
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`SignInParams`](/reference/docgen/javascript/auth/types/sign-in-params)
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### Sign in a user using email and password
|
||||
|
||||
```ts
|
||||
nhost.auth.signIn({
|
||||
email: 'joe@example.com',
|
||||
password: 'secret-password'
|
||||
})
|
||||
```
|
||||
|
||||
### Sign in a user using an OAuth provider (e.g: Google or Facebook)
|
||||
|
||||
```ts
|
||||
nhost.auth.signIn({ provider: 'google' })
|
||||
```
|
||||
|
||||
### Sign in a user using passwordless email (Magic Link)
|
||||
|
||||
```ts
|
||||
nhost.auth.signIn({ email: 'joe@example.com' })
|
||||
```
|
||||
|
||||
### Sign in a user using passwordless SMS
|
||||
|
||||
```ts
|
||||
// [step 1/2] Passwordless sign in using SMS
|
||||
nhost.auth.signIn({ phoneNumber: '001122334455' })
|
||||
|
||||
// [step 2/2] Finish passwordless sign in using SMS (OTP)
|
||||
nhost.auth.signIn({ phoneNumber: '001122334455', otp: '123456' })
|
||||
```
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: signOut()
|
||||
sidebar_label: signOut()
|
||||
slug: /reference/javascript/auth/sign-out
|
||||
description: Use `nhost.auth.signOut` to sign out the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L338
|
||||
---
|
||||
|
||||
# `signOut()`
|
||||
|
||||
Use `nhost.auth.signOut` to sign out the user.
|
||||
|
||||
```ts
|
||||
nhost.auth.signOut()
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">optional</span> `{ all: boolean }`
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
### Sign out the user from current device
|
||||
|
||||
```ts
|
||||
nhost.auth.signOut()
|
||||
```
|
||||
|
||||
### Sign out the user from all decvices
|
||||
|
||||
```ts
|
||||
nhost.auth.signOut({ all: true })
|
||||
```
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: resetPassword()
|
||||
sidebar_label: resetPassword()
|
||||
slug: /reference/javascript/auth/reset-password
|
||||
description: Use `nhost.auth.resetPassword` to reset the password for a user. This will send a reset-password link in an email to the user. When the user clicks the reset-password link the user is automatically signed-in. Once signed-in, the user can change their password using `nhost.auth.changePassword()`.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L365
|
||||
---
|
||||
|
||||
# `resetPassword()`
|
||||
|
||||
Use `nhost.auth.resetPassword` to reset the password for a user. This will send a reset-password link in an email to the user. When the user clicks the reset-password link the user is automatically signed-in. Once signed-in, the user can change their password using `nhost.auth.changePassword()`.
|
||||
|
||||
```ts
|
||||
nhost.auth.resetPassword({ email: 'joe@example.com' })
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">\_\_namedParameters</span>** <span className="optional-status">required</span> [`ResetPasswordParams`](/reference/docgen/javascript/auth/types/reset-password-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------------------ | :--------------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>email</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>options</span> | `RedirectOption` | | |
|
||||
|
||||
---
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: changePassword()
|
||||
sidebar_label: changePassword()
|
||||
slug: /reference/javascript/auth/change-password
|
||||
description: Use `nhost.auth.changePassword` to change the password for the user. The old password is not needed.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L390
|
||||
---
|
||||
|
||||
# `changePassword()`
|
||||
|
||||
Use `nhost.auth.changePassword` to change the password for the user. The old password is not needed.
|
||||
|
||||
```ts
|
||||
nhost.auth.changePassword({ newPassword: 'new-secret-password' })
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`ChangePasswordParams`](/reference/docgen/javascript/auth/types/change-password-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :--------------------------------------------------------------------------------------------- | :------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>newPassword</span> | `string` | ✔️ | |
|
||||
|
||||
---
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: sendVerificationEmail()
|
||||
sidebar_label: sendVerificationEmail()
|
||||
slug: /reference/javascript/auth/send-verification-email
|
||||
description: Use `nhost.auth.sendVerificationEmail` to send a verification email to the specified email. The email contains a verification-email link. When the user clicks the verification-email link their email is verified.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L415
|
||||
---
|
||||
|
||||
# `sendVerificationEmail()`
|
||||
|
||||
Use `nhost.auth.sendVerificationEmail` to send a verification email to the specified email. The email contains a verification-email link. When the user clicks the verification-email link their email is verified.
|
||||
|
||||
```ts
|
||||
nhost.auth.sendVerificationEmail({ email: 'joe@example.com' })
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`SendVerificationEmailParams`](/reference/docgen/javascript/auth/types/send-verification-email-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :----------------------------------------------------------------------------------------- | :--------------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>email</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>options</span> | `RedirectOption` | | |
|
||||
|
||||
---
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: changeEmail()
|
||||
sidebar_label: changeEmail()
|
||||
slug: /reference/javascript/auth/change-email
|
||||
description: Use `nhost.auth.changeEmail` to change a user's email. This will send a confirm-email-change link in an email to the new email. Once the user clicks on the confirm-email-change link the email will be change to the new email.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L442
|
||||
---
|
||||
|
||||
# `changeEmail()`
|
||||
|
||||
Use `nhost.auth.changeEmail` to change a user's email. This will send a confirm-email-change link in an email to the new email. Once the user clicks on the confirm-email-change link the email will be change to the new email.
|
||||
|
||||
```ts
|
||||
nhost.auth.changeEmail({ newEmail: 'doe@example.com' })
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">\_\_namedParameters</span>** <span className="optional-status">required</span> [`ChangeEmailParams`](/reference/docgen/javascript/auth/types/change-email-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :------------------------------------------------------------------------------------------------------- | :--------------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>newEmail</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">\_\_namedParameters.</span>options</span> | `RedirectOption` | | |
|
||||
|
||||
---
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: deanonymize()
|
||||
sidebar_label: deanonymize()
|
||||
slug: /reference/javascript/auth/deanonymize
|
||||
description: Use `nhost.auth.deanonymize` to deanonymize a user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L467
|
||||
---
|
||||
|
||||
# `deanonymize()`
|
||||
|
||||
Use `nhost.auth.deanonymize` to deanonymize a user.
|
||||
|
||||
```ts
|
||||
nhost.auth.deanonymize({
|
||||
signInMethod: 'email-password',
|
||||
email: 'joe@example.com'
|
||||
})
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">params</span>** <span className="optional-status">required</span> [`DeanonymizeParams`](/reference/docgen/javascript/auth/types/deanonymize-params)
|
||||
|
||||
| Property | Type | Required | Notes |
|
||||
| :---------------------------------------------------------------------------------------------- | :------------------------------------- | :------: | :---- |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>email</span> | `string` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>signInMethod</span> | `"email-password"` \| `"passwordless"` | ✔️ | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>allowedRoles</span> | `Array<string>` | | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>defaultRole</span> | `string` | | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>connection</span> | `"email"` \| `"sms"` | | |
|
||||
| <span className="parameter-name"><span className="light-grey">params.</span>password</span> | `string` | | |
|
||||
|
||||
---
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: onTokenChanged()
|
||||
sidebar_label: onTokenChanged()
|
||||
slug: /reference/javascript/auth/on-token-changed
|
||||
description: Use `nhost.auth.onTokenChanged` to add a custom function that runs every time the access or refresh token is changed.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L501
|
||||
---
|
||||
|
||||
# `onTokenChanged()`
|
||||
|
||||
Use `nhost.auth.onTokenChanged` to add a custom function that runs every time the access or refresh token is changed.
|
||||
|
||||
```ts
|
||||
nhost.auth.onTokenChanged(() =>
|
||||
console.log('The access and refresh token has changed')
|
||||
)
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">fn</span>** <span className="optional-status">required</span> [`OnTokenChangedFunction`](/reference/docgen/javascript/auth/types/on-token-changed-function)
|
||||
|
||||
---
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: onAuthStateChanged()
|
||||
sidebar_label: onAuthStateChanged()
|
||||
slug: /reference/javascript/auth/on-auth-state-changed
|
||||
description: Use `nhost.auth.onAuthStateChanged` to add a custom function that runs every time the authentication status of the user changes. E.g. add a custom function that runs every time the authentication status changes from signed-in to signed-out.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L536
|
||||
---
|
||||
|
||||
# `onAuthStateChanged()`
|
||||
|
||||
Use `nhost.auth.onAuthStateChanged` to add a custom function that runs every time the authentication status of the user changes. E.g. add a custom function that runs every time the authentication status changes from signed-in to signed-out.
|
||||
|
||||
```ts
|
||||
nhost.auth.onAuthStateChanged((event, session) => {
|
||||
console.log(
|
||||
`The auth state has changed. State is now ${event} with session: ${session}`
|
||||
)
|
||||
})
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">fn</span>** <span className="optional-status">required</span> [`AuthChangedFunction`](/reference/docgen/javascript/auth/types/auth-changed-function)
|
||||
|
||||
---
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: isAuthenticated()
|
||||
sidebar_label: isAuthenticated()
|
||||
slug: /reference/javascript/auth/is-authenticated
|
||||
description: Use `nhost.auth.isAuthenticated` to check if the user is authenticated or not.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L578
|
||||
---
|
||||
|
||||
# `isAuthenticated()`
|
||||
|
||||
Use `nhost.auth.isAuthenticated` to check if the user is authenticated or not.
|
||||
|
||||
```ts
|
||||
const isAuthenticated = nhost.auth.isAuthenticated()
|
||||
|
||||
if (isAuthenticated) {
|
||||
console.log('User is authenticated')
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: isAuthenticatedAsync()
|
||||
sidebar_label: isAuthenticatedAsync()
|
||||
slug: /reference/javascript/auth/is-authenticated-async
|
||||
description: Use `nhost.auth.isAuthenticatedAsync` to wait (await) for any internal authentication network requests to finish and then return the authentication status.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L596
|
||||
---
|
||||
|
||||
# `isAuthenticatedAsync()`
|
||||
|
||||
Use `nhost.auth.isAuthenticatedAsync` to wait (await) for any internal authentication network requests to finish and then return the authentication status.
|
||||
|
||||
```ts
|
||||
const isAuthenticated = await nhost.auth.isAuthenticatedAsync()
|
||||
|
||||
if (isAuthenticated) {
|
||||
console.log('User is authenticated')
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: getAuthenticationStatus()
|
||||
sidebar_label: getAuthenticationStatus()
|
||||
slug: /reference/javascript/auth/get-authentication-status
|
||||
description: Use `nhost.auth.getAuthenticationStatus` to get the authentication status of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L621
|
||||
---
|
||||
|
||||
# `getAuthenticationStatus()`
|
||||
|
||||
Use `nhost.auth.getAuthenticationStatus` to get the authentication status of the user.
|
||||
|
||||
```ts
|
||||
const { isAuthenticated, isLoading } = nhost.auth.getAuthenticationStatus()
|
||||
|
||||
if (isLoading) {
|
||||
console.log('Loading...')
|
||||
}
|
||||
|
||||
if (isAuthenticated) {
|
||||
console.log('User is authenticated')
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: getJWTToken()
|
||||
sidebar_label: getJWTToken()
|
||||
slug: /reference/javascript/auth/get-jwt-token
|
||||
sidebar_class_name: deprecated
|
||||
description: No description provided.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L635
|
||||
---
|
||||
|
||||
# `getJWTToken()`
|
||||
|
||||
:::caution Deprecated
|
||||
Use `nhost.auth.getAccessToken()` instead.
|
||||
:::
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: getAccessToken()
|
||||
sidebar_label: getAccessToken()
|
||||
slug: /reference/javascript/auth/get-access-token
|
||||
description: Use `nhost.auth.getAccessToken` to get the access token of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L649
|
||||
---
|
||||
|
||||
# `getAccessToken()`
|
||||
|
||||
Use `nhost.auth.getAccessToken` to get the access token of the user.
|
||||
|
||||
```ts
|
||||
const accessToken = nhost.auth.getAccessToken()
|
||||
```
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: getDecodedAccessToken()
|
||||
sidebar_label: getDecodedAccessToken()
|
||||
slug: /reference/javascript/auth/get-decoded-access-token
|
||||
description: Use `nhost.auth.getDecodedAccessToken` to get the decoded access token of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L663
|
||||
---
|
||||
|
||||
# `getDecodedAccessToken()`
|
||||
|
||||
Use `nhost.auth.getDecodedAccessToken` to get the decoded access token of the user.
|
||||
|
||||
```ts
|
||||
const decodedAccessToken = nhost.auth.getDecodedAccessToken()
|
||||
```
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: getHasuraClaims()
|
||||
sidebar_label: getHasuraClaims()
|
||||
slug: /reference/javascript/auth/get-hasura-claims
|
||||
description: Use `nhost.auth.getHasuraClaims` to get the Hasura claims of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L679
|
||||
---
|
||||
|
||||
# `getHasuraClaims()`
|
||||
|
||||
Use `nhost.auth.getHasuraClaims` to get the Hasura claims of the user.
|
||||
|
||||
```ts
|
||||
const hasuraClaims = nhost.auth.getHasuraClaims()
|
||||
```
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: getHasuraClaim()
|
||||
sidebar_label: getHasuraClaim()
|
||||
slug: /reference/javascript/auth/get-hasura-claim
|
||||
description: Use `nhost.auth.getHasuraClaim` to get the value of a specific Hasura claim of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L696
|
||||
---
|
||||
|
||||
# `getHasuraClaim()`
|
||||
|
||||
Use `nhost.auth.getHasuraClaim` to get the value of a specific Hasura claim of the user.
|
||||
|
||||
```ts
|
||||
// if `x-hasura-company-id` exists as a custom claim
|
||||
const companyId = nhost.auth.getHsauraClaim('company-id')
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">name</span>** <span className="optional-status">required</span> `string`
|
||||
|
||||
Name of the variable. You don't have to specify `x-hasura-`.
|
||||
|
||||
---
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: refreshSession()
|
||||
sidebar_label: refreshSession()
|
||||
slug: /reference/javascript/auth/refresh-session
|
||||
description: Use `nhost.auth.refreshSession` to refresh the session with either the current internal refresh token or an external refresh token.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L719
|
||||
---
|
||||
|
||||
# `refreshSession()`
|
||||
|
||||
Use `nhost.auth.refreshSession` to refresh the session with either the current internal refresh token or an external refresh token.
|
||||
|
||||
```ts
|
||||
// Refresh the session with the the current internal refresh token.
|
||||
nhost.auth.refreshToken()
|
||||
|
||||
// Refresh the session with an external refresh token.
|
||||
nhost.auth.refreshToken(refreshToken)
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
---
|
||||
|
||||
**<span className="parameter-name">refreshToken</span>** <span className="optional-status">optional</span> `string`
|
||||
|
||||
---
|
||||
@@ -0,0 +1,16 @@
|
||||
---
|
||||
# ⚠️ AUTO-GENERATED CONTENT. DO NOT EDIT THIS FILE DIRECTLY! ⚠️
|
||||
title: getSession()
|
||||
sidebar_label: getSession()
|
||||
slug: /reference/javascript/auth/get-session
|
||||
description: Use `nhost.auth.getSession()` to get the session of the user.
|
||||
custom_edit_url: https://github.com/nhost/nhost/edit/main/packages/hasura-auth-js/src/hasura-auth-client.ts#L763
|
||||
---
|
||||
|
||||
# `getSession()`
|
||||
|
||||
Use `nhost.auth.getSession()` to get the session of the user.
|
||||
|
||||
```ts
|
||||
const session = nhost.auth.getSession()
|
||||
```
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user