Compare commits
15 Commits
@nhost/has
...
@nhost/rea
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22a8d2dc27 | ||
|
|
c8f24880c8 | ||
|
|
083d4eaf14 | ||
|
|
d7956443a8 | ||
|
|
41c6b4d5b7 | ||
|
|
2e1c0555c7 | ||
|
|
764b8818dc | ||
|
|
03562aff43 | ||
|
|
6fd14867cc | ||
|
|
a8805839e9 | ||
|
|
9e94363724 | ||
|
|
48a9986103 | ||
|
|
3a04d88890 | ||
|
|
b618c23a95 | ||
|
|
0d4c88d4cd |
30
.config/esbuild.lib.js
Normal file
30
.config/esbuild.lib.js
Normal file
@@ -0,0 +1,30 @@
|
||||
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: 'esnext'
|
||||
})
|
||||
.catch(() => process.exit(1))
|
||||
@@ -1,62 +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 reactRefresh from '@vitejs/plugin-react-refresh'
|
||||
const PWD = process.env.PWD
|
||||
const pkg = require(path.join(PWD, 'package.json'))
|
||||
|
||||
export const lib = {
|
||||
entry: path.resolve(PWD, 'src/index.ts'),
|
||||
name: pkg.name,
|
||||
fileName: 'index'
|
||||
}
|
||||
export const basePlugins = [
|
||||
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'))
|
||||
}
|
||||
})
|
||||
]
|
||||
|
||||
/**
|
||||
* @type {import('vite').UserConfig}
|
||||
*/
|
||||
export default defineConfig({
|
||||
plugins: basePlugins,
|
||||
build: {
|
||||
lib
|
||||
}
|
||||
})
|
||||
|
||||
// export const react = defineConfig({
|
||||
// plugins: [reactRefresh(), ...basePlugins],
|
||||
// build: {
|
||||
// lib,
|
||||
// rollupOptions: {
|
||||
// external: ['react'],
|
||||
// output: {
|
||||
// globals: {
|
||||
// react: 'react'
|
||||
// }
|
||||
// }
|
||||
|
||||
// // external: ['react', 'vue'],
|
||||
// // output: {
|
||||
// // globals: {
|
||||
// // react: 'react',
|
||||
// // vue: 'vue'
|
||||
// // }
|
||||
// // }
|
||||
// }
|
||||
// }
|
||||
// })
|
||||
@@ -1,22 +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 react from '@vitejs/plugin-react'
|
||||
|
||||
import { basePlugins, lib } from './vite.lib'
|
||||
const PWD = process.env.PWD
|
||||
const pkg = require(path.join(PWD, 'package.json'))
|
||||
|
||||
if (!fs.existsSync(lib.entry)) {
|
||||
lib.entry = lib.entry.replace('.ts', '.tsx')
|
||||
}
|
||||
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(), ...basePlugins],
|
||||
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,
|
||||
lib: {
|
||||
entry,
|
||||
name: pkg.name,
|
||||
fileName: 'index'
|
||||
},
|
||||
rollupOptions: {
|
||||
external: ['react'],
|
||||
output: {
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -40,6 +40,7 @@ todo.md
|
||||
prettier.config.js
|
||||
vite.*.js
|
||||
jest.*.js
|
||||
esbuild.*.js
|
||||
|
||||
!.config/**
|
||||
|
||||
|
||||
6
docs/CHANGELOG.md
Normal file
6
docs/CHANGELOG.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# nhost-documentation
|
||||
|
||||
## null
|
||||
### Patch Changes
|
||||
|
||||
- 03562af: Build in CommonJS and ESM instead of UMD and ESM as the UMD bundle generated by the default Vite lib build mode doesn't work with NodeJS
|
||||
@@ -2,12 +2,10 @@ import Text from '@/components/ui/Text'
|
||||
import { motion } from 'framer-motion'
|
||||
import { useRouter } from 'next/dist/client/router'
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import createKebabCase from '../utils/createKebabCase'
|
||||
import Permalink from './icons/Permalink'
|
||||
|
||||
// import { ReactNode, useState } from 'react';
|
||||
interface AnchorLinkProps {
|
||||
export interface AnchorLinkProps {
|
||||
children?: any
|
||||
id?: string
|
||||
size?: 'tiny' | 'small' | 'normal' | 'large' | 'big' | 'heading'
|
||||
@@ -72,9 +70,8 @@ export default function AnchorLink({ children, id, size, className }: AnchorLink
|
||||
href={createKebabCase(
|
||||
`#${isQuoted ? (children.props ? children.props.children : children) : children}`
|
||||
)}
|
||||
size={size ? size : 'big'}
|
||||
color="greyscaleDark"
|
||||
className="font-medium"
|
||||
className="font-medium break-all"
|
||||
>
|
||||
{children}
|
||||
</Text>
|
||||
|
||||
@@ -32,6 +32,7 @@ export function Content({ mdxSource, components, frontmatter }) {
|
||||
href={getGithubLink(router.query.category, router.query.subcategory, router.query.post)}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
type={null}
|
||||
>
|
||||
Edit This Page
|
||||
<GithubIcon className="w-3.5 h-3.5 ml-1.5 text-greyscaleDark self-center" />
|
||||
|
||||
@@ -30,6 +30,7 @@ export default function Footer() {
|
||||
variant="secondary"
|
||||
className="md:visible invisible mr-2 text-white cursor-pointer"
|
||||
href="mailto:hello@nhost.io"
|
||||
type={null}
|
||||
>
|
||||
Contact Us
|
||||
</Button>
|
||||
@@ -40,6 +41,7 @@ export default function Footer() {
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="cursor-pointer"
|
||||
type={null}
|
||||
>
|
||||
<span className="md:block hidden">Sign up or Log in</span>
|
||||
<span className="md:hidden">Sign up</span>
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import { MenuIcon } from '@heroicons/react/outline'
|
||||
import { useNavData } from '@/components/NavDataContext'
|
||||
import { ArrowLeftIcon, MenuIcon } from '@heroicons/react/outline'
|
||||
import clsx from 'clsx'
|
||||
import { useRouter } from 'next/dist/client/router'
|
||||
import Link from 'next/link'
|
||||
import React, { useEffect } from 'react'
|
||||
import { useState } from 'react'
|
||||
|
||||
import React, { MouseEvent, useEffect, useState } from 'react'
|
||||
import Button from '../components/ui/Button'
|
||||
import { Nav } from './Nav'
|
||||
|
||||
export default function Header() {
|
||||
const [mobileMenu, setMobileMenu] = useState(false)
|
||||
const router = useRouter()
|
||||
const GithubStarsCounter = () => {
|
||||
const repoUrl = `https://api.github.com/repos/nhost/nhost`
|
||||
const [count, setCount] = useState(null);
|
||||
const format = n => n > 1000 ? `${(n / 1000).toFixed(1)}k` : n;
|
||||
const [count, setCount] = useState(null)
|
||||
const format = (n: number) => (n > 1000 ? `${(n / 1000).toFixed(1)}k` : n)
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
const data = await fetch(repoUrl).then(res => res.json());
|
||||
setCount(data.stargazers_count);
|
||||
})();
|
||||
}, []);
|
||||
;(async () => {
|
||||
const data = await fetch(repoUrl).then((res) => res.json())
|
||||
setCount(data.stargazers_count)
|
||||
})()
|
||||
}, [repoUrl])
|
||||
|
||||
return (
|
||||
<a
|
||||
@@ -40,154 +40,234 @@ export default function Header() {
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
function handleMobileMenuOpen() {
|
||||
setMobileMenu(true)
|
||||
}
|
||||
|
||||
function handleMobileMenuClose() {
|
||||
setMobileMenu(false)
|
||||
}
|
||||
|
||||
if (mobileMenu) {
|
||||
return <MobileNav onClose={handleMobileMenuClose} />
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="bg-white md:max-w-full drop">
|
||||
{mobileMenu ? (
|
||||
<MobileNav setMobileMenu={setMobileMenu} mobileMenu={mobileMenu} />
|
||||
) : (
|
||||
<div className="md:max-w-header2 mx-auto font-display flex flex-row antialiased px-4 ">
|
||||
<div className="flex flex-row w-full mx-auto place-content-between py-2">
|
||||
<div className="flex flex-row">
|
||||
<div className="md:hidden">
|
||||
<MenuIcon
|
||||
className="h-8 w-8 cursor-pointer text-greyscaleDark"
|
||||
aria-hidden="true"
|
||||
onClick={() => setMobileMenu(!mobileMenu)}
|
||||
/>
|
||||
</div>
|
||||
<header className="bg-white md:max-w-full menu-card rounded-md px-4 py-0.5 mx-2">
|
||||
<div className="md:max-w-header2 mx-auto font-display flex flex-row antialiased">
|
||||
<div className="flex flex-row w-full mx-auto place-content-between py-2">
|
||||
<div className="flex flex-row">
|
||||
<button
|
||||
className="md:hidden w-8 h-8 flex items-center justify-center cursor-pointer text-greyscaleDark"
|
||||
aria-label="Open menu"
|
||||
onClick={handleMobileMenuOpen}
|
||||
>
|
||||
<MenuIcon className="h-6 w-6" />
|
||||
</button>
|
||||
|
||||
<Link href="/get-started" passHref>
|
||||
<a className="hidden ml-3 sm:ml-0 self-center md:flex flex-row cursor-pointer">
|
||||
<img src="/images/nhost-docs.svg" width={110} height={35} alt="Nhost white logo" />
|
||||
<h1 className="self-center ml-6 font-medium text-greyscaleDark">DOCS</h1>
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
<div className="ml-20 hidden md:flex flex-row self-center ">
|
||||
<ul className="flex flex-row items-center self-center antialiased font-medium text-greyscaleGrey font-display">
|
||||
<Link href="/get-started" passHref={true}>
|
||||
<a
|
||||
className={clsx(
|
||||
'cursor-pointer text-base- self-center hover:text-greyscaleDark transition-colors duration-200 py-3',
|
||||
router.query.category === 'get-started' && 'text-greyscaleDark'
|
||||
)}
|
||||
>
|
||||
Get Started
|
||||
</a>
|
||||
</Link>
|
||||
<Link href="/platform" passHref={true}>
|
||||
<a
|
||||
className={clsx(
|
||||
'ml-12 cursor-pointer text-base- self-center hover:text-greyscaleDark transition-colors duration-200 py-3',
|
||||
router.query.category === 'platform' && 'text-greyscaleDark'
|
||||
)}
|
||||
>
|
||||
Platform
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
<Link href="/reference" passHref={true}>
|
||||
<a
|
||||
className={clsx(
|
||||
'ml-12 cursor-pointer text-base- self-center hover:text-greyscaleDark transition-colors duration-200 py-3',
|
||||
router.query.category === 'reference' && 'text-greyscaleDark'
|
||||
)}
|
||||
>
|
||||
Reference
|
||||
</a>
|
||||
</Link>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="hidden sm:flex self-center">
|
||||
<GithubStarsCounter />
|
||||
<Button
|
||||
className="self-center"
|
||||
variant="primary"
|
||||
href={'https://app.nhost.io'}
|
||||
Component="a"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
type={null}
|
||||
>
|
||||
Go to Nhost
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
|
||||
export type MobileNavProps = {
|
||||
onClose?: VoidFunction
|
||||
}
|
||||
|
||||
export function MobileNav({ onClose }: MobileNavProps) {
|
||||
const { getConvolutedNavByCategory } = useNavData()
|
||||
const router = useRouter()
|
||||
const [selectedMenuSlug, setSelectedMenuSlug] = useState<string | null>(null)
|
||||
const [selectedMenuName, setSelectedMenuName] = useState<string | null>(null)
|
||||
|
||||
function handleMenuSelect(event: MouseEvent<HTMLAnchorElement>, slug: string, name: string) {
|
||||
event.preventDefault()
|
||||
|
||||
setSelectedMenuSlug(slug)
|
||||
setSelectedMenuName(name)
|
||||
}
|
||||
|
||||
function clearMenuSelection() {
|
||||
setSelectedMenuSlug(null)
|
||||
setSelectedMenuName(null)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="bg-white menu-card rounded-lg px-4 pb-6 max-w-full mx-2">
|
||||
<div className="flex flex-col w-full py-3 mx-auto">
|
||||
<div className="grid grid-flow-col justify-between items-center">
|
||||
{!selectedMenuSlug && (
|
||||
<>
|
||||
<button
|
||||
className="w-8 h-8 flex items-center justify-center cursor-pointer text-greyscaleDark"
|
||||
aria-label="Close menu"
|
||||
onClick={onClose}
|
||||
>
|
||||
<MenuIcon className="h-6 w-6" aria-hidden="true" />
|
||||
</button>
|
||||
|
||||
<Link href="/get-started" passHref>
|
||||
<a className="hidden ml-3 sm:ml-0 self-center md:flex flex-row cursor-pointer">
|
||||
<a
|
||||
className="ml-3 sm:ml-0 self-center flex flex-row cursor-pointer"
|
||||
onClick={onClose}
|
||||
>
|
||||
<img
|
||||
src="/images/nhost-docs.svg"
|
||||
width={110}
|
||||
height={35}
|
||||
alt="Nhost white logo"
|
||||
/>
|
||||
<h1 className="self-center ml-6 font-medium text-greyscaleDark">DOCS</h1>
|
||||
<h1 className="self-center ml-5 font-medium text-greyscaleDark">DOCS</h1>
|
||||
</a>
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
|
||||
<div className="ml-20 hidden md:flex flex-row self-center ">
|
||||
<ul className="flex flex-row items-center self-center antialiased font-medium text-greyscaleGrey font-display">
|
||||
<Link href="/get-started" passHref={true}>
|
||||
<a
|
||||
className={clsx(
|
||||
'cursor-pointer text-base- self-center hover:text-greyscaleDark transition-colors duration-200 py-3',
|
||||
router.query.category === 'get-started' && 'text-greyscaleDark'
|
||||
)}
|
||||
>
|
||||
Get Started
|
||||
</a>
|
||||
</Link>
|
||||
<Link href="/platform" passHref={true}>
|
||||
<a
|
||||
className={clsx(
|
||||
'ml-12 cursor-pointer text-base- self-center hover:text-greyscaleDark transition-colors duration-200 py-3',
|
||||
router.query.category === 'platform' && 'text-greyscaleDark'
|
||||
)}
|
||||
>
|
||||
Platform
|
||||
</a>
|
||||
</Link>
|
||||
{selectedMenuSlug && (
|
||||
<button
|
||||
className="ml-2 h-8 grid grid-flow-col gap-2 items-center justify-center cursor-pointer text-greyscaleDark"
|
||||
aria-label="Go back to main menu"
|
||||
onClick={clearMenuSelection}
|
||||
>
|
||||
<ArrowLeftIcon className="h-4 w-4" aria-hidden="true" />{' '}
|
||||
<span className="font-medium text-base-">{selectedMenuName}</span>
|
||||
</button>
|
||||
)}
|
||||
|
||||
<Link href="/reference" passHref={true}>
|
||||
<a
|
||||
className={clsx(
|
||||
'ml-12 cursor-pointer text-base- self-center hover:text-greyscaleDark transition-colors duration-200 py-3',
|
||||
router.query.category === 'reference' && 'text-greyscaleDark'
|
||||
)}
|
||||
>
|
||||
Reference
|
||||
</a>
|
||||
</Link>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="hidden sm:flex self-center">
|
||||
<GithubStarsCounter />
|
||||
<Button
|
||||
className="self-center"
|
||||
variant="primary"
|
||||
href={'https://app.nhost.io'}
|
||||
Component="a"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
{/* Placeholder for making logo appear correctly in the middle */}
|
||||
<div className="w-8 h-8" />
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col py-6 mt-4 border-divide border-t border-b">
|
||||
{!selectedMenuSlug && (
|
||||
<ul className="flex flex-col font-medium text-greyscaleDark text-base- font-display space-y-4 text-left px-4">
|
||||
<li
|
||||
className={clsx(
|
||||
'cursor-pointer text-base- hover:text-greyscaleDark transition-colors duration-200 text-left ',
|
||||
router.query.category === 'get-started' && 'text-greyscaleDark'
|
||||
)}
|
||||
>
|
||||
Go to Nhost
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<Link href="/get-started" passHref>
|
||||
<a
|
||||
className="block"
|
||||
onClick={(event) => handleMenuSelect(event, 'get-started', 'Get Started')}
|
||||
>
|
||||
Get Started
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
<li
|
||||
className={clsx(
|
||||
'cursor-pointer text-base- hover:text-greyscaleDark transition-colors duration-200 text-left',
|
||||
router.query.category === 'platform' && 'text-greyscaleDark'
|
||||
)}
|
||||
>
|
||||
<Link href="/platform">
|
||||
<a
|
||||
className="block"
|
||||
onClick={(event) => handleMenuSelect(event, 'platform', 'Platform')}
|
||||
>
|
||||
Platform
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
<li
|
||||
className={clsx(
|
||||
'cursor-pointer text-base- hover:text-greyscaleDark transition-colors duration-200',
|
||||
router.query.category === 'reference' && 'text-greyscaleDark'
|
||||
)}
|
||||
>
|
||||
<Link href="/reference">
|
||||
<a
|
||||
className="block"
|
||||
onClick={(event) => handleMenuSelect(event, 'reference', 'Reference')}
|
||||
>
|
||||
Reference
|
||||
</a>
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
)}
|
||||
|
||||
export function MobileNav({ setMobileMenu, mobileMenu }) {
|
||||
const router = useRouter()
|
||||
return (
|
||||
<div className="bg-white rounded-sm shadow-sm drop w-full ">
|
||||
<div className="flex flex-col w-full py-3 mx-auto ">
|
||||
<div className="flex flex-row">
|
||||
<div className="md:hidden">
|
||||
<MenuIcon
|
||||
className="h-8 w-8 cursor-pointer text-greyscaleDark"
|
||||
aria-hidden="true"
|
||||
onClick={() => setMobileMenu(!mobileMenu)}
|
||||
{selectedMenuSlug && (
|
||||
<Nav
|
||||
category={selectedMenuSlug}
|
||||
categoryTitle={selectedMenuName}
|
||||
convolutedNav={getConvolutedNavByCategory(selectedMenuSlug)}
|
||||
onMenuSelected={onClose}
|
||||
/>
|
||||
</div>
|
||||
<div className="mx-auto">
|
||||
<Link href="/" passHref>
|
||||
<a className="md:hidden ml-3 sm:ml-0 self-center flex flex-row cursor-pointer">
|
||||
<img src="/images/nhost-docs.svg" width={110} height={35} alt="Nhost white logo" />
|
||||
<h1 className="self-center ml-5 font-medium text-greyscaleDark">DOCS</h1>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex py-6 mt-4 border-divide border-t border-b ">
|
||||
<ul className="flex flex-col font-medium text-greyscaleDark text-base- font-display space-y-4 text-left px-4 ">
|
||||
<li
|
||||
className={clsx(
|
||||
'cursor-pointer text-base- hover:text-greyscaleDark transition-colors duration-200 text-left ',
|
||||
router.query.category === 'get-started' && 'text-greyscaleDark'
|
||||
)}
|
||||
>
|
||||
<Link href="/get-started" passHref={true}>
|
||||
Get Started
|
||||
</Link>
|
||||
</li>
|
||||
<li
|
||||
className={clsx(
|
||||
'cursor-pointer text-base- hover:text-greyscaleDark transition-colors duration-200 text-left',
|
||||
router.query.category === 'platform' && 'text-greyscaleDark'
|
||||
)}
|
||||
>
|
||||
<Link href="/platform" passHref={true}>
|
||||
<a>Platform</a>
|
||||
</Link>
|
||||
</li>
|
||||
<li
|
||||
className={clsx(
|
||||
'cursor-pointer text-base- hover:text-greyscaleDark transition-colors duration-200',
|
||||
router.query.category === 'reference' && 'text-greyscaleDark'
|
||||
)}
|
||||
>
|
||||
<Link href="/reference" passHref={true}>
|
||||
<a>Reference</a>
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="sm:flex self-center py-2">
|
||||
<Button
|
||||
className="self-center"
|
||||
variant="primary"
|
||||
href={'https://app.nhost.io'}
|
||||
href="https://app.nhost.io"
|
||||
Component="a"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
type={null}
|
||||
>
|
||||
Go to Nhost
|
||||
</Button>
|
||||
|
||||
@@ -10,7 +10,7 @@ import Copy from '../icons/Copy'
|
||||
// @ts-ignore -> add to types
|
||||
SyntaxHighlighter.registerLanguage('js', js)
|
||||
|
||||
interface CodeEditorProps {
|
||||
export interface CodeEditorProps {
|
||||
code: string
|
||||
fileName: string
|
||||
className: string
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import AnchorLink from '@/components/AnchorLink'
|
||||
import CodeComponent from '@/components/MDX/CodeComponent'
|
||||
import Text from '@/components/ui/Text'
|
||||
import AnchorLink, { AnchorLinkProps } from '@/components/AnchorLink'
|
||||
import CodeComponent, { CodeEditorProps } from '@/components/MDX/CodeComponent'
|
||||
import Text, { TextProps } from '@/components/ui/Text'
|
||||
import clsx from 'clsx'
|
||||
import Image from 'next/image'
|
||||
import Link from 'next/link'
|
||||
import React from 'react'
|
||||
import React, { DetailedHTMLProps, HTMLProps, PropsWithChildren } from 'react'
|
||||
|
||||
import Command from '../Command'
|
||||
import Divider from '../Divider'
|
||||
|
||||
function Note({ children }) {
|
||||
function Note({ children }: PropsWithChildren<unknown>) {
|
||||
return (
|
||||
<div className="px-5 py-5 my-5 space-y-2 text-white rounded-md bg-verydark">
|
||||
<Text className="text-white">Note</Text>
|
||||
@@ -17,57 +18,70 @@ function Note({ children }) {
|
||||
)
|
||||
}
|
||||
|
||||
function Video({ src }) {
|
||||
function Video({
|
||||
src,
|
||||
...props
|
||||
}: DetailedHTMLProps<HTMLProps<HTMLSourceElement>, HTMLSourceElement>) {
|
||||
return (
|
||||
<div className="flex justify-center my-8 mx-10">
|
||||
<div className="flex justify-center mx-10 my-8">
|
||||
<video width="800" controls>
|
||||
<source src={src} type="video/mp4" />
|
||||
<source src={src} type="video/mp4" {...props} />
|
||||
</video>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const CustomLink = (props) => {
|
||||
const href = props.href
|
||||
const isInternalLink = href && (href.startsWith('/') || href.startsWith('#'))
|
||||
const CustomLink = ({
|
||||
className,
|
||||
children,
|
||||
href,
|
||||
...props
|
||||
}: DetailedHTMLProps<HTMLProps<HTMLAnchorElement>, HTMLAnchorElement>) => {
|
||||
const isInternalLink = href && ['./', '../', '/', '#'].some((symbol) => href.startsWith(symbol))
|
||||
|
||||
if (isInternalLink) {
|
||||
return (
|
||||
<Link href={href}>
|
||||
<a {...props} className="font-medium text-blue">
|
||||
{props.children}
|
||||
<Link href={href} passHref>
|
||||
<a className={clsx('font-medium text-blue', className)} {...props}>
|
||||
{children}
|
||||
</a>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<a target="_blank" className="font-medium text-blue" rel="noopener noreferrer" {...props} />
|
||||
<a
|
||||
target="_blank"
|
||||
className={clsx('font-medium text-blue', className)}
|
||||
rel="noopener noreferrer"
|
||||
href={href}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
|
||||
const components = {
|
||||
img: (props) => {
|
||||
img: (props: DetailedHTMLProps<HTMLProps<HTMLImageElement>, HTMLImageElement>) => {
|
||||
return (
|
||||
<>
|
||||
<span className="block mt-5 mx-10 ">
|
||||
<img src={props.src} alt={props.alt} className="mx-auto border mt-2" />
|
||||
{props.alt && (
|
||||
<div className="block text-center text-secondary text-sm mb-8 pt-4">
|
||||
<Text color="greyscaleDark" size="tiny">
|
||||
{props.alt}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
</span>
|
||||
</>
|
||||
<span className="block mx-10 mt-5 ">
|
||||
<img src={props.src} alt={props.alt} className="mx-auto mt-2 border" />
|
||||
{props.alt && (
|
||||
<div className="block pt-4 mb-8 text-sm text-center text-secondary">
|
||||
<Text color="greyscaleDark" size="tiny">
|
||||
{props.alt}
|
||||
</Text>
|
||||
</div>
|
||||
)}
|
||||
</span>
|
||||
)
|
||||
},
|
||||
Video,
|
||||
Image,
|
||||
Text,
|
||||
Note,
|
||||
code: (props) => {
|
||||
code: (props: CodeEditorProps) => {
|
||||
if (props.className && props.className.includes('language')) {
|
||||
return <CodeComponent {...props} />
|
||||
} else {
|
||||
@@ -76,50 +90,58 @@ const components = {
|
||||
},
|
||||
Divider,
|
||||
a: CustomLink,
|
||||
h1: (props) => {
|
||||
h1: (props: AnchorLinkProps) => {
|
||||
return (
|
||||
<>
|
||||
<Divider />
|
||||
<AnchorLink {...props} size="heading" className="cursor-pointer" />
|
||||
<AnchorLink {...props} className="text-3xl cursor-pointer md:text-4xl" />
|
||||
</>
|
||||
)
|
||||
},
|
||||
h2: (props) => {
|
||||
h2: (props: AnchorLinkProps) => {
|
||||
return (
|
||||
<>
|
||||
<div className="mt-10">
|
||||
<AnchorLink {...props} size="big" className="cursor-pointer" />
|
||||
</div>
|
||||
</>
|
||||
<div className="mt-10">
|
||||
<AnchorLink {...props} className="cursor-pointer text-lg sm:text-xl md:text-2.5xl" />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
h3: (props) => {
|
||||
h3: (props: AnchorLinkProps) => {
|
||||
return (
|
||||
<>
|
||||
<div className="mt-8">
|
||||
<AnchorLink {...props} size="large" className="cursor-pointer" />
|
||||
</div>
|
||||
</>
|
||||
<div className="mt-8">
|
||||
<AnchorLink {...props} className="text-lg cursor-pointer" />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
h4: (props) => {
|
||||
h4: (props: AnchorLinkProps) => {
|
||||
return (
|
||||
<>
|
||||
<div className="mt-4">
|
||||
<AnchorLink {...props} size="normal" className="font-bold cursor-pointer" />
|
||||
</div>
|
||||
</>
|
||||
<div className="mt-4">
|
||||
<AnchorLink {...props} className="font-bold cursor-pointer text-base-" />
|
||||
</div>
|
||||
)
|
||||
},
|
||||
p: (props) => (
|
||||
<Text
|
||||
variant="body"
|
||||
size="small"
|
||||
color="dark"
|
||||
className="my-2 antialiased leading-6"
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
p: (props: TextProps) => {
|
||||
return (
|
||||
<Text
|
||||
variant="body"
|
||||
size="small"
|
||||
color="dark"
|
||||
className="my-2 antialiased leading-6"
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
},
|
||||
th: ({
|
||||
className,
|
||||
...props
|
||||
}: DetailedHTMLProps<HTMLProps<HTMLTableCellElement>, HTMLTableCellElement>) => {
|
||||
return <th className={clsx('font-display', className)} {...props} />
|
||||
},
|
||||
td: ({
|
||||
className,
|
||||
...props
|
||||
}: DetailedHTMLProps<HTMLProps<HTMLTableCellElement>, HTMLTableCellElement>) => {
|
||||
return <td className={clsx('font-display', className)} {...props} />
|
||||
}
|
||||
}
|
||||
|
||||
export default components
|
||||
|
||||
@@ -2,104 +2,127 @@ import Text from '@/components/ui/Text'
|
||||
import clsx from 'clsx'
|
||||
import Link from 'next/link'
|
||||
import { useRouter } from 'next/router'
|
||||
import React from 'react'
|
||||
import { ParsedUrlQuery } from 'querystring'
|
||||
import React, { MouseEvent } from 'react'
|
||||
import { fixTitle } from '../utils/fixTitle'
|
||||
import { NavItem } from './NavDataContext'
|
||||
|
||||
export function Nav(props) {
|
||||
export type NavProps = {
|
||||
/**
|
||||
* Class name to apply to the wrapper element.
|
||||
*/
|
||||
className?: string
|
||||
/**
|
||||
* Category slug.
|
||||
*/
|
||||
category: string
|
||||
/**
|
||||
* The category title.
|
||||
*/
|
||||
categoryTitle: string
|
||||
/**
|
||||
* Convoluted navigation.
|
||||
*/
|
||||
convolutedNav: NavItem[]
|
||||
/**
|
||||
* Function to be called when a menu item is selected.
|
||||
*/
|
||||
onMenuSelected?: (event?: MouseEvent<HTMLAnchorElement, MouseEvent>) => void
|
||||
}
|
||||
|
||||
export function Nav({ className, onMenuSelected, ...props }: NavProps) {
|
||||
const router = useRouter()
|
||||
|
||||
return (
|
||||
<div className="hidden lg:flex lg:min-w-nav lg:w-nav flex-col space-y-5 antialiased mt-1">
|
||||
<div className={clsx('lg:min-w-nav lg:w-nav flex-col space-y-5 antialiased mt-1', className)}>
|
||||
<div>
|
||||
<ul>
|
||||
<Link href={`/${props.category}`} passHref>
|
||||
<li
|
||||
className={clsx(
|
||||
'cursor-pointer py-1 px-3 transition duration-300 ease-in-out rounded-md hover:text-black hover:bg-veryLightGray',
|
||||
router.query.category === props.category &&
|
||||
!router.query.subcategory &&
|
||||
!router.query.post &&
|
||||
'bg-veryLightGray'
|
||||
)}
|
||||
>
|
||||
<li
|
||||
className={clsx(
|
||||
'transition duration-300 ease-in-out rounded-md hover:text-black hover:bg-veryLightGray',
|
||||
router.query.category === props.category &&
|
||||
!router.query.subcategory &&
|
||||
!router.query.post &&
|
||||
'bg-veryLightGray'
|
||||
)}
|
||||
>
|
||||
<Link href={`/${props.category}`} passHref>
|
||||
<Text
|
||||
variant="a"
|
||||
color="greyscaleDark"
|
||||
size="normal"
|
||||
className={clsx(
|
||||
'transition-colors duration-300 ease-in-out text-greyscaleDark hover:text-dark subpixel-antialiased',
|
||||
'block py-1.5 px-3 transition-colors duration-300 ease-in-out text-greyscaleDark hover:text-dark subpixel-antialiased',
|
||||
'font-medium'
|
||||
)}
|
||||
onClick={onMenuSelected}
|
||||
>
|
||||
{props.categoryTitle}
|
||||
</Text>
|
||||
</li>
|
||||
</Link>
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{props.convolutedNav.map((elem) => {
|
||||
const parentCategory = props.category.replace(' ', '-')
|
||||
|
||||
return (
|
||||
<>
|
||||
<div key={elem.category} className="">
|
||||
{/* <Link
|
||||
href={`/${props.category.replace(" ", "-")}/${elem.category}`}
|
||||
passHref
|
||||
> */}
|
||||
<div className="cursor-pointer">
|
||||
<Link href={`/${props.category.replace(' ', '-')}/${elem.category}/`} passHref>
|
||||
<Text
|
||||
variant="a"
|
||||
color="greyscaleGrey"
|
||||
size="normal"
|
||||
className="font-medium capitalize px-3"
|
||||
<div key={elem.category}>
|
||||
<Link href={`/${parentCategory}/${elem.category}/`} passHref>
|
||||
<Text
|
||||
variant="a"
|
||||
color="greyscaleGrey"
|
||||
size="normal"
|
||||
className="block px-3 py-px font-medium capitalize"
|
||||
onClick={onMenuSelected}
|
||||
>
|
||||
{/* Split */}
|
||||
{fixTitle(elem)}
|
||||
</Text>
|
||||
</Link>
|
||||
|
||||
<ul className="mt-1 space-y-1 ">
|
||||
{elem.posts.map((post) => {
|
||||
const pathToLink =
|
||||
post.fileName != 'index'
|
||||
? `/${parentCategory}/${elem.category}/${post.fileName}`
|
||||
: `/${parentCategory}/${elem.category}`
|
||||
|
||||
const shouldHighlight =
|
||||
router.query.subcategory === elem.category && router.query.post === post.fileName
|
||||
|
||||
const shouldHighlightSubcategories =
|
||||
!router.query.post &&
|
||||
post.fileName === 'index' &&
|
||||
elem.category === router.query.subcategory
|
||||
|
||||
return (
|
||||
<li
|
||||
className={clsx(
|
||||
'transition duration-300 ease-in-out rounded-md hover:text-black hover:bg-veryLightGray',
|
||||
(shouldHighlight || shouldHighlightSubcategories) && 'bg-veryLightGray'
|
||||
)}
|
||||
key={pathToLink}
|
||||
>
|
||||
{/* Split */}
|
||||
{fixTitle(elem)}
|
||||
</Text>
|
||||
</Link>
|
||||
</div>
|
||||
{/* </Link> */}
|
||||
|
||||
<ul className="space-y-1 mt-1 ">
|
||||
{elem.posts.map((post) => {
|
||||
const pathToLink =
|
||||
post.fileName != 'index'
|
||||
? `${props.pathname}/${elem.category}/${post.fileName}`
|
||||
: `${props.pathname}/${elem.category}`
|
||||
|
||||
const shouldHiglight =
|
||||
router.query.subcategory === elem.category && props.query.post === post.fileName
|
||||
|
||||
const shouldHighlightSubCategories =
|
||||
!router.query.post &&
|
||||
post.fileName === 'index' &&
|
||||
elem.category === router.query.subcategory
|
||||
|
||||
return (
|
||||
<Link href={pathToLink} passHref key={post}>
|
||||
<li
|
||||
<Link href={pathToLink} passHref>
|
||||
<Text
|
||||
variant="a"
|
||||
color="greyscaleDark"
|
||||
size="normal"
|
||||
className={clsx(
|
||||
'cursor-pointer py-1 px-3 transition duration-300 ease-in-out rounded-md hover:text-black hover:bg-veryLightGray',
|
||||
(shouldHiglight || shouldHighlightSubCategories) && 'bg-veryLightGray'
|
||||
'py-1.5 px-3 block transition-colors duration-300 ease-in-out text-greyscaleDark hover:text-dark subpixel-antialiased block',
|
||||
(shouldHighlight || shouldHighlightSubcategories) && 'font-medium'
|
||||
)}
|
||||
onClick={onMenuSelected}
|
||||
>
|
||||
<Text
|
||||
variant="a"
|
||||
color="greyscaleDark"
|
||||
size="normal"
|
||||
className={clsx(
|
||||
'transition-colors duration-300 ease-in-out text-greyscaleDark hover:text-dark subpixel-antialiased',
|
||||
(shouldHiglight || shouldHighlightSubCategories) && 'font-medium'
|
||||
)}
|
||||
>
|
||||
{post.title}
|
||||
</Text>
|
||||
</li>
|
||||
{post.title}
|
||||
</Text>
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
85
docs/components/NavDataContext.tsx
Normal file
85
docs/components/NavDataContext.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
import { ParsedUrlQuery } from 'querystring'
|
||||
import { createContext, PropsWithChildren, useContext } from 'react'
|
||||
|
||||
export type Post = {
|
||||
/**
|
||||
* Title of the post.
|
||||
*/
|
||||
title: string
|
||||
/**
|
||||
* File name where the post is located.
|
||||
*/
|
||||
fileName: string
|
||||
/**
|
||||
* Order of posts.
|
||||
*/
|
||||
order: string[]
|
||||
}
|
||||
|
||||
export type NavItem = {
|
||||
/**
|
||||
* Slug of the category.
|
||||
*/
|
||||
category: string
|
||||
/**
|
||||
* List of posts in the category.
|
||||
*/
|
||||
posts: Post[]
|
||||
}
|
||||
|
||||
export type NavDataContextProps = {
|
||||
/**
|
||||
* Category slug.
|
||||
*/
|
||||
category: string
|
||||
/**
|
||||
* The category title.
|
||||
*/
|
||||
categoryTitle: string
|
||||
/**
|
||||
* Convoluted navigation.
|
||||
*/
|
||||
convolutedNav: NavItem[]
|
||||
/**
|
||||
* Available menu items for all categories.
|
||||
*/
|
||||
availableCategoryMenus: {
|
||||
/**
|
||||
* Slug of the category.
|
||||
*/
|
||||
slug: string
|
||||
/**
|
||||
* Menu items of the category.
|
||||
*/
|
||||
items: NavItem[]
|
||||
}[]
|
||||
}
|
||||
|
||||
export const NavDataContext = createContext<NavDataContextProps>(null)
|
||||
|
||||
export function NavDataProvider({ children, ...props }: PropsWithChildren<NavDataContextProps>) {
|
||||
return <NavDataContext.Provider value={props}>{children}</NavDataContext.Provider>
|
||||
}
|
||||
|
||||
export function useNavData() {
|
||||
const context = useContext(NavDataContext)
|
||||
|
||||
if (!context) {
|
||||
throw new Error(`"useNavData" must be used within a "NavDataProvider"`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all of the navigation items for the specified category.
|
||||
*
|
||||
* @param slug Slug of the category.
|
||||
* @returns All of the navigation items for the specified category.
|
||||
*/
|
||||
function getConvolutedNavByCategory(slug: string) {
|
||||
return (
|
||||
context.availableCategoryMenus.find(({ slug: category }) => category === slug)?.items ||
|
||||
context.convolutedNav
|
||||
)
|
||||
}
|
||||
|
||||
return { getConvolutedNavByCategory, ...context }
|
||||
}
|
||||
@@ -7,8 +7,11 @@ import Loading from './ui/Loading'
|
||||
|
||||
function NewsletterForm(props) {
|
||||
return (
|
||||
<div className=" flex flex-row w-64 mt-5">
|
||||
<form className=" flex flex-row" onSubmit={(e) => props.subscribe(e)}>
|
||||
<div className="flex flex-row w-64 mt-5">
|
||||
<form
|
||||
className="grid grid-flow-row sm:grid-flow-col gap-4"
|
||||
onSubmit={(e) => props.subscribe(e)}
|
||||
>
|
||||
<Input
|
||||
color="dark"
|
||||
placeholder="Email address"
|
||||
@@ -32,7 +35,7 @@ function NewsletterError({ errorMessage, retry }) {
|
||||
? errorMessage.split('.').slice(0, 2).join('.')
|
||||
: errorMessage
|
||||
return (
|
||||
<div className="flex flex-row mt-5">
|
||||
<div className="grid grid-flow-row md:grid-flow-col gap-4 mt-5">
|
||||
<p className="text-white font-normal text-sm mt-2.5">{formattedError}.</p>
|
||||
<button
|
||||
className="btn-subscribe font-display text-greyscaleDark font-medium cursor-pointer"
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
import cn from 'classnames'
|
||||
import React, { CSSProperties, FunctionComponent, JSXElementConstructor } from 'react'
|
||||
import React, {
|
||||
CSSProperties,
|
||||
ForwardedRef,
|
||||
forwardRef,
|
||||
FunctionComponent,
|
||||
JSXElementConstructor
|
||||
} from 'react'
|
||||
import mergeRefs from 'react-merge-refs'
|
||||
import s from './Text.module.css'
|
||||
|
||||
interface TextProps {
|
||||
export interface TextProps {
|
||||
variant?: Variant
|
||||
className?: string
|
||||
style?: CSSProperties
|
||||
@@ -23,20 +30,23 @@ type Size = 'tiny' | 'small' | 'normal' | 'large' | 'big' | 'heading'
|
||||
|
||||
type Color = 'dark' | 'grey' | 'blue' | 'greyscaleDark' | 'greyscaleGrey' | 'red' | 'white'
|
||||
|
||||
export const Text: FunctionComponent<TextProps> = ({
|
||||
style,
|
||||
className = '',
|
||||
variant = 'body',
|
||||
color,
|
||||
children,
|
||||
html,
|
||||
onClick,
|
||||
size,
|
||||
rel,
|
||||
href,
|
||||
target,
|
||||
name
|
||||
}) => {
|
||||
export const Text: FunctionComponent<TextProps> = forwardRef(function DefaultText(
|
||||
{
|
||||
style,
|
||||
className = '',
|
||||
variant = 'body',
|
||||
color,
|
||||
children,
|
||||
html,
|
||||
onClick,
|
||||
size,
|
||||
rel,
|
||||
href,
|
||||
target,
|
||||
name
|
||||
},
|
||||
ref: ForwardedRef<HTMLElement>
|
||||
) {
|
||||
const componentsMap: {
|
||||
[P in Variant]: React.ComponentType<any> | string
|
||||
} = {
|
||||
@@ -72,6 +82,7 @@ export const Text: FunctionComponent<TextProps> = ({
|
||||
|
||||
return (
|
||||
<Component
|
||||
ref={ref}
|
||||
className={cn(
|
||||
s.root,
|
||||
{
|
||||
@@ -107,6 +118,6 @@ export const Text: FunctionComponent<TextProps> = ({
|
||||
{children}
|
||||
</Component>
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
export default Text
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export * from './Text'
|
||||
export { default } from './Text'
|
||||
|
||||
@@ -30,6 +30,6 @@ JavaScript and TypeScript functions run your custom code in the backend.
|
||||
|
||||
## Get started
|
||||
|
||||
Follow our [Quick start](./get-started/quick-start) guide to build your first app.
|
||||
Follow our [Quick start](/get-started/quick-start) guide to build your first app.
|
||||
|
||||
Check out [Nhost on GitHub](https://github.com/nhost/nhost). Give us a star, and feel free to open a discussion for any feature requests as well.
|
||||
|
||||
@@ -78,7 +78,7 @@ await nhost.auth.signIn({
|
||||
|
||||
A user can be created anonymously. This is useful for offering a limited version of your application to your users without having them sign in first.
|
||||
|
||||
An anonymous user gets a user ID with the `anonymous` role. This role can be used to [set permissions in Hasura](../database/permissions).
|
||||
An anonymous user gets a user ID with the `anonymous` role. This role can be used to [set permissions in Hasura](/platform/database/permissions).
|
||||
|
||||
### Deanonymize users
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ query {
|
||||
|
||||
## Creating users
|
||||
|
||||
Users should be created using the sign-up or sign-in flows as described under [sign-in methods](./sign-in-methods).
|
||||
Users should be created using the sign-up or sign-in flows as described under [sign-in methods](/platform/authentication/sign-in-methods).
|
||||
|
||||
**Never** create users directly via GraphQL or database. **Never** modify the `auth.users` table. **Never** modify the GraphQL root queries.
|
||||
|
||||
|
||||
@@ -6,28 +6,28 @@ This section:
|
||||
|
||||
### Database
|
||||
|
||||
- [Schema](./platform/database)
|
||||
- [Permissions](./platform/database/permissions)
|
||||
- [GraphQL](./platform/database/graphql)
|
||||
- [Schema](/platform/database)
|
||||
- [Permissions](/platform/database/permissions)
|
||||
- [GraphQL](/platform/database/graphql)
|
||||
|
||||
### Authentication
|
||||
|
||||
- [Authentication overview](./platform/authentication)
|
||||
- [User management](./platform/authentication/user-management)
|
||||
- [Sign-in methods](./platform/authentication/sign-in-methods)
|
||||
- [Social login](./platform/authentication/social-login)
|
||||
- [Authentication overview](/platform/authentication)
|
||||
- [User management](/platform/authentication/user-management)
|
||||
- [Sign-in methods](/platform/authentication/sign-in-methods)
|
||||
- [Social login](/platform/authentication/social-login)
|
||||
|
||||
### Storage
|
||||
|
||||
- [File storage](./platform/storage)
|
||||
- [File storage](/platform/storage)
|
||||
|
||||
### Serverless functions
|
||||
|
||||
- [Creating functions](./platform/serverless-functions)
|
||||
- [Event triggers](./platform/serverless-functions/event-triggers)
|
||||
- [Creating functions](/platform/serverless-functions)
|
||||
- [Event triggers](/platform/serverless-functions/event-triggers)
|
||||
|
||||
### Nhost
|
||||
|
||||
- [Environment variables](./platform/nhost/environment-variables)
|
||||
- [GitHub integration](./platform/nhost/github-integration)
|
||||
- [Local development](./platform/nhost/local-development)
|
||||
- [Environment variables](/platform/nhost/environment-variables)
|
||||
- [GitHub integration](/platform/nhost/github-integration)
|
||||
- [Local development](/platform/nhost/local-development)
|
||||
|
||||
@@ -20,7 +20,7 @@ Specifically, the following will be deployed:
|
||||
|
||||
## Workflow
|
||||
|
||||
Create a new Nhost app. Then use [Nhost CLI](./local-development) to initialize your Nhost app locally.
|
||||
Create a new Nhost app. Then use [Nhost CLI](/platform/nhost/local-development) to initialize your Nhost app locally.
|
||||
|
||||
The workflow is as follows:
|
||||
|
||||
|
||||
@@ -4,6 +4,6 @@ title: 'Overview'
|
||||
|
||||
Documentation for other platform features:
|
||||
|
||||
- [Environment variables](./nhost/environment-variables)
|
||||
- [GitHub integration](./nhost/github-integration)
|
||||
- [Local development](./nhost/local-development)
|
||||
- [Environment variables](/platform/nhost/environment-variables)
|
||||
- [GitHub integration](/platform/nhost/github-integration)
|
||||
- [Local development](/platform/nhost/local-development)
|
||||
|
||||
@@ -14,7 +14,7 @@ Event triggers are managed in Hasura. Go to Hasura, then select **Events** in th
|
||||
|
||||

|
||||
|
||||
Nhost's [environment variables](../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/nhost/environment-variables) can be used in event trigger headers. For example, you can attach `NHOST_WEBHOOK_SECRET` to an outgoing webhook here.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -6,17 +6,17 @@ In this section:
|
||||
|
||||
### Nhost SDK
|
||||
|
||||
- [Overview](./reference/sdk)
|
||||
- [GraphQL](./reference/sdk/graphql)
|
||||
- [Authentication](./reference/sdk/authentication)
|
||||
- [Storage](./reference/sdk/storage)
|
||||
- [Functions](./reference/sdk/functions)
|
||||
- [Overview](/reference/sdk)
|
||||
- [GraphQL](/reference/sdk/graphql)
|
||||
- [Authentication](/reference/sdk/authentication)
|
||||
- [Storage](/reference/sdk/storage)
|
||||
- [Functions](/reference/sdk/functions)
|
||||
|
||||
### Nhost CLI
|
||||
|
||||
- [CLI overview](./reference/cli)
|
||||
- [CLI overview](/reference/cli)
|
||||
|
||||
### Supporting libraries
|
||||
|
||||
- [@nhost/react-auth](./reference/supporting-libraries/react-auth)
|
||||
- [@nhost/react-apollo](./reference/supporting-libraries/react-apollo)
|
||||
- [@nhost/react-auth](/reference/supporting-libraries/react-auth)
|
||||
- [@nhost/react-apollo](/reference/supporting-libraries/react-apollo)
|
||||
|
||||
@@ -5,10 +5,10 @@ subtitle: 'Nhost JavaScript SDK.'
|
||||
|
||||
Nhost SDK is the primary way of interacting with your Nhost app. It exposes a standard interface for each of the following services:
|
||||
|
||||
- [GraphQL](./sdk/graphql)
|
||||
- [Authentication](./sdk/authentication)
|
||||
- [Storage](./sdk/storage)
|
||||
- [Functions](./sdk/functions)
|
||||
- [GraphQL](/reference/sdk/graphql)
|
||||
- [Authentication](/reference/sdk/authentication)
|
||||
- [Storage](/reference/sdk/storage)
|
||||
- [Functions](/reference/sdk/functions)
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@@ -6,5 +6,5 @@ We offer libraries and plugins for specific frameworks to make integration with
|
||||
|
||||
Currently, the following supporting libraries are available:
|
||||
|
||||
- [@nhost/react-apollo](./supporting-libraries/react-apollo)
|
||||
- [@nhost/react-auth](./supporting-libraries/react-auth)
|
||||
- [@nhost/react-apollo](/reference/supporting-libraries/react-apollo)
|
||||
- [@nhost/react-auth](/reference/supporting-libraries/react-auth)
|
||||
|
||||
@@ -10,7 +10,7 @@ title: '@nhost/react-auth'
|
||||
|
||||
Install `@nhost/react-auth` and its dependencies:
|
||||
|
||||
```
|
||||
```sh
|
||||
npm install @nhost/nhost-js @nhost/react-auth
|
||||
```
|
||||
|
||||
|
||||
@@ -42,5 +42,6 @@
|
||||
"tailwindcss": "^2.2.19",
|
||||
"typescript": "^4.5.2"
|
||||
},
|
||||
"prettier": "../prettier.config.js"
|
||||
"prettier": "../prettier.config.js",
|
||||
"version": null
|
||||
}
|
||||
|
||||
@@ -4,50 +4,68 @@ import Footer from '@/components/Footer'
|
||||
import Header from '@/components/Header'
|
||||
import components from '@/components/MDX/components'
|
||||
import { Nav } from '@/components/Nav'
|
||||
import { NavDataProvider } from '@/components/NavDataContext'
|
||||
import { createConvolutedNav } from '@/lib/post'
|
||||
import { capitalize } from '@/utils/capitalize'
|
||||
import fs from 'fs'
|
||||
import matter from 'gray-matter'
|
||||
import { serialize } from 'next-mdx-remote/serialize'
|
||||
import Head from 'next/head'
|
||||
import { useRouter } from 'next/router'
|
||||
import { join } from 'path'
|
||||
import React from 'react'
|
||||
|
||||
import { Main } from '../components/Main'
|
||||
|
||||
export default function Home({ category, frontmatter, mdxSource, convolutedNav, categoryTitle }) {
|
||||
const router = useRouter()
|
||||
const pathname = `/${router.query.category}`
|
||||
|
||||
export default function Home({
|
||||
category,
|
||||
frontmatter,
|
||||
mdxSource,
|
||||
convolutedNav,
|
||||
availableCategoryMenus,
|
||||
categoryTitle
|
||||
}) {
|
||||
return (
|
||||
<div className="bg-white">
|
||||
<Head>
|
||||
<title>
|
||||
{frontmatter.title} – {capitalize(category)} | Nhost Documentation
|
||||
</title>
|
||||
</Head>
|
||||
<Header />
|
||||
<Container>
|
||||
<Nav
|
||||
categoryTitle={categoryTitle}
|
||||
convolutedNav={convolutedNav}
|
||||
category={category}
|
||||
query={router.query}
|
||||
pathname={pathname}
|
||||
/>
|
||||
<Main>
|
||||
<Content mdxSource={mdxSource} components={components} frontmatter={frontmatter} />
|
||||
</Main>
|
||||
</Container>
|
||||
<Footer />
|
||||
</div>
|
||||
<NavDataProvider
|
||||
category={category}
|
||||
categoryTitle={categoryTitle}
|
||||
convolutedNav={convolutedNav}
|
||||
availableCategoryMenus={availableCategoryMenus}
|
||||
>
|
||||
<div className="bg-white pt-2">
|
||||
<Head>
|
||||
<title>
|
||||
{frontmatter.title} - {capitalize(category)} | Nhost Documentation
|
||||
</title>
|
||||
</Head>
|
||||
<Header />
|
||||
<Container>
|
||||
<Nav
|
||||
className="hidden lg:flex"
|
||||
categoryTitle={categoryTitle}
|
||||
convolutedNav={convolutedNav}
|
||||
category={category}
|
||||
/>
|
||||
|
||||
<Main>
|
||||
<Content mdxSource={mdxSource} components={components} frontmatter={frontmatter} />
|
||||
</Main>
|
||||
</Container>
|
||||
<Footer />
|
||||
</div>
|
||||
</NavDataProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticProps({ params }) {
|
||||
const postsDirectory = join(process.cwd(), 'content', 'docs')
|
||||
const convolutedNav = createConvolutedNav(params.category)
|
||||
const availableCategories = fs.readdirSync(postsDirectory)
|
||||
const availableCategoryMenus = availableCategories.map((category) => ({
|
||||
slug: category,
|
||||
items: createConvolutedNav(category)
|
||||
}))
|
||||
|
||||
const convolutedNav =
|
||||
availableCategoryMenus.find(({ slug }) => slug === params.category).items ||
|
||||
createConvolutedNav(params.category)
|
||||
|
||||
const categoryTitle = matter(
|
||||
fs.readFileSync(join(postsDirectory, `${params.category}/index.mdx`), 'utf8')
|
||||
@@ -64,7 +82,8 @@ export async function getStaticProps({ params }) {
|
||||
category: params.category,
|
||||
frontmatter: { ...data },
|
||||
mdxSource,
|
||||
convolutedNav: convolutedNav
|
||||
availableCategoryMenus,
|
||||
convolutedNav
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -84,6 +103,7 @@ export async function getStaticPaths(props) {
|
||||
paths: paths.map((category) => {
|
||||
return {
|
||||
params: {
|
||||
availableCategories: paths,
|
||||
category
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,16 +4,15 @@ import Footer from '@/components/Footer'
|
||||
import Header from '@/components/Header'
|
||||
import components from '@/components/MDX/components'
|
||||
import { Nav } from '@/components/Nav'
|
||||
import { NavDataProvider } from '@/components/NavDataContext'
|
||||
import { createConvolutedNav, getAllPosts } from '@/lib/post'
|
||||
import { capitalize } from '@/utils/capitalize'
|
||||
import fs from 'fs'
|
||||
import matter from 'gray-matter'
|
||||
import { serialize } from 'next-mdx-remote/serialize'
|
||||
import Head from 'next/head'
|
||||
import { useRouter } from 'next/router'
|
||||
import { join } from 'path'
|
||||
import React from 'react'
|
||||
|
||||
import { Main } from '../../components/Main'
|
||||
import { SubNavigation } from '../../components/SubNavigation'
|
||||
import { TopNavigation } from '../../components/TopNavigation'
|
||||
@@ -25,47 +24,60 @@ export default function Post({
|
||||
mdxSource,
|
||||
convolutedNav,
|
||||
post,
|
||||
categoryTitle
|
||||
categoryTitle,
|
||||
availableCategoryMenus
|
||||
}) {
|
||||
const router = useRouter()
|
||||
const pathname = `/${router.query.category}`
|
||||
return (
|
||||
<div className="bg-white">
|
||||
<Head>
|
||||
<title>
|
||||
{frontmatter.title} – {capitalize(category)} | Nhost Documentation
|
||||
</title>
|
||||
</Head>
|
||||
<Header />
|
||||
<Container>
|
||||
<Nav
|
||||
convolutedNav={convolutedNav}
|
||||
category={category}
|
||||
categoryTitle={categoryTitle}
|
||||
query={router.query}
|
||||
pathname={pathname}
|
||||
/>
|
||||
|
||||
<Main>
|
||||
<TopNavigation category={category} subcategory={subcategory} />
|
||||
|
||||
<Content mdxSource={mdxSource} components={components} frontmatter={frontmatter} />
|
||||
<SubNavigation
|
||||
<NavDataProvider
|
||||
category={category}
|
||||
categoryTitle={categoryTitle}
|
||||
convolutedNav={convolutedNav}
|
||||
availableCategoryMenus={availableCategoryMenus}
|
||||
>
|
||||
<div className="bg-white pt-2">
|
||||
<Head>
|
||||
<title>
|
||||
{frontmatter.title} - {capitalize(category)} | Nhost Documentation
|
||||
</title>
|
||||
</Head>
|
||||
<Header />
|
||||
<Container>
|
||||
<Nav
|
||||
className="hidden lg:flex"
|
||||
convolutedNav={convolutedNav}
|
||||
category={category}
|
||||
post={post}
|
||||
subcategory={subcategory}
|
||||
categoryTitle={categoryTitle}
|
||||
/>
|
||||
</Main>
|
||||
</Container>
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
<Main>
|
||||
<TopNavigation category={category} subcategory={subcategory} />
|
||||
|
||||
<Content mdxSource={mdxSource} components={components} frontmatter={frontmatter} />
|
||||
<SubNavigation
|
||||
convolutedNav={convolutedNav}
|
||||
category={category}
|
||||
post={post}
|
||||
subcategory={subcategory}
|
||||
/>
|
||||
</Main>
|
||||
</Container>
|
||||
<Footer />
|
||||
</div>
|
||||
</NavDataProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticProps({ params }) {
|
||||
const postsDirectory = join(process.cwd(), 'content', 'docs')
|
||||
const convolutedNav = createConvolutedNav(params.category)
|
||||
const availableCategories = fs.readdirSync(postsDirectory)
|
||||
const availableCategoryMenus = availableCategories.map((category) => ({
|
||||
slug: category,
|
||||
items: createConvolutedNav(category)
|
||||
}))
|
||||
|
||||
const convolutedNav =
|
||||
availableCategoryMenus.find(({ slug }) => slug === params.category).items ||
|
||||
createConvolutedNav(params.category)
|
||||
|
||||
const fullPath = join(postsDirectory, `${params.category}/${params.subcategory}/index.mdx`)
|
||||
const categoryTitle = matter(
|
||||
@@ -83,7 +95,8 @@ export async function getStaticProps({ params }) {
|
||||
subcategory: params.subcategory,
|
||||
frontmatter: { ...data },
|
||||
mdxSource,
|
||||
convolutedNav: convolutedNav
|
||||
availableCategoryMenus,
|
||||
convolutedNav
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,20 +4,17 @@ import Footer from '@/components/Footer'
|
||||
import Header from '@/components/Header'
|
||||
import components from '@/components/MDX/components'
|
||||
import { Nav } from '@/components/Nav'
|
||||
import { NavDataProvider } from '@/components/NavDataContext'
|
||||
import { SubNavigation } from '@/components/SubNavigation'
|
||||
import { TopNavigation } from '@/components/TopNavigation'
|
||||
import { createConvolutedNav, getAllPosts, getHeadingsByPost, removeIndexFile } from '@/lib/post'
|
||||
import { createConvolutedNav, getAllPosts, removeIndexFile } from '@/lib/post'
|
||||
import { capitalize } from '@/utils/capitalize'
|
||||
import fs from 'fs'
|
||||
import matter from 'gray-matter'
|
||||
import { serialize } from 'next-mdx-remote/serialize'
|
||||
import { useRouter } from 'next/dist/client/router'
|
||||
import Head from 'next/head'
|
||||
import { join } from 'path'
|
||||
import React from 'react'
|
||||
|
||||
// import { PostMetadata } from "../../../components/PostMetadata";
|
||||
// import { HeadingsNavigation } from "../../../components/HeadingsNavigation";
|
||||
import { Main } from '../../../components/Main'
|
||||
|
||||
export default function Post({
|
||||
@@ -25,61 +22,64 @@ export default function Post({
|
||||
subcategory,
|
||||
frontmatter,
|
||||
mdxSource,
|
||||
nav,
|
||||
convolutedNav,
|
||||
availableCategoryMenus,
|
||||
post,
|
||||
headings,
|
||||
categoryTitle
|
||||
}) {
|
||||
const router = useRouter()
|
||||
const pathname = `/${router.query.category}`
|
||||
return (
|
||||
<div className="bg-white">
|
||||
<Head>
|
||||
<title>
|
||||
{frontmatter.title} – {capitalize(subcategory)} - {capitalize(category)} | Nhost
|
||||
Documentation
|
||||
</title>
|
||||
</Head>
|
||||
<Header />
|
||||
<Container>
|
||||
<Nav
|
||||
convolutedNav={convolutedNav}
|
||||
category={category}
|
||||
categoryTitle={categoryTitle}
|
||||
nav={nav}
|
||||
query={router.query}
|
||||
pathname={pathname}
|
||||
headings={headings}
|
||||
/>
|
||||
|
||||
<Main>
|
||||
<TopNavigation category={category} subcategory={subcategory} />
|
||||
|
||||
<Content mdxSource={mdxSource} components={components} frontmatter={frontmatter} />
|
||||
<SubNavigation
|
||||
<NavDataProvider
|
||||
category={category}
|
||||
categoryTitle={categoryTitle}
|
||||
convolutedNav={convolutedNav}
|
||||
availableCategoryMenus={availableCategoryMenus}
|
||||
>
|
||||
<div className="bg-white pt-2">
|
||||
<Head>
|
||||
<title>
|
||||
{frontmatter.title} - {capitalize(subcategory)} - {capitalize(category)} | Nhost
|
||||
Documentation
|
||||
</title>
|
||||
</Head>
|
||||
<Header />
|
||||
<Container>
|
||||
<Nav
|
||||
className="hidden lg:flex"
|
||||
convolutedNav={convolutedNav}
|
||||
category={category}
|
||||
post={post}
|
||||
subcategory={subcategory}
|
||||
categoryTitle={categoryTitle}
|
||||
/>
|
||||
{/* <PostMetadata
|
||||
category={category}
|
||||
subcategory={subcategory}
|
||||
frontmatter={frontmatter}
|
||||
post={post}
|
||||
/> */}
|
||||
</Main>
|
||||
{/* <HeadingsNavigation headings={headings} /> */}
|
||||
</Container>
|
||||
<Footer />
|
||||
</div>
|
||||
|
||||
<Main>
|
||||
<TopNavigation category={category} subcategory={subcategory} />
|
||||
|
||||
<Content mdxSource={mdxSource} components={components} frontmatter={frontmatter} />
|
||||
|
||||
<SubNavigation
|
||||
convolutedNav={convolutedNav}
|
||||
category={category}
|
||||
post={post}
|
||||
subcategory={subcategory}
|
||||
/>
|
||||
</Main>
|
||||
</Container>
|
||||
<Footer />
|
||||
</div>
|
||||
</NavDataProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getStaticProps({ params }) {
|
||||
const postsDirectory = join(process.cwd(), 'content', 'docs')
|
||||
const convolutedNav = createConvolutedNav(params.category)
|
||||
const availableCategories = fs.readdirSync(postsDirectory)
|
||||
const availableCategoryMenus = availableCategories.map((category) => ({
|
||||
slug: category,
|
||||
items: createConvolutedNav(category)
|
||||
}))
|
||||
|
||||
const convolutedNav =
|
||||
availableCategoryMenus.find(({ slug }) => slug === params.category).items ||
|
||||
createConvolutedNav(params.category)
|
||||
|
||||
const categoryTitle = matter(
|
||||
fs.readFileSync(join(postsDirectory, `${params.category}/index.mdx`), 'utf8')
|
||||
@@ -91,7 +91,6 @@ export async function getStaticProps({ params }) {
|
||||
)
|
||||
const fileContents = fs.readFileSync(fullPath, 'utf8')
|
||||
const { data, content } = matter(fileContents)
|
||||
const headings = getHeadingsByPost(content)
|
||||
const mdxSource = await serialize(content)
|
||||
|
||||
return {
|
||||
@@ -102,8 +101,8 @@ export async function getStaticProps({ params }) {
|
||||
post: params.post,
|
||||
frontmatter: { ...data },
|
||||
mdxSource,
|
||||
headings: headings,
|
||||
convolutedNav: convolutedNav
|
||||
availableCategoryMenus,
|
||||
convolutedNav
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,24 @@
|
||||
import Footer from '@/components/Footer'
|
||||
import Header from '@/components/Header'
|
||||
import { NavDataProvider } from '@/components/NavDataContext'
|
||||
import Text from '@/components/ui/Text'
|
||||
import Head from 'next/head'
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="bg-fafafa">
|
||||
<Head>
|
||||
<title>Nhost Documentation</title>
|
||||
</Head>
|
||||
<Header />
|
||||
<div className="flex flex-row max-w-5xl pb-20 mx-auto space-x-20 mt-36 bg-fafafa">
|
||||
<div className="h-screen">
|
||||
<Text>Welcome to Nhost</Text>
|
||||
<NavDataProvider category="" categoryTitle="" convolutedNav={[]} availableCategoryMenus={[]}>
|
||||
<div className="bg-fafafa pt-2">
|
||||
<Head>
|
||||
<title>Nhost Documentation</title>
|
||||
</Head>
|
||||
<Header />
|
||||
<div className="flex flex-row max-w-5xl pb-20 mx-auto space-x-20 mt-36 bg-fafafa">
|
||||
<div className="h-screen">
|
||||
<Text>Welcome to Nhost</Text>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
</NavDataProvider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,36 +1,41 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:news="http://www.google.com/schemas/sitemap-news/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:mobile="http://www.google.com/schemas/sitemap-mobile/1.0" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:video="http://www.google.com/schemas/sitemap-video/1.1">
|
||||
<url><loc>https://docs.nhost.io</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.955Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/quick-start/javascript-client</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/quick-start/permissions</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/quick-start/schema</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/authentication/sign-in-methods</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/authentication/social-login</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/authentication/user-management</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/database/graphql</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/database/permissions</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/nhost/environment-variables</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/nhost/github-integration</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/nhost/local-development</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/serverless-functions/event-triggers</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/sdk/authentication</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/sdk/functions</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/sdk/graphql</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/sdk/storage</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/supporting-libraries/react-apollo</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/supporting-libraries/react-auth</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/authentication</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/quick-start</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/upgrade</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/authentication</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/database</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/nhost</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/serverless-functions</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/storage</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/cli</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/sdk</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/supporting-libraries</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-08T09:55:24.956Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/cli-workflow/install-cli</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/cli-workflow/local-changes</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/cli-workflow/metadata-and-serverless-functions</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/cli-workflow/workflow-setup</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/quick-start/javascript-client</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/quick-start/permissions</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/quick-start/schema</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/authentication/sign-in-methods</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/authentication/social-login</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/authentication/user-management</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/database/graphql</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/database/permissions</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/nhost/environment-variables</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/nhost/github-integration</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/nhost/local-development</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/serverless-functions/event-triggers</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/sdk/authentication</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/sdk/functions</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/sdk/graphql</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/sdk/storage</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/supporting-libraries/react-apollo</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/supporting-libraries/react-auth</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/authentication</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/cli-workflow</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/quick-start</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started/upgrade</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/authentication</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/database</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/nhost</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/serverless-functions</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform/storage</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/cli</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/sdk</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference/supporting-libraries</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/get-started</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/platform</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
<url><loc>https://docs.nhost.io/reference</loc><changefreq>daily</changefreq><priority>0.7</priority><lastmod>2022-02-22T08:04:43.021Z</lastmod></url>
|
||||
</urlset>
|
||||
@@ -69,7 +69,6 @@ body {
|
||||
flex: none;
|
||||
order: 1;
|
||||
flex-grow: 0;
|
||||
margin: 0px 16px;
|
||||
}
|
||||
|
||||
@responsive {
|
||||
@@ -93,6 +92,10 @@ body {
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.menu-card {
|
||||
box-shadow: 0px 1px 4px rgba(14, 24, 39, 0.1), 0px 8px 24px rgba(14, 24, 39, 0.1);
|
||||
}
|
||||
|
||||
.divider {
|
||||
height: 1px;
|
||||
left: 0px;
|
||||
|
||||
@@ -11,10 +11,19 @@
|
||||
}
|
||||
|
||||
.markdown li {
|
||||
@apply text-sm font-display text-greyscaleDark font-medium leading-7;
|
||||
list-style: disc;
|
||||
list-style-type: disc;
|
||||
list-style-position: inside;
|
||||
@apply font-normal leading-7 text-base- font-display text-greyscaleDark;
|
||||
}
|
||||
|
||||
.markdown li::marker {
|
||||
@apply font-normal leading-7 text-base- font-display text-greyscaleDark;
|
||||
}
|
||||
|
||||
.markdown ul li {
|
||||
list-style: disc inside;
|
||||
}
|
||||
|
||||
.markdown ol li {
|
||||
list-style: decimal inside;
|
||||
}
|
||||
|
||||
.markdown table {
|
||||
|
||||
5
examples/docker-compose/.env.example
Normal file
5
examples/docker-compose/.env.example
Normal file
@@ -0,0 +1,5 @@
|
||||
POSTGRES_PASSWORD=secret-pg-password-never-use-this-value
|
||||
HASURA_GRAPHQL_ADMIN_SECRET=hello123
|
||||
HASURA_GRAPHQL_JWT_SECRET='{"type":"HS256", "key":"5152fa850c02dc222631cca898ed1485821a70912a6e3649c49076912daa3b62182ba013315915d64f40cddfbb8b58eb5bd11ba225336a6af45bbae07ca873f3","issuer":"hasura-auth"}'
|
||||
STORAGE_ACCESS_KEY=storage-access-key-never-use-this-value
|
||||
STORAGE_SECRET_KEY=storage-secret-key-never-use-this-value
|
||||
1
examples/docker-compose/.gitignore
vendored
Normal file
1
examples/docker-compose/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
data
|
||||
26
examples/docker-compose/README.md
Normal file
26
examples/docker-compose/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Docker-compose example
|
||||
|
||||
Here is an example on how to reproduce the Nhost stack from a docker-compose file.
|
||||
|
||||
## Configuration
|
||||
|
||||
```sh
|
||||
git clone https://github.com/nhost/nhost
|
||||
cd nhost/examples/docker-compose
|
||||
cp .env.example .env
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
The following endpoints are now exposed:
|
||||
|
||||
- `http://localhost:1337`: Hasura Console
|
||||
- `http://localhost:1337/v1/graphql`: Hasura GraphQL endpoint
|
||||
- `http://localhost:1337/v1/auth`: Hasura Auth
|
||||
- `http://localhost:1337/v1/storage`: Hasura Storage
|
||||
|
||||
- `http://localhost:9090`: Traefik dashboad
|
||||
- `http://localhost:8025`: Mailhog SMTP testing dashboard
|
||||
|
||||
## Limitations
|
||||
|
||||
This example does not implement the custom functions that are available on the cloud-hosted Nhost offer.
|
||||
121
examples/docker-compose/docker-compose.yaml
Normal file
121
examples/docker-compose/docker-compose.yaml
Normal file
@@ -0,0 +1,121 @@
|
||||
version: '3.6'
|
||||
services:
|
||||
traefik:
|
||||
image: "traefik:v2.5"
|
||||
container_name: "traefik"
|
||||
command:
|
||||
- "--api.insecure=true"
|
||||
- "--providers.docker=true"
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--entrypoints.web.address=:1337"
|
||||
ports:
|
||||
- "1337:1337"
|
||||
- "9090:8080"
|
||||
volumes:
|
||||
- "/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||
postgres:
|
||||
image: postgres
|
||||
restart: always
|
||||
volumes:
|
||||
- ./data/db:/var/lib/postgresql/data
|
||||
- ./initdb.d:/docker-entrypoint-initdb.d:ro
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secretpgpassword}
|
||||
ports:
|
||||
- '5432:5432'
|
||||
graphql-engine:
|
||||
image: hasura/graphql-engine:v2.2.0
|
||||
depends_on:
|
||||
- 'postgres'
|
||||
restart: always
|
||||
expose:
|
||||
- 8080
|
||||
environment:
|
||||
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:${POSTGRES_PASSWORD:-secretpgpassword}@postgres:5432/postgres
|
||||
HASURA_GRAPHQL_JWT_SECRET: ${HASURA_GRAPHQL_JWT_SECRET}
|
||||
HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_GRAPHQL_ADMIN_SECRET}
|
||||
HASURA_GRAPHQL_UNAUTHORIZED_ROLE: public
|
||||
HASURA_GRAPHQL_LOG_LEVEL: debug
|
||||
HASURA_GRAPHQL_ENABLE_CONSOLE: 'true'
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.hasura.rule=Host(`localhost`) && PathPrefix(`/`)"
|
||||
- "traefik.http.routers.hasura.entrypoints=web"
|
||||
auth:
|
||||
image: nhost/hasura-auth:latest
|
||||
depends_on:
|
||||
- postgres
|
||||
- graphql-engine
|
||||
restart: always
|
||||
environment:
|
||||
AUTH_HOST: '0.0.0.0'
|
||||
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:${POSTGRES_PASSWORD:-secretpgpassword}@postgres:5432/postgres
|
||||
HASURA_GRAPHQL_GRAPHQL_URL: http://graphql-engine:8080/v1/graphql
|
||||
HASURA_GRAPHQL_JWT_SECRET: ${HASURA_GRAPHQL_JWT_SECRET}
|
||||
HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_GRAPHQL_ADMIN_SECRET}
|
||||
AUTH_SMTP_HOST: mailhog
|
||||
AUTH_SMTP_PORT: 1025
|
||||
expose:
|
||||
- 4000
|
||||
healthcheck:
|
||||
disable: true
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.middlewares.strip-auth.stripprefix.prefixes=/v1/auth"
|
||||
- "traefik.http.routers.auth.rule=Host(`localhost`) && PathPrefix(`/v1/auth`)"
|
||||
- "traefik.http.routers.auth.middlewares=strip-auth@docker"
|
||||
- "traefik.http.routers.auth.entrypoints=web"
|
||||
storage:
|
||||
image: nhost/hasura-storage:latest
|
||||
depends_on:
|
||||
- postgres
|
||||
- graphql-engine
|
||||
- minio
|
||||
restart: always
|
||||
expose:
|
||||
- 4000
|
||||
healthcheck:
|
||||
disable: true
|
||||
environment:
|
||||
STORAGE_HOST: '0.0.0.0'
|
||||
STORAGE_PUBLIC_URL: http://localhost:${PROXY_PORT:-1337}/v1/storage
|
||||
HASURA_GRAPHQL_GRAPHQL_URL: http://graphql-engine:8080/v1/graphql
|
||||
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:${POSTGRES_PASSWORD:-secretpgpassword}@postgres:5432/postgres
|
||||
HASURA_GRAPHQL_ADMIN_SECRET: ${HASURA_GRAPHQL_ADMIN_SECRET}
|
||||
HASURA_GRAPHQL_JWT_SECRET: ${HASURA_GRAPHQL_JWT_SECRET}
|
||||
S3_ACCESS_KEY: ${STORAGE_ACCESS_KEY}
|
||||
S3_SECRET_KEY: ${STORAGE_SECRET_KEY}
|
||||
S3_ENDPOINT: http://minio:8484
|
||||
S3_BUCKET: nhost
|
||||
STORAGE_FORCE_DOWNLOAD_FOR_CONTENT_TYPES: text/html,application/javascript
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.middlewares.strip-storage.stripprefix.prefixes=/v1/storage"
|
||||
- "traefik.http.routers.storage.rule=Host(`localhost`) && PathPrefix(`/v1/storage`)"
|
||||
- "traefik.http.routers.storage.middlewares=strip-storage@docker"
|
||||
- "traefik.http.routers.storage.entrypoints=web"
|
||||
minio:
|
||||
image: minio/minio:RELEASE.2021-09-24T00-24-24Z
|
||||
entrypoint: sh
|
||||
command: -c 'mkdir -p /data/nhost && /opt/bin/minio server --address :8484 /data'
|
||||
environment:
|
||||
MINIO_ROOT_USER: ${STORAGE_ACCESS_KEY}
|
||||
MINIO_ROOT_PASSWORD: ${STORAGE_SECRET_KEY}
|
||||
ports:
|
||||
- ${MINIO_PORT:-8484}:8484
|
||||
volumes:
|
||||
- ./data/minio:/data
|
||||
mailhog:
|
||||
image: mailhog/mailhog
|
||||
environment:
|
||||
SMTP_HOST: ${AUTH_SMTP_HOST:-mailhog}
|
||||
SMTP_PORT: ${AUTH_SMTP_PORT:-1025}
|
||||
SMTP_PASS: ${AUTH_SMTP_PASS:-password}
|
||||
SMTP_USER: ${AUTH_SMTP_USER:-user}
|
||||
SMTP_SECURE: "${AUTH_SMTP_SECURE:-false}"
|
||||
SMTP_SENDER: ${AUTH_SMTP_SENDER:-hbp@hbp.com}
|
||||
ports:
|
||||
- ${AUTH_SMTP_PORT:-1025}:1025
|
||||
- 8025:8025
|
||||
volumes:
|
||||
- ./data/mailhog:/maildir
|
||||
13
examples/docker-compose/initdb.d/0001-create-schema.sql
Normal file
13
examples/docker-compose/initdb.d/0001-create-schema.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- auth schema
|
||||
CREATE SCHEMA IF NOT EXISTS auth;
|
||||
CREATE SCHEMA IF NOT EXISTS storage;
|
||||
-- https://github.com/hasura/graphql-engine/issues/3657
|
||||
CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA public;
|
||||
CREATE EXTENSION IF NOT EXISTS citext WITH SCHEMA public;
|
||||
CREATE OR REPLACE FUNCTION public.set_current_timestamp_updated_at() RETURNS trigger LANGUAGE plpgsql AS $$
|
||||
declare _new record;
|
||||
begin _new := new;
|
||||
_new."updated_at" = now();
|
||||
return _new;
|
||||
end;
|
||||
$$;
|
||||
23
examples/react-xstate/.gitignore
vendored
23
examples/react-xstate/.gitignore
vendored
@@ -1,23 +0,0 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/dist
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
@@ -1,9 +0,0 @@
|
||||
# Xstate & Nhost
|
||||
|
||||
```sh
|
||||
# Start the Nhost CLI in the background
|
||||
pnpm run start --filter @nhost-examples/testing-project
|
||||
|
||||
# Start this project
|
||||
pnpm run start --filter @nhost-examples/react-xstate
|
||||
```
|
||||
@@ -1,16 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/src/favicon.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite App</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -1,50 +0,0 @@
|
||||
{
|
||||
"name": "@nhost-examples/react-xstate",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@xstate/immer": "^0.3.1",
|
||||
"@xstate/react": "^2.0.0",
|
||||
"axios": "^0.25.0",
|
||||
"immer": "^9.0.12",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-use": "^17.3.2",
|
||||
"uuid": "^8.3.2",
|
||||
"xstate": "^4.29.0"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@apollo/client": "^3.5.8",
|
||||
"@types/react": "^17.0.39",
|
||||
"@types/react-dom": "^17.0.11",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@vitejs/plugin-react": "^1.1.4",
|
||||
"@xstate/inspect": "^0.6.2",
|
||||
"subscriptions-transport-ws": "^0.11.0",
|
||||
"typescript": "^4.5.5",
|
||||
"vite": "^2.7.13",
|
||||
"ws": "^8.4.2"
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu',
|
||||
'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
|
||||
}
|
||||
|
||||
button {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
import './App.css'
|
||||
|
||||
import { gql } from '@apollo/client'
|
||||
import { useState } from 'react'
|
||||
import {
|
||||
useEmailPasswordlessSignIn,
|
||||
useAuthenticated,
|
||||
useAccessToken,
|
||||
useSignOut,
|
||||
useEmailPasswordSignIn,
|
||||
useRefreshToken,
|
||||
useSignUpEmailPassword
|
||||
} from './react-auth'
|
||||
import { useAuthQuery } from './react-apollo'
|
||||
|
||||
const GET_GREETING = gql`
|
||||
query MyQuery {
|
||||
test {
|
||||
id
|
||||
}
|
||||
}
|
||||
`
|
||||
function App() {
|
||||
const isAuthenticated = useAuthenticated()
|
||||
const email = 'pilou@pilou.com'
|
||||
const password = 'piloupilou'
|
||||
const [token, setToken] = useState('')
|
||||
const changeToken = (event: React.ChangeEvent<HTMLInputElement>) => setToken(event.target.value)
|
||||
const jwt = useAccessToken()
|
||||
const signOut = useSignOut()
|
||||
const signUp = useSignUpEmailPassword(email, password)
|
||||
const signIn = useEmailPasswordSignIn(email, password)
|
||||
const passwordlessSignIn = useEmailPasswordlessSignIn(email)
|
||||
const [, updateToken] = useRefreshToken()
|
||||
|
||||
// const options = useMemo(() => ({ skip: !isAuthenticated }), [isAuthenticated])
|
||||
const { loading, data } = useAuthQuery(GET_GREETING)
|
||||
// if (loading) return <p>Loading ...</p>;
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
{isAuthenticated ? (
|
||||
<>
|
||||
<button onClick={signOut}>Logout</button>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<button onClick={signUp}>Register</button>
|
||||
<button onClick={signIn}>Email + password signin</button>
|
||||
<button onClick={passwordlessSignIn}>Passwordless signin</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
<input type="text" value={token} onChange={changeToken} />
|
||||
<button onClick={() => updateToken(token)}>Set refresh token</button>
|
||||
|
||||
<p>JWT</p>
|
||||
<div>{jwt}</div>
|
||||
{!loading && <div>ok {JSON.stringify(data)}</div>}
|
||||
</header>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
@@ -1,165 +0,0 @@
|
||||
import { SubscriptionClient } from 'subscriptions-transport-ws'
|
||||
|
||||
import {
|
||||
ApolloClient,
|
||||
ApolloClientOptions,
|
||||
createHttpLink,
|
||||
from,
|
||||
InMemoryCache,
|
||||
RequestHandler,
|
||||
split,
|
||||
WatchQueryFetchPolicy
|
||||
} from '@apollo/client'
|
||||
import { setContext } from '@apollo/client/link/context'
|
||||
import { WebSocketLink } from '@apollo/client/link/ws'
|
||||
import { getMainDefinition } from '@apollo/client/utilities'
|
||||
import { InterpreterFrom } from 'xstate'
|
||||
import { NhostMachine } from './state'
|
||||
|
||||
const isBrowser = () => typeof window !== 'undefined'
|
||||
|
||||
export type NhostApolloClientOptions = {
|
||||
authService: InterpreterFrom<NhostMachine>
|
||||
backendUrl?: string
|
||||
graphqlUrl?: string
|
||||
headers?: any
|
||||
publicRole?: string
|
||||
fetchPolicy?: WatchQueryFetchPolicy
|
||||
connectToDevTools?: boolean
|
||||
cache?: InMemoryCache
|
||||
onError?: RequestHandler
|
||||
}
|
||||
|
||||
export const createApolloClient = ({
|
||||
authService,
|
||||
backendUrl,
|
||||
graphqlUrl,
|
||||
headers = {},
|
||||
publicRole = 'public',
|
||||
fetchPolicy,
|
||||
cache = new InMemoryCache(),
|
||||
connectToDevTools = process.env.NODE_ENV === 'development',
|
||||
onError
|
||||
}: NhostApolloClientOptions) => {
|
||||
let token: string | null = null
|
||||
|
||||
const getAuthHeaders = () => {
|
||||
// add headers
|
||||
const resHeaders = {
|
||||
...headers,
|
||||
'Sec-WebSocket-Protocol': 'graphql-ws'
|
||||
}
|
||||
|
||||
// add auth headers if signed in
|
||||
// or add 'public' role if not signed in
|
||||
if (token) {
|
||||
resHeaders.authorization = `Bearer ${token}`
|
||||
} else {
|
||||
// ? Not sure it changes anything for Hasura
|
||||
resHeaders.role = publicRole
|
||||
}
|
||||
|
||||
return resHeaders
|
||||
}
|
||||
|
||||
let uri = ''
|
||||
if (graphqlUrl) {
|
||||
uri = graphqlUrl
|
||||
} else if (backendUrl) {
|
||||
uri = `${backendUrl}/v1/graphql`
|
||||
} else {
|
||||
throw new Error('no GraphQL URL')
|
||||
}
|
||||
|
||||
const wsUri = uri.startsWith('https') ? uri.replace(/^https/, 'wss') : uri.replace(/^http/, 'ws')
|
||||
|
||||
let webSocketClient: SubscriptionClient | null = null
|
||||
if (isBrowser()) {
|
||||
webSocketClient = new SubscriptionClient(wsUri, {
|
||||
lazy: true,
|
||||
reconnect: true,
|
||||
connectionParams: () => ({
|
||||
headers: getAuthHeaders()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const httplink = createHttpLink({
|
||||
uri
|
||||
})
|
||||
|
||||
const authLink = setContext((_, { headers }) => {
|
||||
return {
|
||||
headers: {
|
||||
...headers,
|
||||
...getAuthHeaders()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
const link = webSocketClient
|
||||
? split(
|
||||
({ query }) => {
|
||||
const mainDefinition = getMainDefinition(query)
|
||||
|
||||
const { kind } = mainDefinition
|
||||
let operation
|
||||
if ('operation' in mainDefinition) {
|
||||
operation = mainDefinition.operation
|
||||
}
|
||||
|
||||
return kind === 'OperationDefinition' && operation === 'subscription'
|
||||
},
|
||||
new WebSocketLink(webSocketClient),
|
||||
authLink.concat(httplink)
|
||||
)
|
||||
: httplink
|
||||
|
||||
const apolloClientOptions: ApolloClientOptions<any> = {
|
||||
cache: cache || new InMemoryCache(),
|
||||
ssrMode: !isBrowser(),
|
||||
defaultOptions: {
|
||||
watchQuery: {
|
||||
fetchPolicy
|
||||
}
|
||||
},
|
||||
connectToDevTools
|
||||
}
|
||||
|
||||
// add link
|
||||
apolloClientOptions.link = typeof onError === 'function' ? from([onError, link]) : from([link])
|
||||
|
||||
const client = new ApolloClient(apolloClientOptions)
|
||||
|
||||
authService.onTransition(async (state, event) => {
|
||||
const newToken = state.context.accessToken.value ?? null
|
||||
|
||||
if (token !== newToken) {
|
||||
token = newToken
|
||||
client.reFetchObservableQueries()
|
||||
if (isBrowser() && webSocketClient) {
|
||||
if (newToken) {
|
||||
if (webSocketClient.status === 1) {
|
||||
// @ts-expect-error
|
||||
webSocketClient.tryReconnect()
|
||||
}
|
||||
} else {
|
||||
if (webSocketClient.status === 1) {
|
||||
// must close first to avoid race conditions
|
||||
webSocketClient.close()
|
||||
// reconnect
|
||||
// @ts-expect-error
|
||||
webSocketClient.tryReconnect()
|
||||
}
|
||||
if (event.type === 'done.invoke.signingOut') {
|
||||
await client.resetStore().catch((error) => {
|
||||
console.error('Error resetting Apollo client cache')
|
||||
console.error(error)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return client
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import App from './App'
|
||||
import { NhostApolloProvider } from './react-apollo'
|
||||
import { NhostProvider } from './react-auth'
|
||||
import { initNhost } from './state'
|
||||
|
||||
const nhost = initNhost({
|
||||
backendUrl: 'http://127.0.0.1:1337'
|
||||
})
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<NhostProvider nhost={nhost}>
|
||||
<NhostApolloProvider>
|
||||
<App />
|
||||
</NhostApolloProvider>
|
||||
</NhostProvider>
|
||||
</React.StrictMode>,
|
||||
document.getElementById('root')
|
||||
)
|
||||
@@ -1,23 +0,0 @@
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import {
|
||||
useQuery,
|
||||
OperationVariables,
|
||||
DocumentNode,
|
||||
TypedDocumentNode,
|
||||
QueryHookOptions
|
||||
} from '@apollo/client'
|
||||
|
||||
import { useAuthenticated } from '../react-auth'
|
||||
|
||||
export function useAuthQuery<TData = any, TVariables = OperationVariables>(
|
||||
query: DocumentNode | TypedDocumentNode<TData, TVariables>,
|
||||
options?: QueryHookOptions<TData, TVariables>
|
||||
) {
|
||||
const isAuthenticated = useAuthenticated()
|
||||
const newOptions = useMemo(
|
||||
() => ({ ...options, skip: options?.skip || !isAuthenticated }),
|
||||
[isAuthenticated, options]
|
||||
)
|
||||
return useQuery(query, newOptions)
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
export * from './provider'
|
||||
export * from './hooks'
|
||||
@@ -1,22 +0,0 @@
|
||||
import React, { useContext, useEffect, useState } from 'react'
|
||||
|
||||
import { ApolloProvider, ApolloClient, InMemoryCache } from '@apollo/client'
|
||||
|
||||
import { createApolloClient, NhostApolloClientOptions } from '../apollo'
|
||||
import { NhostContext } from '../react-auth'
|
||||
|
||||
export const NhostApolloProvider: React.FC<
|
||||
Omit<NhostApolloClientOptions, 'backendUrl' | 'authService'>
|
||||
> = ({ children, ...options }) => {
|
||||
const nhostContext = useContext(NhostContext)
|
||||
|
||||
const [client, setClient] = useState<ApolloClient<InMemoryCache>>()
|
||||
|
||||
useEffect(() => {
|
||||
setClient(createApolloClient({ ...nhostContext, ...options }))
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
if (client) return <ApolloProvider client={client}>{children}</ApolloProvider>
|
||||
else return <div>no Apollo client</div>
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
import { useSelector, useActor } from '@xstate/react'
|
||||
import { useContext } from 'react'
|
||||
|
||||
import { NhostContext } from './provider'
|
||||
|
||||
export const useAuthService = () => {
|
||||
const globalServices = useContext(NhostContext)
|
||||
return globalServices.authService
|
||||
}
|
||||
|
||||
export const useNhostbackendUrl = () => {
|
||||
const globalServices = useContext(NhostContext)
|
||||
return globalServices.backendUrl
|
||||
}
|
||||
|
||||
export const useAuthActor = () => {
|
||||
const service = useAuthService()
|
||||
return useActor(service)
|
||||
}
|
||||
|
||||
export const useLoading = () => {
|
||||
const service = useAuthService()
|
||||
return useSelector(service, (state) =>
|
||||
state.matches({
|
||||
authentication: 'signedOut',
|
||||
tokenRefresher: 'refreshing'
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
export const useAuthenticated = () => {
|
||||
const service = useAuthService()
|
||||
return useSelector(service, (state) => state.matches({ authentication: 'signedIn' }))
|
||||
}
|
||||
|
||||
export const useNhostAuth = () => {
|
||||
const [state] = useAuthActor()
|
||||
const isLoading = state.matches({
|
||||
authentication: 'signedOut',
|
||||
tokenRefresher: 'refreshing'
|
||||
})
|
||||
const isAuthenticated = state.matches({ authentication: 'signedIn' })
|
||||
|
||||
return { isLoading, isAuthenticated }
|
||||
}
|
||||
|
||||
export const useAccessToken = () => {
|
||||
const service = useAuthService()
|
||||
return useSelector(service, (state) => state.context.accessToken.value)
|
||||
}
|
||||
|
||||
export const useSignUpEmailPassword = (email: string, password: string) => {
|
||||
const service = useAuthService()
|
||||
return () =>
|
||||
service.send({
|
||||
type: 'REGISTER',
|
||||
email,
|
||||
password
|
||||
})
|
||||
}
|
||||
|
||||
export const useSignOut = (all = false) => {
|
||||
const service = useAuthService()
|
||||
return () => service.send({ type: 'SIGNOUT', all })
|
||||
}
|
||||
|
||||
export const useEmailPasswordSignIn = (email: string, password: string) => {
|
||||
const service = useAuthService()
|
||||
return () =>
|
||||
service.send({
|
||||
type: 'SIGNIN',
|
||||
email,
|
||||
password
|
||||
})
|
||||
}
|
||||
|
||||
export const useEmailPasswordlessSignIn = (email: string) => {
|
||||
const service = useAuthService()
|
||||
return () =>
|
||||
service.send({
|
||||
type: 'SIGNIN_PASSWORDLESS_EMAIL',
|
||||
email
|
||||
})
|
||||
}
|
||||
|
||||
export const useRefreshToken = (): [string | undefined, (v: string) => void] => {
|
||||
const service = useAuthService()
|
||||
const value = useSelector(service, (state) => state.context.accessToken.value)
|
||||
const setValue = (token: string) => {
|
||||
service.send({ type: 'UPDATE_REFRESH_TOKEN', token })
|
||||
}
|
||||
return [value, setValue]
|
||||
}
|
||||
|
||||
export const useUserData = () => {
|
||||
const service = useAuthService()
|
||||
return useSelector(service, (state) => state.context.user)
|
||||
}
|
||||
|
||||
export const useAvatarUrl = () => {
|
||||
const service = useAuthService()
|
||||
return useSelector(service, (state) => state.context.user?.avatarUrl)
|
||||
}
|
||||
|
||||
export const useDefaultRole = () => {
|
||||
const service = useAuthService()
|
||||
return useSelector(service, (state) => state.context.user?.defaultRole)
|
||||
}
|
||||
|
||||
export const useDisplayName = () => {
|
||||
const service = useAuthService()
|
||||
return useSelector(service, (state) => state.context.user?.displayName)
|
||||
}
|
||||
|
||||
export const useEmail = () => {
|
||||
const service = useAuthService()
|
||||
return useSelector(service, (state) => state.context.user?.email)
|
||||
}
|
||||
|
||||
export const useUserId = () => {
|
||||
const service = useAuthService()
|
||||
return useSelector(service, (state) => state.context.user?.id)
|
||||
}
|
||||
|
||||
export const useIsAnonymous = () => {
|
||||
const service = useAuthService()
|
||||
return useSelector(service, (state) => state.context.user?.isAnonymous)
|
||||
}
|
||||
|
||||
export const useUserLocale = () => {
|
||||
const service = useAuthService()
|
||||
return useSelector(service, (state) => state.context.user?.locale)
|
||||
}
|
||||
|
||||
export const useUserRoles = () => {
|
||||
const service = useAuthService()
|
||||
return useSelector(service, (state) => state.context.user?.roles)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import { inspect } from '@xstate/inspect'
|
||||
|
||||
inspect({
|
||||
url: 'https://statecharts.io/inspect',
|
||||
iframe: false
|
||||
})
|
||||
|
||||
export * from './provider'
|
||||
export * from './hooks'
|
||||
@@ -1,60 +0,0 @@
|
||||
import { useSelector, useInterpret } from '@xstate/react'
|
||||
import { inspect } from '@xstate/inspect'
|
||||
import React, { useEffect, createContext } from 'react'
|
||||
import { useLocation } from 'react-use'
|
||||
import { InterpreterFrom } from 'xstate'
|
||||
|
||||
import { NhostMachine, REFRESH_TOKEN_KEY } from '../state'
|
||||
|
||||
if (process.env.NODE_ENV) {
|
||||
inspect({
|
||||
url: 'https://statecharts.io/inspect',
|
||||
iframe: false
|
||||
})
|
||||
}
|
||||
|
||||
type Context = {
|
||||
authService: InterpreterFrom<NhostMachine>
|
||||
backendUrl: string
|
||||
}
|
||||
|
||||
export const NhostContext = createContext<Context>({} as Context)
|
||||
|
||||
export const NhostProvider: React.FC<{ nhost: { machine: NhostMachine; backendUrl: string } }> = ({
|
||||
nhost: { machine, backendUrl },
|
||||
...props
|
||||
}) => {
|
||||
const authService = useInterpret(machine, { devTools: true })
|
||||
const refreshToken = useSelector(authService, (state) => state.context.refreshToken.value)
|
||||
const location = useLocation()
|
||||
|
||||
useEffect(() => {
|
||||
if (!location.hash) return
|
||||
const params = new URLSearchParams(location.hash.slice(1))
|
||||
const token = params.get('refreshToken')
|
||||
if (token) {
|
||||
const type = params.get('type')
|
||||
if (type === 'signinPasswordless') {
|
||||
authService.send({ type: 'UPDATE_REFRESH_TOKEN', token })
|
||||
} else {
|
||||
console.warn(
|
||||
`Found a refresh token in the url but the redirect type is not implemented: ${type}`
|
||||
)
|
||||
}
|
||||
}
|
||||
}, [location, authService])
|
||||
|
||||
useEffect(() => {
|
||||
// TODO Move into the machine
|
||||
// * Side effect: persist the refresh token if found
|
||||
if (refreshToken) localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken)
|
||||
else {
|
||||
localStorage.removeItem(REFRESH_TOKEN_KEY)
|
||||
}
|
||||
}, [refreshToken])
|
||||
return (
|
||||
<NhostContext.Provider value={{ authService, backendUrl }}>
|
||||
{props.children}
|
||||
</NhostContext.Provider>
|
||||
)
|
||||
}
|
||||
@@ -1,487 +0,0 @@
|
||||
import { createMachine } from 'xstate'
|
||||
import { assign } from '@xstate/immer'
|
||||
import { produce } from 'immer'
|
||||
import axios from 'axios'
|
||||
import { validate as uuidValidate } from 'uuid'
|
||||
|
||||
export const REFRESH_TOKEN_KEY = 'refresh-token'
|
||||
|
||||
const DEFAULT_TOKEN_EXPIRATION = 900
|
||||
const MIN_PASSWORD_LENGTH = 3
|
||||
|
||||
// * Minimum number of seconds before the JWT expiration and the refresh
|
||||
const TOKEN_REFRESH_MARGIN = 900
|
||||
// const TOKEN_REFRESH_MARGIN = 180
|
||||
const MIN_TOKEN_REFRESH_INTERVAL = 60
|
||||
// const MIN_TOKEN_REFRESH_INTERVAL = 10
|
||||
const REFRESH_TOKEN_RETRY_INTERVAL = 10
|
||||
// const REFRESH_TOKEN_RETRY_INTERVAL = 5
|
||||
const REFRESH_TOKEN_RETRY_MAX_ATTEMPTS = 30
|
||||
// const REFRESH_TOKEN_RETRY_MAX_ATTEMPTS = 10
|
||||
|
||||
type User = Record<string, unknown>
|
||||
type NhostContext = {
|
||||
user?: User
|
||||
mfa?: boolean
|
||||
accessToken: { value?: string; expiresIn: number }
|
||||
refreshToken: { value?: string | null; timer: { elapsed: number; attempts: number } }
|
||||
error?: unknown
|
||||
email?: string
|
||||
password?: string
|
||||
}
|
||||
|
||||
type NhostMachineOptions = { backendUrl: string }
|
||||
export type NhostMachine = ReturnType<typeof createNhostMachine>
|
||||
|
||||
export type Nhost = {
|
||||
machine: NhostMachine
|
||||
backendUrl: string
|
||||
}
|
||||
|
||||
export const initNhost = ({ backendUrl }: NhostMachineOptions): Nhost => {
|
||||
return {
|
||||
backendUrl,
|
||||
machine: createNhostMachine({ backendUrl })
|
||||
}
|
||||
}
|
||||
|
||||
export const createNhostMachine = ({ backendUrl }: NhostMachineOptions) => {
|
||||
const initialContext: NhostContext = {
|
||||
user: undefined,
|
||||
mfa: undefined,
|
||||
accessToken: {
|
||||
value: undefined,
|
||||
expiresIn: DEFAULT_TOKEN_EXPIRATION
|
||||
},
|
||||
refreshToken: {
|
||||
value: undefined,
|
||||
timer: {
|
||||
elapsed: 0,
|
||||
attempts: 0
|
||||
}
|
||||
},
|
||||
error: undefined,
|
||||
email: undefined,
|
||||
password: undefined
|
||||
}
|
||||
return createMachine<NhostContext>(
|
||||
{
|
||||
id: 'authentication',
|
||||
type: 'parallel',
|
||||
context: produce(initialContext, (ctx) => {
|
||||
ctx.refreshToken.value = localStorage.getItem(REFRESH_TOKEN_KEY)
|
||||
}),
|
||||
states: {
|
||||
authentication: {
|
||||
initial: 'signedOut',
|
||||
states: {
|
||||
signedOut: {
|
||||
initial: 'noErrors',
|
||||
always: [
|
||||
{
|
||||
target: 'signedIn',
|
||||
cond: 'isUserSet'
|
||||
}
|
||||
],
|
||||
on: {
|
||||
SIGNIN: [
|
||||
{
|
||||
target: '.ininvalidEmail',
|
||||
cond: 'invalidEmail'
|
||||
},
|
||||
{
|
||||
target: '.ininvalidPassword',
|
||||
cond: 'invalidPassword'
|
||||
},
|
||||
{
|
||||
target: 'authenticating',
|
||||
actions: ['saveEmail', 'savePassword']
|
||||
}
|
||||
],
|
||||
SIGNIN_PASSWORDLESS_EMAIL: [
|
||||
{
|
||||
target: '.ininvalidEmail',
|
||||
cond: 'invalidEmail'
|
||||
},
|
||||
{
|
||||
target: 'authenticating',
|
||||
actions: 'saveEmail'
|
||||
}
|
||||
],
|
||||
REGISTER: [
|
||||
{
|
||||
target: '.ininvalidEmail',
|
||||
cond: 'invalidEmail'
|
||||
},
|
||||
{
|
||||
target: '.ininvalidPassword',
|
||||
cond: 'invalidPassword'
|
||||
},
|
||||
{
|
||||
target: 'registering',
|
||||
actions: ['saveEmail', 'savePassword']
|
||||
}
|
||||
]
|
||||
},
|
||||
states: {
|
||||
noErrors: {},
|
||||
ininvalidEmail: {},
|
||||
ininvalidPassword: {},
|
||||
awaitingVerification: {},
|
||||
failed: {
|
||||
initial: 'unkwown',
|
||||
states: {
|
||||
unkwown: {},
|
||||
network: {},
|
||||
existingUser: {},
|
||||
unauthorized: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
authenticating: {
|
||||
invoke: {
|
||||
id: 'authenticateUser',
|
||||
src: 'signIn',
|
||||
onDone: [
|
||||
{
|
||||
cond: 'hasUser',
|
||||
target: 'signedIn',
|
||||
actions: ['saveUser', 'clearForm']
|
||||
},
|
||||
{
|
||||
target: 'signedOut.awaitingVerification'
|
||||
}
|
||||
// TODO other authentication methods
|
||||
],
|
||||
onError: [
|
||||
{
|
||||
cond: 'networkError',
|
||||
target: 'signedOut.failed.network',
|
||||
actions: ['saveError']
|
||||
},
|
||||
{
|
||||
cond: 'unverified',
|
||||
target: 'signedOut.awaitingVerification',
|
||||
actions: 'saveError'
|
||||
},
|
||||
{
|
||||
cond: 'unauthorized',
|
||||
target: 'signedOut.failed.unauthorized',
|
||||
actions: 'saveError'
|
||||
},
|
||||
{
|
||||
target: 'signedOut.failed',
|
||||
actions: 'saveError'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
registering: {
|
||||
invoke: {
|
||||
id: 'registerUser',
|
||||
src: 'registerUser',
|
||||
onDone: [
|
||||
{
|
||||
target: 'signedIn',
|
||||
cond: 'hasUser',
|
||||
actions: ['saveUser', 'clearForm']
|
||||
},
|
||||
{ target: 'authenticating', actions: ['clearForm'] }
|
||||
],
|
||||
onError: [
|
||||
{
|
||||
cond: 'existingUser',
|
||||
target: 'signedOut.failed.existingUser',
|
||||
actions: 'saveError'
|
||||
},
|
||||
{
|
||||
target: 'signedOut.failed',
|
||||
actions: 'saveError'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
signedIn: {
|
||||
on: {
|
||||
SIGNOUT: {
|
||||
target: 'signingOut'
|
||||
}
|
||||
}
|
||||
},
|
||||
signingOut: {
|
||||
invoke: {
|
||||
id: 'signingOut',
|
||||
src: 'signout',
|
||||
onDone: {
|
||||
target: 'signedOut',
|
||||
actions: 'resetSession'
|
||||
},
|
||||
onError: { target: 'signedOut', actions: 'resetSession' }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
newRefreshToken: {
|
||||
initial: 'standby',
|
||||
states: {
|
||||
standby: {
|
||||
initial: 'noErrors',
|
||||
on: {
|
||||
UPDATE_REFRESH_TOKEN: [
|
||||
{
|
||||
cond: 'invalidRefreshToken',
|
||||
target: '.invalid'
|
||||
},
|
||||
{ target: 'validating' }
|
||||
]
|
||||
},
|
||||
states: {
|
||||
noErrors: {},
|
||||
error: {},
|
||||
invalid: {},
|
||||
network: {}
|
||||
}
|
||||
},
|
||||
validating: {
|
||||
invoke: {
|
||||
src: 'validateNewToken',
|
||||
onDone: {
|
||||
target: 'standby',
|
||||
actions: ['saveToken', 'resetRefreshTokenTimer']
|
||||
},
|
||||
onError: [
|
||||
{
|
||||
target: 'standby.network',
|
||||
cond: 'networkError'
|
||||
},
|
||||
{
|
||||
target: 'standby.error'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
tokenRefresher: {
|
||||
initial: 'idle',
|
||||
states: {
|
||||
stopped: {
|
||||
always: {
|
||||
cond: 'shouldWaitForToken',
|
||||
target: 'idle'
|
||||
}
|
||||
},
|
||||
idle: {
|
||||
always: [
|
||||
{
|
||||
cond: 'shouldStartTokenTimer',
|
||||
target: 'pending'
|
||||
}
|
||||
]
|
||||
},
|
||||
pending: {
|
||||
invoke: {
|
||||
src: 'startTokenTimer'
|
||||
},
|
||||
always: [
|
||||
{
|
||||
cond: 'shouldRefreshToken',
|
||||
target: 'refreshing'
|
||||
}
|
||||
],
|
||||
on: {
|
||||
TICK: {
|
||||
actions: 'tickTokenTimer'
|
||||
},
|
||||
SIGNOUT: {
|
||||
target: 'stopped',
|
||||
actions: 'resetRefreshTokenTimer'
|
||||
}
|
||||
}
|
||||
},
|
||||
refreshing: {
|
||||
invoke: {
|
||||
id: 'refreshToken',
|
||||
src: 'refreshToken',
|
||||
onDone: {
|
||||
target: 'pending',
|
||||
actions: ['saveToken', 'resetRefreshTokenTimer']
|
||||
},
|
||||
onError: [
|
||||
{
|
||||
target: 'pending',
|
||||
cond: 'canRetryTokenRefresh',
|
||||
actions: 'retryTokenRefresh'
|
||||
},
|
||||
{
|
||||
target: 'failed.network',
|
||||
cond: 'networkError',
|
||||
actions: 'resetRefreshTokenTimer'
|
||||
},
|
||||
{
|
||||
target: 'failed',
|
||||
actions: 'resetRefreshTokenTimer'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
failed: {
|
||||
initial: 'invalid',
|
||||
states: {
|
||||
invalid: {},
|
||||
network: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
actions: {
|
||||
clearForm: assign((ctx) => {
|
||||
ctx.email = undefined
|
||||
ctx.password = undefined
|
||||
}),
|
||||
saveUser: assign((ctx, e) => {
|
||||
ctx.user = e.data.session.user
|
||||
ctx.accessToken.value = e.data.session.accessToken
|
||||
ctx.accessToken.expiresIn = Math.max(
|
||||
e.data.session.accessTokenExpiresIn - TOKEN_REFRESH_MARGIN,
|
||||
MIN_TOKEN_REFRESH_INTERVAL
|
||||
)
|
||||
ctx.refreshToken.value = e.data.session.refreshToken
|
||||
ctx.mfa = e.data.mfa
|
||||
}),
|
||||
saveToken: assign((ctx, e) => {
|
||||
ctx.user = e.data.user
|
||||
ctx.accessToken.value = e.data.accessToken
|
||||
ctx.accessToken.expiresIn = Math.max(
|
||||
e.data.accessTokenExpiresIn - TOKEN_REFRESH_MARGIN,
|
||||
MIN_TOKEN_REFRESH_INTERVAL
|
||||
)
|
||||
ctx.refreshToken.value = e.data.refreshToken
|
||||
}),
|
||||
saveError: assign((ctx, { data: { response, request } }) => {
|
||||
ctx.error = {
|
||||
error: response?.data.error || request.statusText || 'network',
|
||||
message: response?.data.message || request.responseText || 'Network error',
|
||||
statusCode: response?.data.statusCode || request.status || 0
|
||||
}
|
||||
}),
|
||||
saveEmail: assign((ctx, e) => {
|
||||
ctx.email = e.email
|
||||
}),
|
||||
savePassword: assign((ctx, e) => {
|
||||
ctx.password = e.password
|
||||
}),
|
||||
resetSession: assign((ctx) => {
|
||||
ctx.user = undefined
|
||||
ctx.mfa = undefined
|
||||
ctx.accessToken.value = undefined
|
||||
ctx.refreshToken.value = undefined
|
||||
}),
|
||||
resetRefreshTokenTimer: assign((ctx) => {
|
||||
ctx.refreshToken.timer.elapsed = 0
|
||||
ctx.refreshToken.timer.attempts = 0
|
||||
}),
|
||||
tickTokenTimer: assign((ctx) => {
|
||||
ctx.refreshToken.timer.elapsed += 1 // * One second
|
||||
}),
|
||||
retryTokenRefresh: assign((ctx) => {
|
||||
ctx.accessToken.expiresIn = REFRESH_TOKEN_RETRY_INTERVAL
|
||||
ctx.refreshToken.timer.elapsed = 0
|
||||
ctx.refreshToken.timer.attempts += 1
|
||||
})
|
||||
},
|
||||
guards: {
|
||||
// * Context guards
|
||||
shouldStartTokenTimer: (ctx) => !!ctx.refreshToken.value,
|
||||
shouldWaitForToken: (ctx) => !ctx.refreshToken.value,
|
||||
shouldRefreshToken: (ctx) =>
|
||||
ctx.refreshToken.timer.elapsed >= ctx.accessToken.expiresIn || !ctx.user,
|
||||
isUserSet: (ctx) => !!ctx.user,
|
||||
|
||||
// * Hybrid guards
|
||||
// can retry token refresh only if number of attempts is not reached, and there is a network error
|
||||
canRetryTokenRefresh: (ctx, event) => {
|
||||
const remainingAttempts =
|
||||
ctx.refreshToken.timer.attempts < REFRESH_TOKEN_RETRY_MAX_ATTEMPTS
|
||||
const isNetworkError = !event.data.response && !event.data.request.status
|
||||
return remainingAttempts && isNetworkError
|
||||
},
|
||||
|
||||
// * Event guards
|
||||
hasUser: (_, e) => !!e.data.session,
|
||||
unverified: (_, e) =>
|
||||
e.data.response?.data?.statusCode === 401 &&
|
||||
e.data.response?.data?.message === 'Email is not verified',
|
||||
existingUser: (_, e) => e.data.response?.data.statusCode === 409,
|
||||
unauthorized: (_, e) => e.data.response?.data.statusCode === 401,
|
||||
networkError: (_, e) => !e.data.response && !e.data.request.status,
|
||||
invalidEmail: (_, e) =>
|
||||
!String(e.email)
|
||||
.toLowerCase()
|
||||
.match(
|
||||
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||
),
|
||||
invalidPassword: (_, e) => e.password.length <= MIN_PASSWORD_LENGTH,
|
||||
invalidRefreshToken: (_, e) => !uuidValidate(e.token)
|
||||
},
|
||||
services: {
|
||||
signIn: async ({ email, password }) => {
|
||||
// TODO options
|
||||
if (password) {
|
||||
const { data } = await axios.post(`${backendUrl}/v1/auth/signin/email-password`, {
|
||||
email,
|
||||
password
|
||||
})
|
||||
return data
|
||||
} else {
|
||||
const { data } = await axios.post(`${backendUrl}/v1/auth/signin/passwordless/email`, {
|
||||
email
|
||||
})
|
||||
return data
|
||||
}
|
||||
},
|
||||
signout: async (ctx, e) => {
|
||||
await axios.post(`${backendUrl}/v1/auth/signout`, {
|
||||
refreshToken: ctx.refreshToken.value,
|
||||
all: !!e.all
|
||||
})
|
||||
},
|
||||
|
||||
registerUser: async ({ email, password }) => {
|
||||
// TODO options
|
||||
const { data } = await axios.post(`${backendUrl}/v1/auth/signup/email-password`, {
|
||||
email,
|
||||
password
|
||||
})
|
||||
return data
|
||||
},
|
||||
|
||||
refreshToken: async ({ refreshToken: { value } }) => {
|
||||
const { data } = await axios.post(`${backendUrl}/v1/auth/token`, {
|
||||
refreshToken: value
|
||||
})
|
||||
return data
|
||||
},
|
||||
|
||||
validateNewToken: async (_, event) => {
|
||||
const { data } = await axios.post(`${backendUrl}/v1/auth/token`, {
|
||||
refreshToken: event.token
|
||||
})
|
||||
return data
|
||||
},
|
||||
|
||||
startTokenTimer: () => (cb) => {
|
||||
const interval = setInterval(
|
||||
() => cb('TICK'),
|
||||
1000 // * One tick per second
|
||||
)
|
||||
return () => clearInterval(interval)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()]
|
||||
})
|
||||
7
examples/testing-project/CHANGELOG.md
Normal file
7
examples/testing-project/CHANGELOG.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# @nhost-examples/testing-project
|
||||
|
||||
## 1.0.1
|
||||
### Patch Changes
|
||||
|
||||
- a880583: - Improve typings (close [this PR](https://github.com/nhost/hasura-auth-js/pull/15))
|
||||
- Add the metadata field introduced in [hasura-auth 0.2.0](https://github.com/nhost/hasura-auth/releases/tag/v0.2.0) (close [this PR](https://github.com/nhost/hasura-auth-js/pull/18))
|
||||
@@ -3,11 +3,11 @@ services:
|
||||
mailhog:
|
||||
port: 8025
|
||||
hasura:
|
||||
version: v2.1.0
|
||||
version: v2.2.0
|
||||
environment:
|
||||
hasura_graphql_enable_remote_schema_permissions: false
|
||||
auth:
|
||||
version: sha-c328aa7
|
||||
version: 0.2.1
|
||||
auth:
|
||||
access_control:
|
||||
email:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@nhost-examples/testing-project",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"version": "1.0.1",
|
||||
"description": "Wrapper to run the Nhost CLI for development and testing",
|
||||
"scripts": {
|
||||
"start": "nhost -d"
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
"prepare": "pnpm create-config",
|
||||
"build": "pnpm turbo run build --scope='@nhost/*' --no-deps --include-dependencies",
|
||||
"build:docs": "pnpm run build --filter=nhost-documentation",
|
||||
"clean:all": "pnpm clean && rm -rf ./packages/*/node_modules node_modules",
|
||||
"clean": "rm -rf ./packages/*/dist",
|
||||
"clean:all": "pnpm clean && rm -rf ./{{packages,examples}/*,docs}/node_modules node_modules",
|
||||
"clean": "rm -rf ./{{packages,examples}/*,docs}/{dist,.next,.turbo,coverage}",
|
||||
"ci": "pnpm turbo run build test --concurrency=4 --scope='@nhost/*' && pnpm run lint",
|
||||
"ci:version": "changeset version && pnpm install --frozen-lockfile false",
|
||||
"coverage": "pnpm run test --coverage",
|
||||
@@ -31,6 +31,7 @@
|
||||
"test": "pnpm turbo run test --scope='@nhost/*' --no-deps --include-dependencies",
|
||||
"prerelease": "pnpm clean && pnpm install && pnpm build",
|
||||
"release": "pnpm run prerelease && changeset publish && git push --follow-tags && git status && pnpm -r publish",
|
||||
"changeset": "changeset",
|
||||
"snapshot": "pnpm prerelease && changeset version --snapshot preview && pnpm install && changeset publish --tag preview"
|
||||
},
|
||||
"workspaces": [
|
||||
@@ -50,6 +51,8 @@
|
||||
"@typescript-eslint/eslint-plugin": "^5.10.2",
|
||||
"@typescript-eslint/parser": "^5.10.2",
|
||||
"@vitejs/plugin-react": "^1.1.4",
|
||||
"esbuild": "^0.14.23",
|
||||
"esbuild-node-externals": "^1.4.1",
|
||||
"eslint": "^8.8.0",
|
||||
"eslint-config-react-app": "^7.0.0",
|
||||
"eslint-plugin-flowtype": "^8.0.3",
|
||||
|
||||
@@ -1,6 +1,27 @@
|
||||
# @nhost/hasura-auth-js
|
||||
|
||||
## 0.1.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- c8f2488: build npm package with esbuild instead of vite. Vite does not build isomorphic packages correctly, in particular the dependency to axios
|
||||
|
||||
## 0.1.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2e1c055: Axios causes some trouble when used NodeJS / CommonJS. Any code importing `axios` now does so in using the `require()` syntax
|
||||
|
||||
## 0.1.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- a880583: - Improve typings (close [this PR](https://github.com/nhost/hasura-auth-js/pull/15))
|
||||
- Add the metadata field introduced in [hasura-auth 0.2.0](https://github.com/nhost/hasura-auth/releases/tag/v0.2.0) (close [this PR](https://github.com/nhost/hasura-auth-js/pull/18))
|
||||
- 03562af: Build in CommonJS and ESM instead of UMD and ESM as the UMD bundle generated by the default Vite lib build mode doesn't work with NodeJS
|
||||
|
||||
## 0.1.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7c3a7be: Remove http timeout options (fix[#157](https://github.com/nhost/nhost/issues/157))
|
||||
|
||||
31
packages/hasura-auth-js/build.js
Normal file
31
packages/hasura-auth-js/build.js
Normal file
@@ -0,0 +1,31 @@
|
||||
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: false,
|
||||
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: false, // TODO
|
||||
platform: 'browser',
|
||||
format: 'esm',
|
||||
sourcemap: true,
|
||||
target: 'esnext'
|
||||
})
|
||||
.catch(() => process.exit(1))
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/hasura-auth-js",
|
||||
"version": "0.1.11",
|
||||
"version": "0.1.14",
|
||||
"description": "Hasura-auth client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -20,7 +20,9 @@
|
||||
"url": "https://github.com/nhost/nhost.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "vite build --config ../../vite.lib.js",
|
||||
"build": "run-s build:esbuild build:types",
|
||||
"build:esbuild": "node ../../esbuild.lib.js",
|
||||
"build:types": "tsc --build tsconfig.types.json",
|
||||
"test": "pnpm jest --runInBand --config ../../jest.config.base.js",
|
||||
"prettier": "prettier --check src/",
|
||||
"prettier:fix": "prettier --write src/",
|
||||
@@ -29,16 +31,19 @@
|
||||
"verify": "run-p prettier lint",
|
||||
"verify:fix": "run-p prettier:fix lint:fix"
|
||||
},
|
||||
"main": "src/index.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.es.js",
|
||||
"require": "./dist/index.umd.js"
|
||||
"import": {
|
||||
"node": "./dist/index.cjs.js",
|
||||
"default": "./dist/index.es.js"
|
||||
},
|
||||
"require": "./dist/index.cjs.js"
|
||||
}
|
||||
},
|
||||
"main": "src/index.ts",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.umd.js",
|
||||
"main": "dist/index.cjs.js",
|
||||
"module": "dist/index.es.js",
|
||||
"typings": "./dist/index.d.ts"
|
||||
},
|
||||
|
||||
@@ -33,9 +33,7 @@ export class HasuraAuthApi {
|
||||
constructor({ url = '' }) {
|
||||
this.url = url
|
||||
|
||||
this.httpClient = axios.create({
|
||||
baseURL: this.url
|
||||
})
|
||||
this.httpClient = axios.create({ baseURL: this.url })
|
||||
|
||||
// convert axios error to custom ApiError
|
||||
this.httpClient.interceptors.response.use(
|
||||
|
||||
@@ -26,6 +26,8 @@ import {
|
||||
ApiError,
|
||||
ApiResetPasswordResponse,
|
||||
ApiSendVerificationEmailResponse,
|
||||
ApiSignInResponse,
|
||||
ApiSignOutResponse,
|
||||
AuthChangedFunction,
|
||||
AuthChangeEvent,
|
||||
ChangeEmailParams,
|
||||
@@ -105,7 +107,6 @@ export class HasuraAuthClient {
|
||||
this.initAuthLoading = true
|
||||
|
||||
this.session = null
|
||||
// this.user = null;
|
||||
|
||||
this.api = new HasuraAuthApi({ url: this.url })
|
||||
|
||||
@@ -313,7 +314,7 @@ export class HasuraAuthClient {
|
||||
*
|
||||
* @docs https://docs.nhost.io/TODO
|
||||
*/
|
||||
async signOut(params?: { all?: boolean }): Promise<unknown> {
|
||||
async signOut(params?: { all?: boolean }): Promise<ApiSignOutResponse> {
|
||||
const refreshToken = await this._getItem(NHOST_REFRESH_TOKEN)
|
||||
|
||||
this._clearSession()
|
||||
@@ -333,10 +334,8 @@ export class HasuraAuthClient {
|
||||
*
|
||||
* @docs https://docs.nhost.io/TODO
|
||||
*/
|
||||
async verifyEmail(params: { email: string; ticket: string }): Promise<unknown> {
|
||||
const { data, error } = await this.api.verifyEmail(params)
|
||||
|
||||
return { data, error }
|
||||
async verifyEmail(params: { email: string; ticket: string }): Promise<ApiSignInResponse> {
|
||||
return await this.api.verifyEmail(params)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,7 +7,7 @@ export interface User {
|
||||
email?: string
|
||||
isAnonymous: boolean
|
||||
defaultRole: string
|
||||
roles: Record<string, string>
|
||||
roles: string[]
|
||||
}
|
||||
|
||||
export interface Session {
|
||||
@@ -32,6 +32,7 @@ export interface SignUpEmailPasswordParams {
|
||||
defaultRole?: string
|
||||
displayName?: string
|
||||
redirectTo?: string
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +56,7 @@ export interface SignInPasswordlessEmailParams {
|
||||
defaultRole?: string
|
||||
displayName?: string
|
||||
redirectTo?: string
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +68,7 @@ export interface SignInPasswordlessSmsParams {
|
||||
defaultRole?: string
|
||||
displayName?: string
|
||||
redirectTo?: string
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +95,7 @@ export interface SignInWithProviderOptions {
|
||||
defaultRole?: string
|
||||
displayName?: string
|
||||
redirectTo?: string
|
||||
metadata?: Record<string, unknown>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,24 @@ describe('sign-up', () => {
|
||||
expect(session).toBeNull()
|
||||
})
|
||||
|
||||
test('sign up with metadata', async () => {
|
||||
const email = faker.internet.email().toLocaleLowerCase()
|
||||
const password = faker.internet.password(8)
|
||||
|
||||
const { session, error } = await auth.signUp({
|
||||
email,
|
||||
password,
|
||||
options: {
|
||||
metadata: {
|
||||
birthDate: '1990-01-01'
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
expect(error).toBeNull()
|
||||
expect(session).toBeNull()
|
||||
})
|
||||
|
||||
it('sign up with options', async () => {
|
||||
const email = faker.internet.email().toLocaleLowerCase()
|
||||
const password = faker.internet.password(8)
|
||||
|
||||
10
packages/hasura-auth-js/tsconfig.types.json
Normal file
10
packages/hasura-auth-js/tsconfig.types.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
@@ -1,6 +1,25 @@
|
||||
# @nhost/hasura-storage-js
|
||||
|
||||
## 0.0.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- c8f2488: build npm package with esbuild instead of vite. Vite does not build isomorphic packages correctly, in particular the dependency to axios
|
||||
|
||||
## 0.0.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2e1c055: Axios causes some trouble when used NodeJS / CommonJS. Any code importing `axios` now does so in using the `require()` syntax
|
||||
|
||||
## 0.0.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 03562af: Build in CommonJS and ESM instead of UMD and ESM as the UMD bundle generated by the default Vite lib build mode doesn't work with NodeJS
|
||||
|
||||
## 0.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 7c3a7be: Remove http timeout options (fix[#157](https://github.com/nhost/nhost/issues/157))
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/hasura-storage-js",
|
||||
"version": "0.0.7",
|
||||
"version": "0.0.10",
|
||||
"description": "Hasura-storage client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -18,7 +18,9 @@
|
||||
"url": "https://github.com/nhost/hasura-storage-js.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "vite build --config ../../vite.lib.js",
|
||||
"build": "run-s build:esbuild build:types",
|
||||
"build:esbuild": "node ../../esbuild.lib.js",
|
||||
"build:types": "tsc --build tsconfig.types.json",
|
||||
"test": "pnpm jest --runInBand --config ../../jest.config.base.js",
|
||||
"prettier": "prettier --check src/",
|
||||
"prettier:fix": "prettier --write src/",
|
||||
@@ -27,16 +29,19 @@
|
||||
"verify": "run-p prettier lint",
|
||||
"verify:fix": "run-p prettier:fix lint:fix"
|
||||
},
|
||||
"main": "src/index.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.es.js",
|
||||
"require": "./dist/index.umd.js"
|
||||
"import": {
|
||||
"node": "./dist/index.cjs.js",
|
||||
"default": "./dist/index.es.js"
|
||||
},
|
||||
"require": "./dist/index.cjs.js"
|
||||
}
|
||||
},
|
||||
"main": "src/index.ts",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.umd.js",
|
||||
"main": "dist/index.cjs.js",
|
||||
"module": "dist/index.es.js",
|
||||
"typings": "./dist/index.d.ts"
|
||||
},
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
ApiUploadResponse,
|
||||
UploadHeaders
|
||||
} from './utils/types'
|
||||
|
||||
export class HasuraStorageApi {
|
||||
private url: string
|
||||
private httpClient: AxiosInstance
|
||||
|
||||
10
packages/hasura-storage-js/tsconfig.types.json
Normal file
10
packages/hasura-storage-js/tsconfig.types.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
@@ -1,6 +1,35 @@
|
||||
# @nhost/nhost-js
|
||||
|
||||
## 0.3.10
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- c8f2488: build npm package with esbuild instead of vite. Vite does not build isomorphic packages correctly, in particular the dependency to axios
|
||||
- Updated dependencies [c8f2488]
|
||||
- @nhost/hasura-auth-js@0.1.14
|
||||
- @nhost/hasura-storage-js@0.0.10
|
||||
|
||||
## 0.3.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 2e1c055: Axios causes some trouble when used NodeJS / CommonJS. Any code importing `axios` now does so in using the `require()` syntax
|
||||
- Updated dependencies [2e1c055]
|
||||
- @nhost/hasura-auth-js@0.1.13
|
||||
- @nhost/hasura-storage-js@0.0.9
|
||||
|
||||
## 0.3.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 03562af: Build in CommonJS and ESM instead of UMD and ESM as the UMD bundle generated by the default Vite lib build mode doesn't work with NodeJS
|
||||
- Updated dependencies [a880583]
|
||||
- Updated dependencies [03562af]
|
||||
- @nhost/hasura-auth-js@0.1.12
|
||||
- @nhost/hasura-storage-js@0.0.8
|
||||
|
||||
## 0.3.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [7c3a7be]
|
||||
|
||||
BIN
packages/nhost-js/nhost-nhost-js-0.3.9.tgz
Normal file
BIN
packages/nhost-js/nhost-nhost-js-0.3.9.tgz
Normal file
Binary file not shown.
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/nhost-js",
|
||||
"version": "0.3.7",
|
||||
"version": "0.3.10",
|
||||
"description": "Nhost JavaScript SDK",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -20,16 +20,19 @@
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/nhost/nhost.git"
|
||||
},
|
||||
"main": "src/index.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.es.js",
|
||||
"require": "./dist/index.umd.js"
|
||||
"import": {
|
||||
"node": "./dist/index.cjs.js",
|
||||
"default": "./dist/index.es.js"
|
||||
},
|
||||
"require": "./dist/index.cjs.js"
|
||||
}
|
||||
},
|
||||
"main": "src/index.ts",
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.umd.js",
|
||||
"main": "dist/index.cjs.js",
|
||||
"module": "dist/index.es.js",
|
||||
"typings": "./dist/index.d.ts"
|
||||
},
|
||||
@@ -37,7 +40,9 @@
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "vite build --config ../../vite.lib.js",
|
||||
"build": "run-s build:esbuild build:types",
|
||||
"build:esbuild": "node ../../esbuild.lib.js",
|
||||
"build:types": "tsc --build tsconfig.types.json",
|
||||
"test": "pnpm jest --runInBand --config ../../jest.config.base.js",
|
||||
"prettier": "prettier --check src/",
|
||||
"prettier:fix": "prettier --write src/",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import axios, { AxiosInstance, AxiosRequestConfig } from 'axios'
|
||||
|
||||
import { FunctionCallResponse } from '../types'
|
||||
|
||||
export interface NhostFunctionsConstructorParams {
|
||||
url: string
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AxiosResponse } from 'axios'
|
||||
import type { AxiosResponse } from 'axios'
|
||||
|
||||
export type GraphqlRequestResponse =
|
||||
| {
|
||||
|
||||
@@ -4,6 +4,6 @@
|
||||
"outDir": "dist",
|
||||
"composite": true
|
||||
},
|
||||
"include": ["src/**/*", "types/**/*", "../../types/**/*", "tests/**/*"],
|
||||
"include": ["src/**/*", "tests/**/*"],
|
||||
"references": [{ "path": "../hasura-auth-js" }, { "path": "../hasura-storage-js" }]
|
||||
}
|
||||
|
||||
10
packages/nhost-js/tsconfig.types.json
Normal file
10
packages/nhost-js/tsconfig.types.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"emitDeclarationOnly": true,
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"composite": false
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
}
|
||||
@@ -1,6 +1,30 @@
|
||||
# @nhost/react-apollo
|
||||
|
||||
## 2.1.1
|
||||
## 2.1.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@0.3.7
|
||||
- c8f2488: optimize npm packages: only include the `dist` directory, and introduce the `exports` field in package.json as per Vite's recommendations.
|
||||
- Updated dependencies [c8f2488]
|
||||
- @nhost/nhost-js@0.3.10
|
||||
|
||||
## 2.1.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2e1c055]
|
||||
- @nhost/nhost-js@0.3.9
|
||||
|
||||
## 2.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 03562af: Build in CommonJS and ESM instead of UMD and ESM as the UMD bundle generated by the default Vite lib build mode doesn't work with NodeJS
|
||||
- Updated dependencies [03562af]
|
||||
- @nhost/nhost-js@0.3.8
|
||||
|
||||
## 2.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@0.3.7
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/react-apollo",
|
||||
"version": "2.1.1",
|
||||
"version": "2.1.4",
|
||||
"description": "Nhost React Apollo client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -33,16 +33,21 @@
|
||||
"verify:fix": "run-p prettier:fix lint:fix"
|
||||
},
|
||||
"main": "src/index.tsx",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.es.js",
|
||||
"require": "./dist/index.umd.js"
|
||||
}
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.umd.js",
|
||||
"module": "dist/index.es.js",
|
||||
"typings": "dist/index.d.ts"
|
||||
},
|
||||
"exports": {
|
||||
"import": "./dist/index.es.js",
|
||||
"require": "./dist/index.umd.js"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@nhost/nhost-js": "workspace:*",
|
||||
"subscriptions-transport-ws": "^0.11.0"
|
||||
|
||||
@@ -1,6 +1,30 @@
|
||||
# @nhost/react-auth
|
||||
|
||||
## 2.0.4
|
||||
## 2.0.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@0.3.7
|
||||
- c8f2488: optimize npm packages: only include the `dist` directory, and introduce the `exports` field in package.json as per Vite's recommendations.
|
||||
- Updated dependencies [c8f2488]
|
||||
- @nhost/nhost-js@0.3.10
|
||||
|
||||
## 2.0.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [2e1c055]
|
||||
- @nhost/nhost-js@0.3.9
|
||||
|
||||
## 2.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 03562af: Build in CommonJS and ESM instead of UMD and ESM as the UMD bundle generated by the default Vite lib build mode doesn't work with NodeJS
|
||||
- Updated dependencies [03562af]
|
||||
- @nhost/nhost-js@0.3.8
|
||||
|
||||
## 2.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- @nhost/nhost-js@0.3.7
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nhost/react-auth",
|
||||
"version": "2.0.4",
|
||||
"version": "2.0.7",
|
||||
"description": "Nhost React client",
|
||||
"license": "MIT",
|
||||
"keywords": [
|
||||
@@ -32,16 +32,21 @@
|
||||
"verify:fix": "run-p prettier:fix lint:fix"
|
||||
},
|
||||
"main": "src/index.tsx",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.es.js",
|
||||
"require": "./dist/index.umd.js"
|
||||
}
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"main": "dist/index.umd.js",
|
||||
"module": "dist/index.es.js",
|
||||
"typings": "dist/index.d.ts"
|
||||
},
|
||||
"exports": {
|
||||
"import": "./dist/index.es.js",
|
||||
"require": "./dist/index.umd.js"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@nhost/nhost-js": "workspace:*"
|
||||
},
|
||||
|
||||
549
pnpm-lock.yaml
generated
549
pnpm-lock.yaml
generated
@@ -18,6 +18,8 @@ importers:
|
||||
'@typescript-eslint/eslint-plugin': ^5.10.2
|
||||
'@typescript-eslint/parser': ^5.10.2
|
||||
'@vitejs/plugin-react': ^1.1.4
|
||||
esbuild: ^0.14.23
|
||||
esbuild-node-externals: ^1.4.1
|
||||
eslint: ^8.8.0
|
||||
eslint-config-react-app: ^7.0.0
|
||||
eslint-plugin-flowtype: ^8.0.3
|
||||
@@ -51,6 +53,8 @@ importers:
|
||||
'@typescript-eslint/eslint-plugin': 5.10.2_2595c2126aec4d4b6e944b931dabb4c2
|
||||
'@typescript-eslint/parser': 5.10.2_eslint@8.8.0+typescript@4.5.5
|
||||
'@vitejs/plugin-react': 1.1.4
|
||||
esbuild: 0.14.23
|
||||
esbuild-node-externals: 1.4.1_esbuild@0.14.23
|
||||
eslint: 8.8.0
|
||||
eslint-config-react-app: 7.0.0_a6c0b4b025f24103ac02f085889529a6
|
||||
eslint-plugin-flowtype: 8.0.3_12258a13d40b5ed3e212f958cc1c2840
|
||||
@@ -65,7 +69,7 @@ importers:
|
||||
jest: 27.5.0
|
||||
npm-run-all: 4.1.5
|
||||
prettier: 2.5.1
|
||||
ts-jest: 27.1.3_7ef2d78ce471893f470776eba2d1fa48
|
||||
ts-jest: 27.1.3_878bcc2d6ed80d2663ee54e5f78292d8
|
||||
tsconfig-paths-jest: 0.0.1
|
||||
turbo: 1.1.2
|
||||
typescript: 4.5.5
|
||||
@@ -224,49 +228,6 @@ importers:
|
||||
postcss: 7.0.39
|
||||
tailwindcss: /@tailwindcss/postcss7-compat/2.2.17
|
||||
|
||||
examples/react-xstate:
|
||||
specifiers:
|
||||
'@apollo/client': ^3.5.8
|
||||
'@types/react': ^17.0.39
|
||||
'@types/react-dom': ^17.0.11
|
||||
'@types/uuid': ^8.3.4
|
||||
'@vitejs/plugin-react': ^1.1.4
|
||||
'@xstate/immer': ^0.3.1
|
||||
'@xstate/inspect': ^0.6.2
|
||||
'@xstate/react': ^2.0.0
|
||||
axios: ^0.25.0
|
||||
immer: ^9.0.12
|
||||
react: ^17.0.2
|
||||
react-dom: ^17.0.2
|
||||
react-use: ^17.3.2
|
||||
subscriptions-transport-ws: ^0.11.0
|
||||
typescript: ^4.5.5
|
||||
uuid: ^8.3.2
|
||||
vite: ^2.7.13
|
||||
ws: ^8.4.2
|
||||
xstate: ^4.29.0
|
||||
dependencies:
|
||||
'@xstate/immer': 0.3.1_immer@9.0.12+xstate@4.29.0
|
||||
'@xstate/react': 2.0.0_b2730fbad1dada8c45d201a94f0d2c3b
|
||||
axios: 0.25.0
|
||||
immer: 9.0.12
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
react-use: 17.3.2_react-dom@17.0.2+react@17.0.2
|
||||
uuid: 8.3.2
|
||||
xstate: 4.29.0
|
||||
devDependencies:
|
||||
'@apollo/client': 3.5.8_cbd8c9fa2001af7e0ced74f4858d2097
|
||||
'@types/react': 17.0.39
|
||||
'@types/react-dom': 17.0.11
|
||||
'@types/uuid': 8.3.4
|
||||
'@vitejs/plugin-react': 1.1.4
|
||||
'@xstate/inspect': 0.6.2_ws@8.4.2
|
||||
subscriptions-transport-ws: 0.11.0
|
||||
typescript: 4.5.5
|
||||
vite: 2.7.13
|
||||
ws: 8.4.2
|
||||
|
||||
examples/testing-project:
|
||||
specifiers: {}
|
||||
|
||||
@@ -380,34 +341,6 @@ packages:
|
||||
zen-observable-ts: 1.2.3
|
||||
dev: true
|
||||
|
||||
/@apollo/client/3.5.8_cbd8c9fa2001af7e0ced74f4858d2097:
|
||||
resolution: {integrity: sha512-MAm05+I1ullr64VLpZwon/ISnkMuNLf6vDqgo9wiMhHYBGT4yOAbAIseRdjCHZwfSx/7AUuBgaTNOssZPIr6FQ==}
|
||||
peerDependencies:
|
||||
graphql: ^14.0.0 || ^15.0.0 || ^16.0.0
|
||||
react: ^16.8.0 || ^17.0.0
|
||||
subscriptions-transport-ws: ^0.9.0 || ^0.11.0
|
||||
peerDependenciesMeta:
|
||||
react:
|
||||
optional: true
|
||||
subscriptions-transport-ws:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@graphql-typed-document-node/core': 3.1.1
|
||||
'@wry/context': 0.6.1
|
||||
'@wry/equality': 0.5.2
|
||||
'@wry/trie': 0.3.1
|
||||
graphql-tag: 2.12.6
|
||||
hoist-non-react-statics: 3.3.2
|
||||
optimism: 0.16.1
|
||||
prop-types: 15.8.1
|
||||
react: 17.0.2
|
||||
subscriptions-transport-ws: 0.11.0
|
||||
symbol-observable: 4.0.0
|
||||
ts-invariant: 0.9.4
|
||||
tslib: 2.3.1
|
||||
zen-observable-ts: 1.2.3
|
||||
dev: true
|
||||
|
||||
/@apollo/client/3.5.8_graphql@15.7.2+react@17.0.2:
|
||||
resolution: {integrity: sha512-MAm05+I1ullr64VLpZwon/ISnkMuNLf6vDqgo9wiMhHYBGT4yOAbAIseRdjCHZwfSx/7AUuBgaTNOssZPIr6FQ==}
|
||||
peerDependencies:
|
||||
@@ -2710,12 +2643,6 @@ packages:
|
||||
value-or-promise: 1.0.11
|
||||
dev: true
|
||||
|
||||
/@graphql-typed-document-node/core/3.1.1:
|
||||
resolution: {integrity: sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==}
|
||||
peerDependencies:
|
||||
graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
|
||||
dev: true
|
||||
|
||||
/@graphql-typed-document-node/core/3.1.1_graphql@15.7.2:
|
||||
resolution: {integrity: sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==}
|
||||
peerDependencies:
|
||||
@@ -4073,10 +4000,6 @@ packages:
|
||||
jest-diff: 27.5.0
|
||||
pretty-format: 27.5.0
|
||||
|
||||
/@types/js-cookie/2.2.7:
|
||||
resolution: {integrity: sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==}
|
||||
dev: false
|
||||
|
||||
/@types/js-yaml/4.0.5:
|
||||
resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==}
|
||||
dev: true
|
||||
@@ -4185,6 +4108,7 @@ packages:
|
||||
resolution: {integrity: sha512-f96K3k+24RaLGVu/Y2Ng3e1EbZ8/cVJvypZWd7cy0ofCBaf2lcM46xNhycMZ2xGwbBjRql7hOlZ+e2WlJ5MH3Q==}
|
||||
dependencies:
|
||||
'@types/react': 17.0.39
|
||||
dev: false
|
||||
|
||||
/@types/react/17.0.39:
|
||||
resolution: {integrity: sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug==}
|
||||
@@ -4239,10 +4163,6 @@ packages:
|
||||
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
|
||||
dev: false
|
||||
|
||||
/@types/uuid/8.3.4:
|
||||
resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==}
|
||||
dev: true
|
||||
|
||||
/@types/webpack-sources/3.2.0:
|
||||
resolution: {integrity: sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg==}
|
||||
dependencies:
|
||||
@@ -4782,53 +4702,6 @@ packages:
|
||||
dependencies:
|
||||
tslib: 2.3.1
|
||||
|
||||
/@xobotyi/scrollbar-width/1.9.5:
|
||||
resolution: {integrity: sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==}
|
||||
dev: false
|
||||
|
||||
/@xstate/immer/0.3.1_immer@9.0.12+xstate@4.29.0:
|
||||
resolution: {integrity: sha512-YE+KY08IjEEmXo6XKKpeSGW4j9LfcXw+5JVixLLUO3fWQ3M95joWJ40VtGzx0w0zQSzoCNk8NgfvwWBGSbIaTA==}
|
||||
peerDependencies:
|
||||
immer: ^9.0.6
|
||||
xstate: ^4.29.0
|
||||
dependencies:
|
||||
immer: 9.0.12
|
||||
xstate: 4.29.0
|
||||
dev: false
|
||||
|
||||
/@xstate/inspect/0.6.2_ws@8.4.2:
|
||||
resolution: {integrity: sha512-ZDJ0NETucV7wyT2Tyr3VeEgVD45TUGMTwbzmU2JfzUOjJQMyqn/XjcXGa3wxzgSvz2I0L4xC5ahRZN85j7oh1Q==}
|
||||
peerDependencies:
|
||||
'@types/ws': ^8.0.0
|
||||
ws: ^8.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/ws':
|
||||
optional: true
|
||||
dependencies:
|
||||
fast-safe-stringify: 2.1.1
|
||||
ws: 8.4.2
|
||||
dev: true
|
||||
|
||||
/@xstate/react/2.0.0_b2730fbad1dada8c45d201a94f0d2c3b:
|
||||
resolution: {integrity: sha512-Pw8uHkamrMxoV8cwnVHv570Zun7o2ktokn5bkUOrv6PufFg5JHL2URiGvbyR9JqmIxfJdXregWvCGa3pqXd7Cg==}
|
||||
peerDependencies:
|
||||
'@xstate/fsm': ^1.6.4
|
||||
react: ^16.8.0 || ^17.0.0
|
||||
xstate: ^4.29.0
|
||||
peerDependenciesMeta:
|
||||
'@xstate/fsm':
|
||||
optional: true
|
||||
xstate:
|
||||
optional: true
|
||||
dependencies:
|
||||
react: 17.0.2
|
||||
use-isomorphic-layout-effect: 1.1.1_a0c521d4794c7ad97f5f4c1c4a7d5818
|
||||
use-subscription: 1.5.1_react@17.0.2
|
||||
xstate: 4.29.0
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
dev: false
|
||||
|
||||
/@xtuc/ieee754/1.2.0:
|
||||
resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==}
|
||||
dev: false
|
||||
@@ -6865,12 +6738,6 @@ packages:
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/copy-to-clipboard/3.3.1:
|
||||
resolution: {integrity: sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==}
|
||||
dependencies:
|
||||
toggle-selection: 1.0.6
|
||||
dev: false
|
||||
|
||||
/core-js-compat/3.21.0:
|
||||
resolution: {integrity: sha512-OSXseNPSK2OPJa6GdtkMz/XxeXx8/CJvfhQWTqd6neuUraujcL4jVsjkLQz1OWnax8xVQJnRPe0V2jqNWORA+A==}
|
||||
dependencies:
|
||||
@@ -7065,13 +6932,6 @@ packages:
|
||||
postcss-selector-parser: 5.0.0
|
||||
dev: false
|
||||
|
||||
/css-in-js-utils/2.0.1:
|
||||
resolution: {integrity: sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==}
|
||||
dependencies:
|
||||
hyphenate-style-name: 1.0.4
|
||||
isobject: 3.0.1
|
||||
dev: false
|
||||
|
||||
/css-loader/4.3.0_webpack@4.44.2:
|
||||
resolution: {integrity: sha512-rdezjCjScIrsL8BSYszgT4s476IcNKt6yX69t0pHjJVnPUTDpn4WfIpDQTN3wCJvUvfsz/mFjuGOekf3PY3NUg==}
|
||||
engines: {node: '>= 10.13.0'}
|
||||
@@ -7963,6 +7823,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-android-arm64/0.14.23:
|
||||
resolution: {integrity: sha512-k9sXem++mINrZty1v4FVt6nC5BQCFG4K2geCIUUqHNlTdFnuvcqsY7prcKZLFhqVC1rbcJAr9VSUGFL/vD4vsw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-darwin-64/0.13.15:
|
||||
resolution: {integrity: sha512-ihOQRGs2yyp7t5bArCwnvn2Atr6X4axqPpEdCFPVp7iUj4cVSdisgvEKdNR7yH3JDjW6aQDw40iQFoTqejqxvQ==}
|
||||
cpu: [x64]
|
||||
@@ -7971,6 +7840,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-darwin-64/0.14.23:
|
||||
resolution: {integrity: sha512-lB0XRbtOYYL1tLcYw8BoBaYsFYiR48RPrA0KfA/7RFTr4MV7Bwy/J4+7nLsVnv9FGuQummM3uJ93J3ptaTqFug==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-darwin-arm64/0.13.15:
|
||||
resolution: {integrity: sha512-i1FZssTVxUqNlJ6cBTj5YQj4imWy3m49RZRnHhLpefFIh0To05ow9DTrXROTE1urGTQCloFUXTX8QfGJy1P8dQ==}
|
||||
cpu: [arm64]
|
||||
@@ -7979,6 +7857,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-darwin-arm64/0.14.23:
|
||||
resolution: {integrity: sha512-yat73Z/uJ5tRcfRiI4CCTv0FSnwErm3BJQeZAh+1tIP0TUNh6o+mXg338Zl5EKChD+YGp6PN+Dbhs7qa34RxSw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-freebsd-64/0.13.15:
|
||||
resolution: {integrity: sha512-G3dLBXUI6lC6Z09/x+WtXBXbOYQZ0E8TDBqvn7aMaOCzryJs8LyVXKY4CPnHFXZAbSwkCbqiPuSQ1+HhrNk7EA==}
|
||||
cpu: [x64]
|
||||
@@ -7987,6 +7874,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-freebsd-64/0.14.23:
|
||||
resolution: {integrity: sha512-/1xiTjoLuQ+LlbfjJdKkX45qK/M7ARrbLmyf7x3JhyQGMjcxRYVR6Dw81uH3qlMHwT4cfLW4aEVBhP1aNV7VsA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-freebsd-arm64/0.13.15:
|
||||
resolution: {integrity: sha512-KJx0fzEDf1uhNOZQStV4ujg30WlnwqUASaGSFPhznLM/bbheu9HhqZ6mJJZM32lkyfGJikw0jg7v3S0oAvtvQQ==}
|
||||
cpu: [arm64]
|
||||
@@ -7995,6 +7891,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-freebsd-arm64/0.14.23:
|
||||
resolution: {integrity: sha512-uyPqBU/Zcp6yEAZS4LKj5jEE0q2s4HmlMBIPzbW6cTunZ8cyvjG6YWpIZXb1KK3KTJDe62ltCrk3VzmWHp+iLg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-32/0.13.15:
|
||||
resolution: {integrity: sha512-ZvTBPk0YWCLMCXiFmD5EUtB30zIPvC5Itxz0mdTu/xZBbbHJftQgLWY49wEPSn2T/TxahYCRDWun5smRa0Tu+g==}
|
||||
cpu: [ia32]
|
||||
@@ -8003,6 +7908,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-32/0.14.23:
|
||||
resolution: {integrity: sha512-37R/WMkQyUfNhbH7aJrr1uCjDVdnPeTHGeDhZPUNhfoHV0lQuZNCKuNnDvlH/u/nwIYZNdVvz1Igv5rY/zfrzQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-64/0.13.15:
|
||||
resolution: {integrity: sha512-eCKzkNSLywNeQTRBxJRQ0jxRCl2YWdMB3+PkWFo2BBQYC5mISLIVIjThNtn6HUNqua1pnvgP5xX0nHbZbPj5oA==}
|
||||
cpu: [x64]
|
||||
@@ -8011,6 +7925,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-64/0.14.23:
|
||||
resolution: {integrity: sha512-H0gztDP60qqr8zoFhAO64waoN5yBXkmYCElFklpd6LPoobtNGNnDe99xOQm28+fuD75YJ7GKHzp/MLCLhw2+vQ==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-arm/0.13.15:
|
||||
resolution: {integrity: sha512-wUHttDi/ol0tD8ZgUMDH8Ef7IbDX+/UsWJOXaAyTdkT7Yy9ZBqPg8bgB/Dn3CZ9SBpNieozrPRHm0BGww7W/jA==}
|
||||
cpu: [arm]
|
||||
@@ -8019,6 +7942,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-arm/0.14.23:
|
||||
resolution: {integrity: sha512-x64CEUxi8+EzOAIpCUeuni0bZfzPw/65r8tC5cy5zOq9dY7ysOi5EVQHnzaxS+1NmV+/RVRpmrzGw1QgY2Xpmw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-arm64/0.13.15:
|
||||
resolution: {integrity: sha512-bYpuUlN6qYU9slzr/ltyLTR9YTBS7qUDymO8SV7kjeNext61OdmqFAzuVZom+OLW1HPHseBfJ/JfdSlx8oTUoA==}
|
||||
cpu: [arm64]
|
||||
@@ -8027,6 +7959,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-arm64/0.14.23:
|
||||
resolution: {integrity: sha512-c4MLOIByNHR55n3KoYf9hYDfBRghMjOiHLaoYLhkQkIabb452RWi+HsNgB41sUpSlOAqfpqKPFNg7VrxL3UX9g==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-mips64le/0.13.15:
|
||||
resolution: {integrity: sha512-KlVjIG828uFPyJkO/8gKwy9RbXhCEUeFsCGOJBepUlpa7G8/SeZgncUEz/tOOUJTcWMTmFMtdd3GElGyAtbSWg==}
|
||||
cpu: [mips64el]
|
||||
@@ -8035,6 +7976,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-mips64le/0.14.23:
|
||||
resolution: {integrity: sha512-kHKyKRIAedYhKug2EJpyJxOUj3VYuamOVA1pY7EimoFPzaF3NeY7e4cFBAISC/Av0/tiV0xlFCt9q0HJ68IBIw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-ppc64le/0.13.15:
|
||||
resolution: {integrity: sha512-h6gYF+OsaqEuBjeesTBtUPw0bmiDu7eAeuc2OEH9S6mV9/jPhPdhOWzdeshb0BskRZxPhxPOjqZ+/OqLcxQwEQ==}
|
||||
cpu: [ppc64]
|
||||
@@ -8043,6 +7993,33 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-ppc64le/0.14.23:
|
||||
resolution: {integrity: sha512-7ilAiJEPuJJnJp/LiDO0oJm5ygbBPzhchJJh9HsHZzeqO+3PUzItXi+8PuicY08r0AaaOe25LA7sGJ0MzbfBag==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-riscv64/0.14.23:
|
||||
resolution: {integrity: sha512-fbL3ggK2wY0D8I5raPIMPhpCvODFE+Bhb5QGtNP3r5aUsRR6TQV+ZBXIaw84iyvKC8vlXiA4fWLGhghAd/h/Zg==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-linux-s390x/0.14.23:
|
||||
resolution: {integrity: sha512-GHMDCyfy7+FaNSO8RJ8KCFsnax8fLUsOrj9q5Gi2JmZMY0Zhp75keb5abTFCq2/Oy6KVcT0Dcbyo/bFb4rIFJA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-netbsd-64/0.13.15:
|
||||
resolution: {integrity: sha512-3+yE9emwoevLMyvu+iR3rsa+Xwhie7ZEHMGDQ6dkqP/ndFzRHkobHUKTe+NCApSqG5ce2z4rFu+NX/UHnxlh3w==}
|
||||
cpu: [x64]
|
||||
@@ -8051,6 +8028,25 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-netbsd-64/0.14.23:
|
||||
resolution: {integrity: sha512-ovk2EX+3rrO1M2lowJfgMb/JPN1VwVYrx0QPUyudxkxLYrWeBxDKQvc6ffO+kB4QlDyTfdtAURrVzu3JeNdA2g==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-node-externals/1.4.1_esbuild@0.14.23:
|
||||
resolution: {integrity: sha512-ZFNGa6w1kYzn4wx9ty4eaItaOTSe2hWQZ6WXa/8guKJCiXL3XpW2CZT4gkx2OhfBKxpqaqa7ZeGK54ScoLSUdw==}
|
||||
peerDependencies:
|
||||
esbuild: 0.12 - 0.14
|
||||
dependencies:
|
||||
esbuild: 0.14.23
|
||||
find-up: 5.0.0
|
||||
tslib: 2.3.1
|
||||
dev: true
|
||||
|
||||
/esbuild-openbsd-64/0.13.15:
|
||||
resolution: {integrity: sha512-wTfvtwYJYAFL1fSs8yHIdf5GEE4NkbtbXtjLWjM3Cw8mmQKqsg8kTiqJ9NJQe5NX/5Qlo7Xd9r1yKMMkHllp5g==}
|
||||
cpu: [x64]
|
||||
@@ -8059,6 +8055,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-openbsd-64/0.14.23:
|
||||
resolution: {integrity: sha512-uYYNqbVR+i7k8ojP/oIROAHO9lATLN7H2QeXKt2H310Fc8FJj4y3Wce6hx0VgnJ4k1JDrgbbiXM8rbEgQyg8KA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-sunos-64/0.13.15:
|
||||
resolution: {integrity: sha512-lbivT9Bx3t1iWWrSnGyBP9ODriEvWDRiweAs69vI+miJoeKwHWOComSRukttbuzjZ8r1q0mQJ8Z7yUsDJ3hKdw==}
|
||||
cpu: [x64]
|
||||
@@ -8067,6 +8072,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-sunos-64/0.14.23:
|
||||
resolution: {integrity: sha512-hAzeBeET0+SbScknPzS2LBY6FVDpgE+CsHSpe6CEoR51PApdn2IB0SyJX7vGelXzlyrnorM4CAsRyb9Qev4h9g==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-32/0.13.15:
|
||||
resolution: {integrity: sha512-fDMEf2g3SsJ599MBr50cY5ve5lP1wyVwTe6aLJsM01KtxyKkB4UT+fc5MXQFn3RLrAIAZOG+tHC+yXObpSn7Nw==}
|
||||
cpu: [ia32]
|
||||
@@ -8075,6 +8089,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-32/0.14.23:
|
||||
resolution: {integrity: sha512-Kttmi3JnohdaREbk6o9e25kieJR379TsEWF0l39PQVHXq3FR6sFKtVPgY8wk055o6IB+rllrzLnbqOw/UV60EA==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-64/0.13.15:
|
||||
resolution: {integrity: sha512-9aMsPRGDWCd3bGjUIKG/ZOJPKsiztlxl/Q3C1XDswO6eNX/Jtwu4M+jb6YDH9hRSUflQWX0XKAfWzgy5Wk54JQ==}
|
||||
cpu: [x64]
|
||||
@@ -8083,6 +8106,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-64/0.14.23:
|
||||
resolution: {integrity: sha512-JtIT0t8ymkpl6YlmOl6zoSWL5cnCgyLaBdf/SiU/Eg3C13r0NbHZWNT/RDEMKK91Y6t79kTs3vyRcNZbfu5a8g==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-arm64/0.13.15:
|
||||
resolution: {integrity: sha512-zzvyCVVpbwQQATaf3IG8mu1IwGEiDxKkYUdA4FpoCHi1KtPa13jeScYDjlW0Qh+ebWzpKfR2ZwvqAQkSWNcKjA==}
|
||||
cpu: [arm64]
|
||||
@@ -8091,6 +8123,15 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild-windows-arm64/0.14.23:
|
||||
resolution: {integrity: sha512-cTFaQqT2+ik9e4hePvYtRZQ3pqOvKDVNarzql0VFIzhc0tru/ZgdLoXd6epLiKT+SzoSce6V9YJ+nn6RCn6SHw==}
|
||||
engines: {node: '>=12'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/esbuild/0.12.29:
|
||||
resolution: {integrity: sha512-w/XuoBCSwepyiZtIRsKsetiLDUVGPVw1E/R3VTFSecIy8UR7Cq3SOtwKHJMFoVqqVG36aGkzh4e8BvpO1Fdc7g==}
|
||||
hasBin: true
|
||||
@@ -8121,6 +8162,33 @@ packages:
|
||||
esbuild-windows-arm64: 0.13.15
|
||||
dev: true
|
||||
|
||||
/esbuild/0.14.23:
|
||||
resolution: {integrity: sha512-XjnIcZ9KB6lfonCa+jRguXyRYcldmkyZ99ieDksqW/C8bnyEX299yA4QH2XcgijCgaddEZePPTgvx/2imsq7Ig==}
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
esbuild-android-arm64: 0.14.23
|
||||
esbuild-darwin-64: 0.14.23
|
||||
esbuild-darwin-arm64: 0.14.23
|
||||
esbuild-freebsd-64: 0.14.23
|
||||
esbuild-freebsd-arm64: 0.14.23
|
||||
esbuild-linux-32: 0.14.23
|
||||
esbuild-linux-64: 0.14.23
|
||||
esbuild-linux-arm: 0.14.23
|
||||
esbuild-linux-arm64: 0.14.23
|
||||
esbuild-linux-mips64le: 0.14.23
|
||||
esbuild-linux-ppc64le: 0.14.23
|
||||
esbuild-linux-riscv64: 0.14.23
|
||||
esbuild-linux-s390x: 0.14.23
|
||||
esbuild-netbsd-64: 0.14.23
|
||||
esbuild-openbsd-64: 0.14.23
|
||||
esbuild-sunos-64: 0.14.23
|
||||
esbuild-windows-32: 0.14.23
|
||||
esbuild-windows-64: 0.14.23
|
||||
esbuild-windows-arm64: 0.14.23
|
||||
dev: true
|
||||
|
||||
/escalade/3.1.1:
|
||||
resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -9168,18 +9236,6 @@ packages:
|
||||
/fast-levenshtein/2.0.6:
|
||||
resolution: {integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=}
|
||||
|
||||
/fast-safe-stringify/2.1.1:
|
||||
resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
|
||||
dev: true
|
||||
|
||||
/fast-shallow-equal/1.0.0:
|
||||
resolution: {integrity: sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==}
|
||||
dev: false
|
||||
|
||||
/fastest-stable-stringify/2.0.2:
|
||||
resolution: {integrity: sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==}
|
||||
dev: false
|
||||
|
||||
/fastq/1.13.0:
|
||||
resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==}
|
||||
dependencies:
|
||||
@@ -9867,15 +9923,6 @@ packages:
|
||||
graphql: 15.7.2
|
||||
dev: true
|
||||
|
||||
/graphql-tag/2.12.6:
|
||||
resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0
|
||||
dependencies:
|
||||
tslib: 2.3.1
|
||||
dev: true
|
||||
|
||||
/graphql-tag/2.12.6_graphql@15.7.2:
|
||||
resolution: {integrity: sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -10368,10 +10415,6 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/hyphenate-style-name/1.0.4:
|
||||
resolution: {integrity: sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==}
|
||||
dev: false
|
||||
|
||||
/iconv-lite/0.4.24:
|
||||
resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -10423,10 +10466,6 @@ packages:
|
||||
resolution: {integrity: sha512-aqXhGP7//Gui2+UrEtvxZxSquQVXTpZ7KDxfCcKAF3Vysvw0CViVaW9RZ1j1xlIYqaaaipBoqdqeibkc18PNvA==}
|
||||
dev: false
|
||||
|
||||
/immer/9.0.12:
|
||||
resolution: {integrity: sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA==}
|
||||
dev: false
|
||||
|
||||
/immutable/3.7.6:
|
||||
resolution: {integrity: sha1-E7TTyxK++hVIKib+Gy665kAHHks=}
|
||||
engines: {node: '>=0.8.0'}
|
||||
@@ -10527,12 +10566,6 @@ packages:
|
||||
resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==}
|
||||
dev: false
|
||||
|
||||
/inline-style-prefixer/6.0.1:
|
||||
resolution: {integrity: sha512-AsqazZ8KcRzJ9YPN1wMH2aNM7lkWQ8tSPrW5uDk1ziYwiAPWSZnUsC7lfZq+BDqLqz0B4Pho5wscWcJzVvRzDQ==}
|
||||
dependencies:
|
||||
css-in-js-utils: 2.0.1
|
||||
dev: false
|
||||
|
||||
/inquirer/8.2.0:
|
||||
resolution: {integrity: sha512-0crLweprevJ02tTuA6ThpoAERAGyVILC4sS74uib58Xf/zSr1/ZWtmm7D5CI+bSQEaA04f0K7idaHpQbSWgiVQ==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
@@ -12129,10 +12162,6 @@ packages:
|
||||
- utf-8-validate
|
||||
dev: true
|
||||
|
||||
/js-cookie/2.2.1:
|
||||
resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==}
|
||||
dev: false
|
||||
|
||||
/js-tokens/4.0.0:
|
||||
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
|
||||
|
||||
@@ -13215,24 +13244,6 @@ packages:
|
||||
/nan/2.15.0:
|
||||
resolution: {integrity: sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==}
|
||||
|
||||
/nano-css/5.3.4_react-dom@17.0.2+react@17.0.2:
|
||||
resolution: {integrity: sha512-wfcviJB6NOxDIDfr7RFn/GlaN7I/Bhe4d39ZRCJ3xvZX60LVe2qZ+rDqM49nm4YT81gAjzS+ZklhKP/Gnfnubg==}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
react-dom: '*'
|
||||
dependencies:
|
||||
css-tree: 1.1.3
|
||||
csstype: 3.0.10
|
||||
fastest-stable-stringify: 2.0.2
|
||||
inline-style-prefixer: 6.0.1
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
rtl-css-js: 1.15.0
|
||||
sourcemap-codec: 1.4.8
|
||||
stacktrace-js: 2.0.2
|
||||
stylis: 4.0.13
|
||||
dev: false
|
||||
|
||||
/nanoid/3.2.0:
|
||||
resolution: {integrity: sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==}
|
||||
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
|
||||
@@ -15456,16 +15467,6 @@ packages:
|
||||
refractor: 3.5.0
|
||||
dev: false
|
||||
|
||||
/react-universal-interface/0.6.2_react@17.0.2+tslib@2.3.1:
|
||||
resolution: {integrity: sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==}
|
||||
peerDependencies:
|
||||
react: '*'
|
||||
tslib: '*'
|
||||
dependencies:
|
||||
react: 17.0.2
|
||||
tslib: 2.3.1
|
||||
dev: false
|
||||
|
||||
/react-use-measure/2.1.1_react-dom@17.0.2+react@17.0.2:
|
||||
resolution: {integrity: sha512-nocZhN26cproIiIduswYpV5y5lQpSQS1y/4KuvUCjSKmw7ZWIS/+g3aFnX3WdBkyuGUtTLif3UTqnLLhbDoQig==}
|
||||
peerDependencies:
|
||||
@@ -15477,30 +15478,6 @@ packages:
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
dev: false
|
||||
|
||||
/react-use/17.3.2_react-dom@17.0.2+react@17.0.2:
|
||||
resolution: {integrity: sha512-bj7OD0/1wL03KyWmzFXAFe425zziuTf7q8olwCYBfOeFHY1qfO1FAMjROQLsLZYwG4Rx63xAfb7XAbBrJsZmEw==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0
|
||||
dependencies:
|
||||
'@types/js-cookie': 2.2.7
|
||||
'@xobotyi/scrollbar-width': 1.9.5
|
||||
copy-to-clipboard: 3.3.1
|
||||
fast-deep-equal: 3.1.3
|
||||
fast-shallow-equal: 1.0.0
|
||||
js-cookie: 2.2.1
|
||||
nano-css: 5.3.4_react-dom@17.0.2+react@17.0.2
|
||||
react: 17.0.2
|
||||
react-dom: 17.0.2_react@17.0.2
|
||||
react-universal-interface: 0.6.2_react@17.0.2+tslib@2.3.1
|
||||
resize-observer-polyfill: 1.5.1
|
||||
screenfull: 5.2.0
|
||||
set-harmonic-interval: 1.0.1
|
||||
throttle-debounce: 3.0.1
|
||||
ts-easing: 0.2.0
|
||||
tslib: 2.3.1
|
||||
dev: false
|
||||
|
||||
/react/17.0.2:
|
||||
resolution: {integrity: sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -15837,10 +15814,6 @@ packages:
|
||||
resolution: {integrity: sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=}
|
||||
dev: false
|
||||
|
||||
/resize-observer-polyfill/1.5.1:
|
||||
resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==}
|
||||
dev: false
|
||||
|
||||
/resolve-cwd/2.0.0:
|
||||
resolution: {integrity: sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=}
|
||||
engines: {node: '>=4'}
|
||||
@@ -16045,12 +16018,6 @@ packages:
|
||||
engines: {node: 6.* || >= 7.*}
|
||||
dev: false
|
||||
|
||||
/rtl-css-js/1.15.0:
|
||||
resolution: {integrity: sha512-99Cu4wNNIhrI10xxUaABHsdDqzalrSRTie4GeCmbGVuehm4oj+fIy8fTzB+16pmKe8Bv9rl+hxIBez6KxExTew==}
|
||||
dependencies:
|
||||
'@babel/runtime': 7.17.0
|
||||
dev: false
|
||||
|
||||
/run-async/2.4.1:
|
||||
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
|
||||
engines: {node: '>=0.12.0'}
|
||||
@@ -16183,11 +16150,6 @@ packages:
|
||||
ajv-keywords: 3.5.2_ajv@6.12.6
|
||||
dev: false
|
||||
|
||||
/screenfull/5.2.0:
|
||||
resolution: {integrity: sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/scuid/1.1.0:
|
||||
resolution: {integrity: sha512-MuCAyrGZcTLfQoH2XoBlQ8C6bzwN88XT/0slOGz0pn8+gIP85BOAfYa44ZXQUTOwRwPU0QvgU+V+OSajl/59Xg==}
|
||||
dev: true
|
||||
@@ -16298,11 +16260,6 @@ packages:
|
||||
/set-blocking/2.0.0:
|
||||
resolution: {integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc=}
|
||||
|
||||
/set-harmonic-interval/1.0.1:
|
||||
resolution: {integrity: sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==}
|
||||
engines: {node: '>=6.9'}
|
||||
dev: false
|
||||
|
||||
/set-value/2.0.1:
|
||||
resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -16546,11 +16503,6 @@ packages:
|
||||
deprecated: See https://github.com/lydell/source-map-url#deprecated
|
||||
dev: false
|
||||
|
||||
/source-map/0.5.6:
|
||||
resolution: {integrity: sha1-dc449SvwczxafwwRjYEzSiu19BI=}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/source-map/0.5.7:
|
||||
resolution: {integrity: sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -16659,12 +16611,6 @@ packages:
|
||||
resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==}
|
||||
dev: false
|
||||
|
||||
/stack-generator/2.0.5:
|
||||
resolution: {integrity: sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q==}
|
||||
dependencies:
|
||||
stackframe: 1.2.0
|
||||
dev: false
|
||||
|
||||
/stack-utils/2.0.5:
|
||||
resolution: {integrity: sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -16675,21 +16621,6 @@ packages:
|
||||
resolution: {integrity: sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==}
|
||||
dev: false
|
||||
|
||||
/stacktrace-gps/3.0.4:
|
||||
resolution: {integrity: sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg==}
|
||||
dependencies:
|
||||
source-map: 0.5.6
|
||||
stackframe: 1.2.0
|
||||
dev: false
|
||||
|
||||
/stacktrace-js/2.0.2:
|
||||
resolution: {integrity: sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==}
|
||||
dependencies:
|
||||
error-stack-parser: 2.0.6
|
||||
stack-generator: 2.0.5
|
||||
stacktrace-gps: 3.0.4
|
||||
dev: false
|
||||
|
||||
/state-toggle/1.0.3:
|
||||
resolution: {integrity: sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==}
|
||||
dev: false
|
||||
@@ -16984,25 +16915,6 @@ packages:
|
||||
postcss-selector-parser: 3.1.2
|
||||
dev: false
|
||||
|
||||
/stylis/4.0.13:
|
||||
resolution: {integrity: sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==}
|
||||
dev: false
|
||||
|
||||
/subscriptions-transport-ws/0.11.0:
|
||||
resolution: {integrity: sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==}
|
||||
peerDependencies:
|
||||
graphql: ^15.7.2 || ^16.0.0
|
||||
dependencies:
|
||||
backo2: 1.0.2
|
||||
eventemitter3: 3.1.2
|
||||
iterall: 1.3.0
|
||||
symbol-observable: 1.2.0
|
||||
ws: 7.5.6
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
dev: true
|
||||
|
||||
/subscriptions-transport-ws/0.11.0_graphql@15.7.2:
|
||||
resolution: {integrity: sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==}
|
||||
peerDependencies:
|
||||
@@ -17325,11 +17237,6 @@ packages:
|
||||
resolution: {integrity: sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==}
|
||||
dev: true
|
||||
|
||||
/throttle-debounce/3.0.1:
|
||||
resolution: {integrity: sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==}
|
||||
engines: {node: '>=10'}
|
||||
dev: false
|
||||
|
||||
/through/2.3.8:
|
||||
resolution: {integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=}
|
||||
dev: true
|
||||
@@ -17428,10 +17335,6 @@ packages:
|
||||
safe-regex: 1.1.0
|
||||
dev: false
|
||||
|
||||
/toggle-selection/1.0.6:
|
||||
resolution: {integrity: sha1-bkWxJj8gF/oKzH2J14sVuL932jI=}
|
||||
dev: false
|
||||
|
||||
/toidentifier/1.0.1:
|
||||
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
|
||||
engines: {node: '>=0.6'}
|
||||
@@ -17481,10 +17384,6 @@ packages:
|
||||
resolution: {integrity: sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==}
|
||||
dev: false
|
||||
|
||||
/ts-easing/0.2.0:
|
||||
resolution: {integrity: sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==}
|
||||
dev: false
|
||||
|
||||
/ts-invariant/0.4.4:
|
||||
resolution: {integrity: sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==}
|
||||
dependencies:
|
||||
@@ -17497,7 +17396,7 @@ packages:
|
||||
dependencies:
|
||||
tslib: 2.3.1
|
||||
|
||||
/ts-jest/27.1.3_7ef2d78ce471893f470776eba2d1fa48:
|
||||
/ts-jest/27.1.3_878bcc2d6ed80d2663ee54e5f78292d8:
|
||||
resolution: {integrity: sha512-6Nlura7s6uM9BVUAoqLH7JHyMXjz8gluryjpPXxr3IxZdAXnU6FhjvVLHFtfd1vsE1p8zD1OJfskkc0jhTSnkA==}
|
||||
engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0}
|
||||
hasBin: true
|
||||
@@ -17521,6 +17420,7 @@ packages:
|
||||
'@babel/core': 7.17.0
|
||||
'@types/jest': 27.4.0
|
||||
bs-logger: 0.2.6
|
||||
esbuild: 0.14.23
|
||||
fast-json-stable-stringify: 2.1.0
|
||||
jest: 27.5.0
|
||||
jest-util: 27.5.0
|
||||
@@ -18105,19 +18005,6 @@ packages:
|
||||
querystring: 0.2.0
|
||||
dev: false
|
||||
|
||||
/use-isomorphic-layout-effect/1.1.1_a0c521d4794c7ad97f5f4c1c4a7d5818:
|
||||
resolution: {integrity: sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: ^16.8.0 || ^17.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 17.0.39
|
||||
react: 17.0.2
|
||||
dev: false
|
||||
|
||||
/use-subscription/1.5.1_react@17.0.2:
|
||||
resolution: {integrity: sha512-Xv2a1P/yReAjAbhylMfFplFKj9GssgTwN7RlcTxBujFQcloStWNDQdc4g4NRWH9xS4i/FDk04vQBptAXoF3VcA==}
|
||||
peerDependencies:
|
||||
@@ -18881,10 +18768,6 @@ packages:
|
||||
cssfilter: 0.0.10
|
||||
dev: false
|
||||
|
||||
/xstate/4.29.0:
|
||||
resolution: {integrity: sha512-F6WF5s6xG/bm8Oxi2ETuzwGQW8yleL5I4JPxZl49m7Uw7D4LAXu+4dvUK78Uo4D863sM8auqw6+1Xmj9mFlmDQ==}
|
||||
dev: false
|
||||
|
||||
/xtend/4.0.2:
|
||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||
engines: {node: '>=0.4'}
|
||||
|
||||
Reference in New Issue
Block a user