diff --git a/.gitignore b/.gitignore
index 66ce6a85ba..3b4f9b069e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -116,6 +116,10 @@ docs/docs/reference/solidstart
# Express
docs/docs/reference/express
+# Fastify
+docs/docs/reference/fastify
+
+
# Adapters
docs/docs/reference/adapter
diff --git a/.prettierignore b/.prettierignore
index af5e116db3..f4d874cbc1 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -42,6 +42,9 @@ packages/frameworks-sveltekit/vite.config.{js,ts}.timestamp-*
# @auth/express
packages/frameworks-express/providers
+# @auth/fastify
+packages/frameworks-fastify/providers
+
# next-auth
packages/next-auth/src/providers/oauth-types.ts
packages/next-auth/css/index.css
diff --git a/apps/dev/fastify/.env.example b/apps/dev/fastify/.env.example
new file mode 100644
index 0000000000..6959cc6e03
--- /dev/null
+++ b/apps/dev/fastify/.env.example
@@ -0,0 +1,7 @@
+AUTH_SECRET=
+
+AUTH_GITHUB_ID=
+AUTH_GITHUB_SECRET=
+
+AUTH_GOOGLE_ID=
+AUTH_GOOGLE_SECRET=
\ No newline at end of file
diff --git a/apps/dev/fastify/.gitignore b/apps/dev/fastify/.gitignore
new file mode 100644
index 0000000000..01fd4ed6db
--- /dev/null
+++ b/apps/dev/fastify/.gitignore
@@ -0,0 +1,21 @@
+# API keys and secrets
+.env
+
+# Dependency directory
+node_modules
+
+# Editors
+.idea
+*.iml
+.vscode/settings.json
+
+# OS metadata
+.DS_Store
+Thumbs.db
+
+# Ignore built ts files
+dist/**/*
+
+# Ignore built css files
+/public/css/output.css
+
diff --git a/apps/dev/fastify/.prettierignore b/apps/dev/fastify/.prettierignore
new file mode 100644
index 0000000000..f97e266fdd
--- /dev/null
+++ b/apps/dev/fastify/.prettierignore
@@ -0,0 +1,14 @@
+
+.DS_Store
+node_modules
+/dist
+/.turbo
+/package
+.env
+.env.*
+!.env.example
+
+# Ignore files for PNPM, NPM and YARN
+pnpm-lock.yaml
+package-lock.json
+yarn.lock
diff --git a/apps/dev/fastify/README.md b/apps/dev/fastify/README.md
new file mode 100644
index 0000000000..b8124cc9f9
--- /dev/null
+++ b/apps/dev/fastify/README.md
@@ -0,0 +1,28 @@
+> The example repository is maintained from a [monorepo](https://github.com/nextauthjs/next-auth/tree/main/apps/examples/fastify). Pull Requests should be opened against [`nextauthjs/next-auth`](https://github.com/nextauthjs/next-auth).
+
+
+
+
+
Auth.js Example App with Fastify
+
+ Open Source. Full Stack. Own Your Data.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Documentation
+
+- [fastify.authjs.dev](https://fastify.authjs.dev)
diff --git a/apps/dev/fastify/api/index.js b/apps/dev/fastify/api/index.js
new file mode 100644
index 0000000000..37795e6772
--- /dev/null
+++ b/apps/dev/fastify/api/index.js
@@ -0,0 +1,3 @@
+import { app } from "../src/app.js"
+
+export default app
diff --git a/apps/dev/fastify/package.json b/apps/dev/fastify/package.json
new file mode 100644
index 0000000000..1c27aba00e
--- /dev/null
+++ b/apps/dev/fastify/package.json
@@ -0,0 +1,34 @@
+{
+ "name": "fastify-auth-app",
+ "description": "Fastify + Auth.js Developer app",
+ "type": "module",
+ "private": true,
+ "scripts": {
+ "start": "node dist/server.js",
+ "clean": "rm -rf dist",
+ "build": "pnpm build:ts && pnpm build:css",
+ "build:ts": "tsc",
+ "build:css": "tailwindcss -i ./public/css/style.css -o ./public/css/output.css",
+ "dev": "tsx watch --env-file=.env src/server.ts & pnpm build:css -w",
+ "debug": "tsx watch --inspect --env-file=.env src/server.ts & pnpm build:css -w",
+ "lint": "eslint src/*.ts --fix",
+ "prettier": "prettier src/*.ts --write"
+ },
+ "author": "Songkeys (https://github.com/songkeys)",
+ "license": "MIT",
+ "dependencies": {
+ "@auth/fastify": "workspace:*",
+ "fastify": "^5.0.0",
+ "@fastify/view": "^10.0.1",
+ "@fastify/static": "^8.0.1",
+ "pug": "^3.0.2",
+ "tailwindcss": "^3.4.3"
+ },
+ "devDependencies": {
+ "@prettier/plugin-pug": "^3.0.0",
+ "@types/morgan": "^1.9.9",
+ "@types/pug": "^2.0.10",
+ "tsx": "^4.7.3",
+ "typescript": "5.4.5"
+ }
+}
diff --git a/apps/dev/fastify/public/css/style.css b/apps/dev/fastify/public/css/style.css
new file mode 100644
index 0000000000..7f393742af
--- /dev/null
+++ b/apps/dev/fastify/public/css/style.css
@@ -0,0 +1,5 @@
+@tailwind base;
+
+@tailwind components;
+
+@tailwind utilities;
diff --git a/apps/dev/fastify/src/app.ts b/apps/dev/fastify/src/app.ts
new file mode 100644
index 0000000000..b008b3b21e
--- /dev/null
+++ b/apps/dev/fastify/src/app.ts
@@ -0,0 +1,87 @@
+import Fastify from "fastify"
+
+import * as path from "node:path"
+import {
+ errorHandler,
+ errorNotFoundHandler,
+} from "./middleware/error.middleware.js"
+import {
+ authenticatedApi,
+ authenticatedPage,
+ currentSession,
+} from "./middleware/auth.middleware.js"
+
+import { FastifyAuth, type Session } from "@auth/fastify"
+import { authConfig } from "./config/auth.config.js"
+
+import * as pug from "pug"
+import fastifyView from "@fastify/view"
+import fastifyStatic from "@fastify/static"
+
+declare module "fastify" {
+ interface FastifyReply {
+ session: Session | null
+ }
+}
+
+// Trust Proxy for Proxies (Heroku, Render.com, Docker behind Nginx, etc)
+export const fastify = Fastify({ trustProxy: true, logger: true })
+
+// Decorating the reply is not required but will optimise performance
+// Only decorate the reply with a value type like null, as reference types like objects are shared among all requests, creating a security risk.
+fastify.decorateReply("session", null)
+
+fastify.register(fastifyView, {
+ engine: {
+ pug,
+ },
+ root: path.join(import.meta.dirname, "..", "views"),
+})
+
+// Serve static files
+// NB: Uncomment this out if you want Fastify to serve static files for you vs. using a
+// hosting provider which does so for you (for example through a CDN).
+fastify.register(fastifyStatic, {
+ root: path.join(import.meta.dirname, "..", "public"),
+})
+
+// Set session in reply
+fastify.addHook("preHandler", currentSession)
+
+// Set up FastifyAuth to handle authentication
+// IMPORTANT: It is highly encouraged set up rate limiting on this route
+fastify.register(FastifyAuth(authConfig), { prefix: "/api/auth" })
+
+// Routes
+fastify.get(
+ "/protected",
+ { preHandler: [authenticatedPage] },
+ async (req, reply) => {
+ return reply.view("protected", { session: reply.session })
+ }
+)
+
+fastify.get(
+ "/api/protected",
+ { preHandler: [authenticatedApi] },
+ async (req, reply) => {
+ return reply.send(reply.session)
+ }
+)
+
+fastify.get("/", async (_req, reply) => {
+ return reply.view("index", {
+ title: "Fastify Auth Example",
+ user: reply.session?.user,
+ })
+})
+
+fastify.get("/2", async (_req, reply) => {
+ return reply.view("index", {
+ title: "Fastify Auth Example",
+ user: reply.session?.user,
+ })
+})
+
+fastify.setErrorHandler(errorHandler)
+fastify.setNotFoundHandler(errorNotFoundHandler)
diff --git a/apps/dev/fastify/src/config/auth.config.ts b/apps/dev/fastify/src/config/auth.config.ts
new file mode 100644
index 0000000000..1798ef1f43
--- /dev/null
+++ b/apps/dev/fastify/src/config/auth.config.ts
@@ -0,0 +1,69 @@
+import Apple from "@auth/fastify/providers/apple"
+import Auth0 from "@auth/fastify/providers/auth0"
+import AzureB2C from "@auth/fastify/providers/azure-ad-b2c"
+import BoxyHQSAML from "@auth/fastify/providers/boxyhq-saml"
+import Cognito from "@auth/fastify/providers/cognito"
+import Coinbase from "@auth/fastify/providers/coinbase"
+import Discord from "@auth/fastify/providers/discord"
+import Dropbox from "@auth/fastify/providers/dropbox"
+import Facebook from "@auth/fastify/providers/facebook"
+import GitHub from "@auth/fastify/providers/github"
+import Gitlab from "@auth/fastify/providers/gitlab"
+import Google from "@auth/fastify/providers/google"
+import Hubspot from "@auth/fastify/providers/hubspot"
+import Keycloak from "@auth/fastify/providers/keycloak"
+import LinkedIn from "@auth/fastify/providers/linkedin"
+import Netlify from "@auth/fastify/providers/netlify"
+import Okta from "@auth/fastify/providers/okta"
+import Passage from "@auth/fastify/providers/passage"
+import Pinterest from "@auth/fastify/providers/pinterest"
+import Reddit from "@auth/fastify/providers/reddit"
+import Slack from "@auth/fastify/providers/slack"
+import Spotify from "@auth/fastify/providers/spotify"
+import Twitch from "@auth/fastify/providers/twitch"
+import Twitter from "@auth/fastify/providers/twitter"
+import WorkOS from "@auth/fastify/providers/workos"
+import Zoom from "@auth/fastify/providers/zoom"
+
+export const authConfig = {
+ trustHost: true,
+ debug: process.env.NODE_ENV !== "production",
+ providers: [
+ Apple,
+ Auth0,
+ AzureB2C({
+ clientId: process.env.AUTH_AZURE_AD_B2C_ID,
+ clientSecret: process.env.AUTH_AZURE_AD_B2C_SECRET,
+ issuer: process.env.AUTH_AZURE_AD_B2C_ISSUER,
+ }),
+ BoxyHQSAML({
+ clientId: "dummy",
+ clientSecret: "dummy",
+ issuer: process.env.AUTH_BOXYHQ_SAML_ISSUER,
+ }),
+ Cognito,
+ Coinbase,
+ Discord,
+ Dropbox,
+ Facebook,
+ GitHub,
+ Gitlab,
+ Google,
+ Hubspot,
+ Keycloak,
+ LinkedIn,
+ Netlify,
+ Okta,
+ Passage,
+ Pinterest,
+ Reddit,
+ Slack,
+ Spotify,
+ Twitch,
+ Twitter,
+ WorkOS({
+ connection: process.env.AUTH_WORKOS_CONNECTION!,
+ }),
+ Zoom,
+ ],
+}
diff --git a/apps/dev/fastify/src/errors.ts b/apps/dev/fastify/src/errors.ts
new file mode 100644
index 0000000000..43853cfe84
--- /dev/null
+++ b/apps/dev/fastify/src/errors.ts
@@ -0,0 +1,14 @@
+export class HttpError extends Error {
+ status: number
+ constructor(status: number, message: string) {
+ super(message)
+ this.status = status
+ }
+}
+
+export class NotFoundError extends HttpError {
+ constructor(message: string, status = 404) {
+ super(status, message)
+ this.name = "NotFoundError"
+ }
+}
diff --git a/apps/dev/fastify/src/middleware/auth.middleware.ts b/apps/dev/fastify/src/middleware/auth.middleware.ts
new file mode 100644
index 0000000000..498cf82012
--- /dev/null
+++ b/apps/dev/fastify/src/middleware/auth.middleware.ts
@@ -0,0 +1,28 @@
+//// @ts-nocheck
+import { getSession } from "@auth/fastify"
+import { authConfig } from "../config/auth.config.js"
+import { FastifyReply, FastifyRequest } from "fastify"
+
+export async function authenticatedApi(
+ req: FastifyRequest,
+ reply: FastifyReply
+) {
+ reply.session ??= (await getSession(req, authConfig)) ?? null
+ if (!reply.session) {
+ reply.status(401).send({ message: "Not Authenticated" })
+ }
+}
+
+export async function authenticatedPage(
+ req: FastifyRequest,
+ reply: FastifyReply
+) {
+ reply.session ??= (await getSession(req, authConfig)) ?? null
+ if (!reply.session) {
+ return reply.view("unauthenticated")
+ }
+}
+
+export async function currentSession(req: FastifyRequest, reply: FastifyReply) {
+ reply.session = (await getSession(req, authConfig)) ?? null
+}
diff --git a/apps/dev/fastify/src/middleware/error.middleware.ts b/apps/dev/fastify/src/middleware/error.middleware.ts
new file mode 100644
index 0000000000..701e77ffd2
--- /dev/null
+++ b/apps/dev/fastify/src/middleware/error.middleware.ts
@@ -0,0 +1,22 @@
+//// @ts-nocheck
+import { HttpError, NotFoundError } from "../errors.js"
+import { FastifyReply, FastifyRequest } from "fastify"
+
+export const errorHandler = (
+ err: HttpError | Error,
+ _req: FastifyRequest,
+ _reply: FastifyReply
+): void => {
+ const statusCode = (err instanceof HttpError && err.status) || 500
+ _reply.status(statusCode).view("error", {
+ title: err instanceof HttpError ? err.status : err.name,
+ message: err.message,
+ })
+}
+
+export const errorNotFoundHandler = (
+ _req: FastifyRequest,
+ _reply: FastifyReply
+): void => {
+ new NotFoundError("Not Found")
+}
diff --git a/apps/dev/fastify/src/server.ts b/apps/dev/fastify/src/server.ts
new file mode 100644
index 0000000000..1e0a75062c
--- /dev/null
+++ b/apps/dev/fastify/src/server.ts
@@ -0,0 +1,18 @@
+const { fastify } = await import("./app.js")
+
+// const address = fastify.server.address()
+// const port = (typeof address === "object" && address?.port) || 3000
+
+const port = Number(process.env.PORT) || 3000
+
+const start = async () => {
+ try {
+ await fastify.listen({ port })
+ fastify.log.info(`server listening on ${fastify.server.address()}`)
+ } catch (err) {
+ fastify.log.error(err)
+ process.exit(1)
+ }
+}
+
+start()
diff --git a/apps/dev/fastify/tsconfig.json b/apps/dev/fastify/tsconfig.json
new file mode 100644
index 0000000000..6b8858be5f
--- /dev/null
+++ b/apps/dev/fastify/tsconfig.json
@@ -0,0 +1,16 @@
+{
+ "compilerOptions": {
+ "module": "NodeNext",
+ "esModuleInterop": true,
+ "target": "esnext",
+ "noImplicitAny": true,
+ "moduleResolution": "NodeNext",
+ "sourceMap": true,
+ "outDir": "dist",
+ "baseUrl": ".",
+ "skipLibCheck": true,
+ "strict": true
+ },
+ "include": ["src/**/*.ts"],
+ "exclude": ["node_modules"]
+}
diff --git a/apps/dev/fastify/views/error.pug b/apps/dev/fastify/views/error.pug
new file mode 100644
index 0000000000..904c3bccb0
--- /dev/null
+++ b/apps/dev/fastify/views/error.pug
@@ -0,0 +1,5 @@
+extends layout
+
+block content
+ h1(class="text-3xl font-bold")= title
+ p= message
diff --git a/apps/dev/fastify/views/index.pug b/apps/dev/fastify/views/index.pug
new file mode 100644
index 0000000000..3781e616a5
--- /dev/null
+++ b/apps/dev/fastify/views/index.pug
@@ -0,0 +1,11 @@
+extends layout
+
+block content
+ h1(class="text-3xl font-bold")= title
+ p
+ | This is an example site to demonstrate how to use #{ ' ' }
+ a(href="https://fastify.dev/", class="mb-2 font-medium underline") Fastify
+ | #{ ' ' } with #{ ' ' }
+ a(href="https://authjs.dev/reference/fastify", class="underline") Fastify Auth
+ |
+ | for authentication.
diff --git a/apps/dev/fastify/views/layout.pug b/apps/dev/fastify/views/layout.pug
new file mode 100644
index 0000000000..32cc435314
--- /dev/null
+++ b/apps/dev/fastify/views/layout.pug
@@ -0,0 +1,40 @@
+doctype html
+html
+ head
+ title= title
+ link(rel="stylesheet", href="/css/output.css")
+ meta(name="viewport", content="width=device-width, initial-scale=1.0")
+ body(class="flex flex-col items-center")
+ div(class="flex w-[90%] max-w-2xl flex-col justify-start gap-2")
+ div(
+ class="mb-2 flex items-center justify-between gap-2 rounded-b-md bg-gray-100 p-2 pl-4"
+ )
+ if session
+ div(class="flex flex-row items-center gap-2")
+ if session.user.image
+ img(src=`${session.user.image}`, class="h-8 w-8 rounded-full")
+ span
+ | Signed in as #{ ' ' }
+ strong= session.user.email || session.user.name
+ a(
+ class="rounded-md bg-blue-600 px-5 py-2.5 font-medium text-white",
+ href="/api/auth/signout"
+ ) Sign out
+ else
+ span(class="") You are not signed in
+ a#sign-indiv(
+ ,
+ class="rounded-md bg-blue-600 px-5 py-2.5 font-medium text-white",
+ href="/api/auth/signin"
+ ) Sign in
+
+ nav(class="mb-4")
+ ul(class="flex flex-row gap-4 underline")
+ li
+ a(href="/") Home
+ li
+ a(href="/protected") Protected
+ li
+ a(href="/api/protected") Protected (API)
+
+ block content
diff --git a/apps/dev/fastify/views/protected.pug b/apps/dev/fastify/views/protected.pug
new file mode 100644
index 0000000000..9ceaac767c
--- /dev/null
+++ b/apps/dev/fastify/views/protected.pug
@@ -0,0 +1,8 @@
+extends layout
+
+block content
+ h1(class="mb-2 text-3xl font-medium") Protected page
+ p
+ | This is a protected content. You can access this content because you are
+ | signed in.
+ p Session expiry: #{ session.expires ? session.expires : '' }
diff --git a/apps/dev/fastify/views/unauthenticated.pug b/apps/dev/fastify/views/unauthenticated.pug
new file mode 100644
index 0000000000..6b334387bd
--- /dev/null
+++ b/apps/dev/fastify/views/unauthenticated.pug
@@ -0,0 +1,8 @@
+extends layout
+
+block content
+ h1(class="mb-2 text-3xl font-medium") Access Denied
+ p
+ | You must be #{ ' ' }
+ a(href="/api/auth/signin", class="underline") signed in
+ | #{ ' ' } to view this page
diff --git a/apps/examples/fastify/.env.example b/apps/examples/fastify/.env.example
new file mode 100644
index 0000000000..6959cc6e03
--- /dev/null
+++ b/apps/examples/fastify/.env.example
@@ -0,0 +1,7 @@
+AUTH_SECRET=
+
+AUTH_GITHUB_ID=
+AUTH_GITHUB_SECRET=
+
+AUTH_GOOGLE_ID=
+AUTH_GOOGLE_SECRET=
\ No newline at end of file
diff --git a/apps/examples/fastify/.eslintrc.cjs b/apps/examples/fastify/.eslintrc.cjs
new file mode 100644
index 0000000000..8ee6a4c20c
--- /dev/null
+++ b/apps/examples/fastify/.eslintrc.cjs
@@ -0,0 +1,26 @@
+module.exports = {
+ root: true,
+ env: {
+ browser: true,
+ es2021: true,
+ },
+ extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
+ overrides: [
+ {
+ env: {
+ node: true,
+ },
+ files: [".eslintrc.{js,cjs}"],
+ parserOptions: {
+ sourceType: "script",
+ },
+ },
+ ],
+ parser: "@typescript-eslint/parser",
+ parserOptions: {
+ ecmaVersion: "latest",
+ sourceType: "module",
+ },
+ plugins: ["@typescript-eslint"],
+ rules: {},
+}
diff --git a/apps/examples/fastify/.gitignore b/apps/examples/fastify/.gitignore
new file mode 100644
index 0000000000..01fd4ed6db
--- /dev/null
+++ b/apps/examples/fastify/.gitignore
@@ -0,0 +1,21 @@
+# API keys and secrets
+.env
+
+# Dependency directory
+node_modules
+
+# Editors
+.idea
+*.iml
+.vscode/settings.json
+
+# OS metadata
+.DS_Store
+Thumbs.db
+
+# Ignore built ts files
+dist/**/*
+
+# Ignore built css files
+/public/css/output.css
+
diff --git a/apps/examples/fastify/.prettierignore b/apps/examples/fastify/.prettierignore
new file mode 100644
index 0000000000..f97e266fdd
--- /dev/null
+++ b/apps/examples/fastify/.prettierignore
@@ -0,0 +1,14 @@
+
+.DS_Store
+node_modules
+/dist
+/.turbo
+/package
+.env
+.env.*
+!.env.example
+
+# Ignore files for PNPM, NPM and YARN
+pnpm-lock.yaml
+package-lock.json
+yarn.lock
diff --git a/apps/examples/fastify/.prettierrc b/apps/examples/fastify/.prettierrc
new file mode 100644
index 0000000000..5451234106
--- /dev/null
+++ b/apps/examples/fastify/.prettierrc
@@ -0,0 +1,5 @@
+{
+ "semi": false,
+ "plugins": ["@prettier/plugin-pug", "prettier-plugin-tailwindcss"],
+ "pugClassNotation": "attribute"
+}
diff --git a/apps/examples/fastify/README.md b/apps/examples/fastify/README.md
new file mode 100644
index 0000000000..403cb758e3
--- /dev/null
+++ b/apps/examples/fastify/README.md
@@ -0,0 +1,63 @@
+> The example repository is maintained from a [monorepo](https://github.com/nextauthjs/next-auth/tree/main/apps/examples/fastify). Pull Requests should be opened against [`nextauthjs/next-auth`](https://github.com/nextauthjs/next-auth).
+
+
+
+
+
+
+
+
+
+
Fastify Auth - Example App
+
+ Open Source. Full Stack. Own Your Data.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+## Overview
+
+This is the official Fastify Auth example for [Auth.js](https://fastify.authjs.dev).
+
+## Getting started
+
+You can instantly deploy this example to [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=fastify-auth-example) by clicking the following button.
+
+[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/nextauthjs/fastify-auth-example&project-name=fastify-auth-example&repository-name=fastify-auth-example)
+
+## Environment Variables
+
+Once deployed, kindly ensure you set all [required environment variables](https://authjs.dev/getting-started/deployment#environment-variables) in the `Environment` section of your hosting service.
+
+## Node.js Compatibility
+
+The recommended version of Node.js to use in this example is Node.js v20.0.0.
+
+If you are using a version of Node.js lower than this (for example the minimum supported node version v18.0.0), you may need to enable Web Crypto API via the `--experimental-webcrypto` flag in the `start` and `dev` scripts of your `package.json` file.
+
+Instead of using the experimental flag, you may use the following polyfill:
+
+```ts
+// polyfill.cjs
+globalThis.crypto ??= require("crypto").webcrypto
+```
+
+And then import it within a top-level file in the application:
+
+```ts
+// server.ts
+import "./polyfill.cjs"
+```
diff --git a/apps/examples/fastify/api/index.js b/apps/examples/fastify/api/index.js
new file mode 100644
index 0000000000..7bdcdc07d1
--- /dev/null
+++ b/apps/examples/fastify/api/index.js
@@ -0,0 +1,3 @@
+const { app } = await import("../src/app.js")
+
+export default app
diff --git a/apps/examples/fastify/package.json b/apps/examples/fastify/package.json
new file mode 100644
index 0000000000..905e542a7f
--- /dev/null
+++ b/apps/examples/fastify/package.json
@@ -0,0 +1,35 @@
+{
+ "description": "Fastify Auth example app",
+ "engines": {
+ "node": ">=20.11.0"
+ },
+ "type": "module",
+ "private": true,
+ "scripts": {
+ "start": "node dist/server.js",
+ "clean": "rm -rf dist",
+ "build": "pnpm build:ts && pnpm build:css",
+ "build:ts": "tsc",
+ "build:css": "tailwindcss -i ./public/css/style.css -o ./public/css/output.css",
+ "dev": "tsx watch --env-file=.env src/server.ts & pnpm build:css -w",
+ "debug": "tsx watch --inspect --env-file=.env src/server.ts & pnpm build:css -w",
+ "lint": "eslint src/*.ts --fix",
+ "prettier": "prettier src/*.ts --write"
+ },
+ "author": "Lachie Hill ",
+ "license": "ISC",
+ "dependencies": {
+ "@auth/fastify": "workspace:*",
+ "@fastify/view": "^10.0.1",
+ "@fastify/static": "^8.0.1",
+ "fastify": "^5.0.0",
+ "pug": "^3.0.2",
+ "tailwindcss": "^3.4.3"
+ },
+ "devDependencies": {
+ "@types/node": "^20.12.7",
+ "@types/pug": "^2.0.10",
+ "tsx": "^4.7.0",
+ "typescript": "5.3.3"
+ }
+}
diff --git a/apps/examples/fastify/public/css/style.css b/apps/examples/fastify/public/css/style.css
new file mode 100644
index 0000000000..b5c61c9567
--- /dev/null
+++ b/apps/examples/fastify/public/css/style.css
@@ -0,0 +1,3 @@
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
diff --git a/apps/examples/fastify/src/app.ts b/apps/examples/fastify/src/app.ts
new file mode 100644
index 0000000000..229be62a82
--- /dev/null
+++ b/apps/examples/fastify/src/app.ts
@@ -0,0 +1,75 @@
+//// @ts-nocheck
+import Fastify from "fastify"
+
+import * as path from "node:path"
+import {
+ errorHandler,
+ errorNotFoundHandler,
+} from "./middleware/error.middleware.js"
+import {
+ authenticatedApi,
+ authenticatedPage,
+ currentSession,
+} from "./middleware/auth.middleware.js"
+
+import { FastifyAuth } from "@auth/fastify"
+import { authConfig } from "./config/auth.config.js"
+
+import * as pug from "pug"
+import fastifyView from "@fastify/view"
+import fastifyStatic from "@fastify/static"
+
+// Trust Proxy for Proxies (Heroku, Render.com, Docker behind Nginx, etc)
+export const fastify = Fastify({ trustProxy: true, logger: true })
+
+// Decorating the reply is not required but will optimise performance
+// Only decorate the reply with a value type like null, as reference types like objects are shared among all requests, creating a security risk.
+fastify.decorateReply("session", null)
+
+fastify.register(fastifyView, {
+ engine: {
+ pug,
+ },
+ root: path.join(import.meta.dirname, "..", "views"),
+})
+
+// Serve static files
+// NB: Uncomment this out if you want Fastify to serve static files for you vs. using a
+// hosting provider which does so for you (for example through a CDN).
+fastify.register(fastifyStatic, {
+ root: path.join(import.meta.dirname, "..", "public"),
+})
+
+// Set session in reply
+fastify.addHook("preHandler", currentSession)
+
+// Set up FastifyAuth to handle authentication
+// IMPORTANT: It is highly encouraged set up rate limiting on this route
+fastify.register(FastifyAuth(authConfig), { prefix: "/api/auth" })
+
+// Routes
+fastify.get(
+ "/protected",
+ { preHandler: [authenticatedPage] },
+ async (req, reply) => {
+ return reply.view("protected", { session: reply.session })
+ },
+)
+
+fastify.get(
+ "/api/protected",
+ { preHandler: [authenticatedApi] },
+ async (req, reply) => {
+ return reply.send(reply.session)
+ },
+)
+
+fastify.get("/", async (_req, reply) => {
+ return reply.view("index", {
+ title: "Fastify Auth Example",
+ user: reply.session?.user,
+ })
+})
+
+fastify.setErrorHandler(errorHandler)
+fastify.setNotFoundHandler(errorNotFoundHandler)
diff --git a/apps/examples/fastify/src/config/auth.config.ts b/apps/examples/fastify/src/config/auth.config.ts
new file mode 100644
index 0000000000..1798ef1f43
--- /dev/null
+++ b/apps/examples/fastify/src/config/auth.config.ts
@@ -0,0 +1,69 @@
+import Apple from "@auth/fastify/providers/apple"
+import Auth0 from "@auth/fastify/providers/auth0"
+import AzureB2C from "@auth/fastify/providers/azure-ad-b2c"
+import BoxyHQSAML from "@auth/fastify/providers/boxyhq-saml"
+import Cognito from "@auth/fastify/providers/cognito"
+import Coinbase from "@auth/fastify/providers/coinbase"
+import Discord from "@auth/fastify/providers/discord"
+import Dropbox from "@auth/fastify/providers/dropbox"
+import Facebook from "@auth/fastify/providers/facebook"
+import GitHub from "@auth/fastify/providers/github"
+import Gitlab from "@auth/fastify/providers/gitlab"
+import Google from "@auth/fastify/providers/google"
+import Hubspot from "@auth/fastify/providers/hubspot"
+import Keycloak from "@auth/fastify/providers/keycloak"
+import LinkedIn from "@auth/fastify/providers/linkedin"
+import Netlify from "@auth/fastify/providers/netlify"
+import Okta from "@auth/fastify/providers/okta"
+import Passage from "@auth/fastify/providers/passage"
+import Pinterest from "@auth/fastify/providers/pinterest"
+import Reddit from "@auth/fastify/providers/reddit"
+import Slack from "@auth/fastify/providers/slack"
+import Spotify from "@auth/fastify/providers/spotify"
+import Twitch from "@auth/fastify/providers/twitch"
+import Twitter from "@auth/fastify/providers/twitter"
+import WorkOS from "@auth/fastify/providers/workos"
+import Zoom from "@auth/fastify/providers/zoom"
+
+export const authConfig = {
+ trustHost: true,
+ debug: process.env.NODE_ENV !== "production",
+ providers: [
+ Apple,
+ Auth0,
+ AzureB2C({
+ clientId: process.env.AUTH_AZURE_AD_B2C_ID,
+ clientSecret: process.env.AUTH_AZURE_AD_B2C_SECRET,
+ issuer: process.env.AUTH_AZURE_AD_B2C_ISSUER,
+ }),
+ BoxyHQSAML({
+ clientId: "dummy",
+ clientSecret: "dummy",
+ issuer: process.env.AUTH_BOXYHQ_SAML_ISSUER,
+ }),
+ Cognito,
+ Coinbase,
+ Discord,
+ Dropbox,
+ Facebook,
+ GitHub,
+ Gitlab,
+ Google,
+ Hubspot,
+ Keycloak,
+ LinkedIn,
+ Netlify,
+ Okta,
+ Passage,
+ Pinterest,
+ Reddit,
+ Slack,
+ Spotify,
+ Twitch,
+ Twitter,
+ WorkOS({
+ connection: process.env.AUTH_WORKOS_CONNECTION!,
+ }),
+ Zoom,
+ ],
+}
diff --git a/apps/examples/fastify/src/errors.ts b/apps/examples/fastify/src/errors.ts
new file mode 100644
index 0000000000..43853cfe84
--- /dev/null
+++ b/apps/examples/fastify/src/errors.ts
@@ -0,0 +1,14 @@
+export class HttpError extends Error {
+ status: number
+ constructor(status: number, message: string) {
+ super(message)
+ this.status = status
+ }
+}
+
+export class NotFoundError extends HttpError {
+ constructor(message: string, status = 404) {
+ super(status, message)
+ this.name = "NotFoundError"
+ }
+}
diff --git a/apps/examples/fastify/src/middleware/auth.middleware.ts b/apps/examples/fastify/src/middleware/auth.middleware.ts
new file mode 100644
index 0000000000..ef6c56cf78
--- /dev/null
+++ b/apps/examples/fastify/src/middleware/auth.middleware.ts
@@ -0,0 +1,28 @@
+//// @ts-nocheck
+import { getSession } from "@auth/fastify"
+import { authConfig } from "../config/auth.config.js"
+import { FastifyReply, FastifyRequest } from "fastify"
+
+export async function authenticatedApi(
+ req: FastifyRequest,
+ reply: FastifyReply,
+) {
+ reply.session ??= await getSession(req, authConfig)
+ if (!reply.session) {
+ reply.status(401).send({ message: "Not Authenticated" })
+ }
+}
+
+export async function authenticatedPage(
+ req: FastifyRequest,
+ reply: FastifyReply,
+) {
+ reply.session ??= await getSession(req, authConfig)
+ if (!reply.session) {
+ return reply.view("unauthenticated")
+ }
+}
+
+export async function currentSession(req: FastifyRequest, reply: FastifyReply) {
+ reply.session = await getSession(req, authConfig)
+}
diff --git a/apps/examples/fastify/src/middleware/error.middleware.ts b/apps/examples/fastify/src/middleware/error.middleware.ts
new file mode 100644
index 0000000000..eb24ee3ef8
--- /dev/null
+++ b/apps/examples/fastify/src/middleware/error.middleware.ts
@@ -0,0 +1,22 @@
+//// @ts-nocheck
+import { HttpError, NotFoundError } from "../errors.js"
+import { FastifyReply, FastifyRequest } from "fastify"
+
+export const errorHandler = (
+ err: HttpError | Error,
+ _req: FastifyRequest,
+ _reply: FastifyReply,
+): void => {
+ const statusCode = (err instanceof HttpError && err.status) || 500
+ _reply.status(statusCode).view("error", {
+ title: err instanceof HttpError ? err.status : err.name,
+ message: err.message,
+ })
+}
+
+export const errorNotFoundHandler = (
+ _req: FastifyRequest,
+ _reply: FastifyReply,
+): void => {
+ new NotFoundError("Not Found")
+}
diff --git a/apps/examples/fastify/src/server.ts b/apps/examples/fastify/src/server.ts
new file mode 100644
index 0000000000..1e0a75062c
--- /dev/null
+++ b/apps/examples/fastify/src/server.ts
@@ -0,0 +1,18 @@
+const { fastify } = await import("./app.js")
+
+// const address = fastify.server.address()
+// const port = (typeof address === "object" && address?.port) || 3000
+
+const port = Number(process.env.PORT) || 3000
+
+const start = async () => {
+ try {
+ await fastify.listen({ port })
+ fastify.log.info(`server listening on ${fastify.server.address()}`)
+ } catch (err) {
+ fastify.log.error(err)
+ process.exit(1)
+ }
+}
+
+start()
diff --git a/apps/examples/fastify/tailwind.config.js b/apps/examples/fastify/tailwind.config.js
new file mode 100644
index 0000000000..137ee749c8
--- /dev/null
+++ b/apps/examples/fastify/tailwind.config.js
@@ -0,0 +1,8 @@
+/** @type {import('tailwindcss').Config} */
+export default {
+ content: ["./src/*.{html,js,css}", "./views/*.pug"],
+ theme: {
+ extend: {},
+ },
+ plugins: [],
+}
diff --git a/apps/examples/fastify/tsconfig.json b/apps/examples/fastify/tsconfig.json
new file mode 100644
index 0000000000..6945a6415c
--- /dev/null
+++ b/apps/examples/fastify/tsconfig.json
@@ -0,0 +1,17 @@
+{
+ "compilerOptions": {
+ "module": "NodeNext",
+ "esModuleInterop": true,
+ "target": "esnext",
+ "noImplicitAny": true,
+ "moduleResolution": "NodeNext",
+ "sourceMap": true,
+ "outDir": "dist",
+ "baseUrl": ".",
+ "skipLibCheck": true,
+ "strict": true,
+ "typeRoots": ["types/", "node_modules/@types"]
+ },
+ "include": ["src/**/*.ts"],
+ "exclude": ["node_modules"]
+}
diff --git a/apps/examples/fastify/types/fastify/index.d.ts b/apps/examples/fastify/types/fastify/index.d.ts
new file mode 100644
index 0000000000..35b3b657c4
--- /dev/null
+++ b/apps/examples/fastify/types/fastify/index.d.ts
@@ -0,0 +1,7 @@
+import { type Session } from "@auth/fastify"
+
+declare module "fastify" {
+ interface FastifyReply {
+ session: Session | null
+ }
+}
diff --git a/apps/examples/fastify/vercel.json b/apps/examples/fastify/vercel.json
new file mode 100644
index 0000000000..fbeec9f1b9
--- /dev/null
+++ b/apps/examples/fastify/vercel.json
@@ -0,0 +1,4 @@
+{
+ "$schema": "https://openapi.vercel.sh/vercel.json",
+ "rewrites": [{ "source": "/(.*)", "destination": "/api" }]
+}
diff --git a/apps/examples/fastify/views/error.pug b/apps/examples/fastify/views/error.pug
new file mode 100644
index 0000000000..904c3bccb0
--- /dev/null
+++ b/apps/examples/fastify/views/error.pug
@@ -0,0 +1,5 @@
+extends layout
+
+block content
+ h1(class="text-3xl font-bold")= title
+ p= message
diff --git a/apps/examples/fastify/views/index.pug b/apps/examples/fastify/views/index.pug
new file mode 100644
index 0000000000..3781e616a5
--- /dev/null
+++ b/apps/examples/fastify/views/index.pug
@@ -0,0 +1,11 @@
+extends layout
+
+block content
+ h1(class="text-3xl font-bold")= title
+ p
+ | This is an example site to demonstrate how to use #{ ' ' }
+ a(href="https://fastify.dev/", class="mb-2 font-medium underline") Fastify
+ | #{ ' ' } with #{ ' ' }
+ a(href="https://authjs.dev/reference/fastify", class="underline") Fastify Auth
+ |
+ | for authentication.
diff --git a/apps/examples/fastify/views/layout.pug b/apps/examples/fastify/views/layout.pug
new file mode 100644
index 0000000000..32cc435314
--- /dev/null
+++ b/apps/examples/fastify/views/layout.pug
@@ -0,0 +1,40 @@
+doctype html
+html
+ head
+ title= title
+ link(rel="stylesheet", href="/css/output.css")
+ meta(name="viewport", content="width=device-width, initial-scale=1.0")
+ body(class="flex flex-col items-center")
+ div(class="flex w-[90%] max-w-2xl flex-col justify-start gap-2")
+ div(
+ class="mb-2 flex items-center justify-between gap-2 rounded-b-md bg-gray-100 p-2 pl-4"
+ )
+ if session
+ div(class="flex flex-row items-center gap-2")
+ if session.user.image
+ img(src=`${session.user.image}`, class="h-8 w-8 rounded-full")
+ span
+ | Signed in as #{ ' ' }
+ strong= session.user.email || session.user.name
+ a(
+ class="rounded-md bg-blue-600 px-5 py-2.5 font-medium text-white",
+ href="/api/auth/signout"
+ ) Sign out
+ else
+ span(class="") You are not signed in
+ a#sign-indiv(
+ ,
+ class="rounded-md bg-blue-600 px-5 py-2.5 font-medium text-white",
+ href="/api/auth/signin"
+ ) Sign in
+
+ nav(class="mb-4")
+ ul(class="flex flex-row gap-4 underline")
+ li
+ a(href="/") Home
+ li
+ a(href="/protected") Protected
+ li
+ a(href="/api/protected") Protected (API)
+
+ block content
diff --git a/apps/examples/fastify/views/protected.pug b/apps/examples/fastify/views/protected.pug
new file mode 100644
index 0000000000..9ceaac767c
--- /dev/null
+++ b/apps/examples/fastify/views/protected.pug
@@ -0,0 +1,8 @@
+extends layout
+
+block content
+ h1(class="mb-2 text-3xl font-medium") Protected page
+ p
+ | This is a protected content. You can access this content because you are
+ | signed in.
+ p Session expiry: #{ session.expires ? session.expires : '' }
diff --git a/apps/examples/fastify/views/unauthenticated.pug b/apps/examples/fastify/views/unauthenticated.pug
new file mode 100644
index 0000000000..6b334387bd
--- /dev/null
+++ b/apps/examples/fastify/views/unauthenticated.pug
@@ -0,0 +1,8 @@
+extends layout
+
+block content
+ h1(class="mb-2 text-3xl font-medium") Access Denied
+ p
+ | You must be #{ ' ' }
+ a(href="/api/auth/signin", class="underline") signed in
+ | #{ ' ' } to view this page
diff --git a/docs/components/Code/index.tsx b/docs/components/Code/index.tsx
index 63b231b1da..3c4f36648e 100644
--- a/docs/components/Code/index.tsx
+++ b/docs/components/Code/index.tsx
@@ -14,6 +14,7 @@ Code.NextClient = NextClientCode
Code.Svelte = SvelteCode
// Code.Solid = SolidCode;
Code.Express = ExpressCode
+Code.Fastify = FastifyCode
Code.Qwik = QwikCode
const baseFrameworks = {
@@ -22,6 +23,7 @@ const baseFrameworks = {
[SvelteCode.name]: "SvelteKit",
[ExpressCode.name]: "Express",
// [SolidCode.name]: "SolidStart",
+ [FastifyCode.name]: "Fastify",
}
const allFrameworks = {
@@ -31,6 +33,7 @@ const allFrameworks = {
[SvelteCode.name]: "SvelteKit",
// [SolidCode.name]: "SolidStart",
[ExpressCode.name]: "Express",
+ [FastifyCode.name]: "Fastify",
}
const findTabIndex = (frameworks: Record, tab: string) => {
@@ -131,3 +134,7 @@ function ExpressCode({ children }: ChildrenProps) {
function QwikCode({ children }: ChildrenProps) {
return {children}
}
+
+function FastifyCode({ children }: ChildrenProps) {
+ return {children}
+}
diff --git a/docs/pages/getting-started/installation.mdx b/docs/pages/getting-started/installation.mdx
index 544ee8f693..fefe7b7ad7 100644
--- a/docs/pages/getting-started/installation.mdx
+++ b/docs/pages/getting-started/installation.mdx
@@ -36,6 +36,13 @@ Start by installing the appropriate package for your framework.
```
+
+
+ ```bash npm2yarn
+ npm install @auth/fastify
+ ```
+
+
@@ -162,6 +169,23 @@ app.use("/auth/*", ExpressAuth({ providers: [] }))
Note this creates the Auth.js API, but does not yet protect resources. Continue on to [protecting resources](/getting-started/session-management/protecting) for more details.
+
+
+1. Start by importing `FastifyAuth` registering it to your auth API route.
+
+```ts filename="./src/routes/auth.route.ts" {1, 7}
+import { FastifyAuth } from "@auth/fastify"
+import Fastify from "fastify"
+
+// If your app is served through a proxy
+// trust the proxy to allow us to read the `X-Forwarded-*` headers
+const fastify = Fastify({ trustProxy: true })
+fastify.register(FastifyAuth({ providers: [] }), { prefix: "/auth" })
+```
+
+Note this creates the Auth.js API, but does not yet protect resources. Continue on to [protecting resources](/getting-started/session-management/protecting) for more details.
+
+
### Setup Authentication Methods
diff --git a/docs/pages/getting-started/session-management/custom-pages.mdx b/docs/pages/getting-started/session-management/custom-pages.mdx
index 0bc990c3a0..2abdbb4a6b 100644
--- a/docs/pages/getting-started/session-management/custom-pages.mdx
+++ b/docs/pages/getting-started/session-management/custom-pages.mdx
@@ -91,6 +91,27 @@ app.use(
```
+
+
+```ts filename="src/routes/auth.route.ts" {10-12}
+import { FastifyAuth } from "@auth/fastify"
+import Fastify from "fastify"
+import GitHub from "@auth/fastify/providers/github"
+
+const fastify = Fastify({ trustProxy: true })
+
+fastify.register(
+ FastifyAuth({
+ providers: [GitHub],
+ pages: {
+ signIn: "/signin",
+ },
+ }),
+ { prefix: "/auth" }
+)
+```
+
+
To continue setting up the custom page, checkout our [guide on custom pages](/guides/pages/signin).
diff --git a/docs/pages/getting-started/session-management/get-session.mdx b/docs/pages/getting-started/session-management/get-session.mdx
index 392b08235a..aad0675b39 100644
--- a/docs/pages/getting-started/session-management/get-session.mdx
+++ b/docs/pages/getting-started/session-management/get-session.mdx
@@ -202,6 +202,31 @@ app.get("/", (req, res) => {
```
+
+
+```ts filename="app.ts"
+import { getSession } from "@auth/fastify"
+
+// Decorating the reply is not required but will optimise performance
+// Only decorate the reply with a value type like null, as reference types like objects are shared among all requests, creating a security risk.
+fastify.decorateReply("session", null)
+
+export async function authSession(req: FastifyRequest, reply: FastifyReply) {
+ reply.session = await getSession(req, authConfig)
+}
+
+fastify.addHook("preHandler", authSession)
+
+// Now in your route
+fastify.get("/", (req, reply) => {
+ const session = reply.session
+ reply.view("index", { user: session?.user })
+})
+```
+
+Note for TypeScript, you may want to augment the Fastify types to include the `session` property on the reply object.
+
+
If you'd like to extend your session with more fields from your OAuth provider, for example, please check out our ["extending the session" guide](/guides/extending-the-session).
diff --git a/docs/pages/getting-started/session-management/login.mdx b/docs/pages/getting-started/session-management/login.mdx
index 91fbf04442..81357271b4 100644
--- a/docs/pages/getting-started/session-management/login.mdx
+++ b/docs/pages/getting-started/session-management/login.mdx
@@ -132,6 +132,11 @@ Just like in other frameworks, you can also pass a provider to the `signIn` func
The Express package runs server-side and therefore it doesn't make sense to create a "SignIn button component". However, to signin or signout with Express, send a request to the appropriate [REST API Endpoints](/reference/core/types#authaction) from your client (i.e. `/auth/signin`, `/auth/signout`, etc.).
+
+
+The Fastify package runs server-side and therefore it doesn't make sense to create a "SignIn button component". However, to signin or signout with Fastify, send a request to the appropriate [REST API Endpoints](/reference/core/types#authaction) from your client (i.e. `/auth/signin`, `/auth/signout`, etc.).
+
+
You can also pass a provider to the `signIn` function which will attempt to login directly with that provider. Otherwise, when clicking this button in your application, the user will be redirected to the configured sign in page. If you did not setup a [custom sign in page](/guides/pages/signin), the user will be redirected to the default signin page at `/[basePath]/signin`.
@@ -353,6 +358,11 @@ Client-side is a bit simpler as we just need to import a button `on:click` handl
The Express package runs server-side and therefore it doesn't make sense to create a "SignIn button component". However, to signin or signout with Express, send a request to the appropriate [REST API Endpoints](/reference/core/types#authaction) from your client (i.e. `/auth/signin`, `/auth/signout`, etc.).
+
+
+The Fastify package runs server-side and therefore it doesn't make sense to create a "SignIn button component". However, to signin or signout with Fastify, send a request to the appropriate [REST API Endpoints](/reference/core/types#authaction) from your client (i.e. `/auth/signin`, `/auth/signout`, etc.).
+
+
diff --git a/docs/pages/getting-started/session-management/protecting.mdx b/docs/pages/getting-started/session-management/protecting.mdx
index 2d62aada8c..8191988338 100644
--- a/docs/pages/getting-started/session-management/protecting.mdx
+++ b/docs/pages/getting-started/session-management/protecting.mdx
@@ -150,6 +150,65 @@ app.use("/", root)
```
+
+
+You can protect routes by checking for the presence of a session and then redirect to a login page if the session is not present. This can either be done per route, or for a group of routes using a middleware such as the following:
+
+```ts filename="lib.ts"
+import { getSession } from "@auth/fastify"
+
+export async function authenticatedUser(
+ req: FastifyRequest,
+ reply: FastifyReply
+) {
+ reply.session ??= await getSession(req, authConfig)
+ if (!reply.session?.user) {
+ res.redirect("/login")
+ }
+}
+```
+
+To protect a single route, simply register the preHandler hook to the route as follows:
+
+```ts filename="app.ts"
+import { authenticatedUser } from "./lib.ts"
+
+// This route is protected
+fastify.get("/profile", { preHandler: [authenticatedUser] }, (req, reply) => {
+ const session = reply.session
+ reply.view("profile", { user: session?.user })
+})
+
+// This route is not protected
+fastify.get("/", (req, reply) => {
+ reply.view("index")
+})
+```
+
+To protect a group of routes, create a plugin and register the authenication hook and routes to the instance as follows:
+
+```ts filename="app.ts"
+import { authenticatedUser } from "./lib.ts"
+
+fastify.register(
+ async (instance) => {
+ // All routes on this instance will be protected because of the preHandler hook
+ instance.addHook("preHandler", authenticatedUser)
+
+ instance.get("/", (req, reply) => {
+ reply.view("protected")
+ })
+
+ // Example api route
+ instance.get("/me", (req, reply) => {
+ reply.send(reply.session?.user)
+ })
+ },
+ { prefix: "/protected" }
+)
+```
+
+
### API Routes
@@ -238,6 +297,11 @@ export const GET: RequestHandler = async (event) => {
API Routes are protected in the same way as any other route in Express, see [the examples above](/getting-started/session-management/protecting?framework=express#pages).
+
+
+API Routes are protected in the same way as any other route in Fastify, see [the examples above](/getting-started/session-management/protecting?framework=fastify#pages).
+
+
### Next.js Middleware
diff --git a/docs/pages/reference/_meta.js b/docs/pages/reference/_meta.js
index ea0ffabbab..b42fccaa8b 100644
--- a/docs/pages/reference/_meta.js
+++ b/docs/pages/reference/_meta.js
@@ -10,6 +10,7 @@ export default {
express: "@auth/express",
qwik: "@auth/qwik",
"solid-start": "@auth/solid-start",
+ fastify: "@auth/fastify",
warnings: "Warnings",
errors: {
title: "Errors",
diff --git a/docs/vercel.json b/docs/vercel.json
index 6bc2b3a7e0..76fd1c16dd 100644
--- a/docs/vercel.json
+++ b/docs/vercel.json
@@ -5,9 +5,18 @@
{
"source": "/(.*)",
"headers": [
- { "key": "X-Content-Type-Options", "value": "nosniff" },
- { "key": "X-Frame-Options", "value": "DENY" },
- { "key": "X-XSS-Protection", "value": "1; mode=block" },
+ {
+ "key": "X-Content-Type-Options",
+ "value": "nosniff"
+ },
+ {
+ "key": "X-Frame-Options",
+ "value": "DENY"
+ },
+ {
+ "key": "X-XSS-Protection",
+ "value": "1; mode=block"
+ },
{
"key": "Strict-Transport-Security",
"value": "max-age=31536000; includeSubDomains; preload"
diff --git a/package.json b/package.json
index 4a1cebe2c3..768801c0c8 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"dev:sveltekit": "turbo run dev --parallel --continue --filter=sveltekit-auth-app...",
"dev:express": "turbo run dev --parallel --continue --filter=express-auth-app...",
"dev:qwik": "turbo run dev --parallel --continue --filter=qwik-auth-app...",
+ "dev:fastify": "turbo run dev --parallel --continue --filter=fastify-auth-app...",
"dev:docs": "turbo run dev --filter=docs",
"email": "fake-smtp-server",
"lint": "eslint --cache .",
diff --git a/packages/frameworks-fastify/README.md b/packages/frameworks-fastify/README.md
new file mode 100644
index 0000000000..9ed85c79ae
--- /dev/null
+++ b/packages/frameworks-fastify/README.md
@@ -0,0 +1,24 @@
+
+
+
+
Fastify Auth
+ Authentication for Fastify.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+F
+
+---
+
+Check out the documentation at [fastify.authjs.dev](https://fastify.authjs.dev).
diff --git a/packages/frameworks-fastify/package.json b/packages/frameworks-fastify/package.json
new file mode 100644
index 0000000000..cce7657b05
--- /dev/null
+++ b/packages/frameworks-fastify/package.json
@@ -0,0 +1,62 @@
+{
+ "name": "@auth/fastify",
+ "description": "Authentication for Fastify.",
+ "version": "0.0.1",
+ "type": "module",
+ "files": [
+ "*.js",
+ "*.d.ts*",
+ "lib",
+ "providers",
+ "src"
+ ],
+ "exports": {
+ ".": {
+ "types": "./index.d.ts",
+ "import": "./index.js"
+ },
+ "./providers": {
+ "types": "./providers/index.d.ts"
+ },
+ "./adapters": {
+ "types": "./adapters.d.ts"
+ },
+ "./providers/*": {
+ "types": "./providers/*.d.ts",
+ "import": "./providers/*.js"
+ },
+ "./package.json": "./package.json"
+ },
+ "scripts": {
+ "build": "pnpm clean && pnpm providers && tsc",
+ "clean": "rm -rf lib index.* src/lib/providers",
+ "test": "vitest run -c ../utils/vitest.config.ts",
+ "test:debug": "vitest --inspect --inspect-brk --pool threads --poolOptions.threads.singleThread run -c ../utils/vitest.config.ts",
+ "providers": "node ../utils/scripts/providers"
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "dependencies": {
+ "@auth/core": "workspace:*",
+ "@fastify/formbody": "^8.0.1"
+ },
+ "devDependencies": {
+ "@auth/core": "workspace:experimental",
+ "fastify": "^5.0.0"
+ },
+ "peerDependencies": {
+ "fastify": "^5.0.0"
+ },
+ "keywords": [
+ "Fastify",
+ "Auth.js"
+ ],
+ "author": "Lachie Hill ",
+ "contributors": [
+ "Rexford Essilfie "
+ ],
+ "repository": "https://github.com/nextauthjs/next-auth",
+ "license": "ISC"
+}
diff --git a/packages/frameworks-fastify/src/adapters.ts b/packages/frameworks-fastify/src/adapters.ts
new file mode 100644
index 0000000000..e907436642
--- /dev/null
+++ b/packages/frameworks-fastify/src/adapters.ts
@@ -0,0 +1 @@
+export type * from "@auth/core/adapters"
diff --git a/packages/frameworks-fastify/src/index.ts b/packages/frameworks-fastify/src/index.ts
new file mode 100644
index 0000000000..a84c9dc035
--- /dev/null
+++ b/packages/frameworks-fastify/src/index.ts
@@ -0,0 +1,204 @@
+/**
+ *
+ * :::warning
+ * `@auth/fastify` is currently experimental. The API _will_ change in the future.
+ * :::
+ *
+ * Fastify Auth is the official Fastify integration for Auth.js.
+ * It provides a simple way to add authentication to your Fastify app in a few lines of code.
+ *
+ * ## Installation
+ * ```bash npm2yarn
+ * npm install @auth/fastify
+ * ```
+ *
+ * ## Usage
+ *
+ * ```ts title="src/routes/auth.route.ts"
+ * import { FastifyAuth } from "@auth/fastify"
+ * import GitHub from "@auth/fastify/providers/github"
+ * import Fastify from "fastify"
+ *
+ * // If app is served through a proxy, trust the proxy to allow HTTPS protocol to be detected
+ * const fastify = Fastify({ trustProxy: true });
+ *
+ * fastify.register(FastifyAuth({ providers: [ GitHub ] }), { prefix: '/auth' })
+ * ```
+ *
+ * Don't forget to set the `AUTH_SECRET` environment variable. This should be a minimum of 32 characters, random string. On UNIX systems you can use `openssl rand -hex 32` or check out `https://generate-secret.vercel.app/32`.
+ *
+ * You will also need to load the environment variables into your runtime environment. For example in Node.js with a package like [`dotenv`](https://www.npmjs.com/package/dotenv) or `Deno.env` in Deno.
+ *
+ * ### Provider Configuration
+ * The callback URL used by the [providers](https://authjs.dev/reference/core/modules/providers) must be set to the following, unless you mount the `FastifyAuth` handler on a different path:
+ *
+ * ```
+ * [origin]/auth/callback/[provider]
+ * ```
+ *
+ * ## Signing in and signing out
+ * Once your application is mounted you can sign in or out by making requests to the following [REST API endpoints](https://authjs.dev/reference/core/types#authaction) from your client-side code.
+ * NB: Make sure to include the `csrfToken` in the request body for all sign-in and sign-out requests.
+ *
+ * ## Managing the session
+ * If you are using Fastify with a template engine (e.g @fastify/view with EJS, Pug), you can make the session data available to all routes via a preHandler hook as follows
+ *
+ * ```ts title="app.ts"
+ * import { getSession } from "@auth/fastify"
+ *
+ * // Decorating the reply is not required but will optimise performance
+ * // Only decorate the reply with a value type like null, as reference types like objects are shared among all requests, creating a security risk.
+ * fastify.decorateReply('session', null)
+
+ * export async function authSession(req: FastifyRequest, reply: FastifyReply) {
+ * reply.session = await getSession(req, authConfig)
+ * }
+ *
+ * fastify.addHook("preHandler", authSession)
+ *
+ * // Now in your route
+ * fastify.get("/", (req, reply) => {
+ * const session = reply.session;
+ * reply.view("index.pug", { user: session?.user })
+ * })
+ * ```
+ *
+ * Note for TypeScript, you may want to augment the Fastify types to include the `session` property on the reply object. This can be done by creating a @types/fastify/index.d.ts file:
+ *
+ * ```ts title="@types/fastify/index.d.ts"
+ * import { Session } from "@auth/core/types";
+ * declare module "fastify" {
+ * interface FastifyReply {
+ * session: Session | null;
+ * }
+ * }
+ * ```
+ *
+ * You may need to add `"typeRoots": ["@types"]` to `compilerOptions` in your tsconfig.json.
+ *
+ * ## Authorization
+ * You can protect routes with hooks by checking for the presence of a session and then redirect to a login page if the session is not present.
+ *
+ * ```ts
+ * export async function authenticatedUser(
+ * req: FastifyRequest,
+ * reply: FastifyReply
+ * ) {
+ * reply.session ??= await getSession(req, authConfig);
+ * if (!reply.session?.user) {
+ * reply.redirect("/auth/signin?error=SessionRequired");
+ * }
+ * }
+ * ```
+ *
+ * ### Per Route
+ * To protect a single route, simply register the preHandler hook to the route as follows:
+ * ```ts title="app.ts"
+ * // This route is protected
+ * fastify.get("/profile", { preHandler: [authenticatedUser] }, (req, reply) => {
+ * const session = reply.session;
+ * reply.view("profile.pug", { user: session?.user })
+ * });
+ *
+ * // This route is not protected
+ * fastify.get("/", (req, reply) => {
+ * reply.view("index");
+ * });
+ * ```
+ *
+ * ### Per Group of Routes
+ * To protect a group of routes, create a plugin and register the authenication hook and routes to the instance as follows:
+ *
+ * ```ts title="app.ts"
+ * fastify.register(
+ * async (instance) => {
+ * // All routes on this instance will be protected because of the preHandler hook
+ * instance.addHook("preHandler", authenticatedUser)
+ *
+ * instance.get("/", (req, reply) => {
+ * reply.view("protected.pug")
+ * })
+ *
+ * instance.get("/me", (req, reply) => {
+ * reply.send(reply.session?.user)
+ * })
+ * },
+ * { prefix: "/protected" }
+ * )
+ * ```
+ *
+ * @module @auth/fastify
+ */
+
+import {
+ Auth,
+ type AuthConfig,
+ setEnvDefaults,
+ createActionURL,
+} from "@auth/core"
+import type { Session } from "@auth/core/types"
+import type { FastifyRequest, FastifyPluginAsync } from "fastify"
+import formbody from "@fastify/formbody"
+import { toWebRequest, toFastifyReply } from "./lib/index.js"
+
+export type FastifyAuthConfig = Omit
+
+export type {
+ Account,
+ DefaultSession,
+ Profile,
+ Session,
+ User,
+} from "@auth/core/types"
+
+export function FastifyAuth(config: FastifyAuthConfig): FastifyPluginAsync {
+ setEnvDefaults(process.env, config)
+ return async (fastify) => {
+ if (!fastify.hasContentTypeParser("application/x-www-form-urlencoded")) {
+ fastify.register(formbody)
+ }
+ fastify.route({
+ method: ["GET", "POST"],
+ url: "/*",
+ handler: async (request, reply) => {
+ config.basePath = getBasePath(request)
+ const response = await Auth(toWebRequest(request), config)
+ return toFastifyReply(response, reply)
+ },
+ })
+ }
+}
+
+export type GetSessionResult = Promise
+
+export async function getSession(
+ req: FastifyRequest,
+ config: FastifyAuthConfig
+): GetSessionResult {
+ setEnvDefaults(process.env, config)
+ const url = createActionURL(
+ "session",
+ req.protocol,
+ // @ts-expect-error headers type is not compatible
+ new Headers(req.headers),
+ process.env,
+ config
+ )
+
+ const response = await Auth(
+ new Request(url, { headers: { cookie: req.headers.cookie ?? "" } }),
+ config
+ )
+
+ const { status = 200 } = response
+
+ const data = await response.json()
+
+ if (!data || !Object.keys(data).length) return null
+ if (status === 200) return data
+ throw new Error(data.message)
+}
+
+function getBasePath(req: FastifyRequest) {
+ return req.routeOptions.config.url.split("/*")[0]
+}
diff --git a/packages/frameworks-fastify/src/lib/http-api-adapters.ts b/packages/frameworks-fastify/src/lib/http-api-adapters.ts
new file mode 100644
index 0000000000..18380bdeb2
--- /dev/null
+++ b/packages/frameworks-fastify/src/lib/http-api-adapters.ts
@@ -0,0 +1,98 @@
+import type { FastifyRequest, FastifyReply } from "fastify"
+
+/**
+ * Encodes an object as url-encoded string.
+ */
+export function encodeUrlEncoded(object: Record = {}) {
+ const params = new URLSearchParams()
+
+ for (const [key, value] of Object.entries(object)) {
+ if (Array.isArray(value)) {
+ value.forEach((v) => params.append(key, v))
+ } else {
+ params.append(key, value)
+ }
+ }
+
+ return params.toString()
+}
+
+/**
+ * Encodes an object as JSON
+ */
+function encodeJson(obj: Record) {
+ return JSON.stringify(obj)
+}
+
+/**
+ * Encodes an Fastify Request body based on the content type header.
+ */
+function encodeRequestBody(req: FastifyRequest): string | undefined {
+ const contentType = req.headers["content-type"]
+ if (typeof req.body === "object" && req.body !== null) {
+ if (contentType?.includes("application/x-www-form-urlencoded")) {
+ return encodeUrlEncoded(req.body)
+ }
+
+ if (contentType?.includes("application/json")) {
+ return encodeJson(req.body)
+ }
+ }
+
+ if (typeof req.body === "string") {
+ return req.body
+ }
+
+ return undefined
+}
+
+/**
+ * Adapts an Fastify Request to a Web Request, returning the Web Request.
+ */
+export function toWebRequest(req: FastifyRequest) {
+ const url = req.protocol + "://" + req.host + req.originalUrl
+
+ const headers = new Headers()
+
+ Object.entries(req.headers).forEach(([key, value]) => {
+ if (Array.isArray(value)) {
+ value.forEach((v) => {
+ if (v) {
+ headers.append(key, v)
+ }
+ })
+ return
+ }
+
+ if (value) {
+ headers.append(key, value)
+ }
+ })
+
+ // GET and HEAD not allowed to receive body
+ const body = /GET|HEAD/.test(req.method) ? undefined : encodeRequestBody(req)
+
+ const request = new Request(url, {
+ method: req.method,
+ headers,
+ body,
+ })
+
+ return request
+}
+
+/**
+ * Adapts a Web Response to an Fastify Response, invoking appropriate
+ * Fastify response methods to handle the response.
+ */
+export async function toFastifyReply(response: Response, reply: FastifyReply) {
+ response.headers.forEach((value, key) => {
+ if (value) {
+ reply.header(key, value)
+ }
+ })
+
+ reply.status(response.status)
+
+ return await response.text()
+}
diff --git a/packages/frameworks-fastify/src/lib/index.ts b/packages/frameworks-fastify/src/lib/index.ts
new file mode 100644
index 0000000000..b7f64b862b
--- /dev/null
+++ b/packages/frameworks-fastify/src/lib/index.ts
@@ -0,0 +1 @@
+export * from "./http-api-adapters.js"
diff --git a/packages/frameworks-fastify/tests/http-api-adapters/request.test.ts b/packages/frameworks-fastify/tests/http-api-adapters/request.test.ts
new file mode 100644
index 0000000000..6e21d6b8a0
--- /dev/null
+++ b/packages/frameworks-fastify/tests/http-api-adapters/request.test.ts
@@ -0,0 +1,143 @@
+import { describe, beforeEach, it, expect } from "vitest"
+import Fastify from "fastify"
+import type { FastifyRequest } from "fastify"
+import { encodeUrlEncoded, toWebRequest } from "../../src/lib"
+import formbodyParser from "@fastify/formbody"
+
+function expectMatchingRequestHeaders(req: FastifyRequest, request: Request) {
+ for (let headerName in req.headers) {
+ expect(request.headers.get(headerName)).toEqual(req.headers[headerName])
+ }
+}
+
+async function expectMatchingJsonRequestBody(
+ req: FastifyRequest,
+ request: Request
+) {
+ const body = await request.json()
+ expect(body).toEqual(req.body)
+}
+
+async function expectMatchingUrlEncodedRequestBody(
+ req: FastifyRequest,
+ request: Request
+) {
+ const body = await request.text()
+ expect(typeof req.body).toEqual("object")
+ expect(req.body).not.toBeNull()
+ if (typeof req.body === "object" && req.body !== null) {
+ expect(body).toEqual(encodeUrlEncoded(req.body))
+ } else {
+ throw new Error("req.body is not an object or is null")
+ }
+}
+
+describe("toWebRequest", () => {
+ let fastify: ReturnType
+
+ beforeEach(() => {
+ fastify = Fastify()
+ })
+
+ it("adapts request headers", async () => {
+ let expectations: Function = () => {}
+
+ fastify.post("/", async (req, reply) => {
+ const request = toWebRequest(req)
+
+ expectations = async () => {
+ expectMatchingRequestHeaders(req, request)
+ return true
+ }
+
+ return "OK"
+ })
+
+ await fastify.ready()
+
+ const res = await fastify.inject({
+ method: "POST",
+ url: "/",
+ headers: {
+ "X-Test-Header": "foo",
+ "Content-Type": "application/json",
+ },
+ payload: {},
+ })
+
+ expect(res.statusCode).toEqual(200)
+
+ const expectationResult = await expectations()
+ expect(expectationResult).toEqual(true)
+ })
+
+ it("adapts request with json encoded body", async () => {
+ let expectations: Function = () => {}
+
+ fastify.post("/", async (req, reply) => {
+ const request = toWebRequest(req)
+
+ expectations = async () => {
+ await expectMatchingJsonRequestBody(req, request)
+ return true
+ }
+
+ return "OK"
+ })
+
+ await fastify.ready()
+
+ const data = {
+ name: "Rexford",
+ }
+
+ await fastify.inject({
+ method: "POST",
+ url: "/",
+ headers: {
+ "Content-Type": "application/json",
+ },
+ payload: data,
+ })
+
+ const expectationResult = await expectations()
+ expect(expectationResult).toEqual(true)
+ })
+
+ it("adapts request with url-encoded body", async () => {
+ let expectations: Function = () => {}
+
+ fastify.register(formbodyParser)
+ fastify.post("/", async (req, reply) => {
+ const request = toWebRequest(req)
+
+ expectations = async () => {
+ await expectMatchingUrlEncodedRequestBody(req, request)
+ return true
+ }
+
+ return "OK"
+ })
+
+ await fastify.ready()
+
+ const data = {
+ name: "Rexford",
+ nums: [1, 2, 3],
+ }
+
+ const res = await fastify.inject({
+ method: "POST",
+ url: "/",
+ headers: {
+ "Content-Type": "application/x-www-form-urlencoded",
+ },
+ payload: encodeUrlEncoded(data),
+ })
+
+ expect(res.statusCode).toEqual(200)
+
+ const expectationResult = await expectations()
+ expect(expectationResult).toEqual(true)
+ })
+})
diff --git a/packages/frameworks-fastify/tests/http-api-adapters/response.test.ts b/packages/frameworks-fastify/tests/http-api-adapters/response.test.ts
new file mode 100644
index 0000000000..c962fb8278
--- /dev/null
+++ b/packages/frameworks-fastify/tests/http-api-adapters/response.test.ts
@@ -0,0 +1,51 @@
+import { describe, beforeEach, it, expect } from "vitest"
+import Fastify from "fastify"
+import type { LightMyRequestResponse } from "fastify"
+import { toFastifyReply } from "../../src/lib"
+
+function expectMatchingResponseHeaders(
+ response: Response,
+ res: LightMyRequestResponse
+) {
+ for (let [headerName] of response.headers) {
+ const resValue = res.headers[headerName.toLowerCase()] as string
+ expect(response.headers.get(headerName)).toEqual(
+ resValue.split("; charset=utf-8")[0]
+ )
+ }
+}
+
+describe("toWebResponse", () => {
+ let fastify: ReturnType
+
+ beforeEach(() => {
+ fastify = Fastify()
+ })
+
+ it("adapts response", async () => {
+ let webResponse: Response = new Response()
+
+ fastify.post("/", async (req, reply) => {
+ const headers = new Headers()
+ headers.append("X-Test-Header", "foo")
+ headers.append("Content-Type", "application/json")
+
+ webResponse = new Response(JSON.stringify({ name: "Rexford" }), {
+ headers: headers,
+ status: 200,
+ })
+ return toFastifyReply(webResponse, reply)
+ })
+
+ await fastify.ready()
+
+ const res = await fastify.inject({
+ method: "POST",
+ url: "/",
+ })
+
+ expect(res.statusCode).toEqual(200)
+ expectMatchingResponseHeaders(webResponse, res)
+ expect(res.body).toEqual(JSON.stringify({ name: "Rexford" }))
+ })
+})
diff --git a/packages/frameworks-fastify/tests/login.test.ts b/packages/frameworks-fastify/tests/login.test.ts
new file mode 100644
index 0000000000..d7394ba270
--- /dev/null
+++ b/packages/frameworks-fastify/tests/login.test.ts
@@ -0,0 +1,130 @@
+import { describe, beforeEach, it, expect } from "vitest"
+import Fastify, { LightMyRequestResponse } from "fastify"
+import formbodyParser from "@fastify/formbody"
+import { FastifyAuth, getSession } from "../src/index.js"
+
+import CredentialsProvider from "@auth/core/providers/credentials"
+import type { AuthConfig } from "@auth/core"
+
+export const authConfig = {
+ secret: "secret",
+ providers: [
+ CredentialsProvider({
+ credentials: { username: { label: "Username" } },
+ async authorize(credentials) {
+ if (typeof credentials?.username === "string") {
+ const { username: name } = credentials
+ return { name: name, email: name.replace(" ", "") + "@example.com" }
+ }
+ return null
+ },
+ }),
+ ],
+} satisfies AuthConfig
+
+const extractCookieValue = (
+ cookies: LightMyRequestResponse["cookies"],
+ name: string
+) => {
+ const cookie = cookies.find(({ name: _name }) => _name === name)
+ return cookie?.value
+}
+
+describe("Integration test with login and getSession", () => {
+ let fastify: ReturnType
+
+ beforeEach(() => {
+ fastify = Fastify()
+ })
+
+ it("Should return the session with username after logging in", async () => {
+ let expectations: Function = () => {}
+
+ fastify.register(FastifyAuth(authConfig), { prefix: "/api/auth" })
+
+ fastify.post("/test", async (request, reply) => {
+ const session = await getSession(request, authConfig)
+
+ expectations = async () => {
+ expect(session?.user?.name).toEqual("johnsmith")
+ return true
+ }
+
+ return "OK"
+ })
+
+ await fastify.ready()
+
+ // Get signin page
+ const response = await fastify.inject({
+ method: "GET",
+ url: "/api/auth/signin",
+ headers: {
+ Accept: "application/json",
+ },
+ })
+
+ // Parse cookies for csrf token and callback url
+ const csrfTokenCookie =
+ extractCookieValue(response.cookies, "authjs.csrf-token") ?? ""
+ const callbackCookie =
+ extractCookieValue(response.cookies, "authjs.callback-url") ?? ""
+ const csrfFromCookie = csrfTokenCookie?.split("|")[0] ?? ""
+
+ // Get csrf token. We could just strip the csrf cookie but this tests the csrf endpoint as well.
+ const responseCsrf = await fastify.inject({
+ method: "GET",
+ url: "/api/auth/csrf",
+ headers: { Accept: "application/json" },
+ cookies: { "authjs.csrf-token": csrfTokenCookie },
+ })
+ const csrfTokenValue = JSON.parse(responseCsrf.body).csrfToken
+
+ // Check that csrf tokens are the same
+ expect(csrfTokenValue).toEqual(csrfFromCookie)
+
+ // Sign in
+ const responseCredentials = await fastify.inject({
+ method: "POST",
+ url: "/api/auth/callback/credentials",
+ cookies: {
+ "authjs.csrf-token": csrfTokenCookie,
+ "authjs.callback-url": callbackCookie,
+ },
+ payload: {
+ csrfToken: csrfTokenValue,
+ username: "johnsmith",
+ password: "ABC123",
+ },
+ })
+
+ // Parse cookie for session token
+ const sessionTokenCookie =
+ extractCookieValue(responseCredentials.cookies, "authjs.session-token") ??
+ ""
+
+ // Call test route
+ const res = await fastify.inject({
+ method: "POST",
+ url: "/test",
+ headers: {
+ Accept: "application/json",
+ },
+ cookies: {
+ "authjs.csrf-token": csrfTokenCookie,
+ "authjs.callback-url": callbackCookie,
+ "authjs.session-token": sessionTokenCookie,
+ },
+ })
+
+ expect(res.statusCode).toEqual(200)
+ const expectationResult = await expectations()
+ expect(expectationResult).toEqual(true)
+ })
+
+ it("Should not throw when form body parser already registered", async () => {
+ fastify.register(formbodyParser)
+ fastify.register(FastifyAuth(authConfig), { prefix: "/api/auth" })
+ await fastify.ready()
+ })
+})
diff --git a/packages/frameworks-fastify/tests/session.test.ts b/packages/frameworks-fastify/tests/session.test.ts
new file mode 100644
index 0000000000..b8a51799c0
--- /dev/null
+++ b/packages/frameworks-fastify/tests/session.test.ts
@@ -0,0 +1,66 @@
+import { vi, describe, beforeEach, it, expect } from "vitest"
+
+import Fastify from "fastify"
+
+const sessionJson = {
+ user: {
+ name: "John Doe",
+ email: "test@example.com",
+ image: "",
+ id: "1234",
+ },
+ expires: "",
+}
+
+vi.mock("@auth/core", async (importOriginal) => {
+ const mod = await importOriginal()
+ return {
+ ...mod,
+ Auth: vi.fn((request, config) => {
+ return new Response(JSON.stringify(sessionJson), {
+ status: 200,
+ headers: { "Content-Type": "application/json" },
+ })
+ }),
+ }
+})
+
+// dynamic import to avoid loading Auth before hoisting
+const { getSession } = await import("../src/index.js")
+
+describe("getSession", () => {
+ let fastify: ReturnType
+
+ beforeEach(() => {
+ fastify = Fastify()
+ })
+
+ it("Should return the mocked session from the Auth response", async () => {
+ let expectations: Function = () => {}
+
+ fastify.get("/", async (request, reply) => {
+ const session = await getSession(request, {
+ providers: [],
+ secret: "secret",
+ })
+
+ expectations = async () => {
+ expect(session).toEqual(sessionJson)
+ return true
+ }
+
+ return "OK"
+ })
+
+ await fastify.ready()
+
+ const res = await fastify.inject({
+ method: "GET",
+ url: "/",
+ })
+
+ expect(res.statusCode).toEqual(200)
+ const expectationResult = await expectations()
+ expect(expectationResult).toEqual(true)
+ })
+})
diff --git a/packages/frameworks-fastify/tsconfig.json b/packages/frameworks-fastify/tsconfig.json
new file mode 100644
index 0000000000..887554cc03
--- /dev/null
+++ b/packages/frameworks-fastify/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "utils/tsconfig.json",
+ "compilerOptions": {
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "outDir": ".",
+ "rootDir": "src"
+ },
+ "include": ["src/**/*"],
+ "exclude": ["*.js", "*.d.ts", "lib"]
+}
diff --git a/packages/frameworks-fastify/typedoc.config.cjs b/packages/frameworks-fastify/typedoc.config.cjs
new file mode 100644
index 0000000000..603345b7b6
--- /dev/null
+++ b/packages/frameworks-fastify/typedoc.config.cjs
@@ -0,0 +1,14 @@
+// @ts-check
+
+/**
+ * @type {import('typedoc').TypeDocOptions & import('typedoc-plugin-markdown').MarkdownTheme}
+ */
+module.exports = {
+ entryPoints: ["src/index.ts", "src/adapters.ts", "src/lib/index.ts", "src/lib/http-api-adapters.ts"],
+ entryPointStrategy: "expand",
+ tsconfig: "./tsconfig.json",
+ entryModule: "@auth/fastify",
+ entryFileName: "../fastify.mdx",
+ includeVersion: true,
+ readme: 'none',
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 19d4272f40..574974430b 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -33,7 +33,7 @@ importers:
version: 1.40.0
'@types/node':
specifier: ^20.8.10
- version: 20.11.7
+ version: 20.12.7
'@typescript-eslint/eslint-plugin':
specifier: v6.19.1
version: 6.19.1(@typescript-eslint/parser@6.19.1(eslint@9.9.1(jiti@1.21.0))(typescript@5.3.3))(eslint@9.9.1(jiti@1.21.0))(typescript@5.3.3)
@@ -42,7 +42,7 @@ importers:
version: 6.19.1(eslint@9.9.1(jiti@1.21.0))(typescript@5.3.3)
'@vitest/coverage-v8':
specifier: 1.2.1
- version: 1.2.1(vitest@1.2.2(@types/node@20.11.7)(@vitest/ui@1.2.2)(sass@1.70.0)(terser@5.27.0))
+ version: 1.2.1(vitest@1.2.2(@types/node@20.12.7)(@vitest/ui@1.2.2)(sass@1.70.0)(terser@5.27.0))
'@vitest/ui':
specifier: ^1.2.2
version: 1.2.2(vitest@1.2.2)
@@ -66,7 +66,7 @@ importers:
version: 7.33.2(eslint@9.9.1(jiti@1.21.0))
eslint-plugin-svelte:
specifier: ^2.38.0
- version: 2.38.0(eslint@9.9.1(jiti@1.21.0))(svelte@4.2.9)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3))
+ version: 2.38.0(eslint@9.9.1(jiti@1.21.0))(svelte@4.2.9)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3))
fake-smtp-server:
specifier: ^0.8.0
version: 0.8.0
@@ -102,10 +102,10 @@ importers:
version: link:packages/utils
vite:
specifier: ^5.0.13
- version: 5.0.13(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)
+ version: 5.0.13(@types/node@20.12.7)(sass@1.70.0)(terser@5.27.0)
vitest:
specifier: 1.2.2
- version: 1.2.2(@types/node@20.11.7)(@vitest/ui@1.2.2)(sass@1.70.0)(terser@5.27.0)
+ version: 1.2.2(@types/node@20.12.7)(@vitest/ui@1.2.2)(sass@1.70.0)(terser@5.27.0)
apps/dev/express:
dependencies:
@@ -141,6 +141,43 @@ importers:
specifier: 5.4.5
version: 5.4.5
+ apps/dev/fastify:
+ dependencies:
+ '@auth/fastify':
+ specifier: workspace:*
+ version: link:../../../packages/frameworks-fastify
+ '@fastify/static':
+ specifier: ^8.0.1
+ version: 8.0.1
+ '@fastify/view':
+ specifier: ^10.0.1
+ version: 10.0.1
+ fastify:
+ specifier: ^5.0.0
+ version: 5.0.0
+ pug:
+ specifier: ^3.0.2
+ version: 3.0.2
+ tailwindcss:
+ specifier: ^3.4.3
+ version: 3.4.3(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5))
+ devDependencies:
+ '@prettier/plugin-pug':
+ specifier: ^3.0.0
+ version: 3.0.0(prettier@3.3.3)
+ '@types/morgan':
+ specifier: ^1.9.9
+ version: 1.9.9
+ '@types/pug':
+ specifier: ^2.0.10
+ version: 2.0.10
+ tsx:
+ specifier: ^4.7.3
+ version: 4.7.3
+ typescript:
+ specifier: 5.4.5
+ version: 5.4.5
+
apps/dev/nextjs:
dependencies:
next:
@@ -158,7 +195,7 @@ importers:
devDependencies:
'@types/react':
specifier: ^18.2.23
- version: 18.2.48
+ version: 18.2.78
'@types/react-dom':
specifier: ^18.2.8
version: 18.2.18
@@ -234,7 +271,7 @@ importers:
version: 4.2.9
svelte-check:
specifier: 2.10.2
- version: 2.10.2(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9)
+ version: 2.10.2(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9)
typescript:
specifier: 5.2.2
version: 5.2.2
@@ -617,10 +654,10 @@ importers:
version: 8.11.3
typeorm:
specifier: 0.3.17
- version: 0.3.17(ioredis@5.4.1)(mssql@7.3.5(encoding@0.1.13))(mysql2@3.9.7)(pg@8.11.3)(redis@4.6.12)(sqlite3@5.1.6(encoding@0.1.13))(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3))
+ version: 0.3.17(ioredis@5.4.1)(mssql@7.3.5(encoding@0.1.13))(mysql2@3.9.7)(pg@8.11.3)(redis@4.6.12)(sqlite3@5.1.6(encoding@0.1.13))(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3))
typeorm-naming-strategies:
specifier: ^4.1.0
- version: 4.1.0(typeorm@0.3.17(ioredis@5.4.1)(mssql@7.3.5(encoding@0.1.13))(mysql2@3.9.7)(pg@8.11.3)(redis@4.6.12)(sqlite3@5.1.6(encoding@0.1.13))(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)))
+ version: 4.1.0(typeorm@0.3.17(ioredis@5.4.1)(mssql@7.3.5(encoding@0.1.13))(mysql2@3.9.7)(pg@8.11.3)(redis@4.6.12)(sqlite3@5.1.6(encoding@0.1.13))(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)))
packages/adapter-unstorage:
dependencies:
@@ -741,6 +778,19 @@ importers:
specifier: ^6.3.3
version: 6.3.4
+ packages/frameworks-fastify:
+ dependencies:
+ '@auth/core':
+ specifier: workspace:*
+ version: link:../core
+ '@fastify/formbody':
+ specifier: ^8.0.1
+ version: 8.0.1
+ devDependencies:
+ fastify:
+ specifier: ^5.0.0
+ version: 5.0.0
+
packages/frameworks-qwik:
dependencies:
'@auth/core':
@@ -826,7 +876,7 @@ importers:
version: 4.2.9
svelte-check:
specifier: ^3.4.3
- version: 3.6.3(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9)
+ version: 3.6.3(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9)
tslib:
specifier: ^2.4.1
version: 2.6.2
@@ -1399,14 +1449,12 @@ packages:
'@babel/plugin-proposal-class-properties@7.18.6':
resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==}
engines: {node: '>=6.9.0'}
- deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead.
peerDependencies:
'@babel/core': ^7.0.0-0
'@babel/plugin-proposal-object-rest-spread@7.20.7':
resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==}
engines: {node: '>=6.9.0'}
- deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.
peerDependencies:
'@babel/core': ^7.0.0-0
@@ -2740,6 +2788,12 @@ packages:
resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
+ '@fastify/accept-negotiator@2.0.0':
+ resolution: {integrity: sha512-/Sce/kBzuTxIq5tJh85nVNOq9wKD8s+viIgX0fFMDBdw95gnpf53qmF1oBgJym3cPFliWUuSloVg/1w/rH0FcQ==}
+
+ '@fastify/ajv-compiler@4.0.1':
+ resolution: {integrity: sha512-DxrBdgsjNLP0YM6W5Hd6/Fmj43S8zMKiFJYgi+Ri3htTGAowPVG/tG1wpnWLMjufEnehRivUCKZ1pLDIoZdTuw==}
+
'@fastify/busboy@1.2.1':
resolution: {integrity: sha512-7PQA7EH43S0CxcOa9OeAnaeA0oQ+e/DHNPZwSQM9CQHW76jle5+OvLdibRp/Aafs9KXbLhxyjOTkRjWUbQEd3Q==}
engines: {node: '>=14'}
@@ -2748,6 +2802,27 @@ packages:
resolution: {integrity: sha512-+KpH+QxZU7O4675t3mnkQKcZZg56u+K/Ct2K+N2AZYNVK8kyeo/bI18tI8aPm3tvNNRyTWfj6s5tnGNlcbQRsA==}
engines: {node: '>=14'}
+ '@fastify/error@4.0.0':
+ resolution: {integrity: sha512-OO/SA8As24JtT1usTUTKgGH7uLvhfwZPwlptRi2Dp5P4KKmJI3gvsZ8MIHnNwDs4sLf/aai5LzTyl66xr7qMxA==}
+
+ '@fastify/fast-json-stringify-compiler@5.0.1':
+ resolution: {integrity: sha512-f2d3JExJgFE3UbdFcpPwqNUEoHWmt8pAKf8f+9YuLESdefA0WgqxeT6DrGL4Yrf/9ihXNSKOqpjEmurV405meA==}
+
+ '@fastify/formbody@8.0.1':
+ resolution: {integrity: sha512-LPrcadSIK8TrQk510Zdj56fnw7cyHq0/PW0YHGGM8ycGL4X7XAex+FKcwpzB4i5lF9eykc71a4EtcO9AEoByqw==}
+
+ '@fastify/merge-json-schemas@0.1.1':
+ resolution: {integrity: sha512-fERDVz7topgNjtXsJTTW1JKLy0rhuLRcquYqNR9rF7OcVpCa2OVW49ZPDIhaRRCaUuvVxI+N416xUoF76HNSXA==}
+
+ '@fastify/send@3.1.1':
+ resolution: {integrity: sha512-LdiV2mle/2tH8vh6GwGl0ubfUAgvY+9yF9oGI1iiwVyNUVOQamvw5n+OFu6iCNNoyuCY80FFURBn4TZCbTe8LA==}
+
+ '@fastify/static@8.0.1':
+ resolution: {integrity: sha512-7idyhbcgf14v4bjWzUeHEFvnVxvNJ1n5cyGPgFtwTZjnjUQ1wgC7a2FQai7OGKqCKywDEjzbPhAZRW+uEK1LMg==}
+
+ '@fastify/view@10.0.1':
+ resolution: {integrity: sha512-rXtBN0oVDmoRZAS7lelrCIahf+qFtlMOOas8VPdA7JvrJ9ChcF7e36pIUPU0Vbs3KmHxESUb7XatavUZEe/k5Q==}
+
'@firebase/app-check-interop-types@0.3.2':
resolution: {integrity: sha512-LMs47Vinv2HBMZi49C09dJxp0QT5LwDzFaVGf/+ITHe3BlIhUiLNttkATSXplc89A2lAaeTqjgqVkiRfUGyQiQ==}
@@ -3495,6 +3570,10 @@ packages:
cpu: [x64]
os: [win32]
+ '@lukeed/ms@2.0.2':
+ resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==}
+ engines: {node: '>=8'}
+
'@manypkg/find-root@1.1.0':
resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==}
@@ -4495,51 +4574,26 @@ packages:
cpu: [arm]
os: [android]
- '@rollup/rollup-android-arm-eabi@4.9.6':
- resolution: {integrity: sha512-MVNXSSYN6QXOulbHpLMKYi60ppyO13W9my1qogeiAqtjb2yR4LSmfU2+POvDkLzhjYLXz9Rf9+9a3zFHW1Lecg==}
- cpu: [arm]
- os: [android]
-
'@rollup/rollup-android-arm64@4.18.0':
resolution: {integrity: sha512-avCea0RAP03lTsDhEyfy+hpfr85KfyTctMADqHVhLAF3MlIkq83CP8UfAHUssgXTYd+6er6PaAhx/QGv4L1EiA==}
cpu: [arm64]
os: [android]
- '@rollup/rollup-android-arm64@4.9.6':
- resolution: {integrity: sha512-T14aNLpqJ5wzKNf5jEDpv5zgyIqcpn1MlwCrUXLrwoADr2RkWA0vOWP4XxbO9aiO3dvMCQICZdKeDrFl7UMClw==}
- cpu: [arm64]
- os: [android]
-
'@rollup/rollup-darwin-arm64@4.18.0':
resolution: {integrity: sha512-IWfdwU7KDSm07Ty0PuA/W2JYoZ4iTj3TUQjkVsO/6U+4I1jN5lcR71ZEvRh52sDOERdnNhhHU57UITXz5jC1/w==}
cpu: [arm64]
os: [darwin]
- '@rollup/rollup-darwin-arm64@4.9.6':
- resolution: {integrity: sha512-CqNNAyhRkTbo8VVZ5R85X73H3R5NX9ONnKbXuHisGWC0qRbTTxnF1U4V9NafzJbgGM0sHZpdO83pLPzq8uOZFw==}
- cpu: [arm64]
- os: [darwin]
-
'@rollup/rollup-darwin-x64@4.18.0':
resolution: {integrity: sha512-n2LMsUz7Ynu7DoQrSQkBf8iNrjOGyPLrdSg802vk6XT3FtsgX6JbE8IHRvposskFm9SNxzkLYGSq9QdpLYpRNA==}
cpu: [x64]
os: [darwin]
- '@rollup/rollup-darwin-x64@4.9.6':
- resolution: {integrity: sha512-zRDtdJuRvA1dc9Mp6BWYqAsU5oeLixdfUvkTHuiYOHwqYuQ4YgSmi6+/lPvSsqc/I0Omw3DdICx4Tfacdzmhog==}
- cpu: [x64]
- os: [darwin]
-
'@rollup/rollup-linux-arm-gnueabihf@4.18.0':
resolution: {integrity: sha512-C/zbRYRXFjWvz9Z4haRxcTdnkPt1BtCkz+7RtBSuNmKzMzp3ZxdM28Mpccn6pt28/UWUCTXa+b0Mx1k3g6NOMA==}
cpu: [arm]
os: [linux]
- '@rollup/rollup-linux-arm-gnueabihf@4.9.6':
- resolution: {integrity: sha512-oNk8YXDDnNyG4qlNb6is1ojTOGL/tRhbbKeE/YuccItzerEZT68Z9gHrY3ROh7axDc974+zYAPxK5SH0j/G+QQ==}
- cpu: [arm]
- os: [linux]
-
'@rollup/rollup-linux-arm-musleabihf@4.18.0':
resolution: {integrity: sha512-l3m9ewPgjQSXrUMHg93vt0hYCGnrMOcUpTz6FLtbwljo2HluS4zTXFy2571YQbisTnfTKPZ01u/ukJdQTLGh9A==}
cpu: [arm]
@@ -4550,21 +4604,11 @@ packages:
cpu: [arm64]
os: [linux]
- '@rollup/rollup-linux-arm64-gnu@4.9.6':
- resolution: {integrity: sha512-Z3O60yxPtuCYobrtzjo0wlmvDdx2qZfeAWTyfOjEDqd08kthDKexLpV97KfAeUXPosENKd8uyJMRDfFMxcYkDQ==}
- cpu: [arm64]
- os: [linux]
-
'@rollup/rollup-linux-arm64-musl@4.18.0':
resolution: {integrity: sha512-be6Yx37b24ZwxQ+wOQXXLZqpq4jTckJhtGlWGZs68TgdKXJgw54lUUoFYrg6Zs/kjzAQwEwYbp8JxZVzZLRepQ==}
cpu: [arm64]
os: [linux]
- '@rollup/rollup-linux-arm64-musl@4.9.6':
- resolution: {integrity: sha512-gpiG0qQJNdYEVad+1iAsGAbgAnZ8j07FapmnIAQgODKcOTjLEWM9sRb+MbQyVsYCnA0Im6M6QIq6ax7liws6eQ==}
- cpu: [arm64]
- os: [linux]
-
'@rollup/rollup-linux-powerpc64le-gnu@4.18.0':
resolution: {integrity: sha512-hNVMQK+qrA9Todu9+wqrXOHxFiD5YmdEi3paj6vP02Kx1hjd2LLYR2eaN7DsEshg09+9uzWi2W18MJDlG0cxJA==}
cpu: [ppc64]
@@ -4575,11 +4619,6 @@ packages:
cpu: [riscv64]
os: [linux]
- '@rollup/rollup-linux-riscv64-gnu@4.9.6':
- resolution: {integrity: sha512-+uCOcvVmFUYvVDr27aiyun9WgZk0tXe7ThuzoUTAukZJOwS5MrGbmSlNOhx1j80GdpqbOty05XqSl5w4dQvcOA==}
- cpu: [riscv64]
- os: [linux]
-
'@rollup/rollup-linux-s390x-gnu@4.18.0':
resolution: {integrity: sha512-0UyyRHyDN42QL+NbqevXIIUnKA47A+45WyasO+y2bGJ1mhQrfrtXUpTxCOrfxCR4esV3/RLYyucGVPiUsO8xjg==}
cpu: [s390x]
@@ -4590,51 +4629,26 @@ packages:
cpu: [x64]
os: [linux]
- '@rollup/rollup-linux-x64-gnu@4.9.6':
- resolution: {integrity: sha512-HUNqM32dGzfBKuaDUBqFB7tP6VMN74eLZ33Q9Y1TBqRDn+qDonkAUyKWwF9BR9unV7QUzffLnz9GrnKvMqC/fw==}
- cpu: [x64]
- os: [linux]
-
'@rollup/rollup-linux-x64-musl@4.18.0':
resolution: {integrity: sha512-LKaqQL9osY/ir2geuLVvRRs+utWUNilzdE90TpyoX0eNqPzWjRm14oMEE+YLve4k/NAqCdPkGYDaDF5Sw+xBfg==}
cpu: [x64]
os: [linux]
- '@rollup/rollup-linux-x64-musl@4.9.6':
- resolution: {integrity: sha512-ch7M+9Tr5R4FK40FHQk8VnML0Szi2KRujUgHXd/HjuH9ifH72GUmw6lStZBo3c3GB82vHa0ZoUfjfcM7JiiMrQ==}
- cpu: [x64]
- os: [linux]
-
'@rollup/rollup-win32-arm64-msvc@4.18.0':
resolution: {integrity: sha512-7J6TkZQFGo9qBKH0pk2cEVSRhJbL6MtfWxth7Y5YmZs57Pi+4x6c2dStAUvaQkHQLnEQv1jzBUW43GvZW8OFqA==}
cpu: [arm64]
os: [win32]
- '@rollup/rollup-win32-arm64-msvc@4.9.6':
- resolution: {integrity: sha512-VD6qnR99dhmTQ1mJhIzXsRcTBvTjbfbGGwKAHcu+52cVl15AC/kplkhxzW/uT0Xl62Y/meBKDZvoJSJN+vTeGA==}
- cpu: [arm64]
- os: [win32]
-
'@rollup/rollup-win32-ia32-msvc@4.18.0':
resolution: {integrity: sha512-Txjh+IxBPbkUB9+SXZMpv+b/vnTEtFyfWZgJ6iyCmt2tdx0OF5WhFowLmnh8ENGNpfUlUZkdI//4IEmhwPieNg==}
cpu: [ia32]
os: [win32]
- '@rollup/rollup-win32-ia32-msvc@4.9.6':
- resolution: {integrity: sha512-J9AFDq/xiRI58eR2NIDfyVmTYGyIZmRcvcAoJ48oDld/NTR8wyiPUu2X/v1navJ+N/FGg68LEbX3Ejd6l8B7MQ==}
- cpu: [ia32]
- os: [win32]
-
'@rollup/rollup-win32-x64-msvc@4.18.0':
resolution: {integrity: sha512-UOo5FdvOL0+eIVTgS4tIdbW+TtnBLWg1YBCcU2KWM7nuNwRz9bksDX1bekJJCpu25N1DVWaCwnT39dVQxzqS8g==}
cpu: [x64]
os: [win32]
- '@rollup/rollup-win32-x64-msvc@4.9.6':
- resolution: {integrity: sha512-jqzNLhNDvIZOrt69Ce4UjGRpXJBzhUBzawMwnaDAwyHriki3XollsewxWzOzz+4yOFDkuJHtTsZFwMxhYJWmLQ==}
- cpu: [x64]
- os: [win32]
-
'@rushstack/node-core-library@4.0.2':
resolution: {integrity: sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==}
peerDependencies:
@@ -5214,9 +5228,6 @@ packages:
'@types/node@18.11.10':
resolution: {integrity: sha512-juG3RWMBOqcOuXC643OAdSA525V44cVgGV6dUDuiFtss+8Fk5x1hI93Rsld43VeJVIeqlP9I7Fn9/qaVqoEAuQ==}
- '@types/node@20.11.7':
- resolution: {integrity: sha512-GPmeN1C3XAyV5uybAf4cMLWT9fDWcmQhZVtMFu7OR32WjrqGG+Wnk2V1d0bmtUyE/Zy1QJ9BxyiTih9z8Oks8A==}
-
'@types/node@20.12.7':
resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==}
@@ -5307,9 +5318,6 @@ packages:
'@types/react@18.0.37':
resolution: {integrity: sha512-4yaZZtkRN3ZIQD3KSEwkfcik8s0SWV+82dlJot1AbGYHCzJkWP3ENBY6wYeDRmKZ6HkrgoGAmR2HqdwYGp6OEw==}
- '@types/react@18.2.48':
- resolution: {integrity: sha512-qboRCl6Ie70DQQG9hhNREz81jqC1cs9EVNcjQ1AU+jH6NFfSAhVVbrrY/+nSF+Bsk4AOwm9Qa61InvMCyV+H3w==}
-
'@types/react@18.2.78':
resolution: {integrity: sha512-qOwdPnnitQY4xKlKayt42q5W5UQrSHjgoXNVEtxeqdITJ99k4VXJOP3vt8Rkm9HmgJpH50UNU+rlqfkfWOqp0A==}
@@ -6049,6 +6057,9 @@ packages:
resolution: {integrity: sha512-TU5nlYgta8YrBMNpc9FwQzRbiXsj49gsALsXadbGHt9CROPzX5fB0rWDR5mtdpOOKa5XqRFpbj1QroPAoPzVjQ==}
engines: {node: '>=6'}
+ abstract-logging@2.0.1:
+ resolution: {integrity: sha512-2BjRTZxTPvheOvGbBslFSYOUkr+SjPtOnrLP33f+VIWLzezQpZcqVg7ja3L4dBXmzzgwT+a029jRx5PCi3JuiA==}
+
accepts@1.3.8:
resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==}
engines: {node: '>= 0.6'}
@@ -6106,9 +6117,20 @@ packages:
resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==}
engines: {node: '>=8'}
+ ajv-formats@3.0.1:
+ resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==}
+ peerDependencies:
+ ajv: ^8.0.0
+ peerDependenciesMeta:
+ ajv:
+ optional: true
+
ajv@6.12.6:
resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==}
+ ajv@8.13.0:
+ resolution: {integrity: sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA==}
+
algoliasearch-helper@3.18.0:
resolution: {integrity: sha512-ZXvA8r6VG46V343jnIE7Tei8Xr0/9N8YhD27joC0BKxeogQyvNu7O37i510wA7FnrDjoa/tFhK90WUaBlkaqnw==}
peerDependencies:
@@ -6297,6 +6319,10 @@ packages:
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
engines: {node: '>= 4.0.0'}
+ atomic-sleep@1.0.0:
+ resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==}
+ engines: {node: '>=8.0.0'}
+
auto-bind@4.0.0:
resolution: {integrity: sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==}
engines: {node: '>=8'}
@@ -6326,6 +6352,9 @@ packages:
resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==}
engines: {node: '>= 0.4'}
+ avvio@9.0.0:
+ resolution: {integrity: sha512-UbYrOXgE/I+knFG+3kJr9AgC7uNo8DG+FGGODpH9Bj1O1kL/QDjBXnTem9leD3VdQKtaHjV3O85DQ7hHh4IIHw==}
+
axios@0.21.4:
resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==}
@@ -7969,15 +7998,28 @@ packages:
fast-json-stable-stringify@2.1.0:
resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==}
+ fast-json-stringify@6.0.0:
+ resolution: {integrity: sha512-FGMKZwniMTgZh7zQp9b6XnBVxUmKVahQLQeRQHqwYmPDqDhcEKZ3BaQsxelFFI5PY7nN71OEeiL47/zUWcYe1A==}
+
fast-levenshtein@2.0.6:
resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==}
fast-querystring@1.1.2:
resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==}
+ fast-redact@3.5.0:
+ resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==}
+ engines: {node: '>=6'}
+
fast-safe-stringify@2.1.1:
resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==}
+ fast-uri@2.3.0:
+ resolution: {integrity: sha512-eel5UKGn369gGEWOqBShmFJWfq/xSJvsgDzgLYC845GneayWvXBf0lJCBn5qTABfewy1ZDPoaR5OZCP+kssfuw==}
+
+ fast-uri@3.0.2:
+ resolution: {integrity: sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==}
+
fast-url-parser@1.1.3:
resolution: {integrity: sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==}
@@ -7989,9 +8031,18 @@ packages:
resolution: {integrity: sha512-coV/D1MhrShMvU6D0I+VAK3umz6hUaxxhL0yp/9RjfiYUfAv14rDhGQL+PLForhMdr0wq3PiV07WtkkNjJjNHg==}
hasBin: true
+ fastify-plugin@5.0.1:
+ resolution: {integrity: sha512-HCxs+YnRaWzCl+cWRYFnHmeRFyR5GVnJTAaCJQiYzQSDwK9MgJdyAsuL3nh0EWRCYMgQ5MeziymvmAhUHYHDUQ==}
+
+ fastify@5.0.0:
+ resolution: {integrity: sha512-Qe4dU+zGOzg7vXjw4EvcuyIbNnMwTmcuOhlOrOJsgwzvjEZmsM/IeHulgJk+r46STjdJS/ZJbxO8N70ODXDMEQ==}
+
fastq@1.16.0:
resolution: {integrity: sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==}
+ fastq@1.17.1:
+ resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
+
fault@2.0.1:
resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==}
@@ -8067,6 +8118,10 @@ packages:
resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==}
engines: {node: '>= 0.8'}
+ find-my-way@9.1.0:
+ resolution: {integrity: sha512-Y5jIsuYR4BwWDYYQ2A/RWWE6gD8a0FMgtU+HOq1WKku+Cwdz8M1v8wcAmRXXM1/iqtoqg06v+LjAxMYbCjViMw==}
+ engines: {node: '>=14'}
+
find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
@@ -8332,6 +8387,11 @@ packages:
engines: {node: '>=16 || 14 >=14.17'}
hasBin: true
+ glob@11.0.0:
+ resolution: {integrity: sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==}
+ engines: {node: 20 || >=22}
+ hasBin: true
+
glob@7.2.3:
resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
deprecated: Glob versions prior to v9 are no longer supported
@@ -9082,6 +9142,10 @@ packages:
resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
engines: {node: '>=14'}
+ jackspeak@4.0.2:
+ resolution: {integrity: sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==}
+ engines: {node: 20 || >=22}
+
jake@10.8.7:
resolution: {integrity: sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==}
engines: {node: '>=10'}
@@ -9151,9 +9215,15 @@ packages:
json-parse-even-better-errors@2.3.1:
resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
+ json-schema-ref-resolver@1.0.1:
+ resolution: {integrity: sha512-EJAj1pgHc1hxF6vo2Z3s69fMjO1INq6eGHXZ8Z6wCQeldCuwxGK9Sxf4/cScGn3FZubCVUehfWtcDM/PLteCQw==}
+
json-schema-traverse@0.4.1:
resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==}
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
json-stable-stringify-without-jsonify@1.0.1:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
@@ -9413,6 +9483,9 @@ packages:
resolution: {integrity: sha512-lvhKr7WV3NLWRbXkjn/MeKqXOAqWKU0PX9QYrvDh7fneukapj+iUQ4qgJASrQyxcCrEsClXCQiiK5W6OoYPAlA==}
os: [darwin, linux, win32]
+ light-my-request@6.0.0:
+ resolution: {integrity: sha512-kFkFXrmKCL0EEeOmJybMH5amWFd+AFvlvMlvFTRxCUwbhfapZqDmeLMPoWihntnYY6JpoQDE9k+vOzObF1fDqg==}
+
lil-fp@1.4.5:
resolution: {integrity: sha512-RrMQ2dB7SDXriFPZMMHEmroaSP6lFw3QEV7FOfSkf19kvJnDzHqKMc2P9HOf5uE8fOp5YxodSrq7XxWjdeC2sw==}
@@ -9571,6 +9644,10 @@ packages:
resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==}
engines: {node: 14 || >=16.14}
+ lru-cache@11.0.1:
+ resolution: {integrity: sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ==}
+ engines: {node: 20 || >=22}
+
lru-cache@4.0.2:
resolution: {integrity: sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==}
@@ -10008,6 +10085,10 @@ packages:
resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
engines: {node: '>=4'}
+ minimatch@10.0.1:
+ resolution: {integrity: sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==}
+ engines: {node: 20 || >=22}
+
minimatch@3.0.8:
resolution: {integrity: sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==}
@@ -10077,6 +10158,10 @@ packages:
resolution: {integrity: sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==}
engines: {node: '>=16 || 14 >=14.17'}
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
minizlib@2.1.2:
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
engines: {node: '>= 8'}
@@ -10550,6 +10635,10 @@ packages:
ohash@1.1.3:
resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==}
+ on-exit-leak-free@2.1.2:
+ resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==}
+ engines: {node: '>=14.0.0'}
+
on-finished@2.3.0:
resolution: {integrity: sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==}
engines: {node: '>= 0.8'}
@@ -10643,6 +10732,9 @@ packages:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
+ package-json-from-dist@1.0.1:
+ resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
+
package-manager-detector@0.2.0:
resolution: {integrity: sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==}
@@ -10752,6 +10844,10 @@ packages:
resolution: {integrity: sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==}
engines: {node: '>=16 || 14 >=14.17'}
+ path-scurry@2.0.0:
+ resolution: {integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==}
+ engines: {node: 20 || >=22}
+
path-to-regexp@0.1.7:
resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==}
@@ -10837,6 +10933,16 @@ packages:
resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
engines: {node: '>=6'}
+ pino-abstract-transport@1.2.0:
+ resolution: {integrity: sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==}
+
+ pino-std-serializers@6.2.2:
+ resolution: {integrity: sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==}
+
+ pino@9.0.0:
+ resolution: {integrity: sha512-uI1ThkzTShNSwvsUM6b4ND8ANzWURk9zTELMztFkmnCQeR/4wkomJ+echHee5GMWGovoSfjwdeu80DsFIt7mbA==}
+ hasBin: true
+
pirates@4.0.6:
resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
engines: {node: '>= 6'}
@@ -10990,10 +11096,6 @@ packages:
resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==}
engines: {node: ^10 || ^12 || >=14}
- postcss@8.4.33:
- resolution: {integrity: sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==}
- engines: {node: ^10 || ^12 || >=14}
-
postcss@8.4.38:
resolution: {integrity: sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==}
engines: {node: ^10 || ^12 || >=14}
@@ -11219,6 +11321,16 @@ packages:
process-nextick-args@2.0.1:
resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
+ process-warning@3.0.0:
+ resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==}
+
+ process-warning@4.0.0:
+ resolution: {integrity: sha512-/MyYDxttz7DfGMMHiysAsFE4qF+pQYAA8ziO/3NcRVrQ5fSk+Mns4QZA/oRPFzvcqNoVJXQNWNAsdwBXLUkQKw==}
+
+ process@0.11.10:
+ resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==}
+ engines: {node: '>= 0.6.0'}
+
promise-inflight@1.0.1:
resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==}
peerDependencies:
@@ -11339,6 +11451,9 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ quick-format-unescaped@4.0.4:
+ resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
+
quick-lru@4.0.1:
resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==}
engines: {node: '>=8'}
@@ -11502,6 +11617,10 @@ packages:
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
engines: {node: '>= 6'}
+ readable-stream@4.5.2:
+ resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==}
+ engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
+
readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
@@ -11509,6 +11628,10 @@ packages:
reading-time@1.5.0:
resolution: {integrity: sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==}
+ real-require@0.2.0:
+ resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==}
+ engines: {node: '>= 12.13.0'}
+
rechoir@0.8.0:
resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==}
engines: {node: '>= 10.13.0'}
@@ -11645,6 +11768,10 @@ packages:
resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
engines: {node: '>=0.10.0'}
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
require-main-filename@2.0.0:
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
@@ -11681,6 +11808,10 @@ packages:
resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==}
engines: {node: '>=8'}
+ ret@0.5.0:
+ resolution: {integrity: sha512-I1XxrZSQ+oErkRR4jYbAyEEu2I0avBvvMM5JN+6EBprOGRCs63ENqZ3vjavq8fBw2+62G5LF5XelKwuJpcvcxw==}
+ engines: {node: '>=10'}
+
retext-latin@4.0.0:
resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==}
@@ -11759,11 +11890,6 @@ packages:
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
- rollup@4.9.6:
- resolution: {integrity: sha512-05lzkCS2uASX0CiLFybYfVkwNbKZG5NFQ6Go0VWyogFTXXbR039UVsegViTntkk4OglHBdF54ccApXRRuXRbsg==}
- engines: {node: '>=18.0.0', npm: '>=8.0.0'}
- hasBin: true
-
roughjs@4.6.6:
resolution: {integrity: sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==}
@@ -11810,6 +11936,13 @@ packages:
resolution: {integrity: sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==}
engines: {node: '>= 0.4'}
+ safe-regex2@4.0.0:
+ resolution: {integrity: sha512-Hvjfv25jPDVr3U+4LDzBuZPPOymELG3PYcSk5hcevooo1yxxamQL/bHs/GrEPGmMoMEwRrHVGiCA1pXi97B8Ew==}
+
+ safe-stable-stringify@2.4.3:
+ resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==}
+ engines: {node: '>=10'}
+
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
@@ -11846,6 +11979,9 @@ packages:
resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
engines: {node: '>=4'}
+ secure-json-parse@2.7.0:
+ resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==}
+
selderee@0.11.0:
resolution: {integrity: sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==}
@@ -12102,6 +12238,9 @@ packages:
solid-start-vercel:
optional: true
+ sonic-boom@3.8.1:
+ resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==}
+
sorcery@0.10.0:
resolution: {integrity: sha512-R5ocFmKZQFfSTstfOtHjJuAwbpGyf9qjQa1egyhvXSbM7emjrtLXtGdZsDJDABC85YBfVvrOiGWKSYXPKdvP1g==}
hasBin: true
@@ -12114,10 +12253,6 @@ packages:
resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==}
engines: {node: '>=0.10.0'}
- source-map-js@1.1.0:
- resolution: {integrity: sha512-9vC2SfsJzlej6MAaMPLu8HiBSHGdRAJ9hVFYN1ibZoNkeanmDmLUcIrj6G9DGL7XMJ54AKg/G75akXl1/izTOw==}
- engines: {node: '>=0.10.0'}
-
source-map-js@1.2.0:
resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
engines: {node: '>=0.10.0'}
@@ -12627,6 +12762,9 @@ packages:
third-party-capital@1.0.20:
resolution: {integrity: sha512-oB7yIimd8SuGptespDAZnNkzIz+NWaJCu2RMsbs4Wmp9zSDUM8Nhi3s2OOcqYuv3mN4hitXc8DVx+LyUmbUDiA==}
+ thread-stream@2.7.0:
+ resolution: {integrity: sha512-qQiRWsU/wvNolI6tbbCKd9iKaTnCXsTwVxhhKM6nctPdujTyztjlbUkUTUymidWcMnZ5pWR0ej4a0tjsW021vw==}
+
through2@2.0.5:
resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==}
@@ -12688,6 +12826,10 @@ packages:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
+ toad-cache@3.7.0:
+ resolution: {integrity: sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==}
+ engines: {node: '>=12'}
+
toidentifier@1.0.1:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'}
@@ -16164,12 +16306,57 @@ snapshots:
'@eslint/object-schema@2.1.4': {}
+ '@fastify/accept-negotiator@2.0.0': {}
+
+ '@fastify/ajv-compiler@4.0.1':
+ dependencies:
+ ajv: 8.13.0
+ ajv-formats: 3.0.1(ajv@8.13.0)
+ fast-uri: 3.0.2
+
'@fastify/busboy@1.2.1':
dependencies:
text-decoding: 1.0.0
'@fastify/busboy@2.1.0': {}
+ '@fastify/error@4.0.0': {}
+
+ '@fastify/fast-json-stringify-compiler@5.0.1':
+ dependencies:
+ fast-json-stringify: 6.0.0
+
+ '@fastify/formbody@8.0.1':
+ dependencies:
+ fast-querystring: 1.1.2
+ fastify-plugin: 5.0.1
+
+ '@fastify/merge-json-schemas@0.1.1':
+ dependencies:
+ fast-deep-equal: 3.1.3
+
+ '@fastify/send@3.1.1':
+ dependencies:
+ '@lukeed/ms': 2.0.2
+ escape-html: 1.0.3
+ fast-decode-uri-component: 1.0.1
+ http-errors: 2.0.0
+ mime: 3.0.0
+
+ '@fastify/static@8.0.1':
+ dependencies:
+ '@fastify/accept-negotiator': 2.0.0
+ '@fastify/send': 3.1.1
+ content-disposition: 0.5.4
+ fastify-plugin: 5.0.1
+ fastq: 1.17.1
+ glob: 11.0.0
+
+ '@fastify/view@10.0.1':
+ dependencies:
+ fastify-plugin: 5.0.1
+ toad-cache: 3.7.0
+
'@firebase/app-check-interop-types@0.3.2': {}
'@firebase/app-types@0.9.2': {}
@@ -17234,6 +17421,8 @@ snapshots:
'@libsql/win32-x64-msvc@0.3.18':
optional: true
+ '@lukeed/ms@2.0.2': {}
+
'@manypkg/find-root@1.1.0':
dependencies:
'@babel/runtime': 7.23.9
@@ -17277,7 +17466,7 @@ snapshots:
nopt: 5.0.0
npmlog: 5.0.1
rimraf: 3.0.2
- semver: 7.5.4
+ semver: 7.6.0
tar: 6.2.0
transitivePeerDependencies:
- encoding
@@ -17572,7 +17761,7 @@ snapshots:
'@npmcli/fs@1.1.1':
dependencies:
'@gar/promisify': 1.1.3
- semver: 7.6.0
+ semver: 7.6.3
optional: true
'@npmcli/move-file@1.1.2':
@@ -18392,90 +18581,51 @@ snapshots:
'@rollup/rollup-android-arm-eabi@4.18.0':
optional: true
- '@rollup/rollup-android-arm-eabi@4.9.6':
- optional: true
-
'@rollup/rollup-android-arm64@4.18.0':
optional: true
- '@rollup/rollup-android-arm64@4.9.6':
- optional: true
-
'@rollup/rollup-darwin-arm64@4.18.0':
optional: true
- '@rollup/rollup-darwin-arm64@4.9.6':
- optional: true
-
'@rollup/rollup-darwin-x64@4.18.0':
optional: true
- '@rollup/rollup-darwin-x64@4.9.6':
- optional: true
-
'@rollup/rollup-linux-arm-gnueabihf@4.18.0':
optional: true
- '@rollup/rollup-linux-arm-gnueabihf@4.9.6':
- optional: true
-
'@rollup/rollup-linux-arm-musleabihf@4.18.0':
optional: true
'@rollup/rollup-linux-arm64-gnu@4.18.0':
optional: true
- '@rollup/rollup-linux-arm64-gnu@4.9.6':
- optional: true
-
'@rollup/rollup-linux-arm64-musl@4.18.0':
optional: true
- '@rollup/rollup-linux-arm64-musl@4.9.6':
- optional: true
-
'@rollup/rollup-linux-powerpc64le-gnu@4.18.0':
optional: true
'@rollup/rollup-linux-riscv64-gnu@4.18.0':
optional: true
- '@rollup/rollup-linux-riscv64-gnu@4.9.6':
- optional: true
-
'@rollup/rollup-linux-s390x-gnu@4.18.0':
optional: true
'@rollup/rollup-linux-x64-gnu@4.18.0':
optional: true
- '@rollup/rollup-linux-x64-gnu@4.9.6':
- optional: true
-
'@rollup/rollup-linux-x64-musl@4.18.0':
optional: true
- '@rollup/rollup-linux-x64-musl@4.9.6':
- optional: true
-
'@rollup/rollup-win32-arm64-msvc@4.18.0':
optional: true
- '@rollup/rollup-win32-arm64-msvc@4.9.6':
- optional: true
-
'@rollup/rollup-win32-ia32-msvc@4.18.0':
optional: true
- '@rollup/rollup-win32-ia32-msvc@4.9.6':
- optional: true
-
'@rollup/rollup-win32-x64-msvc@4.18.0':
optional: true
- '@rollup/rollup-win32-x64-msvc@4.9.6':
- optional: true
-
'@rushstack/node-core-library@4.0.2(@types/node@20.12.7)':
dependencies:
fs-extra: 7.0.1
@@ -19222,10 +19372,6 @@ snapshots:
'@types/node@18.11.10': {}
- '@types/node@20.11.7':
- dependencies:
- undici-types: 5.26.5
-
'@types/node@20.12.7':
dependencies:
undici-types: 5.26.5
@@ -19361,12 +19507,6 @@ snapshots:
'@types/scheduler': 0.16.8
csstype: 3.1.3
- '@types/react@18.2.48':
- dependencies:
- '@types/prop-types': 15.7.11
- '@types/scheduler': 0.16.8
- csstype: 3.1.3
-
'@types/react@18.2.78':
dependencies:
'@types/prop-types': 15.7.11
@@ -19720,7 +19860,7 @@ snapshots:
dependencies:
'@upstash/redis': 1.25.1
- '@vitest/coverage-v8@1.2.1(vitest@1.2.2(@types/node@20.11.7)(@vitest/ui@1.2.2)(sass@1.70.0)(terser@5.27.0))':
+ '@vitest/coverage-v8@1.2.1(vitest@1.2.2(@types/node@20.12.7)(@vitest/ui@1.2.2)(sass@1.70.0)(terser@5.27.0))':
dependencies:
'@ampproject/remapping': 2.2.1
'@bcoe/v8-coverage': 0.2.3
@@ -19735,7 +19875,7 @@ snapshots:
std-env: 3.7.0
test-exclude: 6.0.0
v8-to-istanbul: 9.2.0
- vitest: 1.2.2(@types/node@20.11.7)(@vitest/ui@1.2.2)(sass@1.70.0)(terser@5.27.0)
+ vitest: 1.2.2(@types/node@20.12.7)(@vitest/ui@1.2.2)(sass@1.70.0)(terser@5.27.0)
transitivePeerDependencies:
- supports-color
@@ -19770,7 +19910,7 @@ snapshots:
pathe: 1.1.2
picocolors: 1.0.0
sirv: 2.0.4
- vitest: 1.2.2(@types/node@20.11.7)(@vitest/ui@1.2.2)(sass@1.70.0)(terser@5.27.0)
+ vitest: 1.2.2(@types/node@20.12.7)(@vitest/ui@1.2.2)(sass@1.70.0)(terser@5.27.0)
'@vitest/utils@1.2.2':
dependencies:
@@ -20768,6 +20908,8 @@ snapshots:
level-supports: 1.0.1
xtend: 4.0.2
+ abstract-logging@2.0.1: {}
+
accepts@1.3.8:
dependencies:
mime-types: 2.1.35
@@ -20830,6 +20972,10 @@ snapshots:
clean-stack: 2.2.0
indent-string: 4.0.0
+ ajv-formats@3.0.1(ajv@8.13.0):
+ optionalDependencies:
+ ajv: 8.13.0
+
ajv@6.12.6:
dependencies:
fast-deep-equal: 3.1.3
@@ -20837,6 +20983,13 @@ snapshots:
json-schema-traverse: 0.4.1
uri-js: 4.4.1
+ ajv@8.13.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+ uri-js: 4.4.1
+
algoliasearch-helper@3.18.0(algoliasearch@4.23.3):
dependencies:
'@algolia/events': 4.0.1
@@ -21029,6 +21182,8 @@ snapshots:
at-least-node@1.0.0: {}
+ atomic-sleep@1.0.0: {}
+
auto-bind@4.0.0: {}
autoprefixer@10.4.13(postcss@8.4.19):
@@ -21063,6 +21218,11 @@ snapshots:
available-typed-arrays@1.0.5: {}
+ avvio@9.0.0:
+ dependencies:
+ '@fastify/error': 4.0.0
+ fastq: 1.17.1
+
axios@0.21.4(debug@4.3.4):
dependencies:
follow-redirects: 1.15.5(debug@4.3.4)
@@ -21324,7 +21484,7 @@ snapshots:
builtins@5.0.1:
dependencies:
- semver: 7.6.0
+ semver: 7.6.3
bundle-n-require@1.1.1:
dependencies:
@@ -21830,7 +21990,7 @@ snapshots:
core-js-compat@3.35.1:
dependencies:
- browserslist: 4.22.2
+ browserslist: 4.23.0
core-js-pure@3.35.1: {}
@@ -22718,7 +22878,7 @@ snapshots:
escape-string-regexp: 4.0.0
eslint: 9.9.1(jiti@1.21.0)
esquery: 1.5.0
- semver: 7.5.4
+ semver: 7.6.0
spdx-expression-parse: 3.0.1
transitivePeerDependencies:
- supports-color
@@ -22752,7 +22912,7 @@ snapshots:
semver: 6.3.1
string.prototype.matchall: 4.0.10
- eslint-plugin-svelte@2.38.0(eslint@9.9.1(jiti@1.21.0))(svelte@4.2.9)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)):
+ eslint-plugin-svelte@2.38.0(eslint@9.9.1(jiti@1.21.0))(svelte@4.2.9)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)):
dependencies:
'@eslint-community/eslint-utils': 4.4.0(eslint@9.9.1(jiti@1.21.0))
'@jridgewell/sourcemap-codec': 1.4.15
@@ -22762,7 +22922,7 @@ snapshots:
esutils: 2.0.3
known-css-properties: 0.30.0
postcss: 8.4.38
- postcss-load-config: 3.1.4(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3))
+ postcss-load-config: 3.1.4(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3))
postcss-safe-parser: 6.0.0(postcss@8.4.38)
postcss-selector-parser: 6.0.16
semver: 7.6.0
@@ -23132,14 +23292,30 @@ snapshots:
fast-json-stable-stringify@2.1.0: {}
+ fast-json-stringify@6.0.0:
+ dependencies:
+ '@fastify/merge-json-schemas': 0.1.1
+ ajv: 8.13.0
+ ajv-formats: 3.0.1(ajv@8.13.0)
+ fast-deep-equal: 3.1.3
+ fast-uri: 2.3.0
+ json-schema-ref-resolver: 1.0.1
+ rfdc: 1.3.1
+
fast-levenshtein@2.0.6: {}
fast-querystring@1.1.2:
dependencies:
fast-decode-uri-component: 1.0.1
+ fast-redact@3.5.0: {}
+
fast-safe-stringify@2.1.1: {}
+ fast-uri@2.3.0: {}
+
+ fast-uri@3.0.2: {}
+
fast-url-parser@1.1.3:
dependencies:
punycode: 1.4.1
@@ -23152,10 +23328,34 @@ snapshots:
dependencies:
strnum: 1.0.5
+ fastify-plugin@5.0.1: {}
+
+ fastify@5.0.0:
+ dependencies:
+ '@fastify/ajv-compiler': 4.0.1
+ '@fastify/error': 4.0.0
+ '@fastify/fast-json-stringify-compiler': 5.0.1
+ abstract-logging: 2.0.1
+ avvio: 9.0.0
+ fast-json-stringify: 6.0.0
+ find-my-way: 9.1.0
+ light-my-request: 6.0.0
+ pino: 9.0.0
+ process-warning: 4.0.0
+ proxy-addr: 2.0.7
+ rfdc: 1.3.1
+ secure-json-parse: 2.7.0
+ semver: 7.6.3
+ toad-cache: 3.7.0
+
fastq@1.16.0:
dependencies:
reusify: 1.0.4
+ fastq@1.17.1:
+ dependencies:
+ reusify: 1.0.4
+
fault@2.0.1:
dependencies:
format: 0.2.2
@@ -23295,6 +23495,12 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ find-my-way@9.1.0:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-querystring: 1.1.2
+ safe-regex2: 4.0.0
+
find-up@4.1.0:
dependencies:
locate-path: 5.0.0
@@ -23606,6 +23812,15 @@ snapshots:
minipass: 5.0.0
path-scurry: 1.10.1
+ glob@11.0.0:
+ dependencies:
+ foreground-child: 3.1.1
+ jackspeak: 4.0.2
+ minimatch: 10.0.1
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.1
+ path-scurry: 2.0.0
+
glob@7.2.3:
dependencies:
fs.realpath: 1.0.0
@@ -24518,6 +24733,10 @@ snapshots:
optionalDependencies:
'@pkgjs/parseargs': 0.11.0
+ jackspeak@4.0.2:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+
jake@10.8.7:
dependencies:
async: 3.2.5
@@ -24578,8 +24797,14 @@ snapshots:
json-parse-even-better-errors@2.3.1: {}
+ json-schema-ref-resolver@1.0.1:
+ dependencies:
+ fast-deep-equal: 3.1.3
+
json-schema-traverse@0.4.1: {}
+ json-schema-traverse@1.0.0: {}
+
json-stable-stringify-without-jsonify@1.0.1: {}
json-stable-stringify@1.1.1:
@@ -24636,7 +24861,7 @@ snapshots:
lodash.isstring: 4.0.1
lodash.once: 4.1.1
ms: 2.1.3
- semver: 7.5.4
+ semver: 7.6.0
jstransformer@1.0.0:
dependencies:
@@ -24890,6 +25115,12 @@ snapshots:
'@libsql/linux-x64-musl': 0.3.18
'@libsql/win32-x64-msvc': 0.3.18
+ light-my-request@6.0.0:
+ dependencies:
+ cookie: 0.6.0
+ process-warning: 4.0.0
+ set-cookie-parser: 2.6.0
+
lil-fp@1.4.5: {}
lilconfig@2.1.0: {}
@@ -25067,6 +25298,8 @@ snapshots:
lru-cache@10.2.0: {}
+ lru-cache@11.0.1: {}
+
lru-cache@4.0.2:
dependencies:
pseudomap: 1.0.2
@@ -25923,6 +26156,10 @@ snapshots:
min-indent@1.0.1: {}
+ minimatch@10.0.1:
+ dependencies:
+ brace-expansion: 2.0.1
+
minimatch@3.0.8:
dependencies:
brace-expansion: 1.1.11
@@ -26000,6 +26237,8 @@ snapshots:
minipass@7.1.1: {}
+ minipass@7.1.2: {}
+
minizlib@2.1.2:
dependencies:
minipass: 3.3.6
@@ -26411,7 +26650,7 @@ snapshots:
nopt: 5.0.0
npmlog: 6.0.2
rimraf: 3.0.2
- semver: 7.5.4
+ semver: 7.6.0
tar: 6.2.0
which: 2.0.2
transitivePeerDependencies:
@@ -26497,7 +26736,7 @@ snapshots:
dependencies:
execa: 6.1.0
parse-package-name: 1.0.0
- semver: 7.5.4
+ semver: 7.6.0
validate-npm-package-name: 4.0.0
nth-check@2.1.1:
@@ -26566,6 +26805,8 @@ snapshots:
ohash@1.1.3: {}
+ on-exit-leak-free@2.1.2: {}
+
on-finished@2.3.0:
dependencies:
ee-first: 1.1.1
@@ -26679,6 +26920,8 @@ snapshots:
p-try@2.2.0: {}
+ package-json-from-dist@1.0.1: {}
+
package-manager-detector@0.2.0: {}
packet-reader@1.0.0: {}
@@ -26797,6 +27040,11 @@ snapshots:
lru-cache: 10.2.0
minipass: 5.0.0
+ path-scurry@2.0.0:
+ dependencies:
+ lru-cache: 11.0.1
+ minipass: 7.1.2
+
path-to-regexp@0.1.7: {}
path-type@4.0.0: {}
@@ -26876,6 +27124,27 @@ snapshots:
pify@4.0.1: {}
+ pino-abstract-transport@1.2.0:
+ dependencies:
+ readable-stream: 4.5.2
+ split2: 4.2.0
+
+ pino-std-serializers@6.2.2: {}
+
+ pino@9.0.0:
+ dependencies:
+ atomic-sleep: 1.0.0
+ fast-redact: 3.5.0
+ on-exit-leak-free: 2.1.2
+ pino-abstract-transport: 1.2.0
+ pino-std-serializers: 6.2.2
+ process-warning: 3.0.0
+ quick-format-unescaped: 4.0.4
+ real-require: 0.2.0
+ safe-stable-stringify: 2.4.3
+ sonic-boom: 3.8.1
+ thread-stream: 2.7.0
+
pirates@4.0.6: {}
pkg-dir@4.2.0:
@@ -26941,21 +27210,21 @@ snapshots:
camelcase-css: 2.0.1
postcss: 8.4.38
- postcss-load-config@3.1.4(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)):
+ postcss-load-config@3.1.4(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)):
dependencies:
lilconfig: 2.1.0
yaml: 1.10.2
optionalDependencies:
postcss: 8.4.38
- ts-node: 10.9.2(@types/node@20.11.7)(typescript@5.3.3)
+ ts-node: 10.9.2(@types/node@20.12.7)(typescript@5.3.3)
- postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)):
+ postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)):
dependencies:
lilconfig: 3.1.1
yaml: 2.3.4
optionalDependencies:
postcss: 8.4.38
- ts-node: 10.9.2(@types/node@20.11.7)(typescript@5.3.3)
+ ts-node: 10.9.2(@types/node@20.12.7)(typescript@5.3.3)
optional: true
postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.4.5)):
@@ -27027,12 +27296,6 @@ snapshots:
picocolors: 1.0.0
source-map-js: 1.2.0
- postcss@8.4.33:
- dependencies:
- nanoid: 3.3.7
- picocolors: 1.0.0
- source-map-js: 1.1.0
-
postcss@8.4.38:
dependencies:
nanoid: 3.3.7
@@ -27288,6 +27551,12 @@ snapshots:
process-nextick-args@2.0.1: {}
+ process-warning@3.0.0: {}
+
+ process-warning@4.0.0: {}
+
+ process@0.11.10: {}
+
promise-inflight@1.0.1:
optional: true
@@ -27455,6 +27724,8 @@ snapshots:
queue-microtask@1.2.3: {}
+ quick-format-unescaped@4.0.4: {}
+
quick-lru@4.0.1: {}
radix3@1.1.0: {}
@@ -27666,12 +27937,22 @@ snapshots:
string_decoder: 1.3.0
util-deprecate: 1.0.2
+ readable-stream@4.5.2:
+ dependencies:
+ abort-controller: 3.0.0
+ buffer: 6.0.3
+ events: 3.3.0
+ process: 0.11.10
+ string_decoder: 1.3.0
+
readdirp@3.6.0:
dependencies:
picomatch: 2.3.1
reading-time@1.5.0: {}
+ real-require@0.2.0: {}
+
rechoir@0.8.0:
dependencies:
resolve: 1.22.8
@@ -27891,6 +28172,8 @@ snapshots:
require-directory@2.1.1: {}
+ require-from-string@2.0.2: {}
+
require-main-filename@2.0.0: {}
requires-port@1.0.0: {}
@@ -27925,6 +28208,8 @@ snapshots:
onetime: 5.1.2
signal-exit: 3.0.7
+ ret@0.5.0: {}
+
retext-latin@4.0.0:
dependencies:
'@types/nlcst': 2.0.3
@@ -28026,25 +28311,6 @@ snapshots:
'@rollup/rollup-win32-x64-msvc': 4.18.0
fsevents: 2.3.3
- rollup@4.9.6:
- dependencies:
- '@types/estree': 1.0.5
- optionalDependencies:
- '@rollup/rollup-android-arm-eabi': 4.9.6
- '@rollup/rollup-android-arm64': 4.9.6
- '@rollup/rollup-darwin-arm64': 4.9.6
- '@rollup/rollup-darwin-x64': 4.9.6
- '@rollup/rollup-linux-arm-gnueabihf': 4.9.6
- '@rollup/rollup-linux-arm64-gnu': 4.9.6
- '@rollup/rollup-linux-arm64-musl': 4.9.6
- '@rollup/rollup-linux-riscv64-gnu': 4.9.6
- '@rollup/rollup-linux-x64-gnu': 4.9.6
- '@rollup/rollup-linux-x64-musl': 4.9.6
- '@rollup/rollup-win32-arm64-msvc': 4.9.6
- '@rollup/rollup-win32-ia32-msvc': 4.9.6
- '@rollup/rollup-win32-x64-msvc': 4.9.6
- fsevents: 2.3.3
-
roughjs@4.6.6:
dependencies:
hachure-fill: 0.5.2
@@ -28093,6 +28359,12 @@ snapshots:
get-intrinsic: 1.2.2
is-regex: 1.1.4
+ safe-regex2@4.0.0:
+ dependencies:
+ ret: 0.5.0
+
+ safe-stable-stringify@2.4.3: {}
+
safer-buffer@2.1.2: {}
sander@0.5.1:
@@ -28131,6 +28403,8 @@ snapshots:
extend-shallow: 2.0.1
kind-of: 6.0.3
+ secure-json-parse@2.7.0: {}
+
selderee@0.11.0:
dependencies:
parseley: 0.12.1
@@ -28189,7 +28463,7 @@ snapshots:
moment-timezone: 0.5.44
pg-connection-string: 2.6.2
retry-as-promised: 7.0.4
- semver: 7.5.4
+ semver: 7.6.0
sequelize-pool: 7.1.0
toposort-class: 1.0.1
uuid: 8.3.2
@@ -28427,7 +28701,7 @@ snapshots:
connect: 3.7.0
debug: 4.3.4(supports-color@8.1.1)
dequal: 2.0.3
- dotenv: 16.4.1
+ dotenv: 16.3.1
es-module-lexer: 1.4.1
esbuild: 0.17.19
esbuild-plugin-solid: 0.5.0(esbuild@0.17.19)(solid-js@1.8.12)
@@ -28453,6 +28727,10 @@ snapshots:
- '@testing-library/jest-dom'
- supports-color
+ sonic-boom@3.8.1:
+ dependencies:
+ atomic-sleep: 1.0.0
+
sorcery@0.10.0:
dependencies:
buffer-crc32: 0.2.13
@@ -28469,8 +28747,6 @@ snapshots:
source-map-js@1.0.2: {}
- source-map-js@1.1.0: {}
-
source-map-js@1.2.0: {}
source-map-support@0.5.21:
@@ -28759,7 +29035,7 @@ snapshots:
methods: 1.1.2
mime: 2.6.0
qs: 6.11.2
- semver: 7.5.4
+ semver: 7.6.0
transitivePeerDependencies:
- supports-color
@@ -28807,7 +29083,7 @@ snapshots:
- bufferutil
- utf-8-validate
- svelte-check@2.10.2(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9):
+ svelte-check@2.10.2(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9):
dependencies:
'@jridgewell/trace-mapping': 0.3.22
chokidar: 3.5.3
@@ -28816,7 +29092,7 @@ snapshots:
picocolors: 1.0.0
sade: 1.8.1
svelte: 4.2.9
- svelte-preprocess: 4.10.7(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9)(typescript@5.4.5)
+ svelte-preprocess: 4.10.7(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9)(typescript@5.4.5)
typescript: 5.4.5
transitivePeerDependencies:
- '@babel/core'
@@ -28830,7 +29106,7 @@ snapshots:
- stylus
- sugarss
- svelte-check@3.6.3(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9):
+ svelte-check@3.6.3(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9):
dependencies:
'@jridgewell/trace-mapping': 0.3.22
chokidar: 3.5.3
@@ -28839,7 +29115,7 @@ snapshots:
picocolors: 1.0.0
sade: 1.8.1
svelte: 4.2.9
- svelte-preprocess: 5.1.3(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9)(typescript@5.4.5)
+ svelte-preprocess: 5.1.3(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9)(typescript@5.4.5)
typescript: 5.4.5
transitivePeerDependencies:
- '@babel/core'
@@ -28866,7 +29142,7 @@ snapshots:
dependencies:
svelte: 4.2.9
- svelte-preprocess@4.10.7(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9)(typescript@5.4.5):
+ svelte-preprocess@4.10.7(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9)(typescript@5.4.5):
dependencies:
'@types/pug': 2.0.10
'@types/sass': 1.45.0
@@ -28878,23 +29154,23 @@ snapshots:
optionalDependencies:
'@babel/core': 7.23.9
postcss: 8.4.38
- postcss-load-config: 4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3))
+ postcss-load-config: 4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3))
pug: 3.0.2
sass: 1.70.0
typescript: 5.4.5
- svelte-preprocess@5.1.3(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9)(typescript@5.4.5):
+ svelte-preprocess@5.1.3(@babel/core@7.23.9)(postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)))(postcss@8.4.38)(pug@3.0.2)(sass@1.70.0)(svelte@4.2.9)(typescript@5.4.5):
dependencies:
'@types/pug': 2.0.10
detect-indent: 6.1.0
- magic-string: 0.30.5
+ magic-string: 0.30.8
sorcery: 0.11.0
strip-indent: 3.0.0
svelte: 4.2.9
optionalDependencies:
'@babel/core': 7.23.9
postcss: 8.4.38
- postcss-load-config: 4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3))
+ postcss-load-config: 4.0.2(postcss@8.4.38)(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3))
pug: 3.0.2
sass: 1.70.0
typescript: 5.4.5
@@ -29066,9 +29342,13 @@ snapshots:
third-party-capital@1.0.20: {}
+ thread-stream@2.7.0:
+ dependencies:
+ real-require: 0.2.0
+
through2@2.0.5:
dependencies:
- readable-stream: 2.3.8
+ readable-stream: 2.3.7
xtend: 4.0.2
through2@3.0.2:
@@ -29120,6 +29400,8 @@ snapshots:
dependencies:
is-number: 7.0.0
+ toad-cache@3.7.0: {}
+
toidentifier@1.0.1: {}
token-stream@1.0.0: {}
@@ -29209,14 +29491,14 @@ snapshots:
optionalDependencies:
'@swc/core': 1.3.106(@swc/helpers@0.5.13)
- ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3):
+ ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3):
dependencies:
'@cspotcode/source-map-support': 0.8.1
'@tsconfig/node10': 1.0.9
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
- '@types/node': 20.11.7
+ '@types/node': 20.12.7
acorn: 8.11.3
acorn-walk: 8.3.2
arg: 4.1.3
@@ -29385,11 +29667,11 @@ snapshots:
shiki: 0.14.7
typescript: 5.4.5
- typeorm-naming-strategies@4.1.0(typeorm@0.3.17(ioredis@5.4.1)(mssql@7.3.5(encoding@0.1.13))(mysql2@3.9.7)(pg@8.11.3)(redis@4.6.12)(sqlite3@5.1.6(encoding@0.1.13))(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3))):
+ typeorm-naming-strategies@4.1.0(typeorm@0.3.17(ioredis@5.4.1)(mssql@7.3.5(encoding@0.1.13))(mysql2@3.9.7)(pg@8.11.3)(redis@4.6.12)(sqlite3@5.1.6(encoding@0.1.13))(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3))):
dependencies:
- typeorm: 0.3.17(ioredis@5.4.1)(mssql@7.3.5(encoding@0.1.13))(mysql2@3.9.7)(pg@8.11.3)(redis@4.6.12)(sqlite3@5.1.6(encoding@0.1.13))(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3))
+ typeorm: 0.3.17(ioredis@5.4.1)(mssql@7.3.5(encoding@0.1.13))(mysql2@3.9.7)(pg@8.11.3)(redis@4.6.12)(sqlite3@5.1.6(encoding@0.1.13))(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3))
- typeorm@0.3.17(ioredis@5.4.1)(mssql@7.3.5(encoding@0.1.13))(mysql2@3.9.7)(pg@8.11.3)(redis@4.6.12)(sqlite3@5.1.6(encoding@0.1.13))(ts-node@10.9.2(@types/node@20.11.7)(typescript@5.3.3)):
+ typeorm@0.3.17(ioredis@5.4.1)(mssql@7.3.5(encoding@0.1.13))(mysql2@3.9.7)(pg@8.11.3)(redis@4.6.12)(sqlite3@5.1.6(encoding@0.1.13))(ts-node@10.9.2(@types/node@20.12.7)(typescript@5.3.3)):
dependencies:
'@sqltools/formatter': 1.2.5
app-root-path: 3.1.0
@@ -29398,7 +29680,7 @@ snapshots:
cli-highlight: 2.1.11
date-fns: 2.30.0
debug: 4.3.4(supports-color@8.1.1)
- dotenv: 16.4.1
+ dotenv: 16.3.1
glob: 8.1.0
mkdirp: 2.1.6
reflect-metadata: 0.1.14
@@ -29413,7 +29695,7 @@ snapshots:
pg: 8.11.3
redis: 4.6.12
sqlite3: 5.1.6(encoding@0.1.13)
- ts-node: 10.9.2(@types/node@20.11.7)(typescript@5.3.3)
+ ts-node: 10.9.2(@types/node@20.12.7)(typescript@5.3.3)
transitivePeerDependencies:
- supports-color
@@ -29634,7 +29916,7 @@ snapshots:
unplugin@1.6.0:
dependencies:
acorn: 8.11.3
- chokidar: 3.5.3
+ chokidar: 3.6.0
webpack-sources: 3.2.3
webpack-virtual-modules: 0.6.1
@@ -29682,7 +29964,7 @@ snapshots:
dependencies:
citty: 0.1.5
consola: 3.2.3
- pathe: 1.1.2
+ pathe: 1.1.1
unws@0.2.4(ws@8.16.0):
dependencies:
@@ -29831,13 +30113,13 @@ snapshots:
transitivePeerDependencies:
- rollup
- vite-node@1.2.2(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0):
+ vite-node@1.2.2(@types/node@20.12.7)(sass@1.70.0)(terser@5.27.0):
dependencies:
cac: 6.7.14
debug: 4.3.4(supports-color@8.1.1)
- pathe: 1.1.2
+ pathe: 1.1.1
picocolors: 1.0.0
- vite: 5.3.1(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)
+ vite: 5.0.13(@types/node@20.12.7)(sass@1.70.0)(terser@5.27.0)
transitivePeerDependencies:
- '@types/node'
- less
@@ -29912,35 +30194,24 @@ snapshots:
- supports-color
- typescript
- vite@5.0.13(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0):
+ vite@5.0.13(@types/node@20.12.7)(sass@1.70.0)(terser@5.27.0):
dependencies:
esbuild: 0.19.12
- postcss: 8.4.33
- rollup: 4.9.6
- optionalDependencies:
- '@types/node': 20.11.7
- fsevents: 2.3.3
- sass: 1.70.0
- terser: 5.27.0
-
- vite@5.3.1(@types/node@18.11.10)(sass@1.70.0)(terser@5.27.0):
- dependencies:
- esbuild: 0.21.5
postcss: 8.4.38
rollup: 4.18.0
optionalDependencies:
- '@types/node': 18.11.10
+ '@types/node': 20.12.7
fsevents: 2.3.3
sass: 1.70.0
terser: 5.27.0
- vite@5.3.1(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0):
+ vite@5.3.1(@types/node@18.11.10)(sass@1.70.0)(terser@5.27.0):
dependencies:
esbuild: 0.21.5
postcss: 8.4.38
rollup: 4.18.0
optionalDependencies:
- '@types/node': 20.11.7
+ '@types/node': 18.11.10
fsevents: 2.3.3
sass: 1.70.0
terser: 5.27.0
@@ -29964,7 +30235,7 @@ snapshots:
optionalDependencies:
vite: 5.3.1(@types/node@20.12.7)(sass@1.70.0)(terser@5.27.0)
- vitest@1.2.2(@types/node@20.11.7)(@vitest/ui@1.2.2)(sass@1.70.0)(terser@5.27.0):
+ vitest@1.2.2(@types/node@20.12.7)(@vitest/ui@1.2.2)(sass@1.70.0)(terser@5.27.0):
dependencies:
'@vitest/expect': 1.2.2
'@vitest/runner': 1.2.2
@@ -29978,17 +30249,17 @@ snapshots:
execa: 8.0.1
local-pkg: 0.5.0
magic-string: 0.30.5
- pathe: 1.1.2
+ pathe: 1.1.1
picocolors: 1.0.0
std-env: 3.7.0
strip-literal: 1.3.0
tinybench: 2.6.0
tinypool: 0.8.2
- vite: 5.0.13(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)
- vite-node: 1.2.2(@types/node@20.11.7)(sass@1.70.0)(terser@5.27.0)
+ vite: 5.0.13(@types/node@20.12.7)(sass@1.70.0)(terser@5.27.0)
+ vite-node: 1.2.2(@types/node@20.12.7)(sass@1.70.0)(terser@5.27.0)
why-is-node-running: 2.2.2
optionalDependencies:
- '@types/node': 20.11.7
+ '@types/node': 20.12.7
'@vitest/ui': 1.2.2(vitest@1.2.2)
transitivePeerDependencies:
- less
diff --git a/turbo.json b/turbo.json
index 9e42a71a33..da8021a29a 100644
--- a/turbo.json
+++ b/turbo.json
@@ -67,7 +67,8 @@
"@auth/sveltekit#build",
"@auth/express#build",
"@auth/solid-start#build",
- "@auth/qwik#build"
+ "@auth/qwik#build",
+ "@auth/fastify#build"
],
"persistent": true,
"cache": false
@@ -112,6 +113,7 @@
"@auth/upstash-redis-adapter#build",
"@auth/xata-adapter#build",
"@auth/qwik#build",
+ "@auth/fastify#build",
"next-auth#build",
"^build"
],