diff --git a/.changeset/sweet-socks-juggle.md b/.changeset/sweet-socks-juggle.md
deleted file mode 100644
index fd48e574d7..0000000000
--- a/.changeset/sweet-socks-juggle.md
+++ /dev/null
@@ -1,11 +0,0 @@
----
-"@blitzjs/next": major
-"@blitzjs/rpc": major
-"blitz": major
-"@blitzjs/auth": major
-"@blitzjs/codemod": major
-"@blitzjs/config": major
-"@blitzjs/generator": major
----
-
-TODO: Upgrade @tanstack/react-query to v5.1.1
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 113ff0ee39..d116b8cfad 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -148,7 +148,7 @@ jobs:
- name: Install playwright
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
run: |
- pnpx playwright@1.49.1 install --with-deps
+ pnpx playwright@1.28.0 install --with-deps
shell: bash
- name: Build
diff --git a/.github/workflows/pr-release.yml b/.github/workflows/pr-release.yml
index e25e971e0c..280f622969 100644
--- a/.github/workflows/pr-release.yml
+++ b/.github/workflows/pr-release.yml
@@ -29,7 +29,7 @@ jobs:
run: |
pr="$(gh api repos/${{ github.repository }}/pulls/${{ github.event.issue.number }})"
head_sha="$(echo "$pr" | jq -r .head.sha)"
-
+
echo "head_sha=$head_sha" >> $GITHUB_OUTPUT
- uses: actions/checkout@v4
@@ -39,7 +39,7 @@ jobs:
- name: Setup PNPM
uses: pnpm/action-setup@646cdf48217256a3d0b80361c5a50727664284f2
with:
- version: 8.6.6
+ version: 8.9.0
- name: Setup Node
uses: actions/setup-node@v4
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index c08e988015..5931008bf4 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -37,7 +37,7 @@ jobs:
- name: Pre-publish
uses: pnpm/action-setup@646cdf48217256a3d0b80361c5a50727664284f2
with:
- version: 8.6.6
+ version: 8.9.0
- run: pnpm install
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
diff --git a/apps/next13/package.json b/apps/next13/package.json
index 4a95146f37..c5e9021482 100644
--- a/apps/next13/package.json
+++ b/apps/next13/package.json
@@ -19,7 +19,7 @@
"@hookform/error-message": "2.0.0",
"@hookform/resolvers": "2.9.10",
"@prisma/client": "^4.5.0",
- "@tanstack/react-query": "5.51.1",
+ "@tanstack/react-query": "4.0.10",
"blitz": "2.2.1",
"flatted": "3.2.7",
"next": "15.0.1",
diff --git a/apps/next13/src/app/loading.tsx b/apps/next13/src/app/loading.tsx
deleted file mode 100644
index 2a20138001..0000000000
--- a/apps/next13/src/app/loading.tsx
+++ /dev/null
@@ -1,4 +0,0 @@
-export default function Loading() {
- // You can add any UI inside Loading, including a Skeleton.
- return "Loading..."
-}
diff --git a/apps/next13/src/app/react-query.tsx b/apps/next13/src/app/react-query.tsx
index c12a61b4da..aeadd4868d 100644
--- a/apps/next13/src/app/react-query.tsx
+++ b/apps/next13/src/app/react-query.tsx
@@ -1,6 +1,6 @@
"use client"
-import {useQuery, useMutation, useSuspenseQuery} from "@blitzjs/rpc"
+import {useQuery, useMutation} from "@blitzjs/rpc"
import logout from "../auth/mutations/logout"
import getCurrentUser from "../users/queries/getCurrentUser"
import {useTransition} from "react"
@@ -8,7 +8,7 @@ import {useRouter} from "next/navigation"
export default function Test() {
const router = useRouter()
- const [user] = useSuspenseQuery(getCurrentUser, null)
+ const [user] = useQuery(getCurrentUser, null)
const [isPending, startTransition] = useTransition()
const [logoutMutation] = useMutation(logout)
console.log(user)
diff --git a/apps/toolkit-app-passportjs/next-env.d.ts b/apps/toolkit-app-passportjs/next-env.d.ts
index a4a7b3f5cf..4f11a03dc6 100644
--- a/apps/toolkit-app-passportjs/next-env.d.ts
+++ b/apps/toolkit-app-passportjs/next-env.d.ts
@@ -2,4 +2,4 @@
///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/apps/toolkit-app/next.config.js b/apps/toolkit-app/next.config.js
index 8fb0eda0ab..8840fb33b3 100644
--- a/apps/toolkit-app/next.config.js
+++ b/apps/toolkit-app/next.config.js
@@ -1,3 +1,4 @@
+const { withNextAuthAdapter } = require("@blitzjs/auth/next-auth")
const { withBlitz } = require("@blitzjs/next")
/**
@@ -10,4 +11,4 @@ const config = {
},
}
-module.exports = withBlitz(config)
+module.exports = withBlitz(withNextAuthAdapter(config))
diff --git a/apps/toolkit-app/src/pages/api/auth/[...nextauth].ts b/apps/toolkit-app/src/pages/api/auth/[...nextauth].ts
new file mode 100644
index 0000000000..5f9a90f21a
--- /dev/null
+++ b/apps/toolkit-app/src/pages/api/auth/[...nextauth].ts
@@ -0,0 +1,48 @@
+import { api } from "src/blitz-server"
+import GithubProvider from "next-auth/providers/github"
+import EmailProvider from "next-auth/providers/email"
+import { NextAuthAdapter, BlitzNextAuthOptions } from "@blitzjs/auth/next-auth"
+import db, { User } from "db"
+import { Role } from "types"
+
+// Has to be defined separately for `profile` to be correctly typed below
+const providers = [
+ GithubProvider({
+ clientId: process.env.GITHUB_CLIENT_ID as string,
+ clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
+ }),
+ EmailProvider({
+ from: process.env.GITHUB_CLIENT_ID as string,
+ server: process.env.GITHUB_CLIENT_SECRET as string,
+ }),
+]
+
+export default api(
+ NextAuthAdapter({
+ successRedirectUrl: "/",
+ errorRedirectUrl: "/error",
+ providers,
+ callback: async (user, account, profile, session) => {
+ console.log("USER SIDE PROFILE_DATA", { user, account, profile })
+ let newUser: User
+ try {
+ newUser = await db.user.findFirstOrThrow({ where: { name: { equals: user.name } } })
+ } catch (e) {
+ newUser = await db.user.create({
+ data: {
+ email: user.email as string,
+ name: user.name as string,
+ role: "USER",
+ },
+ })
+ }
+ const publicData = {
+ userId: newUser.id,
+ role: newUser.role as Role,
+ source: "github",
+ }
+ await session.$create(publicData)
+ return { redirectUrl: "/" }
+ },
+ })
+)
diff --git a/apps/toolkit-app/src/pages/index.tsx b/apps/toolkit-app/src/pages/index.tsx
index 03435b61bd..58e6730bc8 100644
--- a/apps/toolkit-app/src/pages/index.tsx
+++ b/apps/toolkit-app/src/pages/index.tsx
@@ -44,6 +44,11 @@ const UserInfo = () => {
Login
+
+
+ Sign in with GitHub
+
+
>
)
}
diff --git a/apps/web/next-env.d.ts b/apps/web/next-env.d.ts
index a4a7b3f5cf..4f11a03dc6 100644
--- a/apps/web/next-env.d.ts
+++ b/apps/web/next-env.d.ts
@@ -2,4 +2,4 @@
///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/apps/web/src/pages/api/auth/[...auth].ts b/apps/web/src/pages/api/auth/[...auth].ts
new file mode 100644
index 0000000000..1a7d874e06
--- /dev/null
+++ b/apps/web/src/pages/api/auth/[...auth].ts
@@ -0,0 +1,44 @@
+import {passportAuth} from "@blitzjs/auth"
+import {api} from "src/blitz-server"
+import db from "db"
+import {Strategy as TwitterStrategy} from "passport-twitter"
+
+export default api(
+ passportAuth({
+ successRedirectUrl: "/",
+ errorRedirectUrl: "/",
+ strategies: [
+ {
+ strategy: new TwitterStrategy(
+ {
+ consumerKey: process.env.TWITTER_CONSUMER_KEY as string,
+ consumerSecret: process.env.TWITTER_CONSUMER_SECRET as string,
+ accessTokenURL: "https://api.twitter.com/oauth/access_token",
+ callbackURL: "http://127.0.0.1:3000/api/auth/twitter/callback",
+ includeEmail: true,
+ },
+ async function (_token, _tokenSecret, profile, done) {
+ const email = profile.emails?.[0]?.value ?? "blitz@test.com"
+
+ const user = await db.user.upsert({
+ where: {email},
+ create: {
+ email,
+ name: profile.displayName,
+ },
+ update: {email},
+ })
+
+ const publicData = {
+ userId: user.id,
+ roles: [user.role],
+ source: "twitter",
+ }
+
+ done(undefined, {publicData})
+ },
+ ),
+ },
+ ],
+ }),
+)
diff --git a/apps/web/src/pages/page-with-inf-prefetch.tsx b/apps/web/src/pages/page-with-inf-prefetch.tsx
index 23d0946478..ca48f2408f 100644
--- a/apps/web/src/pages/page-with-inf-prefetch.tsx
+++ b/apps/web/src/pages/page-with-inf-prefetch.tsx
@@ -1,4 +1,4 @@
-import {useSuspenseInfiniteQuery} from "@blitzjs/rpc"
+import {useInfiniteQuery} from "@blitzjs/rpc"
import {gSSP} from "src/blitz-server"
import getInfiniteUsers from "src/queries/getInfiniteUsers"
@@ -10,14 +10,9 @@ export const getServerSideProps = gSSP(async ({ctx}) => {
})
function PageWithPrefetchInfiniteQuery(props) {
- const [usersPages] = useSuspenseInfiniteQuery(
- getInfiniteUsers,
- (page = {take: 3, skip: 0}) => page,
- {
- getNextPageParam: (lastPage) => lastPage.nextPage,
- initialPageParam: {take: 3, skip: 0},
- },
- )
+ const [usersPages] = useInfiniteQuery(getInfiniteUsers, (page = {take: 3, skip: 0}) => page, {
+ getNextPageParam: (lastPage) => lastPage.nextPage,
+ })
return (
{usersPages.map((usersPage) =>
diff --git a/apps/web/src/pages/page-with-prefetch.tsx b/apps/web/src/pages/page-with-prefetch.tsx
index c6e0bff679..1b9da771a6 100644
--- a/apps/web/src/pages/page-with-prefetch.tsx
+++ b/apps/web/src/pages/page-with-prefetch.tsx
@@ -1,4 +1,4 @@
-import {useSuspenseQuery} from "@blitzjs/rpc"
+import {useQuery} from "@blitzjs/rpc"
import {gSSP} from "src/blitz-server"
import getUsers from "src/queries/getUsers"
@@ -10,7 +10,7 @@ export const getServerSideProps = gSSP(async ({ctx}) => {
})
function PageWithPrefetch(props) {
- const [users] = useSuspenseQuery(getUsers, {})
+ const [users] = useQuery(getUsers, {})
return (
{users.map((u) => (
diff --git a/apps/web/src/pages/users.tsx b/apps/web/src/pages/users.tsx
index b04844e551..487c6e6fe4 100644
--- a/apps/web/src/pages/users.tsx
+++ b/apps/web/src/pages/users.tsx
@@ -7,7 +7,7 @@ function UsersPage() {
Users:
- {users?.map((user) => (
+ {users.map((user) => (
-
{user.name} - {user.email}
diff --git a/integration-tests/auth-with-rpc/next-env.d.ts b/integration-tests/auth-with-rpc/next-env.d.ts
index a4a7b3f5cf..4f11a03dc6 100644
--- a/integration-tests/auth-with-rpc/next-env.d.ts
+++ b/integration-tests/auth-with-rpc/next-env.d.ts
@@ -2,4 +2,4 @@
///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/integration-tests/auth-with-rpc/package.json b/integration-tests/auth-with-rpc/package.json
index a47160b9ab..ba9df6499d 100644
--- a/integration-tests/auth-with-rpc/package.json
+++ b/integration-tests/auth-with-rpc/package.json
@@ -49,7 +49,7 @@
"husky": "8.0.2",
"jsdom": "20.0.3",
"lint-staged": "13.0.3",
- "playwright": "1.49.1",
+ "playwright": "1.28.0",
"prettier": "^2.7.1",
"prettier-plugin-prisma": "4.4.0",
"pretty-quick": "3.1.3",
diff --git a/integration-tests/auth-with-rpc/src/pages/authenticated-query.tsx b/integration-tests/auth-with-rpc/src/pages/authenticated-query.tsx
index a48556d78c..32d61d4e0b 100644
--- a/integration-tests/auth-with-rpc/src/pages/authenticated-query.tsx
+++ b/integration-tests/auth-with-rpc/src/pages/authenticated-query.tsx
@@ -1,14 +1,13 @@
-import {QueryClient, useMutation, useQuery} from "@blitzjs/rpc"
+import {useMutation, useQuery} from "@blitzjs/rpc"
import logout from "../mutations/logout"
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
+import {Suspense} from "react"
function Content() {
- const [result, {isLoading, isError, error}] = useQuery(getAuthenticatedBasic, undefined)
+ const [result] = useQuery(getAuthenticatedBasic, undefined)
const [logoutMutation] = useMutation(logout)
- if (isError) throw error
- if (isLoading || !result) return Loading...
return (
- <>
+
)
}
function AuthenticatedQuery() {
return (
-
+
+
+
)
}
diff --git a/integration-tests/auth-with-rpc/src/pages/layout-authenticate-redirect.tsx b/integration-tests/auth-with-rpc/src/pages/layout-authenticate-redirect.tsx
index 97d8cfe28a..2beb50a154 100644
--- a/integration-tests/auth-with-rpc/src/pages/layout-authenticate-redirect.tsx
+++ b/integration-tests/auth-with-rpc/src/pages/layout-authenticate-redirect.tsx
@@ -1,4 +1,4 @@
-import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
+import {useMutation, useQuery} from "@blitzjs/rpc"
import {BlitzPage} from "@blitzjs/next"
import AuthenticateRedirectLayout from "../layouts/AuthenticateRedirectLayout"
import logout from "../mutations/logout"
@@ -6,7 +6,7 @@ import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
import {Suspense} from "react"
function Content() {
- const [result] = useSuspenseQuery(getAuthenticatedBasic, undefined)
+ const [result] = useQuery(getAuthenticatedBasic, undefined)
const [logoutMutation] = useMutation(logout)
return (
diff --git a/integration-tests/auth-with-rpc/src/pages/login.tsx b/integration-tests/auth-with-rpc/src/pages/login.tsx
index b2998ee778..20d64e2737 100644
--- a/integration-tests/auth-with-rpc/src/pages/login.tsx
+++ b/integration-tests/auth-with-rpc/src/pages/login.tsx
@@ -1,5 +1,5 @@
import {useRouter} from "next/router"
-import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
+import {useMutation, useQuery} from "@blitzjs/rpc"
import login from "../mutations/login"
import logout from "../mutations/logout"
import getCurrentUser from "../queries/getCurrentUser"
@@ -8,7 +8,7 @@ import {Suspense, useState} from "react"
function Content() {
const router = useRouter()
const [error, setError] = useState(null)
- const [userId] = useSuspenseQuery(getCurrentUser, null)
+ const [userId] = useQuery(getCurrentUser, null)
const [loginMutation] = useMutation(login)
const [logoutMutation] = useMutation(logout)
diff --git a/integration-tests/auth-with-rpc/src/pages/noauth-query.tsx b/integration-tests/auth-with-rpc/src/pages/noauth-query.tsx
index 3b45207baa..42f2a5c887 100644
--- a/integration-tests/auth-with-rpc/src/pages/noauth-query.tsx
+++ b/integration-tests/auth-with-rpc/src/pages/noauth-query.tsx
@@ -1,9 +1,9 @@
-import {useSuspenseQuery} from "@blitzjs/rpc"
+import {useQuery} from "@blitzjs/rpc"
import getNoauthBasic from "../queries/getNoauthBasic"
import {Suspense} from "react"
function Content() {
- const [result] = useSuspenseQuery(getNoauthBasic, undefined)
+ const [result] = useQuery(getNoauthBasic, undefined)
return
{result}
}
diff --git a/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-redirect.tsx b/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-redirect.tsx
index 749ff02259..457609abbe 100644
--- a/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-redirect.tsx
+++ b/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-redirect.tsx
@@ -1,11 +1,11 @@
-import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
+import {useMutation, useQuery} from "@blitzjs/rpc"
import {BlitzPage} from "@blitzjs/next"
import logout from "../mutations/logout"
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
import {Suspense} from "react"
function Content() {
- const [result] = useSuspenseQuery(getAuthenticatedBasic, undefined)
+ const [result] = useQuery(getAuthenticatedBasic, undefined)
const [logoutMutation] = useMutation(logout)
return (
diff --git a/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role-redirect-stay.tsx b/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role-redirect-stay.tsx
index 25be46a783..a4b9cb5fb5 100644
--- a/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role-redirect-stay.tsx
+++ b/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role-redirect-stay.tsx
@@ -1,11 +1,11 @@
-import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
+import {useMutation, useQuery} from "@blitzjs/rpc"
import {BlitzPage} from "@blitzjs/next"
import logout from "../mutations/logout"
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
import {Suspense} from "react"
function Content() {
- const [result] = useSuspenseQuery(getAuthenticatedBasic, undefined)
+ const [result] = useQuery(getAuthenticatedBasic, undefined)
const [logoutMutation] = useMutation(logout)
return (
diff --git a/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role-redirect.tsx b/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role-redirect.tsx
index fa76850c33..59f64fc5e4 100644
--- a/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role-redirect.tsx
+++ b/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role-redirect.tsx
@@ -1,11 +1,11 @@
-import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
+import {useMutation, useQuery} from "@blitzjs/rpc"
import {BlitzPage} from "@blitzjs/next"
import logout from "../mutations/logout"
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
import {Suspense} from "react"
function Content() {
- const [result] = useSuspenseQuery(getAuthenticatedBasic, undefined)
+ const [result] = useQuery(getAuthenticatedBasic, undefined)
const [logoutMutation] = useMutation(logout)
return (
diff --git a/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role-working.tsx b/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role-working.tsx
index 1cf83dcb6a..df3ffcdf3a 100644
--- a/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role-working.tsx
+++ b/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role-working.tsx
@@ -1,11 +1,11 @@
-import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
+import {useMutation, useQuery} from "@blitzjs/rpc"
import {BlitzPage} from "@blitzjs/next"
import logout from "../mutations/logout"
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
import {Suspense} from "react"
function Content() {
- const [result] = useSuspenseQuery(getAuthenticatedBasic, undefined)
+ const [result] = useQuery(getAuthenticatedBasic, undefined)
const [logoutMutation] = useMutation(logout)
return (
diff --git a/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role.tsx b/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role.tsx
index 10212669e8..c67446e0c2 100644
--- a/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role.tsx
+++ b/integration-tests/auth-with-rpc/src/pages/page-dot-authenticate-role.tsx
@@ -1,11 +1,11 @@
-import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
+import {useMutation, useQuery} from "@blitzjs/rpc"
import {BlitzPage} from "@blitzjs/next"
import logout from "../mutations/logout"
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
import {Suspense} from "react"
function Content() {
- const [result] = useSuspenseQuery(getAuthenticatedBasic, undefined)
+ const [result] = useQuery(getAuthenticatedBasic, undefined)
const [logoutMutation] = useMutation(logout)
return (
diff --git a/integration-tests/auth-with-rpc/src/pages/prefetching.tsx b/integration-tests/auth-with-rpc/src/pages/prefetching.tsx
index d7a8b50734..ce418cc871 100644
--- a/integration-tests/auth-with-rpc/src/pages/prefetching.tsx
+++ b/integration-tests/auth-with-rpc/src/pages/prefetching.tsx
@@ -32,9 +32,9 @@ type Props = {
}
export const getServerSideProps = gSSP
(async ({ctx}) => {
- await getQueryClient().prefetchQuery({
- queryKey: getQueryKey(getNoauthBasic),
- })
+ await getQueryClient().prefetchQuery(getQueryKey(getNoauthBasic, null), () =>
+ getNoauthBasic(null, ctx),
+ )
return {
props: {
dehydratedState: dehydrate(queryClient),
diff --git a/integration-tests/auth-with-rpc/src/pages/set-public-data.tsx b/integration-tests/auth-with-rpc/src/pages/set-public-data.tsx
index b3048cd8dd..8971d80121 100644
--- a/integration-tests/auth-with-rpc/src/pages/set-public-data.tsx
+++ b/integration-tests/auth-with-rpc/src/pages/set-public-data.tsx
@@ -1,10 +1,10 @@
-import {invalidateQuery, useMutation, useSuspenseQuery} from "@blitzjs/rpc"
+import {invalidateQuery, useMutation, useQuery} from "@blitzjs/rpc"
import changeRole from "../mutations/changeRole"
import getPublicDataForUser from "../queries/getPublicDataForUser"
import {Suspense} from "react"
function Content() {
- const [publicData] = useSuspenseQuery(getPublicDataForUser, {userId: 1})
+ const [publicData] = useQuery(getPublicDataForUser, {userId: 1})
return (
<>
diff --git a/integration-tests/auth/next-env.d.ts b/integration-tests/auth/next-env.d.ts
index a4a7b3f5cf..4f11a03dc6 100644
--- a/integration-tests/auth/next-env.d.ts
+++ b/integration-tests/auth/next-env.d.ts
@@ -2,4 +2,4 @@
///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/integration-tests/auth/package.json b/integration-tests/auth/package.json
index 4f9cf77ea1..3694c94ec2 100644
--- a/integration-tests/auth/package.json
+++ b/integration-tests/auth/package.json
@@ -42,7 +42,7 @@
"fs-extra": "10.0.1",
"get-port": "6.1.2",
"node-fetch": "3.2.3",
- "playwright": "1.49.1",
+ "playwright": "1.28.0",
"ts-node": "10.9.1",
"typescript": "^4.8.4"
}
diff --git a/integration-tests/get-initial-props/next-env.d.ts b/integration-tests/get-initial-props/next-env.d.ts
index 725dd6f245..4f11a03dc6 100644
--- a/integration-tests/get-initial-props/next-env.d.ts
+++ b/integration-tests/get-initial-props/next-env.d.ts
@@ -1,6 +1,5 @@
///
///
-///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/integration-tests/get-initial-props/tsconfig.json b/integration-tests/get-initial-props/tsconfig.json
index b3f2aed3d2..f391da135f 100644
--- a/integration-tests/get-initial-props/tsconfig.json
+++ b/integration-tests/get-initial-props/tsconfig.json
@@ -1,16 +1,10 @@
{
"extends": "@blitzjs/config/tsconfig.nextjs.json",
- "include": ["**/*.ts", "**/*.tsx", "next-env.d.ts", "types", ".next/types/**/*.ts"],
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"],
"compilerOptions": {
"paths": {
"react": ["./node_modules/@types/react"]
- },
- "plugins": [
- {
- "name": "next"
- }
- ],
- "strictNullChecks": true
+ }
},
"exclude": ["node_modules"],
"baseUrl": "."
diff --git a/integration-tests/middleware/next-env.d.ts b/integration-tests/middleware/next-env.d.ts
index 725dd6f245..fd36f9494e 100644
--- a/integration-tests/middleware/next-env.d.ts
+++ b/integration-tests/middleware/next-env.d.ts
@@ -3,4 +3,4 @@
///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/integration-tests/next-13-app-dir/app/react-query/query.tsx b/integration-tests/next-13-app-dir/app/react-query/query.tsx
index cc3f0582b5..d2cbd8628d 100644
--- a/integration-tests/next-13-app-dir/app/react-query/query.tsx
+++ b/integration-tests/next-13-app-dir/app/react-query/query.tsx
@@ -1,10 +1,10 @@
"use client"
-import {getQueryData, useSuspenseQuery} from "@blitzjs/rpc"
+import {getQueryData, useQuery} from "@blitzjs/rpc"
import {Suspense, useState} from "react"
import getBasic from "../../src/queries/getBasic"
function Content() {
- const [data] = useSuspenseQuery(getBasic, undefined)
+ const [data] = useQuery(getBasic, undefined)
const [newData, setNewData] = useState
()
return (
diff --git a/integration-tests/next-13-app-dir/package.json b/integration-tests/next-13-app-dir/package.json
index 492ce7132d..1577c8786a 100644
--- a/integration-tests/next-13-app-dir/package.json
+++ b/integration-tests/next-13-app-dir/package.json
@@ -43,7 +43,7 @@
"fs-extra": "10.0.1",
"get-port": "6.1.2",
"node-fetch": "3.2.3",
- "playwright": "1.49.1",
+ "playwright": "1.28.0",
"ts-node": "10.9.1",
"typescript": "^4.9.5"
}
diff --git a/integration-tests/no-suspense/next-env.d.ts b/integration-tests/no-suspense/next-env.d.ts
index 725dd6f245..4f11a03dc6 100644
--- a/integration-tests/no-suspense/next-env.d.ts
+++ b/integration-tests/no-suspense/next-env.d.ts
@@ -1,6 +1,5 @@
///
///
-///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/integration-tests/no-suspense/tsconfig.json b/integration-tests/no-suspense/tsconfig.json
index b3f2aed3d2..f391da135f 100644
--- a/integration-tests/no-suspense/tsconfig.json
+++ b/integration-tests/no-suspense/tsconfig.json
@@ -1,16 +1,10 @@
{
"extends": "@blitzjs/config/tsconfig.nextjs.json",
- "include": ["**/*.ts", "**/*.tsx", "next-env.d.ts", "types", ".next/types/**/*.ts"],
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"],
"compilerOptions": {
"paths": {
"react": ["./node_modules/@types/react"]
- },
- "plugins": [
- {
- "name": "next"
- }
- ],
- "strictNullChecks": true
+ }
},
"exclude": ["node_modules"],
"baseUrl": "."
diff --git a/integration-tests/qm/package.json b/integration-tests/qm/package.json
index adb503927f..39ed74b00a 100644
--- a/integration-tests/qm/package.json
+++ b/integration-tests/qm/package.json
@@ -13,7 +13,7 @@
"@blitzjs/next": "2.2.1",
"@blitzjs/rpc": "2.2.1",
"@prisma/client": "6.1.0",
- "@tanstack/react-query": "5.51.1",
+ "@tanstack/react-query": "4.0.10",
"blitz": "2.2.1",
"next": "15.0.1",
"prisma": "6.1.0",
diff --git a/integration-tests/qm/test/__snapshots__/use-query.test.tsx.snap b/integration-tests/qm/test/__snapshots__/use-query.test.tsx.snap
index 9666036a0c..d5ffa3c0bc 100644
--- a/integration-tests/qm/test/__snapshots__/use-query.test.tsx.snap
+++ b/integration-tests/qm/test/__snapshots__/use-query.test.tsx.snap
@@ -3,7 +3,3 @@
exports[`useQuery > a "query" that converts the string parameter to uppercase > shouldn't work with mutation function 1`] = `"\\"useQuery\\" was expected to be called with a query but was called with a \\"mutation\\""`;
exports[`useQuery > a "query" that converts the string parameter to uppercase > shouldn't work with regular functions 1`] = `"Either the file path to your resolver is incorrect (must be in a \\"queries\\" or \\"mutations\\" folder that isn't nested inside \\"pages\\" or \\"api\\") or you are trying to use Blitz's useQuery to fetch from third-party APIs (to do that, import useQuery directly from \\"@tanstack/react-query\\")."`;
-
-exports[`useSuspenseQuery > a "query" that converts the string parameter to uppercase > shouldn't work with mutation function 1`] = `"\\"useQuery\\" was expected to be called with a query but was called with a \\"mutation\\""`;
-
-exports[`useSuspenseQuery > a "query" that converts the string parameter to uppercase > shouldn't work with regular functions 1`] = `"Either the file path to your resolver is incorrect (must be in a \\"queries\\" or \\"mutations\\" folder that isn't nested inside \\"pages\\" or \\"api\\") or you are trying to use Blitz's useQuery to fetch from third-party APIs (to do that, import useQuery directly from \\"@tanstack/react-query\\")."`;
diff --git a/integration-tests/qm/test/use-query.test.tsx b/integration-tests/qm/test/use-query.test.tsx
index 7031aa43ed..05c2a933f6 100644
--- a/integration-tests/qm/test/use-query.test.tsx
+++ b/integration-tests/qm/test/use-query.test.tsx
@@ -1,12 +1,6 @@
import {describe, it, expect, beforeAll, vi} from "vitest"
import {act, screen, waitForElementToBeRemoved} from "@testing-library/react"
-import {
- useSuspenseQuery,
- useQuery,
- useSuspenseInfiniteQuery,
- BlitzRpcPlugin,
- BlitzProvider,
-} from "@blitzjs/rpc"
+import {useQuery, useInfiniteQuery, BlitzRpcPlugin, BlitzProvider} from "@blitzjs/rpc"
import React from "react"
import delay from "delay"
import {buildMutationRpc, buildQueryRpc, mockRouter, render} from "../../utils/blitz-test-utils"
@@ -17,18 +11,19 @@ beforeAll(() => {
globalThis.IS_REACT_ACT_ENVIRONMENT = true
})
-describe("useSuspenseQuery", () => {
+describe("useQuery", () => {
const setupHook = (
ID: string,
params: any,
queryFn: (...args: any) => any,
- options: Parameters
[2] = {} as any,
+ options: Parameters[2] = {} as any,
): [{data?: any; setQueryData?: any}, Function] => {
let res = {}
const qc = BlitzRpcPlugin({})
- function TestSuspenseHarness() {
- const [data, {setQueryData}] = useSuspenseQuery(queryFn, params, {
+ function TestHarness() {
+ const [data, {setQueryData}] = useQuery(queryFn, params, {
+ suspense: true,
...(options as any),
} as any)
@@ -43,7 +38,7 @@ describe("useSuspenseQuery", () => {
const ui = () => (
-
+
)
@@ -95,101 +90,6 @@ describe("useSuspenseQuery", () => {
expect(() => setupHook("5", "test", buildMutationRpc(upcase))).toThrowErrorMatchingSnapshot()
})
- it("works with options other than enabled & suspense without type error", () => {
- const Demo = () => {
- useSuspenseQuery(buildQueryRpc(upcase), undefined, {refetchInterval: 10000})
- return
- }
- const ui = () =>
-
- const {rerender} = render(ui(), {
- wrapper: ({children}) => (
-
- {children}
-
- ),
- })
- })
- })
-})
-
-describe("useQuery", () => {
- const setupHook = (
- ID: string,
- params: any,
- queryFn: (...args: any) => any,
- options: Parameters[2] = {} as any,
- ): [{data?: any; setQueryData?: any}, Function] => {
- let res = {}
- const qc = BlitzRpcPlugin({})
-
- function TestHarness() {
- const [data, {setQueryData, isLoading}] = useQuery(queryFn, params, {
- ...(options as any),
- } as any)
-
- Object.assign(res, {data, setQueryData})
- if (isLoading) {
- return Loading...
- }
- return (
-
- {data ? `Ready${ID}` : "No data"}
- {data}
-
- )
- }
-
- const ui = () =>
-
- const {rerender} = render(ui(), {
- wrapper: ({children}) => (
-
- {children}
-
- ),
- })
- return [res, () => rerender(ui())]
- }
-
- describe('a "query" that converts the string parameter to uppercase', () => {
- const upcase = async (args: string) => {
- await delay(500)
- return args.toUpperCase()
- }
-
- it("should work with Blitz queries", async () => {
- const [res] = setupHook("2", "test", buildQueryRpc(upcase))
- await waitForElementToBeRemoved(() => screen.getByText("Loading..."))
- await act(async () => {
- await screen.queryAllByText("Ready2")[0]
- expect(res.data).toBe("TEST")
- })
- })
-
- it("should be able to change the data with setQueryData", async () => {
- const [res] = setupHook("3", "fooBar", buildQueryRpc(upcase))
- await waitForElementToBeRemoved(() => screen.getByText("Loading..."))
- await act(async () => {
- await screen.queryAllByText("Ready3")[0]
- expect(res.data).toBe("FOOBAR")
- res.setQueryData((p: string) => p.substr(3, 3), {refetch: false})
- await delay(100)
- })
-
- expect(res.data).toBe("BAR")
- })
-
- it("shouldn't work with regular functions", () => {
- console.error = vi.fn()
- expect(() => setupHook("4", "test", upcase)).toThrowErrorMatchingSnapshot()
- })
-
- it("shouldn't work with mutation function", () => {
- console.error = vi.fn()
- expect(() => setupHook("5", "test", buildMutationRpc(upcase))).toThrowErrorMatchingSnapshot()
- })
-
it("suspense disabled if enabled is false", async () => {
setupHook("6", "test", buildQueryRpc(upcase), {enabled: false})
await screen.findByText("No data")
@@ -200,9 +100,17 @@ describe("useQuery", () => {
await screen.findByText("No data")
})
+ // it("suspense disabled if enabled is false and suspense set", async () => {
+ // setupHook("8", "test", buildQueryRpc(upcase), {
+ // enabled: false,
+ // suspense: true,
+ // })
+ // await screen.findByText("No data")
+ // })
+
it("works with options other than enabled & suspense without type error", () => {
const Demo = () => {
- useSuspenseQuery(buildQueryRpc(upcase), undefined, {refetchInterval: 10000})
+ useQuery(buildQueryRpc(upcase), undefined, {refetchInterval: 10000})
return
}
const ui = () =>
@@ -218,7 +126,7 @@ describe("useQuery", () => {
})
})
-describe("useSuspenseInfiniteQuery", () => {
+describe("useInfiniteQuery", () => {
const setupHook = (
ID: string,
params: (arg?: any) => any,
@@ -230,7 +138,7 @@ describe("useSuspenseInfiniteQuery", () => {
function TestHarness() {
// TODO - fix typing
//@ts-ignore
- const [groupedData] = useSuspenseInfiniteQuery(queryFn, params, {
+ const [groupedData] = useInfiniteQuery(queryFn, params, {
suspense: true,
getNextPageParam: () => {},
})
diff --git a/integration-tests/react-query-utils/next-env.d.ts b/integration-tests/react-query-utils/next-env.d.ts
index 725dd6f245..fd36f9494e 100644
--- a/integration-tests/react-query-utils/next-env.d.ts
+++ b/integration-tests/react-query-utils/next-env.d.ts
@@ -3,4 +3,4 @@
///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/integration-tests/react-query-utils/pages/page-with-get-query-data.tsx b/integration-tests/react-query-utils/pages/page-with-get-query-data.tsx
index 091188a299..6e737bfe59 100644
--- a/integration-tests/react-query-utils/pages/page-with-get-query-data.tsx
+++ b/integration-tests/react-query-utils/pages/page-with-get-query-data.tsx
@@ -1,9 +1,9 @@
-import {getQueryData, useSuspenseQuery} from "@blitzjs/rpc"
+import {getQueryData, useQuery} from "@blitzjs/rpc"
import {Suspense, useState} from "react"
import getBasic from "../app/queries/getBasic"
function Content() {
- const [data] = useSuspenseQuery(getBasic, undefined)
+ const [data] = useQuery(getBasic, undefined)
const [newData, setNewData] = useState()
return (
diff --git a/integration-tests/react-query-utils/pages/page-with-invalidate.tsx b/integration-tests/react-query-utils/pages/page-with-invalidate.tsx
index 308c0e8370..01d254ddb8 100644
--- a/integration-tests/react-query-utils/pages/page-with-invalidate.tsx
+++ b/integration-tests/react-query-utils/pages/page-with-invalidate.tsx
@@ -1,9 +1,9 @@
import React, {Suspense} from "react"
import {BlitzPage} from "@blitzjs/next"
-import {invalidateQuery, useSuspenseQuery} from "@blitzjs/rpc"
+import {invalidateQuery, useQuery} from "@blitzjs/rpc"
import getSequence from "../app/queries/getSequence"
-const useSuspenseQueryOptions = {
+const useQueryOptions = {
refetchInterval: 0,
refetchOnMount: false,
refetchOnReconnect: false,
@@ -11,16 +11,8 @@ const useSuspenseQueryOptions = {
}
const PageWithInvalidateQuery: React.FC = () => {
- const [query1, {isFetching: isQ1Fetching}] = useSuspenseQuery(
- getSequence,
- "query1",
- useSuspenseQueryOptions,
- )
- const [query2, {isFetching: isQ2Fetching}] = useSuspenseQuery(
- getSequence,
- "query2",
- useSuspenseQueryOptions,
- )
+ const [query1, {isFetching: isQ1Fetching}] = useQuery(getSequence, "query1", useQueryOptions)
+ const [query2, {isFetching: isQ2Fetching}] = useQuery(getSequence, "query2", useQueryOptions)
const isFetching = isQ1Fetching || isQ2Fetching
diff --git a/integration-tests/react-query-utils/pages/page-with-monorepo-query.tsx b/integration-tests/react-query-utils/pages/page-with-monorepo-query.tsx
index 6f73038f88..5cb431b1ae 100644
--- a/integration-tests/react-query-utils/pages/page-with-monorepo-query.tsx
+++ b/integration-tests/react-query-utils/pages/page-with-monorepo-query.tsx
@@ -1,9 +1,9 @@
-import {getQueryData, useSuspenseQuery} from "@blitzjs/rpc"
+import {getQueryData, useQuery} from "@blitzjs/rpc"
import {Suspense, useState} from "react"
import getNoSuspenseBasic from "../../no-suspense/app/queries/getNoSuspenseBasic"
function Content() {
- const [data] = useSuspenseQuery(getNoSuspenseBasic, undefined)
+ const [data] = useQuery(getNoSuspenseBasic, undefined)
const [newData, setNewData] = useState
()
return (
diff --git a/integration-tests/react-query-utils/pages/page-with-prefetch-inf-query.tsx b/integration-tests/react-query-utils/pages/page-with-prefetch-inf-query.tsx
index 0b0981ff8f..622ecfa879 100644
--- a/integration-tests/react-query-utils/pages/page-with-prefetch-inf-query.tsx
+++ b/integration-tests/react-query-utils/pages/page-with-prefetch-inf-query.tsx
@@ -1,4 +1,4 @@
-import {useSuspenseInfiniteQuery} from "@blitzjs/rpc"
+import {useInfiniteQuery} from "@blitzjs/rpc"
import {gSSP} from "../app/blitz-server"
import testQuery from "../app/queries/getInfiniteData"
@@ -12,12 +12,12 @@ export const getServerSideProps = gSSP(async ({ctx}) => {
})
const PageWithPrefetchInfQuery = () => {
- const [data] = useSuspenseInfiniteQuery(
+ const [data] = useInfiniteQuery(
testQuery,
(pageParams) => ({...pageParams, name: "hello world"}),
{
+ suspense: false,
getNextPageParam: (lastPage) => lastPage,
- initialPageParam: {name: "hello world"},
},
)
return
{data ? data : "no-data"}
diff --git a/integration-tests/react-query-utils/test/index.test.ts b/integration-tests/react-query-utils/test/index.test.ts
index c73053497b..7423ec1cc8 100644
--- a/integration-tests/react-query-utils/test/index.test.ts
+++ b/integration-tests/react-query-utils/test/index.test.ts
@@ -51,22 +51,22 @@ const runTests = () => {
)
})
- // describe("prefetch infinite query", () => {
- // it(
- // "should work",
- // async () => {
- // const browser = await webdriver(appPort, "/page-with-prefetch-inf-query")
-
- // browser.waitForElementByCss("#data", 0)
- // const newText = await browser.elementByCss("#data").text()
- // expect(newText).not.toMatch("no-data")
- // expect(newText).toMatch("thanks")
-
- // if (browser) await browser.close()
- // },
- // 5000 * 60 * 2,
- // )
- // })
+ describe("prefetch infinite query", () => {
+ it(
+ "should work",
+ async () => {
+ const browser = await webdriver(appPort, "/page-with-prefetch-inf-query")
+
+ browser.waitForElementByCss("#data", 0)
+ const newText = await browser.elementByCss("#data").text()
+ expect(newText).not.toMatch("no-data")
+ expect(newText).toMatch("thanks")
+
+ if (browser) await browser.close()
+ },
+ 5000 * 60 * 2,
+ )
+ })
describe("invalidate query", () => {
it(
diff --git a/integration-tests/trailing-slash/next-env.d.ts b/integration-tests/trailing-slash/next-env.d.ts
index 725dd6f245..4f11a03dc6 100644
--- a/integration-tests/trailing-slash/next-env.d.ts
+++ b/integration-tests/trailing-slash/next-env.d.ts
@@ -1,6 +1,5 @@
///
///
-///
// NOTE: This file should not be edited
-// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/integration-tests/trailing-slash/pages/use-query.tsx b/integration-tests/trailing-slash/pages/use-query.tsx
index 51ead85c0c..2fee1c3d98 100644
--- a/integration-tests/trailing-slash/pages/use-query.tsx
+++ b/integration-tests/trailing-slash/pages/use-query.tsx
@@ -1,9 +1,9 @@
import getBasic from "../app/queries/getBasic"
-import {useSuspenseQuery} from "@blitzjs/rpc"
+import {useQuery} from "@blitzjs/rpc"
import {Suspense} from "react"
function Content() {
- const [result] = useSuspenseQuery(getBasic, undefined)
+ const [result] = useQuery(getBasic, undefined)
return
{result}
}
diff --git a/integration-tests/trailing-slash/tsconfig.json b/integration-tests/trailing-slash/tsconfig.json
index e39f5a770e..f391da135f 100644
--- a/integration-tests/trailing-slash/tsconfig.json
+++ b/integration-tests/trailing-slash/tsconfig.json
@@ -1,16 +1,10 @@
{
"extends": "@blitzjs/config/tsconfig.nextjs.json",
- "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types", ".next/types/**/*.ts"],
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"],
"compilerOptions": {
"paths": {
"react": ["./node_modules/@types/react"]
- },
- "plugins": [
- {
- "name": "next"
- }
- ],
- "strictNullChecks": true
+ }
},
"exclude": ["node_modules"],
"baseUrl": "."
diff --git a/integration-tests/utils/package.json b/integration-tests/utils/package.json
index 2af3351bc5..d5604e9d63 100644
--- a/integration-tests/utils/package.json
+++ b/integration-tests/utils/package.json
@@ -22,7 +22,7 @@
"get-port": "6.1.2",
"node-fetch": "3.2.3",
"pkg-dir": "5.0.0",
- "playwright-chromium": "1.49.1",
+ "playwright-chromium": "1.28.0",
"react": "19.0.0",
"react-dom": "19.0.0",
"resolve-cwd": "3.0.0",
diff --git a/package.json b/package.json
index bad343bf42..bfd68be590 100644
--- a/package.json
+++ b/package.json
@@ -46,6 +46,9 @@
]
},
"pnpm": {
+ "patchedDependencies": {
+ "next-auth@4.24.7": "patches/next-auth@4.24.7.patch"
+ },
"overrides": {
"@types/mime": "3.0.4",
"next": "15.0.1",
diff --git a/packages/blitz-auth/src/client/index.tsx b/packages/blitz-auth/src/client/index.tsx
index 6190cd610a..246d1aff43 100644
--- a/packages/blitz-auth/src/client/index.tsx
+++ b/packages/blitz-auth/src/client/index.tsx
@@ -152,7 +152,7 @@ export interface UseSessionOptions {
}
export const useSession = (options: UseSessionOptions = {}): ClientSession => {
- const suspense = options?.suspense ?? true
+ const suspense = options?.suspense ?? Boolean(globalThis.__BLITZ_SUSPENSE_ENABLED)
let initialState: ClientSession
if (options.initialPublicData) {
diff --git a/packages/blitz-auth/src/global.ts b/packages/blitz-auth/src/global.ts
index 0916eba0ff..c4def8d920 100644
--- a/packages/blitz-auth/src/global.ts
+++ b/packages/blitz-auth/src/global.ts
@@ -5,5 +5,6 @@ import type {SessionConfigMethods} from "./shared"
declare global {
var sessionConfig: AuthPluginOptions & SessionConfigMethods
var __BLITZ_SESSION_COOKIE_PREFIX: string | undefined
+ var __BLITZ_SUSPENSE_ENABLED: boolean
var __BLITZ_GET_RSC_CONTEXT: () => Promise
}
diff --git a/packages/blitz-next/src/index-server.ts b/packages/blitz-next/src/index-server.ts
index 5be8137274..a3af4c8528 100644
--- a/packages/blitz-next/src/index-server.ts
+++ b/packages/blitz-next/src/index-server.ts
@@ -123,15 +123,11 @@ const prefetchQueryFactory = (
}
if (infinite) {
- await queryClient.prefetchQuery({
- queryKey: getInfiniteQueryKey(fn, input),
- queryFn: () => fn(input, ctx),
- })
+ await queryClient.prefetchInfiniteQuery(getInfiniteQueryKey(fn, input), () =>
+ fn(input, ctx),
+ )
} else {
- await queryClient.prefetchQuery({
- queryKey: getQueryKey(fn, input),
- queryFn: () => fn(input, ctx),
- })
+ await queryClient.prefetchQuery(getQueryKey(fn, input), () => fn(input, ctx))
}
},
}
@@ -247,6 +243,7 @@ export interface BlitzConfig extends NextConfig {
}
}
+
export function withBlitz(nextConfig: BlitzConfig = {}): NextConfig {
if (
process.env.NODE_ENV !== "production" &&
diff --git a/packages/blitz-next/src/provider.tsx b/packages/blitz-next/src/provider.tsx
index 51f18693d6..ba414b3162 100644
--- a/packages/blitz-next/src/provider.tsx
+++ b/packages/blitz-next/src/provider.tsx
@@ -1,4 +1,4 @@
-import {QueryClientProvider, HydrationBoundary} from "@blitzjs/rpc"
+import {QueryClientProvider, Hydrate} from "@blitzjs/rpc"
import type {QueryClient, HydrateOptions} from "@blitzjs/rpc"
import React from "react"
@@ -12,16 +12,20 @@ export type BlitzProviderProps = {
export const BlitzProvider = ({
client = globalThis.queryClient,
+ contextSharing = false,
dehydratedState,
hydrateOptions,
children,
}: BlitzProviderProps) => {
if (client) {
return (
-
-
+
+
{children}
-
+
)
}
diff --git a/packages/blitz-rpc/package.json b/packages/blitz-rpc/package.json
index bb3d0aaf7f..08c9612386 100644
--- a/packages/blitz-rpc/package.json
+++ b/packages/blitz-rpc/package.json
@@ -27,7 +27,7 @@
],
"dependencies": {
"@swc/core": "1.3.7",
- "@tanstack/react-query": "5.51.1",
+ "@tanstack/react-query": "4.24.4",
"b64-lite": "1.4.0",
"bad-behavior": "1.0.1",
"chalk": "^4.1.0",
@@ -36,7 +36,7 @@
"supports-color": "8.1.1"
},
"peerDependencies": {
- "@tanstack/query-core": "5.51.1",
+ "@tanstack/query-core": "4.24.4",
"blitz": "2.2.1",
"next": "*",
"react": "*"
@@ -44,7 +44,7 @@
"devDependencies": {
"@blitzjs/auth": "2.2.1",
"@blitzjs/config": "2.2.1",
- "@tanstack/query-core": "5.51.1",
+ "@tanstack/query-core": "4.24.4",
"@types/debug": "4.1.7",
"@types/react": "npm:types-react@19.0.0",
"@types/react-dom": "npm:types-react-dom@19.0.0",
diff --git a/packages/blitz-rpc/src/global.ts b/packages/blitz-rpc/src/global.ts
index 9b4f11c9b6..950669f38e 100644
--- a/packages/blitz-rpc/src/global.ts
+++ b/packages/blitz-rpc/src/global.ts
@@ -4,6 +4,7 @@ import type {Ctx} from "blitz"
declare global {
var queryClient: QueryClient
+ var __BLITZ_SUSPENSE_ENABLED: boolean
var blitzRpcRpcLoggerOptions: RpcLoggerOptions | undefined
var __BLITZ_GET_RSC_CONTEXT: () => Promise
}
diff --git a/packages/blitz-rpc/src/index-browser.tsx b/packages/blitz-rpc/src/index-browser.tsx
index ed6f648eb6..a134bcde90 100644
--- a/packages/blitz-rpc/src/index-browser.tsx
+++ b/packages/blitz-rpc/src/index-browser.tsx
@@ -15,8 +15,6 @@ export {
useMutation,
usePaginatedQuery,
useQuery,
- useSuspenseInfiniteQuery,
- useSuspenseQuery,
} from "./query/react-query"
export type {
DefaultOptions,
@@ -30,6 +28,5 @@ export type {
export * from "./query/utils"
import {reactQueryClientReExports} from "./query/react-query"
-const {QueryClientProvider, HydrationBoundary, useQueryErrorResetBoundary} =
- reactQueryClientReExports
-export {QueryClientProvider, HydrationBoundary, useQueryErrorResetBoundary}
+const {QueryClientProvider, Hydrate, useQueryErrorResetBoundary} = reactQueryClientReExports
+export {QueryClientProvider, Hydrate, useQueryErrorResetBoundary}
diff --git a/packages/blitz-rpc/src/query/react-query/index.ts b/packages/blitz-rpc/src/query/react-query/index.ts
index ec1bec1097..e7aa4d0f0a 100644
--- a/packages/blitz-rpc/src/query/react-query/index.ts
+++ b/packages/blitz-rpc/src/query/react-query/index.ts
@@ -28,6 +28,11 @@ export const BlitzRpcPlugin = createClientPlugin<
>((options?: BlitzRpcOptions) => {
const initializeQueryClient = () => {
const {reactQueryOptions} = options || {}
+ let suspenseEnabled = reactQueryOptions?.queries?.suspense ?? true
+ if (!process.env.CLI_COMMAND_CONSOLE && !process.env.CLI_COMMAND_DB) {
+ globalThis.__BLITZ_SUSPENSE_ENABLED = suspenseEnabled
+ }
+
return new QueryClient({
defaultOptions: {
...reactQueryOptions,
@@ -42,6 +47,7 @@ export const BlitzRpcPlugin = createClientPlugin<
return false
},
...reactQueryOptions?.queries,
+ suspense: suspenseEnabled,
},
},
})
diff --git a/packages/blitz-rpc/src/query/react-query/react-query.ts b/packages/blitz-rpc/src/query/react-query/react-query.ts
index 697cfbaa39..d8872ce867 100644
--- a/packages/blitz-rpc/src/query/react-query/react-query.ts
+++ b/packages/blitz-rpc/src/query/react-query/react-query.ts
@@ -1,21 +1,13 @@
-import {
- useQueryErrorResetBoundary,
- QueryClientProvider,
- HydrationBoundary,
- keepPreviousData,
-} from "@tanstack/react-query"
-import type {DefaultError, InfiniteData} from "@tanstack/query-core"
+import {useQueryErrorResetBoundary, QueryClientProvider, Hydrate} from "@tanstack/react-query"
import {useInfiniteQuery as useInfiniteReactQuery} from "@tanstack/react-query"
-import {useSuspenseInfiniteQuery as useSuspenseInfiniteReactQuery} from "@tanstack/react-query"
import {useQuery as useReactQuery} from "@tanstack/react-query"
-import {useSuspenseQuery as useSuspenseReactQuery} from "@tanstack/react-query"
import {useMutation as useReactQueryMutation} from "@tanstack/react-query"
export const reactQueryClientReExports = {
useQueryErrorResetBoundary,
QueryClientProvider,
- HydrationBoundary,
+ Hydrate,
}
import type {
@@ -26,8 +18,6 @@ import type {
UseMutationOptions,
UseMutationResult,
MutateOptions,
- UseSuspenseQueryOptions,
- UseSuspenseInfiniteQueryOptions,
} from "@tanstack/react-query"
import {isServer, FirstParam, PromiseReturnType, AsyncFunc} from "blitz"
@@ -62,42 +52,43 @@ export type RestQueryResult = Omit,
- TError = DefaultError,
+ TError = unknown,
TSelectedData = TResult,
>(
queryFn: T,
params: FirstParam,
- options?: Omit, "queryKey"> & QueryNonLazyOptions,
-): [TSelectedData | undefined, RestQueryResult]
+ options?: UseQueryOptions & QueryNonLazyOptions,
+): [TSelectedData, RestQueryResult]
export function useQuery<
T extends AsyncFunc,
TResult = PromiseReturnType,
- TError = DefaultError,
+ TError = unknown,
TSelectedData = TResult,
>(
queryFn: T,
params: FirstParam,
- options: Omit, "queryKey"> & QueryLazyOptions,
-): [TSelectedData | undefined, RestQueryResult]
+ options: UseQueryOptions & QueryLazyOptions,
+): [TSelectedData | undefined, RestQueryResult]
export function useQuery<
T extends AsyncFunc,
TResult = PromiseReturnType,
- TError = DefaultError,
+ TError = unknown,
TSelectedData = TResult,
>(
queryFn: T,
params: FirstParam,
- options: Omit, "queryKey"> = {},
+ options: UseQueryOptions = {},
) {
if (typeof queryFn === "undefined") {
throw new Error("useQuery is missing the first argument - it must be a query function")
}
- let enabled = isServer ? false : options?.enabled ?? options?.enabled !== null
+ const suspenseEnabled = Boolean(globalThis.__BLITZ_SUSPENSE_ENABLED)
+ let enabled = isServer && suspenseEnabled ? false : options?.enabled ?? options?.enabled !== null
let routerIsReady = false
const router = useRouter()
if (router) {
- routerIsReady = router?.isReady || isServer
+ routerIsReady = router?.isReady || (isServer && suspenseEnabled)
} else {
routerIsReady = true
}
@@ -108,70 +99,19 @@ export function useQuery<
queryKey: routerIsReady ? queryKey : ["_routerNotReady_"],
queryFn: routerIsReady
? ({signal}) => enhancedResolverRpcClient(params, {fromQueryHook: true}, signal)
- : (emptyQueryFn as PromiseReturnType),
+ : (emptyQueryFn as any),
...options,
enabled,
})
- const rest = {
- ...queryRest,
- ...getQueryCacheFunctions, TResult, T>(queryFn, params),
- }
-
- return [data, rest]
-}
-
-// -------------------------
-// useSuspenseQuery
-// -------------------------
-
-export function useSuspenseQuery<
- T extends AsyncFunc,
- TResult = PromiseReturnType,
- TError = DefaultError,
- TSelectedData = TResult,
->(
- queryFn: T,
- params: FirstParam,
- options?: Omit, "queryKey"> & QueryNonLazyOptions,
-): [TSelectedData, RestQueryResult]
-export function useSuspenseQuery<
- T extends AsyncFunc,
- TResult = PromiseReturnType,
- TError = DefaultError,
- TSelectedData = TResult,
->(
- queryFn: T,
- params: FirstParam,
- options: Omit, "queryKey"> &
- QueryLazyOptions,
-): [TSelectedData | undefined, RestQueryResult]
-export function useSuspenseQuery<
- T extends AsyncFunc,
- TResult = PromiseReturnType,
- TError = DefaultError,
- TSelectedData = TResult,
->(
- queryFn: T,
- params: FirstParam,
- options: Omit, "queryKey"> = {},
-) {
- if (typeof queryFn === "undefined") {
- throw new Error("useQuery is missing the first argument - it must be a query function")
- }
-
- const enhancedResolverRpcClient = sanitizeQuery(queryFn)
- const queryKey = getQueryKey(queryFn, params)
-
- let routerIsReady = false
- const router = useRouter()
- if (router) {
- routerIsReady = router?.isReady || isServer
- } else {
- routerIsReady = true
- }
-
- if (isServer) {
+ if (
+ queryRest.fetchStatus === "idle" &&
+ isServer &&
+ suspenseEnabled !== false &&
+ !data &&
+ (!options || !("suspense" in options) || options.suspense) &&
+ (!options || !("enabled" in options) || options.enabled)
+ ) {
const e = new NextError()
e.name = "Rendering Suspense fallback..."
e.digest = "DYNAMIC_SERVER_USAGE"
@@ -181,19 +121,12 @@ export function useSuspenseQuery<
throw e
}
- const {data, ...queryRest} = useSuspenseReactQuery({
- queryKey: routerIsReady ? queryKey : ["_routerNotReady_"],
- queryFn: routerIsReady
- ? ({signal}) => enhancedResolverRpcClient(params, {fromQueryHook: true}, signal)
- : (emptyQueryFn as PromiseReturnType),
- ...options,
- })
-
const rest = {
...queryRest,
...getQueryCacheFunctions, TResult, T>(queryFn, params),
}
+ // return [data, rest as RestQueryResult]
return [data, rest]
}
@@ -206,42 +139,43 @@ export type RestPaginatedResult = Omit,
- TError = DefaultError,
+ TError = unknown,
TSelectedData = TResult,
>(
queryFn: T,
params: FirstParam,
- options?: Omit, "queryKey"> & QueryNonLazyOptions,
-): [TSelectedData | undefined, RestPaginatedResult]
+ options?: UseQueryOptions & QueryNonLazyOptions,
+): [TSelectedData, RestPaginatedResult]
export function usePaginatedQuery<
T extends AsyncFunc,
TResult = PromiseReturnType,
- TError = DefaultError,
+ TError = unknown,
TSelectedData = TResult,
>(
queryFn: T,
params: FirstParam,
- options: Omit, "queryKey"> & QueryLazyOptions,
+ options: UseQueryOptions & QueryLazyOptions,
): [TSelectedData | undefined, RestPaginatedResult]
export function usePaginatedQuery<
T extends AsyncFunc,
TResult = PromiseReturnType,
- TError = DefaultError,
+ TError = unknown,
TSelectedData = TResult,
>(
queryFn: T,
params: FirstParam,
- options: Omit, "queryKey"> = {},
+ options: UseQueryOptions = {},
) {
if (typeof queryFn === "undefined") {
throw new Error("usePaginatedQuery is missing the first argument - it must be a query function")
}
- let enabled = isServer ? false : options?.enabled ?? options?.enabled !== null
+ const suspenseEnabled = Boolean(globalThis.__BLITZ_SUSPENSE_ENABLED)
+ let enabled = isServer && suspenseEnabled ? false : options?.enabled ?? options?.enabled !== null
let routerIsReady = false
const router = useRouter()
if (router) {
- routerIsReady = router?.isReady || isServer
+ routerIsReady = router?.isReady || (isServer && suspenseEnabled)
} else {
routerIsReady = true
}
@@ -252,13 +186,20 @@ export function usePaginatedQuery<
queryKey: routerIsReady ? queryKey : ["_routerNotReady_"],
queryFn: routerIsReady
? ({signal}) => enhancedResolverRpcClient(params, {fromQueryHook: true}, signal)
- : (emptyQueryFn as PromiseReturnType),
+ : (emptyQueryFn as any),
...options,
- placeholderData: keepPreviousData,
+ keepPreviousData: true,
enabled,
})
- if (queryRest.fetchStatus === "idle" && isServer && !data) {
+ if (
+ queryRest.fetchStatus === "idle" &&
+ isServer &&
+ suspenseEnabled !== false &&
+ !data &&
+ (!options || !("suspense" in options) || options.suspense) &&
+ (!options || !("enabled" in options) || options.enabled)
+ ) {
const e = new NextError()
e.name = "Rendering Suspense fallback..."
e.digest = "DYNAMIC_SERVER_USAGE"
@@ -295,43 +236,43 @@ interface InfiniteQueryConfig
export function useInfiniteQuery<
T extends AsyncFunc,
TResult = PromiseReturnType,
- TError = DefaultError,
+ TError = unknown,
TSelectedData = TResult,
>(
queryFn: T,
getQueryParams: (pageParam: any) => FirstParam,
- options: Omit, "queryKey"> &
- QueryNonLazyOptions,
-): [TSelectedData[] | undefined, RestInfiniteResult]
+ options: InfiniteQueryConfig & QueryNonLazyOptions,
+): [TSelectedData[], RestInfiniteResult]
export function useInfiniteQuery<
T extends AsyncFunc,
TResult = PromiseReturnType,
- TError = DefaultError,
+ TError = unknown,
TSelectedData = TResult,
>(
queryFn: T,
getQueryParams: (pageParam: any) => FirstParam,
- options: Omit, "queryKey"> & QueryLazyOptions,
+ options: InfiniteQueryConfig & QueryLazyOptions,
): [TSelectedData[] | undefined, RestInfiniteResult]
export function useInfiniteQuery<
T extends AsyncFunc,
TResult = PromiseReturnType,
- TError = DefaultError,
+ TError = unknown,
TSelectedData = TResult,
>(
queryFn: T,
getQueryParams: (pageParam: any) => FirstParam,
- options: Omit, "queryKey">,
+ options: InfiniteQueryConfig,
) {
if (typeof queryFn === "undefined") {
throw new Error("useInfiniteQuery is missing the first argument - it must be a query function")
}
- let enabled = isServer ? false : options?.enabled ?? options?.enabled !== null
+ const suspenseEnabled = Boolean(globalThis.__BLITZ_SUSPENSE_ENABLED)
+ let enabled = isServer && suspenseEnabled ? false : options?.enabled ?? options?.enabled !== null
let routerIsReady = false
const router = useRouter()
if (router) {
- routerIsReady = router?.isReady || isServer
+ routerIsReady = router?.isReady || (isServer && suspenseEnabled)
} else {
routerIsReady = true
}
@@ -351,93 +292,14 @@ export function useInfiniteQuery<
enabled,
})
- const infiniteQueryData = data as InfiniteData
-
- const rest = {
- ...queryRest,
- ...getQueryCacheFunctions, TResult, T>(queryFn, getQueryParams),
- pageParams: infiniteQueryData?.pageParams,
- }
-
- return [infiniteQueryData?.pages as any, rest]
-}
-
-// -------------------------
-// useInfiniteQuery
-// -------------------------
-export interface RestInfiniteResult
- extends Omit, "data">,
- QueryCacheFunctions {
- pageParams: any
-}
-
-interface InfiniteQueryConfig
- extends UseInfiniteQueryOptions {
- // getPreviousPageParam?: (lastPage: TResult, allPages: TResult[]) => TGetPageParamResult
- // getNextPageParam?: (lastPage: TResult, allPages: TResult[]) => TGetPageParamResult
-}
-
-export function useSuspenseInfiniteQuery<
- T extends AsyncFunc,
- TResult = PromiseReturnType,
- TError = DefaultError,
- TSelectedData = TResult,
->(
- queryFn: T,
- getQueryParams: (pageParam: any) => FirstParam,
- options: Omit, "queryKey"> &
- QueryNonLazyOptions,
-): [TSelectedData[], RestInfiniteResult]
-export function useSuspenseInfiniteQuery<
- T extends AsyncFunc,
- TResult = PromiseReturnType,
- TError = DefaultError,
- TSelectedData = TResult,
->(
- queryFn: T,
- getQueryParams: (pageParam: any) => FirstParam,
- options: Omit, "queryKey"> &
- QueryLazyOptions,
-): [TSelectedData[] | undefined, RestInfiniteResult]
-export function useSuspenseInfiniteQuery<
- T extends AsyncFunc,
- TResult = PromiseReturnType,
- TError = DefaultError,
- TSelectedData = TResult,
->(
- queryFn: T,
- getQueryParams: (pageParam: any) => FirstParam,
- options: Omit, "queryKey">,
-) {
- if (typeof queryFn === "undefined") {
- throw new Error("useInfiniteQuery is missing the first argument - it must be a query function")
- }
-
- let routerIsReady = false
- const router = useRouter()
- if (router) {
- routerIsReady = router?.isReady || isServer
- } else {
- routerIsReady = true
- }
- const enhancedResolverRpcClient = sanitizeQuery(queryFn)
- const queryKey = getInfiniteQueryKey(queryFn, getQueryParams)
-
- const {data, ...queryRest} = useSuspenseInfiniteReactQuery({
- // we need an extra cache key for infinite loading so that the cache for
- // for this query is stored separately since the hook result is an array of results.
- // Without this cache for usePaginatedQuery and this will conflict and break.
- queryKey: routerIsReady ? queryKey : ["_routerNotReady_"],
- queryFn: routerIsReady
- ? ({pageParam, signal}) =>
- enhancedResolverRpcClient(getQueryParams(pageParam), {fromQueryHook: true}, signal)
- : (emptyQueryFn as any),
- ...options,
- })
-
- const infiniteQueryData = data as InfiniteData
-
- if (queryRest.fetchStatus === "idle" && isServer && !infiniteQueryData) {
+ if (
+ queryRest.fetchStatus === "idle" &&
+ isServer &&
+ suspenseEnabled !== false &&
+ !data &&
+ (!options || !("suspense" in options) || options.suspense) &&
+ (!options || !("enabled" in options) || options.enabled)
+ ) {
const e = new NextError()
e.name = "Rendering Suspense fallback..."
e.digest = "DYNAMIC_SERVER_USAGE"
@@ -450,10 +312,10 @@ export function useSuspenseInfiniteQuery<
const rest = {
...queryRest,
...getQueryCacheFunctions, TResult, T>(queryFn, getQueryParams),
- pageParams: infiniteQueryData?.pageParams,
+ pageParams: data?.pageParams,
}
- return [infiniteQueryData?.pages as unknown, rest]
+ return [data?.pages as any, rest]
}
// -------------------------------------------------------------------
@@ -490,7 +352,7 @@ export declare type MutationFunction = (
export function useMutation<
TData = unknown,
- TError = DefaultError,
+ TError = unknown,
TVariables = void,
TContext = unknown,
>(
@@ -500,11 +362,11 @@ export function useMutation<
const enhancedResolverRpcClient = sanitizeMutation(mutationResolver)
const {mutate, mutateAsync, ...rest} = useReactQueryMutation(
+ (variables) => enhancedResolverRpcClient(variables, {fromQueryHook: true}),
{
- mutationFn: (variables) => enhancedResolverRpcClient(variables, {fromQueryHook: true}),
throwOnError: true,
...config,
- },
+ } as any,
)
return [mutateAsync, rest] as MutationResultPair
diff --git a/packages/blitz-rpc/src/query/utils.ts b/packages/blitz-rpc/src/query/utils.ts
index fa12cc1394..7ce9b6b341 100644
--- a/packages/blitz-rpc/src/query/utils.ts
+++ b/packages/blitz-rpc/src/query/utils.ts
@@ -31,10 +31,16 @@ type MutateOptions = {
}
export const initializeQueryClient = () => {
+ let suspenseEnabled = true
+ if (!process.env.CLI_COMMAND_CONSOLE && !process.env.CLI_COMMAND_DB) {
+ suspenseEnabled = Boolean(globalThis.__BLITZ_SUSPENSE_ENABLED)
+ }
+
return new QueryClient({
defaultOptions: {
queries: {
...(isServer && {cacheTime: 0}),
+ suspense: suspenseEnabled,
retry: (failureCount, error: any) => {
if (process.env.NODE_ENV !== "production") return false
@@ -49,7 +55,7 @@ export const initializeQueryClient = () => {
}
// Query client is initialised in `BlitzRpcPlugin`, and can only be used with BlitzRpcPlugin right now
-export const getQueryClient = () => globalThis.queryClient as QueryClient
+export const getQueryClient = () => globalThis.queryClient
function isRpcClient(f: any): f is RpcClient {
return !!f._isRpcClient
@@ -165,9 +171,7 @@ interface InvalidateQuery {
export const invalidateQuery: InvalidateQuery = (resolver = undefined, ...params: []) => {
const fullQueryKey =
typeof resolver === "undefined" ? undefined : getQueryKey(resolver, ...params)
- return getQueryClient().invalidateQueries({
- queryKey: fullQueryKey,
- })
+ return getQueryClient().invalidateQueries(fullQueryKey)
}
export function setQueryData(
diff --git a/packages/blitz-rpc/test/unit/react-query-utils.unit.test.ts b/packages/blitz-rpc/test/unit/react-query-utils.unit.test.ts
index f7d28864f2..d09fb217b7 100644
--- a/packages/blitz-rpc/test/unit/react-query-utils.unit.test.ts
+++ b/packages/blitz-rpc/test/unit/react-query-utils.unit.test.ts
@@ -59,7 +59,7 @@ describe("invalidateQuery", () => {
expect(spyRefetchQueries).toBeCalledTimes(1)
const calledWith = spyRefetchQueries.mock.calls[0]![0] as any
// json of the queryKey is "a"
- expect(calledWith.queryKey[1].json).toEqual("a")
+ expect(calledWith[1].json).toEqual("a")
})
})
@@ -90,7 +90,7 @@ describe("setQueryData", () => {
expect(spySetQueryData).toBeCalledTimes(1)
const invalidateCalledWith = spyRefetchQueries.mock.calls[0]![0] as any
- expect(invalidateCalledWith.queryKey[1].json).toEqual("params")
+ expect(invalidateCalledWith[1].json).toEqual("params")
const calledWith = spySetQueryData.mock.calls[0] as Array
expect(calledWith[0][1].json).toEqual("params")
diff --git a/patches/next-auth@4.24.7.patch b/patches/next-auth@4.24.7.patch
new file mode 100644
index 0000000000..092a042cd6
--- /dev/null
+++ b/patches/next-auth@4.24.7.patch
@@ -0,0 +1,23 @@
+diff --git a/package.json b/package.json
+index c89e03c41a03de738cfb0ad090a63c2e99dadc7b..a5f38083c24732651c427c2b2d17cbcb23495473 100644
+--- a/package.json
++++ b/package.json
+@@ -57,6 +57,18 @@
+ "./providers/*": {
+ "types": "./providers/*.d.ts",
+ "default": "./providers/*.js"
++ },
++ "./core/init": {
++ "types": "./core/init.d.ts",
++ "default": "./core/init.js"
++ },
++ "./core/lib/oauth/authorization-url": {
++ "types": "./core/lib/oauth/authorization-url.d.ts",
++ "default": "./core/lib/oauth/authorization-url.js"
++ },
++ "./core/lib/oauth/callback": {
++ "types": "./core/lib/oauth/callback.d.ts",
++ "default": "./core/lib/oauth/callback.js"
+ }
+ },
+ "files": [
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 4405629bdd..aaeb043724 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -10,6 +10,11 @@ overrides:
"@types/react": npm:types-react@rc
"@types/react-dom": npm:types-react-dom@rc
+patchedDependencies:
+ next-auth@4.24.7:
+ hash: xxwv3g3ul7bnzqsfasefw3kyq4
+ path: patches/next-auth@4.24.7.patch
+
importers:
.:
dependencies:
@@ -80,8 +85,8 @@ importers:
specifier: ^4.5.0
version: 4.6.1(prisma@4.6.1)
"@tanstack/react-query":
- specifier: 5.51.1
- version: 5.51.1(react@19.0.0)
+ specifier: 4.0.10
+ version: 4.0.10(react-dom@19.0.0)(react@19.0.0)
blitz:
specifier: 2.2.1
version: link:../../packages/blitz
@@ -160,7 +165,7 @@ importers:
version: 15.0.1(@babel/core@7.20.2)(react-dom@19.0.0)(react@19.0.0)
next-auth:
specifier: 4.24.7
- version: 4.24.7(next@15.0.1)(react-dom@19.0.0)(react@19.0.0)
+ version: 4.24.7(patch_hash=xxwv3g3ul7bnzqsfasefw3kyq4)(next@15.0.1)(react-dom@19.0.0)(react@19.0.0)
prisma:
specifier: 6.1.0
version: 6.1.0
@@ -493,8 +498,8 @@ importers:
specifier: 3.2.3
version: 3.2.3
playwright:
- specifier: 1.49.1
- version: 1.49.1
+ specifier: 1.28.0
+ version: 1.28.0
ts-node:
specifier: 10.9.1
version: 10.9.1(@types/node@18.7.13)(typescript@4.8.4)
@@ -596,8 +601,8 @@ importers:
specifier: 13.0.3
version: 13.0.3
playwright:
- specifier: 1.49.1
- version: 1.49.1
+ specifier: 1.28.0
+ version: 1.28.0
prettier:
specifier: ^2.7.1
version: 2.7.1
@@ -821,8 +826,8 @@ importers:
specifier: 3.2.3
version: 3.2.3
playwright:
- specifier: 1.49.1
- version: 1.49.1
+ specifier: 1.28.0
+ version: 1.28.0
ts-node:
specifier: 10.9.1
version: 10.9.1(@types/node@18.7.13)(typescript@4.9.5)
@@ -918,8 +923,8 @@ importers:
specifier: 6.1.0
version: 6.1.0(prisma@6.1.0)
"@tanstack/react-query":
- specifier: 5.51.1
- version: 5.51.1(react@19.0.0)
+ specifier: 4.0.10
+ version: 4.0.10(react-dom@19.0.0)(react@19.0.0)
blitz:
specifier: 2.2.1
version: link:../../packages/blitz
@@ -1259,8 +1264,8 @@ importers:
specifier: 5.0.0
version: 5.0.0
playwright-chromium:
- specifier: 1.49.1
- version: 1.49.1
+ specifier: 1.28.0
+ version: 1.28.0
react:
specifier: 19.0.0
version: 19.0.0
@@ -1607,7 +1612,7 @@ importers:
version: 15.0.1(@babel/core@7.20.2)(react-dom@19.0.0)(react@19.0.0)
next-auth:
specifier: 4.24.7
- version: 4.24.7(next@15.0.1)(react-dom@19.0.0)(react@19.0.0)
+ version: 4.24.7(patch_hash=xxwv3g3ul7bnzqsfasefw3kyq4)(next@15.0.1)(react-dom@19.0.0)(react@19.0.0)
react:
specifier: 19.0.0
version: 19.0.0
@@ -1730,8 +1735,8 @@ importers:
specifier: 1.3.7
version: 1.3.7
"@tanstack/react-query":
- specifier: 5.51.1
- version: 5.51.1(react@19.0.0)
+ specifier: 4.24.4
+ version: 4.24.4(react-dom@19.0.0)(react@19.0.0)
b64-lite:
specifier: 1.4.0
version: 1.4.0
@@ -1758,8 +1763,8 @@ importers:
specifier: 2.2.1
version: link:../config
"@tanstack/query-core":
- specifier: 5.51.1
- version: 5.51.1
+ specifier: 4.24.4
+ version: 4.24.4
"@types/debug":
specifier: 4.1.7
version: 4.1.7
@@ -6738,12 +6743,34 @@ packages:
}
dev: true
- /@tanstack/query-core@5.51.1:
+ /@tanstack/query-core@4.24.4:
resolution:
{
- integrity: sha512-fJBMQMpo8/KSsWW5ratJR5+IFr7YNJ3K2kfP9l5XObYHsgfVy1w3FJUWU4FT2fj7+JMaEg33zOcNDBo0LMwHnw==,
+ integrity: sha512-9dqjv9eeB6VHN7lD3cLo16ZAjfjCsdXetSAD5+VyKqLUvcKTL0CklGQRJu+bWzdrS69R6Ea4UZo8obHYZnG6aA==,
}
+ /@tanstack/react-query@4.0.10(react-dom@19.0.0)(react@19.0.0):
+ resolution:
+ {
+ integrity: sha512-Wn5QhZUE5wvr6rGClV7KeQIUsdTmYR9mgmMZen7DSRWauHW2UTynFg3Kkf6pw+XlxxOLsyLWwz/Q6q1lSpM3TQ==,
+ }
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+ react-native: "*"
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
+ dependencies:
+ "@tanstack/query-core": 4.24.4
+ "@types/use-sync-external-store": 0.0.3
+ react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ use-sync-external-store: 1.2.0(react@19.0.0)
+ dev: false
+
/@tanstack/react-query@4.13.0(react-dom@19.0.0)(react@19.0.0):
resolution:
{
@@ -6765,16 +6792,25 @@ packages:
use-sync-external-store: 1.2.0(react@19.0.0)
dev: true
- /@tanstack/react-query@5.51.1(react@19.0.0):
+ /@tanstack/react-query@4.24.4(react-dom@19.0.0)(react@19.0.0):
resolution:
{
- integrity: sha512-s47HKFnQ4HOJAHoIiXcpna/roMMPZJPy6fJ6p4ZNVn8+/onlLBEDd1+xc8OnDuwgvecqkZD7Z2mnSRbcWefrKw==,
+ integrity: sha512-RpaS/3T/a3pHuZJbIAzAYRu+1nkp+/enr9hfRXDS/mojwx567UiMksoqW4wUFWlwIvWTXyhot2nbIipTKEg55Q==,
}
peerDependencies:
- react: ^18.0.0
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
+ react-native: "*"
+ peerDependenciesMeta:
+ react-dom:
+ optional: true
+ react-native:
+ optional: true
dependencies:
- "@tanstack/query-core": 5.51.1
+ "@tanstack/query-core": 4.24.4
react: 19.0.0
+ react-dom: 19.0.0(react@19.0.0)
+ use-sync-external-store: 1.2.0(react@19.0.0)
dev: false
/@testim/chrome-version@1.1.2:
@@ -7732,6 +7768,13 @@ packages:
integrity: sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==,
}
+ /@types/use-sync-external-store@0.0.3:
+ resolution:
+ {
+ integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==,
+ }
+ dev: false
+
/@types/vinyl@2.0.6:
resolution:
{
@@ -13696,17 +13739,6 @@ packages:
integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==,
}
- /fsevents@2.3.2:
- resolution:
- {
- integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==,
- }
- engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
- os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
-
/fsevents@2.3.3:
resolution:
{
@@ -17999,7 +18031,7 @@ packages:
}
dev: false
- /next-auth@4.24.7(next@15.0.1)(react-dom@19.0.0)(react@19.0.0):
+ /next-auth@4.24.7(patch_hash=xxwv3g3ul7bnzqsfasefw3kyq4)(next@15.0.1)(react-dom@19.0.0)(react@19.0.0):
resolution:
{
integrity: sha512-iChjE8ov/1K/z98gdKbn2Jw+2vLgJtVV39X+rCP5SGnVQuco7QOr19FRNGMIrD8d3LYhHWV9j9sKLzq1aDWWQQ==,
@@ -18025,6 +18057,7 @@ packages:
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
uuid: 8.3.2
+ patched: true
/next-router-mock@0.9.1(next@15.0.1)(react@19.0.0):
resolution:
@@ -19276,38 +19309,37 @@ packages:
pathe: 0.3.2
dev: true
- /playwright-chromium@1.49.1:
+ /playwright-chromium@1.28.0:
resolution:
{
- integrity: sha512-XAQDkZ1Eem1OONhfS8B2LM2mgHG/i5jIxooxjvqjbF/9GnLnRTJHdQamNjo1e4FZvt7J0BFD/15+qAcT0eKlfA==,
+ integrity: sha512-5IUBJShMJMaK6NmRj/7KWdvVqd7J8DqLH0wVdXBs/4MfZUAvByBB35y5v6B33NjlJg3SZGX5alR8TANrcKaJNA==,
}
- engines: {node: ">=18"}
+ engines: {node: ">=14"}
hasBin: true
requiresBuild: true
dependencies:
- playwright-core: 1.49.1
+ playwright-core: 1.28.0
dev: true
- /playwright-core@1.49.1:
+ /playwright-core@1.28.0:
resolution:
{
- integrity: sha512-BzmpVcs4kE2CH15rWfzpjzVGhWERJfmnXmniSyKeRZUs9Ws65m+RGIi7mjJK/euCegfn3i7jvqWeWyHe9y3Vgg==,
+ integrity: sha512-nJLknd28kPBiCNTbqpu6Wmkrh63OEqJSFw9xOfL9qxfNwody7h6/L3O2dZoWQ6Oxcm0VOHjWmGiCUGkc0X3VZA==,
}
- engines: {node: ">=18"}
+ engines: {node: ">=14"}
hasBin: true
dev: true
- /playwright@1.49.1:
+ /playwright@1.28.0:
resolution:
{
- integrity: sha512-VYL8zLoNTBxVOrJBbDuRgDWa3i+mfQgDTrL8Ah9QXZ7ax4Dsj0MSq5bYgytRnDVVe+njoKnfsYkH3HzqVj5UZA==,
+ integrity: sha512-kyOXGc5y1mgi+hgEcCIyE1P1+JumLrxS09nFHo5sdJNzrucxPRAGwM4A2X3u3SDOfdgJqx61yIoR6Av+5plJPg==,
}
- engines: {node: ">=18"}
+ engines: {node: ">=14"}
hasBin: true
+ requiresBuild: true
dependencies:
- playwright-core: 1.49.1
- optionalDependencies:
- fsevents: 2.3.2
+ playwright-core: 1.28.0
dev: true
/pluralize@8.0.0:
@@ -22947,7 +22979,6 @@ packages:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
react: 19.0.0
- dev: true
/use@3.1.1:
resolution: