Compare commits
1 Commits
@blitzjs/c
...
2.2.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bddc1d88f5 |
@@ -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
|
||||
2
.github/workflows/main.yml
vendored
2
.github/workflows/main.yml
vendored
@@ -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
|
||||
|
||||
4
.github/workflows/pr-release.yml
vendored
4
.github/workflows/pr-release.yml
vendored
@@ -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
|
||||
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
export default function Loading() {
|
||||
// You can add any UI inside Loading, including a Skeleton.
|
||||
return "Loading..."
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
2
apps/toolkit-app-passportjs/next-env.d.ts
vendored
2
apps/toolkit-app-passportjs/next-env.d.ts
vendored
@@ -2,4 +2,4 @@
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -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))
|
||||
|
||||
48
apps/toolkit-app/src/pages/api/auth/[...nextauth].ts
Normal file
48
apps/toolkit-app/src/pages/api/auth/[...nextauth].ts
Normal file
@@ -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: "/" }
|
||||
},
|
||||
})
|
||||
)
|
||||
@@ -44,6 +44,11 @@ const UserInfo = () => {
|
||||
<Link href={"/auth/login"} className={styles.loginButton}>
|
||||
<strong>Login</strong>
|
||||
</Link>
|
||||
<Link href="/api/auth/github/login" passHref legacyBehavior>
|
||||
<a className="button small">
|
||||
<strong>Sign in with GitHub</strong>
|
||||
</a>
|
||||
</Link>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
2
apps/web/next-env.d.ts
vendored
2
apps/web/next-env.d.ts
vendored
@@ -2,4 +2,4 @@
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// 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.
|
||||
|
||||
44
apps/web/src/pages/api/auth/[...auth].ts
Normal file
44
apps/web/src/pages/api/auth/[...auth].ts
Normal file
@@ -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})
|
||||
},
|
||||
),
|
||||
},
|
||||
],
|
||||
}),
|
||||
)
|
||||
@@ -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 (
|
||||
<div>
|
||||
{usersPages.map((usersPage) =>
|
||||
|
||||
@@ -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 (
|
||||
<div>
|
||||
{users.map((u) => (
|
||||
|
||||
@@ -7,7 +7,7 @@ function UsersPage() {
|
||||
<div>
|
||||
Users:
|
||||
<ul>
|
||||
{users?.map((user) => (
|
||||
{users.map((user) => (
|
||||
<li key={user.id}>
|
||||
{user.name} - {user.email}
|
||||
</li>
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 <div>Loading...</div>
|
||||
return (
|
||||
<>
|
||||
<div>
|
||||
<div id="content">{result}</div>
|
||||
<button
|
||||
id="logout"
|
||||
@@ -18,14 +17,16 @@ function Content() {
|
||||
>
|
||||
logout
|
||||
</button>
|
||||
</>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function AuthenticatedQuery() {
|
||||
return (
|
||||
<div id="page">
|
||||
<Content />
|
||||
<Suspense fallback={"Loading..."}>
|
||||
<Content />
|
||||
</Suspense>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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 (
|
||||
<div>
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 <div id="content">{result}</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -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 (
|
||||
<div>
|
||||
|
||||
@@ -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 (
|
||||
<div>
|
||||
|
||||
@@ -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 (
|
||||
<div>
|
||||
|
||||
@@ -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 (
|
||||
<div>
|
||||
|
||||
@@ -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 (
|
||||
<div>
|
||||
|
||||
@@ -32,9 +32,9 @@ type Props = {
|
||||
}
|
||||
|
||||
export const getServerSideProps = gSSP<Props>(async ({ctx}) => {
|
||||
await getQueryClient().prefetchQuery({
|
||||
queryKey: getQueryKey(getNoauthBasic),
|
||||
})
|
||||
await getQueryClient().prefetchQuery(getQueryKey(getNoauthBasic, null), () =>
|
||||
getNoauthBasic(null, ctx),
|
||||
)
|
||||
return {
|
||||
props: {
|
||||
dehydratedState: dehydrate(queryClient),
|
||||
|
||||
@@ -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 (
|
||||
<div id="session">
|
||||
<>
|
||||
|
||||
2
integration-tests/auth/next-env.d.ts
vendored
2
integration-tests/auth/next-env.d.ts
vendored
@@ -2,4 +2,4 @@
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
/// <reference types="next/navigation-types/compat/navigation" />
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -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": "."
|
||||
|
||||
2
integration-tests/middleware/next-env.d.ts
vendored
2
integration-tests/middleware/next-env.d.ts
vendored
@@ -3,4 +3,4 @@
|
||||
/// <reference types="next/navigation-types/compat/navigation" />
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -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<string>()
|
||||
return (
|
||||
<div>
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
3
integration-tests/no-suspense/next-env.d.ts
vendored
3
integration-tests/no-suspense/next-env.d.ts
vendored
@@ -1,6 +1,5 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
/// <reference types="next/navigation-types/compat/navigation" />
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -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": "."
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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\\")."`;
|
||||
|
||||
@@ -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<typeof useSuspenseQuery>[2] = {} as any,
|
||||
options: Parameters<typeof useQuery>[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 = () => (
|
||||
<React.Suspense fallback="Loading...">
|
||||
<TestSuspenseHarness />
|
||||
<TestHarness />
|
||||
</React.Suspense>
|
||||
)
|
||||
|
||||
@@ -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 <div></div>
|
||||
}
|
||||
const ui = () => <Demo />
|
||||
|
||||
const {rerender} = render(ui(), {
|
||||
wrapper: ({children}) => (
|
||||
<BlitzProvider>
|
||||
<RouterContext.Provider value={mockRouter}>{children}</RouterContext.Provider>
|
||||
</BlitzProvider>
|
||||
),
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe("useQuery", () => {
|
||||
const setupHook = (
|
||||
ID: string,
|
||||
params: any,
|
||||
queryFn: (...args: any) => any,
|
||||
options: Parameters<typeof useQuery>[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 <div>Loading...</div>
|
||||
}
|
||||
return (
|
||||
<div id={`harness-${ID}`}>
|
||||
<span>{data ? `Ready${ID}` : "No data"}</span>
|
||||
<span>{data}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const ui = () => <TestHarness />
|
||||
|
||||
const {rerender} = render(ui(), {
|
||||
wrapper: ({children}) => (
|
||||
<BlitzProvider>
|
||||
<RouterContext.Provider value={mockRouter}>{children}</RouterContext.Provider>
|
||||
</BlitzProvider>
|
||||
),
|
||||
})
|
||||
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 <div></div>
|
||||
}
|
||||
const ui = () => <Demo />
|
||||
@@ -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: () => {},
|
||||
})
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
/// <reference types="next/navigation-types/compat/navigation" />
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -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<string>()
|
||||
return (
|
||||
<div>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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<string>()
|
||||
return (
|
||||
<div>
|
||||
|
||||
@@ -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 <div id="data">{data ? data : "no-data"}</div>
|
||||
|
||||
@@ -51,22 +51,22 @@ const runTests = () => {
|
||||
)
|
||||
})
|
||||
|
||||
// describe("prefetch infinite query", () => {
|
||||
// it(
|
||||
// "should work",
|
||||
// async () => {
|
||||
// const browser = await webdriver(appPort, "/page-with-prefetch-inf-query")
|
||||
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")
|
||||
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,
|
||||
// )
|
||||
// })
|
||||
if (browser) await browser.close()
|
||||
},
|
||||
5000 * 60 * 2,
|
||||
)
|
||||
})
|
||||
|
||||
describe("invalidate query", () => {
|
||||
it(
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
/// <reference types="next/navigation-types/compat/navigation" />
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -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 <div id="content">{result}</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -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": "."
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<Ctx>
|
||||
}
|
||||
|
||||
@@ -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" &&
|
||||
|
||||
@@ -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 (
|
||||
<QueryClientProvider client={client || globalThis.queryClient}>
|
||||
<HydrationBoundary state={dehydratedState} options={hydrateOptions}>
|
||||
<QueryClientProvider
|
||||
client={client || globalThis.queryClient}
|
||||
contextSharing={contextSharing}
|
||||
>
|
||||
<Hydrate state={dehydratedState} options={hydrateOptions}>
|
||||
{children}
|
||||
</HydrationBoundary>
|
||||
</Hydrate>
|
||||
</QueryClientProvider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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<Ctx>
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -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<TResult, TError> = Omit<UseQueryResult<TResult, TErr
|
||||
export function useQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TError = unknown,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
params: FirstParam<T>,
|
||||
options?: Omit<UseQueryOptions<TResult, TError, TSelectedData>, "queryKey"> & QueryNonLazyOptions,
|
||||
): [TSelectedData | undefined, RestQueryResult<TSelectedData | undefined, TError>]
|
||||
options?: UseQueryOptions<TResult, TError, TSelectedData> & QueryNonLazyOptions,
|
||||
): [TSelectedData, RestQueryResult<TSelectedData, TError>]
|
||||
export function useQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TError = unknown,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
params: FirstParam<T>,
|
||||
options: Omit<UseQueryOptions<TResult, TError, TSelectedData>, "queryKey"> & QueryLazyOptions,
|
||||
): [TSelectedData | undefined, RestQueryResult<TSelectedData | undefined, TError>]
|
||||
options: UseQueryOptions<TResult, TError, TSelectedData> & QueryLazyOptions,
|
||||
): [TSelectedData | undefined, RestQueryResult<TSelectedData, TError>]
|
||||
export function useQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TError = unknown,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
params: FirstParam<T>,
|
||||
options: Omit<UseQueryOptions<TResult, TError, TSelectedData>, "queryKey"> = {},
|
||||
options: UseQueryOptions<TResult, TError, TSelectedData> = {},
|
||||
) {
|
||||
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<T>),
|
||||
: (emptyQueryFn as any),
|
||||
...options,
|
||||
enabled,
|
||||
})
|
||||
|
||||
const rest = {
|
||||
...queryRest,
|
||||
...getQueryCacheFunctions<FirstParam<T>, TResult, T>(queryFn, params),
|
||||
}
|
||||
|
||||
return [data, rest]
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// useSuspenseQuery
|
||||
// -------------------------
|
||||
|
||||
export function useSuspenseQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
params: FirstParam<T>,
|
||||
options?: Omit<UseQueryOptions<TResult, TError, TSelectedData>, "queryKey"> & QueryNonLazyOptions,
|
||||
): [TSelectedData, RestQueryResult<TSelectedData, TError>]
|
||||
export function useSuspenseQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
params: FirstParam<T>,
|
||||
options: Omit<UseSuspenseQueryOptions<TResult, TError, TSelectedData>, "queryKey"> &
|
||||
QueryLazyOptions,
|
||||
): [TSelectedData | undefined, RestQueryResult<TSelectedData, TError>]
|
||||
export function useSuspenseQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
params: FirstParam<T>,
|
||||
options: Omit<UseSuspenseQueryOptions<TResult, TError, TSelectedData>, "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<T>),
|
||||
...options,
|
||||
})
|
||||
|
||||
const rest = {
|
||||
...queryRest,
|
||||
...getQueryCacheFunctions<FirstParam<T>, TResult, T>(queryFn, params),
|
||||
}
|
||||
|
||||
// return [data, rest as RestQueryResult<TResult>]
|
||||
return [data, rest]
|
||||
}
|
||||
|
||||
@@ -206,42 +139,43 @@ export type RestPaginatedResult<TResult, TError> = Omit<UseQueryResult<TResult,
|
||||
export function usePaginatedQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TError = unknown,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
params: FirstParam<T>,
|
||||
options?: Omit<UseQueryOptions<TResult, TError, TSelectedData>, "queryKey"> & QueryNonLazyOptions,
|
||||
options?: UseQueryOptions<TResult, TError, TSelectedData> & QueryNonLazyOptions,
|
||||
): [TSelectedData, RestPaginatedResult<TSelectedData, TError>]
|
||||
export function usePaginatedQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = unknown,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
params: FirstParam<T>,
|
||||
options: UseQueryOptions<TResult, TError, TSelectedData> & QueryLazyOptions,
|
||||
): [TSelectedData | undefined, RestPaginatedResult<TSelectedData, TError>]
|
||||
export function usePaginatedQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TError = unknown,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
params: FirstParam<T>,
|
||||
options: Omit<UseQueryOptions<TResult, TError, TSelectedData>, "queryKey"> & QueryLazyOptions,
|
||||
): [TSelectedData | undefined, RestPaginatedResult<TSelectedData, TError>]
|
||||
export function usePaginatedQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
params: FirstParam<T>,
|
||||
options: Omit<UseQueryOptions<TResult, TError, TSelectedData>, "queryKey"> = {},
|
||||
options: UseQueryOptions<TResult, TError, TSelectedData> = {},
|
||||
) {
|
||||
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<T>),
|
||||
: (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<TResult, TError, TSelectedData>
|
||||
export function useInfiniteQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TError = unknown,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
getQueryParams: (pageParam: any) => FirstParam<T>,
|
||||
options: Omit<InfiniteQueryConfig<TResult, TError, TSelectedData>, "queryKey"> &
|
||||
QueryNonLazyOptions,
|
||||
options: InfiniteQueryConfig<TResult, TError, TSelectedData> & QueryNonLazyOptions,
|
||||
): [TSelectedData[], RestInfiniteResult<TSelectedData, TError>]
|
||||
export function useInfiniteQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = unknown,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
getQueryParams: (pageParam: any) => FirstParam<T>,
|
||||
options: InfiniteQueryConfig<TResult, TError, TSelectedData> & QueryLazyOptions,
|
||||
): [TSelectedData[] | undefined, RestInfiniteResult<TSelectedData, TError>]
|
||||
export function useInfiniteQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TError = unknown,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
getQueryParams: (pageParam: any) => FirstParam<T>,
|
||||
options: Omit<InfiniteQueryConfig<TResult, TError, TSelectedData>, "queryKey"> & QueryLazyOptions,
|
||||
): [TSelectedData[] | undefined, RestInfiniteResult<TSelectedData, TError>]
|
||||
export function useInfiniteQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
getQueryParams: (pageParam: any) => FirstParam<T>,
|
||||
options: Omit<InfiniteQueryConfig<TResult, TError, TSelectedData>, "queryKey">,
|
||||
options: InfiniteQueryConfig<TResult, TError, TSelectedData>,
|
||||
) {
|
||||
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<TResult>
|
||||
|
||||
const rest = {
|
||||
...queryRest,
|
||||
...getQueryCacheFunctions<FirstParam<T>, TResult, T>(queryFn, getQueryParams),
|
||||
pageParams: infiniteQueryData?.pageParams,
|
||||
}
|
||||
|
||||
return [infiniteQueryData?.pages as any, rest]
|
||||
}
|
||||
|
||||
// -------------------------
|
||||
// useInfiniteQuery
|
||||
// -------------------------
|
||||
export interface RestInfiniteResult<TResult, TError>
|
||||
extends Omit<UseInfiniteQueryResult<TResult, TError>, "data">,
|
||||
QueryCacheFunctions<TResult> {
|
||||
pageParams: any
|
||||
}
|
||||
|
||||
interface InfiniteQueryConfig<TResult, TError, TSelectedData>
|
||||
extends UseInfiniteQueryOptions<TResult, TError, TSelectedData, TResult> {
|
||||
// getPreviousPageParam?: (lastPage: TResult, allPages: TResult[]) => TGetPageParamResult
|
||||
// getNextPageParam?: (lastPage: TResult, allPages: TResult[]) => TGetPageParamResult
|
||||
}
|
||||
|
||||
export function useSuspenseInfiniteQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
getQueryParams: (pageParam: any) => FirstParam<T>,
|
||||
options: Omit<UseSuspenseInfiniteQueryOptions<TResult, TError, TSelectedData>, "queryKey"> &
|
||||
QueryNonLazyOptions,
|
||||
): [TSelectedData[], RestInfiniteResult<TSelectedData, TError>]
|
||||
export function useSuspenseInfiniteQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
getQueryParams: (pageParam: any) => FirstParam<T>,
|
||||
options: Omit<UseSuspenseInfiniteQueryOptions<TResult, TError, TSelectedData>, "queryKey"> &
|
||||
QueryLazyOptions,
|
||||
): [TSelectedData[] | undefined, RestInfiniteResult<TSelectedData, TError>]
|
||||
export function useSuspenseInfiniteQuery<
|
||||
T extends AsyncFunc,
|
||||
TResult = PromiseReturnType<T>,
|
||||
TError = DefaultError,
|
||||
TSelectedData = TResult,
|
||||
>(
|
||||
queryFn: T,
|
||||
getQueryParams: (pageParam: any) => FirstParam<T>,
|
||||
options: Omit<UseSuspenseInfiniteQueryOptions<TResult, TError, TSelectedData>, "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<TResult>
|
||||
|
||||
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<FirstParam<T>, 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<TData, TVariables = unknown> = (
|
||||
|
||||
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<TData, TError, TVariables, TContext>(
|
||||
(variables) => enhancedResolverRpcClient(variables, {fromQueryHook: true}),
|
||||
{
|
||||
mutationFn: (variables) => enhancedResolverRpcClient(variables, {fromQueryHook: true}),
|
||||
throwOnError: true,
|
||||
...config,
|
||||
},
|
||||
} as any,
|
||||
)
|
||||
|
||||
return [mutateAsync, rest] as MutationResultPair<TData, TError, TVariables, TContext>
|
||||
|
||||
@@ -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<any, any> {
|
||||
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<TInput, TResult, T extends AsyncFunc>(
|
||||
|
||||
@@ -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<any>
|
||||
expect(calledWith[0][1].json).toEqual("params")
|
||||
|
||||
23
patches/next-auth@4.24.7.patch
Normal file
23
patches/next-auth@4.24.7.patch
Normal file
@@ -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": [
|
||||
131
pnpm-lock.yaml
generated
131
pnpm-lock.yaml
generated
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user