From 67f84c61ab447cf9ecef8fefd0aac3c6ebf2d2ef Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Fri, 18 Apr 2025 17:26:14 +0200 Subject: [PATCH 01/36] feat: implement better-auth & portal.sh --- docs/.gitignore | 1 + docs/app/api/auth/[...all]/route.ts | 4 + docs/app/api/auth/[...nextauth]/route.ts | 2 - docs/app/confirmation/page.tsx | 10 + docs/app/portal/page.tsx | 19 ++ docs/app/signup/page.tsx | 58 ++++ docs/auth.ts | 195 +++++--------- docs/components/AuthNavButton.tsx | 8 +- docs/components/example/ExampleBlock.tsx | 6 +- docs/components/example/index.tsx | 11 +- docs/package.json | 11 +- docs/pages/_app.tsx | 3 - docs/util/auth-client.ts | 7 + docs/util/authUtil.tsx | 16 -- package.json | 3 +- pnpm-lock.yaml | 325 ++++++++++++++++++++++- 16 files changed, 500 insertions(+), 179 deletions(-) create mode 100644 docs/app/api/auth/[...all]/route.ts delete mode 100644 docs/app/api/auth/[...nextauth]/route.ts create mode 100644 docs/app/confirmation/page.tsx create mode 100644 docs/app/portal/page.tsx create mode 100644 docs/app/signup/page.tsx create mode 100644 docs/util/auth-client.ts delete mode 100644 docs/util/authUtil.tsx diff --git a/docs/.gitignore b/docs/.gitignore index 1dd45b2022..af673ac194 100644 --- a/docs/.gitignore +++ b/docs/.gitignore @@ -37,3 +37,4 @@ next-env.d.ts # Sentry Config File .env.sentry-build-plugin +*.db \ No newline at end of file diff --git a/docs/app/api/auth/[...all]/route.ts b/docs/app/api/auth/[...all]/route.ts new file mode 100644 index 0000000000..a1953d1270 --- /dev/null +++ b/docs/app/api/auth/[...all]/route.ts @@ -0,0 +1,4 @@ +import { auth } from "../../../../auth"; +import { toNextJsHandler } from "better-auth/next-js"; + +export const { POST, GET } = toNextJsHandler(auth); \ No newline at end of file diff --git a/docs/app/api/auth/[...nextauth]/route.ts b/docs/app/api/auth/[...nextauth]/route.ts deleted file mode 100644 index 62da3d047a..0000000000 --- a/docs/app/api/auth/[...nextauth]/route.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { GET, POST } from "../../../../auth"; -export const runtime = "edge"; // optional diff --git a/docs/app/confirmation/page.tsx b/docs/app/confirmation/page.tsx new file mode 100644 index 0000000000..939e55c7c3 --- /dev/null +++ b/docs/app/confirmation/page.tsx @@ -0,0 +1,10 @@ + +export default function Page({ + searchParams: { checkoutId }, +}: { + searchParams: { + checkoutId: string + } +}) { + return
Thank you! Your checkout is now being processed.
+} \ No newline at end of file diff --git a/docs/app/portal/page.tsx b/docs/app/portal/page.tsx new file mode 100644 index 0000000000..5c97ff74e9 --- /dev/null +++ b/docs/app/portal/page.tsx @@ -0,0 +1,19 @@ +"use client"; + +import { useSession } from "@/util/auth-client"; + +// Just shows session info +export default function Me() { + const { data: session } = useSession(); + + if (!session) { + return
Not authenticated
; + } + + return ( +
+

Welcome {session.user.name}

+
{JSON.stringify(session, null, 2)}
+
+ ); +}; \ No newline at end of file diff --git a/docs/app/signup/page.tsx b/docs/app/signup/page.tsx new file mode 100644 index 0000000000..1ec8a359c6 --- /dev/null +++ b/docs/app/signup/page.tsx @@ -0,0 +1,58 @@ +"use client"; + +import { signUp } from "@/util/auth-client"; +import { useState } from "react"; + +// TODO Do we want email & password signin? or just social? +export default function Register() { + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + + const handleRegister = async () => { + await signUp.email({ + email, + password, + name, + }); + }; + + return ( +
+

Register

+ setName(e.target.value)} + /> + setEmail(e.target.value)} + /> + setPassword(e.target.value)} + /> + +
+ ); +}; \ No newline at end of file diff --git a/docs/auth.ts b/docs/auth.ts index b0e8d09cdf..fc072c8746 100644 --- a/docs/auth.ts +++ b/docs/auth.ts @@ -1,138 +1,65 @@ -import NextAuth from "next-auth"; -import GitHub from "next-auth/providers/github"; +import { betterAuth } from "better-auth"; +import Database from "better-sqlite3"; +import { polar } from "@polar-sh/better-auth"; +import { Polar } from "@polar-sh/sdk"; +import { openAPI } from "better-auth/plugins" -export const { - handlers: { GET, POST }, - auth, - signIn, - signOut, -} = NextAuth({ - callbacks: { - signIn: async (params) => { - if (params.profile!.sponsorInfo) { - // user is sponsor - return true; - } - // user is signed in to github, but not a sponsor. - // TODO: We could redirect to pricing page here - return true; - // return "https://www.blocknotejs.org/pricing"; - }, - // https://authjs.dev/guides/extending-the-session - jwt({ token, user }) { - if (user) { - // User is available during sign-in - token.sponsorInfo = (user as any).sponsorInfo; - } - return token; - }, - session: async (params) => { - (params.session.user as any).sponsorInfo = ( - params.token as any - ).sponsorInfo; - return params.session; - }, +export const client = new Polar({ + accessToken: process.env.POLAR_ACCESS_TOKEN, + // Use 'sandbox' if you're using the Polar Sandbox environment + // Remember that access tokens, products, etc. are completely separated between environments. + // Access tokens obtained in Production are for instance not usable in the Sandbox environment. + server: 'sandbox' +}); + +export const auth = betterAuth({ + emailAndPassword: { + enabled: true }, - providers: [ - // copied from https://github.com/nextauthjs/next-auth/blob/234a150e2cac3bc62a9162fa00ed7cb16a105244/packages/core/src/providers/github.ts#L2, - // but with extra sponsorship api call - GitHub({ - userinfo: { - url: `https://api.github.com/user`, - async request({ tokens, provider }: any) { - const profile = await fetch(provider.userinfo?.url as URL, { - headers: { - Authorization: `Bearer ${tokens.access_token}`, - "User-Agent": "authjs", + socialProviders: { + github: { + clientId: process.env.AUTH_GITHUB_ID as string, + clientSecret: process.env.AUTH_GITHUB_SECRET as string + }, + }, + database: new Database("./sqlite.db"), + plugins: [ + // Just temporary for testing + // Serves on http://localhost:3000/api/auth/reference + openAPI(), + polar({ + client, + // Enable automatic Polar Customer creation on signup + createCustomerOnSignUp: true, + // http://localhost:3000/api/auth/portal + enableCustomerPortal: true, + // Configure checkout + checkout: { + enabled: true, + products: [ + { + productId: "8049f66f-fd0a-4690-a0aa-442ac5b03040", // ID of Product from Polar Dashboard + slug: "business" // Custom slug for easy reference in Checkout URL, e.g. /checkout/pro + // http://localhost:3000/api/auth/checkout/business + }, + { + productId: 'ab70fea5-172c-4aac-b3fc-0824f2a5b670', + slug: 'starter' + // http://localhost:3000/api/auth/checkout/starter + } + ], + // TODO set to actual page (welcome screen) + successUrl: "/success?checkout_id={CHECKOUT_ID}" }, - }).then(async (res) => await res.json()); - - if (!profile.email) { - // If the user does not have a public email, get another via the GitHub API - // See https://docs.github.com/en/rest/users/emails#list-public-email-addresses-for-the-authenticated-user - const res = await fetch(`https://api.github.com/user/emails`, { - headers: { - Authorization: `Bearer ${tokens.access_token}`, - "User-Agent": "authjs", - }, - }); - - if (res.ok) { - const emails: any[] = await res.json(); - profile.email = ( - emails.find((e) => e.primary) ?? emails[0] - ).email; + // Incoming Webhooks handler will be installed at /polar/webhooks + webhooks: { + // webhooks have to be publicly accessible + // ngrok http http://localhost:3000 + secret: process.env.POLAR_WEBHOOK_SECRET as string, + onPayload: async (payload) => { + console.log(payload) + }, } - } - - const resSponsor = await fetch(`https://api.github.com/graphql`, { - method: "POST", - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${tokens.access_token}`, - }, - // organization(login:"TypeCellOS") { - // user(login:"YousefED") { - body: JSON.stringify({ - query: `{ - user(login:"YousefED") { - sponsorshipForViewerAsSponsor(activeOnly:false) { - isActive, - tier { - name - monthlyPriceInDollars - } - } - } - }`, - }), - }); - - if (resSponsor.ok) { - // Mock data. TODO: disable and test actial data - // profile.sponsorInfo = { - // isActive: true, - // tier: { - // name: "test", - // monthlyPriceInDollars: 100, - // }, - // }; - // use API data: - - const data = await resSponsor.json(); - // eslint-disable-next-line no-console - console.log("sponsor data", data); - - // { - // "data": { - // "user": { - // "sponsorshipForViewerAsSponsor": { - // "isActive": true, - // "tier": { - // "name": "$90 a month", - // "monthlyPriceInDollars": 90 - // } - // } - // } - // } - // } - - profile.sponsorInfo = data.data.user.sponsorshipForViewerAsSponsor; - } - - return profile; - }, - }, - profile: (profile) => { - return { - id: profile.id.toString(), - name: profile.name ?? profile.login, - email: profile.email, - image: profile.avatar_url, - username: profile.login, - sponsorInfo: profile.sponsorInfo, - }; - }, - }), - ], -}); + }) + ] +}); \ No newline at end of file diff --git a/docs/components/AuthNavButton.tsx b/docs/components/AuthNavButton.tsx index 568e2249ea..57cba5e7f9 100644 --- a/docs/components/AuthNavButton.tsx +++ b/docs/components/AuthNavButton.tsx @@ -1,13 +1,13 @@ import { Menu, Transition } from "@headlessui/react"; import clsx from "clsx"; -import { signOut, useSession } from "next-auth/react"; +import { authClient } from "@/util/auth-client"; import Image from "next/image"; import { ReactElement, ReactNode } from "react"; export function AuthNavButton(props: any) { - const session = useSession(); + const session = authClient.useSession(); - return session.status === "authenticated" ? ( + return session.data ? ( @@ -22,7 +22,7 @@ export function AuthNavButton(props: any) { {" "} diff --git a/docs/components/example/index.tsx b/docs/components/example/index.tsx index 2db9d6947e..a1f5ee4e3d 100644 --- a/docs/components/example/index.tsx +++ b/docs/components/example/index.tsx @@ -1,20 +1,23 @@ import { useSession } from "next-auth/react"; -import { getProLevel } from "../../util/authUtil"; +// import { authClient } from "../../util/auth-client"; import { examples } from "./generated/exampleComponents.gen"; +import { authClient } from "@/util/auth-client"; export function Example(props: { name: keyof typeof examples }) { - const session = useSession(); + // authClient. + const session = authClient.useSession() + // const session = useSession(); const example = examples[props.name]; if (!example) { throw new Error(`Example ${props.name} not found`); } const ExampleWithCode = example.ExampleWithCode; - const userStatus = getProLevel(session); + // const userStatus = getProLevel(session); return ( ); } diff --git a/docs/package.json b/docs/package.json index a5ff4a43c4..420b02f74a 100644 --- a/docs/package.json +++ b/docs/package.json @@ -10,8 +10,8 @@ }, "dependencies": { "@blocknote/ariakit": "workspace:^", - "@blocknote/core": "workspace:^", "@blocknote/code-block": "workspace:^", + "@blocknote/core": "workspace:^", "@blocknote/mantine": "workspace:^", "@blocknote/react": "workspace:^", "@blocknote/shadcn": "workspace:^", @@ -20,9 +20,15 @@ "@heroicons/react": "^2.1.4", "@mantine/core": "^7.10.1", "@next/bundle-analyzer": "^14.1.0", + "@polar-sh/better-auth": "0.1.0", + "@polar-sh/nextjs": "0.3.23", + "@polar-sh/sdk": "0.32.10", "@sentry/nextjs": "9.4.0", + "@types/better-sqlite3": "7.6.13", "@vercel/analytics": "^1.2.2", "@vercel/og": "^0.6.2", + "better-auth": "1.2.7", + "better-sqlite3": "11.9.1", "classnames": "2.3.2", "clsx": "^2.1.0", "framer-motion": "^10.16.16", @@ -37,7 +43,8 @@ "react-github-btn": "^1.4.0", "react-icons": "^5.2.1", "y-partykit": "^0.0.25", - "yjs": "^13.6.15" + "yjs": "^13.6.15", + "zod": "^3.23.8" }, "devDependencies": { "@types/node": "^20", diff --git a/docs/pages/_app.tsx b/docs/pages/_app.tsx index c2888af87e..24644c1eb0 100644 --- a/docs/pages/_app.tsx +++ b/docs/pages/_app.tsx @@ -1,6 +1,5 @@ // import "../custom.css"; import { Analytics } from "@vercel/analytics/react"; -import { SessionProvider } from "next-auth/react"; import type { AppProps } from "next/app"; import { type ReactNode } from "react"; import "../styles.css"; @@ -16,10 +15,8 @@ export default function Nextra({ Component, pageProps }: NextraAppProps) { return ( <> - - ); } diff --git a/docs/util/auth-client.ts b/docs/util/auth-client.ts new file mode 100644 index 0000000000..314e890ab5 --- /dev/null +++ b/docs/util/auth-client.ts @@ -0,0 +1,7 @@ +import { createAuthClient } from "better-auth/react" +export const authClient = createAuthClient({ + /** The base URL of the server (optional if you're using the same domain) */ + baseURL: "http://localhost:3000" +}) + +export const { useSession, signIn, signOut, signUp } = authClient \ No newline at end of file diff --git a/docs/util/authUtil.tsx b/docs/util/authUtil.tsx deleted file mode 100644 index 8c265b0dc2..0000000000 --- a/docs/util/authUtil.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import type { useSession } from "next-auth/react"; - -export function getProLevel( - session: ReturnType, -): "business" | "starter" | "free" | undefined { - if (session.status !== "authenticated") { - return undefined; - } - - const sponsorInfo = (session?.data?.user as any)?.sponsorInfo; - if (!sponsorInfo?.isActive) { - return "free"; - } - - return sponsorInfo.tier.monthlyPriceInDollars > 100 ? "business" : "starter"; -} diff --git a/package.json b/package.json index a4a34feee3..9f8c9ba0ec 100644 --- a/package.json +++ b/package.json @@ -25,7 +25,8 @@ "@sentry/cli", "canvas", "esbuild", - "nx" + "nx", + "better-sqlite3" ] }, "packageManager": "pnpm@10.7.1+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4a82205cdc..b559c56a90 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -83,15 +83,33 @@ importers: '@next/bundle-analyzer': specifier: ^14.1.0 version: 14.2.26 + '@polar-sh/better-auth': + specifier: 0.1.0 + version: 0.1.0(@polar-sh/sdk@0.32.10(zod@3.24.2))(better-auth@1.2.7) + '@polar-sh/nextjs': + specifier: 0.3.23 + version: 0.3.23(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(zod@3.24.2) + '@polar-sh/sdk': + specifier: 0.32.10 + version: 0.32.10(zod@3.24.2) '@sentry/nextjs': specifier: 9.4.0 version: 9.4.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.98.0) + '@types/better-sqlite3': + specifier: 7.6.13 + version: 7.6.13 '@vercel/analytics': specifier: ^1.2.2 version: 1.5.0(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) '@vercel/og': specifier: ^0.6.2 version: 0.6.5 + better-auth: + specifier: 1.2.7 + version: 1.2.7 + better-sqlite3: + specifier: 11.9.1 + version: 11.9.1 classnames: specifier: 2.3.2 version: 2.3.2 @@ -137,6 +155,9 @@ importers: yjs: specifier: ^13.6.15 version: 13.6.24 + zod: + specifier: ^3.23.8 + version: 3.24.2 devDependencies: '@types/node': specifier: ^20 @@ -4714,6 +4735,12 @@ packages: '@base2/pretty-print-object@1.0.1': resolution: {integrity: sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==} + '@better-auth/utils@0.2.4': + resolution: {integrity: sha512-ayiX87Xd5sCHEplAdeMgwkA0FgnXsEZBgDn890XHHwSWNqqRZDYOq3uj2Ei2leTv1I2KbG5HHn60Ah1i2JWZjQ==} + + '@better-fetch/fetch@1.1.18': + resolution: {integrity: sha512-rEFOE1MYIsBmoMJtQbl32PGHHXuG2hDxvEd7rUHE0vCBoFQVSDqaVs9hkZEtHCxRoY+CljXKFCOuJ8uxqw1LcA==} + '@braintree/sanitize-url@6.0.4': resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==} @@ -5348,6 +5375,9 @@ packages: peerDependencies: react: '>= 16 || ^19.0.0-rc' + '@hexagon/base64@1.1.28': + resolution: {integrity: sha512-lhqDEAvWixy3bZ+UOYbPwUbBkwBq5C1LAJ/xPC8Oi+lL54oyakv/npbA0aU2hgCsx/1NUd4IBvV03+aUBWxerw==} + '@hocuspocus/common@2.15.2': resolution: {integrity: sha512-wU1wxXNnQQMXyeL3mdSDYiQsm/r/QyJVjjQhF7sUBrLnjdsN7bA1cvfcSvJBr1ymrMSeYRmUL3UlQmEHEOaP7w==} @@ -5523,6 +5553,9 @@ packages: '@juggle/resize-observer@3.4.0': resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} + '@levischuck/tiny-cbor@0.2.11': + resolution: {integrity: sha512-llBRm4dT4Z89aRsm6u2oEZ8tfwL/2l6BwpZ7JcyieouniDECM5AqNgr/y08zalEIvW3RSK4upYyybDcmjXqAow==} + '@lifeomic/attempt@3.1.0': resolution: {integrity: sha512-QZqem4QuAnAyzfz+Gj5/+SLxqwCAw2qmt7732ZXodr6VDWGeYLG6w1i/vYLa55JQM9wRuBKLmXmiZ2P0LtE5rw==} @@ -5838,6 +5871,13 @@ packages: '@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1': resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} + '@noble/ciphers@0.6.0': + resolution: {integrity: sha512-mIbq/R9QXk5/cTfESb1OKtyFnk7oc1Om/8onA1158K9/OZUQFDEVy55jVTato+xmp3XX6F6Qh0zz0Nc1AxAlRQ==} + + '@noble/hashes@1.7.2': + resolution: {integrity: sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==} + engines: {node: ^14.21.3 || >=16} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -6127,6 +6167,21 @@ packages: '@panva/hkdf@1.2.1': resolution: {integrity: sha512-6oclG6Y3PiDFcoyk8srjLfVKyMfVCKJ27JwNPViuXziFpmdz+MZnZN/aKY0JGXgYuO/VghU0jcOAZgWXZ1Dmrw==} + '@peculiar/asn1-android@2.3.16': + resolution: {integrity: sha512-a1viIv3bIahXNssrOIkXZIlI2ePpZaNmR30d4aBL99mu2rO+mT9D6zBsp7H6eROWGtmwv0Ionp5olJurIo09dw==} + + '@peculiar/asn1-ecc@2.3.15': + resolution: {integrity: sha512-/HtR91dvgog7z/WhCVdxZJ/jitJuIu8iTqiyWVgRE9Ac5imt2sT/E4obqIVGKQw7PIy+X6i8lVBoT6wC73XUgA==} + + '@peculiar/asn1-rsa@2.3.15': + resolution: {integrity: sha512-p6hsanvPhexRtYSOHihLvUUgrJ8y0FtOM97N5UEpC+VifFYyZa0iZ5cXjTkZoDwxJ/TTJ1IJo3HVTB2JJTpXvg==} + + '@peculiar/asn1-schema@2.3.15': + resolution: {integrity: sha512-QPeD8UA8axQREpgR5UTAfu2mqQmm97oUqahDtNdBcfj3qAnoXzFdQW+aNf/tD2WVXF8Fhmftxoj0eMIT++gX2w==} + + '@peculiar/asn1-x509@2.3.15': + resolution: {integrity: sha512-0dK5xqTqSLaxv1FHXIcd4Q/BZNuopg+u1l23hT9rOmQ1g4dNtw0g/RnEi+TboB0gOwGtrWn269v27cMgchFIIg==} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -6145,6 +6200,32 @@ packages: engines: {node: '>=18'} hasBin: true + '@polar-sh/adapter-utils@0.1.15': + resolution: {integrity: sha512-hYHdvFRAaV8Z8FrPYZX2uTxEVwHNKy/woLFDn5SSxPo+Uqmrog7a/v8XZN7T9Sz8UePTFRUY6m+QbEBAPjDK9A==} + + '@polar-sh/better-auth@0.1.0': + resolution: {integrity: sha512-Gw67CoLoPIelwpa+BR7cMZb/i8MJP2g2E93MhEl26OuWGt8xNbAqzXasDoyUgZQ/r6ZwwdYPRzUqMWmwnRTEqQ==} + engines: {node: '>=16'} + peerDependencies: + '@polar-sh/sdk': ^0.32.11 + better-auth: ^1.2.0 + + '@polar-sh/nextjs@0.3.23': + resolution: {integrity: sha512-AiQDffXnpaydBeCghDsBaGHTanUEG2039JbukDCBbbbzgbjdl1NpgpmPh62le+Fl0f+s21qU+ZCnwEeJJelrTg==} + engines: {node: '>=16'} + peerDependencies: + next: ^15.0.0 || ^15.2.0-canary.* + + '@polar-sh/sdk@0.32.10': + resolution: {integrity: sha512-k7og3L1RP7kTRFVSxiVF4GIkTy/JQwfUY4D1aqSEnj3OtR13NjHsAW2Rb6bEJDuws2/bzfAVQvbQTxf+VsmK9A==} + hasBin: true + peerDependencies: + '@modelcontextprotocol/sdk': ^1.5.0 + zod: '>= 3' + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + '@polka/url@1.0.0-next.28': resolution: {integrity: sha512-8LduaNlMZGwdZ6qWrKlfa+2M4gahzFkprZiAt2TF8uS0qQgBizKXpXURqvTJ4WtmupWxaLqjRb2UCTe72mu+Aw==} @@ -6878,6 +6959,13 @@ packages: '@sideway/pinpoint@2.0.0': resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + '@simplewebauthn/browser@13.1.0': + resolution: {integrity: sha512-WuHZ/PYvyPJ9nxSzgHtOEjogBhwJfC8xzYkPC+rR/+8chl/ft4ngjiK8kSU5HtRJfczupyOh33b25TjYbvwAcg==} + + '@simplewebauthn/server@13.1.1': + resolution: {integrity: sha512-1hsLpRHfSuMB9ee2aAdh0Htza/X3f4djhYISrggqGe3xopNjOcePiSDkDDoPzDYaaMCrbqGP1H2TYU7bgL9PmA==} + engines: {node: '>=20.0.0'} + '@sinclair/typebox@0.27.8': resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} @@ -7093,6 +7181,9 @@ packages: resolution: {integrity: sha512-JtaY3FxmD+te+KSI2FJuEcfNC9T/DGGVf551babM7fAaXhjJUt7oSYurH1Devxd2+BOSUACCgt3buinx4UnmEA==} engines: {node: '>=18.0.0'} + '@stablelib/base64@1.0.1': + resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} + '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} @@ -7284,6 +7375,9 @@ packages: '@types/babel__traverse@7.20.7': resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} + '@types/better-sqlite3@7.6.13': + resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} + '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} @@ -8051,6 +8145,10 @@ packages: as-table@1.0.55: resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + asn1js@3.0.6: + resolution: {integrity: sha512-UOCGPYbl0tv8+006qks/dTgV9ajs97X2p0FAbyS2iyCRrmLSRolDaHdp+v/CLgnzHc3fVB+CwYiUmei7ndFcgA==} + engines: {node: '>=12.0.0'} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -8146,6 +8244,15 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + better-auth@1.2.7: + resolution: {integrity: sha512-2hCB263GSrgetsMUZw8vv9O1e4S4AlYJW3P4e8bX9u3Q3idv4u9BzDFCblpTLuL4YjYovghMCN0vurAsctXOAQ==} + + better-call@1.0.8: + resolution: {integrity: sha512-/PV8JLqDRUN7JyBPbklVsS/8E4SO3pnf8hbpa8B7xrBrr+BBYpeOAxoqtnsyk/pRs35vNB4MZx8cn9dBuNlLDA==} + + better-sqlite3@11.9.1: + resolution: {integrity: sha512-Ba0KR+Fzxh2jDRhdg6TSH0SJGzb8C0aBY4hR8w8madIdIzzC6Y1+kx5qR6eS1Z+Gy20h6ZU28aeyg0z1VIrShQ==} + bidi-js@1.0.3: resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} @@ -8156,6 +8263,9 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -8779,6 +8889,9 @@ packages: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + delaunator@5.0.1: resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} @@ -9257,6 +9370,9 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-sha256@1.3.0: + resolution: {integrity: sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==} + fast-uri@3.0.6: resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} @@ -9289,6 +9405,9 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} @@ -10165,6 +10284,10 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} + kysely@0.27.6: + resolution: {integrity: sha512-FIyV/64EkKhJmjgC0g2hygpBv5RNWVPyNCqSAD7eTCv6eFWNIi4PN1UvdSJGicN/o35bnevgis4Y0UDC0qi8jQ==} + engines: {node: '>=14.0.0'} + language-subtag-registry@0.3.23: resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} @@ -10739,6 +10862,10 @@ packages: engines: {node: ^18 || >=20} hasBin: true + nanostores@0.11.4: + resolution: {integrity: sha512-k1oiVNN4hDK8NcNERSZLQiMfRzEGtfnvZvdBvey3SQbgn8Dcrk0h1I6vpxApjb10PFUflZrgJ2WEZyJQ+5v7YQ==} + engines: {node: ^18.0.0 || >=20.0.0} + napi-build-utils@2.0.0: resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} @@ -11462,6 +11589,13 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + + pvutils@1.1.3: + resolution: {integrity: sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==} + engines: {node: '>=6.0.0'} + querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} @@ -11822,6 +11956,9 @@ packages: rope-sequence@1.3.4: resolution: {integrity: sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==} + rou3@0.5.1: + resolution: {integrity: sha512-OXMmJ3zRk2xeXFGfA3K+EOPHC5u7RDFG7lIOx0X1pdnhUkI8MdVrbV+sNsD80ElpUZ+MRHdyxPnFthq9VHs8uQ==} + rrweb-cssom@0.6.0: resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==} @@ -11920,6 +12057,9 @@ packages: set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-cookie-parser@2.7.1: + resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -12087,6 +12227,9 @@ packages: stacktracey@2.1.8: resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} + standardwebhooks@1.0.0: + resolution: {integrity: sha512-BbHGOQK9olHPMvQNHWul6MYlrRTAOKn03rOe4A8O3CLWhNf4YHBqq2HJKKC+sfqpxiBY52pNeesD6jIiLDz8jg==} + std-env@3.8.1: resolution: {integrity: sha512-vj5lIj3Mwf9D79hBkltk5qmkFI+biIKWS2IBxEyEU3AX1tUf7AoL8nSazCOiiqQsGKIq01SClsKEzweu34uwvA==} @@ -12477,6 +12620,9 @@ packages: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} @@ -14415,6 +14561,13 @@ snapshots: '@base2/pretty-print-object@1.0.1': {} + '@better-auth/utils@0.2.4': + dependencies: + typescript: 5.8.2 + uncrypto: 0.1.3 + + '@better-fetch/fetch@1.1.18': {} + '@braintree/sanitize-url@6.0.4': {} '@cloudflare/workerd-darwin-64@1.20240129.0': @@ -14848,6 +15001,8 @@ snapshots: dependencies: react: 18.3.1 + '@hexagon/base64@1.1.28': {} + '@hocuspocus/common@2.15.2': dependencies: lib0: 0.2.101 @@ -14977,7 +15132,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 20.17.28 + '@types/node': 20.17.30 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -15010,6 +15165,8 @@ snapshots: '@juggle/resize-observer@3.4.0': {} + '@levischuck/tiny-cbor@0.2.11': {} + '@lifeomic/attempt@3.1.0': {} '@liveblocks/client@2.22.3': @@ -15374,6 +15531,10 @@ snapshots: dependencies: eslint-scope: 5.1.1 + '@noble/ciphers@0.6.0': {} + + '@noble/hashes@1.7.2': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -15737,6 +15898,39 @@ snapshots: '@panva/hkdf@1.2.1': {} + '@peculiar/asn1-android@2.3.16': + dependencies: + '@peculiar/asn1-schema': 2.3.15 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-ecc@2.3.15': + dependencies: + '@peculiar/asn1-schema': 2.3.15 + '@peculiar/asn1-x509': 2.3.15 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-rsa@2.3.15': + dependencies: + '@peculiar/asn1-schema': 2.3.15 + '@peculiar/asn1-x509': 2.3.15 + asn1js: 3.0.6 + tslib: 2.8.1 + + '@peculiar/asn1-schema@2.3.15': + dependencies: + asn1js: 3.0.6 + pvtsutils: 1.3.6 + tslib: 2.8.1 + + '@peculiar/asn1-x509@2.3.15': + dependencies: + '@peculiar/asn1-schema': 2.3.15 + asn1js: 3.0.6 + pvtsutils: 1.3.6 + tslib: 2.8.1 + '@pkgjs/parseargs@0.11.0': optional: true @@ -15775,6 +15969,33 @@ snapshots: dependencies: playwright: 1.51.1 + '@polar-sh/adapter-utils@0.1.15(zod@3.24.2)': + dependencies: + '@polar-sh/sdk': 0.32.10(zod@3.24.2) + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - zod + + '@polar-sh/better-auth@0.1.0(@polar-sh/sdk@0.32.10(zod@3.24.2))(better-auth@1.2.7)': + dependencies: + '@polar-sh/sdk': 0.32.10(zod@3.24.2) + better-auth: 1.2.7 + zod: 3.24.2 + + '@polar-sh/nextjs@0.3.23(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(zod@3.24.2)': + dependencies: + '@polar-sh/adapter-utils': 0.1.15(zod@3.24.2) + '@polar-sh/sdk': 0.32.10(zod@3.24.2) + next: 15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - zod + + '@polar-sh/sdk@0.32.10(zod@3.24.2)': + dependencies: + standardwebhooks: 1.0.0 + zod: 3.24.2 + '@polka/url@1.0.0-next.28': {} '@popperjs/core@2.11.8': {} @@ -16603,6 +16824,18 @@ snapshots: '@sideway/pinpoint@2.0.0': {} + '@simplewebauthn/browser@13.1.0': {} + + '@simplewebauthn/server@13.1.1': + dependencies: + '@hexagon/base64': 1.1.28 + '@levischuck/tiny-cbor': 0.2.11 + '@peculiar/asn1-android': 2.3.16 + '@peculiar/asn1-ecc': 2.3.15 + '@peculiar/asn1-rsa': 2.3.15 + '@peculiar/asn1-schema': 2.3.15 + '@peculiar/asn1-x509': 2.3.15 + '@sinclair/typebox@0.27.8': {} '@smithy/abort-controller@4.0.2': @@ -16936,6 +17169,8 @@ snapshots: '@smithy/types': 4.2.0 tslib: 2.8.1 + '@stablelib/base64@1.0.1': {} + '@swc/counter@0.1.3': {} '@swc/helpers@0.5.15': @@ -17145,9 +17380,13 @@ snapshots: dependencies: '@babel/types': 7.27.0 + '@types/better-sqlite3@7.6.13': + dependencies: + '@types/node': 20.17.30 + '@types/connect@3.4.38': dependencies: - '@types/node': 20.17.28 + '@types/node': 20.17.30 '@types/cookie@0.6.0': {} @@ -17270,7 +17509,7 @@ snapshots: '@types/mysql@2.15.26': dependencies: - '@types/node': 20.17.28 + '@types/node': 20.17.30 '@types/node@20.17.28': dependencies: @@ -17292,7 +17531,7 @@ snapshots: '@types/pg@8.6.1': dependencies: - '@types/node': 20.17.28 + '@types/node': 20.17.30 pg-protocol: 1.8.0 pg-types: 2.2.0 @@ -17329,7 +17568,7 @@ snapshots: '@types/tedious@4.0.14': dependencies: - '@types/node': 20.17.28 + '@types/node': 20.17.30 '@types/tough-cookie@4.0.5': {} @@ -18028,6 +18267,12 @@ snapshots: dependencies: printable-characters: 1.0.42 + asn1js@3.0.6: + dependencies: + pvtsutils: 1.3.6 + pvutils: 1.1.3 + tslib: 2.8.1 + assertion-error@2.0.1: {} ast-types-flow@0.0.8: {} @@ -18144,6 +18389,33 @@ snapshots: base64-js@1.5.1: {} + better-auth@1.2.7: + dependencies: + '@better-auth/utils': 0.2.4 + '@better-fetch/fetch': 1.1.18 + '@noble/ciphers': 0.6.0 + '@noble/hashes': 1.7.2 + '@simplewebauthn/browser': 13.1.0 + '@simplewebauthn/server': 13.1.1 + better-call: 1.0.8 + defu: 6.1.4 + jose: 5.10.0 + kysely: 0.27.6 + nanostores: 0.11.4 + zod: 3.24.2 + + better-call@1.0.8: + dependencies: + '@better-fetch/fetch': 1.1.18 + rou3: 0.5.1 + set-cookie-parser: 2.7.1 + uncrypto: 0.1.3 + + better-sqlite3@11.9.1: + dependencies: + bindings: 1.5.0 + prebuild-install: 7.1.3 + bidi-js@1.0.3: dependencies: require-from-string: 2.0.2 @@ -18152,6 +18424,10 @@ snapshots: binary-extensions@2.3.0: {} + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + bl@4.1.0: dependencies: buffer: 5.7.1 @@ -18814,6 +19090,8 @@ snapshots: has-property-descriptors: 1.0.2 object-keys: 1.1.1 + defu@6.1.4: {} + delaunator@5.0.1: dependencies: robust-predicates: 3.0.2 @@ -19153,7 +19431,7 @@ snapshots: '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.4(eslint@8.57.1) @@ -19200,7 +19478,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1): + eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0 @@ -19215,14 +19493,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -19245,7 +19523,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -19516,6 +19794,8 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-sha256@1.3.0: {} + fast-uri@3.0.6: {} fast-xml-parser@4.4.1: @@ -19542,6 +19822,8 @@ snapshots: dependencies: flat-cache: 3.2.0 + file-uri-to-path@1.0.0: {} + filelist@1.0.4: dependencies: minimatch: 5.1.6 @@ -20426,7 +20708,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 20.17.28 + '@types/node': 20.17.30 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -20580,6 +20862,8 @@ snapshots: kleur@4.1.5: {} + kysely@0.27.6: {} + language-subtag-registry@0.3.23: {} language-tags@1.0.9: @@ -21600,6 +21884,8 @@ snapshots: nanoid@5.1.5: {} + nanostores@0.11.4: {} + napi-build-utils@2.0.0: {} natural-compare-lite@1.4.0: {} @@ -22362,6 +22648,12 @@ snapshots: punycode@2.3.1: {} + pvtsutils@1.3.6: + dependencies: + tslib: 2.8.1 + + pvutils@1.1.3: {} + querystringify@2.2.0: {} queue-microtask@1.2.3: {} @@ -22831,6 +23123,8 @@ snapshots: rope-sequence@1.3.4: {} + rou3@0.5.1: {} + rrweb-cssom@0.6.0: {} rrweb-cssom@0.7.1: {} @@ -22961,6 +23255,8 @@ snapshots: set-blocking@2.0.0: optional: true + set-cookie-parser@2.7.1: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -23176,6 +23472,11 @@ snapshots: as-table: 1.0.55 get-source: 2.0.12 + standardwebhooks@1.0.0: + dependencies: + '@stablelib/base64': 1.0.1 + fast-sha256: 1.3.0 + std-env@3.8.1: {} stoppable@1.1.0: {} @@ -23590,6 +23891,8 @@ snapshots: has-symbols: 1.1.0 which-boxed-primitive: 1.1.1 + uncrypto@0.1.3: {} + undici-types@6.19.8: {} undici-types@6.20.0: {} From 5975ba9b596d97702607ccdff5eab77382bf48fc Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Tue, 22 Apr 2025 15:56:33 +0200 Subject: [PATCH 02/36] chore: hoist prettier to top-level --- docs/package.json | 3 +- docs/prettier.config.js | 7 -- package.json | 2 + packages/ariakit/package.json | 1 - packages/code-block/package.json | 1 - packages/core/package.json | 1 - packages/dev-scripts/package.json | 1 - packages/mantine/package.json | 1 - packages/react/package.json | 1 - packages/server-util/package.json | 1 - packages/shadcn/package.json | 1 - packages/xl-docx-exporter/package.json | 1 - packages/xl-multi-column/package.json | 1 - packages/xl-odt-exporter/package.json | 1 - packages/xl-pdf-exporter/package.json | 1 - pnpm-lock.yaml | 109 ++++++++++++------------- prettier.config.js | 1 + 17 files changed, 56 insertions(+), 78 deletions(-) delete mode 100644 docs/prettier.config.js diff --git a/docs/package.json b/docs/package.json index 420b02f74a..27fa0123ea 100644 --- a/docs/package.json +++ b/docs/package.json @@ -25,6 +25,7 @@ "@polar-sh/sdk": "0.32.10", "@sentry/nextjs": "9.4.0", "@types/better-sqlite3": "7.6.13", + "@types/nodemailer": "6.4.17", "@vercel/analytics": "^1.2.2", "@vercel/og": "^0.6.2", "better-auth": "1.2.7", @@ -36,6 +37,7 @@ "next-auth": "^5.0.0-beta.19", "nextra": "^2.13.2", "nextra-theme-docs": "^2.13.2", + "nodemailer": "6.10.1", "partykit": "^0.0.84", "raw-loader": "^4.0.2", "react": "^18.3.1", @@ -54,7 +56,6 @@ "eslint": "^8", "eslint-config-next": "14.1.0", "postcss": "^8", - "prettier-plugin-tailwindcss": "^0.5.11", "tailwindcss": "^3.3.0", "typescript": "^5" } diff --git a/docs/prettier.config.js b/docs/prettier.config.js deleted file mode 100644 index 64cfdbc5d1..0000000000 --- a/docs/prettier.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - $schema: "http://json.schemastore.org/prettierrc", - tabWidth: 2, - printWidth: 80, - jsxBracketSameLine: true, - plugins: ["prettier-plugin-tailwindcss"] -}; diff --git a/package.json b/package.json index 9f8c9ba0ec..e7f83a9a7c 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,8 @@ "eslint-plugin-import": "^2.31.0", "glob": "^10.3.10", "nx": "20.6.4", + "prettier": "3.5.3", + "prettier-plugin-tailwindcss": "0.6.11", "serve": "14.2.4", "typescript": "^5.3.3", "vitest": "^2.0.3", diff --git a/packages/ariakit/package.json b/packages/ariakit/package.json index 1a94994ac4..030f5b2b49 100644 --- a/packages/ariakit/package.json +++ b/packages/ariakit/package.json @@ -64,7 +64,6 @@ "@types/react-dom": "^18.0.9", "@vitejs/plugin-react": "^4.3.1", "eslint": "^8.10.0", - "prettier": "^2.7.1", "rimraf": "^5.0.5", "rollup-plugin-webpack-stats": "^0.2.2", "typescript": "^5.3.3", diff --git a/packages/code-block/package.json b/packages/code-block/package.json index 3a81dbab5c..6361035d67 100644 --- a/packages/code-block/package.json +++ b/packages/code-block/package.json @@ -59,7 +59,6 @@ }, "devDependencies": { "eslint": "^8.10.0", - "prettier": "^2.7.1", "rollup-plugin-webpack-stats": "^0.2.2", "typescript": "^5.0.4", "vite": "^5.3.4", diff --git a/packages/core/package.json b/packages/core/package.json index a4311e89ef..c9f0839a55 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -121,7 +121,6 @@ "@types/uuid": "^8.3.4", "eslint": "^8.10.0", "jsdom": "^25.0.1", - "prettier": "^2.7.1", "rimraf": "^5.0.5", "rollup-plugin-webpack-stats": "^0.2.2", "typescript": "^5.3.3", diff --git a/packages/dev-scripts/package.json b/packages/dev-scripts/package.json index e810282178..3f9a5e8d51 100644 --- a/packages/dev-scripts/package.json +++ b/packages/dev-scripts/package.json @@ -23,7 +23,6 @@ "@types/react-dom": "^18.0.9", "eslint": "^8.10.0", "glob": "^10.3.10", - "prettier": "^2.7.1", "react": "^18.3.1", "react-dom": "^18.3.1", "tinyglobby": "0.2.12", diff --git a/packages/mantine/package.json b/packages/mantine/package.json index fd08ffe6b9..bc9fbc2fbc 100644 --- a/packages/mantine/package.json +++ b/packages/mantine/package.json @@ -67,7 +67,6 @@ "@types/react-dom": "^18.0.9", "@vitejs/plugin-react": "^4.3.1", "eslint": "^8.10.0", - "prettier": "^2.7.1", "rimraf": "^5.0.5", "rollup-plugin-webpack-stats": "^0.2.2", "typescript": "^5.3.3", diff --git a/packages/react/package.json b/packages/react/package.json index 4c77f9ce22..e154caa9f9 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -76,7 +76,6 @@ "@types/react-dom": "^18.0.9", "@vitejs/plugin-react": "^4.3.1", "eslint": "^8.10.0", - "prettier": "^2.7.1", "react": "^18.3.1", "react-dom": "^18.3.1", "rimraf": "^5.0.5", diff --git a/packages/server-util/package.json b/packages/server-util/package.json index 10853fd895..ce3b5e3316 100644 --- a/packages/server-util/package.json +++ b/packages/server-util/package.json @@ -69,7 +69,6 @@ "@types/react": "^18.0.25", "@types/react-dom": "^18.0.9", "eslint": "^8.10.0", - "prettier": "^2.7.1", "rollup-plugin-webpack-stats": "^0.2.2", "typescript": "^5.0.4", "vite": "^5.3.4", diff --git a/packages/shadcn/package.json b/packages/shadcn/package.json index 37cd2cc86a..3454eec888 100644 --- a/packages/shadcn/package.json +++ b/packages/shadcn/package.json @@ -85,7 +85,6 @@ "@types/react-dom": "^18.0.9", "@vitejs/plugin-react": "^4.3.1", "eslint": "^8.10.0", - "prettier": "^2.7.1", "rimraf": "^5.0.5", "rollup-plugin-webpack-stats": "^0.2.2", "typescript": "^5.3.3", diff --git a/packages/xl-docx-exporter/package.json b/packages/xl-docx-exporter/package.json index f14007e272..784e32441b 100644 --- a/packages/xl-docx-exporter/package.json +++ b/packages/xl-docx-exporter/package.json @@ -66,7 +66,6 @@ "@types/react-dom": "^18.0.9", "@zip.js/zip.js": "^2.7.57", "eslint": "^8.10.0", - "prettier": "^2.7.1", "rollup-plugin-webpack-stats": "^0.2.2", "typescript": "^5.0.4", "vite": "^5.3.4", diff --git a/packages/xl-multi-column/package.json b/packages/xl-multi-column/package.json index 94443ce77c..a711a6252a 100644 --- a/packages/xl-multi-column/package.json +++ b/packages/xl-multi-column/package.json @@ -67,7 +67,6 @@ "@vitest/ui": "^2.1.4", "eslint": "^8.10.0", "jsdom": "^21.1.0", - "prettier": "^2.7.1", "rimraf": "^5.0.5", "rollup-plugin-webpack-stats": "^0.2.2", "typescript": "^5.3.3", diff --git a/packages/xl-odt-exporter/package.json b/packages/xl-odt-exporter/package.json index 58d2b617ab..3083653382 100644 --- a/packages/xl-odt-exporter/package.json +++ b/packages/xl-odt-exporter/package.json @@ -65,7 +65,6 @@ "@testing-library/react": "^16.0.1", "@types/react": "^18.0.25", "@types/react-dom": "^18.0.9", - "prettier": "^2.7.1", "rollup-plugin-webpack-stats": "^0.2.2", "typescript": "^5.0.4", "vite": "^5.3.4", diff --git a/packages/xl-pdf-exporter/package.json b/packages/xl-pdf-exporter/package.json index a73d927887..783fc077f2 100644 --- a/packages/xl-pdf-exporter/package.json +++ b/packages/xl-pdf-exporter/package.json @@ -70,7 +70,6 @@ "eslint": "^8.10.0", "jest-image-snapshot": "^6.4.0", "pdf-to-img": "^4.2.0", - "prettier": "^2.7.1", "react-element-to-jsx-string": "^15.0.0", "rollup-plugin-webpack-stats": "^0.2.2", "typescript": "^5.0.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b559c56a90..f8387dc6ce 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,6 +35,12 @@ importers: nx: specifier: 20.6.4 version: 20.6.4 + prettier: + specifier: 3.5.3 + version: 3.5.3 + prettier-plugin-tailwindcss: + specifier: 0.6.11 + version: 0.6.11(prettier@3.5.3) serve: specifier: 14.2.4 version: 14.2.4 @@ -98,6 +104,9 @@ importers: '@types/better-sqlite3': specifier: 7.6.13 version: 7.6.13 + '@types/nodemailer': + specifier: 6.4.17 + version: 6.4.17 '@vercel/analytics': specifier: ^1.2.2 version: 1.5.0(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) @@ -124,13 +133,16 @@ importers: version: 15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) next-auth: specifier: ^5.0.0-beta.19 - version: 5.0.0-beta.25(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) + version: 5.0.0-beta.25(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nodemailer@6.10.1)(react@18.3.1) nextra: specifier: ^2.13.2 version: 2.13.4(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) nextra-theme-docs: specifier: ^2.13.2 version: 2.13.4(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@2.13.4(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + nodemailer: + specifier: 6.10.1 + version: 6.10.1 partykit: specifier: ^0.0.84 version: 0.0.84 @@ -180,9 +192,6 @@ importers: postcss: specifier: ^8 version: 8.5.3 - prettier-plugin-tailwindcss: - specifier: ^0.5.11 - version: 0.5.14(prettier@2.8.8) tailwindcss: specifier: ^3.3.0 version: 3.4.17 @@ -2799,9 +2808,6 @@ importers: eslint: specifier: ^8.10.0 version: 8.57.1 - prettier: - specifier: ^2.7.1 - version: 2.8.8 rimraf: specifier: ^5.0.5 version: 5.0.10 @@ -2848,9 +2854,6 @@ importers: eslint: specifier: ^8.10.0 version: 8.57.1 - prettier: - specifier: ^2.7.1 - version: 2.8.8 rollup-plugin-webpack-stats: specifier: ^0.2.2 version: 0.2.6(rollup@4.37.0) @@ -3014,9 +3017,6 @@ importers: jsdom: specifier: ^25.0.1 version: 25.0.1(canvas@2.11.2(encoding@0.1.13)) - prettier: - specifier: ^2.7.1 - version: 2.8.8 rimraf: specifier: ^5.0.5 version: 5.0.10 @@ -3050,9 +3050,6 @@ importers: glob: specifier: ^10.3.10 version: 10.4.5 - prettier: - specifier: ^2.7.1 - version: 2.8.8 react: specifier: ^18.3.1 version: 18.3.1 @@ -3108,9 +3105,6 @@ importers: eslint: specifier: ^8.10.0 version: 8.57.1 - prettier: - specifier: ^2.7.1 - version: 2.8.8 rimraf: specifier: ^5.0.5 version: 5.0.10 @@ -3184,9 +3178,6 @@ importers: eslint: specifier: ^8.10.0 version: 8.57.1 - prettier: - specifier: ^2.7.1 - version: 2.8.8 react: specifier: ^18.3.1 version: 18.3.1 @@ -3260,9 +3251,6 @@ importers: eslint: specifier: ^8.10.0 version: 8.57.1 - prettier: - specifier: ^2.7.1 - version: 2.8.8 rollup-plugin-webpack-stats: specifier: ^0.2.2 version: 0.2.6(rollup@4.37.0) @@ -3372,9 +3360,6 @@ importers: eslint: specifier: ^8.10.0 version: 8.57.1 - prettier: - specifier: ^2.7.1 - version: 2.8.8 rimraf: specifier: ^5.0.5 version: 5.0.10 @@ -3421,9 +3406,6 @@ importers: eslint: specifier: ^8.10.0 version: 8.57.1 - prettier: - specifier: ^2.7.1 - version: 2.8.8 react: specifier: ^18.3.1 version: 18.3.1 @@ -3494,9 +3476,6 @@ importers: jsdom: specifier: ^21.1.0 version: 21.1.2(canvas@2.11.2(encoding@0.1.13)) - prettier: - specifier: ^2.7.1 - version: 2.8.8 react: specifier: ^18.3.1 version: 18.3.1 @@ -3546,9 +3525,6 @@ importers: '@types/react-dom': specifier: ^18.0.9 version: 18.3.5(@types/react@18.3.20) - prettier: - specifier: ^2.7.1 - version: 2.8.8 react: specifier: ^18.3.1 version: 18.3.1 @@ -3616,9 +3592,6 @@ importers: pdf-to-img: specifier: ^4.2.0 version: 4.4.0(encoding@0.1.13) - prettier: - specifier: ^2.7.1 - version: 2.8.8 react: specifier: ^18.3.1 version: 18.3.1 @@ -7498,6 +7471,9 @@ packages: '@types/node@22.13.13': resolution: {integrity: sha512-ClsL5nMwKaBRwPcCvH8E7+nU4GxHVx1axNvMZTFHMEfNI7oahimt26P5zjVCRrjiIWj6YFXfE1v3dEp94wLcGQ==} + '@types/nodemailer@6.4.17': + resolution: {integrity: sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww==} + '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -10978,6 +10954,10 @@ packages: node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} + nodemailer@6.10.1: + resolution: {integrity: sha512-Z+iLaBGVaSjbIzQ4pX6XV41HrooLsQ10ZWPUehGmuantvzWoDVBnmsdUcOIDM1t+yPor5pDhVlDESgOMEGxhHA==} + engines: {node: '>=6.0.0'} + non-layered-tidy-tree-layout@2.0.2: resolution: {integrity: sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==} @@ -11382,21 +11362,22 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier-plugin-tailwindcss@0.5.14: - resolution: {integrity: sha512-Puaz+wPUAhFp8Lo9HuciYKM2Y2XExESjeT+9NQoVFXZsPPnc9VYss2SpxdQ6vbatmt8/4+SN0oe0I1cPDABg9Q==} + prettier-plugin-tailwindcss@0.6.11: + resolution: {integrity: sha512-YxaYSIvZPAqhrrEpRtonnrXdghZg1irNg4qrjboCXrpybLWVs55cW2N3juhspVJiO0JBvYJT8SYsJpc8OQSnsA==} engines: {node: '>=14.21.3'} peerDependencies: '@ianvs/prettier-plugin-sort-imports': '*' '@prettier/plugin-pug': '*' '@shopify/prettier-plugin-liquid': '*' '@trivago/prettier-plugin-sort-imports': '*' - '@zackad/prettier-plugin-twig-melody': '*' + '@zackad/prettier-plugin-twig': '*' prettier: ^3.0 prettier-plugin-astro: '*' prettier-plugin-css-order: '*' prettier-plugin-import-sort: '*' prettier-plugin-jsdoc: '*' prettier-plugin-marko: '*' + prettier-plugin-multiline-arrays: '*' prettier-plugin-organize-attributes: '*' prettier-plugin-organize-imports: '*' prettier-plugin-sort-imports: '*' @@ -11411,7 +11392,7 @@ packages: optional: true '@trivago/prettier-plugin-sort-imports': optional: true - '@zackad/prettier-plugin-twig-melody': + '@zackad/prettier-plugin-twig': optional: true prettier-plugin-astro: optional: true @@ -11423,6 +11404,8 @@ packages: optional: true prettier-plugin-marko: optional: true + prettier-plugin-multiline-arrays: + optional: true prettier-plugin-organize-attributes: optional: true prettier-plugin-organize-imports: @@ -11434,9 +11417,9 @@ packages: prettier-plugin-svelte: optional: true - prettier@2.8.8: - resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} - engines: {node: '>=10.13.0'} + prettier@3.5.3: + resolution: {integrity: sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==} + engines: {node: '>=14'} hasBin: true pretty-format@27.5.1: @@ -13239,7 +13222,7 @@ snapshots: '@csstools/css-tokenizer': 3.0.3 lru-cache: 10.4.3 - '@auth/core@0.37.2': + '@auth/core@0.37.2(nodemailer@6.10.1)': dependencies: '@panva/hkdf': 1.2.1 '@types/cookie': 0.6.0 @@ -13248,6 +13231,8 @@ snapshots: oauth4webapi: 3.3.1 preact: 10.11.3 preact-render-to-string: 5.2.3(preact@10.11.3) + optionalDependencies: + nodemailer: 6.10.1 '@aws-crypto/crc32@5.2.0': dependencies: @@ -17523,6 +17508,10 @@ snapshots: dependencies: undici-types: 6.20.0 + '@types/nodemailer@6.4.17': + dependencies: + '@types/node': 20.17.30 + '@types/parse-json@4.0.2': {} '@types/pg-pool@2.0.6': @@ -19431,7 +19420,7 @@ snapshots: '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.4(eslint@8.57.1) @@ -19478,7 +19467,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1): + eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0 @@ -19493,14 +19482,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -19523,7 +19512,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -21896,11 +21885,13 @@ snapshots: neo-async@2.6.2: {} - next-auth@5.0.0-beta.25(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1): + next-auth@5.0.0-beta.25(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nodemailer@6.10.1)(react@18.3.1): dependencies: - '@auth/core': 0.37.2 + '@auth/core': 0.37.2(nodemailer@6.10.1) next: 15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 + optionalDependencies: + nodemailer: 6.10.1 next-mdx-remote@4.4.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: @@ -22022,6 +22013,8 @@ snapshots: node-releases@2.0.19: {} + nodemailer@6.10.1: {} + non-layered-tidy-tree-layout@2.0.2: {} nopt@5.0.0: @@ -22479,11 +22472,11 @@ snapshots: prelude-ls@1.2.1: {} - prettier-plugin-tailwindcss@0.5.14(prettier@2.8.8): + prettier-plugin-tailwindcss@0.6.11(prettier@3.5.3): dependencies: - prettier: 2.8.8 + prettier: 3.5.3 - prettier@2.8.8: {} + prettier@3.5.3: {} pretty-format@27.5.1: dependencies: diff --git a/prettier.config.js b/prettier.config.js index add9f85b15..273f1e5c09 100644 --- a/prettier.config.js +++ b/prettier.config.js @@ -3,4 +3,5 @@ module.exports = { tabWidth: 2, printWidth: 80, jsxBracketSameLine: true, + plugins: ["prettier-plugin-tailwindcss"], }; From af103ad071a916159f40e9ce0d3440824292c642 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Tue, 22 Apr 2025 15:59:27 +0200 Subject: [PATCH 03/36] chore: fix generation --- packages/dev-scripts/examples/gen.ts | 10 +++++----- packages/dev-scripts/package.json | 3 +++ pnpm-lock.yaml | 4 ++++ 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/dev-scripts/examples/gen.ts b/packages/dev-scripts/examples/gen.ts index c14fcfca14..e0e600cdc9 100644 --- a/packages/dev-scripts/examples/gen.ts +++ b/packages/dev-scripts/examples/gen.ts @@ -33,7 +33,7 @@ async function writeTemplate(project: Project, templateFile: string) { const targetFilePath = path.join( "../../", project.pathFromRoot, - path.basename(templateFile).replace(".template.tsx", "") + path.basename(templateFile).replace(".template.tsx", ""), ); let stringOutput: string | undefined = undefined; @@ -41,10 +41,10 @@ async function writeTemplate(project: Project, templateFile: string) { stringOutput = ReactDOM.renderToString(ret); const prettierConfig = await prettier.resolveConfig(targetFilePath); - stringOutput = prettier.format(stringOutput, { + stringOutput = await prettier.format(stringOutput, { ...prettierConfig, parser: "html", - }) as string; + }); } else if (typeof ret === "string") { stringOutput = ret; } else if (typeof ret === "object") { @@ -58,7 +58,7 @@ async function writeTemplate(project: Project, templateFile: string) { async function generateCodeForExample(project: Project) { const templates = glob.sync( - replacePathSepToSlash(path.resolve(dir, "./template-react/*.template.tsx")) + replacePathSepToSlash(path.resolve(dir, "./template-react/*.template.tsx")), ); for (const template of templates) { @@ -90,5 +90,5 @@ for (const project of projects) { } await generateExamplesData( - projects.filter((p) => p.config?.playground === true) + projects.filter((p) => p.config?.playground === true), ); diff --git a/packages/dev-scripts/package.json b/packages/dev-scripts/package.json index 3f9a5e8d51..0b997a7ffc 100644 --- a/packages/dev-scripts/package.json +++ b/packages/dev-scripts/package.json @@ -33,5 +33,8 @@ "extends": [ "../../.eslintrc.js" ] + }, + "dependencies": { + "prettier": "3.5.3" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f8387dc6ce..81450f204e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3037,6 +3037,10 @@ importers: version: 2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) packages/dev-scripts: + dependencies: + prettier: + specifier: 3.5.3 + version: 3.5.3 devDependencies: '@types/react': specifier: ^18.0.25 From 284d550fe167f79300e29a040a8dedab8b1af671 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Tue, 22 Apr 2025 19:29:48 +0200 Subject: [PATCH 04/36] feat: implement email notifications and magic links --- docs/.env.local.example | 18 +- docs/app/signup/page.tsx | 19 +- docs/auth.ts | 138 +-- docs/emails/magic-link.tsx | 97 ++ docs/emails/reset-password.tsx | 94 ++ docs/emails/verify-email.tsx | 94 ++ docs/package.json | 11 +- docs/theme.config.tsx | 6 +- docs/util/auth-client.ts | 12 +- docs/util/send-mail.tsx | 86 ++ package.json | 2 +- pnpm-lock.yaml | 1552 +++++++++++++++++++++++++++----- 12 files changed, 1837 insertions(+), 292 deletions(-) create mode 100644 docs/emails/magic-link.tsx create mode 100644 docs/emails/reset-password.tsx create mode 100644 docs/emails/verify-email.tsx create mode 100644 docs/util/send-mail.tsx diff --git a/docs/.env.local.example b/docs/.env.local.example index 50ec3e8011..e9dcc0e453 100644 --- a/docs/.env.local.example +++ b/docs/.env.local.example @@ -1,8 +1,22 @@ -AUTH_SECRET= # Linux: `openssl rand -hex 32` or go to https://generate-secret.vercel.app/32 - AUTH_GITHUB_ID= AUTH_GITHUB_SECRET= # The SENTRY_AUTH_TOKEN variable is picked up by the Sentry Build Plugin. # It's used for authentication when uploading source maps. SENTRY_AUTH_TOKEN= + +#Email +SMTP_HOST= +SMTP_USER= +SMTP_PASS= +SMTP_PORT= +# Insecure if false, secure if any other value +SMTP_SECURE=false + +# Better Auth +BETTER_AUTH_SECRET= # Linux: `openssl rand -hex 32` or go to https://generate-secret.vercel.app/32 +BETTER_AUTH_URL=http://localhost:3000 + +# Polar +POLAR_ACCESS_TOKEN= +POLAR_WEBHOOK_SECRET= diff --git a/docs/app/signup/page.tsx b/docs/app/signup/page.tsx index 1ec8a359c6..66f741e183 100644 --- a/docs/app/signup/page.tsx +++ b/docs/app/signup/page.tsx @@ -1,6 +1,6 @@ "use client"; -import { signUp } from "@/util/auth-client"; +import { signIn, signUp } from "@/util/auth-client"; import { useState } from "react"; // TODO Do we want email & password signin? or just social? @@ -19,7 +19,6 @@ export default function Register() { return (
-

Register

Register +
); -}; \ No newline at end of file +} diff --git a/docs/auth.ts b/docs/auth.ts index fc072c8746..63b3701a28 100644 --- a/docs/auth.ts +++ b/docs/auth.ts @@ -1,65 +1,93 @@ -import { betterAuth } from "better-auth"; -import Database from "better-sqlite3"; import { polar } from "@polar-sh/better-auth"; import { Polar } from "@polar-sh/sdk"; -import { openAPI } from "better-auth/plugins" +import { betterAuth } from "better-auth"; +import { magicLink, openAPI } from "better-auth/plugins"; +import Database from "better-sqlite3"; + +import { sendEmail } from "./util/send-mail"; export const client = new Polar({ - accessToken: process.env.POLAR_ACCESS_TOKEN, - // Use 'sandbox' if you're using the Polar Sandbox environment - // Remember that access tokens, products, etc. are completely separated between environments. - // Access tokens obtained in Production are for instance not usable in the Sandbox environment. - server: 'sandbox' + accessToken: process.env.POLAR_ACCESS_TOKEN, + // Use 'sandbox' if you're using the Polar Sandbox environment + // Remember that access tokens, products, etc. are completely separated between environments. + // Access tokens obtained in Production are for instance not usable in the Sandbox environment. + server: "sandbox", }); export const auth = betterAuth({ - emailAndPassword: { - enabled: true + emailVerification: { + async sendVerificationEmail({ user, url }) { + await sendEmail({ + to: user.email, + template: "verifyEmail", + props: { url }, + }); + }, + }, + emailAndPassword: { + enabled: true, + requireEmailVerification: true, + async sendResetPassword(data) { + await sendEmail({ + to: data.user.email, + template: "resetPassword", + props: { url: data.url }, + }); + }, }, - socialProviders: { - github: { - clientId: process.env.AUTH_GITHUB_ID as string, - clientSecret: process.env.AUTH_GITHUB_SECRET as string - }, + socialProviders: { + github: { + clientId: process.env.AUTH_GITHUB_ID as string, + clientSecret: process.env.AUTH_GITHUB_SECRET as string, + }, }, database: new Database("./sqlite.db"), - plugins: [ - // Just temporary for testing - // Serves on http://localhost:3000/api/auth/reference - openAPI(), - polar({ - client, - // Enable automatic Polar Customer creation on signup - createCustomerOnSignUp: true, - // http://localhost:3000/api/auth/portal - enableCustomerPortal: true, - // Configure checkout - checkout: { - enabled: true, - products: [ - { - productId: "8049f66f-fd0a-4690-a0aa-442ac5b03040", // ID of Product from Polar Dashboard - slug: "business" // Custom slug for easy reference in Checkout URL, e.g. /checkout/pro - // http://localhost:3000/api/auth/checkout/business - }, - { - productId: 'ab70fea5-172c-4aac-b3fc-0824f2a5b670', - slug: 'starter' - // http://localhost:3000/api/auth/checkout/starter - } - ], - // TODO set to actual page (welcome screen) - successUrl: "/success?checkout_id={CHECKOUT_ID}" - }, - // Incoming Webhooks handler will be installed at /polar/webhooks - webhooks: { - // webhooks have to be publicly accessible - // ngrok http http://localhost:3000 - secret: process.env.POLAR_WEBHOOK_SECRET as string, - onPayload: async (payload) => { - console.log(payload) - }, - } - }) - ] -}); \ No newline at end of file + plugins: [ + magicLink({ + sendMagicLink: async ({ email, url }) => { + await sendEmail({ + to: email, + template: "magicLink", + props: { url }, + }); + }, + }), + // Just temporary for testing + // Serves on http://localhost:3000/api/auth/reference + openAPI(), + polar({ + client, + // Enable automatic Polar Customer creation on signup + createCustomerOnSignUp: true, + // http://localhost:3000/api/auth/portal + enableCustomerPortal: true, + // Configure checkout + checkout: { + enabled: true, + products: [ + { + productId: "8049f66f-fd0a-4690-a0aa-442ac5b03040", // ID of Product from Polar Dashboard + slug: "business", // Custom slug for easy reference in Checkout URL, e.g. /checkout/pro + // http://localhost:3000/api/auth/checkout/business + }, + { + productId: "ab70fea5-172c-4aac-b3fc-0824f2a5b670", + slug: "starter", + // http://localhost:3000/api/auth/checkout/starter + }, + ], + // TODO set to actual page (welcome screen) + successUrl: "/success?checkout_id={CHECKOUT_ID}", + }, + // Incoming Webhooks handler will be installed at /polar/webhooks + webhooks: { + // webhooks have to be publicly accessible + // ngrok http http://localhost:3000 + secret: process.env.POLAR_WEBHOOK_SECRET as string, + onPayload: async (payload) => { + console.log(payload); + }, + }, + }), + ], +}); diff --git a/docs/emails/magic-link.tsx b/docs/emails/magic-link.tsx new file mode 100644 index 0000000000..747a7d0df2 --- /dev/null +++ b/docs/emails/magic-link.tsx @@ -0,0 +1,97 @@ +import { + Body, + Button, + Container, + Head, + Html, + Img, + Preview, + Section, + Text, +} from "@react-email/components"; + +export interface MagicLinkEmailProps { + name?: string; + url?: string; +} + +export const MagicLinkEmail = ({ name, url }: MagicLinkEmailProps) => { + return ( + + + + BlockNote - Sign in to your account + + BlockNote +
+ Hi{name ? ` ${name}` : ""}, + + Someone recently requested a magic link for your BlockNote + account. If this was you, you can sign in here: + + + + If you don't want to sign in or didn't request this, + just ignore and delete this message. + + + To keep your account secure, please don't forward this email + to anyone. + +
+
+ + + ); +}; + +MagicLinkEmail.PreviewProps = { + name: "", + url: "https://blocknotejs.org", +} as MagicLinkEmailProps; + +export default MagicLinkEmail; + +const main = { + backgroundColor: "#f6f9fc", + padding: "10px 0", +}; + +const container = { + backgroundColor: "#ffffff", + border: "1px solid #f0f0f0", + padding: "45px", +}; + +const text = { + fontSize: "16px", + fontFamily: + "'Open Sans', 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif", + fontWeight: "300", + color: "#404040", + lineHeight: "26px", +}; + +const button = { + backgroundColor: "#007ee6", + borderRadius: "4px", + color: "#fff", + fontFamily: "'Open Sans', 'Helvetica Neue', Arial", + fontSize: "15px", + textDecoration: "none", + textAlign: "center" as const, + display: "block", + width: "210px", + padding: "14px 7px", +}; + +const anchor = { + textDecoration: "underline", +}; diff --git a/docs/emails/reset-password.tsx b/docs/emails/reset-password.tsx new file mode 100644 index 0000000000..a98175e2d3 --- /dev/null +++ b/docs/emails/reset-password.tsx @@ -0,0 +1,94 @@ +import { + Body, + Button, + Container, + Head, + Html, + Img, + Preview, + Section, + Text, +} from "@react-email/components"; + +export interface ResetPasswordProps { + name?: string; + url?: string; +} + +export const ResetPassword = ({ name, url }: ResetPasswordProps) => { + return ( + + + + BlockNote - Reset your password + + BlockNote +
+ Hi{name ? ` ${name}` : ""}, + + Someone recently requested a password reset for your BlockNote + account. If this was you, you can reset your password by clicking + the button below: + + + + If you didn't request a password reset, you can safely ignore + this email. + + + To keep your account secure, please don't forward this email + to anyone. + +
+
+ + + ); +}; + +ResetPassword.PreviewProps = { + name: "", + url: "https://blocknotejs.org", +} as ResetPasswordProps; + +export default ResetPassword; + +const main = { + backgroundColor: "#f6f9fc", + padding: "10px 0", +}; + +const container = { + backgroundColor: "#ffffff", + border: "1px solid #f0f0f0", + padding: "45px", +}; + +const text = { + fontSize: "16px", + fontFamily: + "'Open Sans', 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif", + fontWeight: "300", + color: "#404040", + lineHeight: "26px", +}; + +const button = { + backgroundColor: "#007ee6", + borderRadius: "4px", + color: "#fff", + fontFamily: "'Open Sans', 'Helvetica Neue', Arial", + fontSize: "15px", + textDecoration: "none", + textAlign: "center" as const, + display: "block", + width: "210px", + padding: "14px 7px", +}; diff --git a/docs/emails/verify-email.tsx b/docs/emails/verify-email.tsx new file mode 100644 index 0000000000..b6d8be7954 --- /dev/null +++ b/docs/emails/verify-email.tsx @@ -0,0 +1,94 @@ +import { + Body, + Button, + Container, + Head, + Html, + Img, + Preview, + Section, + Text, +} from "@react-email/components"; + +export interface VerifyEmailProps { + name?: string; + url?: string; +} + +export const VerifyEmail = ({ name, url }: VerifyEmailProps) => { + return ( + + + + BlockNote - Verify your email address + + BlockNote +
+ Hi{name ? ` ${name}` : ""}, + + Thanks for signing up for BlockNote! To complete your + registration, please verify your email address by clicking the + button below: + + + + If you didn't create a BlockNote account, you can safely + ignore this email. + + + To keep your account secure, please don't forward this email + to anyone. + +
+
+ + + ); +}; + +VerifyEmail.PreviewProps = { + name: "", + url: "https://blocknotejs.org", +} as VerifyEmailProps; + +export default VerifyEmail; + +const main = { + backgroundColor: "#f6f9fc", + padding: "10px 0", +}; + +const container = { + backgroundColor: "#ffffff", + border: "1px solid #f0f0f0", + padding: "45px", +}; + +const text = { + fontSize: "16px", + fontFamily: + "'Open Sans', 'HelveticaNeue-Light', 'Helvetica Neue Light', 'Helvetica Neue', Helvetica, Arial, 'Lucida Grande', sans-serif", + fontWeight: "300", + color: "#404040", + lineHeight: "26px", +}; + +const button = { + backgroundColor: "#007ee6", + borderRadius: "4px", + color: "#fff", + fontFamily: "'Open Sans', 'Helvetica Neue', Arial", + fontSize: "15px", + textDecoration: "none", + textAlign: "center" as const, + display: "block", + width: "210px", + padding: "14px 7px", +}; diff --git a/docs/package.json b/docs/package.json index 27fa0123ea..916cfa2447 100644 --- a/docs/package.json +++ b/docs/package.json @@ -4,6 +4,8 @@ "private": true, "scripts": { "dev": "next dev", + "dev:email": "email dev", + "build:email": "email export --outDir ./", "build:site": "next build", "start": "next start", "lint": "next lint" @@ -20,9 +22,10 @@ "@heroicons/react": "^2.1.4", "@mantine/core": "^7.10.1", "@next/bundle-analyzer": "^14.1.0", - "@polar-sh/better-auth": "0.1.0", - "@polar-sh/nextjs": "0.3.23", - "@polar-sh/sdk": "0.32.10", + "@polar-sh/better-auth": "^0.1", + "@polar-sh/nextjs": "^0.3.23", + "@polar-sh/sdk": "^0.32.11", + "@react-email/render": "1.0.6", "@sentry/nextjs": "9.4.0", "@types/better-sqlite3": "7.6.13", "@types/nodemailer": "6.4.17", @@ -49,6 +52,7 @@ "zod": "^3.23.8" }, "devDependencies": { + "@react-email/components": "^0.0.36", "@types/node": "^20", "@types/react": "^18.0.25", "@types/react-dom": "^18.0.9", @@ -56,6 +60,7 @@ "eslint": "^8", "eslint-config-next": "14.1.0", "postcss": "^8", + "react-email": "^4.0.7", "tailwindcss": "^3.3.0", "typescript": "^5" } diff --git a/docs/theme.config.tsx b/docs/theme.config.tsx index c04826a1ba..0fd892d77f 100644 --- a/docs/theme.config.tsx +++ b/docs/theme.config.tsx @@ -222,11 +222,11 @@ const config: DocsThemeConfig = { Discord - {/* - + + Sign in - */} + ); diff --git a/docs/util/auth-client.ts b/docs/util/auth-client.ts index 314e890ab5..a76177f15e 100644 --- a/docs/util/auth-client.ts +++ b/docs/util/auth-client.ts @@ -1,7 +1,9 @@ -import { createAuthClient } from "better-auth/react" +import { createAuthClient } from "better-auth/react"; + +import { magicLinkClient } from "better-auth/client/plugins"; + export const authClient = createAuthClient({ - /** The base URL of the server (optional if you're using the same domain) */ - baseURL: "http://localhost:3000" -}) + plugins: [magicLinkClient()], +}); -export const { useSession, signIn, signOut, signUp } = authClient \ No newline at end of file +export const { useSession, signIn, signOut, signUp } = authClient; diff --git a/docs/util/send-mail.tsx b/docs/util/send-mail.tsx new file mode 100644 index 0000000000..702f9378b1 --- /dev/null +++ b/docs/util/send-mail.tsx @@ -0,0 +1,86 @@ +import nodemailer from "nodemailer"; +import { render } from "@react-email/render"; +import MagicLinkEmail from "@/emails/magic-link"; +import VerifyEmail from "@/emails/verify-email"; +import ResetPassword from "@/emails/reset-password"; + +const transporter = nodemailer.createTransport({ + host: String(process.env.SMTP_HOST), + port: Number(process.env.SMTP_PORT), + secure: process.env.SMTP_SECURE !== "false", // true for port 465, false for other ports + auth: { + user: String(process.env.SMTP_USER), + pass: String(process.env.SMTP_PASS), + }, +}); + +type TEMPLATES = { + verifyEmail: { + url: string; + name?: string; + }; + resetPassword: { + url: string; + name?: string; + }; + magicLink: { + url: string; + name?: string; + }; +}; + +const TEMPLATE_TEXTS = { + verifyEmail: (props: TEMPLATES["verifyEmail"]) => + render(, { + pretty: true, + plainText: true, + }), + resetPassword: (props: TEMPLATES["resetPassword"]) => + render(, { + pretty: true, + plainText: true, + }), + magicLink: (props: TEMPLATES["magicLink"]) => + render(, { + pretty: true, + plainText: true, + }), +}; +const TEMPLATE_HTMLS = { + verifyEmail: (props: TEMPLATES["verifyEmail"]) => + render(, { + pretty: true, + }), + resetPassword: (props: TEMPLATES["resetPassword"]) => + render(, { + pretty: true, + }), + magicLink: (props: TEMPLATES["magicLink"]): Promise => + render(, { + pretty: true, + }), +}; + +export async function sendEmail({ + to, + template, + props, +}: { + to: string; + template: T; + props: TEMPLATES[T]; +}) { + const info = await transporter.sendMail({ + from: '"BlockNote" ', + to, + subject: { + verifyEmail: "BlockNote - Verify your email address", + resetPassword: "BlockNote - Reset your password", + magicLink: "BlockNote - Sign in to your account", + }[template], + text: await TEMPLATE_TEXTS[template](props), + html: await TEMPLATE_HTMLS[template](props), + }); + + console.log("Email sent: ", info.messageId); +} diff --git a/package.json b/package.json index e7f83a9a7c..3618f79eb6 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "dev:docs": "nx run docs:dev", "build": "nx run-many --target=build", "build:clean": "pnpm run clean && pnpm run gen && pnpm run clean && pnpm run build", - "build:site": "pnpm run gen && nx run docs:build:site", + "build:site": "pnpm run gen && nx run-many --target=build:site", "clean": "nx run-many --target=clean", "deploy": "nx release --skip-publish", "gen": "nx run @blocknote/dev-scripts:gen", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 81450f204e..b4f82ad6db 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -49,7 +49,7 @@ importers: version: 5.8.2 vitest: specifier: ^2.0.3 - version: 2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) + version: 2.1.9(@types/node@22.14.1)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) wait-on: specifier: 8.0.3 version: 8.0.3 @@ -90,14 +90,17 @@ importers: specifier: ^14.1.0 version: 14.2.26 '@polar-sh/better-auth': - specifier: 0.1.0 - version: 0.1.0(@polar-sh/sdk@0.32.10(zod@3.24.2))(better-auth@1.2.7) + specifier: ^0.1 + version: 0.1.0(@polar-sh/sdk@0.32.11(zod@3.24.2))(better-auth@1.2.7) '@polar-sh/nextjs': - specifier: 0.3.23 + specifier: ^0.3.23 version: 0.3.23(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(zod@3.24.2) '@polar-sh/sdk': - specifier: 0.32.10 - version: 0.32.10(zod@3.24.2) + specifier: ^0.32.11 + version: 0.32.11(zod@3.24.2) + '@react-email/render': + specifier: 1.0.6 + version: 1.0.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@sentry/nextjs': specifier: 9.4.0 version: 9.4.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.98.0) @@ -171,6 +174,9 @@ importers: specifier: ^3.23.8 version: 3.24.2 devDependencies: + '@react-email/components': + specifier: ^0.0.36 + version: 0.0.36(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/node': specifier: ^20 version: 20.17.28 @@ -192,6 +198,9 @@ importers: postcss: specifier: ^8 version: 8.5.3 + react-email: + specifier: ^4.0.7 + version: 4.0.7(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tailwindcss: specifier: ^3.3.0 version: 3.4.17 @@ -231,10 +240,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/02-block-objects: dependencies: @@ -268,10 +277,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/03-multi-column: dependencies: @@ -308,10 +317,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/04-default-blocks: dependencies: @@ -345,10 +354,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/05-removing-default-blocks: dependencies: @@ -382,10 +391,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/06-block-manipulation: dependencies: @@ -419,10 +428,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/07-selection-blocks: dependencies: @@ -456,10 +465,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/08-ariakit: dependencies: @@ -493,10 +502,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/09-shadcn: dependencies: @@ -530,10 +539,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/10-localization: dependencies: @@ -567,10 +576,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/11-custom-placeholder: dependencies: @@ -604,10 +613,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/12-multi-editor: dependencies: @@ -641,10 +650,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/13-custom-paste-handler: dependencies: @@ -678,10 +687,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/01-basic/testing: dependencies: @@ -715,10 +724,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/02-backend/01-file-uploading: dependencies: @@ -752,10 +761,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/02-backend/02-saving-loading: dependencies: @@ -789,10 +798,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/02-backend/03-s3: dependencies: @@ -832,10 +841,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/02-backend/04-rendering-static-documents: dependencies: @@ -872,10 +881,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/01-ui-elements-remove: dependencies: @@ -909,10 +918,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/02-formatting-toolbar-buttons: dependencies: @@ -946,10 +955,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/03-formatting-toolbar-block-type-items: dependencies: @@ -989,10 +998,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/04-side-menu-buttons: dependencies: @@ -1029,10 +1038,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/05-side-menu-drag-handle-items: dependencies: @@ -1069,10 +1078,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/06-suggestion-menus-slash-menu-items: dependencies: @@ -1109,10 +1118,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/07-suggestion-menus-slash-menu-component: dependencies: @@ -1146,10 +1155,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/08-suggestion-menus-emoji-picker-columns: dependencies: @@ -1183,10 +1192,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/09-suggestion-menus-emoji-picker-component: dependencies: @@ -1220,10 +1229,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/10-suggestion-menus-grid-mentions: dependencies: @@ -1257,10 +1266,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/11-uppy-file-panel: dependencies: @@ -1330,10 +1339,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/12-static-formatting-toolbar: dependencies: @@ -1367,10 +1376,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/13-custom-ui: dependencies: @@ -1416,10 +1425,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/14-experimental-mobile-formatting-toolbar: dependencies: @@ -1453,10 +1462,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/15-advanced-tables: dependencies: @@ -1490,10 +1499,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/03-ui-components/link-toolbar-buttons: dependencies: @@ -1527,10 +1536,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/04-theming/01-theming-dom-attributes: dependencies: @@ -1564,10 +1573,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/04-theming/02-changing-font: dependencies: @@ -1601,10 +1610,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/04-theming/03-theming-css: dependencies: @@ -1638,10 +1647,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/04-theming/04-theming-css-variables: dependencies: @@ -1675,10 +1684,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/04-theming/05-theming-css-variables-code: dependencies: @@ -1712,10 +1721,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/04-theming/06-code-block: dependencies: @@ -1752,10 +1761,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/04-theming/07-custom-code-block: dependencies: @@ -1807,10 +1816,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/05-interoperability/01-converting-blocks-to-html: dependencies: @@ -1844,10 +1853,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/05-interoperability/02-converting-blocks-from-html: dependencies: @@ -1881,10 +1890,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/05-interoperability/03-converting-blocks-to-md: dependencies: @@ -1918,10 +1927,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/05-interoperability/04-converting-blocks-from-md: dependencies: @@ -1955,10 +1964,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/05-interoperability/05-converting-blocks-to-pdf: dependencies: @@ -1998,10 +2007,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/05-interoperability/06-converting-blocks-to-docx: dependencies: @@ -2041,10 +2050,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/05-interoperability/07-converting-blocks-to-odt: dependencies: @@ -2081,10 +2090,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/06-custom-schema/01-alert-block: dependencies: @@ -2124,10 +2133,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/06-custom-schema/02-suggestion-menus-mentions: dependencies: @@ -2161,10 +2170,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/06-custom-schema/03-font-style: dependencies: @@ -2201,10 +2210,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/06-custom-schema/04-pdf-file-block: dependencies: @@ -2244,10 +2253,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/06-custom-schema/05-alert-block-full-ux: dependencies: @@ -2287,10 +2296,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/06-custom-schema/react-custom-blocks: dependencies: @@ -2324,10 +2333,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/06-custom-schema/react-custom-inline-content: dependencies: @@ -2361,10 +2370,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/06-custom-schema/react-custom-styles: dependencies: @@ -2398,10 +2407,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/07-collaboration/01-partykit: dependencies: @@ -2441,10 +2450,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/07-collaboration/02-liveblocks: dependencies: @@ -2496,10 +2505,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/07-collaboration/03-y-sweet: dependencies: @@ -2536,10 +2545,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/07-collaboration/04-comments: dependencies: @@ -2579,10 +2588,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/07-collaboration/05-comments-with-sidebar: dependencies: @@ -2622,10 +2631,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/08-extensions/01-tiptap-arrow-conversion: dependencies: @@ -2662,10 +2671,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/vanilla-js/react-vanilla-custom-blocks: dependencies: @@ -2699,10 +2708,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/vanilla-js/react-vanilla-custom-inline-content: dependencies: @@ -2736,10 +2745,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) examples/vanilla-js/react-vanilla-custom-styles: dependencies: @@ -2773,10 +2782,10 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) packages/ariakit: dependencies: @@ -2804,7 +2813,7 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) eslint: specifier: ^8.10.0 version: 8.57.1 @@ -2819,13 +2828,13 @@ importers: version: 5.8.2 vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite-plugin-externalize-deps: specifier: ^0.8.0 - version: 0.8.0(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 0.8.0(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) packages/code-block: dependencies: @@ -2862,13 +2871,13 @@ importers: version: 5.8.2 vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vitest: specifier: ^2.0.3 - version: 2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) + version: 2.1.9(@types/node@22.14.1)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) packages/core: dependencies: @@ -3028,13 +3037,13 @@ importers: version: 5.8.2 vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vitest: specifier: ^2.0.3 - version: 2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) + version: 2.1.9(@types/node@22.14.1)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) packages/dev-scripts: dependencies: @@ -3070,6 +3079,28 @@ importers: specifier: ^5.3.3 version: 5.8.2 + packages/email: + dependencies: + '@react-email/components': + specifier: ^0.0.36 + version: 0.0.36(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + react: + specifier: ^19.1.0 + version: 19.1.0 + react-dom: + specifier: ^19.1.0 + version: 19.1.0(react@19.1.0) + devDependencies: + '@types/react': + specifier: ^19.1.2 + version: 19.1.2 + '@types/react-dom': + specifier: ^19.1.2 + version: 19.1.2(@types/react@19.1.2) + react-email: + specifier: ^4.0.7 + version: 4.0.7(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + packages/mantine: dependencies: '@blocknote/core': @@ -3105,7 +3136,7 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) eslint: specifier: ^8.10.0 version: 8.57.1 @@ -3120,13 +3151,13 @@ importers: version: 5.8.2 vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite-plugin-externalize-deps: specifier: ^0.8.0 - version: 0.8.0(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 0.8.0(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) packages/react: dependencies: @@ -3178,7 +3209,7 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) eslint: specifier: ^8.10.0 version: 8.57.1 @@ -3199,16 +3230,16 @@ importers: version: 5.8.2 vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vite-plugin-externalize-deps: specifier: ^0.8.0 - version: 0.8.0(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 0.8.0(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vitest: specifier: ^2.0.3 - version: 2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) + version: 2.1.9(@types/node@22.14.1)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) packages/server-util: dependencies: @@ -3263,13 +3294,13 @@ importers: version: 5.8.2 vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vitest: specifier: ^2.0.3 - version: 2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) + version: 2.1.9(@types/node@22.14.1)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) packages/shadcn: dependencies: @@ -3424,13 +3455,13 @@ importers: version: 5.8.2 vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vitest: specifier: ^2.0.3 - version: 2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) + version: 2.1.9(@types/node@22.14.1)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) xml-formatter: specifier: ^3.6.3 version: 3.6.5 @@ -3497,13 +3528,13 @@ importers: version: 5.8.2 vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vitest: specifier: ^2.0.3 - version: 2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@21.1.2(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) + version: 2.1.9(@types/node@22.14.1)(@vitest/ui@2.1.9)(jsdom@21.1.2(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) packages/xl-odt-exporter: dependencies: @@ -3543,13 +3574,13 @@ importers: version: 5.8.2 vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vitest: specifier: ^2.0.3 - version: 2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) + version: 2.1.9(@types/node@22.14.1)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) xml-formatter: specifier: ^3.6.3 version: 3.6.5 @@ -3613,13 +3644,13 @@ importers: version: 5.8.2 vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) vitest: specifier: ^2.0.3 - version: 2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) + version: 2.1.9(@types/node@22.14.1)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) playground: dependencies: @@ -3761,7 +3792,7 @@ importers: version: 18.3.5(@types/react@18.3.20) '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) eslint: specifier: ^8.10.0 version: 8.57.1 @@ -3773,10 +3804,10 @@ importers: version: 0.2.6(rollup@4.37.0) vite: specifier: ^5.3.4 - version: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + version: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite-plugin-eslint: specifier: ^1.8.1 - version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + version: 1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) shared: dependencies: @@ -4164,6 +4195,11 @@ packages: resolution: {integrity: sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==} engines: {node: '>=6.9.0'} + '@babel/parser@7.24.5': + resolution: {integrity: sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/parser@7.27.0': resolution: {integrity: sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==} engines: {node: '>=6.0.0'} @@ -4701,6 +4737,10 @@ packages: resolution: {integrity: sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.25.6': + resolution: {integrity: sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==} + engines: {node: '>=6.9.0'} + '@babel/traverse@7.27.0': resolution: {integrity: sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==} engines: {node: '>=6.9.0'} @@ -4877,6 +4917,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.25.0': + resolution: {integrity: sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.25.1': resolution: {integrity: sha512-kfYGy8IdzTGy+z0vFGvExZtxkFlA4zAxgKEahG9KE1ScBjpQnFsNOX8KTU5ojNru5ed5CVoJYXFtoxaq5nFbjQ==} engines: {node: '>=18'} @@ -4895,6 +4941,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.25.0': + resolution: {integrity: sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.25.1': resolution: {integrity: sha512-50tM0zCJW5kGqgG7fQ7IHvQOcAn9TKiVRuQ/lN0xR+T2lzEFvAi1ZcS8DiksFcEpf1t/GYOeOfCAgDHFpkiSmA==} engines: {node: '>=18'} @@ -4913,6 +4965,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.25.0': + resolution: {integrity: sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.25.1': resolution: {integrity: sha512-dp+MshLYux6j/JjdqVLnMglQlFu+MuVeNrmT5nk6q07wNhCdSnB7QZj+7G8VMUGh1q+vj2Bq8kRsuyA00I/k+Q==} engines: {node: '>=18'} @@ -4931,6 +4989,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.25.0': + resolution: {integrity: sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.25.1': resolution: {integrity: sha512-GCj6WfUtNldqUzYkN/ITtlhwQqGWu9S45vUXs7EIYf+7rCiiqH9bCloatO9VhxsL0Pji+PF4Lz2XXCES+Q8hDw==} engines: {node: '>=18'} @@ -4949,6 +5013,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.25.0': + resolution: {integrity: sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.25.1': resolution: {integrity: sha512-5hEZKPf+nQjYoSr/elb62U19/l1mZDdqidGfmFutVUjjUZrOazAtwK+Kr+3y0C/oeJfLlxo9fXb1w7L+P7E4FQ==} engines: {node: '>=18'} @@ -4967,6 +5037,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.25.0': + resolution: {integrity: sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.25.1': resolution: {integrity: sha512-hxVnwL2Dqs3fM1IWq8Iezh0cX7ZGdVhbTfnOy5uURtao5OIVCEyj9xIzemDi7sRvKsuSdtCAhMKarxqtlyVyfA==} engines: {node: '>=18'} @@ -4985,6 +5061,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.25.0': + resolution: {integrity: sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.25.1': resolution: {integrity: sha512-1MrCZs0fZa2g8E+FUo2ipw6jw5qqQiH+tERoS5fAfKnRx6NXH31tXBKI3VpmLijLH6yriMZsxJtaXUyFt/8Y4A==} engines: {node: '>=18'} @@ -5003,6 +5085,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.25.0': + resolution: {integrity: sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.1': resolution: {integrity: sha512-0IZWLiTyz7nm0xuIs0q1Y3QWJC52R8aSXxe40VUxm6BB1RNmkODtW6LHvWRrGiICulcX7ZvyH6h5fqdLu4gkww==} engines: {node: '>=18'} @@ -5021,6 +5109,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.25.0': + resolution: {integrity: sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.25.1': resolution: {integrity: sha512-jaN3dHi0/DDPelk0nLcXRm1q7DNJpjXy7yWaWvbfkPvI+7XNSc/lDOnCLN7gzsyzgu6qSAmgSvP9oXAhP973uQ==} engines: {node: '>=18'} @@ -5039,6 +5133,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.25.0': + resolution: {integrity: sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.25.1': resolution: {integrity: sha512-NdKOhS4u7JhDKw9G3cY6sWqFcnLITn6SqivVArbzIaf3cemShqfLGHYMx8Xlm/lBit3/5d7kXvriTUGa5YViuQ==} engines: {node: '>=18'} @@ -5057,6 +5157,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.25.0': + resolution: {integrity: sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.25.1': resolution: {integrity: sha512-OJykPaF4v8JidKNGz8c/q1lBO44sQNUQtq1KktJXdBLn1hPod5rE/Hko5ugKKZd+D2+o1a9MFGUEIUwO2YfgkQ==} engines: {node: '>=18'} @@ -5075,6 +5181,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.25.0': + resolution: {integrity: sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.25.1': resolution: {integrity: sha512-nGfornQj4dzcq5Vp835oM/o21UMlXzn79KobKlcs3Wz9smwiifknLy4xDCLUU0BWp7b/houtdrgUz7nOGnfIYg==} engines: {node: '>=18'} @@ -5093,6 +5205,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.25.0': + resolution: {integrity: sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.25.1': resolution: {integrity: sha512-1osBbPEFYwIE5IVB/0g2X6i1qInZa1aIoj1TdL4AaAb55xIIgbg8Doq6a5BzYWgr+tEcDzYH67XVnTmUzL+nXg==} engines: {node: '>=18'} @@ -5111,6 +5229,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.25.0': + resolution: {integrity: sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.25.1': resolution: {integrity: sha512-/6VBJOwUf3TdTvJZ82qF3tbLuWsscd7/1w+D9LH0W/SqUgM5/JJD0lrJ1fVIfZsqB6RFmLCe0Xz3fmZc3WtyVg==} engines: {node: '>=18'} @@ -5129,6 +5253,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.25.0': + resolution: {integrity: sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.25.1': resolution: {integrity: sha512-nSut/Mx5gnilhcq2yIMLMe3Wl4FK5wx/o0QuuCLMtmJn+WeWYoEGDN1ipcN72g1WHsnIbxGXd4i/MF0gTcuAjQ==} engines: {node: '>=18'} @@ -5147,6 +5277,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.25.0': + resolution: {integrity: sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.25.1': resolution: {integrity: sha512-cEECeLlJNfT8kZHqLarDBQso9a27o2Zd2AQ8USAEoGtejOrCYHNtKP8XQhMDJMtthdF4GBmjR2au3x1udADQQQ==} engines: {node: '>=18'} @@ -5165,12 +5301,24 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.25.0': + resolution: {integrity: sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.25.1': resolution: {integrity: sha512-xbfUhu/gnvSEg+EGovRc+kjBAkrvtk38RlerAzQxvMzlB4fXpCFCeUAYzJvrnhFtdeyVCDANSjJvOvGYoeKzFA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/netbsd-arm64@0.25.0': + resolution: {integrity: sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-arm64@0.25.1': resolution: {integrity: sha512-O96poM2XGhLtpTh+s4+nP7YCCAfb4tJNRVZHfIE7dgmax+yMP2WgMd2OecBuaATHKTHsLWHQeuaxMRnCsH8+5g==} engines: {node: '>=18'} @@ -5189,12 +5337,24 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.25.0': + resolution: {integrity: sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.1': resolution: {integrity: sha512-X53z6uXip6KFXBQ+Krbx25XHV/NCbzryM6ehOAeAil7X7oa4XIq+394PWGnwaSQ2WRA0KI6PUO6hTO5zeF5ijA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/openbsd-arm64@0.25.0': + resolution: {integrity: sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-arm64@0.25.1': resolution: {integrity: sha512-Na9T3szbXezdzM/Kfs3GcRQNjHzM6GzFBeU1/6IV/npKP5ORtp9zbQjvkDJ47s6BCgaAZnnnu/cY1x342+MvZg==} engines: {node: '>=18'} @@ -5213,6 +5373,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.25.0': + resolution: {integrity: sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.1': resolution: {integrity: sha512-T3H78X2h1tszfRSf+txbt5aOp/e7TAz3ptVKu9Oyir3IAOFPGV6O9c2naym5TOriy1l0nNf6a4X5UXRZSGX/dw==} engines: {node: '>=18'} @@ -5231,6 +5397,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.25.0': + resolution: {integrity: sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.25.1': resolution: {integrity: sha512-2H3RUvcmULO7dIE5EWJH8eubZAI4xw54H1ilJnRNZdeo8dTADEZ21w6J22XBkXqGJbe0+wnNJtw3UXRoLJnFEg==} engines: {node: '>=18'} @@ -5249,6 +5421,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.25.0': + resolution: {integrity: sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.25.1': resolution: {integrity: sha512-GE7XvrdOzrb+yVKB9KsRMq+7a2U/K5Cf/8grVFRAGJmfADr/e/ODQ134RK2/eeHqYV5eQRFxb1hY7Nr15fv1NQ==} engines: {node: '>=18'} @@ -5267,6 +5445,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.25.0': + resolution: {integrity: sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.25.1': resolution: {integrity: sha512-uOxSJCIcavSiT6UnBhBzE8wy3n0hOkJsBOzy7HDAuTDE++1DJMRRVCPGisULScHL+a/ZwdXPpXD3IyFKjA7K8A==} engines: {node: '>=18'} @@ -5285,6 +5469,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.25.0': + resolution: {integrity: sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.25.1': resolution: {integrity: sha512-Y1EQdcfwMSeQN/ujR5VayLOJ1BHaK+ssyk0AEzPjC+t1lITgsnccPqFjb6V+LsTp/9Iov4ysfjxLaGJ9RPtkVg==} engines: {node: '>=18'} @@ -6193,11 +6383,11 @@ packages: peerDependencies: next: ^15.0.0 || ^15.2.0-canary.* - '@polar-sh/sdk@0.32.10': - resolution: {integrity: sha512-k7og3L1RP7kTRFVSxiVF4GIkTy/JQwfUY4D1aqSEnj3OtR13NjHsAW2Rb6bEJDuws2/bzfAVQvbQTxf+VsmK9A==} + '@polar-sh/sdk@0.32.11': + resolution: {integrity: sha512-GmMDrWyJJnM45rByMRkY8U8DYbL2ggJNohhTc/9naMlGHnP3+RRgIG9IG6yxuXfQ1wljKyoViHAWCAGCvS3DPA==} hasBin: true peerDependencies: - '@modelcontextprotocol/sdk': ^1.5.0 + '@modelcontextprotocol/sdk': '>=1.5.0 <1.10.0' zod: '>= 3' peerDependenciesMeta: '@modelcontextprotocol/sdk': @@ -6603,6 +6793,131 @@ packages: '@radix-ui/rect@1.1.0': resolution: {integrity: sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==} + '@react-email/body@0.0.11': + resolution: {integrity: sha512-ZSD2SxVSgUjHGrB0Wi+4tu3MEpB4fYSbezsFNEJk2xCWDBkFiOeEsjTmR5dvi+CxTK691hQTQlHv0XWuP7ENTg==} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/button@0.0.19': + resolution: {integrity: sha512-HYHrhyVGt7rdM/ls6FuuD6XE7fa7bjZTJqB2byn6/oGsfiEZaogY77OtoLL/mrQHjHjZiJadtAMSik9XLcm7+A==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/code-block@0.0.12': + resolution: {integrity: sha512-Faw3Ij9+/Qwq6moWaeHnV8Hn7ekc/EqyAzPi6yUar21dhcqYugCC4Da1x4d9nA9zC0H9KU3lYVJczh8D3cA+Eg==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/code-inline@0.0.5': + resolution: {integrity: sha512-MmAsOzdJpzsnY2cZoPHFPk6uDO/Ncpb4Kh1hAt9UZc1xOW3fIzpe1Pi9y9p6wwUmpaeeDalJxAxH6/fnTquinA==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/column@0.0.13': + resolution: {integrity: sha512-Lqq17l7ShzJG/d3b1w/+lVO+gp2FM05ZUo/nW0rjxB8xBICXOVv6PqjDnn3FXKssvhO5qAV20lHM6S+spRhEwQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/components@0.0.36': + resolution: {integrity: sha512-VMh+OQplAnG8JMLlJjdnjt+ThJZ+JVkp0q2YMS2NEz+T88N22bLD2p7DZO0QgtNaKgumOhJI/0a2Q7VzCrwu5g==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/container@0.0.15': + resolution: {integrity: sha512-Qo2IQo0ru2kZq47REmHW3iXjAQaKu4tpeq/M8m1zHIVwKduL2vYOBQWbC2oDnMtWPmkBjej6XxgtZByxM6cCFg==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/font@0.0.9': + resolution: {integrity: sha512-4zjq23oT9APXkerqeslPH3OZWuh5X4crHK6nx82mVHV2SrLba8+8dPEnWbaACWTNjOCbcLIzaC9unk7Wq2MIXw==} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/head@0.0.12': + resolution: {integrity: sha512-X2Ii6dDFMF+D4niNwMAHbTkeCjlYYnMsd7edXOsi0JByxt9wNyZ9EnhFiBoQdqkE+SMDcu8TlNNttMrf5sJeMA==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/heading@0.0.15': + resolution: {integrity: sha512-xF2GqsvBrp/HbRHWEfOgSfRFX+Q8I5KBEIG5+Lv3Vb2R/NYr0s8A5JhHHGf2pWBMJdbP4B2WHgj/VUrhy8dkIg==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/hr@0.0.11': + resolution: {integrity: sha512-S1gZHVhwOsd1Iad5IFhpfICwNPMGPJidG/Uysy1AwmspyoAP5a4Iw3OWEpINFdgh9MHladbxcLKO2AJO+cA9Lw==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/html@0.0.11': + resolution: {integrity: sha512-qJhbOQy5VW5qzU74AimjAR9FRFQfrMa7dn4gkEXKMB/S9xZN8e1yC1uA9C15jkXI/PzmJ0muDIWmFwatm5/+VA==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/img@0.0.11': + resolution: {integrity: sha512-aGc8Y6U5C3igoMaqAJKsCpkbm1XjguQ09Acd+YcTKwjnC2+0w3yGUJkjWB2vTx4tN8dCqQCXO8FmdJpMfOA9EQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/link@0.0.12': + resolution: {integrity: sha512-vF+xxQk2fGS1CN7UPQDbzvcBGfffr+GjTPNiWM38fhBfsLv6A/YUfaqxWlmL7zLzVmo0K2cvvV9wxlSyNba1aQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/markdown@0.0.14': + resolution: {integrity: sha512-5IsobCyPkb4XwnQO8uFfGcNOxnsg3311GRXhJ3uKv51P7Jxme4ycC/MITnwIZ10w2zx7HIyTiqVzTj4XbuIHbg==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/preview@0.0.12': + resolution: {integrity: sha512-g/H5fa9PQPDK6WUEG7iTlC19sAktI23qyoiJtMLqQiXFCfWeQMhqjLGKeLSKkfzszqmfJCjZtpSiKtBoOdxp3Q==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/render@1.0.6': + resolution: {integrity: sha512-zNueW5Wn/4jNC1c5LFgXzbUdv5Lhms+FWjOvWAhal7gx5YVf0q6dPJ0dnR70+ifo59gcMLwCZEaTS9EEuUhKvQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/row@0.0.12': + resolution: {integrity: sha512-HkCdnEjvK3o+n0y0tZKXYhIXUNPDx+2vq1dJTmqappVHXS5tXS6W5JOPZr5j+eoZ8gY3PShI2LWj5rWF7ZEtIQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/section@0.0.16': + resolution: {integrity: sha512-FjqF9xQ8FoeUZYKSdt8sMIKvoT9XF8BrzhT3xiFKdEMwYNbsDflcjfErJe3jb7Wj/es/lKTbV5QR1dnLzGpL3w==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/tailwind@1.0.4': + resolution: {integrity: sha512-tJdcusncdqgvTUYZIuhNC6LYTfL9vNTSQpwWdTCQhQ1lsrNCEE4OKCSdzSV3S9F32pi0i0xQ+YPJHKIzGjdTSA==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + + '@react-email/text@0.1.1': + resolution: {integrity: sha512-Zo9tSEzkO3fODLVH1yVhzVCiwETfeEL5wU93jXKWo2DHoMuiZ9Iabaso3T0D0UjhrCB1PBMeq2YiejqeToTyIQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^18.0 || ^19.0 || ^19.0.0-rc + '@react-pdf/fns@3.1.2': resolution: {integrity: sha512-qTKGUf0iAMGg2+OsUcp9ffKnKi41RukM/zYIWMDJ4hRVYSr89Q7e3wSDW/Koqx3ea3Uy/z3h2y3wPX6Bdfxk6g==} @@ -6785,6 +7100,9 @@ packages: '@rushstack/eslint-patch@1.11.0': resolution: {integrity: sha512-zxnHvoMQVqewTJr/W4pKjF0bMGiKJv1WX7bSrkl46Hg0QjESbzBROWK0Wg4RphzSOS5Jiy7eFimmM3UgMrMZbQ==} + '@selderee/plugin-htmlparser2@0.11.0': + resolution: {integrity: sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==} + '@sentry-internal/browser-utils@9.4.0': resolution: {integrity: sha512-huoSluJhyhN/EFXpRhUIFg0DQICrE9bCGZ4TBSG7l0zOVm3i957W5pUiE5qQkR7wmAfCuJ8Dh/tgo4ngSA21Gg==} engines: {node: '>=18'} @@ -7158,6 +7476,9 @@ packages: resolution: {integrity: sha512-JtaY3FxmD+te+KSI2FJuEcfNC9T/DGGVf551babM7fAaXhjJUt7oSYurH1Devxd2+BOSUACCgt3buinx4UnmEA==} engines: {node: '>=18.0.0'} + '@socket.io/component-emitter@3.1.2': + resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + '@stablelib/base64@1.0.1': resolution: {integrity: sha512-1bnPQqSxSuc3Ii6MhBysoWCg58j97aUjuCSZrGSmDxNqtytIi0k8utUenAwTZN4V5mXXYGsVUI9zeBqy+jBOSQ==} @@ -7361,6 +7682,9 @@ packages: '@types/cookie@0.6.0': resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + '@types/cors@2.8.17': + resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} + '@types/d3-scale-chromatic@3.1.0': resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} @@ -7475,6 +7799,9 @@ packages: '@types/node@22.13.13': resolution: {integrity: sha512-ClsL5nMwKaBRwPcCvH8E7+nU4GxHVx1axNvMZTFHMEfNI7oahimt26P5zjVCRrjiIWj6YFXfE1v3dEp94wLcGQ==} + '@types/node@22.14.1': + resolution: {integrity: sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==} + '@types/nodemailer@6.4.17': resolution: {integrity: sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww==} @@ -7498,6 +7825,11 @@ packages: peerDependencies: '@types/react': ^18.0.0 + '@types/react-dom@19.1.2': + resolution: {integrity: sha512-XGJkWF41Qq305SKWEILa1O8vzhb3aOo3ogBlSmiqNko/WmRb6QIaweuZCXjKygVDXpzXb5wyxKTSOsmkuqj+Qw==} + peerDependencies: + '@types/react': ^19.0.0 + '@types/react-transition-group@4.4.12': resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==} peerDependencies: @@ -7506,8 +7838,8 @@ packages: '@types/react@18.3.20': resolution: {integrity: sha512-IPaCZN7PShZK/3t6Q87pfTkRm6oLTd4vztyoj+cbHUF1g3FfVb2tFIL79uCRKEfv16AhqDMBywP2VW3KIZUvcg==} - '@types/react@19.0.12': - resolution: {integrity: sha512-V6Ar115dBDrjbtXSrS+/Oruobc+qVbbUxDFC1RSbRqLt5SYvxxyIDrSC85RWml54g+jfNeEMZhEj7wW07ONQhA==} + '@types/react@19.1.2': + resolution: {integrity: sha512-oxLPMytKchWGbnQM9O7D67uPa9paTNxO7jVoNMXgkkErULBPhPARCfkKL9ytcIJJRGjbsVwW4ugJzyFFvm/Tiw==} '@types/retry@0.12.2': resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} @@ -8224,6 +8556,10 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + base64id@2.0.0: + resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} + engines: {node: ^4.5.0 || >= 5.9} + better-auth@1.2.7: resolution: {integrity: sha512-2hCB263GSrgetsMUZw8vv9O1e4S4AlYJW3P4e8bX9u3Q3idv4u9BzDFCblpTLuL4YjYovghMCN0vurAsctXOAQ==} @@ -8386,6 +8722,10 @@ packages: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} @@ -8498,6 +8838,10 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -8565,6 +8909,10 @@ packages: core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + cose-base@1.0.3: resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} @@ -8804,6 +9152,10 @@ packages: debounce@1.2.1: resolution: {integrity: sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==} + debounce@2.0.0: + resolution: {integrity: sha512-xRetU6gL1VJbs85Mc4FoEGSjQxzpdxRyFhe3lmWFyy2EzydIcD4xzUvRJMD+NPDfMwKNhxa3PvsIOU32luIWeA==} + engines: {node: '>=18'} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -8820,6 +9172,15 @@ packages: supports-color: optional: true + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.0: resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} @@ -8854,6 +9215,10 @@ packages: deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + defaults@1.0.4: resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} @@ -8944,14 +9309,27 @@ packages: dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + domexception@4.0.0: resolution: {integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==} engines: {node: '>=12'} deprecated: Use your platform's native DOMException instead + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + dompurify@3.1.6: resolution: {integrity: sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==} + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + dotenv-expand@11.0.7: resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} engines: {node: '>=12'} @@ -9006,6 +9384,14 @@ packages: end-of-stream@1.4.4: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + engine.io-parser@5.2.3: + resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} + engines: {node: '>=10.0.0'} + + engine.io@6.6.4: + resolution: {integrity: sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==} + engines: {node: '>=10.2.0'} + enhanced-resolve@5.18.1: resolution: {integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==} engines: {node: '>=10.13.0'} @@ -9066,6 +9452,11 @@ packages: engines: {node: '>=12'} hasBin: true + esbuild@0.25.0: + resolution: {integrity: sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==} + engines: {node: '>=18'} + hasBin: true + esbuild@0.25.1: resolution: {integrity: sha512-BGO5LtrGC7vxnqucAe/rmvKdJllfGaYWdyABvyMoXQlfYMb2bbRuReWR5tEGE//4LcNJj9XrkovTqNYRFZHAMQ==} engines: {node: '>=18'} @@ -9337,6 +9728,9 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + fast-deep-equal@2.0.1: + resolution: {integrity: sha512-bCK/2Z4zLidyB4ReuIsvALH6w31YfAQDmXMqMx6FyfHqvBxtjC0eRumeSu4Bs3XtXwpyIywtSTrVT99BxY1f9w==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -9583,6 +9977,11 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true + glob@10.3.4: + resolution: {integrity: sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==} + engines: {node: '>=16 || 14 >=14.17'} + hasBin: true + glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} hasBin: true @@ -9767,6 +10166,10 @@ packages: html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + html-to-text@9.0.5: + resolution: {integrity: sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==} + engines: {node: '>=14'} + html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} @@ -9776,6 +10179,9 @@ packages: htmlfy@0.6.7: resolution: {integrity: sha512-r8hRd+oIM10lufovN+zr3VKPTYEIvIwqXGucidh2XQufmiw6sbUXFUFjWlfjo3AnefIDTyzykVzQ8IUVuT1peQ==} + htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + http-proxy-agent@5.0.0: resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} engines: {node: '>= 6'} @@ -10278,6 +10684,9 @@ packages: layout-base@1.0.2: resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + leac@0.6.0: + resolution: {integrity: sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -10392,6 +10801,11 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + marked@7.0.4: + resolution: {integrity: sha512-t8eP0dXRJMtMvBojtkcsA7n48BkauktUKzfkPSCq85ZMTJ0v76Rke4DYz01omYpPTUh4p/f7HePgRo3ebG8+QQ==} + engines: {node: '>= 16'} + hasBin: true + match-sorter@6.3.4: resolution: {integrity: sha512-jfZW7cWS5y/1xswZo8VBOdudUiSd9nifYRWphc9M5D/ee4w4AoXLgBEdRbgVaxbMuagBPeUC5y2Hi8DO6o9aDg==} @@ -10399,6 +10813,11 @@ packages: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} + md-to-react-email@5.0.5: + resolution: {integrity: sha512-OvAXqwq57uOk+WZqFFNCMZz8yDp8BD3WazW1wAKHUrPbbdr89K9DWS6JXY09vd9xNdPNeurI8DU/X4flcfaD8A==} + peerDependencies: + react: ^18.0 || ^19.0 + mdast-util-definitions@5.1.2: resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==} @@ -11096,6 +11515,10 @@ packages: resolution: {integrity: sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==} engines: {node: '>=10'} + ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + orderedmap@2.1.1: resolution: {integrity: sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==} @@ -11165,6 +11588,9 @@ packages: parse5@7.2.1: resolution: {integrity: sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==} + parseley@0.12.1: + resolution: {integrity: sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==} + partykit@0.0.84: resolution: {integrity: sha512-qY9WfnEsOPVIYMmPuFye4H0V9JqKt3/Ylu2IBlJNEGTI4OQ9MJp/D24mznE5/KorfaL35MQSGmSuYbrOHa4Jwg==} hasBin: true @@ -11226,6 +11652,9 @@ packages: resolution: {integrity: sha512-rJmuBDFpD7cqC8WIkQUEClyB4UAH05K4AsyewToMTp2gSy3Rrx8c1ydAVqlJlGv3yZSOrhEERQU/4ScQQFlLHA==} engines: {node: '>=18'} + peberminta@0.9.0: + resolution: {integrity: sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==} + periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} @@ -11440,6 +11869,10 @@ packages: printable-characters@1.0.42: resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==} + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + proc-log@3.0.0: resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -11614,12 +12047,22 @@ packages: peerDependencies: react: ^18.3.1 + react-dom@19.1.0: + resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} + peerDependencies: + react: ^19.1.0 + react-element-to-jsx-string@15.0.0: resolution: {integrity: sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==} peerDependencies: react: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0 react-dom: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0 + react-email@4.0.7: + resolution: {integrity: sha512-XCXlfZLKv9gHd/ZwUEhCpRGc/FJLZGYczeuG1kVR/be2PlkwEB4gjX9ARBbRFv86ncbtpOu/wI6jD6kadRyAKw==} + engines: {node: '>=18.0.0'} + hasBin: true + react-github-btn@1.4.0: resolution: {integrity: sha512-lV4FYClAfjWnBfv0iNlJUGhamDgIq6TayD0kPZED6VzHWdpcHmPfsYOZ/CFwLfPv4Zp+F4m8QKTj0oy2HjiGXg==} peerDependencies: @@ -11657,6 +12100,9 @@ packages: react: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^0.14 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-promise-suspense@0.3.4: + resolution: {integrity: sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ==} + react-refresh@0.14.2: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} @@ -11720,6 +12166,10 @@ packages: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} + react@19.1.0: + resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} + engines: {node: '>=0.10.0'} + read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} @@ -11734,6 +12184,10 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + reading-time@1.5.0: resolution: {integrity: sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==} @@ -12006,12 +12460,15 @@ packages: scheduler@0.25.0-rc-603e6108-20241029: resolution: {integrity: sha512-pFwF6H1XrSdYYNLfOcGlM28/j8CGLu8IvdrxqhjWULe2bPcKiKW4CV+OWqR/9fT52mywx65l7ysNkjLKBda7eA==} + scheduler@0.26.0: + resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} + schema-utils@3.3.0: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} - schema-utils@4.3.0: - resolution: {integrity: sha512-Gf9qqc58SpCA/xdziiHz35F4GNIWYWZrEshUc/G/r5BnLph6xpKuLeoJoQuj5WfBIx/eQLf+hmVPYHaxJu7V2g==} + schema-utils@4.3.1: + resolution: {integrity: sha512-jjlZ7UknkyQxGnHF1w8wDgWfdtnW0hBX7tmDp04zBwDBZ/6tPJI1+RWfBHGMA4+0nAjGptp+eDpIYP6mldJbqg==} engines: {node: '>= 10.13.0'} scroll-into-view-if-needed@3.1.0: @@ -12021,6 +12478,9 @@ packages: resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==} engines: {node: '>=4'} + selderee@0.11.0: + resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==} + semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -12162,6 +12622,17 @@ packages: slate@0.110.2: resolution: {integrity: sha512-4xGULnyMCiEQ0Ml7JAC1A6HVE6MNpPJU7Eq4cXh1LxlrR0dFXC3XC+rNfQtUJ7chHoPkws57x7DDiWiZAt+PBA==} + socket.io-adapter@2.5.5: + resolution: {integrity: sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==} + + socket.io-parser@4.2.4: + resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} + engines: {node: '>=10.0.0'} + + socket.io@4.8.1: + resolution: {integrity: sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==} + engines: {node: '>=10.2.0'} + sort-keys@5.1.0: resolution: {integrity: sha512-aSbHV0DaBcr7u0PVHXzM6NbZNAtrr9sF6+Qfs9UUVG7Ll3jQ6hHi8F/xqIIcn2rvIVbr0v/2zyjSdwSV47AgLQ==} engines: {node: '>=12'} @@ -12616,6 +13087,9 @@ packages: undici-types@6.20.0: resolution: {integrity: sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==} + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici@5.29.0: resolution: {integrity: sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==} engines: {node: '>=14.0'} @@ -13063,6 +13537,18 @@ packages: utf-8-validate: optional: true + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + ws@8.18.1: resolution: {integrity: sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==} engines: {node: '>=10.0.0'} @@ -13874,6 +14360,10 @@ snapshots: '@babel/template': 7.27.0 '@babel/types': 7.27.0 + '@babel/parser@7.24.5': + dependencies: + '@babel/types': 7.27.0 + '@babel/parser@7.27.0': dependencies: '@babel/types': 7.27.0 @@ -14531,7 +15021,7 @@ snapshots: '@babel/parser': 7.27.0 '@babel/types': 7.27.0 - '@babel/traverse@7.27.0': + '@babel/traverse@7.25.6': dependencies: '@babel/code-frame': 7.26.2 '@babel/generator': 7.27.0 @@ -14543,7 +15033,19 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/types@7.27.0': + '@babel/traverse@7.27.0': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.27.0 + '@babel/parser': 7.27.0 + '@babel/template': 7.27.0 + '@babel/types': 7.27.0 + debug: 4.4.0 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.27.0': dependencies: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 @@ -14716,6 +15218,9 @@ snapshots: '@esbuild/aix-ppc64@0.21.5': optional: true + '@esbuild/aix-ppc64@0.25.0': + optional: true + '@esbuild/aix-ppc64@0.25.1': optional: true @@ -14725,6 +15230,9 @@ snapshots: '@esbuild/android-arm64@0.21.5': optional: true + '@esbuild/android-arm64@0.25.0': + optional: true + '@esbuild/android-arm64@0.25.1': optional: true @@ -14734,6 +15242,9 @@ snapshots: '@esbuild/android-arm@0.21.5': optional: true + '@esbuild/android-arm@0.25.0': + optional: true + '@esbuild/android-arm@0.25.1': optional: true @@ -14743,6 +15254,9 @@ snapshots: '@esbuild/android-x64@0.21.5': optional: true + '@esbuild/android-x64@0.25.0': + optional: true + '@esbuild/android-x64@0.25.1': optional: true @@ -14752,6 +15266,9 @@ snapshots: '@esbuild/darwin-arm64@0.21.5': optional: true + '@esbuild/darwin-arm64@0.25.0': + optional: true + '@esbuild/darwin-arm64@0.25.1': optional: true @@ -14761,6 +15278,9 @@ snapshots: '@esbuild/darwin-x64@0.21.5': optional: true + '@esbuild/darwin-x64@0.25.0': + optional: true + '@esbuild/darwin-x64@0.25.1': optional: true @@ -14770,6 +15290,9 @@ snapshots: '@esbuild/freebsd-arm64@0.21.5': optional: true + '@esbuild/freebsd-arm64@0.25.0': + optional: true + '@esbuild/freebsd-arm64@0.25.1': optional: true @@ -14779,6 +15302,9 @@ snapshots: '@esbuild/freebsd-x64@0.21.5': optional: true + '@esbuild/freebsd-x64@0.25.0': + optional: true + '@esbuild/freebsd-x64@0.25.1': optional: true @@ -14788,6 +15314,9 @@ snapshots: '@esbuild/linux-arm64@0.21.5': optional: true + '@esbuild/linux-arm64@0.25.0': + optional: true + '@esbuild/linux-arm64@0.25.1': optional: true @@ -14797,6 +15326,9 @@ snapshots: '@esbuild/linux-arm@0.21.5': optional: true + '@esbuild/linux-arm@0.25.0': + optional: true + '@esbuild/linux-arm@0.25.1': optional: true @@ -14806,6 +15338,9 @@ snapshots: '@esbuild/linux-ia32@0.21.5': optional: true + '@esbuild/linux-ia32@0.25.0': + optional: true + '@esbuild/linux-ia32@0.25.1': optional: true @@ -14815,6 +15350,9 @@ snapshots: '@esbuild/linux-loong64@0.21.5': optional: true + '@esbuild/linux-loong64@0.25.0': + optional: true + '@esbuild/linux-loong64@0.25.1': optional: true @@ -14824,6 +15362,9 @@ snapshots: '@esbuild/linux-mips64el@0.21.5': optional: true + '@esbuild/linux-mips64el@0.25.0': + optional: true + '@esbuild/linux-mips64el@0.25.1': optional: true @@ -14833,6 +15374,9 @@ snapshots: '@esbuild/linux-ppc64@0.21.5': optional: true + '@esbuild/linux-ppc64@0.25.0': + optional: true + '@esbuild/linux-ppc64@0.25.1': optional: true @@ -14842,6 +15386,9 @@ snapshots: '@esbuild/linux-riscv64@0.21.5': optional: true + '@esbuild/linux-riscv64@0.25.0': + optional: true + '@esbuild/linux-riscv64@0.25.1': optional: true @@ -14851,6 +15398,9 @@ snapshots: '@esbuild/linux-s390x@0.21.5': optional: true + '@esbuild/linux-s390x@0.25.0': + optional: true + '@esbuild/linux-s390x@0.25.1': optional: true @@ -14860,9 +15410,15 @@ snapshots: '@esbuild/linux-x64@0.21.5': optional: true + '@esbuild/linux-x64@0.25.0': + optional: true + '@esbuild/linux-x64@0.25.1': optional: true + '@esbuild/netbsd-arm64@0.25.0': + optional: true + '@esbuild/netbsd-arm64@0.25.1': optional: true @@ -14872,9 +15428,15 @@ snapshots: '@esbuild/netbsd-x64@0.21.5': optional: true + '@esbuild/netbsd-x64@0.25.0': + optional: true + '@esbuild/netbsd-x64@0.25.1': optional: true + '@esbuild/openbsd-arm64@0.25.0': + optional: true + '@esbuild/openbsd-arm64@0.25.1': optional: true @@ -14884,6 +15446,9 @@ snapshots: '@esbuild/openbsd-x64@0.21.5': optional: true + '@esbuild/openbsd-x64@0.25.0': + optional: true + '@esbuild/openbsd-x64@0.25.1': optional: true @@ -14893,6 +15458,9 @@ snapshots: '@esbuild/sunos-x64@0.21.5': optional: true + '@esbuild/sunos-x64@0.25.0': + optional: true + '@esbuild/sunos-x64@0.25.1': optional: true @@ -14902,6 +15470,9 @@ snapshots: '@esbuild/win32-arm64@0.21.5': optional: true + '@esbuild/win32-arm64@0.25.0': + optional: true + '@esbuild/win32-arm64@0.25.1': optional: true @@ -14911,6 +15482,9 @@ snapshots: '@esbuild/win32-ia32@0.21.5': optional: true + '@esbuild/win32-ia32@0.25.0': + optional: true + '@esbuild/win32-ia32@0.25.1': optional: true @@ -14920,6 +15494,9 @@ snapshots: '@esbuild/win32-x64@0.21.5': optional: true + '@esbuild/win32-x64@0.25.0': + optional: true + '@esbuild/win32-x64@0.25.1': optional: true @@ -15960,27 +16537,27 @@ snapshots: '@polar-sh/adapter-utils@0.1.15(zod@3.24.2)': dependencies: - '@polar-sh/sdk': 0.32.10(zod@3.24.2) + '@polar-sh/sdk': 0.32.11(zod@3.24.2) transitivePeerDependencies: - '@modelcontextprotocol/sdk' - zod - '@polar-sh/better-auth@0.1.0(@polar-sh/sdk@0.32.10(zod@3.24.2))(better-auth@1.2.7)': + '@polar-sh/better-auth@0.1.0(@polar-sh/sdk@0.32.11(zod@3.24.2))(better-auth@1.2.7)': dependencies: - '@polar-sh/sdk': 0.32.10(zod@3.24.2) + '@polar-sh/sdk': 0.32.11(zod@3.24.2) better-auth: 1.2.7 zod: 3.24.2 '@polar-sh/nextjs@0.3.23(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(zod@3.24.2)': dependencies: '@polar-sh/adapter-utils': 0.1.15(zod@3.24.2) - '@polar-sh/sdk': 0.32.10(zod@3.24.2) + '@polar-sh/sdk': 0.32.11(zod@3.24.2) next: 15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) transitivePeerDependencies: - '@modelcontextprotocol/sdk' - zod - '@polar-sh/sdk@0.32.10(zod@3.24.2)': + '@polar-sh/sdk@0.32.11(zod@3.24.2)': dependencies: standardwebhooks: 1.0.0 zod: 3.24.2 @@ -16389,6 +16966,230 @@ snapshots: '@radix-ui/rect@1.1.0': {} + '@react-email/body@0.0.11(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/body@0.0.11(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/button@0.0.19(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/button@0.0.19(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/code-block@0.0.12(react@18.3.1)': + dependencies: + prismjs: 1.30.0 + react: 18.3.1 + + '@react-email/code-block@0.0.12(react@19.1.0)': + dependencies: + prismjs: 1.30.0 + react: 19.1.0 + + '@react-email/code-inline@0.0.5(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/code-inline@0.0.5(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/column@0.0.13(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/column@0.0.13(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/components@0.0.36(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + '@react-email/body': 0.0.11(react@18.3.1) + '@react-email/button': 0.0.19(react@18.3.1) + '@react-email/code-block': 0.0.12(react@18.3.1) + '@react-email/code-inline': 0.0.5(react@18.3.1) + '@react-email/column': 0.0.13(react@18.3.1) + '@react-email/container': 0.0.15(react@18.3.1) + '@react-email/font': 0.0.9(react@18.3.1) + '@react-email/head': 0.0.12(react@18.3.1) + '@react-email/heading': 0.0.15(react@18.3.1) + '@react-email/hr': 0.0.11(react@18.3.1) + '@react-email/html': 0.0.11(react@18.3.1) + '@react-email/img': 0.0.11(react@18.3.1) + '@react-email/link': 0.0.12(react@18.3.1) + '@react-email/markdown': 0.0.14(react@18.3.1) + '@react-email/preview': 0.0.12(react@18.3.1) + '@react-email/render': 1.0.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@react-email/row': 0.0.12(react@18.3.1) + '@react-email/section': 0.0.16(react@18.3.1) + '@react-email/tailwind': 1.0.4(react@18.3.1) + '@react-email/text': 0.1.1(react@18.3.1) + react: 18.3.1 + transitivePeerDependencies: + - react-dom + + '@react-email/components@0.0.36(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + '@react-email/body': 0.0.11(react@19.1.0) + '@react-email/button': 0.0.19(react@19.1.0) + '@react-email/code-block': 0.0.12(react@19.1.0) + '@react-email/code-inline': 0.0.5(react@19.1.0) + '@react-email/column': 0.0.13(react@19.1.0) + '@react-email/container': 0.0.15(react@19.1.0) + '@react-email/font': 0.0.9(react@19.1.0) + '@react-email/head': 0.0.12(react@19.1.0) + '@react-email/heading': 0.0.15(react@19.1.0) + '@react-email/hr': 0.0.11(react@19.1.0) + '@react-email/html': 0.0.11(react@19.1.0) + '@react-email/img': 0.0.11(react@19.1.0) + '@react-email/link': 0.0.12(react@19.1.0) + '@react-email/markdown': 0.0.14(react@19.1.0) + '@react-email/preview': 0.0.12(react@19.1.0) + '@react-email/render': 1.0.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + '@react-email/row': 0.0.12(react@19.1.0) + '@react-email/section': 0.0.16(react@19.1.0) + '@react-email/tailwind': 1.0.4(react@19.1.0) + '@react-email/text': 0.1.1(react@19.1.0) + react: 19.1.0 + transitivePeerDependencies: + - react-dom + + '@react-email/container@0.0.15(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/container@0.0.15(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/font@0.0.9(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/font@0.0.9(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/head@0.0.12(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/head@0.0.12(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/heading@0.0.15(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/heading@0.0.15(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/hr@0.0.11(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/hr@0.0.11(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/html@0.0.11(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/html@0.0.11(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/img@0.0.11(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/img@0.0.11(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/link@0.0.12(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/link@0.0.12(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/markdown@0.0.14(react@18.3.1)': + dependencies: + md-to-react-email: 5.0.5(react@18.3.1) + react: 18.3.1 + + '@react-email/markdown@0.0.14(react@19.1.0)': + dependencies: + md-to-react-email: 5.0.5(react@19.1.0) + react: 19.1.0 + + '@react-email/preview@0.0.12(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/preview@0.0.12(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/render@1.0.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + dependencies: + html-to-text: 9.0.5 + prettier: 3.5.3 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-promise-suspense: 0.3.4 + + '@react-email/render@1.0.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': + dependencies: + html-to-text: 9.0.5 + prettier: 3.5.3 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + react-promise-suspense: 0.3.4 + + '@react-email/row@0.0.12(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/row@0.0.12(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/section@0.0.16(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/section@0.0.16(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/tailwind@1.0.4(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/tailwind@1.0.4(react@19.1.0)': + dependencies: + react: 19.1.0 + + '@react-email/text@0.1.1(react@18.3.1)': + dependencies: + react: 18.3.1 + + '@react-email/text@0.1.1(react@19.1.0)': + dependencies: + react: 19.1.0 + '@react-pdf/fns@3.1.2': {} '@react-pdf/font@4.0.2': @@ -16585,6 +17386,11 @@ snapshots: '@rushstack/eslint-patch@1.11.0': {} + '@selderee/plugin-htmlparser2@0.11.0': + dependencies: + domhandler: 5.0.3 + selderee: 0.11.0 + '@sentry-internal/browser-utils@9.4.0': dependencies: '@sentry/core': 9.4.0 @@ -17158,6 +17964,8 @@ snapshots: '@smithy/types': 4.2.0 tslib: 2.8.1 + '@socket.io/component-emitter@3.1.2': {} + '@stablelib/base64@1.0.1': {} '@swc/counter@0.1.3': {} @@ -17379,6 +18187,10 @@ snapshots: '@types/cookie@0.6.0': {} + '@types/cors@2.8.17': + dependencies: + '@types/node': 20.17.30 + '@types/d3-scale-chromatic@3.1.0': {} '@types/d3-scale@4.0.9': @@ -17393,7 +18205,7 @@ snapshots: '@types/emoji-mart@3.0.14': dependencies: - '@types/react': 19.0.12 + '@types/react': 19.1.2 '@types/eslint-scope@3.7.7': dependencies: @@ -17512,6 +18324,11 @@ snapshots: dependencies: undici-types: 6.20.0 + '@types/node@22.14.1': + dependencies: + undici-types: 6.21.0 + optional: true + '@types/nodemailer@6.4.17': dependencies: '@types/node': 20.17.30 @@ -17538,6 +18355,10 @@ snapshots: dependencies: '@types/react': 18.3.20 + '@types/react-dom@19.1.2(@types/react@19.1.2)': + dependencies: + '@types/react': 19.1.2 + '@types/react-transition-group@4.4.12(@types/react@18.3.20)': dependencies: '@types/react': 18.3.20 @@ -17547,7 +18368,7 @@ snapshots: '@types/prop-types': 15.7.14 csstype: 3.1.3 - '@types/react@19.0.12': + '@types/react@19.1.2': dependencies: csstype: 3.1.3 @@ -17869,14 +18690,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-react@4.3.4(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0))': + '@vitejs/plugin-react@4.3.4(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0))': dependencies: '@babel/core': 7.26.10 '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.10) '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.10) '@types/babel__core': 7.20.5 react-refresh: 0.14.2 - vite: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + vite: 5.4.15(@types/node@22.14.1)(terser@5.39.0) transitivePeerDependencies: - supports-color @@ -17895,13 +18716,13 @@ snapshots: optionalDependencies: vite: 5.4.15(@types/node@20.17.28)(terser@5.39.0) - '@vitest/mocker@2.1.9(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0))': + '@vitest/mocker@2.1.9(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0))': dependencies: '@vitest/spy': 2.1.9 estree-walker: 3.0.3 magic-string: 0.30.17 optionalDependencies: - vite: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + vite: 5.4.15(@types/node@22.14.1)(terser@5.39.0) '@vitest/pretty-format@2.1.9': dependencies: @@ -17931,7 +18752,7 @@ snapshots: sirv: 3.0.1 tinyglobby: 0.2.12 tinyrainbow: 1.2.0 - vitest: 2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) + vitest: 2.1.9(@types/node@22.14.1)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0) '@vitest/utils@2.1.9': dependencies: @@ -18382,6 +19203,8 @@ snapshots: base64-js@1.5.1: {} + base64id@2.0.0: {} + better-auth@1.2.7: dependencies: '@better-auth/utils': 0.2.4 @@ -18591,6 +19414,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + chownr@1.1.4: {} chownr@2.0.0: @@ -18698,6 +19525,8 @@ snapshots: comma-separated-tokens@2.0.3: {} + commander@11.1.0: {} + commander@2.20.3: {} commander@4.1.1: {} @@ -18759,6 +19588,11 @@ snapshots: core-util-is@1.0.3: {} + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + cose-base@1.0.3: dependencies: layout-base: 1.0.2 @@ -19032,6 +19866,8 @@ snapshots: debounce@1.2.1: {} + debounce@2.0.0: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -19040,6 +19876,10 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.3.7: + dependencies: + ms: 2.1.3 + debug@4.4.0: dependencies: ms: 2.1.3 @@ -19065,6 +19905,8 @@ snapshots: deep-is@0.1.4: {} + deepmerge@4.3.1: {} + defaults@1.0.4: dependencies: clone: 1.0.4 @@ -19151,12 +19993,30 @@ snapshots: '@babel/runtime': 7.27.0 csstype: 3.1.3 + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + domexception@4.0.0: dependencies: webidl-conversions: 7.0.0 + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + dompurify@3.1.6: {} + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dotenv-expand@11.0.7: dependencies: dotenv: 16.4.7 @@ -19202,6 +20062,24 @@ snapshots: dependencies: once: 1.4.0 + engine.io-parser@5.2.3: {} + + engine.io@6.6.4: + dependencies: + '@types/cors': 2.8.17 + '@types/node': 20.17.30 + accepts: 1.3.8 + base64id: 2.0.0 + cookie: 0.7.2 + cors: 2.8.5 + debug: 4.3.7 + engine.io-parser: 5.2.3 + ws: 8.17.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + enhanced-resolve@5.18.1: dependencies: graceful-fs: 4.2.11 @@ -19369,6 +20247,34 @@ snapshots: '@esbuild/win32-ia32': 0.21.5 '@esbuild/win32-x64': 0.21.5 + esbuild@0.25.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.0 + '@esbuild/android-arm': 0.25.0 + '@esbuild/android-arm64': 0.25.0 + '@esbuild/android-x64': 0.25.0 + '@esbuild/darwin-arm64': 0.25.0 + '@esbuild/darwin-x64': 0.25.0 + '@esbuild/freebsd-arm64': 0.25.0 + '@esbuild/freebsd-x64': 0.25.0 + '@esbuild/linux-arm': 0.25.0 + '@esbuild/linux-arm64': 0.25.0 + '@esbuild/linux-ia32': 0.25.0 + '@esbuild/linux-loong64': 0.25.0 + '@esbuild/linux-mips64el': 0.25.0 + '@esbuild/linux-ppc64': 0.25.0 + '@esbuild/linux-riscv64': 0.25.0 + '@esbuild/linux-s390x': 0.25.0 + '@esbuild/linux-x64': 0.25.0 + '@esbuild/netbsd-arm64': 0.25.0 + '@esbuild/netbsd-x64': 0.25.0 + '@esbuild/openbsd-arm64': 0.25.0 + '@esbuild/openbsd-x64': 0.25.0 + '@esbuild/sunos-x64': 0.25.0 + '@esbuild/win32-arm64': 0.25.0 + '@esbuild/win32-ia32': 0.25.0 + '@esbuild/win32-x64': 0.25.0 + esbuild@0.25.1: optionalDependencies: '@esbuild/aix-ppc64': 0.25.1 @@ -19424,7 +20330,7 @@ snapshots: '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.4(eslint@8.57.1) @@ -19471,7 +20377,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1): + eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0 @@ -19486,14 +20392,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -19516,7 +20422,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -19773,6 +20679,8 @@ snapshots: extend@3.0.2: {} + fast-deep-equal@2.0.1: {} + fast-deep-equal@3.1.3: {} fast-glob@3.3.3: @@ -20019,6 +20927,14 @@ snapshots: minipass: 7.1.2 path-scurry: 1.11.1 + glob@10.3.4: + dependencies: + foreground-child: 3.3.1 + jackspeak: 2.3.6 + minimatch: 9.0.5 + minipass: 7.1.2 + path-scurry: 1.11.1 + glob@10.4.5: dependencies: foreground-child: 3.3.1 @@ -20327,12 +21243,27 @@ snapshots: html-escaper@2.0.2: {} + html-to-text@9.0.5: + dependencies: + '@selderee/plugin-htmlparser2': 0.11.0 + deepmerge: 4.3.1 + dom-serializer: 2.0.0 + htmlparser2: 8.0.2 + selderee: 0.11.0 + html-void-elements@3.0.0: {} html-whitespace-sensitive-tag-names@3.0.1: {} htmlfy@0.6.7: {} + htmlparser2@8.0.2: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.2.2 + entities: 4.5.0 + http-proxy-agent@5.0.0: dependencies: '@tootallnate/once': 2.0.0 @@ -20865,6 +21796,8 @@ snapshots: layout-base@1.0.2: {} + leac@0.6.0: {} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -20973,6 +21906,8 @@ snapshots: markdown-table@3.0.4: {} + marked@7.0.4: {} + match-sorter@6.3.4: dependencies: '@babel/runtime': 7.27.0 @@ -20980,6 +21915,16 @@ snapshots: math-intrinsics@1.1.0: {} + md-to-react-email@5.0.5(react@18.3.1): + dependencies: + marked: 7.0.4 + react: 18.3.1 + + md-to-react-email@5.0.5(react@19.1.0): + dependencies: + marked: 7.0.4 + react: 19.1.0 + mdast-util-definitions@5.1.2: dependencies: '@types/mdast': 3.0.15 @@ -21947,6 +22892,33 @@ snapshots: - '@babel/core' - babel-plugin-macros + next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + '@next/env': 15.2.4 + '@swc/counter': 0.1.3 + '@swc/helpers': 0.5.15 + busboy: 1.6.0 + caniuse-lite: 1.0.30001707 + postcss: 8.4.31 + react: 19.1.0 + react-dom: 19.1.0(react@19.1.0) + styled-jsx: 5.1.6(@babel/core@7.26.10)(react@19.1.0) + optionalDependencies: + '@next/swc-darwin-arm64': 15.2.4 + '@next/swc-darwin-x64': 15.2.4 + '@next/swc-linux-arm64-gnu': 15.2.4 + '@next/swc-linux-arm64-musl': 15.2.4 + '@next/swc-linux-x64-gnu': 15.2.4 + '@next/swc-linux-x64-musl': 15.2.4 + '@next/swc-win32-arm64-msvc': 15.2.4 + '@next/swc-win32-x64-msvc': 15.2.4 + '@opentelemetry/api': 1.9.0 + '@playwright/test': 1.51.1 + sharp: 0.33.5 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + nextra-theme-docs@2.13.4(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@2.13.4(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@headlessui/react': 1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -22212,6 +23184,18 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + ora@5.4.1: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + orderedmap@2.1.1: {} own-keys@1.0.1: @@ -22291,6 +23275,11 @@ snapshots: dependencies: entities: 4.5.0 + parseley@0.12.1: + dependencies: + leac: 0.6.0 + peberminta: 0.9.0 + partykit@0.0.84: dependencies: '@cloudflare/workers-types': 4.20240129.0 @@ -22351,6 +23340,8 @@ snapshots: - encoding - supports-color + peberminta@0.9.0: {} + periscopic@3.1.0: dependencies: '@types/estree': 1.0.7 @@ -22498,6 +23489,8 @@ snapshots: printable-characters@1.0.42: {} + prismjs@1.30.0: {} + proc-log@3.0.0: {} process-nextick-args@2.0.1: {} @@ -22684,6 +23677,11 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 + react-dom@19.1.0(react@19.1.0): + dependencies: + react: 19.1.0 + scheduler: 0.26.0 + react-element-to-jsx-string@15.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@base2/pretty-print-object': 1.0.1 @@ -22692,6 +23690,64 @@ snapshots: react-dom: 18.3.1(react@18.3.1) react-is: 18.1.0 + react-email@4.0.7(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@babel/parser': 7.24.5 + '@babel/traverse': 7.25.6 + chalk: 4.1.2 + chokidar: 4.0.3 + commander: 11.1.0 + debounce: 2.0.0 + esbuild: 0.25.0 + glob: 10.3.4 + log-symbols: 4.1.0 + mime-types: 2.1.35 + next: 15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + normalize-path: 3.0.0 + ora: 5.4.1 + socket.io: 4.8.1 + transitivePeerDependencies: + - '@babel/core' + - '@opentelemetry/api' + - '@playwright/test' + - babel-plugin-macros + - babel-plugin-react-compiler + - bufferutil + - react + - react-dom + - sass + - supports-color + - utf-8-validate + + react-email@4.0.7(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): + dependencies: + '@babel/parser': 7.24.5 + '@babel/traverse': 7.25.6 + chalk: 4.1.2 + chokidar: 4.0.3 + commander: 11.1.0 + debounce: 2.0.0 + esbuild: 0.25.0 + glob: 10.3.4 + log-symbols: 4.1.0 + mime-types: 2.1.35 + next: 15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) + normalize-path: 3.0.0 + ora: 5.4.1 + socket.io: 4.8.1 + transitivePeerDependencies: + - '@babel/core' + - '@opentelemetry/api' + - '@playwright/test' + - babel-plugin-macros + - babel-plugin-react-compiler + - bufferutil + - react + - react-dom + - sass + - supports-color + - utf-8-validate + react-github-btn@1.4.0(react@18.3.1): dependencies: github-buttons: 2.29.1 @@ -22720,6 +23776,10 @@ snapshots: react: 18.3.1 react-dom: 18.3.1(react@18.3.1) + react-promise-suspense@0.3.4: + dependencies: + fast-deep-equal: 2.0.1 + react-refresh@0.14.2: {} react-remove-scroll-bar@2.3.8(@types/react@18.3.20)(react@18.3.1): @@ -22783,6 +23843,8 @@ snapshots: dependencies: loose-envify: 1.4.0 + react@19.1.0: {} + read-cache@1.0.0: dependencies: pify: 2.3.0 @@ -22807,6 +23869,8 @@ snapshots: dependencies: picomatch: 2.3.1 + readdirp@4.1.2: {} + reading-time@1.5.0: {} recrawl-sync@2.2.3: @@ -23193,13 +24257,15 @@ snapshots: scheduler@0.25.0-rc-603e6108-20241029: {} + scheduler@0.26.0: {} + schema-utils@3.3.0: dependencies: '@types/json-schema': 7.0.15 ajv: 6.12.6 ajv-keywords: 3.5.2(ajv@6.12.6) - schema-utils@4.3.0: + schema-utils@4.3.1: dependencies: '@types/json-schema': 7.0.15 ajv: 8.17.1 @@ -23215,6 +24281,10 @@ snapshots: extend-shallow: 2.0.1 kind-of: 6.0.3 + selderee@0.11.0: + dependencies: + parseley: 0.12.1 + semver@6.3.1: {} semver@7.7.1: {} @@ -23424,6 +24494,36 @@ snapshots: is-plain-object: 5.0.0 tiny-warning: 1.0.3 + socket.io-adapter@2.5.5: + dependencies: + debug: 4.3.7 + ws: 8.17.1 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + socket.io-parser@4.2.4: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.7 + transitivePeerDependencies: + - supports-color + + socket.io@4.8.1: + dependencies: + accepts: 1.3.8 + base64id: 2.0.0 + cors: 2.8.5 + debug: 4.3.7 + engine.io: 6.6.4 + socket.io-adapter: 2.5.5 + socket.io-parser: 4.2.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + sort-keys@5.1.0: dependencies: is-plain-obj: 4.1.0 @@ -23594,6 +24694,13 @@ snapshots: optionalDependencies: '@babel/core': 7.26.10 + styled-jsx@5.1.6(@babel/core@7.26.10)(react@19.1.0): + dependencies: + client-only: 0.0.1 + react: 19.1.0 + optionalDependencies: + '@babel/core': 7.26.10 + stylis@4.2.0: {} stylis@4.3.6: {} @@ -23694,7 +24801,7 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.25 jest-worker: 27.5.1 - schema-utils: 4.3.0 + schema-utils: 4.3.1 serialize-javascript: 6.0.2 terser: 5.39.0 webpack: 5.98.0 @@ -23894,6 +25001,9 @@ snapshots: undici-types@6.20.0: {} + undici-types@6.21.0: + optional: true + undici@5.29.0: dependencies: '@fastify/busboy': 2.1.1 @@ -24182,13 +25292,13 @@ snapshots: - supports-color - terser - vite-node@2.1.9(@types/node@22.13.13)(terser@5.39.0): + vite-node@2.1.9(@types/node@22.14.1)(terser@5.39.0): dependencies: cac: 6.7.14 debug: 4.4.0 es-module-lexer: 1.6.0 pathe: 1.1.2 - vite: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + vite: 5.4.15(@types/node@22.14.1)(terser@5.39.0) transitivePeerDependencies: - '@types/node' - less @@ -24208,21 +25318,21 @@ snapshots: rollup: 2.79.2 vite: 5.4.15(@types/node@20.17.28)(terser@5.39.0) - vite-plugin-eslint@1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)): + vite-plugin-eslint@1.8.1(eslint@8.57.1)(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)): dependencies: '@rollup/pluginutils': 4.2.1 '@types/eslint': 8.56.12 eslint: 8.57.1 rollup: 2.79.2 - vite: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + vite: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite-plugin-externalize-deps@0.8.0(vite@5.4.15(@types/node@20.17.28)(terser@5.39.0)): dependencies: vite: 5.4.15(@types/node@20.17.28)(terser@5.39.0) - vite-plugin-externalize-deps@0.8.0(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)): + vite-plugin-externalize-deps@0.8.0(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)): dependencies: - vite: 5.4.15(@types/node@22.13.13)(terser@5.39.0) + vite: 5.4.15(@types/node@22.14.1)(terser@5.39.0) vite@5.4.15(@types/node@20.17.28)(terser@5.39.0): dependencies: @@ -24234,13 +25344,13 @@ snapshots: fsevents: 2.3.3 terser: 5.39.0 - vite@5.4.15(@types/node@22.13.13)(terser@5.39.0): + vite@5.4.15(@types/node@22.14.1)(terser@5.39.0): dependencies: esbuild: 0.21.5 postcss: 8.5.3 rollup: 4.37.0 optionalDependencies: - '@types/node': 22.13.13 + '@types/node': 22.14.1 fsevents: 2.3.3 terser: 5.39.0 @@ -24290,10 +25400,10 @@ snapshots: - supports-color - terser - vitest@2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@21.1.2(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0): + vitest@2.1.9(@types/node@22.14.1)(@vitest/ui@2.1.9)(jsdom@21.1.2(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0): dependencies: '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + '@vitest/mocker': 2.1.9(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) '@vitest/pretty-format': 2.1.9 '@vitest/runner': 2.1.9 '@vitest/snapshot': 2.1.9 @@ -24309,11 +25419,11 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 1.2.0 - vite: 5.4.15(@types/node@22.13.13)(terser@5.39.0) - vite-node: 2.1.9(@types/node@22.13.13)(terser@5.39.0) + vite: 5.4.15(@types/node@22.14.1)(terser@5.39.0) + vite-node: 2.1.9(@types/node@22.14.1)(terser@5.39.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.13.13 + '@types/node': 22.14.1 '@vitest/ui': 2.1.9(vitest@2.1.9) jsdom: 21.1.2(canvas@2.11.2(encoding@0.1.13)) transitivePeerDependencies: @@ -24327,10 +25437,10 @@ snapshots: - supports-color - terser - vitest@2.1.9(@types/node@22.13.13)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0): + vitest@2.1.9(@types/node@22.14.1)(@vitest/ui@2.1.9)(jsdom@25.0.1(canvas@2.11.2(encoding@0.1.13)))(terser@5.39.0): dependencies: '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.15(@types/node@22.13.13)(terser@5.39.0)) + '@vitest/mocker': 2.1.9(vite@5.4.15(@types/node@22.14.1)(terser@5.39.0)) '@vitest/pretty-format': 2.1.9 '@vitest/runner': 2.1.9 '@vitest/snapshot': 2.1.9 @@ -24346,11 +25456,11 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.0.2 tinyrainbow: 1.2.0 - vite: 5.4.15(@types/node@22.13.13)(terser@5.39.0) - vite-node: 2.1.9(@types/node@22.13.13)(terser@5.39.0) + vite: 5.4.15(@types/node@22.14.1)(terser@5.39.0) + vite-node: 2.1.9(@types/node@22.14.1)(terser@5.39.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.13.13 + '@types/node': 22.14.1 '@vitest/ui': 2.1.9(vitest@2.1.9) jsdom: 25.0.1(canvas@2.11.2(encoding@0.1.13)) transitivePeerDependencies: @@ -24448,7 +25558,7 @@ snapshots: loader-runner: 4.3.0 mime-types: 2.1.35 neo-async: 2.6.2 - schema-utils: 4.3.0 + schema-utils: 4.3.1 tapable: 2.2.1 terser-webpack-plugin: 5.3.14(webpack@5.98.0) watchpack: 2.4.2 @@ -24576,6 +25686,8 @@ snapshots: ws@7.5.10: {} + ws@8.17.1: {} + ws@8.18.1: {} xml-formatter@3.6.5: From 06e8a4d6e997f47113f889761b8cb4a5acebff72 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Wed, 23 Apr 2025 17:27:11 +0200 Subject: [PATCH 05/36] feat: implement github sponsors fallback --- docs/auth.ts | 162 +++++++++++++++++++- docs/components/example/index.tsx | 14 +- docs/package.json | 1 - docs/pages/pricing.mdx | 4 +- docs/util/auth-client.ts | 5 +- docs/util/product-list.ts | 19 +++ docs/util/send-mail.tsx | 85 ++++------- pnpm-lock.yaml | 242 +----------------------------- 8 files changed, 223 insertions(+), 309 deletions(-) create mode 100644 docs/util/product-list.ts diff --git a/docs/auth.ts b/docs/auth.ts index 63b3701a28..eff1451a05 100644 --- a/docs/auth.ts +++ b/docs/auth.ts @@ -1,10 +1,13 @@ import { polar } from "@polar-sh/better-auth"; import { Polar } from "@polar-sh/sdk"; import { betterAuth } from "better-auth"; +import { customSession } from "better-auth/plugins"; +import { github } from "better-auth/social-providers"; import { magicLink, openAPI } from "better-auth/plugins"; import Database from "better-sqlite3"; import { sendEmail } from "./util/send-mail"; +import { PRODUCTS } from "./util/product-list"; export const client = new Polar({ accessToken: process.env.POLAR_ACCESS_TOKEN, @@ -15,12 +18,21 @@ export const client = new Polar({ }); export const auth = betterAuth({ + user: { + additionalFields: { + ghSponsorPlanType: { + type: "string", + required: false, + input: false, // don't allow user to set role + }, + }, + }, emailVerification: { async sendVerificationEmail({ user, url }) { await sendEmail({ to: user.email, template: "verifyEmail", - props: { url }, + props: { url, name: user.name }, }); }, }, @@ -31,7 +43,7 @@ export const auth = betterAuth({ await sendEmail({ to: data.user.email, template: "resetPassword", - props: { url: data.url }, + props: { url: data.url, name: data.user.name }, }); }, }, @@ -39,10 +51,146 @@ export const auth = betterAuth({ github: { clientId: process.env.AUTH_GITHUB_ID as string, clientSecret: process.env.AUTH_GITHUB_SECRET as string, + async getUserInfo(token) { + // This is a workaround to still re-use the default github provider getUserInfo + // and still be able to fetch the sponsor info with the token + return (await github({ + clientId: process.env.AUTH_GITHUB_ID as string, + clientSecret: process.env.AUTH_GITHUB_SECRET as string, + async mapProfileToUser() { + const resSponsor = await fetch(`https://api.github.com/graphql`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${token.accessToken}`, + }, + // organization(login:"TypeCellOS") { + // user(login:"YousefED") { + body: JSON.stringify({ + query: `{ + user(login:"YousefED") { + sponsorshipForViewerAsSponsor(activeOnly:false) { + isActive, + tier { + name + monthlyPriceInDollars + } + } + } + }`, + }), + }); + + if (resSponsor.ok) { + // Mock data. TODO: disable and test actial data + // profile.sponsorInfo = { + // isActive: true, + // tier: { + // name: "test", + // monthlyPriceInDollars: 100, + // }, + // }; + // use API data: + + const data = await resSponsor.json(); + // eslint-disable-next-line no-console + console.log("sponsor data", data); + + // { + // "data": { + // "user": { + // "sponsorshipForViewerAsSponsor": { + // "isActive": true, + // "tier": { + // "name": "$90 a month", + // "monthlyPriceInDollars": 90 + // } + // } + // } + // } + // } + + const sponsorInfo: null | { + isActive: boolean; + tier: { + monthlyPriceInDollars: number; + }; + } = data.data.user.sponsorshipForViewerAsSponsor; + + if (!sponsorInfo?.isActive) { + return {}; + } + + return { + ghSponsorPlanType: + sponsorInfo.tier.monthlyPriceInDollars > 100 + ? "business" + : "starter", + }; + } + + return {}; + }, + }).getUserInfo(token))!; + }, }, }, database: new Database("./sqlite.db"), plugins: [ + customSession( + async ({ user, session }) => { + // Otherwise, check with Polar + const polarState = await client.customers.getStateExternal({ + externalId: user.id, + }); + + if ( + // No active subscriptions + !polarState.activeSubscriptions.length || + // Or, the subscription is not active + polarState.activeSubscriptions[0].status !== "active" + ) { + if (user.ghSponsorPlanType) { + // The user may be a GitHub sponsor plan type + return { + planType: user.ghSponsorPlanType, + user, + session, + }; + } + + return { + planType: PRODUCTS.free.slug, + user, + session, + }; + } + const subscription = polarState.activeSubscriptions[0]; + + const planType = Object.values(PRODUCTS).find( + (p) => p.id === subscription.productId, + )?.slug; + + // See if they are subscribed to a Polar product, if not, use the free plan + return { + planType: planType ?? PRODUCTS.free.slug, + user, + session, + }; + }, + { + // This is really only for type inference + user: { + additionalFields: { + ghSponsorPlanType: { + type: "string", + required: false, + input: false, // don't allow user to set role + }, + }, + }, + }, + ), magicLink({ sendMagicLink: async ({ email, url }) => { await sendEmail({ @@ -66,18 +214,18 @@ export const auth = betterAuth({ enabled: true, products: [ { - productId: "8049f66f-fd0a-4690-a0aa-442ac5b03040", // ID of Product from Polar Dashboard - slug: "business", // Custom slug for easy reference in Checkout URL, e.g. /checkout/pro + productId: PRODUCTS.business.id, // ID of Product from Polar Dashboard + slug: PRODUCTS.business.slug, // Custom slug for easy reference in Checkout URL, e.g. /checkout/pro // http://localhost:3000/api/auth/checkout/business }, { - productId: "ab70fea5-172c-4aac-b3fc-0824f2a5b670", - slug: "starter", + productId: PRODUCTS.starter.id, + slug: PRODUCTS.starter.slug, // http://localhost:3000/api/auth/checkout/starter }, ], // TODO set to actual page (welcome screen) - successUrl: "/success?checkout_id={CHECKOUT_ID}", + successUrl: "/?checkout_id={CHECKOUT_ID}", }, // Incoming Webhooks handler will be installed at /polar/webhooks webhooks: { diff --git a/docs/components/example/index.tsx b/docs/components/example/index.tsx index a1f5ee4e3d..19f7bfa348 100644 --- a/docs/components/example/index.tsx +++ b/docs/components/example/index.tsx @@ -1,23 +1,21 @@ -import { useSession } from "next-auth/react"; -// import { authClient } from "../../util/auth-client"; -import { examples } from "./generated/exampleComponents.gen"; import { authClient } from "@/util/auth-client"; +import { examples } from "./generated/exampleComponents.gen"; export function Example(props: { name: keyof typeof examples }) { - // authClient. - const session = authClient.useSession() - // const session = useSession(); + const session = authClient.useSession(); const example = examples[props.name]; if (!example) { throw new Error(`Example ${props.name} not found`); } const ExampleWithCode = example.ExampleWithCode; - // const userStatus = getProLevel(session); return ( ); } diff --git a/docs/package.json b/docs/package.json index 916cfa2447..125c2270d8 100644 --- a/docs/package.json +++ b/docs/package.json @@ -5,7 +5,6 @@ "scripts": { "dev": "next dev", "dev:email": "email dev", - "build:email": "email export --outDir ./", "build:site": "next build", "start": "next start", "lint": "next lint" diff --git a/docs/pages/pricing.mdx b/docs/pages/pricing.mdx index 699bd37636..b0f138a76a 100644 --- a/docs/pages/pricing.mdx +++ b/docs/pages/pricing.mdx @@ -28,7 +28,7 @@ export default function Pricing() { "Keep the open source library running and maintained", "XL packages available for open source projects under AGPL-3.0" ], - githubTierId: "291733", + href: "/api/auth/checkout/starter", }, { id: "tier-business", @@ -48,7 +48,7 @@ export default function Pricing() { "Access to a private Discord channel with the maintainers", "Up to 2 hours of individual support per month", ], - githubTierId: "440968", + href: "/api/auth/checkout/business", }, { id: "tier-enterprise", diff --git a/docs/util/auth-client.ts b/docs/util/auth-client.ts index a76177f15e..0c8a150b29 100644 --- a/docs/util/auth-client.ts +++ b/docs/util/auth-client.ts @@ -1,9 +1,10 @@ import { createAuthClient } from "better-auth/react"; - +import { customSessionClient } from "better-auth/client/plugins"; import { magicLinkClient } from "better-auth/client/plugins"; +import type { auth } from "@/auth"; export const authClient = createAuthClient({ - plugins: [magicLinkClient()], + plugins: [magicLinkClient(), customSessionClient()], }); export const { useSession, signIn, signOut, signUp } = authClient; diff --git a/docs/util/product-list.ts b/docs/util/product-list.ts new file mode 100644 index 0000000000..fc266a1766 --- /dev/null +++ b/docs/util/product-list.ts @@ -0,0 +1,19 @@ +export const PRODUCTS = { + business: { + id: "8049f66f-fd0a-4690-a0aa-442ac5b03040", + name: "Business", + slug: "business", + } as const, + starter: { + id: "ab70fea5-172c-4aac-b3fc-0824f2a5b670", + name: "Starter", + slug: "starter", + } as const, + free: { + id: "00000000-0000-0000-0000-000000000000", + name: "Free", + slug: "free", + } as const, +} as const; + +export type ProductSlug = (typeof PRODUCTS)[keyof typeof PRODUCTS]["slug"]; diff --git a/docs/util/send-mail.tsx b/docs/util/send-mail.tsx index 702f9378b1..661c7283e6 100644 --- a/docs/util/send-mail.tsx +++ b/docs/util/send-mail.tsx @@ -14,72 +14,53 @@ const transporter = nodemailer.createTransport({ }, }); -type TEMPLATES = { +const TEMPLATE_COMPONENTS = { verifyEmail: { - url: string; - name?: string; - }; + subject: "BlockNote - Verify your email address", + component: VerifyEmail, + }, resetPassword: { - url: string; - name?: string; - }; + subject: "BlockNote - Reset your password", + component: ResetPassword, + }, magicLink: { - url: string; - name?: string; - }; -}; - -const TEMPLATE_TEXTS = { - verifyEmail: (props: TEMPLATES["verifyEmail"]) => - render(, { - pretty: true, - plainText: true, - }), - resetPassword: (props: TEMPLATES["resetPassword"]) => - render(, { - pretty: true, - plainText: true, - }), - magicLink: (props: TEMPLATES["magicLink"]) => - render(, { - pretty: true, - plainText: true, - }), -}; -const TEMPLATE_HTMLS = { - verifyEmail: (props: TEMPLATES["verifyEmail"]) => - render(, { - pretty: true, - }), - resetPassword: (props: TEMPLATES["resetPassword"]) => - render(, { - pretty: true, - }), - magicLink: (props: TEMPLATES["magicLink"]): Promise => - render(, { - pretty: true, - }), -}; + subject: "BlockNote - Sign in to your account", + component: MagicLinkEmail, + }, +} as const; -export async function sendEmail({ +export async function sendEmail({ to, template, props, }: { to: string; template: T; - props: TEMPLATES[T]; + props: Parameters<(typeof TEMPLATE_COMPONENTS)[T]["component"]>[0]; }) { + if ( + !process.env.SMTP_HOST || + !process.env.SMTP_PORT || + !process.env.SMTP_USER || + !process.env.SMTP_PASS + ) { + console.log(template, props); + throw new Error( + "SMTP_HOST, SMTP_PORT, SMTP_USER, and SMTP_PASS must be set to send emails", + ); + } + const info = await transporter.sendMail({ from: '"BlockNote" ', to, - subject: { - verifyEmail: "BlockNote - Verify your email address", - resetPassword: "BlockNote - Reset your password", - magicLink: "BlockNote - Sign in to your account", - }[template], - text: await TEMPLATE_TEXTS[template](props), - html: await TEMPLATE_HTMLS[template](props), + subject: TEMPLATE_COMPONENTS[template].subject, + text: await render(TEMPLATE_COMPONENTS[template].component(props), { + pretty: true, + plainText: true, + }), + html: await render(TEMPLATE_COMPONENTS[template].component(props), { + pretty: true, + }), }); console.log("Email sent: ", info.messageId); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b4f82ad6db..cc80841909 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3079,28 +3079,6 @@ importers: specifier: ^5.3.3 version: 5.8.2 - packages/email: - dependencies: - '@react-email/components': - specifier: ^0.0.36 - version: 0.0.36(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - react: - specifier: ^19.1.0 - version: 19.1.0 - react-dom: - specifier: ^19.1.0 - version: 19.1.0(react@19.1.0) - devDependencies: - '@types/react': - specifier: ^19.1.2 - version: 19.1.2 - '@types/react-dom': - specifier: ^19.1.2 - version: 19.1.2(@types/react@19.1.2) - react-email: - specifier: ^4.0.7 - version: 4.0.7(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - packages/mantine: dependencies: '@blocknote/core': @@ -7825,11 +7803,6 @@ packages: peerDependencies: '@types/react': ^18.0.0 - '@types/react-dom@19.1.2': - resolution: {integrity: sha512-XGJkWF41Qq305SKWEILa1O8vzhb3aOo3ogBlSmiqNko/WmRb6QIaweuZCXjKygVDXpzXb5wyxKTSOsmkuqj+Qw==} - peerDependencies: - '@types/react': ^19.0.0 - '@types/react-transition-group@4.4.12': resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==} peerDependencies: @@ -12047,11 +12020,6 @@ packages: peerDependencies: react: ^18.3.1 - react-dom@19.1.0: - resolution: {integrity: sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==} - peerDependencies: - react: ^19.1.0 - react-element-to-jsx-string@15.0.0: resolution: {integrity: sha512-UDg4lXB6BzlobN60P8fHWVPX3Kyw8ORrTeBtClmIlGdkOOE+GYQSFvmEU5iLLpwp/6v42DINwNcwOhOLfQ//FQ==} peerDependencies: @@ -12166,10 +12134,6 @@ packages: resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} engines: {node: '>=0.10.0'} - react@19.1.0: - resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==} - engines: {node: '>=0.10.0'} - read-cache@1.0.0: resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==} @@ -12460,9 +12424,6 @@ packages: scheduler@0.25.0-rc-603e6108-20241029: resolution: {integrity: sha512-pFwF6H1XrSdYYNLfOcGlM28/j8CGLu8IvdrxqhjWULe2bPcKiKW4CV+OWqR/9fT52mywx65l7ysNkjLKBda7eA==} - scheduler@0.26.0: - resolution: {integrity: sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==} - schema-utils@3.3.0: resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} engines: {node: '>= 10.13.0'} @@ -16970,44 +16931,23 @@ snapshots: dependencies: react: 18.3.1 - '@react-email/body@0.0.11(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/button@0.0.19(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/button@0.0.19(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/code-block@0.0.12(react@18.3.1)': dependencies: prismjs: 1.30.0 react: 18.3.1 - '@react-email/code-block@0.0.12(react@19.1.0)': - dependencies: - prismjs: 1.30.0 - react: 19.1.0 - '@react-email/code-inline@0.0.5(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/code-inline@0.0.5(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/column@0.0.13(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/column@0.0.13(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/components@0.0.36(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@react-email/body': 0.0.11(react@18.3.1) @@ -17034,114 +16974,47 @@ snapshots: transitivePeerDependencies: - react-dom - '@react-email/components@0.0.36(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': - dependencies: - '@react-email/body': 0.0.11(react@19.1.0) - '@react-email/button': 0.0.19(react@19.1.0) - '@react-email/code-block': 0.0.12(react@19.1.0) - '@react-email/code-inline': 0.0.5(react@19.1.0) - '@react-email/column': 0.0.13(react@19.1.0) - '@react-email/container': 0.0.15(react@19.1.0) - '@react-email/font': 0.0.9(react@19.1.0) - '@react-email/head': 0.0.12(react@19.1.0) - '@react-email/heading': 0.0.15(react@19.1.0) - '@react-email/hr': 0.0.11(react@19.1.0) - '@react-email/html': 0.0.11(react@19.1.0) - '@react-email/img': 0.0.11(react@19.1.0) - '@react-email/link': 0.0.12(react@19.1.0) - '@react-email/markdown': 0.0.14(react@19.1.0) - '@react-email/preview': 0.0.12(react@19.1.0) - '@react-email/render': 1.0.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - '@react-email/row': 0.0.12(react@19.1.0) - '@react-email/section': 0.0.16(react@19.1.0) - '@react-email/tailwind': 1.0.4(react@19.1.0) - '@react-email/text': 0.1.1(react@19.1.0) - react: 19.1.0 - transitivePeerDependencies: - - react-dom - '@react-email/container@0.0.15(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/container@0.0.15(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/font@0.0.9(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/font@0.0.9(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/head@0.0.12(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/head@0.0.12(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/heading@0.0.15(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/heading@0.0.15(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/hr@0.0.11(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/hr@0.0.11(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/html@0.0.11(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/html@0.0.11(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/img@0.0.11(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/img@0.0.11(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/link@0.0.12(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/link@0.0.12(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/markdown@0.0.14(react@18.3.1)': dependencies: md-to-react-email: 5.0.5(react@18.3.1) react: 18.3.1 - '@react-email/markdown@0.0.14(react@19.1.0)': - dependencies: - md-to-react-email: 5.0.5(react@19.1.0) - react: 19.1.0 - '@react-email/preview@0.0.12(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/preview@0.0.12(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/render@1.0.6(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: html-to-text: 9.0.5 @@ -17150,46 +17023,22 @@ snapshots: react-dom: 18.3.1(react@18.3.1) react-promise-suspense: 0.3.4 - '@react-email/render@1.0.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)': - dependencies: - html-to-text: 9.0.5 - prettier: 3.5.3 - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) - react-promise-suspense: 0.3.4 - '@react-email/row@0.0.12(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/row@0.0.12(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/section@0.0.16(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/section@0.0.16(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/tailwind@1.0.4(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/tailwind@1.0.4(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-email/text@0.1.1(react@18.3.1)': dependencies: react: 18.3.1 - '@react-email/text@0.1.1(react@19.1.0)': - dependencies: - react: 19.1.0 - '@react-pdf/fns@3.1.2': {} '@react-pdf/font@4.0.2': @@ -18355,10 +18204,6 @@ snapshots: dependencies: '@types/react': 18.3.20 - '@types/react-dom@19.1.2(@types/react@19.1.2)': - dependencies: - '@types/react': 19.1.2 - '@types/react-transition-group@4.4.12(@types/react@18.3.20)': dependencies: '@types/react': 18.3.20 @@ -20330,7 +20175,7 @@ snapshots: '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.4(eslint@8.57.1) @@ -20377,7 +20222,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1): + eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0 @@ -20392,14 +20237,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -20422,7 +20267,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -21920,11 +21765,6 @@ snapshots: marked: 7.0.4 react: 18.3.1 - md-to-react-email@5.0.5(react@19.1.0): - dependencies: - marked: 7.0.4 - react: 19.1.0 - mdast-util-definitions@5.1.2: dependencies: '@types/mdast': 3.0.15 @@ -22892,33 +22732,6 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): - dependencies: - '@next/env': 15.2.4 - '@swc/counter': 0.1.3 - '@swc/helpers': 0.5.15 - busboy: 1.6.0 - caniuse-lite: 1.0.30001707 - postcss: 8.4.31 - react: 19.1.0 - react-dom: 19.1.0(react@19.1.0) - styled-jsx: 5.1.6(@babel/core@7.26.10)(react@19.1.0) - optionalDependencies: - '@next/swc-darwin-arm64': 15.2.4 - '@next/swc-darwin-x64': 15.2.4 - '@next/swc-linux-arm64-gnu': 15.2.4 - '@next/swc-linux-arm64-musl': 15.2.4 - '@next/swc-linux-x64-gnu': 15.2.4 - '@next/swc-linux-x64-musl': 15.2.4 - '@next/swc-win32-arm64-msvc': 15.2.4 - '@next/swc-win32-x64-msvc': 15.2.4 - '@opentelemetry/api': 1.9.0 - '@playwright/test': 1.51.1 - sharp: 0.33.5 - transitivePeerDependencies: - - '@babel/core' - - babel-plugin-macros - nextra-theme-docs@2.13.4(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(nextra@2.13.4(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@headlessui/react': 1.7.19(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -23677,11 +23490,6 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 - react-dom@19.1.0(react@19.1.0): - dependencies: - react: 19.1.0 - scheduler: 0.26.0 - react-element-to-jsx-string@15.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: '@base2/pretty-print-object': 1.0.1 @@ -23719,35 +23527,6 @@ snapshots: - supports-color - utf-8-validate - react-email@4.0.7(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0): - dependencies: - '@babel/parser': 7.24.5 - '@babel/traverse': 7.25.6 - chalk: 4.1.2 - chokidar: 4.0.3 - commander: 11.1.0 - debounce: 2.0.0 - esbuild: 0.25.0 - glob: 10.3.4 - log-symbols: 4.1.0 - mime-types: 2.1.35 - next: 15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@19.1.0(react@19.1.0))(react@19.1.0) - normalize-path: 3.0.0 - ora: 5.4.1 - socket.io: 4.8.1 - transitivePeerDependencies: - - '@babel/core' - - '@opentelemetry/api' - - '@playwright/test' - - babel-plugin-macros - - babel-plugin-react-compiler - - bufferutil - - react - - react-dom - - sass - - supports-color - - utf-8-validate - react-github-btn@1.4.0(react@18.3.1): dependencies: github-buttons: 2.29.1 @@ -23843,8 +23622,6 @@ snapshots: dependencies: loose-envify: 1.4.0 - react@19.1.0: {} - read-cache@1.0.0: dependencies: pify: 2.3.0 @@ -24257,8 +24034,6 @@ snapshots: scheduler@0.25.0-rc-603e6108-20241029: {} - scheduler@0.26.0: {} - schema-utils@3.3.0: dependencies: '@types/json-schema': 7.0.15 @@ -24694,13 +24469,6 @@ snapshots: optionalDependencies: '@babel/core': 7.26.10 - styled-jsx@5.1.6(@babel/core@7.26.10)(react@19.1.0): - dependencies: - client-only: 0.0.1 - react: 19.1.0 - optionalDependencies: - '@babel/core': 7.26.10 - stylis@4.2.0: {} stylis@4.3.6: {} From d64c270bf8131d796dab9c43f2dd46afc424e3f1 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Thu, 24 Apr 2025 14:59:13 +0200 Subject: [PATCH 06/36] feat: use supabase or any PG db --- docs/.env.local.example | 1 + docs/auth.ts | 74 ++++++++++------- docs/package.json | 4 +- docs/util/send-mail.tsx | 31 ++++--- package.json | 3 +- pnpm-lock.yaml | 176 ++++++++++++++++++++++++++++++---------- 6 files changed, 198 insertions(+), 91 deletions(-) diff --git a/docs/.env.local.example b/docs/.env.local.example index e9dcc0e453..0b6aca8e63 100644 --- a/docs/.env.local.example +++ b/docs/.env.local.example @@ -16,6 +16,7 @@ SMTP_SECURE=false # Better Auth BETTER_AUTH_SECRET= # Linux: `openssl rand -hex 32` or go to https://generate-secret.vercel.app/32 BETTER_AUTH_URL=http://localhost:3000 +POSTGRES_URL= # Polar POLAR_ACCESS_TOKEN= diff --git a/docs/auth.ts b/docs/auth.ts index eff1451a05..f98cd1311e 100644 --- a/docs/auth.ts +++ b/docs/auth.ts @@ -1,20 +1,20 @@ import { polar } from "@polar-sh/better-auth"; import { Polar } from "@polar-sh/sdk"; +import * as Sentry from "@sentry/nextjs"; import { betterAuth } from "better-auth"; -import { customSession } from "better-auth/plugins"; +import { customSession, magicLink, openAPI } from "better-auth/plugins"; import { github } from "better-auth/social-providers"; -import { magicLink, openAPI } from "better-auth/plugins"; -import Database from "better-sqlite3"; +import { Pool } from "pg"; -import { sendEmail } from "./util/send-mail"; import { PRODUCTS } from "./util/product-list"; +import { sendEmail } from "./util/send-mail"; export const client = new Polar({ accessToken: process.env.POLAR_ACCESS_TOKEN, // Use 'sandbox' if you're using the Polar Sandbox environment // Remember that access tokens, products, etc. are completely separated between environments. // Access tokens obtained in Production are for instance not usable in the Sandbox environment. - server: "sandbox", + server: process.env.NODE_ENV === "production" ? "production" : "sandbox", }); export const auth = betterAuth({ @@ -135,29 +135,53 @@ export const auth = betterAuth({ }, }, }, - database: new Database("./sqlite.db"), + database: new Pool({ + connectionString: process.env.POSTGRES_URL, + }), plugins: [ customSession( async ({ user, session }) => { - // Otherwise, check with Polar - const polarState = await client.customers.getStateExternal({ - externalId: user.id, - }); + try { + // Check for a Polar subscription + const polarState = await client.customers.getStateExternal({ + externalId: user.id, + }); + + if ( + // No active subscriptions + !polarState.activeSubscriptions.length || + // Or, the subscription is not active + polarState.activeSubscriptions[0].status !== "active" + ) { + if (user.ghSponsorPlanType) { + // The user may be a GitHub sponsor plan type + return { + planType: user.ghSponsorPlanType, + user, + session, + }; + } - if ( - // No active subscriptions - !polarState.activeSubscriptions.length || - // Or, the subscription is not active - polarState.activeSubscriptions[0].status !== "active" - ) { - if (user.ghSponsorPlanType) { - // The user may be a GitHub sponsor plan type return { - planType: user.ghSponsorPlanType, + planType: PRODUCTS.free.slug, user, session, }; } + const subscription = polarState.activeSubscriptions[0]; + + const planType = Object.values(PRODUCTS).find( + (p) => p.id === subscription.productId, + )?.slug; + + // See if they are subscribed to a Polar product, if not, use the free plan + return { + planType: planType ?? PRODUCTS.free.slug, + user, + session, + }; + } catch (err) { + Sentry.captureException(err); return { planType: PRODUCTS.free.slug, @@ -165,18 +189,6 @@ export const auth = betterAuth({ session, }; } - const subscription = polarState.activeSubscriptions[0]; - - const planType = Object.values(PRODUCTS).find( - (p) => p.id === subscription.productId, - )?.slug; - - // See if they are subscribed to a Polar product, if not, use the free plan - return { - planType: planType ?? PRODUCTS.free.slug, - user, - session, - }; }, { // This is really only for type inference diff --git a/docs/package.json b/docs/package.json index 125c2270d8..fe9867c3f0 100644 --- a/docs/package.json +++ b/docs/package.json @@ -26,12 +26,10 @@ "@polar-sh/sdk": "^0.32.11", "@react-email/render": "1.0.6", "@sentry/nextjs": "9.4.0", - "@types/better-sqlite3": "7.6.13", "@types/nodemailer": "6.4.17", "@vercel/analytics": "^1.2.2", "@vercel/og": "^0.6.2", "better-auth": "1.2.7", - "better-sqlite3": "11.9.1", "classnames": "2.3.2", "clsx": "^2.1.0", "framer-motion": "^10.16.16", @@ -41,6 +39,7 @@ "nextra-theme-docs": "^2.13.2", "nodemailer": "6.10.1", "partykit": "^0.0.84", + "pg": "8.15.5", "raw-loader": "^4.0.2", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -53,6 +52,7 @@ "devDependencies": { "@react-email/components": "^0.0.36", "@types/node": "^20", + "@types/pg": "8.11.14", "@types/react": "^18.0.25", "@types/react-dom": "^18.0.9", "autoprefixer": "^10.0.1", diff --git a/docs/util/send-mail.tsx b/docs/util/send-mail.tsx index 661c7283e6..0afd21fe59 100644 --- a/docs/util/send-mail.tsx +++ b/docs/util/send-mail.tsx @@ -3,6 +3,7 @@ import { render } from "@react-email/render"; import MagicLinkEmail from "@/emails/magic-link"; import VerifyEmail from "@/emails/verify-email"; import ResetPassword from "@/emails/reset-password"; +import * as Sentry from "@sentry/nextjs"; const transporter = nodemailer.createTransport({ host: String(process.env.SMTP_HOST), @@ -50,18 +51,22 @@ export async function sendEmail({ ); } - const info = await transporter.sendMail({ - from: '"BlockNote" ', - to, - subject: TEMPLATE_COMPONENTS[template].subject, - text: await render(TEMPLATE_COMPONENTS[template].component(props), { - pretty: true, - plainText: true, - }), - html: await render(TEMPLATE_COMPONENTS[template].component(props), { - pretty: true, - }), - }); + try { + const info = await transporter.sendMail({ + from: '"BlockNote" ', + to, + subject: TEMPLATE_COMPONENTS[template].subject, + text: await render(TEMPLATE_COMPONENTS[template].component(props), { + pretty: true, + plainText: true, + }), + html: await render(TEMPLATE_COMPONENTS[template].component(props), { + pretty: true, + }), + }); - console.log("Email sent: ", info.messageId); + console.log("Email sent: ", info.messageId); + } catch (err) { + Sentry.captureException(err); + } } diff --git a/package.json b/package.json index 3618f79eb6..36dc29bac9 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,7 @@ "@sentry/cli", "canvas", "esbuild", - "nx", - "better-sqlite3" + "nx" ] }, "packageManager": "pnpm@10.7.1+sha512.2d92c86b7928dc8284f53494fb4201f983da65f0fb4f0d40baafa5cf628fa31dae3e5968f12466f17df7e97310e30f343a648baea1b9b350685dafafffdf5808", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cc80841909..77d26bf446 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -104,9 +104,6 @@ importers: '@sentry/nextjs': specifier: 9.4.0 version: 9.4.0(@opentelemetry/context-async-hooks@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/core@1.30.1(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.57.2(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@1.30.1(@opentelemetry/api@1.9.0))(encoding@0.1.13)(next@15.2.4(@babel/core@7.26.10)(@opentelemetry/api@1.9.0)(@playwright/test@1.51.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)(webpack@5.98.0) - '@types/better-sqlite3': - specifier: 7.6.13 - version: 7.6.13 '@types/nodemailer': specifier: 6.4.17 version: 6.4.17 @@ -119,9 +116,6 @@ importers: better-auth: specifier: 1.2.7 version: 1.2.7 - better-sqlite3: - specifier: 11.9.1 - version: 11.9.1 classnames: specifier: 2.3.2 version: 2.3.2 @@ -149,6 +143,9 @@ importers: partykit: specifier: ^0.0.84 version: 0.0.84 + pg: + specifier: 8.15.5 + version: 8.15.5 raw-loader: specifier: ^4.0.2 version: 4.0.2(webpack@5.98.0) @@ -180,6 +177,9 @@ importers: '@types/node': specifier: ^20 version: 20.17.28 + '@types/pg': + specifier: 8.11.14 + version: 8.11.14 '@types/react': specifier: ^18.0.25 version: 18.3.20 @@ -7651,9 +7651,6 @@ packages: '@types/babel__traverse@7.20.7': resolution: {integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==} - '@types/better-sqlite3@7.6.13': - resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} - '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} @@ -7789,6 +7786,9 @@ packages: '@types/pg-pool@2.0.6': resolution: {integrity: sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==} + '@types/pg@8.11.14': + resolution: {integrity: sha512-qyD11E5R3u0eJmd1lB0WnWKXJGA7s015nyARWljfz5DcX83TKAIlY+QrmvzQTsbIe+hkiFtkyL2gHC6qwF6Fbg==} + '@types/pg@8.6.1': resolution: {integrity: sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==} @@ -8539,9 +8539,6 @@ packages: better-call@1.0.8: resolution: {integrity: sha512-/PV8JLqDRUN7JyBPbklVsS/8E4SO3pnf8hbpa8B7xrBrr+BBYpeOAxoqtnsyk/pRs35vNB4MZx8cn9dBuNlLDA==} - better-sqlite3@11.9.1: - resolution: {integrity: sha512-Ba0KR+Fzxh2jDRhdg6TSH0SJGzb8C0aBY4hR8w8madIdIzzC6Y1+kx5qR6eS1Z+Gy20h6ZU28aeyg0z1VIrShQ==} - bidi-js@1.0.3: resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} @@ -8552,9 +8549,6 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -9752,9 +9746,6 @@ packages: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} @@ -11451,6 +11442,9 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} + obuf@1.1.2: + resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + on-headers@1.0.2: resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} engines: {node: '>= 0.8'} @@ -11631,17 +11625,48 @@ packages: periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} + pg-cloudflare@1.2.5: + resolution: {integrity: sha512-OOX22Vt0vOSRrdoUPKJ8Wi2OpE/o/h9T8X1s4qSkCedbNah9ei2W2765be8iMVxQUsvgT7zIAT2eIa9fs5+vtg==} + + pg-connection-string@2.8.5: + resolution: {integrity: sha512-Ni8FuZ8yAF+sWZzojvtLE2b03cqjO5jNULcHFfM9ZZ0/JXrgom5pBREbtnAw7oxsxJqHw9Nz/XWORUEL3/IFow==} + pg-int8@1.0.1: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} - pg-protocol@1.8.0: - resolution: {integrity: sha512-jvuYlEkL03NRvOoyoRktBK7+qU5kOvlAwvmrH8sr3wbLrOdVWsRxQfz8mMy9sZFsqJ1hEWNfdWKI4SAmoL+j7g==} + pg-numeric@1.0.2: + resolution: {integrity: sha512-BM/Thnrw5jm2kKLE5uJkXqqExRUY/toLHda65XgFTBTFYZyopbKjBe29Ii3RbkvlsMoFwD+tHeGaCjjv0gHlyw==} + engines: {node: '>=4'} + + pg-pool@3.9.5: + resolution: {integrity: sha512-DxyAlOgvUzRFpFAZjbCc8fUfG7BcETDHgepFPf724B0i08k9PAiZV1tkGGgQIL0jbMEuR9jW1YN7eX+WgXxCsQ==} + peerDependencies: + pg: '>=8.0' + + pg-protocol@1.9.5: + resolution: {integrity: sha512-DYTWtWpfd5FOro3UnAfwvhD8jh59r2ig8bPtc9H8Ds7MscE/9NYruUQWFAOuraRl29jwcT2kyMFQ3MxeaVjUhg==} pg-types@2.2.0: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} engines: {node: '>=4'} + pg-types@4.0.2: + resolution: {integrity: sha512-cRL3JpS3lKMGsKaWndugWQoLOCoP+Cic8oseVcbr0qhPzYD5DWXK+RZ9LY9wxRf7RQia4SCwQlXk0q6FCPrVng==} + engines: {node: '>=10'} + + pg@8.15.5: + resolution: {integrity: sha512-EpAhHFQc+aH9VfeffWIVC+XXk6lmAhS9W1FxtxcPXs94yxhrI1I6w/zkWfIOII/OkBv3Be04X3xMOj0kQ78l6w==} + engines: {node: '>= 8.0.0'} + peerDependencies: + pg-native: '>=3.0.1' + peerDependenciesMeta: + pg-native: + optional: true + + pgpass@1.0.5: + resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -11736,18 +11761,37 @@ packages: resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==} engines: {node: '>=4'} + postgres-array@3.0.4: + resolution: {integrity: sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==} + engines: {node: '>=12'} + postgres-bytea@1.0.0: resolution: {integrity: sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==} engines: {node: '>=0.10.0'} + postgres-bytea@3.0.0: + resolution: {integrity: sha512-CNd4jim9RFPkObHSjVHlVrxoVQXz7quwNFpz7RY1okNNme49+sVyiTvTRobiLV548Hx/hb1BG+iE7h9493WzFw==} + engines: {node: '>= 6'} + postgres-date@1.0.7: resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==} engines: {node: '>=0.10.0'} + postgres-date@2.1.0: + resolution: {integrity: sha512-K7Juri8gtgXVcDfZttFKVmhglp7epKb1K4pgrkLxehjqkrgPhfG6OO8LHLkfaqkbpjNRnra018XwAr1yQFWGcA==} + engines: {node: '>=12'} + postgres-interval@1.2.0: resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==} engines: {node: '>=0.10.0'} + postgres-interval@3.0.0: + resolution: {integrity: sha512-BSNDnbyZCXSxgA+1f5UU2GmwhoI0aU5yMxRGO8CdFEcY2BQF9xm/7MqKnYoM1nJDk8nONNWDk9WeSmePFhQdlw==} + engines: {node: '>=12'} + + postgres-range@1.1.4: + resolution: {integrity: sha512-i/hbxIE9803Alj/6ytL7UHQxRvZkI9O4Sy+J3HGc4F4oo/2eQAjTSNJ0bfxyse3bH0nuVesCk+3IRLaMtG3H6w==} + preact-render-to-string@5.2.3: resolution: {integrity: sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==} peerDependencies: @@ -12623,6 +12667,10 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} @@ -18026,10 +18074,6 @@ snapshots: dependencies: '@babel/types': 7.27.0 - '@types/better-sqlite3@7.6.13': - dependencies: - '@types/node': 20.17.30 - '@types/connect@3.4.38': dependencies: '@types/node': 20.17.30 @@ -18186,12 +18230,18 @@ snapshots: '@types/pg-pool@2.0.6': dependencies: - '@types/pg': 8.6.1 + '@types/pg': 8.11.14 + + '@types/pg@8.11.14': + dependencies: + '@types/node': 20.17.30 + pg-protocol: 1.9.5 + pg-types: 4.0.2 '@types/pg@8.6.1': dependencies: '@types/node': 20.17.30 - pg-protocol: 1.8.0 + pg-protocol: 1.9.5 pg-types: 2.2.0 '@types/pixelmatch@5.2.6': @@ -19072,11 +19122,6 @@ snapshots: set-cookie-parser: 2.7.1 uncrypto: 0.1.3 - better-sqlite3@11.9.1: - dependencies: - bindings: 1.5.0 - prebuild-install: 7.1.3 - bidi-js@1.0.3: dependencies: require-from-string: 2.0.2 @@ -19085,10 +19130,6 @@ snapshots: binary-extensions@2.3.0: {} - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - bl@4.1.0: dependencies: buffer: 5.7.1 @@ -20175,7 +20216,7 @@ snapshots: '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) eslint-plugin-import: 2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1) eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) eslint-plugin-react: 7.37.4(eslint@8.57.1) @@ -20222,7 +20263,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1): + eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.0 @@ -20237,14 +20278,14 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1): + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1): dependencies: debug: 3.2.7 optionalDependencies: '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@5.8.2) eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1) + eslint-import-resolver-typescript: 3.10.0(eslint-plugin-import@2.31.0)(eslint@8.57.1) transitivePeerDependencies: - supports-color @@ -20267,7 +20308,7 @@ snapshots: doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint@8.57.1))(eslint@8.57.1))(eslint@8.57.1) + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@5.8.2))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.10.0)(eslint@8.57.1) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -20568,8 +20609,6 @@ snapshots: dependencies: flat-cache: 3.2.0 - file-uri-to-path@1.0.0: {} - filelist@1.0.4: dependencies: minimatch: 5.1.6 @@ -22946,6 +22985,8 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + obuf@1.1.2: {} + on-headers@1.0.2: {} once@1.4.0: @@ -23161,9 +23202,20 @@ snapshots: estree-walker: 3.0.3 is-reference: 3.0.3 + pg-cloudflare@1.2.5: + optional: true + + pg-connection-string@2.8.5: {} + pg-int8@1.0.1: {} - pg-protocol@1.8.0: {} + pg-numeric@1.0.2: {} + + pg-pool@3.9.5(pg@8.15.5): + dependencies: + pg: 8.15.5 + + pg-protocol@1.9.5: {} pg-types@2.2.0: dependencies: @@ -23173,6 +23225,30 @@ snapshots: postgres-date: 1.0.7 postgres-interval: 1.2.0 + pg-types@4.0.2: + dependencies: + pg-int8: 1.0.1 + pg-numeric: 1.0.2 + postgres-array: 3.0.4 + postgres-bytea: 3.0.0 + postgres-date: 2.1.0 + postgres-interval: 3.0.0 + postgres-range: 1.1.4 + + pg@8.15.5: + dependencies: + pg-connection-string: 2.8.5 + pg-pool: 3.9.5(pg@8.15.5) + pg-protocol: 1.9.5 + pg-types: 2.2.0 + pgpass: 1.0.5 + optionalDependencies: + pg-cloudflare: 1.2.5 + + pgpass@1.0.5: + dependencies: + split2: 4.2.0 + picocolors@1.1.1: {} picomatch@2.3.1: {} @@ -23246,14 +23322,26 @@ snapshots: postgres-array@2.0.0: {} + postgres-array@3.0.4: {} + postgres-bytea@1.0.0: {} + postgres-bytea@3.0.0: + dependencies: + obuf: 1.1.2 + postgres-date@1.0.7: {} + postgres-date@2.1.0: {} + postgres-interval@1.2.0: dependencies: xtend: 4.0.2 + postgres-interval@3.0.0: {} + + postgres-range@1.1.4: {} + preact-render-to-string@5.2.3(preact@10.11.3): dependencies: preact: 10.11.3 @@ -24323,6 +24411,8 @@ snapshots: space-separated-tokens@2.0.2: {} + split2@4.2.0: {} + sprintf-js@1.0.3: {} ssim.js@3.5.0: {} From 81ea38783db016c946110b6284472611b77434df Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Fri, 25 Apr 2025 15:55:26 +0200 Subject: [PATCH 07/36] chore: update env file --- docs/.env.local.example | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/.env.local.example b/docs/.env.local.example index 0b6aca8e63..5d23a84dc1 100644 --- a/docs/.env.local.example +++ b/docs/.env.local.example @@ -5,7 +5,7 @@ AUTH_GITHUB_SECRET= # It's used for authentication when uploading source maps. SENTRY_AUTH_TOKEN= -#Email +# Email SMTP_HOST= SMTP_USER= SMTP_PASS= @@ -21,3 +21,5 @@ POSTGRES_URL= # Polar POLAR_ACCESS_TOKEN= POLAR_WEBHOOK_SECRET= +# Polar Sandbox is used in dev mode: https://sandbox.polar.sh/ +# You may need to delete your user in their dashboard if you get a "cannot attach new external ID error" From 14180f0ac67d94a89df326d6f3e014b36c42d21f Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Fri, 25 Apr 2025 16:09:30 +0200 Subject: [PATCH 08/36] fix: auto-sign in after email verification --- docs/auth.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/auth.ts b/docs/auth.ts index f98cd1311e..440ad3fc92 100644 --- a/docs/auth.ts +++ b/docs/auth.ts @@ -39,6 +39,7 @@ export const auth = betterAuth({ emailAndPassword: { enabled: true, requireEmailVerification: true, + autoSignIn: true, async sendResetPassword(data) { await sendEmail({ to: data.user.email, From 40dee604ee389bda927124b64525103d3ee7a010 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Fri, 25 Apr 2025 16:28:32 +0200 Subject: [PATCH 09/36] fix: make it more sensible --- docs/app/signup/page.tsx | 12 +++++++++++- docs/theme.config.tsx | 14 +++++++++----- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/docs/app/signup/page.tsx b/docs/app/signup/page.tsx index 66f741e183..3334f997e2 100644 --- a/docs/app/signup/page.tsx +++ b/docs/app/signup/page.tsx @@ -17,6 +17,13 @@ export default function Register() { }); }; + const handleSignIn = async () => { + await signIn.email({ + email, + password, + }); + }; + return (
Register + + {signingInState.state === "done" && ( +

+ {signingInState.message} +

+ )} + {signingInState.state === "error" && ( +

+ {signingInState.message} +

+ )} + + ); +} + +function AlternativeSignInButton(props: { + name: string; + icon: ReactNode; + onClick: () => void; +}) { + return ( + + ); +} + +function EmailSignInButton() { + const router = useRouter(); + + const searchParams = useSearchParams(); + const callbackURL = searchParams?.get("redirect") || "/"; + const theme = searchParams?.get("theme") || "light"; + + return ( +
)} From 753878dfbf9aa25767dde4ac270f6fb5641b5f6d Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Fri, 2 May 2025 10:39:21 +0200 Subject: [PATCH 26/36] fix: support magic and verify email for welcome emails --- docs/auth.ts | 2 +- docs/emails/welcome.tsx | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/auth.ts b/docs/auth.ts index 0115d5ad81..704e690489 100644 --- a/docs/auth.ts +++ b/docs/auth.ts @@ -266,7 +266,7 @@ export const auth = betterAuth({ }, hooks: { after: createAuthMiddleware(async (ctx) => { - if (ctx.path.startsWith("/verify-email")) { + if (ctx.path === "/magic-link/verify" || ctx.path === "/verify-email") { // After verifying email, send them a welcome email const newSession = ctx.context.newSession; if (newSession) { diff --git a/docs/emails/welcome.tsx b/docs/emails/welcome.tsx index dc40696afa..fed93ca490 100644 --- a/docs/emails/welcome.tsx +++ b/docs/emails/welcome.tsx @@ -29,6 +29,7 @@ export const WelcomeEmail = ({ name }: WelcomeEmailProps) => { />
Hi{name ? ` ${name}` : ""}, + Thanks for verifying your email address. Welcome to BlockNote! We're excited to have you on board. From 99fa736b16d0f85c8a1562d3bdfe4aea0ec4c965 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Fri, 2 May 2025 12:33:44 +0200 Subject: [PATCH 27/36] refactor: update welcome email text --- docs/emails/welcome.tsx | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/docs/emails/welcome.tsx b/docs/emails/welcome.tsx index fed93ca490..5ff6948321 100644 --- a/docs/emails/welcome.tsx +++ b/docs/emails/welcome.tsx @@ -8,6 +8,7 @@ import { Preview, Section, Text, + Link, } from "@react-email/components"; export interface WelcomeEmailProps { @@ -19,7 +20,7 @@ export const WelcomeEmail = ({ name }: WelcomeEmailProps) => { - BlockNote - Welcome to BlockNote + BlockNote - Next Steps & Subscription { />
Hi{name ? ` ${name}` : ""}, - Thanks for verifying your email address. - Welcome to BlockNote! We're excited to have you on board. + Thanks for verifying your email address and welcome to BlockNote! + + + Your next step is to subscribe to a BlockNote plan to unlock more + features. Subscribing to the Business plan grants you a license + for our XL packages. All paid plans also receive prioritized bug + support through GitHub. + + + View Plans & Subscribe + + + We appreciate your support for our open-source project!
@@ -41,7 +53,7 @@ export const WelcomeEmail = ({ name }: WelcomeEmailProps) => { }; WelcomeEmail.PreviewProps = { - name: "", + name: "Alex", } as WelcomeEmailProps; export default WelcomeEmail; @@ -75,6 +87,7 @@ const button = { textDecoration: "none", textAlign: "center" as const, display: "block", - width: "210px", + width: "230px", padding: "14px 7px", + marginTop: "20px", }; From 946f54edf1fb5f31e9439f917096dbb56bd1f9e1 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Tue, 6 May 2025 13:53:10 +0200 Subject: [PATCH 28/36] chore: rename --- docs/auth.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/auth.ts b/docs/auth.ts index 704e690489..c5eacd8638 100644 --- a/docs/auth.ts +++ b/docs/auth.ts @@ -11,7 +11,7 @@ import { Pool } from "pg"; import { PRODUCTS } from "./util/product-list"; import { sendEmail } from "./util/send-mail"; -export const client = new Polar({ +export const polarClient = new Polar({ accessToken: process.env.POLAR_ACCESS_TOKEN, // Use 'sandbox' if you're using the Polar Sandbox environment // Remember that access tokens, products, etc. are completely separated between environments. @@ -152,7 +152,7 @@ export const auth = betterAuth({ async ({ user, session }) => { try { // Check for a Polar subscription - const polarState = await client.customers.getStateExternal({ + const polarState = await polarClient.customers.getStateExternal({ externalId: user.id, }); @@ -225,7 +225,7 @@ export const auth = betterAuth({ // Serves on http://localhost:3000/api/auth/reference openAPI(), polar({ - client, + client: polarClient, // Enable automatic Polar Customer creation on signup createCustomerOnSignUp: true, // http://localhost:3000/api/auth/portal From bd51830c33fa2db848be0e2dd82bb14027a13e3b Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Tue, 6 May 2025 13:53:19 +0200 Subject: [PATCH 29/36] docs: add setup steps --- docs/DEVELOPMENT.md | 99 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 docs/DEVELOPMENT.md diff --git a/docs/DEVELOPMENT.md b/docs/DEVELOPMENT.md new file mode 100644 index 0000000000..0b113d1002 --- /dev/null +++ b/docs/DEVELOPMENT.md @@ -0,0 +1,99 @@ +# Website Development + +To get started with development of the website, you can follow these steps: + +1. Initialize the DB + +If you haven't already, you can initialize the database with the following command: + +```bash +cd docs && pnpm run init-db +``` + +This will initialize an SQLite database at `./docs/sqlite.db`. + +2. Setup environment variables + +Copy the `.env.example` file to `.env.local` and set the environment variables. + +```bash +cp .env.example .env.local +``` + +If you want to test logging in, or payments see more information below [in the environment variables section](#environment-variables). + +3. Start the development server + +```bash +cd docs && pnpm run dev +``` + +This will start the development server on port 3000. + +## Environment Variables + +### Logging in + +To test logging in, you can set the following environment variables: + +```bash +AUTH_SECRET=test +# Github OAuth optionally +AUTH_GITHUB_ID=test +AUTH_GITHUB_SECRET=test +``` + +Note: the GITHUB_ID and GITHUB_SECRET are optional, but if you want to test logging in with Github you'll need to set them. For local development, you'll need to set the callback URL to `http://localhost:3000/api/auth/callback/github` + +### Payments + +To test payments, you can set the following environment variables: + +```bash +POLAR_ACCESS_TOKEN=test +POLAR_WEBHOOK_SECRET=test +``` + +For testing payments, you'll need access to the polar sandbox which needs to be configured to point a webhook to your local server. This can be configured at: + +You'll need something like [ngrok](https://ngrok.com/) to expose your local server to the internet. + +```bash +ngrok http http://localhost:3000 +``` + +You'll need the webhook to point to ngrok like so: + +``` +https://0000-00-00-000-00.ngrok-free.app/api/auth/polar/webhooks +``` + +With this webhook pointing to your local server, you should be able to test payments. + +### Email sending + +Note, this is not required, if email sending is not configured, the app will log the email it would send to the console. Often this is more convenient for development. + +To test email sending, you can set the following environment variables: + +```bash +SMTP_HOST= +SMTP_USER= +SMTP_PASS= +SMTP_PORT= +SMTP_SECURE=false +``` + +When configured, you'll be able to send emails to the email address you've configured. + +To setup with protonmail, you'll need to go to and create a new SMTP submission token. + +You'll need to set the following environment variables: + +```bash +SMTP_HOST=smtp.protonmail.com +SMTP_USER=my.email@protonmail.com +SMTP_PASS=my-smtp-token +SMTP_PORT=587 +SMTP_SECURE=false +``` From ca8c88653b10a7d834ceb1f7818a419d0e230164 Mon Sep 17 00:00:00 2001 From: Nick the Sick Date: Tue, 6 May 2025 15:17:02 +0200 Subject: [PATCH 30/36] feat: revamp to use email first login --- docs/app/AuthenticationPage.tsx | 188 ++++++++++++------- docs/app/signin/page.tsx | 2 +- docs/app/signin/{email => password}/page.tsx | 4 +- docs/auth.ts | 6 +- docs/components/AuthNavButton.tsx | 48 ++--- docs/components/UserImage.tsx | 40 ++++ docs/components/example/ExampleBlock.tsx | 2 +- docs/pages/about.mdx | 13 ++ docs/pages/pricing.mdx | 2 +- docs/theme.config.tsx | 4 +- docs/util/product-list.ts | 2 +- 11 files changed, 205 insertions(+), 106 deletions(-) rename docs/app/signin/{email => password}/page.tsx (80%) create mode 100644 docs/components/UserImage.tsx diff --git a/docs/app/AuthenticationPage.tsx b/docs/app/AuthenticationPage.tsx index b06f888c7f..09373b129f 100644 --- a/docs/app/AuthenticationPage.tsx +++ b/docs/app/AuthenticationPage.tsx @@ -11,7 +11,7 @@ import { useState, } from "react"; -import { signIn, signUp } from "@/util/auth-client"; +import { authClient, signIn, signUp } from "@/util/auth-client"; import blockNoteLogo from "@/public/img/logos/banner.svg"; import blockNoteLogoDark from "@/public/img/logos/banner.dark.svg"; @@ -42,11 +42,14 @@ function AuthenticationInput(props: { ); } -function AuthenticationBox(props: { variant: "login" | "register" | "email" }) { +function AuthenticationBox(props: { + variant: "password" | "register" | "email"; +}) { const router = useRouter(); const searchParams = useSearchParams(); - const callbackURL = searchParams?.get("redirect") || "/"; + const callbackURL = + decodeURIComponent(searchParams?.get("redirect") || "") || "/"; const [name, setName] = useState(""); const [email, setEmail] = useState(""); @@ -64,7 +67,7 @@ function AuthenticationBox(props: { variant: "login" | "register" | "email" }) { setSigningInState({ state: "loading" }); - if (props.variant === "login") { + if (props.variant === "password") { await signIn.email( { email, @@ -73,7 +76,7 @@ function AuthenticationBox(props: { variant: "login" | "register" | "email" }) { }, { onSuccess() { - router.push("/"); + router.push(callbackURL || "/"); }, onError(ctx) { setSigningInState({ @@ -150,58 +153,73 @@ function AuthenticationBox(props: { variant: "login" | "register" | "email" }) { } }; + if (signingInState.state === "done") { + return ( +
+ +

{signingInState.message}

+
+ ); + } + return ( -
- {props.variant === "register" && ( - setName(e.target.value)} - /> - )} - setEmail(e.target.value)} - /> - {props.variant !== "email" && ( + <> + + Redirect to: {callbackURL} + {props.variant === "register" && ( + setName(e.target.value)} + /> + )} setPassword(e.target.value)} + type="email" + name="Email address" + onChange={(e) => setEmail(e.target.value)} /> - )} - - {signingInState.state === "done" && ( -

- {signingInState.message} -

- )} - {signingInState.state === "error" && ( -

- {signingInState.message} -

- )} - + + {signingInState.state === "error" && ( +

+ {signingInState.message} +

+ )} + + + + ); } @@ -239,6 +257,40 @@ function EmailSignInButton() { } + onClick={() => + router.push(`/signin?redirect=${callbackURL}&theme=${theme}`) + } + /> + ); +} + +function PasswordSignInButton() { + const router = useRouter(); + + const searchParams = useSearchParams(); + const callbackURL = searchParams?.get("redirect") || "/"; + const theme = searchParams?.get("theme") || "light"; + + return ( +