Compare commits
10 Commits
@auth/pris
...
@auth/hasu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf68e85885 | ||
|
|
2211693040 | ||
|
|
c21e9b94f5 | ||
|
|
99328272d4 | ||
|
|
ebbf92bf4b | ||
|
|
a0d302fc08 | ||
|
|
145e4428ed | ||
|
|
6e9356dcb1 | ||
|
|
17e45d88e5 | ||
|
|
63c9326664 |
2
.github/FUNDING.yml
vendored
@@ -1,4 +1,4 @@
|
||||
# https://docs.github.com/en/github/administering-a-repository/displaying-a-sponsor-button-in-your-repository
|
||||
|
||||
open_collective: nextauth
|
||||
github: [balazsorban44]
|
||||
github: [balazsorban44, ThangHuuVu]
|
||||
|
||||
1
.github/ISSUE_TEMPLATE/3_bug_adapter.yml
vendored
@@ -29,6 +29,7 @@ body:
|
||||
- "@auth/dynamodb-adapter"
|
||||
- "@auth/fauna-adapter"
|
||||
- "@auth/firebase-adapter"
|
||||
- "@auth/hasura-adapter"
|
||||
- "@auth/kysely-adapter"
|
||||
- "@auth/mikro-orm-adapter"
|
||||
- "@auth/mongodb-adapter"
|
||||
|
||||
1
.github/pr-labeler.yml
vendored
@@ -11,6 +11,7 @@ dynamodb: ["packages/adapter-dynamodb/**/*"]
|
||||
examples: ["apps/examples/**/*"]
|
||||
fauna: ["packages/adapter-fauna/**/*"]
|
||||
firebase: ["packages/adapter-firebase/**/*"]
|
||||
hasura: ["packages/adapter-hasura/**/*"]
|
||||
frameworks: ["packages/frameworks-*/**/*"]
|
||||
legacy: ["packages/next-auth/**/*"]
|
||||
mikro-orm: ["packages/adapter-mikro-orm/**/*"]
|
||||
|
||||
7
.github/workflows/release.yml
vendored
@@ -21,6 +21,7 @@ on:
|
||||
- "@auth/dynamodb-adapter"
|
||||
- "@auth/fauna-adapter"
|
||||
- "@auth/firebase-adapter"
|
||||
- "@auth/hasura-adapter"
|
||||
- "@auth/mikro-orm-adapter"
|
||||
- "@auth/mongodb-adapter"
|
||||
- "@auth/neo4j-adapter"
|
||||
@@ -45,6 +46,7 @@ on:
|
||||
- "adapter-dynamodb"
|
||||
- "adapter-fauna"
|
||||
- "adapter-firebase"
|
||||
- "adapter-hasura"
|
||||
- "adapter-mikro-orm"
|
||||
- "adapter-mongodb"
|
||||
- "adapter-neo4j"
|
||||
@@ -69,7 +71,7 @@ jobs:
|
||||
- name: Init
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 2
|
||||
fetch-depth: 0
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@v2.2.4
|
||||
- name: Setup Node
|
||||
@@ -79,6 +81,9 @@ jobs:
|
||||
cache: "pnpm"
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
- name: Peek
|
||||
run: pnpm peek
|
||||
if: ${{ github.repository == 'nextauthjs/next-auth' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
- name: Build
|
||||
run: pnpm build
|
||||
- name: Run tests
|
||||
|
||||
13
README.md
@@ -73,9 +73,18 @@ If you think you have found a vulnerability (or are not sure) in Auth.js or any
|
||||
<a href="https://vercel.com?utm_source=nextauthjs&utm_campaign=oss"></a>
|
||||
</div>
|
||||
|
||||
### Support
|
||||
### Sponsors
|
||||
|
||||
We have an [OpenCollective](https://opencollective.com/nextauth) for individuals and companies looking to contribute financially to the project!
|
||||
<a href="https://clerk.com?utm_source=sponsorship&utm_medium=github&utm_campaign=authjs&utm_content=callout">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="docs/static/img/clerk-readme-light.png">
|
||||
<source media="(prefers-color-scheme: light)" srcset="docs/static/img/clerk-readme-dark.png">
|
||||
<img alt="Clerk – Authentication & User Management" src="docs/static/img/clerk-readme-dark.png" width="830">
|
||||
</picture>
|
||||
</a>
|
||||
<br><br>
|
||||
|
||||
We have an [OpenCollective](https://opencollective.com/nextauth) for companies and individuals looking to contribute financially to the project!
|
||||
|
||||
<!--sponsors start-->
|
||||
<table>
|
||||
|
||||
@@ -37,6 +37,10 @@ Using an Auth.js / NextAuth.js adapter you can connect to any database service o
|
||||
<img src="/img/adapters/firebase.svg" width="40" />
|
||||
<h4 class="adapter-card__title">Firebase Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/hasura" class="adapter-card">
|
||||
<img src="/img/adapters/hasura.svg" width="40" />
|
||||
<h4 class="adapter-card__title">Hasura Adapter</h4>
|
||||
</a>
|
||||
<a href="/reference/adapter/kysely" class="adapter-card">
|
||||
<img src="/img/adapters/kysely.svg" width="40" />
|
||||
<h4 class="adapter-card__title">Kysely Adapter</h4>
|
||||
|
||||
@@ -284,6 +284,7 @@ const docusaurusConfig = {
|
||||
typedocAdapter("DynamoDB"),
|
||||
typedocAdapter("Fauna"),
|
||||
typedocAdapter("Firebase"),
|
||||
typedocAdapter("Hasura"),
|
||||
typedocAdapter("Kysely"),
|
||||
typedocAdapter("Mikro ORM"),
|
||||
typedocAdapter("MongoDB"),
|
||||
|
||||
@@ -17,14 +17,18 @@
|
||||
"dependencies": {
|
||||
"@mdx-js/react": "1.6.22",
|
||||
"@sapphire/docusaurus-plugin-npm2yarn2pnpm": "1.1.4",
|
||||
"autoprefixer": "^10.4.15",
|
||||
"classnames": "^2.3.2",
|
||||
"framer-motion": "^10.16.4",
|
||||
"mdx-mermaid": "1.2.2",
|
||||
"mermaid": "9.0.1",
|
||||
"postcss": "^8.4.29",
|
||||
"prism-react-renderer": "1.3.5",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-marquee-slider": "^1.1.5",
|
||||
"styled-components": "5.3.6"
|
||||
"styled-components": "5.3.6",
|
||||
"tailwindcss": "^3.3.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@docusaurus/core": "2.4.1",
|
||||
@@ -35,6 +39,7 @@
|
||||
"@docusaurus/theme-mermaid": "2.4.1",
|
||||
"@docusaurus/types": "2.4.1",
|
||||
"docusaurus-plugin-typedoc": "1.0.0-next.13",
|
||||
"postcss-nested": "^6.0.1",
|
||||
"typedoc": "^0.24.8",
|
||||
"typedoc-plugin-markdown": "4.0.0-next.16"
|
||||
},
|
||||
|
||||
7
docs/postcss.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
plugins: [
|
||||
require("tailwindcss"),
|
||||
require("autoprefixer"),
|
||||
require("postcss-nested"),
|
||||
],
|
||||
}
|
||||
@@ -1,18 +1,23 @@
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('@docusaurus/plugin-content-docs').PropSidebarItemHtml} */
|
||||
const clerk = {
|
||||
type: "html",
|
||||
value: `
|
||||
<a href="https://clerk.com?utm_source=sponsorship&utm_medium=github&utm_campaign=authjs&utm_content=callout">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="/img/clerk-sidebar-light.png">
|
||||
<source media="(prefers-color-scheme: light)" srcset="/img/clerk-sidebar-dark.png">
|
||||
<img alt="Clerk – Authentication & User Management" src="/img/clerk-sidebar-dark.png">
|
||||
</picture>
|
||||
</a>`,
|
||||
defaultStyle: true,
|
||||
}
|
||||
|
||||
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
|
||||
module.exports = {
|
||||
gettingStartedSidebar: [
|
||||
{
|
||||
type: "autogenerated",
|
||||
dirName: "getting-started",
|
||||
},
|
||||
],
|
||||
guidesSidebar: [
|
||||
{
|
||||
type: "autogenerated",
|
||||
dirName: "guides",
|
||||
},
|
||||
],
|
||||
gettingStartedSidebar: [{ type: "autogenerated", dirName: "getting-started" }, clerk],
|
||||
guidesSidebar: [{ type: "autogenerated", dirName: "guides" }, clerk],
|
||||
referenceSidebar: [
|
||||
"reference/index",
|
||||
{
|
||||
@@ -33,11 +38,7 @@ module.exports = {
|
||||
link: { type: "doc", id: "reference/solidstart/index" },
|
||||
items: [{ type: "autogenerated", dirName: "reference/solidstart" }],
|
||||
},
|
||||
{
|
||||
type: "link",
|
||||
label: "NextAuth.js (next-auth)",
|
||||
href: "https://next-auth.js.org",
|
||||
},
|
||||
{ type: "link", label: "NextAuth.js (next-auth)", href: "https://next-auth.js.org" },
|
||||
...(process.env.TYPEDOC_SKIP_ADAPTERS
|
||||
? []
|
||||
: [
|
||||
@@ -54,6 +55,7 @@ module.exports = {
|
||||
{ type: "doc", id: "reference/adapter/dynamodb/index" },
|
||||
{ type: "doc", id: "reference/adapter/fauna/index" },
|
||||
{ type: "doc", id: "reference/adapter/firebase/index" },
|
||||
{ type: "doc", id: "reference/adapter/hasura/index" },
|
||||
{ type: "doc", id: "reference/adapter/kysely/index" },
|
||||
{ type: "doc", id: "reference/adapter/mikro-orm/index" },
|
||||
{ type: "doc", id: "reference/adapter/mongodb/index" },
|
||||
@@ -71,11 +73,7 @@ module.exports = {
|
||||
},
|
||||
]),
|
||||
"reference/warnings",
|
||||
clerk,
|
||||
],
|
||||
conceptsSidebar: [
|
||||
{
|
||||
type: "autogenerated",
|
||||
dirName: "concepts",
|
||||
},
|
||||
],
|
||||
conceptsSidebar: [{ type: "autogenerated", dirName: "concepts" }, clerk],
|
||||
}
|
||||
|
||||
553
docs/src/components/clerk.js
Normal file
@@ -0,0 +1,553 @@
|
||||
import { motion, useAnimationControls, useInView } from "framer-motion"
|
||||
import * as React from "react"
|
||||
const { useEffect, useId, useRef, useState } = React
|
||||
|
||||
const width = 76
|
||||
const height = 76
|
||||
const animationDuration = 1
|
||||
|
||||
function easeOut(x) {
|
||||
return x === 1 ? 1 : 1 - Math.pow(2, -10 * x)
|
||||
}
|
||||
|
||||
export function Clerk() {
|
||||
let inViewRef = useRef(null)
|
||||
let isInView = useInView(inViewRef)
|
||||
return (
|
||||
<span className="tailwind">
|
||||
<section
|
||||
ref={inViewRef}
|
||||
className="h-[430px] w-full overflow-hidden py-8 sm:h-[480px] pb-24 mb-24"
|
||||
>
|
||||
<div className="relative mx-auto flex h-full w-full max-w-6xl flex-col">
|
||||
<div className="absolute -top-1 inline-flex w-fit self-center rounded-md ring-black/[0.07] px-6 pt-1 pb-1.5 text-[12px] font-medium tracking-tighter text-[#B2B2B2] shadow-[inset_0px_1px_1px_rgba(0,0,0,0.07),inset_1px_0px_1px_rgba(0,0,0,0.07),inset_-1px_0px_1px_rgba(0,0,0,0.07)] [mask:linear-gradient(180deg,black,black_54%,transparent)] dark:ring-white/[0.07] dark:text-white dark:shadow-[inset_0px_1px_1px_rgba(255,255,255,0.07),inset_1px_0px_1px_rgba(255,255,255,0.07),inset_-1px_0px_1px_rgba(255,255,255,0.07)] ">
|
||||
Sponsored by
|
||||
</div>
|
||||
<div className="flex flex-1 items-center justify-center">
|
||||
<AnimatedLogo />
|
||||
</div>
|
||||
<div className="relative isolate flex flex-1 flex-col items-center justify-between">
|
||||
<div className="absolute -top-5 z-50 h-10 w-full [mask:linear-gradient(90deg,transparent,black_20%,black_80%,transparent)] before:absolute before:inset-0 before:top-5 before:h-[1px] before:bg-gradient-to-r before:from-[#AE48FF] before:via-[#6C47FF] before:via-[25%] before:to-[#18CCFC] before:opacity-50 before:blur-[2px] after:absolute after:inset-0 after:left-1/2 after:top-5 after:h-[1px] after:w-3/4 after:-translate-x-1/2 after:bg-gradient-to-r after:from-[#AE48FF] after:via-[#6C47FF] after:via-[25%] after:to-[#18CCFC] after:[mask:linear-gradient(90deg,transparent,black,black,transparent)]">
|
||||
<motion.div
|
||||
initial={{ x: "-100%" }}
|
||||
animate={isInView ? { x: "100%" } : {}}
|
||||
transition={{
|
||||
delay: 2.5,
|
||||
duration: isInView ? 1 : 0,
|
||||
ease: "easeInOut",
|
||||
repeat: Infinity,
|
||||
repeatDelay: 3,
|
||||
}}
|
||||
className="absolute inset-x-0 top-5 z-10 h-[1px] bg-gradient-to-l from-white/75 to-transparent to-50% dark:from-white/25"
|
||||
/>
|
||||
</div>
|
||||
<div className="absolute inset-0 isolate -z-10 overflow-hidden before:absolute before:inset-0 before:bg-[url(/img/background-pattern.svg)] before:[mask:radial-gradient(ellipse_farthest-side_at_50%_-25vw,black,transparent)] dark:before:opacity-10">
|
||||
<div className="absolute left-1/2 top-0 h-12 w-1/2 -translate-x-1/2 -translate-y-3/4 rounded-[50%] bg-gradient-to-r from-[#AE48FF] via-[#6C47FF] via-[25%] to-[#18CCFC] opacity-20 blur-xl" />
|
||||
</div>
|
||||
|
||||
<h2>
|
||||
<span className="sr-only">Clerk complete user management</span>
|
||||
</h2>
|
||||
|
||||
<p className="text-center text-base leading-tight dark:text-white tracking-tight">
|
||||
More than authentication...
|
||||
<br />
|
||||
<span className="text-2xl font-bold text-[#6C47FF] sm:text-[28px]">
|
||||
Complete user management.
|
||||
</span>
|
||||
</p>
|
||||
|
||||
<div className="relative isolate">
|
||||
<a
|
||||
href="https://clerk.com?utm_source=sponsorship&utm_medium=website&utm_campaign=authjs&utm_content=09_01_2023"
|
||||
className="relative isolate inline-flex h-8 items-center gap-1.5 rounded-[8px] px-4 text-[13px] font-semibold text-white before:absolute before:inset-0 before:-z-10 before:rounded-[inherit] before:shadow-lg before:shadow-[rgb(100_48_247/0.3)] after:absolute after:inset-0 after:rounded-[inherit] after:bg-[#6C47FF] after:shadow-[inset_0px_-8px_16px_-4px_#6430F7,inset_0px_0px_1px_1px_theme(colors.white/4%),inset_0px_1px_0px_theme(colors.white/10%),0px_0px_0px_1px_#6C47FF] dark:before:shadow-black"
|
||||
>
|
||||
<span className="z-20 flex items-center gap-1.5 bg-gradient-to-b from-white from-50% to-[#D7D4FF] bg-clip-text text-transparent drop-shadow-[0px_1px_1px_rgb(86_30_227/60%)]">
|
||||
<span>Get started for free</span>
|
||||
<ArrowIcon />
|
||||
</span>
|
||||
</a>
|
||||
|
||||
{[0, 1, 2, 3].map((i) => (
|
||||
<Ring key={i} i={i} isInView={isInView} />
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="absolute left-1/2 top-0 -z-10 h-[140px] w-3/4 -translate-x-1/2 -translate-y-1/3 rotate-12 transform-gpu rounded-[50%] bg-gradient-to-r from-[#6C47FF] via-[#4818BF] via-25% to-sky-500 opacity-10 blur-3xl" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</span>
|
||||
)
|
||||
}
|
||||
|
||||
function Ring({ i, isInView }) {
|
||||
const transition = {
|
||||
delay: i * 1,
|
||||
duration: 4,
|
||||
ease: "linear",
|
||||
repeat: Infinity,
|
||||
times: [0, 0.1, 1],
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
className="pointer-events-none absolute left-1/2 top-1/2 -z-10 h-[275%] w-[135%] rounded-[22px] border border-[#6C47FF]/[.15] dark:border-[#6C47FF]/25"
|
||||
style={{ x: "-50%", y: "-50%" }}
|
||||
initial={{ opacity: 0, scaleX: 0.75, scaleY: 0.4 }}
|
||||
animate={isInView ? { opacity: [0, 1, 0], scaleX: 1, scaleY: 1 } : {}}
|
||||
transition={isInView ? transition : {}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function ArrowIcon() {
|
||||
const id = useId()
|
||||
|
||||
return (
|
||||
<svg
|
||||
width="10"
|
||||
height="8"
|
||||
viewBox="0 0 10 8"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M9.25 4.00144L5.78125 0.78125M9.25 4.00144L5.78125 7.21875M9.25 4.00144H0.765625"
|
||||
stroke={`url(#${id})`}
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id={id}
|
||||
x1="4.50"
|
||||
y1="0.50"
|
||||
x2="4.50"
|
||||
y2="7.50"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0.50" stopColor="white" />
|
||||
<stop offset="1" stopColor="#D7D4FF" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function AnimatedLogo() {
|
||||
let inViewRef = useRef(null)
|
||||
let isInView = useInView(inViewRef, {
|
||||
amount: "all",
|
||||
margin: "0px 0px -200px 0px",
|
||||
once: true,
|
||||
})
|
||||
|
||||
let [isAnimationFinished] = useState(false)
|
||||
|
||||
let wrapperContainer = useAnimationControls()
|
||||
let iconContainer = useAnimationControls()
|
||||
|
||||
let iconShapeMono = useAnimationControls()
|
||||
let iconPathMono = useAnimationControls()
|
||||
let startCapMono = useAnimationControls()
|
||||
let endCapMono = useAnimationControls()
|
||||
|
||||
let iconPathSpectrumContainer = useAnimationControls()
|
||||
let iconPathSpectrum = useAnimationControls()
|
||||
let startCapSpectrum = useAnimationControls()
|
||||
let endCapSpectrum = useAnimationControls()
|
||||
|
||||
let iconDot = useAnimationControls()
|
||||
|
||||
let logoType = useAnimationControls()
|
||||
|
||||
useEffect(() => {
|
||||
async function startAnimationSequence() {
|
||||
await Promise.all([
|
||||
iconContainer.start({
|
||||
rotate: -135,
|
||||
transition: { duration: animationDuration, ease: easeOut },
|
||||
}),
|
||||
startCapMono.start({ opacity: 1, transition: { duration: 0.1 } }),
|
||||
endCapMono.start({
|
||||
opacity: 1,
|
||||
rotate: 0,
|
||||
transition: {
|
||||
duration: animationDuration,
|
||||
ease: easeOut,
|
||||
opacity: { duration: 0.1 },
|
||||
},
|
||||
}),
|
||||
iconPathMono.start({
|
||||
opacity: 1,
|
||||
pathLength: 1,
|
||||
transition: {
|
||||
duration: animationDuration,
|
||||
ease: easeOut,
|
||||
opacity: { duration: 0.1 },
|
||||
},
|
||||
}),
|
||||
])
|
||||
|
||||
await Promise.all([
|
||||
iconShapeMono.start({ opacity: 1, transition: { duration: 0 } }),
|
||||
startCapMono.start({ opacity: 0, transition: { duration: 0 } }),
|
||||
])
|
||||
|
||||
await Promise.all([
|
||||
iconContainer.start({
|
||||
rotate: 0,
|
||||
transition: { duration: animationDuration, ease: easeOut },
|
||||
x: 0,
|
||||
}),
|
||||
endCapMono.start({
|
||||
opacity: 1,
|
||||
rotate: -180,
|
||||
transition: {
|
||||
duration: animationDuration,
|
||||
ease: easeOut,
|
||||
opacity: { duration: 0.1 },
|
||||
},
|
||||
}),
|
||||
iconPathMono.start({
|
||||
opacity: 1,
|
||||
pathLength: 0,
|
||||
transition: {
|
||||
duration: animationDuration,
|
||||
ease: easeOut,
|
||||
opacity: { duration: 0.1 },
|
||||
},
|
||||
}),
|
||||
iconPathSpectrumContainer.start({
|
||||
rotate: 0,
|
||||
transition: { duration: animationDuration, ease: easeOut },
|
||||
}),
|
||||
iconPathSpectrum.start({
|
||||
opacity: 1,
|
||||
pathLength: 1,
|
||||
transition: {
|
||||
duration: animationDuration,
|
||||
ease: easeOut,
|
||||
opacity: { duration: 0.1 },
|
||||
},
|
||||
}),
|
||||
endCapSpectrum.start({
|
||||
opacity: 1,
|
||||
transition: { duration: 0.1 },
|
||||
}),
|
||||
startCapSpectrum.start({
|
||||
opacity: 1,
|
||||
rotate: 0,
|
||||
transition: {
|
||||
duration: animationDuration,
|
||||
ease: easeOut,
|
||||
opacity: { duration: 0.1 },
|
||||
},
|
||||
}),
|
||||
iconDot.start({
|
||||
opacity: 1,
|
||||
scale: 1,
|
||||
transition: {
|
||||
duration: animationDuration,
|
||||
ease: easeOut,
|
||||
opacity: { duration: 0.2 },
|
||||
},
|
||||
}),
|
||||
logoType.start({
|
||||
WebkitMaskPosition: "100% 0%",
|
||||
opacity: 1,
|
||||
transition: {
|
||||
WebkitMaskPosition: {
|
||||
duration: animationDuration * 3,
|
||||
ease: easeOut,
|
||||
},
|
||||
duration: animationDuration,
|
||||
ease: easeOut,
|
||||
},
|
||||
x: 0,
|
||||
}),
|
||||
])
|
||||
|
||||
// setIsAnimationFinished(true)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (isInView) {
|
||||
startAnimationSequence()
|
||||
}
|
||||
}, [
|
||||
iconContainer,
|
||||
endCapMono,
|
||||
iconDot,
|
||||
iconPathMono,
|
||||
iconShapeMono,
|
||||
logoType,
|
||||
startCapMono,
|
||||
wrapperContainer,
|
||||
iconPathSpectrumContainer,
|
||||
iconPathSpectrum,
|
||||
endCapSpectrum,
|
||||
startCapSpectrum,
|
||||
isInView,
|
||||
])
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
ref={inViewRef}
|
||||
animate={wrapperContainer}
|
||||
className="relative isolate flex scale-75 items-center gap-2 sm:scale-100"
|
||||
>
|
||||
{!isAnimationFinished && (
|
||||
<motion.div
|
||||
style={{ x: "138%" }}
|
||||
animate={iconContainer}
|
||||
className="relative"
|
||||
>
|
||||
<motion.svg
|
||||
initial={{ opacity: 0 }}
|
||||
animate={iconShapeMono}
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M25.0101 27.8385C25.4355 28.2639 25.3928 28.9682 24.8929 29.303C22.3497 31.0065 19.2909 32 16 32C12.7091 32 9.65026 31.0065 7.10707 29.303C6.60723 28.9682 6.56452 28.2639 6.98992 27.8385L10.6439 24.1845C10.9741 23.8543 11.4864 23.8021 11.9021 24.0151C13.1312 24.6447 14.5241 25 16 25C17.4759 25 18.8688 24.6447 20.0979 24.0151C20.5136 23.8021 21.0259 23.8543 21.3561 24.1845L25.0101 27.8385Z"
|
||||
className="fill-[#1C0452] dark:fill-white"
|
||||
/>
|
||||
<path
|
||||
d="M24.8929 2.697C25.3928 3.0318 25.4355 3.73609 25.0101 4.16149L21.3561 7.81545C21.0259 8.14569 20.5135 8.19786 20.0979 7.98491C18.8688 7.35525 17.4759 7 16 7C11.0294 7 7 11.0294 7 16C7 17.4759 7.35525 18.8688 7.98491 20.0979C8.19786 20.5135 8.14569 21.0259 7.81545 21.3561L4.16149 25.0101C3.73609 25.4355 3.0318 25.3928 2.697 24.8929C0.993528 22.3497 0 19.2909 0 16C0 7.16344 7.16344 0 16 0C19.2909 0 22.3497 0.993528 24.8929 2.697Z"
|
||||
className="fill-[#1C0452] dark:fill-white"
|
||||
/>
|
||||
</motion.svg>
|
||||
|
||||
<svg
|
||||
className="absolute inset-0"
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 32 32"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<motion.path
|
||||
className="stroke-[#1C0452] dark:stroke-white"
|
||||
initial={{ opacity: 0, pathLength: 0 }}
|
||||
animate={iconPathMono}
|
||||
d="M4.7719 21.5C3.95737 19.8403 3.5 17.9736 3.5 16C3.5 9.09644 9.09644 3.5 16 3.5C17.5864 3.5 19.1037 3.79551 20.5 4.33449C25.1801 6.14103 28.5 10.6828 28.5 16C28.5 22.9036 22.9036 28.5 16 28.5C14.0264 28.5 11.875 27.9297 10.25 27.1016"
|
||||
strokeWidth="7"
|
||||
fill="none"
|
||||
/>
|
||||
<motion.path
|
||||
className="fill-[#1C0452] dark:fill-white"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={startCapMono}
|
||||
d="M7.8413 19.8045L1.49564 22.7635C1.84251 23.5061 2.24473 24.2177 2.697 24.8929C3.0318 25.3927 3.73609 25.4355 4.16149 25.0101L7.81545 21.3561C8.14569 21.0259 8.19786 20.5135 7.98492 20.0979C7.93533 20.0011 7.88745 19.9033 7.8413 19.8045Z"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{/* End cap */}
|
||||
<motion.svg
|
||||
initial={{ opacity: 0, rotate: -322 }}
|
||||
animate={endCapMono}
|
||||
className="absolute inset-0 fill-[#1C0452] dark:fill-white"
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 32 32"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M7.10709 29.303C6.60725 28.9682 6.56454 28.2639 6.98994 27.8385L10.6439 24.1846C10.9741 23.8543 11.4865 23.8021 11.9021 24.0151C11.9989 24.0647 12.0967 24.1126 12.1955 24.1587L9.23649 30.5044C8.49388 30.1575 7.78231 29.7553 7.10709 29.303Z" />
|
||||
</motion.svg>
|
||||
|
||||
<svg
|
||||
className="absolute inset-0 fill-[#1C0452] dark:fill-white"
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 32 32"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<motion.circle
|
||||
initial={{ opacity: 0, scale: 0.75 }}
|
||||
animate={iconDot}
|
||||
cx="16"
|
||||
cy="16"
|
||||
r="5"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<motion.svg
|
||||
initial={{ rotate: 180 }}
|
||||
animate={iconPathSpectrumContainer}
|
||||
className="absolute inset-0"
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<motion.path
|
||||
initial={{ opacity: 0, pathLength: 0 }}
|
||||
animate={iconPathSpectrum}
|
||||
d="M21.6661,4.85498C21.2881,4.66241 20.899,4.48851 20.5,4.33449C19.1037,3.79551 17.5864,3.5 16,3.5C9.09644,3.5 3.5,9.09644 3.5,16C3.5,17.9736 3.95737,19.8403 4.7719,21.5"
|
||||
stroke="url(#paint0_linear_45_194)"
|
||||
strokeWidth="7"
|
||||
/>
|
||||
|
||||
<motion.path
|
||||
initial={{ opacity: 0, pathLength: 0 }}
|
||||
animate={endCapSpectrum}
|
||||
d="M25.0101 4.16148C25.4355 3.73608 25.3927 3.03179 24.8929 2.69699C24.8134 2.64375 24.7335 2.59121 24.653 2.53938C24.0497 2.15079 23.4187 1.80165 22.7635 1.49561L19.8045 7.84128L19.8069 7.84239C19.9048 7.88819 20.0019 7.93571 20.0979 7.9849C20.5135 8.19784 21.0259 8.14568 21.3561 7.81543L25.0101 4.16148Z"
|
||||
fill="url(#paint0_linear_45_213)"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_45_194"
|
||||
x1="24.5"
|
||||
y1="3.5"
|
||||
x2="3.5"
|
||||
y2="24.5"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#56C2FF" />
|
||||
<stop offset="0.66" stopColor="#6C47FF" />
|
||||
<stop offset="1" stopColor="#9C49FE" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint0_linear_45_213"
|
||||
x1="3.5"
|
||||
y1="25"
|
||||
x2="25.4653"
|
||||
y2="3.98633"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#9B48FD" />
|
||||
<stop offset="0.389423" stopColor="#6C47FF" />
|
||||
<stop offset="1" stopColor="#55C1FF" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</motion.svg>
|
||||
|
||||
<motion.svg
|
||||
initial={{ opacity: 0, rotate: 322 }}
|
||||
animate={startCapSpectrum}
|
||||
className="absolute inset-0"
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M1.55694 22.8933C1.88964 23.5891 2.27113 24.2571 2.697 24.8929C2.7783 25.0143 2.8814 25.1087 2.99701 25.176C3.29792 25.3512 3.68357 25.3427 3.99016 25.1477C4.05078 25.1091 4.10831 25.0632 4.16149 25.0101L7.81544 21.3561C7.85673 21.3148 7.89366 21.2707 7.92628 21.2243C8.15459 20.8993 8.17124 20.4616 7.98491 20.0979C7.97999 20.0883 7.97509 20.0787 7.9702 20.069C7.92584 19.9817 7.88287 19.8935 7.8413 19.8045L1.49563 22.7635C1.51588 22.8069 1.53632 22.8501 1.55694 22.8933Z"
|
||||
fill="url(#paint0_linear_45_202)"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_45_202"
|
||||
x1="3.5"
|
||||
y1="25"
|
||||
x2="25.4653"
|
||||
y2="3.98633"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#9B48FD" />
|
||||
<stop offset="0.33" stopColor="#6C47FF" />
|
||||
<stop offset="1" stopColor="#55C1FF" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</motion.svg>
|
||||
</motion.div>
|
||||
)}
|
||||
|
||||
{isAnimationFinished && (
|
||||
<svg
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 32 32"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M25.0101 27.8385C25.4355 28.2639 25.3928 28.9682 24.8929 29.303C22.3497 31.0064 19.2909 32 16 32C12.7091 32 9.65028 31.0064 7.10708 29.303C6.60725 28.9682 6.56453 28.2639 6.98993 27.8385L10.6439 24.1845C10.9741 23.8543 11.4864 23.8021 11.9021 24.0151C13.1312 24.6447 14.5241 25 16 25C17.4759 25 18.8688 24.6447 20.0979 24.0151C20.5136 23.8021 21.0259 23.8543 21.3561 24.1845L25.0101 27.8385Z"
|
||||
className="fill-[#1C0452] dark:fill-white"
|
||||
/>
|
||||
<circle
|
||||
className="fill-[#1C0452] dark:fill-white"
|
||||
cx="16"
|
||||
cy="16"
|
||||
r="5"
|
||||
/>
|
||||
<path
|
||||
d="M4.7719 21.5C3.95737 19.8403 3.5 17.9736 3.5 16C3.5 9.09644 9.09644 3.5 16 3.5C17.5864 3.5 19.1037 3.79551 20.5 4.33449C20.899 4.48851 21.2881 4.66241 21.6661 4.85498"
|
||||
stroke="url(#paint0_linear_52_261)"
|
||||
strokeWidth="7"
|
||||
/>
|
||||
<path
|
||||
d="M1.55691 22.8933C1.88961 23.5891 2.2711 24.2571 2.69697 24.8929C2.77828 25.0143 2.88138 25.1087 2.99698 25.176C3.29789 25.3512 3.68354 25.3427 3.99013 25.1477C4.05075 25.1091 4.10828 25.0632 4.16146 25.0101L7.81542 21.3561C7.8567 21.3148 7.89363 21.2707 7.92625 21.2243C8.15456 20.8993 8.17121 20.4616 7.98488 20.0979C7.97996 20.0883 7.97506 20.0787 7.97017 20.069C7.92581 19.9817 7.88284 19.8935 7.84127 19.8045L1.49561 22.7635C1.51585 22.8069 1.53629 22.8501 1.55691 22.8933Z"
|
||||
fill="url(#paint1_linear_52_261)"
|
||||
/>
|
||||
<path
|
||||
d="M25.0101 4.16148C25.4355 3.73608 25.3928 3.03179 24.8929 2.69699C24.8135 2.64375 24.7335 2.59121 24.653 2.53938C24.0498 2.15079 23.4187 1.80165 22.7635 1.49561L19.8045 7.84128L19.8069 7.84239C19.9049 7.88819 20.0019 7.93571 20.0979 7.9849C20.5136 8.19784 21.0259 8.14568 21.3561 7.81543L25.0101 4.16148Z"
|
||||
fill="url(#paint2_linear_52_261)"
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="paint0_linear_52_261"
|
||||
x1="24.5"
|
||||
y1="3.5"
|
||||
x2="3.5"
|
||||
y2="24.5"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#56C2FF" />
|
||||
<stop offset="0.66" stopColor="#6C47FF" />
|
||||
<stop offset="1" stopColor="#9C49FE" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint1_linear_52_261"
|
||||
x1="3.49997"
|
||||
y1="25"
|
||||
x2="25.4652"
|
||||
y2="3.98633"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#9B48FD" />
|
||||
<stop offset="0.389423" stopColor="#6C47FF" />
|
||||
<stop offset="1" stopColor="#55C1FF" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint2_linear_52_261"
|
||||
x1="3.50003"
|
||||
y1="25"
|
||||
x2="25.4653"
|
||||
y2="3.98633"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stopColor="#9B48FD" />
|
||||
<stop offset="0.389423" stopColor="#6C47FF" />
|
||||
<stop offset="1" stopColor="#55C1FF" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
)}
|
||||
|
||||
<motion.svg
|
||||
className="fill-[#1C0452] [mask-image:linear-gradient(90deg,transparent_30%,black_60%)] [mask-size:300%_100%] dark:fill-white"
|
||||
initial={{ WebkitMaskPosition: "0% 0%", opacity: 0, x: "-20%" }}
|
||||
animate={logoType}
|
||||
width={67 * 3}
|
||||
height={22 * 3}
|
||||
viewBox="0 0 67 22"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M17.1071 0H20.7394V21.7459H17.1071V0ZM12.407 17.1147C11.887 17.6425 11.2626 18.061 10.5719 18.3447C9.88121 18.6285 9.13867 18.7713 8.3897 18.7646C7.75719 18.7834 7.12745 18.6751 6.53933 18.4465C5.9512 18.2179 5.41705 17.8738 4.96982 17.4354C4.15743 16.6055 3.68984 15.4206 3.68984 14.0081C3.68984 11.1806 5.56976 9.24662 8.3897 9.24662C9.14602 9.2362 9.89539 9.38947 10.5842 9.69537C11.2731 10.0014 11.8844 10.4525 12.3746 11.0165L14.8145 8.90395C13.2245 7.01405 10.6446 6.03728 8.19471 6.03728C3.39992 6.03728 0 9.27362 0 14.035C0 16.39 0.844958 18.373 2.2699 19.7732C3.69483 21.1735 5.72483 21.996 8.06721 21.996C11.1096 21.996 13.537 20.7867 14.8995 19.2665L12.407 17.1147ZM38.3352 13.8163C38.3285 14.2935 38.2951 14.77 38.2352 15.2436H26.7081C27.188 17.4296 28.8731 18.7638 31.208 18.7638C31.964 18.7796 32.7135 18.6246 33.3986 18.3109C34.0836 17.9971 34.6856 17.5331 35.1578 16.9547L35.2753 17.0526L37.6553 19.1163C36.3228 20.7761 34.1003 22 31.013 22C26.4131 22 22.9433 18.8274 22.9433 14.0073C22.9433 11.6425 23.7607 9.65951 25.1231 8.25928C25.8423 7.53925 26.7044 6.971 27.6563 6.58957C28.6081 6.20813 29.6297 6.02156 30.6579 6.04136C35.3202 6.04136 38.3352 9.30707 38.3352 13.8163ZM27.7356 10.5262C27.2625 11.0604 26.9303 11.7 26.7681 12.389H34.6678C34.2203 10.5164 32.9203 9.24586 30.8454 9.24586C30.2635 9.22748 29.6844 9.3324 29.1476 9.5533C28.611 9.77433 28.1292 10.1062 27.7356 10.5262ZM49.5641 5.99467V9.96047C49.1441 9.92871 48.7217 9.89682 48.4642 9.89682C45.7142 9.89682 44.1543 11.8308 44.1543 14.3694V21.7454H40.527V6.21501H44.1543V8.56754H44.1869C45.4193 6.91759 47.1867 5.99958 49.1117 5.99958L49.5641 5.99467ZM55.3999 18.0984L58.0223 15.2414H58.0898L62.2047 21.7459H66.287L60.4872 12.5143L66.187 6.26454H61.8772L55.3999 13.3393V0H51.77V21.7459H55.3999V18.0984Z"
|
||||
/>
|
||||
</motion.svg>
|
||||
</motion.div>
|
||||
)
|
||||
}
|
||||
@@ -1,3 +1,9 @@
|
||||
.tailwind {
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
}
|
||||
|
||||
/* stylelint-disable docusaurus/copyright-header */
|
||||
/**
|
||||
* Any CSS included here will be global. The classic template
|
||||
@@ -104,7 +110,7 @@ html[data-theme="dark"] hr {
|
||||
|
||||
/* Docusaurus announcementBar close button */
|
||||
.close {
|
||||
color: inherit!important;
|
||||
color: inherit !important;
|
||||
}
|
||||
|
||||
.home-main .code {
|
||||
|
||||
@@ -9,6 +9,7 @@ import { useEffect } from "react"
|
||||
import ProviderMarquee from "../components/ProviderMarquee"
|
||||
import styles from "./index.module.css"
|
||||
import providers from "../../providers.json"
|
||||
import { Clerk } from "../components/clerk"
|
||||
|
||||
const providersCount = Object.keys(providers).length + 2 // email, credentials
|
||||
const features = [
|
||||
@@ -127,6 +128,7 @@ export default function Home() {
|
||||
<h1 className="hero__title">{siteConfig.title}</h1>
|
||||
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
||||
</div>
|
||||
|
||||
<div className={styles.buttons}>
|
||||
<a
|
||||
className={classnames(
|
||||
@@ -185,6 +187,7 @@ export default function Home() {
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<Clerk />
|
||||
<div className="row">
|
||||
{features.map((props, idx) => (
|
||||
<Feature key={idx} {...props} />
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
.heroBanner {
|
||||
padding: 4rem 0 0 0;
|
||||
min-height: 60vh;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
1
docs/static/img/adapters/hasura.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Hasura</title><path d="M2.1216.0014c-.1221-.01-.2481.0345-.3354.1382C.448 1.7248.0338 6.021.7236 8.1721c.228.714.293 1.4694.1567 2.2072-.1332.7289-.2692 1.6118-.2692 2.2221C.6111 18.8946 5.712 24 12.0001 24c6.2909 0 11.3889-5.1024 11.3889-11.3986 0-.6133-.1334-1.4932-.2696-2.2221-.1362-.7378-.071-1.4931.157-2.2072.6899-2.151.2753-6.4473-1.0628-8.0325-.1746-.2074-.5033-.1777-.6483.0504l-1.6491 2.5895a1.2678 1.2678 0 0 1-1.6934.2757C16.4348 1.885 14.2973 1.2034 12 1.2034c-2.2973 0-4.435.6815-6.223 1.8518-.5507.3615-1.2849.2399-1.6934-.2757L2.4345.19a.4092.4092 0 0 0-.3129-.1886zM12 3.8046c1.347 0 2.626.3053 3.7716.8505 2.848 1.351 4.8582 4.1864 5.0358 7.499.009.157.0117.3143.0117.4743-.0029 4.865-3.958 8.8234-8.819 8.8234-4.8612 0-8.8165-3.9584-8.8165-8.8234 0-.16.006-.3173.012-.4743.1776-3.3155 2.1878-6.1509 5.0358-7.502C9.374 4.107 10.653 3.8047 12 3.8047zM9.5664 8.732a.2539.2539 0 0 0-.2192.1274c-.0444.08-.0444.1775.003.2546l1.8474 3.1112-2.4811 3.7866a.257.257 0 0 0-.0117.2607.252.252 0 0 0 .222.1333h1.8592a.2575.2575 0 0 0 .2133-.1157l1.3409-2.0976 1.202 2.0859a.2511.2511 0 0 0 .2191.1274h1.8325a.2471.2471 0 0 0 .2188-.1274c.0534-.08.0536-.175.0062-.2549l-2.2529-3.9081-1.9332-3.259a.2512.2512 0 0 0-.2192-.1244Z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
100
docs/static/img/background-pattern.svg
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<svg
|
||||
width="48"
|
||||
height="36"
|
||||
viewBox="0 0 56 42"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
stroke="#E7E8F1"
|
||||
stroke-width="1"
|
||||
>
|
||||
<path
|
||||
d="M45.8935 7.4645L41.483 11.8749C41.3445 12.0134 41.1633 12.1013 40.9689 12.1245C40.7743 12.1478 40.5777 12.105 40.4103 12.0032C38.6755 10.9566 36.6746 10.4346 34.6494 10.5003C32.6242 10.566 30.6615 11.2165 28.998 12.3734C27.975 13.0855 27.0866 13.9738 26.3745 14.9969C25.219 16.6614 24.5691 18.6242 24.5029 20.6494C24.4367 22.6746 24.957 24.6758 26.0014 26.4122C26.1025 26.5792 26.1448 26.7752 26.1216 26.9692C26.0983 27.163 26.0109 27.3435 25.8731 27.482L21.4627 31.8923C21.3739 31.9817 21.2668 32.0509 21.1488 32.095C21.0308 32.1393 20.9046 32.1573 20.7789 32.1483C20.6532 32.1391 20.531 32.103 20.4206 32.0422C20.3102 31.9814 20.2142 31.8975 20.1393 31.7961C17.753 28.5161 16.5197 24.5383 16.632 20.4836C16.7444 16.4289 18.1959 12.5255 20.7602 9.38257C21.543 8.42097 22.4221 7.54189 23.3837 6.75906C26.5264 4.19551 30.4292 2.74437 34.4833 2.63205C38.5373 2.51973 42.5145 3.75255 45.7943 6.13816C45.8964 6.21286 45.9809 6.3088 46.0422 6.41934C46.1036 6.52989 46.1402 6.65241 46.1497 6.77848C46.1592 6.90455 46.1411 7.03117 46.0969 7.1496C46.0526 7.26803 45.9832 7.37547 45.8935 7.4645Z"
|
||||
/>
|
||||
<path
|
||||
d="M45.8897 34.5161L41.4792 30.1057C41.3407 29.9672 41.1595 29.8794 40.9651 29.8561C40.7706 29.8328 40.5739 29.8755 40.4065 29.9773C38.7707 30.9641 36.8965 31.4858 34.9861 31.4858C33.0756 31.4858 31.2014 30.9641 29.5656 29.9773C29.3983 29.8755 29.2016 29.8328 29.007 29.8561C28.8125 29.8794 28.6315 29.9672 28.4929 30.1057L24.0824 34.5161C23.9899 34.6049 23.9182 34.7132 23.8722 34.8329C23.8261 34.9527 23.8071 35.0811 23.8163 35.2091C23.8254 35.3371 23.8626 35.4614 23.9253 35.5734C23.9879 35.6854 24.0744 35.7822 24.1786 35.8569C27.3181 38.1412 31.1007 39.3716 34.9832 39.3716C38.8656 39.3716 42.6482 38.1412 45.7877 35.8569C45.8923 35.7827 45.9793 35.6862 46.0425 35.5744C46.1056 35.4627 46.1434 35.3385 46.1532 35.2105C46.1629 35.0825 46.1443 34.9539 46.0989 34.834C46.0532 34.714 45.9819 34.6054 45.8897 34.5161Z"
|
||||
/>
|
||||
<path
|
||||
d="M34.997 26.244C37.8964 26.244 40.247 23.8935 40.247 20.994C40.247 18.0946 37.8964 15.744 34.997 15.744C32.0975 15.744 29.747 18.0946 29.747 20.994C29.747 23.8935 32.0975 26.244 34.997 26.244Z"
|
||||
/>
|
||||
<path
|
||||
d="M-10.8935 -13.5355L-6.48304 -9.12508C-6.34447 -8.98664 -6.16334 -8.89874 -5.96889 -8.87548C-5.77429 -8.85223 -5.5777 -8.89496 -5.41035 -8.99681C-3.67546 -10.0434 -1.67461 -10.5654 0.350573 -10.4997C2.37576 -10.434 4.33849 -9.78347 6.00196 -8.6266C7.02502 -7.91449 7.91335 -7.02616 8.62548 -6.00309C9.78097 -4.33862 10.4309 -2.37576 10.4971 -0.350574C10.5633 1.67461 10.0429 3.67576 8.99861 5.41218C8.89748 5.57923 8.85516 5.77521 8.87841 5.9692C8.90165 6.16304 8.98912 6.34355 9.12687 6.48196L13.5373 10.8923C13.6261 10.9817 13.7332 11.0509 13.8512 11.095C13.9692 11.1393 14.0954 11.1573 14.2211 11.1483C14.3468 11.1391 14.469 11.103 14.5794 11.0422C14.6898 10.9814 14.7858 10.8975 14.8607 10.7961C17.247 7.51607 18.4803 3.53827 18.368 -0.516392C18.2556 -4.57108 16.8041 -8.47452 14.2398 -11.6174C13.457 -12.579 12.5779 -13.4581 11.6163 -14.2409C8.47363 -16.8045 4.57076 -18.2556 0.516696 -18.368C-3.53735 -18.4803 -7.51454 -17.2474 -10.7943 -14.8618C-10.8964 -14.7871 -10.981 -14.6912 -11.0422 -14.5807C-11.1036 -14.4701 -11.1402 -14.3476 -11.1497 -14.2215C-11.1592 -14.0955 -11.1411 -13.9688 -11.0969 -13.8504C-11.0526 -13.732 -10.9832 -13.6245 -10.8935 -13.5355Z"
|
||||
/>
|
||||
<path
|
||||
d="M-10.8897 13.5161L-6.47923 9.10565C-6.34066 8.96724 -6.15953 8.87936 -5.96508 8.85608C-5.77063 8.83281 -5.57388 8.87553 -5.40654 8.97735C-3.77071 9.96414 -1.89649 10.4858 0.0138683 10.4858C1.92438 10.4858 3.79857 9.96414 5.43441 8.97735C5.60174 8.87553 5.79843 8.83281 5.99295 8.85608C6.18747 8.87936 6.36853 8.96724 6.50713 9.10565L10.9176 13.5161C11.01 13.6049 11.0818 13.7132 11.1278 13.8329C11.1738 13.9527 11.1929 14.0811 11.1837 14.2091C11.1746 14.3371 11.1373 14.4614 11.0747 14.5734C11.0121 14.6854 10.9256 14.7822 10.8214 14.8569C7.68191 17.1412 3.89931 18.3716 0.016777 18.3716C-3.86564 18.3716 -7.64822 17.1412 -10.7877 14.8569C-10.8923 14.7827 -10.9793 14.6862 -11.0425 14.5744C-11.1056 14.4627 -11.1434 14.3385 -11.1532 14.2105C-11.1629 14.0825 -11.1443 13.9539 -11.0989 13.834C-11.0532 13.714 -10.9819 13.6054 -10.8897 13.5161Z"
|
||||
/>
|
||||
<path
|
||||
d="M0.00299549 5.24402C-2.89638 5.24402 -5.24701 2.89352 -5.24701 -0.00602722C-5.24701 -2.90543 -2.89638 -5.25598 0.00299549 -5.25598C2.90252 -5.25598 5.25299 -2.90543 5.25299 -0.00602722C5.25299 2.89352 2.90252 5.24402 0.00299549 5.24402Z"
|
||||
/>
|
||||
<path
|
||||
d="M45.1065 -13.5355L49.517 -9.12508C49.6555 -8.98664 49.8367 -8.89874 50.0311 -8.87548C50.2257 -8.85223 50.4223 -8.89496 50.5897 -8.99681C52.3245 -10.0434 54.3254 -10.5654 56.3506 -10.4997C58.3758 -10.434 60.3385 -9.78347 62.002 -8.6266C63.025 -7.91449 63.9134 -7.02616 64.6255 -6.00309C65.781 -4.33862 66.4309 -2.37576 66.4971 -0.350574C66.5633 1.67461 66.0429 3.67576 64.9986 5.41218C64.8975 5.57923 64.8552 5.77521 64.8784 5.9692C64.9016 6.16304 64.9891 6.34355 65.1269 6.48196L69.5373 10.8923C69.6261 10.9817 69.7332 11.0509 69.8512 11.095C69.9692 11.1393 70.0954 11.1573 70.2211 11.1483C70.3468 11.1391 70.469 11.103 70.5794 11.0422C70.6898 10.9814 70.7858 10.8975 70.8607 10.7961C73.247 7.51607 74.4803 3.53827 74.368 -0.516392C74.2556 -4.57108 72.8041 -8.47452 70.2398 -11.6174C69.457 -12.579 68.5779 -13.4581 67.6163 -14.2409C64.4736 -16.8045 60.5708 -18.2556 56.5167 -18.368C52.4626 -18.4803 48.4855 -17.2474 45.2057 -14.8618C45.1036 -14.7871 45.019 -14.6912 44.9578 -14.5807C44.8964 -14.4701 44.8598 -14.3476 44.8503 -14.2215C44.8408 -14.0955 44.8589 -13.9688 44.9031 -13.8504C44.9474 -13.732 45.0168 -13.6245 45.1065 -13.5355Z"
|
||||
/>
|
||||
<path
|
||||
d="M45.1103 13.5161L49.5208 9.10565C49.6593 8.96724 49.8405 8.87936 50.0349 8.85608C50.2294 8.83281 50.4261 8.87553 50.5935 8.97735C52.2293 9.96414 54.1035 10.4858 56.0139 10.4858C57.9244 10.4858 59.7986 9.96414 61.4344 8.97735C61.6017 8.87553 61.7984 8.83281 61.993 8.85608C62.1875 8.87936 62.3685 8.96724 62.5071 9.10565L66.9176 13.5161C67.01 13.6049 67.0818 13.7132 67.1278 13.8329C67.1739 13.9527 67.1929 14.0811 67.1837 14.2091C67.1746 14.3371 67.1373 14.4614 67.0747 14.5734C67.0121 14.6854 66.9256 14.7822 66.8214 14.8569C63.6819 17.1412 59.8993 18.3716 56.0168 18.3716C52.1344 18.3716 48.3518 17.1412 45.2123 14.8569C45.1077 14.7827 45.0207 14.6862 44.9575 14.5744C44.8944 14.4627 44.8566 14.3385 44.8468 14.2105C44.8371 14.0825 44.8557 13.9539 44.9011 13.834C44.9468 13.714 45.0181 13.6054 45.1103 13.5161Z"
|
||||
/>
|
||||
<path
|
||||
d="M56.003 5.24402C53.1036 5.24402 50.753 2.89352 50.753 -0.00602722C50.753 -2.90543 53.1036 -5.25598 56.003 -5.25598C58.9025 -5.25598 61.253 -2.90543 61.253 -0.00602722C61.253 2.89352 58.9025 5.24402 56.003 5.24402Z"
|
||||
/>
|
||||
<path
|
||||
d="M-10.8935 28.4645L-6.48304 32.8749C-6.34447 33.0134 -6.16334 33.1013 -5.96889 33.1245C-5.77429 33.1478 -5.5777 33.105 -5.41035 33.0032C-3.67546 31.9566 -1.67461 31.4346 0.350573 31.5003C2.37576 31.566 4.33849 32.2165 6.00196 33.3734C7.02502 34.0855 7.91335 34.9738 8.62548 35.9969C9.78097 37.6614 10.4309 39.6242 10.4971 41.6494C10.5633 43.6746 10.0429 45.6758 8.99861 47.4122C8.89748 47.5792 8.85516 47.7752 8.87841 47.9692C8.90165 48.163 8.98912 48.3436 9.12687 48.482L13.5373 52.8923C13.6261 52.9817 13.7332 53.0509 13.8512 53.095C13.9692 53.1393 14.0954 53.1573 14.2211 53.1483C14.3468 53.1391 14.469 53.103 14.5794 53.0422C14.6898 52.9814 14.7858 52.8975 14.8607 52.7962C17.247 49.5161 18.4803 45.5383 18.368 41.4836C18.2556 37.4289 16.8041 33.5255 14.2398 30.3826C13.457 29.421 12.5779 28.5419 11.6163 27.7591C8.47363 25.1955 4.57076 23.7444 0.516696 23.632C-3.53735 23.5197 -7.51454 24.7526 -10.7943 27.1382C-10.8964 27.2129 -10.981 27.3088 -11.0422 27.4193C-11.1036 27.5299 -11.1402 27.6524 -11.1497 27.7785C-11.1592 27.9045 -11.1411 28.0312 -11.0969 28.1496C-11.0526 28.268 -10.9832 28.3755 -10.8935 28.4645Z"
|
||||
/>
|
||||
<path
|
||||
d="M-10.8897 55.5161L-6.47923 51.1057C-6.34066 50.9672 -6.15953 50.8794 -5.96508 50.8561C-5.77063 50.8328 -5.57388 50.8755 -5.40654 50.9773C-3.77071 51.9641 -1.89649 52.4858 0.0138683 52.4858C1.92438 52.4858 3.79857 51.9641 5.43441 50.9773C5.60174 50.8755 5.79843 50.8328 5.99295 50.8561C6.18747 50.8794 6.36853 50.9672 6.50713 51.1057L10.9176 55.5161C11.01 55.6049 11.0818 55.7132 11.1278 55.8329C11.1738 55.9527 11.1929 56.0811 11.1837 56.2091C11.1746 56.3371 11.1373 56.4614 11.0747 56.5734C11.0121 56.6854 10.9256 56.7822 10.8214 56.8569C7.68191 59.1412 3.89931 60.3716 0.016777 60.3716C-3.86564 60.3716 -7.64822 59.1412 -10.7877 56.8569C-10.8923 56.7827 -10.9793 56.6862 -11.0425 56.5744C-11.1056 56.4627 -11.1434 56.3385 -11.1532 56.2105C-11.1629 56.0825 -11.1443 55.9539 -11.0989 55.834C-11.0532 55.714 -10.9819 55.6054 -10.8897 55.5161Z"
|
||||
/>
|
||||
<path
|
||||
d="M0.00299549 47.244C-2.89638 47.244 -5.24701 44.8935 -5.24701 41.994C-5.24701 39.0946 -2.89638 36.744 0.00299549 36.744C2.90252 36.744 5.25299 39.0946 5.25299 41.994C5.25299 44.8935 2.90252 47.244 0.00299549 47.244Z"
|
||||
/>
|
||||
<path
|
||||
d="M45.1065 28.4645L49.517 32.8749C49.6555 33.0134 49.8367 33.1013 50.0311 33.1245C50.2257 33.1478 50.4223 33.105 50.5897 33.0032C52.3245 31.9566 54.3254 31.4346 56.3506 31.5003C58.3758 31.566 60.3385 32.2165 62.002 33.3734C63.025 34.0855 63.9134 34.9738 64.6255 35.9969C65.781 37.6614 66.4309 39.6242 66.4971 41.6494C66.5633 43.6746 66.0429 45.6758 64.9986 47.4122C64.8975 47.5792 64.8552 47.7752 64.8784 47.9692C64.9016 48.163 64.9891 48.3436 65.1269 48.482L69.5373 52.8923C69.6261 52.9817 69.7332 53.0509 69.8512 53.095C69.9692 53.1393 70.0954 53.1573 70.2211 53.1483C70.3468 53.1391 70.469 53.103 70.5794 53.0422C70.6898 52.9814 70.7858 52.8975 70.8607 52.7962C73.247 49.5161 74.4803 45.5383 74.368 41.4836C74.2556 37.4289 72.8041 33.5255 70.2398 30.3826C69.457 29.421 68.5779 28.5419 67.6163 27.7591C64.4736 25.1955 60.5708 23.7444 56.5167 23.632C52.4626 23.5197 48.4855 24.7526 45.2057 27.1382C45.1036 27.2129 45.019 27.3088 44.9578 27.4193C44.8964 27.5299 44.8598 27.6524 44.8503 27.7785C44.8408 27.9045 44.8589 28.0312 44.9031 28.1496C44.9474 28.268 45.0168 28.3755 45.1065 28.4645Z"
|
||||
/>
|
||||
<path
|
||||
d="M45.1103 55.5161L49.5208 51.1057C49.6593 50.9672 49.8405 50.8794 50.0349 50.8561C50.2294 50.8328 50.4261 50.8755 50.5935 50.9773C52.2293 51.9641 54.1035 52.4858 56.0139 52.4858C57.9244 52.4858 59.7986 51.9641 61.4344 50.9773C61.6017 50.8755 61.7984 50.8328 61.993 50.8561C62.1875 50.8794 62.3685 50.9672 62.5071 51.1057L66.9176 55.5161C67.01 55.6049 67.0818 55.7132 67.1278 55.8329C67.1739 55.9527 67.1929 56.0811 67.1837 56.2091C67.1746 56.3371 67.1373 56.4614 67.0747 56.5734C67.0121 56.6854 66.9256 56.7822 66.8214 56.8569C63.6819 59.1412 59.8993 60.3716 56.0168 60.3716C52.1344 60.3716 48.3518 59.1412 45.2123 56.8569C45.1077 56.7827 45.0207 56.6862 44.9575 56.5744C44.8944 56.4627 44.8566 56.3385 44.8468 56.2105C44.8371 56.0825 44.8557 55.9539 44.9011 55.834C44.9468 55.714 45.0181 55.6054 45.1103 55.5161Z"
|
||||
/>
|
||||
<path
|
||||
d="M56.003 47.244C53.1036 47.244 50.753 44.8935 50.753 41.994C50.753 39.0946 53.1036 36.744 56.003 36.744C58.9025 36.744 61.253 39.0946 61.253 41.994C61.253 44.8935 58.9025 47.244 56.003 47.244Z"
|
||||
/>
|
||||
<path
|
||||
d="M45.8935 7.4645L41.483 11.8749C41.3445 12.0134 41.1633 12.1013 40.9689 12.1245C40.7743 12.1478 40.5777 12.105 40.4103 12.0032C38.6755 10.9566 36.6746 10.4346 34.6494 10.5003C32.6242 10.566 30.6615 11.2165 28.998 12.3734C27.975 13.0855 27.0866 13.9738 26.3745 14.9969C25.219 16.6614 24.5691 18.6242 24.5029 20.6494C24.4367 22.6746 24.957 24.6758 26.0014 26.4122C26.1025 26.5792 26.1448 26.7752 26.1216 26.9692C26.0983 27.163 26.0109 27.3435 25.8731 27.482L21.4627 31.8923C21.3739 31.9817 21.2668 32.0509 21.1488 32.095C21.0308 32.1393 20.9046 32.1573 20.7789 32.1483C20.6532 32.1391 20.531 32.103 20.4206 32.0422C20.3102 31.9814 20.2142 31.8975 20.1393 31.7961C17.753 28.5161 16.5197 24.5383 16.632 20.4836C16.7444 16.4289 18.1959 12.5255 20.7602 9.38257C21.543 8.42097 22.4221 7.54189 23.3837 6.75906C26.5264 4.19551 30.4292 2.74437 34.4833 2.63205C38.5373 2.51973 42.5145 3.75255 45.7943 6.13816C45.8964 6.21286 45.9809 6.3088 46.0422 6.41934C46.1036 6.52989 46.1402 6.65241 46.1497 6.77848C46.1592 6.90455 46.1411 7.03117 46.0969 7.1496C46.0526 7.26803 45.9832 7.37547 45.8935 7.4645Z"
|
||||
/>
|
||||
<path
|
||||
d="M45.8897 34.5161L41.4792 30.1057C41.3407 29.9672 41.1595 29.8794 40.9651 29.8561C40.7706 29.8328 40.5739 29.8755 40.4065 29.9773C38.7707 30.9641 36.8965 31.4858 34.9861 31.4858C33.0756 31.4858 31.2014 30.9641 29.5656 29.9773C29.3983 29.8755 29.2016 29.8328 29.007 29.8561C28.8125 29.8794 28.6315 29.9672 28.4929 30.1057L24.0824 34.5161C23.9899 34.6049 23.9182 34.7132 23.8722 34.8329C23.8261 34.9527 23.8071 35.0811 23.8163 35.2091C23.8254 35.3371 23.8626 35.4614 23.9253 35.5734C23.9879 35.6854 24.0744 35.7822 24.1786 35.8569C27.3181 38.1412 31.1007 39.3716 34.9832 39.3716C38.8656 39.3716 42.6482 38.1412 45.7877 35.8569C45.8923 35.7827 45.9793 35.6862 46.0425 35.5744C46.1056 35.4627 46.1434 35.3385 46.1532 35.2105C46.1629 35.0825 46.1443 34.9539 46.0989 34.834C46.0532 34.714 45.9819 34.6054 45.8897 34.5161Z"
|
||||
/>
|
||||
<path
|
||||
d="M34.997 26.244C37.8964 26.244 40.247 23.8935 40.247 20.994C40.247 18.0946 37.8964 15.744 34.997 15.744C32.0975 15.744 29.747 18.0946 29.747 20.994C29.747 23.8935 32.0975 26.244 34.997 26.244Z"
|
||||
/>
|
||||
<path
|
||||
d="M-10.8935 -13.5355L-6.48304 -9.12508C-6.34447 -8.98664 -6.16334 -8.89874 -5.96889 -8.87548C-5.77429 -8.85223 -5.5777 -8.89496 -5.41035 -8.99681C-3.67546 -10.0434 -1.67461 -10.5654 0.350573 -10.4997C2.37576 -10.434 4.33849 -9.78347 6.00196 -8.6266C7.02502 -7.91449 7.91335 -7.02616 8.62548 -6.00309C9.78097 -4.33862 10.4309 -2.37576 10.4971 -0.350574C10.5633 1.67461 10.0429 3.67576 8.99861 5.41218C8.89748 5.57923 8.85516 5.77521 8.87841 5.9692C8.90165 6.16304 8.98912 6.34355 9.12687 6.48196L13.5373 10.8923C13.6261 10.9817 13.7332 11.0509 13.8512 11.095C13.9692 11.1393 14.0954 11.1573 14.2211 11.1483C14.3468 11.1391 14.469 11.103 14.5794 11.0422C14.6898 10.9814 14.7858 10.8975 14.8607 10.7961C17.247 7.51607 18.4803 3.53827 18.368 -0.516392C18.2556 -4.57108 16.8041 -8.47452 14.2398 -11.6174C13.457 -12.579 12.5779 -13.4581 11.6163 -14.2409C8.47363 -16.8045 4.57076 -18.2556 0.516696 -18.368C-3.53735 -18.4803 -7.51454 -17.2474 -10.7943 -14.8618C-10.8964 -14.7871 -10.981 -14.6912 -11.0422 -14.5807C-11.1036 -14.4701 -11.1402 -14.3476 -11.1497 -14.2215C-11.1592 -14.0955 -11.1411 -13.9688 -11.0969 -13.8504C-11.0526 -13.732 -10.9832 -13.6245 -10.8935 -13.5355Z"
|
||||
/>
|
||||
<path
|
||||
d="M-10.8897 13.5161L-6.47923 9.10565C-6.34066 8.96724 -6.15953 8.87936 -5.96508 8.85608C-5.77063 8.83281 -5.57388 8.87553 -5.40654 8.97735C-3.77071 9.96414 -1.89649 10.4858 0.0138683 10.4858C1.92438 10.4858 3.79857 9.96414 5.43441 8.97735C5.60174 8.87553 5.79843 8.83281 5.99295 8.85608C6.18747 8.87936 6.36853 8.96724 6.50713 9.10565L10.9176 13.5161C11.01 13.6049 11.0818 13.7132 11.1278 13.8329C11.1738 13.9527 11.1929 14.0811 11.1837 14.2091C11.1746 14.3371 11.1373 14.4614 11.0747 14.5734C11.0121 14.6854 10.9256 14.7822 10.8214 14.8569C7.68191 17.1412 3.89931 18.3716 0.016777 18.3716C-3.86564 18.3716 -7.64822 17.1412 -10.7877 14.8569C-10.8923 14.7827 -10.9793 14.6862 -11.0425 14.5744C-11.1056 14.4627 -11.1434 14.3385 -11.1532 14.2105C-11.1629 14.0825 -11.1443 13.9539 -11.0989 13.834C-11.0532 13.714 -10.9819 13.6054 -10.8897 13.5161Z"
|
||||
/>
|
||||
<path
|
||||
d="M0.00299549 5.24402C-2.89638 5.24402 -5.24701 2.89352 -5.24701 -0.00602722C-5.24701 -2.90543 -2.89638 -5.25598 0.00299549 -5.25598C2.90252 -5.25598 5.25299 -2.90543 5.25299 -0.00602722C5.25299 2.89352 2.90252 5.24402 0.00299549 5.24402Z"
|
||||
/>
|
||||
<path
|
||||
d="M45.1065 -13.5355L49.517 -9.12508C49.6555 -8.98664 49.8367 -8.89874 50.0311 -8.87548C50.2257 -8.85223 50.4223 -8.89496 50.5897 -8.99681C52.3245 -10.0434 54.3254 -10.5654 56.3506 -10.4997C58.3758 -10.434 60.3385 -9.78347 62.002 -8.6266C63.025 -7.91449 63.9134 -7.02616 64.6255 -6.00309C65.781 -4.33862 66.4309 -2.37576 66.4971 -0.350574C66.5633 1.67461 66.0429 3.67576 64.9986 5.41218C64.8975 5.57923 64.8552 5.77521 64.8784 5.9692C64.9016 6.16304 64.9891 6.34355 65.1269 6.48196L69.5373 10.8923C69.6261 10.9817 69.7332 11.0509 69.8512 11.095C69.9692 11.1393 70.0954 11.1573 70.2211 11.1483C70.3468 11.1391 70.469 11.103 70.5794 11.0422C70.6898 10.9814 70.7858 10.8975 70.8607 10.7961C73.247 7.51607 74.4803 3.53827 74.368 -0.516392C74.2556 -4.57108 72.8041 -8.47452 70.2398 -11.6174C69.457 -12.579 68.5779 -13.4581 67.6163 -14.2409C64.4736 -16.8045 60.5708 -18.2556 56.5167 -18.368C52.4626 -18.4803 48.4855 -17.2474 45.2057 -14.8618C45.1036 -14.7871 45.019 -14.6912 44.9578 -14.5807C44.8964 -14.4701 44.8598 -14.3476 44.8503 -14.2215C44.8408 -14.0955 44.8589 -13.9688 44.9031 -13.8504C44.9474 -13.732 45.0168 -13.6245 45.1065 -13.5355Z"
|
||||
/>
|
||||
<path
|
||||
d="M45.1103 13.5161L49.5208 9.10565C49.6593 8.96724 49.8405 8.87936 50.0349 8.85608C50.2294 8.83281 50.4261 8.87553 50.5935 8.97735C52.2293 9.96414 54.1035 10.4858 56.0139 10.4858C57.9244 10.4858 59.7986 9.96414 61.4344 8.97735C61.6017 8.87553 61.7984 8.83281 61.993 8.85608C62.1875 8.87936 62.3685 8.96724 62.5071 9.10565L66.9176 13.5161C67.01 13.6049 67.0818 13.7132 67.1278 13.8329C67.1739 13.9527 67.1929 14.0811 67.1837 14.2091C67.1746 14.3371 67.1373 14.4614 67.0747 14.5734C67.0121 14.6854 66.9256 14.7822 66.8214 14.8569C63.6819 17.1412 59.8993 18.3716 56.0168 18.3716C52.1344 18.3716 48.3518 17.1412 45.2123 14.8569C45.1077 14.7827 45.0207 14.6862 44.9575 14.5744C44.8944 14.4627 44.8566 14.3385 44.8468 14.2105C44.8371 14.0825 44.8557 13.9539 44.9011 13.834C44.9468 13.714 45.0181 13.6054 45.1103 13.5161Z"
|
||||
/>
|
||||
<path
|
||||
d="M56.003 5.24402C53.1036 5.24402 50.753 2.89352 50.753 -0.00602722C50.753 -2.90543 53.1036 -5.25598 56.003 -5.25598C58.9025 -5.25598 61.253 -2.90543 61.253 -0.00602722C61.253 2.89352 58.9025 5.24402 56.003 5.24402Z"
|
||||
/>
|
||||
<path
|
||||
d="M-10.8935 28.4645L-6.48304 32.8749C-6.34447 33.0134 -6.16334 33.1013 -5.96889 33.1245C-5.77429 33.1478 -5.5777 33.105 -5.41035 33.0032C-3.67546 31.9566 -1.67461 31.4346 0.350573 31.5003C2.37576 31.566 4.33849 32.2165 6.00196 33.3734C7.02502 34.0855 7.91335 34.9738 8.62548 35.9969C9.78097 37.6614 10.4309 39.6242 10.4971 41.6494C10.5633 43.6746 10.0429 45.6758 8.99861 47.4122C8.89748 47.5792 8.85516 47.7752 8.87841 47.9692C8.90165 48.163 8.98912 48.3436 9.12687 48.482L13.5373 52.8923C13.6261 52.9817 13.7332 53.0509 13.8512 53.095C13.9692 53.1393 14.0954 53.1573 14.2211 53.1483C14.3468 53.1391 14.469 53.103 14.5794 53.0422C14.6898 52.9814 14.7858 52.8975 14.8607 52.7962C17.247 49.5161 18.4803 45.5383 18.368 41.4836C18.2556 37.4289 16.8041 33.5255 14.2398 30.3826C13.457 29.421 12.5779 28.5419 11.6163 27.7591C8.47363 25.1955 4.57076 23.7444 0.516696 23.632C-3.53735 23.5197 -7.51454 24.7526 -10.7943 27.1382C-10.8964 27.2129 -10.981 27.3088 -11.0422 27.4193C-11.1036 27.5299 -11.1402 27.6524 -11.1497 27.7785C-11.1592 27.9045 -11.1411 28.0312 -11.0969 28.1496C-11.0526 28.268 -10.9832 28.3755 -10.8935 28.4645Z"
|
||||
/>
|
||||
<path
|
||||
d="M-10.8897 55.5161L-6.47923 51.1057C-6.34066 50.9672 -6.15953 50.8794 -5.96508 50.8561C-5.77063 50.8328 -5.57388 50.8755 -5.40654 50.9773C-3.77071 51.9641 -1.89649 52.4858 0.0138683 52.4858C1.92438 52.4858 3.79857 51.9641 5.43441 50.9773C5.60174 50.8755 5.79843 50.8328 5.99295 50.8561C6.18747 50.8794 6.36853 50.9672 6.50713 51.1057L10.9176 55.5161C11.01 55.6049 11.0818 55.7132 11.1278 55.8329C11.1738 55.9527 11.1929 56.0811 11.1837 56.2091C11.1746 56.3371 11.1373 56.4614 11.0747 56.5734C11.0121 56.6854 10.9256 56.7822 10.8214 56.8569C7.68191 59.1412 3.89931 60.3716 0.016777 60.3716C-3.86564 60.3716 -7.64822 59.1412 -10.7877 56.8569C-10.8923 56.7827 -10.9793 56.6862 -11.0425 56.5744C-11.1056 56.4627 -11.1434 56.3385 -11.1532 56.2105C-11.1629 56.0825 -11.1443 55.9539 -11.0989 55.834C-11.0532 55.714 -10.9819 55.6054 -10.8897 55.5161Z"
|
||||
/>
|
||||
<path
|
||||
d="M0.00299549 47.244C-2.89638 47.244 -5.24701 44.8935 -5.24701 41.994C-5.24701 39.0946 -2.89638 36.744 0.00299549 36.744C2.90252 36.744 5.25299 39.0946 5.25299 41.994C5.25299 44.8935 2.90252 47.244 0.00299549 47.244Z"
|
||||
/>
|
||||
<path
|
||||
d="M45.1065 28.4645L49.517 32.8749C49.6555 33.0134 49.8367 33.1013 50.0311 33.1245C50.2257 33.1478 50.4223 33.105 50.5897 33.0032C52.3245 31.9566 54.3254 31.4346 56.3506 31.5003C58.3758 31.566 60.3385 32.2165 62.002 33.3734C63.025 34.0855 63.9134 34.9738 64.6255 35.9969C65.781 37.6614 66.4309 39.6242 66.4971 41.6494C66.5633 43.6746 66.0429 45.6758 64.9986 47.4122C64.8975 47.5792 64.8552 47.7752 64.8784 47.9692C64.9016 48.163 64.9891 48.3436 65.1269 48.482L69.5373 52.8923C69.6261 52.9817 69.7332 53.0509 69.8512 53.095C69.9692 53.1393 70.0954 53.1573 70.2211 53.1483C70.3468 53.1391 70.469 53.103 70.5794 53.0422C70.6898 52.9814 70.7858 52.8975 70.8607 52.7962C73.247 49.5161 74.4803 45.5383 74.368 41.4836C74.2556 37.4289 72.8041 33.5255 70.2398 30.3826C69.457 29.421 68.5779 28.5419 67.6163 27.7591C64.4736 25.1955 60.5708 23.7444 56.5167 23.632C52.4626 23.5197 48.4855 24.7526 45.2057 27.1382C45.1036 27.2129 45.019 27.3088 44.9578 27.4193C44.8964 27.5299 44.8598 27.6524 44.8503 27.7785C44.8408 27.9045 44.8589 28.0312 44.9031 28.1496C44.9474 28.268 45.0168 28.3755 45.1065 28.4645Z"
|
||||
/>
|
||||
<path
|
||||
d="M45.1103 55.5161L49.5208 51.1057C49.6593 50.9672 49.8405 50.8794 50.0349 50.8561C50.2294 50.8328 50.4261 50.8755 50.5935 50.9773C52.2293 51.9641 54.1035 52.4858 56.0139 52.4858C57.9244 52.4858 59.7986 51.9641 61.4344 50.9773C61.6017 50.8755 61.7984 50.8328 61.993 50.8561C62.1875 50.8794 62.3685 50.9672 62.5071 51.1057L66.9176 55.5161C67.01 55.6049 67.0818 55.7132 67.1278 55.8329C67.1739 55.9527 67.1929 56.0811 67.1837 56.2091C67.1746 56.3371 67.1373 56.4614 67.0747 56.5734C67.0121 56.6854 66.9256 56.7822 66.8214 56.8569C63.6819 59.1412 59.8993 60.3716 56.0168 60.3716C52.1344 60.3716 48.3518 59.1412 45.2123 56.8569C45.1077 56.7827 45.0207 56.6862 44.9575 56.5744C44.8944 56.4627 44.8566 56.3385 44.8468 56.2105C44.8371 56.0825 44.8557 55.9539 44.9011 55.834C44.9468 55.714 45.0181 55.6054 45.1103 55.5161Z"
|
||||
/>
|
||||
<path
|
||||
d="M56.003 47.244C53.1036 47.244 50.753 44.8935 50.753 41.994C50.753 39.0946 53.1036 36.744 56.003 36.744C58.9025 36.744 61.253 39.0946 61.253 41.994C61.253 44.8935 58.9025 47.244 56.003 47.244Z"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 22 KiB |
BIN
docs/static/img/clerk-readme-dark.png
vendored
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
BIN
docs/static/img/clerk-readme-light.png
vendored
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
docs/static/img/clerk-sidebar-dark.png
vendored
Normal file
|
After Width: | Height: | Size: 177 KiB |
BIN
docs/static/img/clerk-sidebar-light.png
vendored
Normal file
|
After Width: | Height: | Size: 129 KiB |
7
docs/tailwind.config.js
Normal file
@@ -0,0 +1,7 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
darkMode: ['class','[data-theme="dark"]'],
|
||||
content: ["./src/**/*.js"],
|
||||
theme: { extend: {} },
|
||||
plugins: [],
|
||||
}
|
||||
13
package.json
@@ -21,12 +21,13 @@
|
||||
"lint": "prettier --check .",
|
||||
"format": "prettier --write .",
|
||||
"release": "release",
|
||||
"peek": "pnpm release --peek",
|
||||
"version:pr": "node ./config/version-pr",
|
||||
"e2e": "turbo run e2e --filter=next-auth-app"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@actions/core": "^1.10.0",
|
||||
"@balazsorban/monorepo-release": "0.2.4",
|
||||
"@balazsorban/monorepo-release": "0.3.1",
|
||||
"@types/jest": "^28.1.3",
|
||||
"@types/node": "^18.15.11",
|
||||
"@typescript-eslint/eslint-plugin": "5.47.0",
|
||||
@@ -60,11 +61,6 @@
|
||||
"url": "https://opencollective.com/nextauth"
|
||||
}
|
||||
],
|
||||
"pnpm": {
|
||||
"patchedDependencies": {
|
||||
"@balazsorban/monorepo-release@0.2.4": "patches/@balazsorban__monorepo-release@0.2.4.patch"
|
||||
}
|
||||
},
|
||||
"eslintIgnore": [
|
||||
".eslintrc.js",
|
||||
".cache-loader",
|
||||
@@ -265,5 +261,10 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"pnpm": {
|
||||
"patchedDependencies": {
|
||||
"@balazsorban/monorepo-release@0.3.1": "patches/@balazsorban__monorepo-release@0.3.1.patch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@auth/azure-tables-adapter",
|
||||
"version": "0.1.1",
|
||||
"version": "0.1.2",
|
||||
"description": "Azure Tables Storage adapter for next-auth.",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
|
||||
@@ -28,8 +28,6 @@ import {
|
||||
TableEntityResult,
|
||||
} from "@azure/data-tables"
|
||||
|
||||
globalThis.crypto ??= require("node:crypto").webcrypto
|
||||
|
||||
export const keys = {
|
||||
user: "user",
|
||||
userByEmail: "userByEmail",
|
||||
|
||||
@@ -7,6 +7,8 @@ import {
|
||||
import { keys, TableStorageAdapter, withoutKeys } from "../src"
|
||||
import type { AdapterUser, VerificationToken } from "@auth/core/adapters"
|
||||
|
||||
globalThis.crypto ??= require("node:crypto").webcrypto
|
||||
|
||||
const testAccount = {
|
||||
// default constants used by a dev instance of azurite
|
||||
name: "devstoreaccount1",
|
||||
|
||||
32
packages/adapter-hasura/README.md
Normal file
@@ -0,0 +1,32 @@
|
||||
<p align="center">
|
||||
<br/>
|
||||
<a href="https://authjs.dev" target="_blank">
|
||||
<img height="64px" src="https://authjs.dev/img/logo/logo-sm.png" />
|
||||
</a>
|
||||
<a href="https://hasura.io" target="_blank">
|
||||
<img height="64px" src="https://authjs.dev/img/adapters/hasura.svg"/>
|
||||
</a>
|
||||
<h3 align="center"><b>Hasura Adapter</b> - NextAuth.js / Auth.js</a></h3>
|
||||
<p align="center" style="align: center;">
|
||||
<a href="https://npm.im/@auth/hasura-adapter">
|
||||
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
|
||||
</a>
|
||||
<a href="https://npm.im/@auth/hasura-adapter">
|
||||
<img alt="npm" src="https://img.shields.io/npm/v/@auth/hasura-adapter?color=green&label=@auth/hasura-adapter&style=flat-square">
|
||||
</a>
|
||||
<a href="https://www.npmtrends.com/@auth/hasura-adapter">
|
||||
<img src="https://img.shields.io/npm/dm/@auth/hasura-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
|
||||
</a>
|
||||
<a href="https://github.com/nextauthjs/next-auth/stargazers">
|
||||
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
|
||||
</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
Check out the documentation at [authjs.dev](https://authjs.dev/reference/adapter/hasura).
|
||||
|
||||
## Credit
|
||||
|
||||
Based on code from [Amruth Pillai](https://github.com/AmruthPillai)
|
||||
28
packages/adapter-hasura/codegen.ts
Normal file
@@ -0,0 +1,28 @@
|
||||
import type { CodegenConfig } from "@graphql-codegen/cli"
|
||||
|
||||
const config: CodegenConfig = {
|
||||
overwrite: true,
|
||||
schema: "schema.graphql",
|
||||
emitLegacyCommonJSImports: false,
|
||||
documents: "src/**/*.graphql",
|
||||
generates: {
|
||||
"src/lib/": {
|
||||
preset: "client",
|
||||
config: {
|
||||
documentMode: "string",
|
||||
skipTypename: true,
|
||||
enumsAsTypes: true,
|
||||
strictScalars: true,
|
||||
useTypeImports: true,
|
||||
scalars: {
|
||||
timestamptz: "string",
|
||||
uuid: "string",
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
},
|
||||
},
|
||||
hooks: { afterAllFileWrite: ["prettier --write"] },
|
||||
}
|
||||
|
||||
export default config
|
||||
38
packages/adapter-hasura/docker-compose.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16
|
||||
volumes:
|
||||
- db_data:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pg_isready -U postgres"]
|
||||
interval: 5s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
environment:
|
||||
POSTGRES_PASSWORD: postgrespassword
|
||||
graphql-engine:
|
||||
image: hasura/graphql-engine:v2.33.4.cli-migrations-v3
|
||||
ports:
|
||||
- "8080:8080"
|
||||
depends_on:
|
||||
postgres:
|
||||
condition: service_healthy
|
||||
environment:
|
||||
## postgres database to store Hasura metadata
|
||||
HASURA_GRAPHQL_METADATA_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres
|
||||
## this env var can be used to add the above postgres database to Hasura as a data source. this can be removed/updated based on your needs
|
||||
PG_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres
|
||||
## enable the console served by server
|
||||
HASURA_GRAPHQL_ENABLE_CONSOLE: "true" # set to "false" to disable console
|
||||
## enable debugging mode. It is recommended to disable this in production
|
||||
HASURA_GRAPHQL_DEV_MODE: "true"
|
||||
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup, http-log, webhook-log, websocket-log, query-log
|
||||
## uncomment next line to run console offline (i.e load console assets from server instead of CDN)
|
||||
# HASURA_GRAPHQL_CONSOLE_ASSETS_DIR: /srv/console-assets
|
||||
## uncomment next line to set an admin secret
|
||||
HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey
|
||||
volumes:
|
||||
- ./hasura/migrations:/hasura-migrations
|
||||
- ./hasura/metadata:/hasura-metadata
|
||||
volumes:
|
||||
db_data:
|
||||
17
packages/adapter-hasura/hasura.svg
Normal file
@@ -0,0 +1,17 @@
|
||||
<svg width="285" height="84" viewBox="0 0 285 84" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_5273_22171)">
|
||||
<path d="M81.7705 28.7985C84.2257 21.3329 82.7488 6.43936 77.9912 0.94089C77.3677 0.219628 76.2075 0.322665 75.6894 1.11886L69.8294 10.1019C68.3809 11.9003 65.7722 12.3125 63.8056 11.0573C57.4466 6.99202 49.8506 4.6315 41.6884 4.6315C33.5262 4.6315 25.93 6.99202 19.571 11.0573C17.6143 12.3125 15.0055 11.891 13.5476 10.1019L7.68738 1.11886C7.16947 0.322665 6.00889 0.228995 5.38548 0.94089C0.628213 6.44869 -0.84884 21.3423 1.60652 28.7985C2.42178 31.2807 2.64238 33.9035 2.16282 36.4513C1.68325 38.9804 1.20369 42.0341 1.20369 44.1604C1.20369 65.9951 19.3312 83.6891 41.6788 83.6891C64.036 83.6891 82.1537 65.9858 82.1537 44.1604C82.1537 42.0341 81.6744 38.9804 81.195 36.4513C80.7249 33.9035 80.9548 31.2807 81.7705 28.7985ZM41.6788 74.8658C24.3954 74.8658 10.3442 61.1335 10.3442 44.2541C10.3442 43.7014 10.3633 43.1581 10.3921 42.6148C11.0156 31.1121 18.1706 21.2861 28.2894 16.6026C32.3465 14.7104 36.8928 13.6613 41.6884 13.6613C46.484 13.6613 51.0207 14.7104 55.0875 16.6119C65.2061 21.2955 72.3611 31.1308 72.9846 42.6242C73.0135 43.1675 73.0326 43.7201 73.0326 44.2634C73.0228 61.1335 58.9623 74.8658 41.6788 74.8658Z" fill="#1EB4D4"/>
|
||||
<path d="M55.2596 56.0378L47.251 42.4741L40.3837 31.1681C40.2206 30.8965 39.9233 30.7372 39.6068 30.7372H33.0463C32.7202 30.7372 32.4229 30.9058 32.2599 31.1869C32.0968 31.4585 32.1064 31.7957 32.2695 32.0673L38.8395 42.8488L30.0251 55.9816C29.8429 56.2533 29.8333 56.5996 29.9867 56.8806C30.1402 57.1615 30.4471 57.3398 30.7828 57.3398H37.3912C37.6981 57.3398 37.9859 57.1898 38.1489 56.9367L42.9158 49.668L47.1934 56.9089C47.3565 57.1806 47.6538 57.3491 47.9704 57.3491H54.4828C54.8087 57.3491 55.1062 57.1806 55.2596 56.9089C55.4229 56.6466 55.4229 56.3095 55.2596 56.0378Z" fill="#1EB4D4"/>
|
||||
<path d="M119.484 21.5306H127.838V66.2673H119.484V47.2056H110.046V66.2771H101.692V21.5306H110.046V40.9578H119.484V21.5306Z" fill="#1B2738"/>
|
||||
<path d="M153.61 66.276L151.864 56.9842H141.842L140.24 66.276H131.886L141.103 21.5391H152.353L162.012 66.276H153.61ZM142.935 50.8111H150.704L146.714 29.398L142.935 50.8111Z" fill="#1B2738"/>
|
||||
<path d="M180.619 58.1171V48.5443C180.619 47.7855 180.476 47.2797 180.188 47.0174C179.9 46.7551 179.363 46.624 178.586 46.624H172.707C167.719 46.624 165.226 44.2635 165.226 39.5331V28.555C165.226 23.8715 167.834 21.5391 173.061 21.5391H181.051C186.278 21.5391 188.887 23.8808 188.887 28.555V34.7934H180.466V29.6884C180.466 28.9297 180.322 28.4239 180.035 28.1616C179.747 27.8993 179.21 27.7682 178.433 27.7682H175.671C174.846 27.7682 174.289 27.8993 174.002 28.1616C173.714 28.4239 173.57 28.9297 173.57 29.6884V38.6901C173.57 39.4489 173.714 39.9547 174.002 40.2169C174.289 40.4792 174.846 40.6104 175.671 40.6104H181.406C186.489 40.6104 189.031 42.924 189.031 47.5607V59.2604C189.031 63.9437 186.394 66.276 181.118 66.276H173.273C167.998 66.276 165.36 63.9344 165.36 59.2604V53.0873H173.704V58.1171C173.704 58.8758 173.848 59.382 174.136 59.6444C174.424 59.9062 174.98 60.0377 175.805 60.0377H178.567C179.344 60.0377 179.871 59.9062 180.169 59.6444C180.466 59.382 180.619 58.8758 180.619 58.1171Z" fill="#1B2738"/>
|
||||
<path d="M211.32 21.5306H219.664V59.2517C219.664 63.9349 217.027 66.2673 211.752 66.2673H202.899C197.624 66.2673 194.986 63.9257 194.986 59.2517V21.5306H203.34V58.1182C203.34 58.8769 203.484 59.3826 203.772 59.6449C204.059 59.9073 204.597 60.0382 205.374 60.0382H209.219C210.044 60.0382 210.601 59.9073 210.888 59.6449C211.176 59.3826 211.32 58.8769 211.32 58.1182V21.5306Z" fill="#1B2738"/>
|
||||
<path d="M234.914 48.8355V66.2771H226.569V21.5306H243.412C248.687 21.5306 251.324 23.8723 251.324 28.5465V41.8102C251.324 45.6882 249.56 47.955 246.021 48.62L253.646 66.2771H244.64L237.667 48.8355H234.914ZM234.914 27.769V42.8031H240.937C241.714 42.8031 242.242 42.672 242.539 42.4097C242.827 42.1474 242.97 41.6416 242.97 40.8829V29.6893C242.97 28.9305 242.827 28.4247 242.539 28.1624C242.251 27.9001 241.714 27.769 240.937 27.769H234.914Z" fill="#1B2738"/>
|
||||
<path d="M276.589 66.276L274.843 56.9842H264.82L263.218 66.276H254.874L264.091 21.5391H275.342L285 66.276H276.589ZM265.923 50.8111H273.692L269.702 29.398L265.923 50.8111Z" fill="#1B2738"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_5273_22171">
|
||||
<rect width="285" height="84" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
6
packages/adapter-hasura/hasura/config.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
version: 3
|
||||
endpoint: http://localhost:8080
|
||||
metadata_directory: metadata
|
||||
actions:
|
||||
kind: synchronous
|
||||
handler_webhook_baseurl: http://localhost:3000
|
||||
6
packages/adapter-hasura/hasura/metadata/actions.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
actions: []
|
||||
custom_types:
|
||||
enums: []
|
||||
input_objects: []
|
||||
objects: []
|
||||
scalars: []
|
||||
1
packages/adapter-hasura/hasura/metadata/allow_list.yaml
Normal file
@@ -0,0 +1 @@
|
||||
[]
|
||||
1
packages/adapter-hasura/hasura/metadata/api_limits.yaml
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1,11 @@
|
||||
- name: default
|
||||
kind: postgres
|
||||
configuration:
|
||||
connection_info:
|
||||
database_url:
|
||||
from_env: PG_DATABASE_URL
|
||||
isolation_level: read-committed
|
||||
use_prepared_statements: false
|
||||
customization:
|
||||
naming_convention: hasura-default
|
||||
tables: "!include default/tables/tables.yaml"
|
||||
@@ -0,0 +1,7 @@
|
||||
table:
|
||||
name: accounts
|
||||
schema: public
|
||||
object_relationships:
|
||||
- name: user
|
||||
using:
|
||||
foreign_key_constraint_on: userId
|
||||
@@ -0,0 +1,4 @@
|
||||
table:
|
||||
name: provider_type
|
||||
schema: public
|
||||
is_enum: true
|
||||
@@ -0,0 +1,7 @@
|
||||
table:
|
||||
name: sessions
|
||||
schema: public
|
||||
object_relationships:
|
||||
- name: user
|
||||
using:
|
||||
foreign_key_constraint_on: userId
|
||||
@@ -0,0 +1,18 @@
|
||||
table:
|
||||
name: users
|
||||
schema: public
|
||||
array_relationships:
|
||||
- name: accounts
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: userId
|
||||
table:
|
||||
name: accounts
|
||||
schema: public
|
||||
- name: sessions
|
||||
using:
|
||||
foreign_key_constraint_on:
|
||||
column: userId
|
||||
table:
|
||||
name: sessions
|
||||
schema: public
|
||||
@@ -0,0 +1,3 @@
|
||||
table:
|
||||
name: verification_tokens
|
||||
schema: public
|
||||
@@ -0,0 +1,5 @@
|
||||
- "!include public_accounts.yaml"
|
||||
- "!include public_provider_type.yaml"
|
||||
- "!include public_sessions.yaml"
|
||||
- "!include public_users.yaml"
|
||||
- "!include public_verification_tokens.yaml"
|
||||
@@ -0,0 +1 @@
|
||||
disabled_for_roles: []
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
1
packages/adapter-hasura/hasura/metadata/network.yaml
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
@@ -0,0 +1 @@
|
||||
[]
|
||||
1
packages/adapter-hasura/hasura/metadata/version.yaml
Normal file
@@ -0,0 +1 @@
|
||||
version: 3
|
||||
@@ -0,0 +1,68 @@
|
||||
CREATE TABLE accounts (
|
||||
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
type text NOT NULL,
|
||||
provider text NOT NULL,
|
||||
"providerAccountId" text NOT NULL,
|
||||
refresh_token text,
|
||||
access_token text,
|
||||
expires_at integer,
|
||||
token_type text,
|
||||
scope text,
|
||||
id_token text,
|
||||
session_state text,
|
||||
"userId" uuid NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE sessions (
|
||||
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
"sessionToken" text NOT NULL,
|
||||
"userId" uuid NOT NULL,
|
||||
expires timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE users (
|
||||
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
name text,
|
||||
email text NOT NULL,
|
||||
"emailVerified" timestamptz,
|
||||
image text
|
||||
);
|
||||
|
||||
CREATE TABLE verification_tokens (
|
||||
token text NOT NULL,
|
||||
identifier text NOT NULL,
|
||||
expires timestamptz NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE provider_type (
|
||||
value text NOT NULL
|
||||
);
|
||||
|
||||
ALTER TABLE ONLY accounts
|
||||
ADD CONSTRAINT accounts_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY sessions
|
||||
ADD CONSTRAINT sessions_pkey PRIMARY KEY ("sessionToken");
|
||||
|
||||
ALTER TABLE ONLY users
|
||||
ADD CONSTRAINT users_email_key UNIQUE (email);
|
||||
|
||||
ALTER TABLE ONLY users
|
||||
ADD CONSTRAINT users_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY verification_tokens
|
||||
ADD CONSTRAINT verification_tokens_pkey PRIMARY KEY (token);
|
||||
|
||||
ALTER TABLE ONLY provider_type
|
||||
ADD CONSTRAINT provider_type_pkey PRIMARY KEY (value);
|
||||
|
||||
ALTER TABLE ONLY accounts
|
||||
ADD CONSTRAINT "accounts_userId_fkey" FOREIGN KEY ("userId") REFERENCES public.users(id) ON UPDATE RESTRICT ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY sessions
|
||||
ADD CONSTRAINT "sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES public.users(id) ON UPDATE RESTRICT ON DELETE CASCADE;
|
||||
|
||||
INSERT INTO provider_type (value) VALUES ('credentials'), ('email'), ('oauth'), ('oidc');
|
||||
|
||||
ALTER TABLE ONLY accounts
|
||||
ADD CONSTRAINT "accounts_type_fkey" FOREIGN KEY ("type") REFERENCES public.provider_type(value) ON UPDATE RESTRICT ON DELETE RESTRICT;
|
||||
68
packages/adapter-hasura/package.json
Normal file
@@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "@auth/hasura-adapter",
|
||||
"version": "0.2.0",
|
||||
"description": "Hasura adapter for Auth.js.",
|
||||
"homepage": "https://authjs.dev",
|
||||
"repository": "https://github.com/nextauthjs/next-auth",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nextauthjs/next-auth/issues"
|
||||
},
|
||||
"contributors": [
|
||||
"Hasura Team",
|
||||
"Amruth Pillai <im.amruth@gmail.com>",
|
||||
"Arjun Yelamanchili"
|
||||
],
|
||||
"license": "ISC",
|
||||
"keywords": [
|
||||
"@auth",
|
||||
"authjs",
|
||||
"Auth.js",
|
||||
"next-auth",
|
||||
"next.js",
|
||||
"oauth",
|
||||
"hasura"
|
||||
],
|
||||
"type": "module",
|
||||
"types": "./index.d.ts",
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.d.ts*",
|
||||
"lib",
|
||||
"src"
|
||||
],
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./index.d.ts",
|
||||
"import": "./index.js"
|
||||
}
|
||||
},
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "./tests/test.sh",
|
||||
"build": "graphql-codegen-esm --config codegen.ts && tsc"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphql": "^16",
|
||||
"graphql-request": "^6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@auth/core": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@auth/adapter-test": "workspace:*",
|
||||
"@auth/tsconfig": "workspace:*",
|
||||
"@graphql-codegen/cli": "^5.0.0",
|
||||
"@graphql-codegen/client-preset": "^4.1.0",
|
||||
"@graphql-typed-document-node/core": "^3.2.0",
|
||||
"graphql": "^16.8.1",
|
||||
"graphql-request": "^6.1.0",
|
||||
"jest": "^29.7.0",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"jest": {
|
||||
"preset": "@auth/adapter-test/jest"
|
||||
}
|
||||
}
|
||||
2291
packages/adapter-hasura/schema.graphql
Normal file
493
packages/adapter-hasura/src/index.ts
Normal file
@@ -0,0 +1,493 @@
|
||||
/**
|
||||
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: 16}}>
|
||||
* <p style={{fontWeight: "normal"}}>Official <a href="https://hasura.io/">Hasura</a> adapter for Auth.js / NextAuth.js.</p>
|
||||
* <a href="https://hasura.io/">
|
||||
* <img style={{display: "block"}} src="/img/adapters/hasura.svg" width="38" />
|
||||
* </a>
|
||||
* </div>
|
||||
*
|
||||
* ## Installation
|
||||
*
|
||||
* ```bash npm2yarn2pnpm
|
||||
* npm install next-auth @auth/hasura-adapter graphql graphql-request
|
||||
* ```
|
||||
*
|
||||
* @module @auth/hasura-adapter
|
||||
*/
|
||||
|
||||
import { GraphQLClient } from "graphql-request"
|
||||
import type { Adapter, AdapterAccount } from "@auth/core/adapters"
|
||||
import { useFragment } from "./lib"
|
||||
import {
|
||||
AccountFragmentDoc,
|
||||
CreateAccountDocument,
|
||||
CreateSessionDocument,
|
||||
CreateUserDocument,
|
||||
CreateVerificationTokenDocument,
|
||||
DeleteAccountDocument,
|
||||
DeleteSessionDocument,
|
||||
DeleteUserDocument,
|
||||
DeleteVerificationTokenDocument,
|
||||
GetSessionAndUserDocument,
|
||||
GetUserDocument,
|
||||
GetUsersDocument,
|
||||
SessionFragmentDoc,
|
||||
UpdateSessionDocument,
|
||||
UpdateUserDocument,
|
||||
UserFragmentDoc,
|
||||
VerificationTokenFragmentDoc,
|
||||
} from "./lib/graphql"
|
||||
import type {
|
||||
AccountFragment,
|
||||
CreateAccountMutation,
|
||||
CreateAccountMutationVariables,
|
||||
CreateSessionMutation,
|
||||
CreateSessionMutationVariables,
|
||||
CreateUserMutation,
|
||||
CreateUserMutationVariables,
|
||||
CreateVerificationTokenMutation,
|
||||
CreateVerificationTokenMutationVariables,
|
||||
DeleteAccountMutation,
|
||||
DeleteAccountMutationVariables,
|
||||
DeleteSessionMutation,
|
||||
DeleteSessionMutationVariables,
|
||||
DeleteUserMutation,
|
||||
DeleteUserMutationVariables,
|
||||
DeleteVerificationTokenMutation,
|
||||
DeleteVerificationTokenMutationVariables,
|
||||
GetSessionAndUserQuery,
|
||||
GetSessionAndUserQueryVariables,
|
||||
GetUserQuery,
|
||||
GetUserQueryVariables,
|
||||
GetUsersQuery,
|
||||
GetUsersQueryVariables,
|
||||
UpdateSessionMutation,
|
||||
UpdateSessionMutationVariables,
|
||||
UpdateUserMutation,
|
||||
UpdateUserMutationVariables,
|
||||
} from "./lib/graphql"
|
||||
import { formatDateConversion } from "./utils"
|
||||
import type { NonNullify } from "./utils"
|
||||
|
||||
interface HasuraAdapterArgs {
|
||||
endpoint: string
|
||||
adminSecret: string
|
||||
graphqlRequestOptions?: any
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* ## Setup
|
||||
*
|
||||
* 1. Create the next-auth schema in your database using SQL.
|
||||
*
|
||||
* ```sql
|
||||
* CREATE TABLE accounts (
|
||||
* id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
* type text NOT NULL,
|
||||
* provider text NOT NULL,
|
||||
* "providerAccountId" text NOT NULL,
|
||||
* refresh_token text,
|
||||
* access_token text,
|
||||
* expires_at integer,
|
||||
* token_type text,
|
||||
* scope text,
|
||||
* id_token text,
|
||||
* session_state text,
|
||||
* "userId" uuid NOT NULL,
|
||||
* );
|
||||
*
|
||||
* CREATE TABLE sessions (
|
||||
* id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
* "sessionToken" text NOT NULL,
|
||||
* "userId" uuid NOT NULL,
|
||||
* expires timestamptz NOT NULL
|
||||
* );
|
||||
*
|
||||
* CREATE TABLE users (
|
||||
* id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||
* name text,
|
||||
* email text NOT NULL,
|
||||
* "emailVerified" timestamptz,
|
||||
* image text
|
||||
* );
|
||||
*
|
||||
* CREATE TABLE verification_tokens (
|
||||
* token text NOT NULL,
|
||||
* identifier text NOT NULL,
|
||||
* expires timestamptz NOT NULL
|
||||
* );
|
||||
*
|
||||
* CREATE TABLE provider_type (
|
||||
* value text NOT NULL
|
||||
* );
|
||||
*
|
||||
* ALTER TABLE ONLY accounts
|
||||
* ADD CONSTRAINT accounts_pkey PRIMARY KEY (id);
|
||||
*
|
||||
* ALTER TABLE ONLY sessions
|
||||
* ADD CONSTRAINT sessions_pkey PRIMARY KEY ("sessionToken");
|
||||
*
|
||||
* ALTER TABLE ONLY users
|
||||
* ADD CONSTRAINT users_email_key UNIQUE (email);
|
||||
*
|
||||
* ALTER TABLE ONLY users
|
||||
* ADD CONSTRAINT users_pkey PRIMARY KEY (id);
|
||||
*
|
||||
* ALTER TABLE ONLY verification_tokens
|
||||
* ADD CONSTRAINT verification_tokens_pkey PRIMARY KEY (token);
|
||||
*
|
||||
* ALTER TABLE ONLY provider_type
|
||||
* ADD CONSTRAINT provider_type_pkey PRIMARY KEY (value);
|
||||
*
|
||||
* ALTER TABLE ONLY accounts
|
||||
* ADD CONSTRAINT "accounts_userId_fkey" FOREIGN KEY ("userId") REFERENCES public.users(id) ON UPDATE RESTRICT ON DELETE CASCADE;
|
||||
*
|
||||
* ALTER TABLE ONLY sessions
|
||||
* ADD CONSTRAINT "sessions_userId_fkey" FOREIGN KEY ("userId") REFERENCES public.users(id) ON UPDATE RESTRICT ON DELETE CASCADE;
|
||||
*
|
||||
* INSERT INTO provider_type (value) VALUES ('credentials'), ('email'), ('oauth'), ('oidc');
|
||||
*
|
||||
* ALTER TABLE ONLY accounts
|
||||
* ADD CONSTRAINT "accounts_type_fkey" FOREIGN KEY ("type") REFERENCES public.provider_type(value) ON UPDATE RESTRICT ON DELETE RESTRICT;
|
||||
* ```
|
||||
*
|
||||
* :::info
|
||||
* Tips: [Track all the tables and relationships in Hasura](https://hasura.io/docs/latest/schema/postgres/using-existing-database/#step-1-track-tablesviews)
|
||||
* :::
|
||||
*
|
||||
*1. Configure your NextAuth.js to use the Hasura Adapter:
|
||||
*
|
||||
* ```javascript title="pages/api/auth/[...nextauth].js"
|
||||
* import NextAuth from "next-auth"
|
||||
* import { HasuraAdapter } from "@next-auth/hasura-adapter"
|
||||
*
|
||||
* // For more information on each option (and a full list of options) go to
|
||||
* // https://next-auth.js.org/configuration/options
|
||||
* export default nextAuth({
|
||||
* adapter: HasuraAdapter({
|
||||
* endpoint: "<Hasura-GraphQL-endpoint>",
|
||||
* adminSecret: "<admin-secret>",
|
||||
* graphqlRequestOptions: {
|
||||
* // Optional graphql-request options
|
||||
* },
|
||||
* }),
|
||||
* ...
|
||||
* })
|
||||
* ```
|
||||
*
|
||||
*## Passing dynamic headers
|
||||
*
|
||||
*If you use [graphql-request's dynamic headers feature](https://github.com/prisma-labs/graphql-request#passing-dynamic-headers-to-the-client), you are responsible for passing the 'X-Hasura-Admin-Secret' header
|
||||
*
|
||||
*```js
|
||||
*export default nextAuth({
|
||||
* adapter: HasuraAdapter({
|
||||
* endpoint: "<Hasura-GraphQL-endpoint>",
|
||||
* adminSecret: "<admin-secret>",
|
||||
* graphqlRequestOptions: {
|
||||
* headers: () => ({
|
||||
* "X-Hasura-Admin-Secret": "<admin-secret>",
|
||||
* // your headers here
|
||||
* }),
|
||||
* },
|
||||
* }),
|
||||
* ...
|
||||
*})
|
||||
*```
|
||||
|
||||
*/
|
||||
export const HasuraAdapter = ({
|
||||
endpoint,
|
||||
adminSecret,
|
||||
graphqlRequestOptions,
|
||||
}: HasuraAdapterArgs): Adapter => {
|
||||
const client = new GraphQLClient(endpoint, {
|
||||
fetch: fetch ?? undefined,
|
||||
...graphqlRequestOptions,
|
||||
headers:
|
||||
graphqlRequestOptions?.headers instanceof Function
|
||||
? graphqlRequestOptions?.headers
|
||||
: {
|
||||
...graphqlRequestOptions?.headers,
|
||||
"x-hasura-admin-secret": adminSecret,
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
// User
|
||||
createUser: async (newUser) => {
|
||||
const variables: CreateUserMutationVariables = {
|
||||
data: formatDateConversion(newUser, "emailVerified", "toDatabase"),
|
||||
}
|
||||
const { insert_users_one } = await client.request<CreateUserMutation>(
|
||||
CreateUserDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const user = useFragment(UserFragmentDoc, insert_users_one)
|
||||
|
||||
if (!user) {
|
||||
throw new Error("Error creating user")
|
||||
}
|
||||
return formatDateConversion(user, "emailVerified", "toJS")
|
||||
},
|
||||
getUser: async (id) => {
|
||||
const variables: GetUserQueryVariables = { id }
|
||||
const { users_by_pk } = await client.request<GetUserQuery>(
|
||||
GetUserDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const user = useFragment(UserFragmentDoc, users_by_pk)
|
||||
|
||||
return user ? formatDateConversion(user, "emailVerified", "toJS") : null
|
||||
},
|
||||
getUserByEmail: async (email) => {
|
||||
const variables: GetUsersQueryVariables = {
|
||||
where: { email: { _eq: email } },
|
||||
}
|
||||
const { users } = await client.request<GetUsersQuery>(
|
||||
GetUsersDocument.toString(),
|
||||
variables
|
||||
)
|
||||
|
||||
const user = useFragment(UserFragmentDoc, users?.[0])
|
||||
|
||||
if (!user) return null
|
||||
|
||||
return user ? formatDateConversion(user, "emailVerified", "toJS") : null
|
||||
},
|
||||
getUserByAccount: async ({ providerAccountId, provider }) => {
|
||||
const variables: GetUsersQueryVariables = {
|
||||
where: {
|
||||
accounts: {
|
||||
provider: { _eq: provider },
|
||||
providerAccountId: { _eq: providerAccountId },
|
||||
},
|
||||
},
|
||||
}
|
||||
const { users } = await client.request<GetUsersQuery>(
|
||||
GetUsersDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const user = useFragment(UserFragmentDoc, users?.[0])
|
||||
|
||||
if (!user) return null
|
||||
|
||||
return user ? formatDateConversion(user, "emailVerified", "toJS") : null
|
||||
},
|
||||
updateUser: async ({ id, ...data }) => {
|
||||
const variables: UpdateUserMutationVariables = {
|
||||
id,
|
||||
data: formatDateConversion(data, "emailVerified", "toDatabase"),
|
||||
}
|
||||
const { update_users_by_pk } = await client.request<UpdateUserMutation>(
|
||||
UpdateUserDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const user = useFragment(UserFragmentDoc, update_users_by_pk)
|
||||
|
||||
if (!user) {
|
||||
throw new Error("Error updating user")
|
||||
}
|
||||
|
||||
return formatDateConversion(user, "emailVerified", "toJS")
|
||||
},
|
||||
deleteUser: async (id) => {
|
||||
const variables: DeleteUserMutationVariables = {
|
||||
id,
|
||||
}
|
||||
const { delete_users_by_pk } = await client.request<DeleteUserMutation>(
|
||||
DeleteUserDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const user = useFragment(UserFragmentDoc, delete_users_by_pk)
|
||||
|
||||
if (!user) {
|
||||
throw new Error("Error deleting user")
|
||||
}
|
||||
return formatDateConversion(user, "emailVerified", "toJS")
|
||||
},
|
||||
// Session
|
||||
createSession: async (data) => {
|
||||
const variables: CreateSessionMutationVariables = {
|
||||
data: formatDateConversion(data, "expires", "toDatabase"),
|
||||
}
|
||||
const { insert_sessions_one } =
|
||||
await client.request<CreateSessionMutation>(
|
||||
CreateSessionDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const session = useFragment(SessionFragmentDoc, insert_sessions_one)
|
||||
|
||||
if (!session) {
|
||||
throw new Error("Error creating session")
|
||||
}
|
||||
session.expires
|
||||
return formatDateConversion(session, "expires", "toJS")
|
||||
},
|
||||
getSessionAndUser: async (sessionToken) => {
|
||||
const variables: GetSessionAndUserQueryVariables = {
|
||||
sessionToken,
|
||||
}
|
||||
const { sessions } = await client.request<GetSessionAndUserQuery>(
|
||||
GetSessionAndUserDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const session = sessions?.[0]
|
||||
|
||||
if (!session) {
|
||||
return null
|
||||
}
|
||||
|
||||
const { user, ...sessionData } = session
|
||||
|
||||
return {
|
||||
session: formatDateConversion(
|
||||
useFragment(SessionFragmentDoc, sessionData),
|
||||
"expires",
|
||||
"toJS"
|
||||
),
|
||||
user: formatDateConversion(
|
||||
useFragment(UserFragmentDoc, user),
|
||||
"emailVerified",
|
||||
"toJS"
|
||||
),
|
||||
}
|
||||
},
|
||||
updateSession: async ({ sessionToken, ...data }) => {
|
||||
const variables: UpdateSessionMutationVariables = {
|
||||
sessionToken,
|
||||
data: formatDateConversion(data, "expires", "toDatabase"),
|
||||
}
|
||||
const { update_sessions } = await client.request<UpdateSessionMutation>(
|
||||
UpdateSessionDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const session = update_sessions?.returning?.[0]
|
||||
|
||||
if (!session) {
|
||||
return null
|
||||
}
|
||||
|
||||
return formatDateConversion(
|
||||
useFragment(SessionFragmentDoc, session),
|
||||
"expires",
|
||||
"toJS"
|
||||
)
|
||||
},
|
||||
deleteSession: async (sessionToken) => {
|
||||
const variables: DeleteSessionMutationVariables = {
|
||||
sessionToken,
|
||||
}
|
||||
const { delete_sessions } = await client.request<DeleteSessionMutation>(
|
||||
DeleteSessionDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const session = delete_sessions?.returning?.[0]
|
||||
|
||||
if (!session) {
|
||||
return null
|
||||
}
|
||||
|
||||
return formatDateConversion(
|
||||
useFragment(SessionFragmentDoc, session),
|
||||
"expires",
|
||||
"toJS"
|
||||
)
|
||||
},
|
||||
// Account
|
||||
linkAccount: async (data) => {
|
||||
const variables: CreateAccountMutationVariables = { data }
|
||||
const { insert_accounts_one } =
|
||||
await client.request<CreateAccountMutation>(
|
||||
CreateAccountDocument.toString(),
|
||||
variables
|
||||
)
|
||||
|
||||
if (!insert_accounts_one) {
|
||||
return
|
||||
}
|
||||
|
||||
const account = useFragment(
|
||||
AccountFragmentDoc,
|
||||
insert_accounts_one
|
||||
) as NonNullify<
|
||||
Omit<AccountFragment, "type"> & { type: "email" | "oauth" | "oidc" }
|
||||
>
|
||||
if (account) {
|
||||
return account as AdapterAccount
|
||||
}
|
||||
},
|
||||
unlinkAccount: async ({ providerAccountId, provider }) => {
|
||||
const variables: DeleteAccountMutationVariables = {
|
||||
provider,
|
||||
providerAccountId,
|
||||
}
|
||||
const { delete_accounts } = await client.request<DeleteAccountMutation>(
|
||||
DeleteAccountDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const account = delete_accounts?.returning[0]
|
||||
|
||||
if (!account) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const accountFragment = useFragment(
|
||||
AccountFragmentDoc,
|
||||
account
|
||||
) as NonNullify<
|
||||
Omit<AccountFragment, "type"> & { type: "email" | "oauth" | "oidc" }
|
||||
>
|
||||
if (accountFragment) {
|
||||
return accountFragment as AdapterAccount
|
||||
}
|
||||
},
|
||||
// Verification Token
|
||||
createVerificationToken: async (data) => {
|
||||
const variables: CreateVerificationTokenMutationVariables = {
|
||||
data: formatDateConversion(data, "expires", "toDatabase"),
|
||||
}
|
||||
const { insert_verification_tokens_one } =
|
||||
await client.request<CreateVerificationTokenMutation>(
|
||||
CreateVerificationTokenDocument.toString(),
|
||||
variables
|
||||
)
|
||||
|
||||
if (!insert_verification_tokens_one) {
|
||||
return null
|
||||
}
|
||||
|
||||
return formatDateConversion(
|
||||
useFragment(
|
||||
VerificationTokenFragmentDoc,
|
||||
insert_verification_tokens_one
|
||||
),
|
||||
"expires",
|
||||
"toJS"
|
||||
)
|
||||
},
|
||||
useVerificationToken: async ({ identifier, token }) => {
|
||||
const variables: DeleteVerificationTokenMutationVariables = {
|
||||
identifier,
|
||||
token,
|
||||
}
|
||||
const { delete_verification_tokens } =
|
||||
await client.request<DeleteVerificationTokenMutation>(
|
||||
DeleteVerificationTokenDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const verificationToken = delete_verification_tokens?.returning?.[0]
|
||||
|
||||
if (!verificationToken) {
|
||||
return null
|
||||
}
|
||||
|
||||
return formatDateConversion(
|
||||
useFragment(VerificationTokenFragmentDoc, verificationToken),
|
||||
"expires",
|
||||
"toJS"
|
||||
)
|
||||
},
|
||||
}
|
||||
}
|
||||
2
packages/adapter-hasura/src/lib/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
29
packages/adapter-hasura/src/queries/account.graphql
Normal file
@@ -0,0 +1,29 @@
|
||||
mutation CreateAccount($data: accounts_insert_input!) {
|
||||
insert_accounts_one(object: $data) {
|
||||
...Account
|
||||
}
|
||||
}
|
||||
|
||||
mutation DeleteAccount($provider: String!, $providerAccountId: String!) {
|
||||
delete_accounts(
|
||||
where: {
|
||||
provider: { _eq: $provider }
|
||||
providerAccountId: { _eq: $providerAccountId }
|
||||
}
|
||||
) {
|
||||
returning {
|
||||
...Account
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query GetAccount($provider: String!, $providerAccountId: String!) {
|
||||
accounts(
|
||||
where: {
|
||||
provider: { _eq: $provider }
|
||||
providerAccountId: { _eq: $providerAccountId }
|
||||
}
|
||||
) {
|
||||
...Account
|
||||
}
|
||||
}
|
||||
14
packages/adapter-hasura/src/queries/delete.graphql
Normal file
@@ -0,0 +1,14 @@
|
||||
mutation DeleteAll {
|
||||
delete_accounts(where: {}) {
|
||||
affected_rows
|
||||
}
|
||||
delete_sessions(where: {}) {
|
||||
affected_rows
|
||||
}
|
||||
delete_users(where: {}) {
|
||||
affected_rows
|
||||
}
|
||||
delete_verification_tokens(where: {}) {
|
||||
affected_rows
|
||||
}
|
||||
}
|
||||
35
packages/adapter-hasura/src/queries/fragments.graphql
Normal file
@@ -0,0 +1,35 @@
|
||||
fragment User on users {
|
||||
id
|
||||
name
|
||||
email
|
||||
image
|
||||
emailVerified
|
||||
}
|
||||
|
||||
fragment Session on sessions {
|
||||
id
|
||||
userId
|
||||
expires
|
||||
sessionToken
|
||||
}
|
||||
|
||||
fragment Account on accounts {
|
||||
id
|
||||
type
|
||||
scope
|
||||
userId
|
||||
id_token
|
||||
provider
|
||||
expires_at
|
||||
token_type
|
||||
access_token
|
||||
refresh_token
|
||||
session_state
|
||||
providerAccountId
|
||||
}
|
||||
|
||||
fragment VerificationToken on verification_tokens {
|
||||
token
|
||||
expires
|
||||
identifier
|
||||
}
|
||||
39
packages/adapter-hasura/src/queries/session.graphql
Normal file
@@ -0,0 +1,39 @@
|
||||
query GetSessionAndUser($sessionToken: String!) {
|
||||
sessions(where: { sessionToken: { _eq: $sessionToken } }) {
|
||||
...Session
|
||||
user {
|
||||
...User
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query GetSession($sessionToken: String!) {
|
||||
sessions_by_pk(sessionToken: $sessionToken) {
|
||||
...Session
|
||||
}
|
||||
}
|
||||
|
||||
mutation CreateSession($data: sessions_insert_input!) {
|
||||
insert_sessions_one(object: $data) {
|
||||
...Session
|
||||
}
|
||||
}
|
||||
|
||||
mutation UpdateSession($sessionToken: String, $data: sessions_set_input!) {
|
||||
update_sessions(
|
||||
where: { sessionToken: { _eq: $sessionToken } }
|
||||
_set: $data
|
||||
) {
|
||||
returning {
|
||||
...Session
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutation DeleteSession($sessionToken: String!) {
|
||||
delete_sessions(where: { sessionToken: { _eq: $sessionToken } }) {
|
||||
returning {
|
||||
...Session
|
||||
}
|
||||
}
|
||||
}
|
||||
29
packages/adapter-hasura/src/queries/user.graphql
Normal file
@@ -0,0 +1,29 @@
|
||||
query GetUser($id: uuid!) {
|
||||
users_by_pk(id: $id) {
|
||||
...User
|
||||
}
|
||||
}
|
||||
|
||||
query GetUsers($where: users_bool_exp!) {
|
||||
users(where: $where) {
|
||||
...User
|
||||
}
|
||||
}
|
||||
|
||||
mutation CreateUser($data: users_insert_input!) {
|
||||
insert_users_one(object: $data) {
|
||||
...User
|
||||
}
|
||||
}
|
||||
|
||||
mutation UpdateUser($id: uuid!, $data: users_set_input!) {
|
||||
update_users_by_pk(pk_columns: { id: $id }, _set: $data) {
|
||||
...User
|
||||
}
|
||||
}
|
||||
|
||||
mutation DeleteUser($id: uuid!) {
|
||||
delete_users_by_pk(id: $id) {
|
||||
...User
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
mutation CreateVerificationToken($data: verification_tokens_insert_input!) {
|
||||
insert_verification_tokens_one(object: $data) {
|
||||
...VerificationToken
|
||||
}
|
||||
}
|
||||
|
||||
mutation DeleteVerificationToken($identifier: String!, $token: String!) {
|
||||
delete_verification_tokens(
|
||||
where: { token: { _eq: $token }, identifier: { _eq: $identifier } }
|
||||
) {
|
||||
returning {
|
||||
...VerificationToken
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query GetVerificationToken($identifier: String!, $token: String!) {
|
||||
verification_tokens(
|
||||
where: { token: { _eq: $token }, identifier: { _eq: $identifier } }
|
||||
) {
|
||||
...VerificationToken
|
||||
}
|
||||
}
|
||||
47
packages/adapter-hasura/src/utils.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
export type NonNullify<T> = {
|
||||
[K in keyof T]: T[K] extends null | infer U ? U : T[K]
|
||||
}
|
||||
|
||||
type FormatToJS<T, K extends keyof T> = T[K] extends string
|
||||
? Omit<T, K> & Record<K, Date>
|
||||
: Omit<T, K> & Record<K, Date | null>
|
||||
|
||||
type FormatToDatabase<T, K extends keyof T> = T[K] extends Date
|
||||
? Omit<T, K> & Record<K, string>
|
||||
: Omit<T, K> & Record<K, string | null>
|
||||
|
||||
export function formatDateConversion<T, K extends keyof T>(
|
||||
object: T,
|
||||
key: K,
|
||||
direction: "toJS"
|
||||
): FormatToJS<T, K>
|
||||
|
||||
export function formatDateConversion<T, K extends keyof T>(
|
||||
object: T,
|
||||
key: K,
|
||||
direction: "toDatabase"
|
||||
): FormatToDatabase<T, K>
|
||||
|
||||
export function formatDateConversion<T, K extends keyof T>(
|
||||
object: T,
|
||||
key: K,
|
||||
direction: "toJS" | "toDatabase"
|
||||
) {
|
||||
if (!object) return object
|
||||
|
||||
const value = object[key]
|
||||
|
||||
if (value === undefined) return object
|
||||
|
||||
if (direction === "toJS") {
|
||||
return {
|
||||
...object,
|
||||
[key]: value ? new Date(value as string) : null,
|
||||
} as FormatToJS<T, K>
|
||||
} else {
|
||||
return {
|
||||
...object,
|
||||
[key]: value ? (value as unknown as Date).toISOString() : null,
|
||||
} as FormatToDatabase<T, K>
|
||||
}
|
||||
}
|
||||
110
packages/adapter-hasura/tests/index.test.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import { runBasicTests } from "@auth/adapter-test"
|
||||
import { GraphQLClient } from "graphql-request"
|
||||
import { HasuraAdapter } from "../src"
|
||||
import { useFragment } from "../src/lib"
|
||||
import {
|
||||
AccountFragmentDoc,
|
||||
DeleteAllDocument,
|
||||
GetAccountDocument,
|
||||
GetSessionDocument,
|
||||
GetUserDocument,
|
||||
GetVerificationTokenDocument,
|
||||
SessionFragmentDoc,
|
||||
UserFragmentDoc,
|
||||
VerificationTokenFragmentDoc,
|
||||
} from "../src/lib/graphql"
|
||||
import type {
|
||||
GetAccountQuery,
|
||||
GetAccountQueryVariables,
|
||||
GetSessionQuery,
|
||||
GetSessionQueryVariables,
|
||||
GetUserQuery,
|
||||
GetUserQueryVariables,
|
||||
GetVerificationTokenQuery,
|
||||
GetVerificationTokenQueryVariables,
|
||||
} from "../src/lib/graphql"
|
||||
import { formatDateConversion } from "../src/utils"
|
||||
|
||||
const client = new GraphQLClient("http://localhost:8080/v1/graphql", {
|
||||
headers: {
|
||||
"x-hasura-admin-secret": "myadminsecretkey",
|
||||
},
|
||||
})
|
||||
|
||||
runBasicTests({
|
||||
adapter: HasuraAdapter({
|
||||
adminSecret: "myadminsecretkey",
|
||||
endpoint: "http://localhost:8080/v1/graphql",
|
||||
}),
|
||||
db: {
|
||||
connect: async () => {
|
||||
await client.request(DeleteAllDocument.toString())
|
||||
},
|
||||
disconnect: async () => {
|
||||
await client.request(DeleteAllDocument.toString())
|
||||
},
|
||||
user: async (id) => {
|
||||
const variables: GetUserQueryVariables = { id }
|
||||
const { users_by_pk } = await client.request<GetUserQuery>(
|
||||
GetUserDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const user = useFragment(UserFragmentDoc, users_by_pk)
|
||||
|
||||
return user ? formatDateConversion(user, "emailVerified", "toJS") : null
|
||||
},
|
||||
account: async ({ providerAccountId, provider }) => {
|
||||
const variables: GetAccountQueryVariables = {
|
||||
provider,
|
||||
providerAccountId,
|
||||
}
|
||||
const { accounts } = await client.request<GetAccountQuery>(
|
||||
GetAccountDocument.toString(),
|
||||
variables
|
||||
)
|
||||
|
||||
const account = useFragment(AccountFragmentDoc, accounts?.[0])
|
||||
return account ?? null
|
||||
},
|
||||
session: async (sessionToken) => {
|
||||
const variables: GetSessionQueryVariables = {
|
||||
sessionToken,
|
||||
}
|
||||
const { sessions_by_pk } = await client.request<GetSessionQuery>(
|
||||
GetSessionDocument.toString(),
|
||||
variables
|
||||
)
|
||||
if (!sessions_by_pk) {
|
||||
return null
|
||||
}
|
||||
|
||||
return formatDateConversion(
|
||||
useFragment(SessionFragmentDoc, sessions_by_pk),
|
||||
"expires",
|
||||
"toJS"
|
||||
)
|
||||
},
|
||||
verificationToken: async ({ identifier, token }) => {
|
||||
const variables: GetVerificationTokenQueryVariables = {
|
||||
identifier,
|
||||
token,
|
||||
}
|
||||
const { verification_tokens } =
|
||||
await client.request<GetVerificationTokenQuery>(
|
||||
GetVerificationTokenDocument.toString(),
|
||||
variables
|
||||
)
|
||||
const verificationToken = verification_tokens?.[0]
|
||||
|
||||
if (!verificationToken) {
|
||||
return null
|
||||
}
|
||||
|
||||
return formatDateConversion(
|
||||
useFragment(VerificationTokenFragmentDoc, verificationToken),
|
||||
"expires",
|
||||
"toJS"
|
||||
)
|
||||
},
|
||||
},
|
||||
})
|
||||
14
packages/adapter-hasura/tests/test.sh
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Start Hasura
|
||||
docker-compose up -d
|
||||
|
||||
echo "Waiting 5 sec for Hasura to start..."
|
||||
sleep 5
|
||||
|
||||
# Always stop container, but exit with 1 when tests are failing
|
||||
if npx jest;then
|
||||
docker compose down -v
|
||||
else
|
||||
docker compose down -v && exit 1
|
||||
fi
|
||||
21
packages/adapter-hasura/tsconfig.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"extends": "@auth/tsconfig/tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"baseUrl": ".",
|
||||
"isolatedModules": true,
|
||||
"target": "ES2020",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": ".",
|
||||
"rootDir": "src",
|
||||
"skipDefaultLibCheck": true,
|
||||
"strictNullChecks": true,
|
||||
"stripInternal": true,
|
||||
"declarationMap": true,
|
||||
"declaration": true,
|
||||
"verbatimModuleSyntax": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["*.js", "*.d.ts"]
|
||||
}
|
||||
@@ -1,12 +1,11 @@
|
||||
diff --git a/dist/publish.js b/dist/publish.js
|
||||
index 9ff19090801bbd6791f6ad29a0ae27bc77bd14fd..50c042c08abd010ed580d76e25cbe4af493fe56b 100644
|
||||
index 09a0c10584159beefa7a915ad92d46601da5ad45..01959c09b98ef8e7b1c2c6c481add782457e6921 100644
|
||||
--- a/dist/publish.js
|
||||
+++ b/dist/publish.js
|
||||
@@ -53,8 +53,9 @@ export async function publish(packages, options) {
|
||||
log.info(`Creating git tag.`);
|
||||
@@ -55,7 +55,9 @@ export async function publish(packages, options) {
|
||||
execSync(`git tag ${gitTag}`);
|
||||
execSync("git push --tags");
|
||||
- log.info(`Creating GitHub release notes.`);
|
||||
log.info(`Creating GitHub release notes.`);
|
||||
- execSync(`gh release create ${gitTag} --notes '${changelog}'`);
|
||||
+ const prerelease = name.startsWith("@auth") ? "--prerelease " : ""
|
||||
+ console.log(`Creating GitHub release notes${prerelease ? " (as prerelease)" : ""}`);
|
||||
2959
pnpm-lock.yaml
generated
@@ -91,6 +91,7 @@
|
||||
"@auth/dynamodb-adapter#build",
|
||||
"@auth/fauna-adapter#build",
|
||||
"@auth/firebase-adapter#build",
|
||||
"@auth/hasura-adapter#build",
|
||||
"@auth/kysely-adapter#build",
|
||||
"@auth/mikro-orm-adapter#build",
|
||||
"@auth/mongodb-adapter#build",
|
||||
@@ -121,6 +122,7 @@
|
||||
"@auth/dynamodb-adapter#build",
|
||||
"@auth/fauna-adapter#build",
|
||||
"@auth/firebase-adapter#build",
|
||||
"@auth/hasura-adapter#build",
|
||||
"@auth/kysely-adapter#build",
|
||||
"@auth/mikro-orm-adapter#build",
|
||||
"@auth/mongodb-adapter#build",
|
||||
|
||||