1
0
mirror of synced 2026-02-04 12:08:33 -05:00

Compare commits

...

60 Commits

Author SHA1 Message Date
github-actions[bot]
024cd819e3 Version Packages (alpha) (#3512)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-07-06 19:25:31 +02:00
Dillon Raphael
12cb7a727d Upgrade Prisma to v4.0.0 (#3511)
* Upgrade Prisma to v4.0.0

* Changeset
2022-07-06 19:21:36 +02:00
github-actions[bot]
923703b661 Version Packages (alpha) (#3510)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-07-06 18:26:09 +02:00
Dillon Raphael
70f9ae4921 Handle next/dynamic default import in codemod (#3509) 2022-07-06 18:21:45 +02:00
beerose
c738ecacbc Remove --tag option from release script 2022-07-06 17:07:55 +02:00
github-actions[bot]
ad0b087d9f Version Packages (alpha) (#3507)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-07-06 16:03:29 +02:00
Dillon Raphael
dc694cf1cf remove mounted check from withBlitz (#3504)
Co-authored-by: Aleksandra <alexsandra.sikora@gmail.com>
2022-07-06 15:59:18 +02:00
Aleksandra
4c221b655e Tag @blitzjs/rpc and @blitzjs/auth with alpha, update package.json files (#3508) 2022-07-06 13:56:25 +02:00
Aleksandra
c11f0401cf Update Next.js version and addBasePath location (#3506) 2022-07-06 13:14:48 +02:00
github-actions[bot]
830b51d0dc Version Packages (alpha) (#3492)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-07-04 17:39:14 +02:00
David
bec9512e30 Expand & rename baseResolverPath (#3421)
Co-authored-by: beerose <alexsandra.sikora@gmail.com>
2022-07-04 17:35:36 +02:00
Dillon Raphael
1493729d6b forked changesets action 2022-07-04 16:48:30 +02:00
Dillon Raphael
6bb5980da9 revert changesets action version 2022-07-04 15:44:21 +02:00
Dillon Raphael
7310f7171d use forked changesets github action 2022-07-04 15:32:28 +02:00
github-actions[bot]
d855ee3e1d Version Packages (alpha) (#3487)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-07-04 13:29:42 +02:00
Aleksandra
93851d90ca Handle duplicated imports with Blitz codemod (#3486) 2022-07-04 13:25:44 +02:00
beerose
3ab05b3cda Update pnpm-lock.yaml 2022-07-01 17:07:36 +02:00
github-actions[bot]
bb3dd56f7a Version Packages (alpha) (#3482)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-07-01 17:06:10 +02:00
Aleksandra
1d9804a610 remove references to the logging package (#3474) 2022-07-01 17:01:41 +02:00
Aleksandra
0fd1f9c9b1 Revert codemod changes (#3483) 2022-07-01 16:10:28 +02:00
Aleksandra
b86b569d56 Remove as any assertion for the PrismaStorage argument (#3481) 2022-07-01 16:04:58 +02:00
Aleksandra
b405c1e876 Add missing _document and 404 pages to the templates (#3480) 2022-07-01 12:44:37 +02:00
Dillon Raphael
c957828ea6 remove release-drafter 2022-06-30 11:54:31 +02:00
Dillon Raphael
c78e5c4704 set config name in release action 2022-06-30 11:47:58 +02:00
Dillon Raphael
009664e0f5 Merge branch 'main' of github.com:blitz-js/blitz 2022-06-30 11:33:42 +02:00
Dillon Raphael
3110522dca release drafter template 2022-06-30 11:33:32 +02:00
github-actions[bot]
7269ac2bc5 Version Packages (alpha) (#3472)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-06-30 11:09:25 +02:00
Datner
7a7ce2229e Add middleware integration tests (#3411)
* Set up middleware integration test application

* Add middleware integration test

* Update pnpm lock

Co-authored-by: Aleksandra <alexsandra.sikora@gmail.com>
2022-06-30 11:05:30 +02:00
Dillon Raphael
10c23d3d20 Merge branch 'main' of github.com:blitz-js/blitz 2022-06-29 13:03:54 +02:00
Dillon Raphael
d93b05d0ac Add github release template 2022-06-29 13:03:41 +02:00
Dillon Raphael
aafdc5b4c4 Codemod: Move middlewares from blitz config to blitz server (#3471)
Co-authored-by: Aleksandra <alexsandra.sikora@gmail.com>
2022-06-29 12:52:56 +02:00
Dillon Raphael
37ef42811b Merge branch 'main' of github.com:blitz-js/blitz 2022-06-29 12:24:44 +02:00
Dillon Raphael
34cc29e40c Turn off auto github releases 2022-06-29 12:24:26 +02:00
Fran Zekan
bee19a259d Hook up onError function for rpc server and next (#3460)
Co-authored-by: beerose <alexsandra.sikora@gmail.com>
2022-06-29 12:18:22 +02:00
Fran Zekan
9ada0f6661 Allow customizing PreviewData in gSSP (#3461) 2022-06-29 11:42:41 +02:00
Dillon Raphael
425559d360 pnpm install without frozen lockfile for github release action 2022-06-29 10:40:12 +02:00
Dillon Raphael
0411689b1d pnpmlock 2022-06-26 06:28:07 -04:00
github-actions[bot]
0d3514cd27 Version Packages (alpha) (#3464)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-06-26 06:18:37 -04:00
Dillon Raphael
a9edde6d83 pnpmlock 2022-06-26 06:05:38 -04:00
Dillon Raphael
5c5decbce2 Remove suspense wrapper from withBlitz (#3463)
* remove suspense wrapper

* changeset
2022-06-26 06:02:45 -04:00
beerose
e476beba39 Update pnpm-lock.yaml 2022-06-23 17:00:27 +02:00
github-actions[bot]
1a1b23a7e8 Version Packages (alpha) (#3459)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-06-23 16:59:54 +02:00
Fran Zekan
ae0b714f69 Expanding types for GetServerSideProps (#3457)
Co-authored-by: beerose <alexsandra.sikora@gmail.com>
2022-06-23 16:56:41 +02:00
Aleksandra
7817fe3a85 Add missing RouteUrlObject on Page.authenticate.redirectTo (#3458) 2022-06-23 16:45:27 +02:00
beerose
30bb474abb Update pnpm-lock.yaml 2022-06-23 13:32:30 +02:00
github-actions[bot]
135b30efde Version Packages (alpha) (#3456)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-06-23 13:31:59 +02:00
Aleksandra
527e48ac3e Fix running bin commands with Blitz CLI (#3455) 2022-06-23 13:29:22 +02:00
beerose
b905270875 Update pnpm-lock.yaml 2022-06-23 12:56:21 +02:00
github-actions[bot]
96ea5291e4 Version Packages (alpha) (#3454)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-06-23 12:54:23 +02:00
Aleksandra
9c2e7d372c Import useRouter form next/router in useParams.tsx (#3453) 2022-06-23 12:47:01 +02:00
beerose
493d505b24 Update pnpm-lock 2022-06-22 12:12:57 +02:00
github-actions[bot]
09da992bef Version Packages (alpha) (#3450)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-06-22 12:11:54 +02:00
Dillon Raphael
bbac7906e8 fix codemod for wrapping \_app arrow function and nested pages directory (#3443)
Co-authored-by: Aleksandra <alexsandra.sikora@gmail.com>
2022-06-22 10:55:35 +02:00
Dillon Raphael
21ca3a9b02 pnpmlock 2022-06-21 10:27:09 -04:00
github-actions[bot]
32274803d9 Version Packages (alpha) (#3449)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-06-21 10:25:53 -04:00
Dillon Raphael
9ded8dacba Export useParam & useParams from @blitzjs/next (#3448) 2022-06-21 14:45:29 +02:00
beerose
80ffbeaa4c Update pnpm-lock.yaml 2022-06-19 18:20:49 +02:00
github-actions[bot]
6bde1b07da Version Packages (alpha) (#3445)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-06-19 18:18:57 +02:00
Datner
b918055bf3 Add aliases for Blitz CLI commands (#3410)
Co-authored-by: Aleksandra <alexsandra.sikora@gmail.com>
2022-06-19 18:13:43 +02:00
Aleksandra
f9a2971f05 Improve typings in blitz cli package (#3444) 2022-06-19 15:48:27 +02:00
131 changed files with 2084 additions and 713 deletions

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/next": patch
---
Use `useRouter` from next/router in useParams function

View File

@@ -0,0 +1,6 @@
---
"@blitzjs/auth": patch
"@blitzjs/next": patch
---
Add missing RouteUrlObject on Page.authenticate.redirectTo

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/codemod": patch
---
fix codemod for wrapping \_app arrow function & fix codemod for nested pages directory

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/next": patch
---
Allow passing optional type argument for ParamsType in GSSP

View File

@@ -0,0 +1,6 @@
---
"@blitzjs/next": patch
"@blitzjs/rpc": patch
---
Support RPC error middleware

View File

@@ -0,0 +1,6 @@
---
"@blitzjs/rpc": patch
"@blitzjs/generator": patch
---
Update Next.js version and addBasePath location

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/next": patch
---
useParam & useParams functions now accessible from @blitzjs/next

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/codemod": patch
---
Move middlewares from blitz config to blitz server with codemod

View File

@@ -0,0 +1,6 @@
---
"blitz": patch
"@blitzjs/codemod": patch
---
Handle duplicate imports with Blitz upgrade-legacy codemod

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/codemod": patch
---
Handle next/dynamic default import in codemod

View File

@@ -17,7 +17,8 @@
"toolkit-app": "1.0.0",
"test-qm": "0.0.0",
"test-no-suspense": "0.0.0",
"test-trailing-slash": "0.0.0"
"test-trailing-slash": "0.0.0",
"test-middleware": "0.0.0"
},
"changesets": [
"big-phones-bow",
@@ -27,20 +28,29 @@
"dirty-monkeys-greet",
"eleven-humans-sort",
"empty-berries-rule",
"empty-turkeys-wave",
"fair-wombats-sneeze",
"famous-kings-explain",
"fast-trainers-kneel",
"flat-bees-approve",
"four-brooms-juggle",
"four-meals-fry",
"fuzzy-jars-admire",
"gentle-dogs-reply",
"good-insects-wink",
"great-months-train",
"green-papayas-do",
"healthy-rice-shout",
"hot-drinks-approve",
"late-steaks-give",
"lemon-games-press",
"lovely-colts-share",
"lucky-cows-try",
"modern-cameras-pull",
"moody-squids-cheer",
"nervous-beds-travel",
"nervous-dolls-rule",
"new-coats-turn",
"nice-starfishes-live",
"nine-onions-admire",
"ninety-pets-heal",
@@ -50,22 +60,33 @@
"poor-peas-lick",
"poor-penguins-look",
"poor-shrimps-think",
"popular-teachers-pay",
"purple-singers-greet",
"quiet-feet-travel",
"quiet-pans-hunt",
"quiet-sloths-rule",
"rich-chairs-invent",
"rich-queens-travel",
"sharp-falcons-begin",
"shy-olives-hang",
"silent-colts-reply",
"slow-walls-poke",
"small-socks-confess",
"smooth-planets-admire",
"strong-apes-reply",
"stupid-walls-sell",
"swift-drinks-dress",
"tall-meals-learn",
"tame-keys-reply",
"tasty-news-collect",
"ten-hairs-listen",
"ten-rivers-burn",
"tender-pianos-check",
"thick-parrots-float",
"thirty-countries-build",
"twenty-beans-pump",
"two-kiwis-help",
"two-tigers-type",
"unlucky-papayas-sleep",
"violet-bags-leave",
"violet-lions-help",

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/next": patch
---
Removes the suspense wrapper from withBlitz since it's not needed

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/next": patch
---
Removes the check for when withBlitz is mounted before rendering the users app. We had this previously to avoid the react 18 suspense error being showin in development with nextjs.

View File

@@ -0,0 +1,8 @@
---
"blitz": patch
"@blitzjs/auth": patch
"@blitzjs/next": patch
"@blitzjs/rpc": patch
---
Remove references to the logging package

View File

@@ -0,0 +1,6 @@
---
"@blitzjs/next": patch
"@blitzjs/rpc": patch
---
Allow resolverPath to be a function which is ran for every file path that is converted to RPC Route

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Add missing \_document.tsx and 404.tsx pages to the new app templates

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Remove as any assertion for the PrismaStorage argument

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Upgrade Prisma to v4.0.0

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Add aliases for Blitz CLI commands

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/next": patch
---
Allow customizing PreviewData in gSSP

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Fix running bin commands with Blitz CLI

2
.github/CODEOWNERS vendored
View File

@@ -1,5 +1,5 @@
# https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners
* @flybayer @beerose
* @flybayer @beerose @dillonraphael
packages/generator/templates**/* @flybayer

View File

@@ -7,9 +7,15 @@ on:
concurrency: ${{ github.workflow }}-${{ github.ref }}
permissions:
contents: read
jobs:
release:
name: Release
permissions:
contents: write
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
@@ -32,13 +38,21 @@ jobs:
uses: pnpm/action-setup@646cdf48217256a3d0b80361c5a50727664284f2
with:
version: 6.32.6
- run: pnpm install --frozen-lockfile
- run: pnpm install --no-frozen-lockfile
- run: pnpm build
- name: Create Release Pull Request
uses: changesets/action@v1
uses: blitz-js/changesets-action@main
with:
publish: pnpm release
createGithubReleases: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
# - name: Github Release
# uses: release-drafter/release-drafter@v5.19.0
# with:
# config-name: release-drafter.yml
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,5 +1,5 @@
import { NotFoundError } from "blitz"
import { db } from "db"
import db from "db"
import { authenticateUser } from "./login"
import { ChangePassword } from "../validations"
import { resolver } from "@blitzjs/rpc"

View File

@@ -1,6 +1,6 @@
import { generateToken, hash256 } from "@blitzjs/auth"
import { resolver } from "@blitzjs/rpc"
import { db } from "db"
import db from "db"
import { forgotPasswordMailer } from "mailers/forgotPasswordMailer"
import { ForgotPassword } from "../validations"

View File

@@ -1,7 +1,7 @@
import { SecurePassword } from "@blitzjs/auth"
import { resolver } from "@blitzjs/rpc"
import { AuthenticationError } from "blitz"
import { db } from "db"
import db from "db"
import { Role } from "types"
import { Login } from "../validations"

View File

@@ -1,5 +1,5 @@
import { SecurePassword, hash256 } from "@blitzjs/auth"
import { db } from "db"
import db from "db"
import { ResetPassword } from "../validations"
import login from "./login"

View File

@@ -1,5 +1,6 @@
import { db } from "db"
import db from "db"
import { SecurePassword } from "@blitzjs/auth"
import { Role } from "types"
export default async function signup(input, ctx) {
const blitzContext = ctx
@@ -13,6 +14,7 @@ export default async function signup(input, ctx) {
await blitzContext.session.$create({
userId: user.id,
role: user.role as Role,
})
return { userId: blitzContext.session.userId, ...user, email: input.email }

View File

@@ -1,14 +1,13 @@
import { setupBlitzServer } from "@blitzjs/next"
import { AuthServerPlugin, PrismaStorage } from "@blitzjs/auth"
import { db } from "db"
import db from "db"
import { simpleRolesIsAuthorized } from "@blitzjs/auth"
const { gSSP, gSP, api } = setupBlitzServer({
plugins: [
AuthServerPlugin({
cookiePrefix: "web-cookie-prefix",
// TODO fix type
storage: PrismaStorage(db as any),
storage: PrismaStorage(db),
isAuthorized: simpleRolesIsAuthorized,
}),
],

View File

@@ -1,5 +1,5 @@
import { Ctx } from "blitz"
import { db } from "db"
import db from "db"
export default async function getCurrentUser(_ = null, { session }: Ctx) {
if (!session.userId) return null

View File

@@ -5,4 +5,4 @@ const EnhancedPrisma = enhancePrisma(PrismaClient)
export * from "@prisma/client"
const db = new EnhancedPrisma()
export { db }
export default db

View File

@@ -1,4 +1,4 @@
import { db } from "./index"
import db from "./index"
/*
* This seed function is executed when you run `blitz db seed`.

View File

@@ -29,14 +29,14 @@
"@blitzjs/rpc": "workspace:*",
"@hookform/resolvers": "2.8.8",
"@prisma/client": "3.9.0",
"blitz": "workspace:2.0.0-alpha.38",
"next": "12.1.6-canary.17",
"prisma": "3.9.0",
"blitz": "workspace:2.0.0-alpha.52",
"next": "12.2.0",
"prisma": "4.0.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"react-hook-form": "7.29.0",
"ts-node": "10.7.0",
"zod": "3.10.1"
"zod": "3.17.3"
},
"devDependencies": {
"@next/bundle-analyzer": "12.0.8",

View File

@@ -0,0 +1,20 @@
import Head from "next/head"
import { ErrorComponent } from "@blitzjs/next"
// ------------------------------------------------------
// This page is rendered if a route match is not found
// ------------------------------------------------------
export default function Page404() {
const statusCode = 404
const title = "This page could not be found"
return (
<>
<Head>
<title>
{statusCode}: {title}
</title>
</Head>
<ErrorComponent statusCode={statusCode} title={title} />
</>
)
}

View File

@@ -0,0 +1,22 @@
import Document, { Html, Main, NextScript, Head } from "next/document"
class MyDocument extends Document {
// Only uncomment if you need to customize this behaviour
// static async getInitialProps(ctx: DocumentContext) {
// const initialProps = await Document.getInitialProps(ctx)
// return {...initialProps}
// }
render() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
}
export default MyDocument

View File

@@ -7,8 +7,7 @@ const {gSSP, gSP, api} = setupBlitzServer({
plugins: [
AuthServerPlugin({
cookiePrefix: "webapp-cookie-prefix",
// TODO fix type
storage: PrismaStorage(db as any),
storage: PrismaStorage(db),
isAuthorized: simpleRolesIsAuthorized,
}),
],

View File

@@ -10,7 +10,6 @@ module.exports = withBlitz(
customServer: {
hotReload: false,
},
resolverBasePath: "root",
},
}),
)

View File

@@ -25,10 +25,10 @@
"@types/passport-twitter": "1.0.37",
"blitz": "workspace:*",
"jest": "27.5.1",
"next": "12.1.6-canary.17",
"next": "12.2.0",
"passport-mock-strategy": "2.0.0",
"passport-twitter": "1.0.4",
"prisma": "3.9.0",
"prisma": "4.0.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"ts-node": "10.7.0"

View File

@@ -1,6 +1,6 @@
import {ErrorFallbackProps, ErrorComponent, ErrorBoundary, AppProps} from "@blitzjs/next"
import {AuthenticationError, AuthorizationError} from "blitz"
import React from "react"
import React, {Suspense} from "react"
import {withBlitz} from "app/blitz-client"
function RootErrorFallback({error}: ErrorFallbackProps) {
@@ -26,7 +26,9 @@ function RootErrorFallback({error}: ErrorFallbackProps) {
function MyApp({Component, pageProps}: AppProps) {
return (
<ErrorBoundary FallbackComponent={RootErrorFallback}>
<Component {...pageProps} />
<Suspense fallback="Loading...">
<Component {...pageProps} />
</Suspense>
</ErrorBoundary>
)
}

View File

@@ -1,13 +1,13 @@
import {setupBlitzServer} from "@blitzjs/next"
import {AuthServerPlugin, PrismaStorage} from "@blitzjs/auth"
import {simpleRolesIsAuthorized} from "@blitzjs/auth"
import {prisma as db} from "../prisma/index"
import db from "../prisma/index"
const {gSSP, gSP, api} = setupBlitzServer({
plugins: [
AuthServerPlugin({
cookiePrefix: "auth-tests-cookie-prefix",
storage: PrismaStorage(db as any),
storage: PrismaStorage(db),
isAuthorized: simpleRolesIsAuthorized,
}),
],

View File

@@ -19,8 +19,8 @@
"@prisma/client": "3.9.0",
"blitz": "workspace:*",
"lowdb": "3.0.0",
"next": "12.1.6-canary.17",
"prisma": "3.9.0",
"next": "12.2.0",
"prisma": "4.0.0",
"react": "18.0.0",
"react-dom": "18.0.0"
},

View File

@@ -1,6 +1,6 @@
import {ErrorFallbackProps, ErrorComponent, ErrorBoundary, AppProps} from "@blitzjs/next"
import {AuthenticationError, AuthorizationError} from "blitz"
import React from "react"
import React, {Suspense} from "react"
import {withBlitz} from "../app/blitz-client"
function RootErrorFallback({error}: ErrorFallbackProps) {
@@ -25,9 +25,11 @@ function RootErrorFallback({error}: ErrorFallbackProps) {
function MyApp({Component, pageProps}: AppProps) {
return (
<ErrorBoundary FallbackComponent={RootErrorFallback}>
<Component {...pageProps} />
</ErrorBoundary>
<Suspense fallback="Loading...">
<ErrorBoundary FallbackComponent={RootErrorFallback}>
<Component {...pageProps} />
</ErrorBoundary>
</Suspense>
)
}

View File

@@ -1,6 +1,7 @@
import {api} from "../../app/blitz-server"
import {prisma} from "../../prisma/index"
import prisma from "../../prisma/index"
import {SecurePassword} from "@blitzjs/auth"
import {Role} from "../../types"
export const authenticateUser = async (email: string, password: string) => {
const user = await prisma.user.findFirst({where: {email}})
@@ -26,6 +27,7 @@ export default api(async (req, res, ctx) => {
await blitzContext.session.$create({
userId: user.id,
role: user.role as Role,
})
res.status(200).json({email: req.query.email, userId: blitzContext.session.userId})

View File

@@ -5,4 +5,4 @@ const EnhancedPrisma = enhancePrisma(PrismaClient)
export * from "@prisma/client"
const prisma = new EnhancedPrisma()
export {prisma}
export default prisma

View File

@@ -1,4 +1,4 @@
import {prisma} from "./index"
import prisma from "./index"
import {SecurePassword} from "@blitzjs/auth"
const seed = async () => {

View File

@@ -1,6 +1,6 @@
{
"extends": "@blitzjs/config/tsconfig.nextjs.json",
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"],
"compilerOptions": {
"paths": {
"react": ["./node_modules/@types/react"]

View File

@@ -0,0 +1,15 @@
import {SimpleRolesIsAuthorized} from "@blitzjs/auth"
import {User} from "./prisma"
export type Role = "ADMIN" | "USER"
declare module "@blitzjs/auth" {
export interface Session {
isAuthorized: SimpleRolesIsAuthorized<Role>
PublicData: {
userId: User["id"]
role: Role
views?: number
}
}
}

View File

@@ -0,0 +1,2 @@
SESSION_SECRET_KEY=hsdenhJfpLHrGjgdgg3jdF8g2bYD2PaQ
HEADLESS=true

View File

@@ -0,0 +1 @@
module.exports = require("@blitzjs/config/eslint")

View File

@@ -0,0 +1,3 @@
node_modules
# Keep environment variables out of version control
*.sqlite

View File

@@ -0,0 +1,5 @@
import {setupBlitzClient} from "@blitzjs/next"
const {withBlitz} = setupBlitzClient({plugins: []})
export {withBlitz}

View File

@@ -0,0 +1,7 @@
import {setupBlitzServer} from "@blitzjs/next"
const {gSSP, gSP, api} = setupBlitzServer({
plugins: [],
})
export {gSSP, gSP, api}

View File

@@ -0,0 +1,3 @@
export default async function getBasic() {
return {success: true}
}

View File

@@ -0,0 +1,7 @@
import {NextResponse} from "next/server"
export function middleware() {
const response = NextResponse.next()
response.headers.set("global-middleware", "true")
return response
}

View File

@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.

View File

@@ -0,0 +1,2 @@
const {withBlitz} = require("@blitzjs/next")
module.exports = withBlitz({})

View File

@@ -0,0 +1,34 @@
{
"name": "test-middleware",
"version": "0.0.0",
"private": true,
"scripts": {
"start:dev": "next dev",
"test": "vitest run",
"test-watch": "vitest",
"start": "next start",
"lint": "next lint",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next"
},
"dependencies": {
"@blitzjs/config": "workspace:*",
"@blitzjs/next": "workspace:*",
"@blitzjs/rpc": "workspace:*",
"blitz": "workspace:*",
"next": "12.2.0",
"react": "18.0.0",
"react-dom": "18.0.0"
},
"devDependencies": {
"@next/bundle-analyzer": "12.0.8",
"@types/express": "4.17.13",
"@types/fs-extra": "9.0.13",
"@types/node-fetch": "2.6.1",
"@types/react": "18.0.1",
"eslint": "7.32.0",
"fs-extra": "10.0.1",
"get-port": "6.1.2",
"node-fetch": "3.2.3",
"typescript": "^4.5.3"
}
}

View File

@@ -0,0 +1,36 @@
import {ErrorFallbackProps, ErrorComponent, ErrorBoundary, AppProps} from "@blitzjs/next"
import {AuthenticationError, AuthorizationError} from "blitz"
import React, {Suspense} from "react"
import {withBlitz} from "../app/blitz-client"
function RootErrorFallback({error}: ErrorFallbackProps) {
if (error instanceof AuthenticationError) {
return <div id="error">Error: You are not authenticated</div>
} else if (error instanceof AuthorizationError) {
return (
<ErrorComponent
statusCode={error.statusCode}
title="Sorry, you are not authorized to access this"
/>
)
} else {
return (
<ErrorComponent
statusCode={(error as any)?.statusCode || 400}
title={error.message || error.name}
/>
)
}
}
function MyApp({Component, pageProps}: AppProps) {
return (
<Suspense fallback="Loading...">
<ErrorBoundary FallbackComponent={RootErrorFallback}>
<Component {...pageProps} />
</ErrorBoundary>
</Suspense>
)
}
export default withBlitz(MyApp)

View File

@@ -0,0 +1,3 @@
import {rpcHandler} from "@blitzjs/rpc"
export default rpcHandler({onError: console.log})

View File

@@ -0,0 +1,5 @@
import {api} from "../../app/blitz-server"
export default api((_req, res) => {
res.status(200).json({success: true})
})

View File

@@ -0,0 +1,11 @@
export const getServerSideProps = () => {
return {props: {}}
}
export default function Web() {
return (
<div>
<h1>Web</h1>
</div>
)
}

View File

@@ -0,0 +1,72 @@
import {describe, it, expect, beforeAll, afterAll} from "vitest"
import {
killApp,
findPort,
launchApp,
nextBuild,
nextStart,
fetchViaHTTP,
} from "../../utils/next-test-utils"
import {join} from "path"
let app: any
let appPort: number
const appDir = join(__dirname, "../")
const runTests = () => {
describe("Middleware", () => {
describe("global middleware", () => {
it(
"should call global middleware on api calls",
async () => {
const res = await fetchViaHTTP(appPort, "/api/test", null, {
method: "GET",
})
expect(res.headers.get("global-middleware")).toBe("true")
},
5000 * 60 * 2,
)
it(
"should call global middleware on rpc calls",
async () => {
const res = await fetchViaHTTP(appPort, "/api/rpc/getBasic", null, {
method: "GET",
})
expect(res.headers.get("global-middleware")).toBe("true")
},
5000 * 60 * 2,
)
})
})
}
describe("Middleware Tests", () => {
describe("dev mode", () => {
beforeAll(async () => {
try {
appPort = await findPort()
app = await launchApp(appDir, appPort, {cwd: process.cwd()})
} catch (error) {
console.log(error)
}
}, 5000 * 60 * 2)
afterAll(async () => await killApp(app))
runTests()
})
describe("server mode", () => {
beforeAll(async () => {
try {
await nextBuild(appDir)
appPort = await findPort()
app = await nextStart(appDir, appPort, {cwd: process.cwd()})
} catch (err) {
console.log(err)
}
}, 5000 * 60 * 2)
afterAll(async () => await killApp(app))
runTests()
})
})

View File

@@ -0,0 +1,11 @@
{
"extends": "@blitzjs/config/tsconfig.nextjs.json",
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"],
"compilerOptions": {
"paths": {
"react": ["./node_modules/@types/react"]
}
},
"exclude": ["node_modules"],
"baseUrl": "."
}

View File

@@ -1,13 +1,13 @@
import {setupBlitzServer} from "@blitzjs/next"
import {AuthServerPlugin, PrismaStorage} from "@blitzjs/auth"
import {simpleRolesIsAuthorized} from "@blitzjs/auth"
import {prisma as db} from "../prisma/index"
import db from "../prisma/index"
const {gSSP, gSP, api} = setupBlitzServer({
plugins: [
AuthServerPlugin({
cookiePrefix: "no-suspense-tests-cookie-prefix",
storage: PrismaStorage(db as any),
storage: PrismaStorage(db),
isAuthorized: simpleRolesIsAuthorized,
}),
],

View File

@@ -19,8 +19,8 @@
"@prisma/client": "3.9.0",
"blitz": "workspace:*",
"lowdb": "3.0.0",
"next": "12.1.6-canary.17",
"prisma": "3.9.0",
"next": "12.2.0",
"prisma": "4.0.0",
"react": "18.0.0",
"react-dom": "18.0.0"
},

View File

@@ -1,6 +1,6 @@
import {ErrorFallbackProps, ErrorComponent, ErrorBoundary, AppProps} from "@blitzjs/next"
import {AuthenticationError, AuthorizationError} from "blitz"
import React from "react"
import React, {Suspense} from "react"
import {withBlitz} from "../app/blitz-client"
function RootErrorFallback({error}: ErrorFallbackProps) {
@@ -25,9 +25,11 @@ function RootErrorFallback({error}: ErrorFallbackProps) {
function MyApp({Component, pageProps}: AppProps) {
return (
<ErrorBoundary FallbackComponent={RootErrorFallback}>
<Component {...pageProps} />
</ErrorBoundary>
<Suspense fallback="Loading...">
<ErrorBoundary FallbackComponent={RootErrorFallback}>
<Component {...pageProps} />
</ErrorBoundary>
</Suspense>
)
}

View File

@@ -5,4 +5,4 @@ const EnhancedPrisma = enhancePrisma(PrismaClient)
export * from "@prisma/client"
const prisma = new EnhancedPrisma()
export {prisma}
export default prisma

View File

@@ -1,4 +1,4 @@
import {prisma} from "./index"
import prisma from "./index"
const seed = async () => {
await prisma.$reset()

View File

@@ -1,6 +1,6 @@
{
"extends": "@blitzjs/config/tsconfig.nextjs.json",
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"],
"compilerOptions": {
"paths": {
"react": ["./node_modules/@types/react"]

View File

@@ -0,0 +1,15 @@
import {SimpleRolesIsAuthorized} from "@blitzjs/auth"
import {User} from "./prisma"
export type Role = "ADMIN" | "USER"
declare module "@blitzjs/auth" {
export interface Session {
isAuthorized: SimpleRolesIsAuthorized<Role>
PublicData: {
userId: User["id"]
role: Role
views?: number
}
}
}

View File

@@ -14,8 +14,8 @@
"@blitzjs/rpc": "workspace:*",
"@prisma/client": "3.9.0",
"blitz": "workspace:*",
"next": "12.1.6-canary.17",
"prisma": "3.9.0",
"next": "12.2.0",
"prisma": "4.0.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"react-query": "3.39.0"

View File

@@ -1,4 +1,4 @@
const {withBlitz} = require("@blitzjs/next")
module.exports = withBlitz({
target: 'experimental-serverless-trace',
target: "experimental-serverless-trace",
})

View File

@@ -12,7 +12,7 @@
"@blitzjs/next": "workspace:*",
"@blitzjs/rpc": "workspace:*",
"blitz": "workspace:*",
"next": "12.1.6-canary.17",
"next": "12.2.0",
"react": "18.0.0",
"react-dom": "18.0.0"
},

View File

@@ -15,6 +15,6 @@
"isolatedModules": true,
"jsx": "preserve"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"],
"exclude": ["node_modules"]
}

View File

@@ -1,13 +1,13 @@
import {setupBlitzServer} from "@blitzjs/next"
import {AuthServerPlugin, PrismaStorage} from "@blitzjs/auth"
import {simpleRolesIsAuthorized} from "@blitzjs/auth"
import {prisma as db} from "../prisma/index"
import db from "../db"
const {gSSP, gSP, api} = setupBlitzServer({
plugins: [
AuthServerPlugin({
cookiePrefix: "trailing-slash-tests-cookie-prefix",
storage: PrismaStorage(db as any),
storage: PrismaStorage(db),
isAuthorized: simpleRolesIsAuthorized,
}),
],

View File

@@ -5,4 +5,4 @@ const EnhancedPrisma = enhancePrisma(PrismaClient)
export * from "@prisma/client"
const prisma = new EnhancedPrisma()
export {prisma}
export default prisma

View File

@@ -1,4 +1,4 @@
import {prisma} from "./index"
import prisma from "./index"
const seed = async () => {
await prisma.$reset()

View File

@@ -12,6 +12,9 @@
"prisma:start": "prisma generate && prisma migrate deploy",
"prisma:studio": "prisma studio"
},
"prisma": {
"schema": "db/schema.prisma"
},
"dependencies": {
"@blitzjs/auth": "workspace:*",
"@blitzjs/next": "workspace:*",
@@ -19,8 +22,8 @@
"@prisma/client": "3.9.0",
"blitz": "workspace:*",
"lowdb": "3.0.0",
"next": "12.1.6-canary.17",
"prisma": "3.9.0",
"next": "12.2.0",
"prisma": "4.0.0",
"react": "18.0.0",
"react-dom": "18.0.0"
},

View File

@@ -1,6 +1,6 @@
import {ErrorFallbackProps, ErrorComponent, ErrorBoundary, AppProps} from "@blitzjs/next"
import {AuthenticationError, AuthorizationError} from "blitz"
import React from "react"
import React, {Suspense} from "react"
import {withBlitz} from "../app/blitz-client"
function RootErrorFallback({error}: ErrorFallbackProps) {
@@ -25,9 +25,11 @@ function RootErrorFallback({error}: ErrorFallbackProps) {
function MyApp({Component, pageProps}: AppProps) {
return (
<ErrorBoundary FallbackComponent={RootErrorFallback}>
<Component {...pageProps} />
</ErrorBoundary>
<Suspense fallback="Loading...">
<ErrorBoundary FallbackComponent={RootErrorFallback}>
<Component {...pageProps} />
</ErrorBoundary>
</Suspense>
)
}

View File

@@ -1,6 +1,6 @@
{
"extends": "@blitzjs/config/tsconfig.nextjs.json",
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"],
"compilerOptions": {
"paths": {
"react": ["./node_modules/@types/react"]

View File

@@ -0,0 +1,15 @@
import {SimpleRolesIsAuthorized} from "@blitzjs/auth"
import {User} from "./db"
export type Role = "ADMIN" | "USER"
declare module "@blitzjs/auth" {
export interface Session {
isAuthorized: SimpleRolesIsAuthorized<Role>
PublicData: {
userId: User["id"]
role: Role
views?: number
}
}
}

View File

@@ -28,9 +28,8 @@
"husky": "7.0.4",
"jsdom": "^19.0.0",
"lint-staged": "12.1.7",
"next": "12.1.6-canary.17",
"next": "12.2.0",
"only-allow": "1.1.0",
"patch-package": "6.4.7",
"prettier": "^2.5.1",
"prettier-plugin-prisma": "3.8.0",
"pretty-quick": "3.1.3",
@@ -39,5 +38,5 @@
"wait-on": "6.0.1"
},
"npmClient": "pnpm",
"packageManager": "pnpm@6.21.0"
"packageManager": "pnpm@7.4.0-1"
}

View File

@@ -1,5 +1,95 @@
# @blitzjs/auth
## 2.0.0-alpha.52
### Patch Changes
- blitz@2.0.0-alpha.52
## 2.0.0-alpha.51
### Patch Changes
- blitz@2.0.0-alpha.51
## 2.0.0-alpha.50
### Patch Changes
- blitz@2.0.0-alpha.50
## 2.0.0-alpha.49
### Patch Changes
- blitz@2.0.0-alpha.49
## 2.0.0-alpha.48
### Patch Changes
- Updated dependencies [93851d90]
- blitz@2.0.0-alpha.48
## 2.0.0-alpha.47
### Patch Changes
- 1d9804a6: Remove references to the logging package
- Updated dependencies [1d9804a6]
- blitz@2.0.0-alpha.47
## 2.0.0-alpha.46
### Patch Changes
- blitz@2.0.0-alpha.46
## 2.0.0-alpha.45
### Patch Changes
- blitz@2.0.0-alpha.45
## 2.0.0-alpha.44
### Patch Changes
- 7817fe3a: Add missing RouteUrlObject on Page.authenticate.redirectTo
- blitz@2.0.0-alpha.44
## 2.0.0-alpha.43
### Patch Changes
- Updated dependencies [527e48ac]
- blitz@2.0.0-alpha.43
## 2.0.0-alpha.42
### Patch Changes
- blitz@2.0.0-alpha.42
## 2.0.0-alpha.41
### Patch Changes
- blitz@2.0.0-alpha.41
## 2.0.0-alpha.40
### Patch Changes
- blitz@2.0.0-alpha.40
## 2.0.0-alpha.39
### Patch Changes
- Updated dependencies [b918055b]
- blitz@2.0.0-alpha.39
## 2.0.0-alpha.38
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/auth",
"version": "2.0.0-alpha.38",
"version": "2.0.0-alpha.52",
"scripts": {
"build": "unbuild",
"predev": "wait-on -d 250 ../blitz/dist/index-server.d.ts",
@@ -26,7 +26,7 @@
"@types/secure-password": "3.1.1",
"b64-lite": "1.4.0",
"bad-behavior": "1.0.1",
"blitz": "2.0.0-alpha.38",
"blitz": "2.0.0-alpha.52",
"cookie": "0.4.1",
"cookie-session": "2.0.0",
"debug": "4.3.3",
@@ -39,7 +39,7 @@
"url": "0.11.0"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-alpha.38",
"@blitzjs/config": "workspace:2.0.0-alpha.52",
"@testing-library/react": "13.0.0",
"@testing-library/react-hooks": "7.0.2",
"@types/cookie": "0.4.1",

View File

@@ -205,7 +205,7 @@ export type RedirectAuthenticatedToFn = (
export type BlitzPage<P = {}> = React.ComponentType<P> & {
getLayout?: (component: JSX.Element) => JSX.Element
authenticate?: boolean | {redirectTo?: string}
authenticate?: boolean | {redirectTo?: string | RouteUrlObject}
suppressFirstRenderFlicker?: boolean
redirectAuthenticatedTo?: RedirectAuthenticatedTo | RedirectAuthenticatedToFn
}

View File

@@ -62,9 +62,6 @@ export function getCookieParser(headers: {[key: string]: undefined | string | st
}
}
// todo
declare const baseLogger: any
const debug = require("debug")("blitz:session")
export interface SimpleRolesIsAuthorized<RoleType = string> {
@@ -555,7 +552,7 @@ async function getSessionKernel(
}
if (enableCsrfProtection && persistedSession.antiCSRFToken !== antiCSRFToken) {
if (!antiCSRFToken) {
baseLogger({displayDateTime: false}).warn(
console.warn(
`This request is missing the ${HEADER_CSRF} header. You can learn about adding this here: https://blitzjs.com/docs/session-management#manual-api-requests`,
)
}
@@ -631,7 +628,7 @@ async function getSessionKernel(
if (enableCsrfProtection && payload.antiCSRFToken !== antiCSRFToken) {
if (!antiCSRFToken) {
baseLogger({displayDateTime: false}).warn(
console.warn(
`This request is missing the ${HEADER_CSRF} header. You can learn about adding this here: https://blitzjs.com/docs/session-management#manual-api-requests`,
)
}

View File

@@ -57,7 +57,7 @@ export type VerifyCallbackResult = {
export type ApiHandlerIncomingMessage = IncomingMessage & {
query: {
[key: string]: string | string[]
[key: string]: string | string[] | undefined
}
}

View File

@@ -1,5 +1,103 @@
# @blitzjs/next
## 2.0.0-alpha.52
### Patch Changes
- @blitzjs/rpc@2.0.0-alpha.52
## 2.0.0-alpha.51
### Patch Changes
- @blitzjs/rpc@2.0.0-alpha.51
## 2.0.0-alpha.50
### Patch Changes
- dc694cf1: Removes the check for when withBlitz is mounted before rendering the users app. We had this previously to avoid the react 18 suspense error being showin in development with nextjs.
- Updated dependencies [c11f0401]
- @blitzjs/rpc@2.0.0-alpha.50
## 2.0.0-alpha.49
### Patch Changes
- bec9512e: Allow resolverPath to be a function which is ran for every file path that is converted to RPC Route
- Updated dependencies [bec9512e]
- @blitzjs/rpc@2.0.0-alpha.49
## 2.0.0-alpha.48
### Patch Changes
- @blitzjs/rpc@2.0.0-alpha.48
## 2.0.0-alpha.47
### Patch Changes
- 1d9804a6: Remove references to the logging package
- Updated dependencies [1d9804a6]
- @blitzjs/rpc@2.0.0-alpha.47
## 2.0.0-alpha.46
### Patch Changes
- bee19a25: Support RPC error middleware
- 9ada0f66: Allow customizing PreviewData in gSSP
- Updated dependencies [bee19a25]
- @blitzjs/rpc@2.0.0-alpha.46
## 2.0.0-alpha.45
### Patch Changes
- 5c5decbc: Removes the suspense wrapper from withBlitz since it's not needed
- @blitzjs/rpc@2.0.0-alpha.45
## 2.0.0-alpha.44
### Patch Changes
- 7817fe3a: Add missing RouteUrlObject on Page.authenticate.redirectTo
- ae0b714f: Allow passing optional type argument for ParamsType in GSSP
- @blitzjs/rpc@2.0.0-alpha.44
## 2.0.0-alpha.43
### Patch Changes
- @blitzjs/rpc@2.0.0-alpha.43
## 2.0.0-alpha.42
### Patch Changes
- 9c2e7d37: Use `useRouter` from next/router in useParams function
- @blitzjs/rpc@2.0.0-alpha.42
## 2.0.0-alpha.41
### Patch Changes
- @blitzjs/rpc@2.0.0-alpha.41
## 2.0.0-alpha.40
### Patch Changes
- 9ded8dac: useParam & useParams functions now accessible from @blitzjs/next
- @blitzjs/rpc@2.0.0-alpha.40
## 2.0.0-alpha.39
### Patch Changes
- @blitzjs/rpc@2.0.0-alpha.39
## 2.0.0-alpha.38
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/next",
"version": "2.0.0-alpha.38",
"version": "2.0.0-alpha.52",
"scripts": {
"build": "unbuild",
"dev": "pnpm predev && pnpm watch unbuild src --wait=0.2",
@@ -23,7 +23,7 @@
"eslint.js"
],
"dependencies": {
"@blitzjs/rpc": "2.0.0-alpha.38",
"@blitzjs/rpc": "2.0.0-alpha.52",
"@types/hoist-non-react-statics": "3.3.1",
"debug": "4.3.3",
"fs-extra": "10.0.1",
@@ -32,22 +32,20 @@
"superjson": "1.8.0"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-alpha.38",
"@blitzjs/config": "workspace:2.0.0-alpha.52",
"@testing-library/dom": "8.13.0",
"@testing-library/jest-dom": "5.16.3",
"@testing-library/react": "13.0.0",
"@testing-library/react-hooks": "7.0.2",
"@testing-library/user-event": "13.5.0",
"@types/lodash.frompairs": "4.0.6",
"@types/node": "17.0.16",
"@types/react": "18.0.1",
"@types/react-dom": "17.0.14",
"@types/testing-library__react-hooks": "4.0.0",
"blitz": "2.0.0-alpha.38",
"blitz": "2.0.0-alpha.52",
"cross-spawn": "7.0.3",
"find-up": "4.1.0",
"lodash.frompairs": "4.0.1",
"next": "12.1.6-canary.17",
"next": "12.2.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"resolve-from": "5.0.0",
@@ -60,7 +58,7 @@
"access": "public"
},
"peerDependencies": {
"next": "*",
"next": ">=12.2.0",
"react": "*"
}
}

View File

@@ -17,6 +17,7 @@ import {Router} from "next/router"
export * from "./error-boundary"
export * from "./error-component"
export * from "./use-params"
export {Routes} from ".blitz"
const compose =
@@ -34,11 +35,7 @@ const buildWithBlitz = <TPlugins extends readonly ClientPlugin<object>[]>(plugin
const BlitzOuterRoot = (props: AppProps) => {
const component = React.useMemo(() => withPlugins(props.Component), [props.Component])
const [mounted, setMounted] = React.useState(false)
React.useEffect(() => {
// Current workaround to fix react 18 suspense error issue
setMounted(true)
// supress first render flicker
setTimeout(() => {
document.documentElement.classList.add("blitz-first-render-complete")
@@ -50,11 +47,7 @@ const buildWithBlitz = <TPlugins extends readonly ClientPlugin<object>[]>(plugin
<>
{/* @ts-ignore todo */}
{props.Component.suppressFirstRenderFlicker && <NoPageFlicker />}
{mounted && (
<React.Suspense fallback="Loading...">
<UserAppRoot {...props} Component={component} />
</React.Suspense>
)}
<UserAppRoot {...props} Component={component} />
</>
</BlitzProvider>
)
@@ -81,7 +74,7 @@ type RedirectAuthenticatedToFnCtx = {
type RedirectAuthenticatedToFn = (args: RedirectAuthenticatedToFnCtx) => RedirectAuthenticatedTo
export type BlitzPage<P = {}> = React.ComponentType<P> & {
getLayout?: (component: JSX.Element) => JSX.Element
authenticate?: boolean | {redirectTo?: string}
authenticate?: boolean | {redirectTo?: string | RouteUrlObject}
suppressFirstRenderFlicker?: boolean
redirectAuthenticatedTo?: RedirectAuthenticatedTo | RedirectAuthenticatedToFn
}

View File

@@ -17,11 +17,19 @@ import type {
MiddlewareResponse,
} from "blitz"
import {handleRequestWithMiddleware, startWatcher, stopWatcher} from "blitz"
import {dehydrate, getQueryKey, getInfiniteQueryKey, loaderClient, loaderServer} from "@blitzjs/rpc"
import {
dehydrate,
getInfiniteQueryKey,
getQueryKey,
installWebpackConfig,
InstallWebpackConfigOptions,
ResolverPathOptions,
} from "@blitzjs/rpc"
import {DefaultOptions, QueryClient} from "react-query"
import {IncomingMessage, ServerResponse} from "http"
import {withSuperJsonProps} from "./superjson"
import {ResolverBasePath} from "@blitzjs/rpc/src/index-server"
import {ParsedUrlQuery} from "querystring"
import {PreviewData} from "next/types"
export * from "./index-browser"
@@ -39,19 +47,32 @@ export type NextApiHandler = (
type SetupBlitzOptions = {
plugins: BlitzServerPlugin<RequestMiddleware, Ctx>[]
onError?: (err: Error) => void
}
export type BlitzGSSPHandler<TProps> = ({
export type BlitzGSSPHandler<
TProps,
Query extends ParsedUrlQuery = ParsedUrlQuery,
PD extends PreviewData = PreviewData,
> = ({
ctx,
req,
res,
...args
}: Parameters<GetServerSideProps<TProps>>[0] & {ctx: Ctx}) => ReturnType<GetServerSideProps<TProps>>
}: Parameters<GetServerSideProps<TProps, Query, PD>>[0] & {ctx: Ctx}) => ReturnType<
GetServerSideProps<TProps, Query, PD>
>
export type BlitzGSPHandler<TProps> = ({
export type BlitzGSPHandler<
TProps,
Query extends ParsedUrlQuery = ParsedUrlQuery,
PD extends PreviewData = PreviewData,
> = ({
ctx,
...args
}: Parameters<GetStaticProps<TProps>>[0] & {ctx: Ctx}) => ReturnType<GetStaticProps<TProps>>
}: Parameters<GetStaticProps<TProps, Query, PD>>[0] & {ctx: Ctx}) => ReturnType<
GetStaticProps<TProps, Query, PD>
>
export type BlitzAPIHandler = (
req: Parameters<NextApiHandler>[0],
@@ -59,12 +80,14 @@ export type BlitzAPIHandler = (
ctx: Ctx,
) => ReturnType<NextApiHandler>
export const setupBlitzServer = ({plugins}: SetupBlitzOptions) => {
export const setupBlitzServer = ({plugins, onError}: SetupBlitzOptions) => {
const middlewares = plugins.flatMap((p) => p.requestMiddlewares)
const contextMiddleware = plugins.flatMap((p) => p.contextMiddleware).filter(Boolean)
const gSSP =
<TProps>(handler: BlitzGSSPHandler<TProps>): GetServerSideProps<TProps> =>
<TProps, Query extends ParsedUrlQuery = ParsedUrlQuery, PD extends PreviewData = PreviewData>(
handler: BlitzGSSPHandler<TProps, Query, PD>,
): GetServerSideProps<TProps, Query, PD> =>
async ({req, res, ...rest}) => {
await handleRequestWithMiddleware<IncomingMessage, ServerResponse>(req, res, middlewares)
const ctx = contextMiddleware.reduceRight(
@@ -88,12 +111,19 @@ export const setupBlitzServer = ({plugins}: SetupBlitzOptions) => {
ctx.prefetchQuery = prefetchQuery
ctx.prefetchInfiniteQuery = (...args) => prefetchQuery(...args, true)
const result = await handler({req, res, ctx, ...rest})
return withSuperJsonProps(withDehydratedState(result, queryClient))
try {
const result = await handler({req, res, ctx, ...rest})
return withSuperJsonProps(withDehydratedState(result, queryClient))
} catch (err: any) {
onError?.(err)
throw err
}
}
const gSP =
<TProps>(handler: BlitzGSPHandler<TProps>): GetStaticProps<TProps> =>
<TProps, Query extends ParsedUrlQuery = ParsedUrlQuery, PD extends PreviewData = PreviewData>(
handler: BlitzGSPHandler<TProps, Query, PD>,
): GetStaticProps<TProps, Query, PD> =>
async (context) => {
const ctx = contextMiddleware.reduceRight((y, f) => (f ? f(y) : y), {} as Ctx)
let queryClient: null | QueryClient = null
@@ -113,8 +143,13 @@ export const setupBlitzServer = ({plugins}: SetupBlitzOptions) => {
ctx.prefetchQuery = prefetchQuery
ctx.prefetchInfiniteQuery = (...args) => prefetchQuery(...args, true)
const result = await handler({...context, ctx: ctx})
return withSuperJsonProps(withDehydratedState(result, queryClient))
try {
const result = await handler({...context, ctx: ctx})
return withSuperJsonProps(withDehydratedState(result, queryClient))
} catch (err: any) {
onError?.(err)
throw err
}
}
const api =
@@ -123,7 +158,8 @@ export const setupBlitzServer = ({plugins}: SetupBlitzOptions) => {
try {
await handleRequestWithMiddleware(req, res, middlewares)
return handler(req, res, res.blitzCtx)
} catch (error) {
} catch (error: any) {
onError?.(error)
return res.status(400).send(error)
}
}
@@ -133,59 +169,13 @@ export const setupBlitzServer = ({plugins}: SetupBlitzOptions) => {
export interface BlitzConfig extends NextConfig {
blitz?: {
resolverBasePath?: ResolverBasePath
resolverPath?: ResolverPathOptions
customServer?: {
hotReload?: boolean
}
}
}
interface WebpackRuleOptions {
resolverBasePath?: ResolverBasePath
}
interface WebpackRule {
test: RegExp
use: Array<{
loader: string
options: WebpackRuleOptions
}>
}
interface InstallWebpackConfigOptions {
webpackConfig: {
module: {
rules: WebpackRule[]
}
}
nextConfig: BlitzConfig
}
export function installWebpackConfig({webpackConfig, nextConfig}: InstallWebpackConfigOptions) {
const options: WebpackRuleOptions = {
resolverBasePath: nextConfig.blitz?.resolverBasePath,
}
webpackConfig.module.rules.push({
test: /\/\[\[\.\.\.blitz]]\.[jt]s$/,
use: [
{
loader: loaderServer,
options,
},
],
})
webpackConfig.module.rules.push({
test: /[\\/](queries|mutations)[\\/]/,
use: [
{
loader: loaderClient,
options,
},
],
})
}
export function withBlitz(nextConfig: BlitzConfig = {}) {
if (
process.env.NODE_ENV !== "production" &&
@@ -206,7 +196,12 @@ export function withBlitz(nextConfig: BlitzConfig = {}) {
const config = Object.assign({}, nextConfig, {
webpack: (config: InstallWebpackConfigOptions["webpackConfig"], options: any) => {
installWebpackConfig({webpackConfig: config, nextConfig})
installWebpackConfig({
webpackConfig: config,
webpackRuleOptions: {
resolverPath: nextConfig.blitz?.resolverPath,
},
})
if (typeof nextConfig.webpack === "function") {
return nextConfig.webpack(config, options)
}

View File

@@ -1,9 +1,8 @@
/**
* @vitest-environment jsdom
*/
import React from "react"
import {describe, it, expect, vi} from "vitest"
import {describe, it, expect, vi, afterEach} from "vitest"
import {extractRouterParams, useParam, useParams} from "./use-params"
import {renderHook as defaultRenderHook} from "@testing-library/react-hooks"
import {NextRouter} from "next/router"
@@ -16,6 +15,14 @@ type RenderHookOptions = DefaultHookParams[1] & {
dehydratedState?: unknown
}
// This is the router query object which includes route params
const query = {
id: "1",
cat: "category",
slug: ["example", "multiple", "slugs"],
empty: "",
}
const mockRouter: NextRouter = {
basePath: "",
pathname: "/",
@@ -54,6 +61,10 @@ export function renderHook(
}
describe("extractRouterParams", () => {
afterEach(() => {
vi.clearAllMocks()
})
it("returns proper params", () => {
const routerQuery = {
id: "1",
@@ -81,92 +92,99 @@ describe("extractRouterParams", () => {
})
describe("useParams", () => {
afterEach(() => {
vi.clearAllMocks()
})
it("works without parameter", () => {
// This is the router query object which includes route params
const query = {
id: "1",
cat: "category",
slug: ["example", "multiple", "slugs"],
empty: "",
}
const {result} = renderHook(() => useParams(), {router: {query}})
expect(result.current).toEqual({
id: "1",
cat: "category",
slug: ["example", "multiple", "slugs"],
empty: "",
vi.mock("next/router", () => {
return {
useRouter: vi.fn(() => ({...mockRouter, query})),
}
})
})
it("works with string", () => {
// This is the router query object which includes route params
const query = {
id: "1",
cat: "category",
slug: ["example", "multiple", "slugs"],
empty: "",
}
it("works with string", () => {
vi.mock("next/router", () => {
return {
useRouter: vi.fn(() => ({...mockRouter, query})),
}
})
const {result} = renderHook(() => useParams("string"), {
router: {query},
const {result} = renderHook(() => useParams("string"), {
router: {query},
})
expect(result.current).toEqual({
id: "1",
cat: "category",
empty: "",
})
})
expect(result.current).toEqual({
id: "1",
cat: "category",
empty: "",
})
})
it("works with number", () => {
// This is the router query object which includes route params
const query = {
id: "1",
cat: "category",
slug: ["example", "multiple", "slugs"],
empty: "",
}
it("works with string", () => {
vi.mock("next/router", () => {
return {
useRouter: vi.fn(() => ({...mockRouter, query})),
}
})
const {result} = renderHook(() => useParams("number"), {
router: {query},
const {result} = renderHook(() => useParams("string"), {
router: {query},
})
expect(result.current).toEqual({
id: "1",
cat: "category",
empty: "",
})
})
expect(result.current).toEqual({
id: 1,
cat: undefined,
slug: undefined,
})
})
it("works with array", () => {
// This is the router query object which includes route params
const query = {
id: "1",
cat: "category",
slug: ["example", "multiple", "slugs"],
empty: "",
}
it("works with number", () => {
vi.mock("next/router", () => {
return {
useRouter: vi.fn(() => ({...mockRouter, query})),
}
})
const {result} = renderHook(() => useParams("array"), {
router: {query},
const {result} = renderHook(() => useParams("number"), {
router: {query},
})
expect(result.current).toEqual({
id: 1,
cat: undefined,
slug: undefined,
})
})
expect(result.current).toEqual({
id: ["1"],
cat: ["category"],
slug: ["example", "multiple", "slugs"],
empty: [""],
it("works with array", () => {
vi.mock("next/router", () => {
return {
useRouter: vi.fn(() => ({...mockRouter, query})),
}
})
const {result} = renderHook(() => useParams("array"), {
router: {query},
})
expect(result.current).toEqual({
id: ["1"],
cat: ["category"],
slug: ["example", "multiple", "slugs"],
empty: [""],
})
})
})
})
describe("useParam", () => {
afterEach(() => {
vi.clearAllMocks()
})
it("works without parameter", () => {
// This is the router query object which includes route params
const query = {
id: "1",
cat: "category",
slug: ["example", "multiple", "slugs"],
empty: "",
}
vi.mock("next/router", () => {
return {
useRouter: vi.fn(() => ({...mockRouter, query})),
}
})
let {result} = renderHook(() => useParam("id"), {router: {query}})
expect(result.current).toEqual("1")
@@ -183,13 +201,11 @@ describe("useParam", () => {
})
it("works with string", () => {
// This is the router query object which includes route params
const query = {
id: "1",
cat: "category",
slug: ["example", "multiple", "slugs"],
empty: "",
}
vi.mock("next/router", () => {
return {
useRouter: vi.fn(() => ({...mockRouter, query})),
}
})
let {result} = renderHook(() => useParam("id", "string"), {
router: {query},

View File

@@ -1,22 +1,10 @@
import fromPairs from "lodash.frompairs"
import {NextRouter} from "next/router"
import {useRouter} from "next/router"
import {ParsedUrlQuery} from "querystring"
import React from "react"
import {RouterContext} from "./router-context"
type Dict<T> = Record<string, T | undefined>
type ReturnTypes = "string" | "number" | "array"
/**
* `useRouter` is a React hook used to access `router` object within components
*
* @returns `router` object
* @see Docs {@link https://blitzjs.com/docs/router#router-object | router}
*/
export function useRouter(): NextRouter {
return React.useContext(RouterContext)
}
/*
* Based on the code of https://github.com/lukeed/qss
*/
@@ -81,7 +69,7 @@ function areQueryValuesEqual(value1: ParsedUrlQueryValue, value2: ParsedUrlQuery
}
export function extractRouterParams(routerQuery: ParsedUrlQuery, asPathQuery: ParsedUrlQuery) {
return fromPairs(
return Object.fromEntries(
Object.entries(routerQuery).filter(
([key, value]) =>
typeof asPathQuery[key] === "undefined" || !areQueryValuesEqual(value, asPathQuery[key]),

View File

@@ -1,5 +1,112 @@
# @blitzjs/rpc
## 2.0.0-alpha.52
### Patch Changes
- blitz@2.0.0-alpha.52
- @blitzjs/auth@2.0.0-alpha.52
## 2.0.0-alpha.51
### Patch Changes
- @blitzjs/auth@2.0.0-alpha.51
- blitz@2.0.0-alpha.51
## 2.0.0-alpha.50
### Patch Changes
- c11f0401: Update Next.js version and addBasePath location
- blitz@2.0.0-alpha.50
- @blitzjs/auth@2.0.0-alpha.50
## 2.0.0-alpha.49
### Patch Changes
- bec9512e: Allow resolverPath to be a function which is ran for every file path that is converted to RPC Route
- @blitzjs/auth@2.0.0-alpha.49
- blitz@2.0.0-alpha.49
## 2.0.0-alpha.48
### Patch Changes
- Updated dependencies [93851d90]
- blitz@2.0.0-alpha.48
- @blitzjs/auth@2.0.0-alpha.48
## 2.0.0-alpha.47
### Patch Changes
- 1d9804a6: Remove references to the logging package
- Updated dependencies [1d9804a6]
- blitz@2.0.0-alpha.47
- @blitzjs/auth@2.0.0-alpha.47
## 2.0.0-alpha.46
### Patch Changes
- bee19a25: Support RPC error middleware
- @blitzjs/auth@2.0.0-alpha.46
- blitz@2.0.0-alpha.46
## 2.0.0-alpha.45
### Patch Changes
- @blitzjs/auth@2.0.0-alpha.45
- blitz@2.0.0-alpha.45
## 2.0.0-alpha.44
### Patch Changes
- Updated dependencies [7817fe3a]
- @blitzjs/auth@2.0.0-alpha.44
- blitz@2.0.0-alpha.44
## 2.0.0-alpha.43
### Patch Changes
- Updated dependencies [527e48ac]
- blitz@2.0.0-alpha.43
- @blitzjs/auth@2.0.0-alpha.43
## 2.0.0-alpha.42
### Patch Changes
- @blitzjs/auth@2.0.0-alpha.42
- blitz@2.0.0-alpha.42
## 2.0.0-alpha.41
### Patch Changes
- @blitzjs/auth@2.0.0-alpha.41
- blitz@2.0.0-alpha.41
## 2.0.0-alpha.40
### Patch Changes
- @blitzjs/auth@2.0.0-alpha.40
- blitz@2.0.0-alpha.40
## 2.0.0-alpha.39
### Patch Changes
- Updated dependencies [b918055b]
- blitz@2.0.0-alpha.39
- @blitzjs/auth@2.0.0-alpha.39
## 2.0.0-alpha.38
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/rpc",
"version": "2.0.0-alpha.38",
"version": "2.0.0-alpha.52",
"scripts": {
"build": "unbuild",
"predev": "wait-on -d 250 ../blitz/dist/index-server.d.ts && wait-on -d 250 ../blitz-auth/dist/index-browser.d.ts",
@@ -20,22 +20,22 @@
"dist/**"
],
"dependencies": {
"@blitzjs/auth": "2.0.0-alpha.38",
"@blitzjs/auth": "2.0.0-alpha.52",
"b64-lite": "1.4.0",
"bad-behavior": "1.0.1",
"chalk": "^4.1.0",
"debug": "4.3.3",
"react-query": "3.39.0",
"superjson": "1.8.0",
"zod": "3.10.1"
"zod": "3.17.3"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-alpha.38",
"@blitzjs/config": "workspace:2.0.0-alpha.52",
"@types/debug": "4.1.7",
"@types/react": "18.0.1",
"@types/react-dom": "17.0.14",
"blitz": "2.0.0-alpha.38",
"next": "12.1.6-canary.17",
"blitz": "2.0.0-alpha.52",
"next": "12.2.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"typescript": "^4.5.3",
@@ -43,8 +43,8 @@
"watch": "1.0.2"
},
"peerDependencies": {
"blitz": "2.0.0-alpha.38",
"next": "*"
"blitz": "2.0.0-alpha.52",
"next": ">=12.2.0"
},
"publishConfig": {
"access": "public"

View File

@@ -1,5 +1,5 @@
import {normalizePathTrailingSlash} from "next/dist/client/normalize-trailing-slash"
import {addBasePath} from "next/dist/shared/lib/router/router"
import {addBasePath} from "next/dist/client/add-base-path"
import {deserialize, serialize} from "superjson"
import {SuperJSONResult} from "superjson/dist/types"
import {CSRFTokenMismatchError, isServer} from "blitz"

View File

@@ -1,7 +1,6 @@
import {assert, baseLogger, Ctx, newLine, prettyMs} from "blitz"
import {assert, Ctx, prettyMs} from "blitz"
import {NextApiRequest, NextApiResponse} from "next"
import {deserialize, serialize as superjsonSerialize} from "superjson"
import chalk from "chalk"
import {resolve} from "path"
// TODO - optimize end user server bundles by not exporting all client stuff here
@@ -13,6 +12,7 @@ export * from "./resolver"
function isObject(value: unknown): value is Record<string | symbol, unknown> {
return typeof value === "object" && value !== null
}
function getGlobalObject<T extends Record<string, unknown>>(key: string, defaultValue: T): T {
assert(key.startsWith("__internal_blitz"), "unsupported key")
if (typeof global === "undefined") {
@@ -25,7 +25,7 @@ function getGlobalObject<T extends Record<string, unknown>>(key: string, default
type Resolver = (...args: unknown[]) => Promise<unknown>
type ResolverFiles = Record<string, () => Promise<{default?: Resolver}>>
export type ResolverBasePath = "queries|mutations" | "root" | undefined
export type ResolverPathOptions = "queries|mutations" | "root" | ((path: string) => string)
// We define `global.__internal_blitzRpcResolverFiles` to ensure we use the same global object.
// Needed for Next.js. I'm guessing that Next.js is including the `node_modules/` files in a seperate bundle than user files.
@@ -50,8 +50,53 @@ export function __internal_addBlitzRpcResolver(
}
const dir = __dirname + (() => "")() // trick to avoid `@vercel/ncc` to glob import
export const loaderServer = resolve(dir, "./loader-server.cjs")
export const loaderClient = resolve(dir, "./loader-client.cjs")
const loaderServer = resolve(dir, "./loader-server.cjs")
const loaderClient = resolve(dir, "./loader-client.cjs")
interface WebpackRuleOptions {
resolverPath: ResolverPathOptions | undefined
}
interface WebpackRule {
test: RegExp
use: Array<{
loader: string
options: WebpackRuleOptions
}>
}
export interface InstallWebpackConfigOptions {
webpackConfig: {
module: {
rules: WebpackRule[]
}
}
webpackRuleOptions: WebpackRuleOptions
}
export function installWebpackConfig({
webpackConfig,
webpackRuleOptions,
}: InstallWebpackConfigOptions) {
webpackConfig.module.rules.push({
test: /\/\[\[\.\.\.blitz]]\.[jt]s$/,
use: [
{
loader: loaderServer,
options: webpackRuleOptions,
},
],
})
webpackConfig.module.rules.push({
test: /[\\/](queries|mutations)[\\/]/,
use: [
{
loader: loaderClient,
options: webpackRuleOptions,
},
],
})
}
// ----------
// END LOADER
@@ -109,14 +154,6 @@ export function rpcHandler(config: RpcConfig) {
throw new Error("No default export for resolver path: " + routePath)
}
const log = baseLogger().getChildLogger({
prefix: [relativeRoutePath + "()"],
})
const customChalk = new chalk.Instance({
level: log.settings.type === "json" ? 0 : chalk.level,
})
if (req.method === "HEAD") {
// We used to initiate database connection here
res.status(200).end()
@@ -126,7 +163,7 @@ export function rpcHandler(config: RpcConfig) {
if (typeof req.body.params === "undefined") {
const error = {message: "Request body is missing the `params` key"}
log.error(error.message)
console.error(error.message)
res.status(400).json({
result: null,
error,
@@ -140,11 +177,11 @@ export function rpcHandler(config: RpcConfig) {
meta: req.body.meta?.params,
})
log.info(customChalk.dim("Starting with input:"), data ? data : JSON.stringify(data))
console.info("Starting with input:", data ? data : JSON.stringify(data))
const startTime = Date.now()
const result = await resolver(data, (res as any).blitzCtx)
const resolverDuration = Date.now() - startTime
log.debug(customChalk.dim("Result:"), result ? result : JSON.stringify(result))
console.debug("Result:", result ? result : JSON.stringify(result))
const serializerStartTime = Date.now()
const serializedResult = superjsonSerialize(result)
@@ -158,30 +195,27 @@ export function rpcHandler(config: RpcConfig) {
result: serializedResult.meta,
},
})
log.debug(
customChalk.dim(
`Next.js serialization:${prettyMs(Date.now() - nextSerializerStartTime)}`,
),
)
console.debug(`Next.js serialization:${prettyMs(Date.now() - nextSerializerStartTime)}`)
const serializerDuration = Date.now() - serializerStartTime
const duration = Date.now() - startTime
log.info(
customChalk.dim(
`Finished: resolver:${prettyMs(resolverDuration)} serializer:${prettyMs(
serializerDuration,
)} total:${prettyMs(duration)}`,
),
console.info(
`Finished: resolver:${prettyMs(resolverDuration)} serializer:${prettyMs(
serializerDuration,
)} total:${prettyMs(duration)}`,
)
newLine()
console.log("\n")
return
} catch (error: any) {
if (error._clearStack) {
delete error.stack
}
log.error(error)
newLine()
config.onError?.(error)
console.error(error)
console.log("\n")
if (!error.statusCode) {
error.statusCode = 500
@@ -200,7 +234,7 @@ export function rpcHandler(config: RpcConfig) {
}
} else {
// Everything else is error
log.warn(`${req.method} method not supported`)
console.warn(`${req.method} method not supported`)
res.status(404).end()
return
}

Some files were not shown because too many files have changed in this diff Show More