Compare commits

..

7 Commits

Author SHA1 Message Date
GitHub Actions
e274c51807 chore(release): bump package version(s) [skip ci] 2023-09-24 13:46:27 +00:00
Thang Vu
2b3836d945 chore: add missing adapters in misc files 2023-09-24 20:30:31 +07:00
Thang Vu
b729f8af0b feat(adapters): azure tables adapter (#8708)
* feat(adapter): Add Azure Table Storage DB adapter

* add newlines

* remove sessionByUserId together with the session

* include import in the readme file

* add types to response objects

* introduce contracts for the db entities

* Rename the lib in docs

Co-authored-by: Nico Domino <yo@ndo.dev>

* run prettier

* feat: azure tables adapter

---------

Co-authored-by: Nikita Dmitriev <nikitadmitry@gmail.com>
Co-authored-by: Nikita Dmitriev <106996965+nikitaclicks@users.noreply.github.com>
Co-authored-by: Nico Domino <yo@ndo.dev>
2023-09-24 17:50:05 +07:00
Guy Korland
9f54222c0e fix(adapters): Avoid parseDataSourceConfig on each call (#8581)
Improve performance by avoiding call to parseDataSourceConfig before checking if _dataSource was already initialized.

Co-authored-by: Thang Vu <hi@thvu.dev>
2023-09-24 10:18:30 +07:00
Joachim Bjørge
a5ac491cb8 fix(providers): optional chaining in azure-ad-b2c profile (#8616)
Fix crash in azure-ad-b2c.ts

Not all b2c-setups return a list of emails. This fixes the resulting crash by using defensive access when setting the profile email address field.

Co-authored-by: Thang Vu <hi@thvu.dev>
2023-09-24 10:01:43 +07:00
Thang Vu
a96dcdbca3 chore: format surrealdb deps 2023-09-24 09:45:44 +07:00
Martin Schaer
bec01a82ea feat(adapters): add SurrealDB adapter (#6251)
* feat(adapter-surrealdb): implemented with unit tests

* chore: update README

* Use stateless DB connection

* Update surrealdb-rest-ts

* chore: bump turbo and pnpm

* chore(docs): fix dynamodb typo (#7130)

fix: typo

* chore: bump pnpm

* chore: update lock file, bump dev dependencies

* chore: run `pnpm install --fix-lockfile`

* chore: re-run pnpm install

* chore: add missing dev dep

* revert lock

* update lock

* use surrealdb.js

* add rest test

* remove commented-out code

* update readme

* modularize repeated code

* fix(docs): fix default `maxAge` formula (#7406)

* feat(adapters): add Account mapping before database write (#7369)

* feat: map Account before saving to database

* document `acconut()`, explain default behaviour

* generate `expires_at` based on `expires_in`

Fixes #6538

* rename

* strip undefined on `defaultProfile`

* don't forward defaults to account callback

* improve internal namings, types, docs

* chore: improve errors, add more docs (#7415)

* JWT Token -> JWT

* document some errors

* improve errors, docs

* fix: loosen profile types

* chore: type fixes

* fix: allow handling OAuth callback error response

related #7407

* fix(docs): remove extra heading

Fixes #7426

* chore: use `@ts-ignore`

* chore: support release any package as experimental

* chore: separate manual release job

* chore: skip test for manual release

* chore: tweak

* chore: tweaks

* chore: tweak manual release version

* Use query instead of select to be able to use query params

* Fix lint errors

* Update surrealdb.js and remove surrealdb-rest-ts in favor of ExperimentalSurrealHTTP

* update pnpm-lock

* fix merge

* fix merge

* fix merge

* migrate surrealdb.js api

* fix queries

* update package.json

* fix types

* prepare for rest

* update readme

* chore: format PR

* Update README.md

* Update package.json

---------

Co-authored-by: Balázs Orbán <info@balazsorban.com>
Co-authored-by: jakzo <jack@jf.id.au>
Co-authored-by: Victor <saptefrativictor@gmail.com>
Co-authored-by: Thang Vu <hi@thvu.dev>
2023-09-23 21:14:40 +07:00
29 changed files with 1333 additions and 562 deletions

View File

@@ -21,6 +21,9 @@ body:
multiple: true
options:
- "Custom adapter"
- "@auth/azure-tables-adapter"
- "@auth/edgedb-adapter"
- "@auth/d1-adapter"
- "@auth/dgraph-adapter"
- "@auth/drizzle-adapter"
- "@auth/dynamodb-adapter"

View File

@@ -1,7 +1,11 @@
# https://github.com/actions/labeler#create-githublabeleryml
adapters: ["packages/core/src/adapters.ts", "packages/adapter-*/**/*"]
core: ["packages/core/src/**/*"]
azure-tables: ["packages/adapter-azure-tables/**/*"]
edgedb: ["packages/adapter-edgedb/**/*"]
d1: ["packages/adapter-d1/**/*"]
dgraph: ["packages/adapter-dgraph/**/*"]
drizzle: ["packages/adapter-drizzle/**/*"]
documentation: ["packages/docs/docs/**/*"]
dynamodb: ["packages/adapter-dynamodb/**/*"]
examples: ["apps/examples/**/*"]
@@ -21,6 +25,7 @@ providers: ["packages/core/src/providers/**/*"]
sequelize: ["packages/adapter-sequelize/**/*"]
solidjs: ["packages/frameworks-solid-start/**/*"]
supabase: ["packages/adapter-supabase/**/*"]
surrealdb: ["packages/adapter-surrealdb/**/*"]
svelte: ["packages/frameworks-sveltekit/**/*"]
test: ["**test**/*"]
typeorm: ["packages/adapter-typeorm/**/*"]

View File

@@ -39,6 +39,7 @@ on:
options:
- "core"
- "frameworks-nextjs"
- "adapter-edgedb"
- "adapter-dgraph"
- "adapter-drizzle"
- "adapter-dynamodb"

View File

@@ -5,6 +5,10 @@ title: Overview
Using an Auth.js / NextAuth.js adapter you can connect to any database service or even several different services at the same time. The following listed official adapters are created and maintained by the community:
<div class="adapter-card-list">
<a href="/reference/adapter/azure-tables" class="adapter-card">
<img src="/img/adapters/azure-tables.svg" width="40" />
<h4 class="adapter-card__title">Azure Table Storage Adapter</h4>
</a>
<a href="/reference/adapter/d1" class="adapter-card">
<img src="/img/adapters/d1.svg" width="40" />
<h4 class="adapter-card__title">D1 Adapter</h4>
@@ -69,6 +73,10 @@ Using an Auth.js / NextAuth.js adapter you can connect to any database service o
<img src="/img/adapters/supabase.svg" width="25" />
<h4 class="adapter-card__title">Supabase Adapter</h4>
</a>
<a href="/reference/adapter/surrealdb" class="adapter-card">
<img src="/img/adapters/surreal.png" width="25" />
<h4 class="adapter-card__title">SurrealDB Adapter</h4>
</a>
<a href="/reference/adapter/typeorm" class="adapter-card">
<img src="/img/adapters/typeorm.png" width="30" />
<h4 class="adapter-card__title">TypeORM Adapter</h4>

View File

@@ -282,6 +282,7 @@ const docusaurusConfig = {
...(process.env.TYPEDOC_SKIP_ADAPTERS
? []
: [
typedocAdapter("Azure Tables"),
typedocAdapter("D1"),
typedocAdapter("EdgeDb"),
typedocAdapter("Dgraph"),
@@ -299,6 +300,7 @@ const docusaurusConfig = {
typedocAdapter("TypeORM"),
typedocAdapter("Sequelize"),
typedocAdapter("Supabase"),
typedocAdapter("SurrealDB"),
typedocAdapter("Upstash Redis"),
typedocAdapter("Xata"),
]),

View File

@@ -46,6 +46,8 @@ module.exports = {
label: "Database Adapters",
link: { type: "doc", id: "reference/adapters/index" },
items: [
{ type: "doc", id: "reference/adapter/azure-tables/index" },
{ type: "doc", id: "reference/adapter/d1/index" },
{ type: "doc", id: "reference/adapter/edgedb/index" },
{ type: "doc", id: "reference/adapter/dgraph/index" },
{ type: "doc", id: "reference/adapter/drizzle/index" },
@@ -61,6 +63,7 @@ module.exports = {
{ type: "doc", id: "reference/adapter/prisma/index" },
{ type: "doc", id: "reference/adapter/sequelize/index" },
{ type: "doc", id: "reference/adapter/supabase/index" },
{ type: "doc", id: "reference/adapter/surrealdb/index" },
{ type: "doc", id: "reference/adapter/typeorm/index" },
{ type: "doc", id: "reference/adapter/upstash-redis/index" },
{ type: "doc", id: "reference/adapter/xata/index" },

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 91 81" fill="#fff" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-linejoin="round"><use xlink:href="#A" x=".5" y=".5"/><symbol id="A" overflow="visible"><path d="M67.678 0H22.559L0 40l22.559 40h44.881L90 40 67.678 0zM42.982 20.976H53.43v10.732H42.982V20.976zm0 13.415H53.43v10.732H42.982V34.39zm0 13.414H53.43v10.732H42.982V47.805zM29.921 20.976h10.448v10.732H29.921V20.976zm0 13.415h10.448v10.732H29.921V34.39zm0 13.414h10.448v10.732H29.921V47.805zM66.254 64.39H23.747V20.732h2.849v40.732h0 0 39.657v2.927zm.237-5.854H56.042V47.805h10.448v10.732zm0-13.414H56.042V34.39h10.448v10.732zm0-13.415H56.042V20.976h10.448v10.732z" fill="#0078d7" stroke="none"/></symbol></svg>

After

Width:  |  Height:  |  Size: 782 B

BIN
docs/static/img/adapters/surreal.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

View File

@@ -0,0 +1,26 @@
<p align="center">
<br/>
<a href="https://authjs.dev" target="_blank">
<img height="64px" src="https://authjs.dev/img/logo/logo-sm.png" />
</a>
<a href="https://azure.microsoft.com/en-us/products/storage/tables" target="_blank">
<img height="64px" src="https://authjs.dev/img/adapters/azure-tables.svg"/>
</a>
<h3 align="center"><b>Azure Table Storage Adapter</b> - NextAuth.js / Auth.js</a></h3>
<p align="center" style="align: center;">
<a href="https://npm.im/@auth/azure-tables-adapter">
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
</a>
<a href="https://npm.im/@auth/azure-tables-adapter">
<img alt="npm" src="https://img.shields.io/npm/v/@auth/azure-tables-adapter?color=green&label=@auth/azure-tables-adapter&style=flat-square">
</a>
<a href="https://www.npmtrends.com/@auth/azure-tables-adapter">
<img src="https://img.shields.io/npm/dm/@auth/azure-tables-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
</a>
<a href="https://github.com/nextauthjs/next-auth/stargazers">
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
</a>
</p>
</p>
---

View File

@@ -0,0 +1,59 @@
{
"name": "@auth/azure-tables-adapter",
"version": "0.1.0",
"description": "Azure Tables Storage adapter for next-auth.",
"homepage": "https://authjs.dev",
"repository": "https://github.com/nextauthjs/next-auth",
"bugs": {
"url": "https://github.com/nextauthjs/next-auth/issues"
},
"author": "Nikita Dmitrijev <nikitadmitry@gmail.com>",
"contributors": [
"Thang Huu Vu <hi@thvu.dev>"
],
"license": "ISC",
"keywords": [
"next-auth",
"next.js",
"oauth",
"azure-tables",
"adapter"
],
"type": "module",
"types": "./index.d.ts",
"exports": {
".": {
"types": "./index.d.ts",
"import": "./index.js"
}
},
"files": [
"*.d.ts*",
"*.js",
"src"
],
"private": false,
"publishConfig": {
"access": "public"
},
"scripts": {
"test": "./tests/test.sh",
"test:watch": "./tests/test.sh -w",
"build": "tsc"
},
"dependencies": {
"@auth/core": "workspace:*"
},
"peerDependencies": {
"@azure/data-tables": "^13.2.1"
},
"devDependencies": {
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"jest": "^27.4.3",
"@azure/data-tables": "^13.2.1"
},
"jest": {
"preset": "@auth/adapter-test/jest"
}
}

View File

@@ -0,0 +1,303 @@
/**
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: 16}}>
* <p style={{fontWeight: "normal"}}>An official <a href="https://azure.microsoft.com/en-us/products/storage/tables">Azure Table Storage</a> adapter for Auth.js / NextAuth.js.</p>
* <a href="https://azure.microsoft.com/en-us/products/storage/tables">
* <img style={{display: "block"}} src="/img/adapters/azure-tables.svg" width="48" />
* </a>
* </div>
*
* ## Installation
*
* ```bash npm2yarn2pnpm
* npm install next-auth @auth/azure-tables-adapter
* ```
*
* @module @auth/azure-tables-adapter
*/
import type {
Adapter,
AdapterUser,
AdapterAccount,
AdapterSession,
VerificationToken,
} from "@auth/core/adapters"
import {
GetTableEntityResponse,
TableClient,
TableEntityResult,
} from "@azure/data-tables"
globalThis.crypto ??= require("node:crypto").webcrypto
export const keys = {
user: "user",
userByEmail: "userByEmail",
account: "account",
accountByUserId: "accountByUserId",
session: "session",
sessionByUserId: "sessionByUserId",
verificationToken: "verificationToken",
}
export function withoutKeys<T>(
entity: GetTableEntityResponse<TableEntityResult<T>>
): T {
delete entity.partitionKey
delete entity.rowKey
// @ts-expect-error
delete entity.etag
delete entity.timestamp
// @ts-expect-error
delete entity["odata.metadata"]
return entity
}
/**
*
* 1. Create a table for authentication data, `auth` in the example below.
*
* ```js title="auth.ts"
* import type { AuthConfig } from "next-auth"
* import { TableStorageAdapter } from "@next-auth/azure-tables-adapter"
* import { AzureNamedKeyCredential, TableClient } from "@azure/data-tables"
*
* const credential = new AzureNamedKeyCredential(
* process.env.AZURE_ACCOUNT,
* process.env.AZURE_ACCESS_KEY
* )
* const authClient = new TableClient(
* process.env.AZURE_TABLES_ENDPOINT,
* "auth",
* credential
* )
*
* // For more information on each option (and a full list of options) go to
* // https://authjs.dev/reference/configuration/auth-options
* export default const authConfig = {
* // https://authjs.dev/reference/providers/oauth-builtin
* providers: [
* // ...
* ],
* adapter: TableStorageAdapter(authClient),
* // ...
* } satisfies AuthConfig
* ```
*
* Environment variable are as follows:
*
* ```
* AZURE_ACCOUNT=storageaccountname
* AZURE_ACCESS_KEY=longRandomKey
* AZURE_TABLES_ENDPOINT=https://$AZURE_ACCOUNT.table.core.windows.net
* ```
*
*/
export const TableStorageAdapter = (client: TableClient): Adapter => {
return {
async createUser(user) {
const id = crypto.randomUUID()
const newUser = {
...user,
id,
}
await Promise.all([
client.createEntity({
...newUser,
partitionKey: keys.userByEmail,
rowKey: user.email,
}),
client.createEntity({
...newUser,
partitionKey: keys.user,
rowKey: id,
}),
])
return newUser
},
async getUser(id: string) {
try {
const user = await client.getEntity<AdapterUser>(keys.user, id)
return withoutKeys(user)
} catch {
return null
}
},
async getUserByEmail(email) {
try {
const user = await client.getEntity<AdapterUser>(
keys.userByEmail,
email
)
return withoutKeys(user)
} catch {
return null
}
},
async getUserByAccount({ providerAccountId, provider }) {
try {
const rowKey = `${providerAccountId}_${provider}`
const account = await client.getEntity<AdapterAccount>(
keys.account,
rowKey
)
const user = await client.getEntity<AdapterUser>(
keys.user,
account.userId
)
return withoutKeys(user)
} catch {
return null
}
},
async updateUser(user) {
const _user = await client.getEntity<AdapterUser>(keys.user, user.id)
const updatedUser = {
...user,
partitionKey: keys.user,
rowKey: _user.id,
}
await client.updateEntity(updatedUser, "Merge")
return { ..._user, ...updatedUser }
},
async deleteUser(userId) {
try {
const user = await client.getEntity<AdapterUser>(keys.user, userId)
const { sessionToken } = await client.getEntity<AdapterSession>(
keys.sessionByUserId,
userId
)
const accounts = withoutKeys(
await client.getEntity<AdapterAccount>(keys.accountByUserId, userId)
)
const deleteAccounts = Object.keys(accounts).map((property) =>
client.deleteEntity(keys.account, `${accounts[property]}_${property}`)
)
await Promise.allSettled([
client.deleteEntity(keys.userByEmail, user.email),
client.deleteEntity(keys.user, userId),
client.deleteEntity(keys.session, sessionToken),
client.deleteEntity(keys.sessionByUserId, userId),
...deleteAccounts,
client.deleteEntity(keys.accountByUserId, userId),
])
return withoutKeys(user)
} catch {
return null
}
},
async linkAccount(account) {
try {
await client.createEntity({
...account,
partitionKey: keys.account,
rowKey: `${account.providerAccountId}_${account.provider}`,
})
await client.upsertEntity({
partitionKey: keys.accountByUserId,
rowKey: account.userId,
[account.provider]: account.providerAccountId,
})
return account
} catch {
return null
}
},
async unlinkAccount({ providerAccountId, provider }) {
const rowKey = `${providerAccountId}_${provider}`
const account = await client.getEntity<AdapterAccount>(
keys.account,
rowKey
)
await client.deleteEntity(keys.account, rowKey)
await client.deleteEntity(keys.accountByUserId, account.userId)
},
async createSession(session) {
await client.createEntity({
...session,
partitionKey: keys.session,
rowKey: session.sessionToken,
})
await client.upsertEntity({
partitionKey: keys.sessionByUserId,
rowKey: session.userId,
sessionToken: session.sessionToken,
})
return session
},
async getSessionAndUser(sessionToken) {
try {
const session = await client.getEntity<AdapterSession>(
keys.session,
sessionToken
)
if (session.expires.valueOf() < Date.now()) {
await client.deleteEntity(keys.session, sessionToken)
}
const user = await client.getEntity<AdapterUser>(
keys.user,
session.userId
)
return {
session: withoutKeys(session),
user: withoutKeys(user),
}
} catch {
return null
}
},
async updateSession(session) {
const _session = await client.getEntity<AdapterSession>(
keys.session,
session.sessionToken
)
const newSession = {
expires: session.expires ?? _session.expires,
}
await client.updateEntity({
...newSession,
partitionKey: keys.session,
rowKey: session.sessionToken,
})
return { ...withoutKeys(_session), ...newSession }
},
async deleteSession(sessionToken) {
try {
const session = await client.getEntity<AdapterSession>(
keys.session,
sessionToken
)
await Promise.allSettled([
client.deleteEntity(keys.session, sessionToken),
client.deleteEntity(keys.sessionByUserId, session.userId),
])
return withoutKeys(session)
} catch {
return null
}
},
async createVerificationToken(token) {
await client.createEntity({
...token,
partitionKey: keys.verificationToken,
rowKey: token.token,
})
return token
},
async useVerificationToken({ identifier, token }) {
try {
const tokenEntity = await client.getEntity<VerificationToken>(
keys.verificationToken,
token
)
if (tokenEntity.identifier !== identifier) {
return null
}
await client.deleteEntity(keys.verificationToken, token)
return withoutKeys(tokenEntity)
} catch {
return null
}
},
}
}

View File

@@ -0,0 +1,90 @@
import { runBasicTests } from "@auth/adapter-test"
import {
AzureNamedKeyCredential,
TableServiceClient,
TableClient,
} from "@azure/data-tables"
import { keys, TableStorageAdapter, withoutKeys } from "../src"
import type { AdapterUser, VerificationToken } from "@auth/core/adapters"
const testAccount = {
// default constants used by a dev instance of azurite
name: "devstoreaccount1",
key: "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==",
tableEndpoint: "http://127.0.0.1:10002/devstoreaccount1",
}
const authTableName = "authTest"
const credential = new AzureNamedKeyCredential(
testAccount.name,
testAccount.key
)
const authClient = new TableClient(
testAccount.tableEndpoint,
authTableName,
credential,
{ allowInsecureConnection: true }
)
runBasicTests({
adapter: TableStorageAdapter(authClient),
db: {
async connect() {
const serviceClient = new TableServiceClient(
testAccount.tableEndpoint,
credential,
{ allowInsecureConnection: true }
)
await serviceClient.createTable(authTableName)
},
async user(id) {
try {
const userById = await authClient.getEntity<AdapterUser>(keys.user, id)
return withoutKeys(userById)
} catch (e) {
console.error(e)
return null
}
},
async account(provider_providerAccountId) {
try {
const account = await authClient.getEntity(
keys.account,
`${provider_providerAccountId.providerAccountId}_${provider_providerAccountId.provider}`
)
return withoutKeys(account)
} catch {
return null
}
},
async session(sessionToken) {
try {
const session = await authClient.getEntity(keys.session, sessionToken)
return withoutKeys(session)
} catch {
return null
}
},
async verificationToken(identifier_token) {
try {
const verificationToken = await authClient.getEntity<VerificationToken>(
keys.verificationToken,
identifier_token.token
)
if (verificationToken.identifier !== identifier_token.identifier) {
return null
}
return withoutKeys(verificationToken)
} catch {
return null
}
},
},
})

View File

@@ -0,0 +1,34 @@
#!/usr/bin/env bash
CONTAINER_NAME=next-auth-azure-tables-test
JEST_WATCH=false
# Is the watch flag passed to the script?
while getopts w flag
do
case "${flag}" in
w) JEST_WATCH=true;;
*) continue;;
esac
done
# Start db
docker run -d -p 10002:10002 --name ${CONTAINER_NAME} mcr.microsoft.com/azure-storage/azurite azurite-table -l /workspace -d /workspace/debug.log --tableHost 0.0.0.0 --loose
echo "Waiting 3 sec for db to start..."
sleep 3
if $JEST_WATCH; then
# Run jest in watch mode
npx jest tests --watch
# Only stop the container after jest has been quit
docker stop "${CONTAINER_NAME}"
else
# Always stop container, but exit with 1 when tests are failing
if npx jest;then
docker stop ${CONTAINER_NAME}
else
docker stop ${CONTAINER_NAME} && exit 1
fi
fi

View File

@@ -0,0 +1,20 @@
{
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",
"isolatedModules": true,
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "node",
"outDir": ".",
"rootDir": "src",
"skipDefaultLibCheck": true,
"strictNullChecks": true,
"stripInternal": true,
"declarationMap": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["*.js", "*.d.ts"]
}

View File

@@ -2,7 +2,7 @@
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center", padding: 16}}>
* <p style={{fontWeight: "normal"}}>An official <a href="https://www.postgresql.org/">PostgreSQL</a> adapter for Auth.js / NextAuth.js.</p>
* <a href="https://www.postgresql.org/">
* <img style={{display: "block"}} src="/img/adapters/pg.svg" width="48" />
* <img style={{display: "block"}} src="/img/adapters/pg.png" width="48" />
* </a>
* </div>
*

View File

@@ -0,0 +1,28 @@
<p align="center">
<br/>
<a href="https://authjs.dev" target="_blank">
<img height="64px" src="https://authjs.dev/img/logo/logo-sm.png" />
</a>
<a href="https://surrealdb.com/" target="_blank">
<img height="64px" src="https://authjs.dev/img/adapters/surrealdb.png"/>
</a>
<h3 align="center"><b>Surreal DB Adapter</b> - NextAuth.js / Auth.js</a></h3>
<p align="center" style="align: center;">
<a href="https://npm.im/@auth/surrealdb-adapter">
<img src="https://img.shields.io/badge/TypeScript-blue?style=flat-square" alt="TypeScript" />
</a>
<a href="https://npm.im/@auth/surrealdb-adapter">
<img alt="npm" src="https://img.shields.io/npm/v/@auth/surrealdb-adapter?color=green&label=@auth/surrealdb-adapter&style=flat-square">
</a>
<a href="https://www.npmtrends.com/@auth/surrealdb-adapter">
<img src="https://img.shields.io/npm/dm/@auth/surrealdb-adapter?label=%20downloads&style=flat-square" alt="Downloads" />
</a>
<a href="https://github.com/nextauthjs/next-auth/stargazers">
<img src="https://img.shields.io/github/stars/nextauthjs/next-auth?style=flat-square" alt="Github Stars" />
</a>
</p>
</p>
---
Check out the documentation at [authjs.dev](https://authjs.dev/reference/adapter/surrealdb).

View File

@@ -0,0 +1,58 @@
{
"name": "@auth/surrealdb-adapter",
"version": "0.1.0",
"description": "SurrealDB adapter for next-auth.",
"homepage": "https://authjs.dev",
"repository": "https://github.com/nextauthjs/next-auth",
"bugs": {
"url": "https://github.com/nextauthjs/next-auth/issues"
},
"author": "Martin Schaer <martin@schaerweb.com>",
"contributors": [
"Thang Huu Vu <hi@thvu.dev>"
],
"type": "module",
"types": "./index.d.ts",
"files": [
"*.js",
"*.d.ts*",
"src"
],
"exports": {
".": {
"types": "./index.d.ts",
"import": "./index.js"
}
},
"license": "ISC",
"keywords": [
"next-auth",
"next.js",
"oauth",
"mongodb",
"adapter"
],
"private": false,
"publishConfig": {
"access": "public"
},
"scripts": {
"test": "./tests/test.sh",
"test:watch": "./tests/test.sh -w",
"build": "tsc"
},
"dependencies": {
"@auth/core": "workspace:*"
},
"peerDependencies": {
"surrealdb.js": "^0.9.0"
},
"devDependencies": {
"@auth/adapter-test": "workspace:*",
"@auth/tsconfig": "workspace:*",
"jest": "^27.4.3"
},
"jest": {
"preset": "@auth/adapter-test/jest"
}
}

View File

@@ -0,0 +1,366 @@
import Surreal, { ExperimentalSurrealHTTP } from "surrealdb.js"
import type {
Adapter,
AdapterUser,
AdapterAccount,
AdapterSession,
VerificationToken,
} from "@auth/core/adapters"
import type { ProviderType } from "@auth/core/providers"
type Document = Record<string, string | null | undefined> & { id: string }
export type UserDoc = Document & { email: string }
export type AccountDoc<T = string> = {
id: string
userId: T
refresh_token?: string
access_token?: string
type: Extract<ProviderType, "oauth" | "oidc" | "email">
provider: string
providerAccountId: string
expires_at?: number
}
export type SessionDoc<T = string> = Document & { userId: T }
const extractId = (surrealId: string) => surrealId.split(":")[1] ?? surrealId
// Convert DB object to AdapterUser
export const docToUser = (doc: UserDoc): AdapterUser => ({
...doc,
id: extractId(doc.id),
emailVerified: doc.emailVerified ? new Date(doc.emailVerified) : null,
})
// Convert DB object to AdapterAccount
export const docToAccount = (doc: AccountDoc) => {
const account: AdapterAccount = {
...doc,
id: extractId(doc.id),
userId: doc.userId ? extractId(doc.userId) : "",
}
return account
}
// Convert DB object to AdapterSession
export const docToSession = (
doc: SessionDoc<string | UserDoc>
): AdapterSession => ({
userId: extractId(
typeof doc.userId === "string" ? doc.userId : doc.userId.id
),
expires: new Date(doc.expires ?? ""),
sessionToken: doc.sessionToken ?? "",
})
// Convert AdapterUser to DB object
const userToDoc = (
user: Omit<AdapterUser, "id"> | Partial<AdapterUser>
): Omit<UserDoc, "id"> => {
const doc = {
...user,
emailVerified: user.emailVerified?.toISOString(),
}
return doc
}
// Convert AdapterAccount to DB object
const accountToDoc = (account: AdapterAccount): Omit<AccountDoc, "id"> => {
const doc = {
...account,
userId: `user:${account.userId}`,
}
return doc
}
// Convert AdapterSession to DB object
export const sessionToDoc = (
session: AdapterSession
): Omit<SessionDoc, "id"> => {
const doc = {
...session,
expires: session.expires.toISOString(),
}
return doc
}
export function SurrealDBAdapter<T>(
client: Promise<Surreal | ExperimentalSurrealHTTP<T>>
// options = {}
): Adapter {
return {
async createUser(user: Omit<AdapterUser, "id">) {
const surreal = await client
const doc = userToDoc(user)
const userDoc = await surreal.create<UserDoc, Omit<UserDoc, "id">>("user", doc)
if (userDoc.length) {
return docToUser(userDoc[0])
}
throw new Error("User not created")
},
async getUser(id: string) {
const surreal = await client
try {
const queryResult = await surreal.query<[UserDoc[]]>(
"SELECT * FROM $user",
{
user: `user:${id}`,
}
)
const doc = queryResult[0].result?.[0]
if (doc) {
return docToUser(doc)
}
} catch (e) { }
return null
},
async getUserByEmail(email: string) {
const surreal = await client
try {
const users = await surreal.query<[UserDoc[]]>(
`SELECT * FROM user WHERE email = $email`,
{ email }
)
const doc = users[0].result?.[0]
if (doc) return docToUser(doc)
} catch (e) { }
return null
},
async getUserByAccount({
providerAccountId,
provider,
}: Pick<AdapterAccount, "provider" | "providerAccountId">) {
const surreal = await client
try {
const users = await surreal.query<[AccountDoc<UserDoc>[]]>(
`SELECT userId
FROM account
WHERE providerAccountId = $providerAccountId
AND provider = $provider
FETCH userId`,
{ providerAccountId, provider }
)
const user = users[0].result?.[0]
?.userId
if (user) return docToUser(user)
} catch (e) { }
return null
},
async updateUser(user: Partial<AdapterUser>) {
const surreal = await client
const doc = { ...user, emailVerified: user.emailVerified?.toISOString(), id: undefined }
let updatedUser = await surreal.merge<UserDoc, Omit<UserDoc, "id">>(`user:${user.id}`, doc)
if (updatedUser.length) {
return docToUser(updatedUser[0])
} else {
throw new Error("User not updated")
}
},
async deleteUser(userId: string) {
const surreal = await client
// delete account
try {
const accounts = await surreal.query<[AccountDoc[]]>(
`SELECT *
FROM account
WHERE userId = $userId
LIMIT 1`,
{ userId: `user:${userId}` }
)
const account = accounts[0].result?.[0]
if (account) {
const accountId = extractId(account.id)
await surreal.delete(`account:${accountId}`)
}
} catch (e) { }
// delete session
try {
const sessions = await surreal.query<[SessionDoc[]]>(
`SELECT *
FROM session
WHERE userId = $userId
LIMIT 1`,
{ userId: `user:${userId}` }
)
const session = sessions[0].result?.[0]
if (session) {
const sessionId = extractId(session.id)
await surreal.delete(`session:${sessionId}`)
}
} catch (e) { }
// delete user
await surreal.delete(`user:${userId}`)
// TODO: put all 3 deletes inside a Promise all
},
async linkAccount(account: AdapterAccount) {
const surreal = await client
const doc = await surreal.create("account", accountToDoc(account))
return docToAccount(doc[0])
},
async unlinkAccount({
providerAccountId,
provider,
}: Pick<AdapterAccount, "provider" | "providerAccountId">) {
const surreal = await client
try {
const accounts = await surreal.query<[AccountDoc[]]>(
`SELECT *
FROM account
WHERE providerAccountId = $providerAccountId
AND provider = $provider
LIMIT 1`,
{ providerAccountId, provider }
)
const account = accounts[0].result?.[0]
if (account) {
const accountId = extractId(account.id)
await surreal.delete(`account:${accountId}`)
}
} catch (e) { }
},
async createSession({
sessionToken,
userId,
expires,
}: {
sessionToken: string
userId: string
expires: Date
}) {
const surreal = await client
const doc = {
sessionToken,
userId: `user:${userId}`,
expires,
}
const result = await surreal.create("session", doc)
return result[0] ?? null
},
async getSessionAndUser(sessionToken: string) {
const surreal = await client
try {
// Can't use limit 1 because it prevent userId to be fetched.
// Works setting limit to 2
const sessions = await surreal.query<[SessionDoc<UserDoc>[]]>(
`SELECT *
FROM session
WHERE sessionToken = $sessionToken
FETCH userId`,
{ sessionToken }
)
const session = sessions[0].result?.[0]
if (session) {
const userDoc = session.userId
if (!userDoc) return null
return {
user: docToUser(userDoc),
session: docToSession({
...session,
userId: userDoc.id,
}),
}
}
} catch (e) { }
return null
},
async updateSession(
session: Partial<AdapterSession> & Pick<AdapterSession, "sessionToken">
) {
const surreal = await client
try {
const sessions = await surreal.query<[SessionDoc[]]>(
`SELECT *
FROM session
WHERE sessionToken = $sessionToken
LIMIT 1`,
{ sessionToken: session.sessionToken }
)
const sessionDoc = sessions[0].result?.[0]
if (sessionDoc && session.expires) {
const sessionId = extractId(sessionDoc.id)
let updatedSession = await surreal.merge<SessionDoc, Omit<SessionDoc, "id">>(
`session:${sessionId}`,
sessionToDoc({
...sessionDoc,
...session,
userId: sessionDoc.userId,
expires: session.expires,
})
)
if (updatedSession.length) {
return docToSession(updatedSession[0])
} else {
return null
}
}
} catch (e) { }
return null
},
async deleteSession(sessionToken: string) {
const surreal = await client
try {
const sessions = await surreal.query<[SessionDoc[]]>(
`SELECT *
FROM session
WHERE sessionToken = $sessionToken
LIMIT 1`,
{ sessionToken }
)
const session = sessions[0].result?.[0]
if (session) {
const sessionId = extractId(session.id)
await surreal.delete(`session:${sessionId}`)
return
}
} catch (e) { }
},
async createVerificationToken({
identifier,
expires,
token,
}: VerificationToken) {
const surreal = await client
const doc = {
identifier,
expires,
token,
}
const result = await surreal.create("verification_token", doc)
return result[0] ?? null
},
async useVerificationToken({
identifier,
token,
}: {
identifier: string
token: string
}) {
const surreal = await client
try {
const tokens = await surreal.query<[{ identifier: string, expires: string, token: string, id: string }[]]>(
`SELECT *
FROM verification_token
WHERE identifier = $identifier
AND token = $verificationToken
LIMIT 1`,
{ identifier, verificationToken: token }
)
if (tokens.length && tokens[0].result) {
const vt = tokens[0].result[0]
if (vt) {
await surreal.delete(vt.id)
return {
identifier: vt.identifier,
expires: new Date(vt.expires),
token: vt.token,
}
}
} else { return null }
} catch (e) { }
return null
},
}
}

View File

@@ -0,0 +1,77 @@
import Surreal, { ExperimentalSurrealHTTP } from "surrealdb.js"
import {
SurrealDBAdapter,
docToUser,
docToAccount,
docToSession,
} from "../src/index"
import type { UserDoc, AccountDoc, SessionDoc } from "../src/index"
export const config = (
clientPromise: Promise<Surreal | ExperimentalSurrealHTTP<typeof fetch>>
) => ({
adapter: SurrealDBAdapter(clientPromise),
db: {
async disconnect() {
const surreal = await clientPromise
if (surreal.close) surreal.close()
},
async user(id: string) {
const surreal = await clientPromise
try {
const users = await surreal.query<[UserDoc[]]>("SELECT * FROM $user", {
user: `user:${id}`,
})
const user = users[0]
if (user.result?.[0] !== undefined) return docToUser(user.result[0])
} catch (e) {}
return null
},
async account({ provider, providerAccountId }) {
const surreal = await clientPromise
const accounts = await surreal.query<[AccountDoc[]]>(
`SELECT * FROM account WHERE provider = $provider AND providerAccountId = $providerAccountId`,
{ provider, providerAccountId }
)
const account = accounts[0]
if (account.result?.[0] !== undefined)
return docToAccount(account.result[0])
return null
},
async session(sessionToken: string) {
const surreal = await clientPromise
const sessions = await surreal.query<[SessionDoc[]]>(
`SELECT * FROM session WHERE sessionToken = $sessionToken`,
{ sessionToken }
)
const session = sessions[0].result?.[0]
if (session !== undefined) {
return docToSession(session)
}
return null
},
async verificationToken({ identifier, token }) {
const surreal = await clientPromise
const tokens = await surreal.query<
[{ identifier: string; expires: string; token: string; id: string }[]]
>(
`SELECT *
FROM verification_token
WHERE identifier = $identifier
AND token = $verificationToken
LIMIT 1`,
{ identifier, verificationToken: token }
)
const verificationToken = tokens[0].result?.[0]
if (verificationToken) {
return {
identifier: verificationToken.identifier,
expires: new Date(verificationToken.expires),
token: verificationToken.token,
}
}
return null
},
},
})

View File

@@ -0,0 +1,23 @@
import Surreal from "surrealdb.js"
import { runBasicTests } from "@auth/adapter-test"
import { config } from "./common"
const clientPromise = new Promise<Surreal>(async (resolve, reject) => {
const db = new Surreal();
try {
await db.connect('http://0.0.0.0:8000/rpc', {
ns: "test",
db: "test",
auth: {
user: "test",
pass: "test",
}
})
resolve(db)
} catch (e) {
reject(e)
}
})
runBasicTests(config(clientPromise))

View File

@@ -0,0 +1,27 @@
test("TODO: test rest", () => {
expect(true).toBe(true)
})
// import { ExperimentalSurrealHTTP } from "surrealdb.js"
// import { runBasicTests } from "@auth/adapter-test"
// import fetch from "node-fetch"
// import { config } from "./common"
// const clientPromise = new Promise<ExperimentalSurrealHTTP<typeof fetch>>(async (resolve, reject) => {
// try {
// const db = new ExperimentalSurrealHTTP("http://0.0.0.0:8000", {
// fetch,
// auth: {
// user: "test",
// pass: "test",
// },
// ns: "test",
// db: "test",
// })
// resolve(db)
// } catch (e) {
// reject(e)
// }
// })
// runBasicTests(config(clientPromise))

View File

@@ -0,0 +1,34 @@
#!/usr/bin/env bash
CONTAINER_NAME=next-auth-surrealdb-test
JEST_WATCH=false
# Is the watch flag passed to the script?
while getopts w flag
do
case "${flag}" in
w) JEST_WATCH=true;;
*) continue;;
esac
done
# Start db
docker run -d --rm -p 8000:8000 --name ${CONTAINER_NAME} surrealdb/surrealdb:latest start --log debug --user test --pass test memory
echo "Waiting 3 sec for db to start..."
sleep 3
if $JEST_WATCH; then
# Run jest in watch mode
npx jest tests --watch
# Only stop the container after jest has been quit
docker stop "${CONTAINER_NAME}"
else
# Always stop container, but exit with 1 when tests are failing
if npx jest;then
docker stop ${CONTAINER_NAME}
else
docker stop ${CONTAINER_NAME} && exit 1
fi
fi

View File

@@ -0,0 +1,25 @@
{
"extends": "@auth/tsconfig/tsconfig.base.json",
"compilerOptions": {
"allowJs": true,
"baseUrl": ".",
"isolatedModules": true,
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "node",
"outDir": ".",
"rootDir": "src",
"skipDefaultLibCheck": true,
"strictNullChecks": true,
"stripInternal": true,
"declarationMap": true,
"declaration": true
},
"include": [
"src/**/*"
],
"exclude": [
"*.js",
"*.d.ts",
]
}

View File

@@ -1,6 +1,6 @@
{
"name": "@auth/typeorm-adapter",
"version": "1.0.1",
"version": "1.0.2",
"description": "TypeORM adapter for Auth.js.",
"homepage": "https://authjs.dev/reference/adapter/typeorm",
"repository": "https://github.com/nextauthjs/next-auth",
@@ -85,4 +85,4 @@
"jest": {
"preset": "@auth/adapter-test/jest"
}
}
}

View File

@@ -42,15 +42,16 @@ export async function getManager(options: {
dataSource: string | DataSourceOptions
entities: Entities
}): Promise<EntityManager> {
const { dataSource, entities } = options
const config = {
...parseDataSourceConfig(dataSource),
entities: Object.values(entities),
if (!_dataSource) {
const { dataSource, entities } = options
const config = {
...parseDataSourceConfig(dataSource),
entities: Object.values(entities),
}
_dataSource = new DataSource(config)
}
if (!_dataSource) _dataSource = new DataSource(config)
const manager = _dataSource?.manager
if (!manager.connection.isInitialized) {
@@ -58,7 +59,7 @@ export async function getManager(options: {
}
if (process.env.NODE_ENV !== "production") {
await updateConnectionEntities(_dataSource, config.entities)
await updateConnectionEntities(_dataSource, Object.values(options.entities))
}
return manager
}

View File

@@ -1,6 +1,6 @@
{
"name": "@auth/core",
"version": "0.15.1",
"version": "0.15.2",
"description": "Authentication for the Web.",
"keywords": [
"authentication",

View File

@@ -118,7 +118,7 @@ export default function AzureADB2C(
return {
id: profile.sub,
name: profile.name,
email: profile.emails[0],
email: profile?.emails?.[0],
image: null,
}
},

668
pnpm-lock.yaml generated
View File

@@ -312,6 +312,25 @@ importers:
specifier: 4.0.0-next.6
version: 4.0.0-next.6(prettier@2.8.1)(typedoc@0.24.8)
packages/adapter-azure-tables:
dependencies:
'@auth/core':
specifier: workspace:*
version: link:../core
devDependencies:
'@auth/adapter-test':
specifier: workspace:*
version: link:../adapter-test
'@auth/tsconfig':
specifier: workspace:*
version: link:../tsconfig
'@azure/data-tables':
specifier: ^13.2.1
version: 13.2.2
jest:
specifier: ^27.4.3
version: 27.5.1
packages/adapter-d1:
dependencies:
'@auth/core':
@@ -709,6 +728,25 @@ importers:
specifier: ^27.4.3
version: 27.5.1
packages/adapter-surrealdb:
dependencies:
'@auth/core':
specifier: workspace:*
version: link:../core
surrealdb.js:
specifier: ^0.9.0
version: 0.9.0
devDependencies:
'@auth/adapter-test':
specifier: workspace:*
version: link:../adapter-test
'@auth/tsconfig':
specifier: workspace:*
version: link:../tsconfig
jest:
specifier: ^27.4.3
version: 27.5.1
packages/adapter-test:
devDependencies:
'@auth/core':
@@ -2526,6 +2564,31 @@ packages:
tslib: 2.5.2
dev: true
/@azure/core-xml@1.3.4:
resolution: {integrity: sha512-B1xI79Ur/u+KR69fGTcsMNj8KDjBSqAy0Ys6Byy4Qm1CqoUy7gCT5A7Pej0EBWRskuH6bpCwrAnosfmQEalkcg==}
engines: {node: '>=14.0.0'}
dependencies:
fast-xml-parser: 4.2.5
tslib: 2.5.2
dev: true
/@azure/data-tables@13.2.2:
resolution: {integrity: sha512-Dq2Aq0mMMF0BPzYQKdBY/OtO7VemP/foh6z+mJpUO1hRL+65C1rGQUJf20LJHotSyU8wHb4HJzOs+Z50GXSy1w==}
engines: {node: '>=14.0.0'}
dependencies:
'@azure/core-auth': 1.3.2
'@azure/core-client': 1.6.0
'@azure/core-paging': 1.3.0
'@azure/core-rest-pipeline': 1.9.0
'@azure/core-tracing': 1.0.1
'@azure/core-xml': 1.3.4
'@azure/logger': 1.0.3
tslib: 2.5.2
uuid: 8.3.2
transitivePeerDependencies:
- supports-color
dev: true
/@azure/identity@1.5.2(debug@4.3.4):
resolution: {integrity: sha512-vqyeRbd2i0h9F4mqW5JbkP1xfabqKQ21l/81osKhpOQ2LtwaJW6nw4+0PsVYnxcbPHFCIZt6EWAk74a3OGYZJA==}
engines: {node: '>=12.0.0'}
@@ -8942,30 +9005,6 @@ packages:
slash: 3.0.0
dev: true
/@jest/console@29.2.1:
resolution: {integrity: sha512-MF8Adcw+WPLZGBiNxn76DOuczG3BhODTcMlDCA4+cFi41OkaY/lyI0XUUhi73F88Y+7IHoGmD80pN5CtxQUdSw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.5.0
'@types/node': 17.0.45
chalk: 4.1.2
jest-message-util: 29.5.0
jest-util: 29.5.0
slash: 3.0.0
dev: true
/@jest/console@29.3.1:
resolution: {integrity: sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.5.0
'@types/node': 17.0.45
chalk: 4.1.2
jest-message-util: 29.5.0
jest-util: 29.5.0
slash: 3.0.0
dev: true
/@jest/console@29.5.0:
resolution: {integrity: sha512-NEpkObxPwyw/XxZVLPmAGKE89IQRp4puc6IQRPru6JKd1M3fW9v1xM1AnzIJE65hbCkzQAdnL8P47e9hzhiYLQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -9115,10 +9154,10 @@ packages:
node-notifier:
optional: true
dependencies:
'@jest/console': 29.2.1
'@jest/reporters': 29.3.0
'@jest/console': 29.5.0
'@jest/reporters': 29.5.0
'@jest/test-result': 29.5.0
'@jest/transform': 29.3.0
'@jest/transform': 29.5.0
'@jest/types': 29.5.0
'@types/node': 17.0.45
ansi-escapes: 4.3.2
@@ -9126,19 +9165,19 @@ packages:
ci-info: 3.7.0
exit: 0.1.2
graceful-fs: 4.2.10
jest-changed-files: 29.2.0
jest-changed-files: 29.5.0
jest-config: 29.5.0(@types/node@17.0.45)
jest-haste-map: 29.3.0
jest-message-util: 29.2.1
jest-regex-util: 29.2.0
jest-resolve: 29.3.0
jest-resolve-dependencies: 29.3.0
jest-runner: 29.3.0
jest-runtime: 29.3.0
jest-snapshot: 29.3.0
jest-haste-map: 29.5.0
jest-message-util: 29.5.0
jest-regex-util: 29.4.3
jest-resolve: 29.5.0
jest-resolve-dependencies: 29.5.0
jest-runner: 29.5.0
jest-runtime: 29.5.0
jest-snapshot: 29.5.0
jest-util: 29.5.0
jest-validate: 29.5.0
jest-watcher: 29.2.2
jest-watcher: 29.5.0
micromatch: 4.0.5
pretty-format: 29.2.1
slash: 3.0.0
@@ -9157,10 +9196,10 @@ packages:
node-notifier:
optional: true
dependencies:
'@jest/console': 29.3.1
'@jest/reporters': 29.3.1
'@jest/console': 29.5.0
'@jest/reporters': 29.5.0
'@jest/test-result': 29.5.0
'@jest/transform': 29.3.1
'@jest/transform': 29.5.0
'@jest/types': 29.5.0
'@types/node': 17.0.45
ansi-escapes: 4.3.2
@@ -9168,19 +9207,19 @@ packages:
ci-info: 3.7.0
exit: 0.1.2
graceful-fs: 4.2.10
jest-changed-files: 29.2.0
jest-changed-files: 29.5.0
jest-config: 29.5.0(@types/node@17.0.45)
jest-haste-map: 29.3.1
jest-message-util: 29.3.1
jest-regex-util: 29.2.0
jest-resolve: 29.3.1
jest-resolve-dependencies: 29.3.1
jest-runner: 29.3.1
jest-runtime: 29.3.1
jest-snapshot: 29.3.1
jest-haste-map: 29.5.0
jest-message-util: 29.5.0
jest-regex-util: 29.4.3
jest-resolve: 29.5.0
jest-resolve-dependencies: 29.5.0
jest-runner: 29.5.0
jest-runtime: 29.5.0
jest-snapshot: 29.5.0
jest-util: 29.5.0
jest-validate: 29.5.0
jest-watcher: 29.3.1
jest-watcher: 29.5.0
micromatch: 4.0.5
pretty-format: 29.3.1
slash: 3.0.0
@@ -9263,10 +9302,10 @@ packages:
resolution: {integrity: sha512-9auVQ2GzQ7nrU+lAr8KyY838YahElTX9HVjbQPPS2XjlxQ+na18G113OoBhyBGBtD6ZnO/SrUy5WR8EzOj1/Uw==}
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
dependencies:
'@jest/fake-timers': 28.1.1
'@jest/fake-timers': 28.1.3
'@jest/types': 28.1.3
'@types/node': 17.0.45
jest-mock: 28.1.1
jest-mock: 28.1.3
dev: true
/@jest/environment@28.1.3:
@@ -9362,7 +9401,7 @@ packages:
'@sinonjs/fake-timers': 9.1.2
'@types/node': 17.0.45
jest-message-util: 28.1.3
jest-mock: 28.1.1
jest-mock: 28.1.3
jest-util: 28.1.3
dev: true
@@ -9541,80 +9580,6 @@ packages:
- supports-color
dev: true
/@jest/reporters@29.3.0:
resolution: {integrity: sha512-MV76tB3Kd80vcv2yMDZfQpMkwkHaY9hlvVhCtHXkVRCWwN+SX3EOmCdX8pT/X4Xh+NusA7l2Rc3yhx4q5p3+Fg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
peerDependenciesMeta:
node-notifier:
optional: true
dependencies:
'@bcoe/v8-coverage': 0.2.3
'@jest/console': 29.5.0
'@jest/test-result': 29.5.0
'@jest/transform': 29.5.0
'@jest/types': 29.5.0
'@jridgewell/trace-mapping': 0.3.17
'@types/node': 17.0.45
chalk: 4.1.2
collect-v8-coverage: 1.0.1
exit: 0.1.2
glob: 7.2.3
graceful-fs: 4.2.10
istanbul-lib-coverage: 3.2.0
istanbul-lib-instrument: 5.2.0
istanbul-lib-report: 3.0.0
istanbul-lib-source-maps: 4.0.1
istanbul-reports: 3.1.4
jest-message-util: 29.5.0
jest-util: 29.5.0
jest-worker: 29.5.0
slash: 3.0.0
string-length: 4.0.2
strip-ansi: 6.0.1
v8-to-istanbul: 9.0.1
transitivePeerDependencies:
- supports-color
dev: true
/@jest/reporters@29.3.1:
resolution: {integrity: sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
peerDependenciesMeta:
node-notifier:
optional: true
dependencies:
'@bcoe/v8-coverage': 0.2.3
'@jest/console': 29.5.0
'@jest/test-result': 29.5.0
'@jest/transform': 29.5.0
'@jest/types': 29.5.0
'@jridgewell/trace-mapping': 0.3.17
'@types/node': 17.0.45
chalk: 4.1.2
collect-v8-coverage: 1.0.1
exit: 0.1.2
glob: 7.2.3
graceful-fs: 4.2.10
istanbul-lib-coverage: 3.2.0
istanbul-lib-instrument: 5.2.0
istanbul-lib-report: 3.0.0
istanbul-lib-source-maps: 4.0.1
istanbul-reports: 3.1.4
jest-message-util: 29.5.0
jest-util: 29.5.0
jest-worker: 29.5.0
slash: 3.0.0
string-length: 4.0.2
strip-ansi: 6.0.1
v8-to-istanbul: 9.0.1
transitivePeerDependencies:
- supports-color
dev: true
/@jest/reporters@29.5.0:
resolution: {integrity: sha512-D05STXqj/M8bP9hQNSICtPqz97u7ffGzZu+9XLucXhkOFBqKcXe04JLZOgIekOxdb73MAoBUFnqvf7MCpKk5OA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -9860,52 +9825,6 @@ packages:
- supports-color
dev: true
/@jest/transform@29.3.0:
resolution: {integrity: sha512-4T8h61ItCakAlJkdYa7XVWP3r39QldlCeOSNmRpiJisi5PrrlzwZdpJDIH13ZZjh+MlSPQ2cq8YbUs3TuH+tRA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/core': 7.22.1
'@jest/types': 29.5.0
'@jridgewell/trace-mapping': 0.3.17
babel-plugin-istanbul: 6.1.1
chalk: 4.1.2
convert-source-map: 2.0.0
fast-json-stable-stringify: 2.1.0
graceful-fs: 4.2.10
jest-haste-map: 29.5.0
jest-regex-util: 29.4.3
jest-util: 29.5.0
micromatch: 4.0.5
pirates: 4.0.5
slash: 3.0.0
write-file-atomic: 4.0.2
transitivePeerDependencies:
- supports-color
dev: true
/@jest/transform@29.3.1:
resolution: {integrity: sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/core': 7.22.1
'@jest/types': 29.5.0
'@jridgewell/trace-mapping': 0.3.17
babel-plugin-istanbul: 6.1.1
chalk: 4.1.2
convert-source-map: 2.0.0
fast-json-stable-stringify: 2.1.0
graceful-fs: 4.2.10
jest-haste-map: 29.5.0
jest-regex-util: 29.4.3
jest-util: 29.5.0
micromatch: 4.0.5
pirates: 4.0.5
slash: 3.0.0
write-file-atomic: 4.0.2
transitivePeerDependencies:
- supports-color
dev: true
/@jest/transform@29.5.0:
resolution: {integrity: sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -18578,7 +18497,7 @@ packages:
'@jest/expect-utils': 29.3.1
jest-get-type: 29.2.0
jest-matcher-utils: 29.3.1
jest-message-util: 29.3.1
jest-message-util: 29.5.0
jest-util: 29.5.0
dev: true
@@ -18810,7 +18729,6 @@ packages:
dependencies:
strnum: 1.0.5
dev: true
optional: true
/fastq@1.15.0:
resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
@@ -21179,7 +21097,7 @@ packages:
/isomorphic-fetch@3.0.0:
resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==}
dependencies:
node-fetch: 2.6.7
node-fetch: 2.6.9
whatwg-fetch: 3.6.2
transitivePeerDependencies:
- encoding
@@ -21275,14 +21193,6 @@ packages:
throat: 6.0.1
dev: true
/jest-changed-files@29.2.0:
resolution: {integrity: sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
execa: 5.1.1
p-limit: 3.1.0
dev: true
/jest-changed-files@29.5.0:
resolution: {integrity: sha512-IFG34IUMUaNBIxjQXF/iu7g6EcdMrGRRxaUSw92I/2g2YC6vCdTltl4nHvt7Ci5nSJwXIkCu8Ka1DKF+X7Z1Ag==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -21993,44 +21903,6 @@ packages:
fsevents: 2.3.2
dev: true
/jest-haste-map@29.3.0:
resolution: {integrity: sha512-ugdLIreycMRRg3+6AjiExECmuFI2D9PS+BmNU7eGvBt3fzVMKybb9USAZXN6kw4Q6Mn8DSK+7OFCloY2rN820Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.5.0
'@types/graceful-fs': 4.1.5
'@types/node': 17.0.45
anymatch: 3.1.3
fb-watchman: 2.0.1
graceful-fs: 4.2.10
jest-regex-util: 29.4.3
jest-util: 29.5.0
jest-worker: 29.5.0
micromatch: 4.0.5
walker: 1.0.8
optionalDependencies:
fsevents: 2.3.2
dev: true
/jest-haste-map@29.3.1:
resolution: {integrity: sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.5.0
'@types/graceful-fs': 4.1.5
'@types/node': 17.0.45
anymatch: 3.1.3
fb-watchman: 2.0.1
graceful-fs: 4.2.10
jest-regex-util: 29.4.3
jest-util: 29.5.0
jest-worker: 29.5.0
micromatch: 4.0.5
walker: 1.0.8
optionalDependencies:
fsevents: 2.3.2
dev: true
/jest-haste-map@29.5.0:
resolution: {integrity: sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -22250,36 +22122,6 @@ packages:
stack-utils: 2.0.5
dev: true
/jest-message-util@29.2.1:
resolution: {integrity: sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/code-frame': 7.21.4
'@jest/types': 29.5.0
'@types/stack-utils': 2.0.1
chalk: 4.1.2
graceful-fs: 4.2.10
micromatch: 4.0.5
pretty-format: 29.5.0
slash: 3.0.0
stack-utils: 2.0.5
dev: true
/jest-message-util@29.3.1:
resolution: {integrity: sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/code-frame': 7.21.4
'@jest/types': 29.5.0
'@types/stack-utils': 2.0.1
chalk: 4.1.2
graceful-fs: 4.2.10
micromatch: 4.0.5
pretty-format: 29.5.0
slash: 3.0.0
stack-utils: 2.0.5
dev: true
/jest-message-util@29.5.0:
resolution: {integrity: sha512-Kijeg9Dag6CKtIDA7O21zNTACqD5MD/8HfIV8pdD94vFyFuer52SigdC3IQMhab3vACxXMiFk+yMHNdbqtyTGA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -22372,30 +22214,6 @@ packages:
jest-resolve: 28.1.1
dev: true
/jest-pnp-resolver@1.2.2(jest-resolve@29.3.0):
resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==}
engines: {node: '>=6'}
peerDependencies:
jest-resolve: '*'
peerDependenciesMeta:
jest-resolve:
optional: true
dependencies:
jest-resolve: 29.3.0
dev: true
/jest-pnp-resolver@1.2.2(jest-resolve@29.3.1):
resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==}
engines: {node: '>=6'}
peerDependencies:
jest-resolve: '*'
peerDependenciesMeta:
jest-resolve:
optional: true
dependencies:
jest-resolve: 29.3.1
dev: true
/jest-pnp-resolver@1.2.2(jest-resolve@29.5.0):
resolution: {integrity: sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==}
engines: {node: '>=6'}
@@ -22423,11 +22241,6 @@ packages:
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
dev: true
/jest-regex-util@29.2.0:
resolution: {integrity: sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dev: true
/jest-regex-util@29.4.3:
resolution: {integrity: sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -22465,26 +22278,6 @@ packages:
- supports-color
dev: true
/jest-resolve-dependencies@29.3.0:
resolution: {integrity: sha512-ykSbDbWmIaHprOBig57AExw7i6Fj0y69M6baiAd75Ivx1UMQt4wsM6A+SNqIhycV6Zy8XV3L40Ac3HYSrDSq7w==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
jest-regex-util: 29.4.3
jest-snapshot: 29.5.0
transitivePeerDependencies:
- supports-color
dev: true
/jest-resolve-dependencies@29.3.1:
resolution: {integrity: sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
jest-regex-util: 29.4.3
jest-snapshot: 29.5.0
transitivePeerDependencies:
- supports-color
dev: true
/jest-resolve-dependencies@29.5.0:
resolution: {integrity: sha512-sjV3GFr0hDJMBpYeUuGduP+YeCRbd7S/ck6IvL3kQ9cpySYKqcqhdLLC2rFwrcL7tz5vYibomBrsFYWkIGGjOg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -22540,36 +22333,6 @@ packages:
slash: 3.0.0
dev: true
/jest-resolve@29.3.0:
resolution: {integrity: sha512-xH6C6loDlOWEWHdCgioLDlbpmsolNdNsV/UR35ChuK217x0ttHuhyEPdh5wa6CTQ/Eq4OGW2/EZTlh0ay5aojQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
chalk: 4.1.2
graceful-fs: 4.2.10
jest-haste-map: 29.5.0
jest-pnp-resolver: 1.2.2(jest-resolve@29.3.0)
jest-util: 29.5.0
jest-validate: 29.5.0
resolve: 1.22.1
resolve.exports: 1.1.0
slash: 3.0.0
dev: true
/jest-resolve@29.3.1:
resolution: {integrity: sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
chalk: 4.1.2
graceful-fs: 4.2.10
jest-haste-map: 29.5.0
jest-pnp-resolver: 1.2.2(jest-resolve@29.3.1)
jest-util: 29.5.0
jest-validate: 29.5.0
resolve: 1.22.1
resolve.exports: 1.1.0
slash: 3.0.0
dev: true
/jest-resolve@29.5.0:
resolution: {integrity: sha512-1TzxJ37FQq7J10jPtQjcc+MkCkE3GBpBecsSUWJ0qZNJpmg6m0D9/7II03yJulm3H/fvVjgqLh/k2eYg+ui52w==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -22678,64 +22441,6 @@ packages:
- supports-color
dev: true
/jest-runner@29.3.0:
resolution: {integrity: sha512-E/ROzAVj7gy44FvIe+Tbz0xGWG1sa8WLkhUg/hsXHewPC0Z48kqWySdfYRtXkB7RmMn4OcWE+hIBfsRAMVV+sQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/console': 29.5.0
'@jest/environment': 29.5.0
'@jest/test-result': 29.5.0
'@jest/transform': 29.5.0
'@jest/types': 29.5.0
'@types/node': 17.0.45
chalk: 4.1.2
emittery: 0.13.1
graceful-fs: 4.2.10
jest-docblock: 29.4.3
jest-environment-node: 29.5.0
jest-haste-map: 29.5.0
jest-leak-detector: 29.5.0
jest-message-util: 29.5.0
jest-resolve: 29.5.0
jest-runtime: 29.5.0
jest-util: 29.5.0
jest-watcher: 29.5.0
jest-worker: 29.5.0
p-limit: 3.1.0
source-map-support: 0.5.13
transitivePeerDependencies:
- supports-color
dev: true
/jest-runner@29.3.1:
resolution: {integrity: sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/console': 29.5.0
'@jest/environment': 29.5.0
'@jest/test-result': 29.5.0
'@jest/transform': 29.5.0
'@jest/types': 29.5.0
'@types/node': 17.0.45
chalk: 4.1.2
emittery: 0.13.1
graceful-fs: 4.2.10
jest-docblock: 29.4.3
jest-environment-node: 29.5.0
jest-haste-map: 29.5.0
jest-leak-detector: 29.5.0
jest-message-util: 29.5.0
jest-resolve: 29.5.0
jest-runtime: 29.5.0
jest-util: 29.5.0
jest-watcher: 29.5.0
jest-worker: 29.5.0
p-limit: 3.1.0
source-map-support: 0.5.13
transitivePeerDependencies:
- supports-color
dev: true
/jest-runner@29.5.0:
resolution: {integrity: sha512-m7b6ypERhFghJsslMLhydaXBiLf7+jXy8FwGRHO3BGV1mcQpPbwiqiKUR2zU2NJuNeMenJmlFZCsIqzJCTeGLQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -22865,66 +22570,6 @@ packages:
- supports-color
dev: true
/jest-runtime@29.3.0:
resolution: {integrity: sha512-ufgX/hbpa7MLnjWRW82T5mVF73FBk3W38dGCLPXWtYZ5Zr1ZFh8QnaAtITKJt0p3kGXR8ZqlIjadSiBTk/QJ/A==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/environment': 29.5.0
'@jest/fake-timers': 29.5.0
'@jest/globals': 29.5.0
'@jest/source-map': 29.4.3
'@jest/test-result': 29.5.0
'@jest/transform': 29.5.0
'@jest/types': 29.5.0
'@types/node': 17.0.45
chalk: 4.1.2
cjs-module-lexer: 1.2.2
collect-v8-coverage: 1.0.1
glob: 7.2.3
graceful-fs: 4.2.10
jest-haste-map: 29.5.0
jest-message-util: 29.5.0
jest-mock: 29.5.0
jest-regex-util: 29.4.3
jest-resolve: 29.5.0
jest-snapshot: 29.5.0
jest-util: 29.5.0
slash: 3.0.0
strip-bom: 4.0.0
transitivePeerDependencies:
- supports-color
dev: true
/jest-runtime@29.3.1:
resolution: {integrity: sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/environment': 29.5.0
'@jest/fake-timers': 29.5.0
'@jest/globals': 29.5.0
'@jest/source-map': 29.4.3
'@jest/test-result': 29.5.0
'@jest/transform': 29.5.0
'@jest/types': 29.5.0
'@types/node': 17.0.45
chalk: 4.1.2
cjs-module-lexer: 1.2.2
collect-v8-coverage: 1.0.1
glob: 7.2.3
graceful-fs: 4.2.10
jest-haste-map: 29.5.0
jest-message-util: 29.5.0
jest-mock: 29.5.0
jest-regex-util: 29.4.3
jest-resolve: 29.5.0
jest-snapshot: 29.5.0
jest-util: 29.5.0
slash: 3.0.0
strip-bom: 4.0.0
transitivePeerDependencies:
- supports-color
dev: true
/jest-runtime@29.5.0:
resolution: {integrity: sha512-1Hr6Hh7bAgXQP+pln3homOiEZtCDZFqwmle7Ew2j8OlbkIu6uE3Y/etJQG8MLQs3Zy90xrp2C0BRrtPHG4zryw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -23056,70 +22701,6 @@ packages:
- supports-color
dev: true
/jest-snapshot@29.3.0:
resolution: {integrity: sha512-+4mX3T8XI3ABbZFzBd/AM74mfwOb6gMpYVFNTc0Cgg2F2fGYvHii8D6jWWka99a3wyNFmni3ov8meEVTF8n13Q==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/core': 7.22.1
'@babel/generator': 7.22.3
'@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.22.1)
'@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.22.1)
'@babel/traverse': 7.22.4
'@babel/types': 7.22.4
'@jest/expect-utils': 29.5.0
'@jest/transform': 29.5.0
'@jest/types': 29.5.0
'@types/babel__traverse': 7.17.1
'@types/prettier': 2.6.3
babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.1)
chalk: 4.1.2
expect: 29.5.0
graceful-fs: 4.2.10
jest-diff: 29.5.0
jest-get-type: 29.4.3
jest-haste-map: 29.5.0
jest-matcher-utils: 29.5.0
jest-message-util: 29.5.0
jest-util: 29.5.0
natural-compare: 1.4.0
pretty-format: 29.5.0
semver: 7.5.1
transitivePeerDependencies:
- supports-color
dev: true
/jest-snapshot@29.3.1:
resolution: {integrity: sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@babel/core': 7.22.1
'@babel/generator': 7.22.3
'@babel/plugin-syntax-jsx': 7.18.6(@babel/core@7.22.1)
'@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.22.1)
'@babel/traverse': 7.22.4
'@babel/types': 7.22.4
'@jest/expect-utils': 29.5.0
'@jest/transform': 29.5.0
'@jest/types': 29.5.0
'@types/babel__traverse': 7.17.1
'@types/prettier': 2.6.3
babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.1)
chalk: 4.1.2
expect: 29.5.0
graceful-fs: 4.2.10
jest-diff: 29.5.0
jest-get-type: 29.4.3
jest-haste-map: 29.5.0
jest-matcher-utils: 29.5.0
jest-message-util: 29.5.0
jest-util: 29.5.0
natural-compare: 1.4.0
pretty-format: 29.5.0
semver: 7.5.1
transitivePeerDependencies:
- supports-color
dev: true
/jest-snapshot@29.5.0:
resolution: {integrity: sha512-x7Wolra5V0tt3wRs3/ts3S6ciSQVypgGQlJpz2rsdQYoUKxMxPNaoHMGJN6qAuPJqS+2iQ1ZUn5kl7HCyls84g==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -23329,34 +22910,6 @@ packages:
string-length: 4.0.2
dev: true
/jest-watcher@29.2.2:
resolution: {integrity: sha512-j2otfqh7mOvMgN2WlJ0n7gIx9XCMWntheYGlBK7+5g3b1Su13/UAK7pdKGyd4kDlrLwtH2QPvRv5oNIxWvsJ1w==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/test-result': 29.5.0
'@jest/types': 29.5.0
'@types/node': 17.0.45
ansi-escapes: 4.3.2
chalk: 4.1.2
emittery: 0.13.1
jest-util: 29.5.0
string-length: 4.0.2
dev: true
/jest-watcher@29.3.1:
resolution: {integrity: sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/test-result': 29.5.0
'@jest/types': 29.5.0
'@types/node': 17.0.45
ansi-escapes: 4.3.2
chalk: 4.1.2
emittery: 0.13.1
jest-util: 29.5.0
string-length: 4.0.2
dev: true
/jest-watcher@29.5.0:
resolution: {integrity: sha512-KmTojKcapuqYrKDpRwfqcQ3zjMlwu27SYext9pt4GlF5FUgB+7XE1mcCnSm6a4uUpFyQIkb6ZhzZvHl+jiBCiA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -23721,7 +23274,7 @@ packages:
whatwg-encoding: 2.0.0
whatwg-mimetype: 3.0.0
whatwg-url: 10.0.0
ws: 8.11.0
ws: 8.14.1
xml-name-validator: 4.0.0
transitivePeerDependencies:
- bufferutil
@@ -25405,7 +24958,7 @@ packages:
inquirer: 8.2.4
is-node-process: 1.0.1
js-levenshtein: 1.1.6
node-fetch: 2.6.7
node-fetch: 2.6.9
outvariant: 1.3.0
path-to-regexp: 6.2.1
statuses: 2.0.1
@@ -30195,7 +29748,6 @@ packages:
resolution: {integrity: sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==}
requiresBuild: true
dev: true
optional: true
/stubs@3.0.0:
resolution: {integrity: sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==}
@@ -30363,6 +29915,16 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
/surrealdb.js@0.9.0:
resolution: {integrity: sha512-JV1lSzeSF4GftfxSvrOd0fDAw0AwRTSTsn+smp4BzhVuvcfJH/2zceEMwsMLzQcUao386pq4xk5JKoieayFJqQ==}
dependencies:
unws: 0.2.4(ws@8.14.1)
ws: 8.14.1
transitivePeerDependencies:
- bufferutil
- utf-8-validate
dev: false
/svelte-check@2.10.1(svelte@3.54.0):
resolution: {integrity: sha512-uscZovyuOPA89NuAkc4vO27mzx//2wFBNtwTsgYcNs7JwaFpJ2TqBawQ/avG7gkieYQ3QXqFUggJZ+s51fQGDQ==}
hasBin: true
@@ -31806,6 +31368,15 @@ packages:
engines: {node: '>=8'}
dev: false
/unws@0.2.4(ws@8.14.1):
resolution: {integrity: sha512-/N1ajiqrSp0A/26/LBg7r10fOcPtGXCqJRJ61sijUFoGZMr6ESWGYn7i0cwr7fR7eEECY5HsitqtjGHDZLAu2w==}
engines: {node: '>=16.14.0'}
peerDependencies:
ws: '*'
dependencies:
ws: 8.14.1
dev: false
/unzipper@0.10.11:
resolution: {integrity: sha512-+BrAq2oFqWod5IESRjL3S8baohbevGcVA+teAIOYWM3pDVdseogqbzhhvvmiyQrUNKFUnDMtELW3X8ykbyDCJw==}
dependencies:
@@ -32483,7 +32054,7 @@ packages:
spdy: 4.0.2
webpack: 5.75.0
webpack-dev-middleware: 5.3.3(webpack@5.75.0)
ws: 8.11.0
ws: 8.14.1
transitivePeerDependencies:
- bufferutil
- debug
@@ -32827,18 +32398,17 @@ packages:
utf-8-validate:
optional: true
/ws@8.11.0:
resolution: {integrity: sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==}
/ws@8.14.1:
resolution: {integrity: sha512-4OOseMUq8AzRBI/7SLMUwO+FEDnguetSk7KMb1sHwvF2w2Wv5Hoj0nlifx8vtGsftE/jWHojPy8sMMzYLJ2G/A==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: ^5.0.2
utf-8-validate: '>=5.0.2'
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
dev: true
/xdg-basedir@4.0.0:
resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==}

View File

@@ -60,11 +60,12 @@
"@auth/prisma-adapter#build",
"@auth/solid-start#build",
"@auth/sveltekit#build",
"@auth/azure-tables-adapter#build",
"@auth/d1-adapter#build",
"@auth/edgedb-adapter#build",
"@auth/dgraph-adapter#build",
"@auth/drizzle-adapter#build",
"@auth/dynamodb-adapter#build",
"@auth/edgedb-adapter#build",
"@auth/fauna-adapter#build",
"@auth/firebase-adapter#build",
"@auth/kysely-adapter#build",
@@ -75,6 +76,7 @@
"@auth/pouchdb-adapter#build",
"@auth/sequelize-adapter#build",
"@auth/supabase-adapter#build",
"@auth/surrealdb-adapter#build",
"@auth/typeorm-adapter#build",
"@auth/upstash-redis-adapter#build",
"@auth/xata-adapter#build",
@@ -88,6 +90,9 @@
"@auth/prisma-adapter#build",
"@auth/solid-start#build",
"@auth/sveltekit#build",
"@auth/azure-tables-adapter#build",
"@auth/d1-adapter#build",
"@auth/edgedb-adapter#build",
"@auth/dgraph-adapter#build",
"@auth/drizzle-adapter#build",
"@auth/dynamodb-adapter#build",
@@ -97,9 +102,11 @@
"@auth/mikro-orm-adapter#build",
"@auth/mongodb-adapter#build",
"@auth/neo4j-adapter#build",
"@auth/pg-adapter#build",
"@auth/pouchdb-adapter#build",
"@auth/sequelize-adapter#build",
"@auth/supabase-adapter#build",
"@auth/surrealdb-adapter#build",
"@auth/typeorm-adapter#build",
"@auth/upstash-redis-adapter#build",
"@auth/xata-adapter#build",