1
0
mirror of synced 2026-02-04 03:01:17 -05:00

Compare commits

...

41 Commits

Author SHA1 Message Date
github-actions[bot]
57a53fa3c2 Version Packages (alpha) (#3561)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-07-20 14:34:36 +02:00
Fran Zekan
abb1ad5d1c Don't throw error on a missing app/api folder when running codemod (#3568)
Co-authored-by: Aleksandra <alexsandra.sikora@gmail.com>
2022-07-20 08:26:14 +02:00
Brandon Bayer
7096083038 Update CODEOWNERS 2022-07-19 18:29:15 +02:00
Ante Primorac
0ac6e17122 fix blitz not loading custom server (#3564)
* fix blitz not loading custom server
2022-07-19 00:42:14 +02:00
Brandon Bayer
8bcb471a53 Fix auth issue where session token and publicData cookie were updated unnecessarily, leading to potential user logout (#3556)
* fix auth issue where session token and public data token was updated unnecessarily
2022-07-19 00:19:55 +02:00
Brandon Bayer
abe2afccdf Fix a long-standing issue with occasional blitz auth flakiness (#3554)
* fix cookie set bug
2022-07-19 00:06:38 +02:00
Fran Zekan
d9fc5d8e26 Fix queryClient not working the same in SSP and SP (#3563)
Co-authored-by: beerose <alexsandra.sikora@gmail.com>
2022-07-18 17:14:53 +02:00
Aleksandra
3f20a47405 Fix delete session type (#3560) 2022-07-18 12:58:03 +02:00
github-actions[bot]
72addbbeed Version Packages (alpha) (#3540)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-07-18 11:29:22 +02:00
Fran Zekan
1c809094fd Fix Page.authenticate not working for layout components (#3547)
Co-authored-by: Aleksandra <alexsandra.sikora@gmail.com>
2022-07-18 10:39:07 +02:00
Fran Zekan
54a66a95dc Show all blitz packages when running blitz version command (#3553)
Co-authored-by: beerose <alexsandra.sikora@gmail.com>
2022-07-18 10:03:44 +02:00
Fran Zekan
8d9ea00e1d Fix prefetching multiple queries causes only the last one to be passed to page (#3551) 2022-07-17 19:28:45 +02:00
Fran Zekan
ab4d9de70f Don't try to copy RPC API endpoint in templates that don't have it (#3545)
* Don't try to copy RPC API endpoint in templates that don't have it
2022-07-17 18:08:08 +02:00
Fran Zekan
8f166a5db0 Check for new versions when running CLI (#3465)
* Simple function to call new on every cli invocation to update blitz

* Fix printing of how to

* Catch network errors

* Cleanup

* Loop through all locally installed and packages and check if an update is needed

* cache checkForLatestVersion so it runs only on every 24 hours

* make update message pretty

* uncomment shouldUpdate boolean

* run checkLatestVersion on dev command and new

* Dont run in our monorepo + small changes

* Create curly-seas-serve.md

Co-authored-by: Dillon Raphael <dillon@creatorsneverdie.com>
2022-07-17 01:01:52 +02:00
Datner
df7cee84ad fix(blitz-rpc): fix 6th pipe resolver not returning resolved value (#3537)
Co-authored-by: beerose <alexsandra.sikora@gmail.com>
2022-07-15 12:18:00 +02:00
github-actions[bot]
b364af7f57 Version Packages (alpha) (#3516)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-07-14 16:07:20 +02:00
Fran Zekan
20fc9f80f4 Fix SSP / SP not prefetching queries correctly (#3518)
* Fix prefetchQuery getting key for infinite wrong

* Add new webpack loader to transform resolvers server-side to have _routePath and other meta values

* Fix key error when loading dehydrated props

* Add unit-tests for loader-server-resolvers.ts
2022-07-12 14:41:26 +02:00
Aleksandra
80e1ead7cb Create jest.config.js with new app generator (#3532)
* Create jest.config.js with new app generator
2022-07-12 11:44:36 +02:00
Fran Zekan
a3bbe6ce3f Fix routes manifest showing duplicates for non queries|resolvers reso… (#3531)
* Fix routes manifest showing duplicates for non queries|resolvers resolver type

* Simplify resolverType checking
2022-07-12 11:36:59 +02:00
Fran Zekan
348fd6f5e4 Fix redirectAuthenticatedTo errors (#3529)
* Wrap BlitzProvider from next with RouterContext
2022-07-11 21:47:16 +02:00
Dawid Urbaniak
cacb65d633 fix: fix wrong import of the db module in blitz db seed command function (#3526)
* fix: fix wrong import of the db module
2022-07-11 11:35:08 +02:00
Fran Zekan
f397cc2036 Fix switch case fall-through bug in CLI (#3525)
* Fix redundant if

* Fix switch fallthrough cases

* Extract install map to top

* Create cool-horses-check.md

Co-authored-by: Dillon Raphael <dillon@creatorsneverdie.com>
2022-07-11 10:30:03 +02:00
Fran Zekan
ffa7b5ccc2 If project name argument is set to "." change it to current folder name (#3523)
* If project name argument is set to "." change it to current folder name

* Create two-carpets-rhyme.md

Co-authored-by: Dillon Raphael <dillon@creatorsneverdie.com>
2022-07-11 10:22:03 +02:00
Aleksandra
a961aff881 Add missing lint deps (#3515) 2022-07-07 16:45:02 +02:00
github-actions[bot]
ac9c4cebc8 Version Packages (alpha) (#3514)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-07-07 15:43:57 +02:00
Dillon Raphael
a7e37c58db Export BlitzProvider from blitz-next (#3513)
Co-authored-by: Aleksandra <alexsandra.sikora@gmail.com>
2022-07-07 15:36:52 +02:00
Brandon Bayer
b0d2505a85 Update CODEOWNERS 2022-07-06 23:54:29 +02:00
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
103 changed files with 1769 additions and 642 deletions

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Fixes issue when generating a new blitz app with the form flag that ends up installing the wrong form library

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Check for new versions when running CLI

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/auth": patch
---
Update `deleteSession` return type — allow undefined values

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Fixes wrong import of the db module in `blitz db seed` command function

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/next": patch
---
Allow prefetching multiple queries in gSSP and gSP

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Show all blitz packages when running `blitz version` command

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Improve codemod utilities

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/generator": patch
---
Don't try to copy RPC API endpoint in templates that don't have it

View File

@@ -0,0 +1,10 @@
---
"@blitzjs/auth": patch
"blitz": patch
---
Fix a long-standing issue with occasional blitz auth flakiness
This bug would sometimes cause users to be logged out or to experience an CSRFTokenMismatchError. This bug, when encountered, usually by lots of setPublicData or session.create calls, would not set the cookie headers correctly resulting in cookies being set to a previous state or in a possibly undefined state.
There are no security concerns as far as I can tell.

View File

@@ -0,0 +1,6 @@
---
"@blitzjs/next": patch
"blitz": patch
---
Fix redirectAuthenticatedTo errors

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/next": patch
---
Export BlitzProvider from @blitzjs/next

View File

@@ -0,0 +1,7 @@
---
"@blitzjs/next": patch
"@blitzjs/rpc": patch
"blitz": patch
---
Fix SSP / SP not prefetching queries correctly

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Add missing lint deps to the new app templates

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/rpc": patch
---
Fix pipe resolver return type

View File

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

View File

@@ -25,7 +25,10 @@
"breezy-cameras-double",
"bright-mangos-run",
"cool-doors-invent",
"cool-horses-check",
"curly-seas-serve",
"dirty-monkeys-greet",
"dirty-planets-chew",
"eleven-humans-sort",
"empty-berries-rule",
"empty-turkeys-wave",
@@ -37,41 +40,61 @@
"four-meals-fry",
"fuzzy-jars-admire",
"gentle-dogs-reply",
"good-apes-drum",
"good-insects-wink",
"gorgeous-buses-scream",
"great-months-train",
"green-papayas-do",
"healthy-rice-shout",
"heavy-apes-judge",
"hot-drinks-approve",
"hungry-baboons-swim",
"late-steaks-give",
"lemon-games-press",
"lemon-seas-push",
"lovely-colts-share",
"lucky-cows-try",
"mean-gorillas-reply",
"modern-cameras-pull",
"moody-bags-walk",
"moody-squids-cheer",
"nervous-beds-travel",
"nervous-dolls-rule",
"new-coats-turn",
"nice-deers-dream",
"nice-starfishes-live",
"nine-birds-confess",
"nine-onions-admire",
"ninety-pets-heal",
"olive-bees-buy",
"olive-feet-rhyme",
"olive-sheep-rhyme",
"perfect-eyes-repeat",
"plenty-bottles-swim",
"poor-peas-lick",
"poor-penguins-look",
"poor-shrimps-think",
"popular-teachers-pay",
"purple-singers-greet",
"quick-cycles-confess",
"quiet-feet-travel",
"quiet-pans-hunt",
"quiet-sloths-rule",
"rich-chairs-invent",
"rich-queens-travel",
"sharp-falcons-begin",
"shy-olives-hang",
"silent-colts-reply",
"slimy-needles-taste",
"slow-walls-poke",
"small-socks-confess",
"smooth-planets-admire",
"soft-adults-smell",
"sour-lemons-hunt",
"strong-apes-reply",
"stupid-walls-sell",
"swift-drinks-dress",
"tall-meals-learn",
"tame-keys-reply",
"tasty-news-collect",
"ten-hairs-listen",
@@ -79,7 +102,10 @@
"tender-pianos-check",
"thick-parrots-float",
"thirty-countries-build",
"tidy-clouds-smoke",
"twelve-lemons-smile",
"twenty-beans-pump",
"two-carpets-rhyme",
"two-kiwis-help",
"two-tigers-type",
"unlucky-papayas-sleep",

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
fixes blitz not loading custom server

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,6 @@
---
"@blitzjs/next": patch
"@blitzjs/generator": patch
---
Add jest.config.js to newly generated typescript apps

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/auth": patch
---
Fix `Page.authenticate` not working for layout components

View File

@@ -0,0 +1,9 @@
---
"@blitzjs/auth": patch
"blitz": patch
---
Fix auth issue where session token and publicData cookie were updated unnecessarily, leading to potential user logout
- Previously, we were updating the session token each time public data changed. This is not needed, and it would cause race condition bugs where a user could be unexpectedly logged out because a request already in flight would not match the new session token.
- Previously, we were updating the publicData cookie even when it hadn't changed. This may reduce unnecessary re-renders on the client.

View File

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

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Fix routes manifest showing duplicates for non queries|resolvers reso…

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/next": patch
---
Fix prefetching multiple queries causes only the last one to be passed to page

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
During `blitz new` if project name argument is set to "." change it to current folder name

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 @dillonraphael
* @beerose @dillonraphael
packages/generator/templates**/* @flybayer

View File

@@ -1,43 +0,0 @@
name-template: "v$RESOLVED_VERSION"
tag-template: "v$RESOLVED_VERSION"
# categories:
# - title: 'Blitz'
# label: 'blitz'
# - title: '@blitzjs/next'
# label: 'blitz-next'
# - title: '@blitzjs/rpc'
# label: 'blitz-rpc'
# - title: '@blitzjs/auth'
# label: 'blitz-auth'
version-resolver:
major:
labels:
- "major"
minor:
labels:
- "minor"
patch:
labels:
- "patch"
default: patch
# autolabeler:
# - label: 'blitz'
# title:
# - '/blitz/i'
# - label: 'blitz-next'
# title:
# - '/@blitzjs\/next/i'
# - label: 'blitz-rpc'
# title:
# - '/@blitzjs\/rpc/i'
# - label: 'blitz-auth'
# title:
# - '/@blitzjs\/auth/i'
template: |
## Whats Changed
$CHANGES
## Contributors
$CONTRIBUTORS

View File

@@ -42,10 +42,10 @@ jobs:
- run: pnpm build
- name: Create Release Pull Request
uses: changesets/action@v1
uses: blitz-js/changesets-action@main
with:
publish: pnpm release
createGithubReleases: false
createGithubReleases: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

2
.npmrc
View File

@@ -6,4 +6,4 @@ public-hoist-pattern[]=*types*
public-hoist-pattern[]=*eslint*
public-hoist-pattern[]=@prettier/plugin-*
public-hoist-pattern[]=*prettier-plugin-*
strict-peer-dependencies=false

View File

@@ -1,6 +1,6 @@
# Contributing
[Read the Contributing Guide at Blitzjs.com](https://blitzjs.com/docs/contributing)
[Read the Contributing Guide at Blitzjs.com](https://alpha.blitzjs.com/docs/contributing)
## To run tests

View File

@@ -1,7 +1,11 @@
import React from "react"
import Head from "next/head"
import React, { FC } from "react"
import { BlitzLayout } from "@blitzjs/next"
const Layout: FC<{ title?: string; children?: React.ReactNode }> = ({ title, children }) => {
const Layout: BlitzLayout<{ title?: string; children?: React.ReactNode }> = ({
title,
children,
}) => {
return (
<>
<Head>

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.48",
"next": "12.1.6-canary.17",
"prisma": "3.9.0",
"blitz": "workspace:2.0.0-alpha.56",
"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",
@@ -46,7 +46,10 @@
"@types/node": "17.0.16",
"@types/preview-email": "2.0.1",
"@types/react": "18.0.1",
"@typescript-eslint/eslint-plugin": "5.9.1",
"eslint": "7.32.0",
"eslint-config-next": "12.2.0",
"eslint-config-prettier": "8.5.0",
"husky": "7.0.4",
"jest": "27.5.1",
"lint-staged": "12.1.7",

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

@@ -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,4 +1,2 @@
const {withBlitz} = require("@blitzjs/next")
module.exports = withBlitz({
// update me
})
module.exports = withBlitz({})

View File

@@ -15,7 +15,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

@@ -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

@@ -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

@@ -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

@@ -22,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

@@ -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,78 @@
# @blitzjs/auth
## 2.0.0-alpha.56
### Patch Changes
- 3f20a474: Update `deleteSession` return type — allow undefined values
- abe2afcc: Fix a long-standing issue with occasional blitz auth flakiness
This bug would sometimes cause users to be logged out or to experience an CSRFTokenMismatchError. This bug, when encountered, usually by lots of setPublicData or session.create calls, would not set the cookie headers correctly resulting in cookies being set to a previous state or in a possibly undefined state.
There are no security concerns as far as I can tell.
- 8bcb471a: Fix auth issue where session token and publicData cookie were updated unnecessarily, leading to potential user logout
- Previously, we were updating the session token each time public data changed. This is not needed, and it would cause race condition bugs where a user could be unexpectedly logged out because a request already in flight would not match the new session token.
- Previously, we were updating the publicData cookie even when it hadn't changed. This may reduce unnecessary re-renders on the client.
- Updated dependencies [abb1ad5d]
- Updated dependencies [abe2afcc]
- Updated dependencies [0ac6e171]
- Updated dependencies [8bcb471a]
- blitz@2.0.0-alpha.56
## 2.0.0-alpha.55
### Patch Changes
- 1c809094: Fix `Page.authenticate` not working for layout components
- Updated dependencies [8f166a5d]
- Updated dependencies [54a66a95]
- blitz@2.0.0-alpha.55
## 2.0.0-alpha.54
### Patch Changes
- Updated dependencies [f397cc20]
- Updated dependencies [cacb65d6]
- Updated dependencies [348fd6f5]
- Updated dependencies [20fc9f80]
- Updated dependencies [a3bbe6ce]
- Updated dependencies [ffa7b5cc]
- blitz@2.0.0-alpha.54
## 2.0.0-alpha.53
### Patch Changes
- blitz@2.0.0-alpha.53
## 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

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/auth",
"version": "2.0.0-alpha.48",
"version": "2.0.0-alpha.56",
"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.48",
"blitz": "2.0.0-alpha.56",
"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.48",
"@blitzjs/config": "workspace:2.0.0-alpha.56",
"@testing-library/react": "13.0.0",
"@testing-library/react-hooks": "7.0.2",
"@types/cookie": "0.4.1",

View File

@@ -216,8 +216,8 @@ export function getAuthValues<TProps = any>(
) {
if (!Page) return {}
let authenticate = "authenticate" in Page && Page.authenticate
let redirectAuthenticatedTo = "redirectAuthenticatedTo" in Page && Page.redirectAuthenticatedTo
let authenticate = (Page as BlitzPage)?.authenticate
let redirectAuthenticatedTo = (Page as BlitzPage)?.redirectAuthenticatedTo
if (authenticate === undefined && redirectAuthenticatedTo === undefined) {
const layout = "getLayout" in Page && Page.getLayout?.(<Page {...props} />)

View File

@@ -0,0 +1,41 @@
import {expect, describe, it} from "vitest"
import {setCookie} from "./auth-sessions"
import cookie from "cookie"
import {ServerResponse} from "http"
describe("blitz-auth", () => {
describe("setCookie", () => {
it("works with empty start", async () => {
const res = new ServerResponse({} as any)
setCookie(res, cookie.serialize("A", "a-value", {}))
expect(res.getHeader("Set-Cookie")).toBe("A=a-value")
})
it("works with string start", async () => {
const res = new ServerResponse({} as any)
res.setHeader("Set-Cookie", cookie.serialize("A", "a-value", {}))
setCookie(res, cookie.serialize("B", "b-value", {}))
expect(res.getHeader("Set-Cookie")).toEqual(["A=a-value", "B=b-value"])
})
it("works with array start for new name", async () => {
const res = new ServerResponse({} as any)
res.setHeader("Set-Cookie", [
cookie.serialize("A", "a-value", {}),
cookie.serialize("B", "b-value", {}),
])
setCookie(res, cookie.serialize("C", "c-value", {}))
expect(res.getHeader("Set-Cookie")).toEqual(["A=a-value", "B=b-value", "C=c-value"])
})
it("works with array start for existing name", async () => {
const res = new ServerResponse({} as any)
res.setHeader("Set-Cookie", [
cookie.serialize("A", "a-value", {}),
cookie.serialize("B", "b-value", {}),
])
setCookie(res, cookie.serialize("A", "new-a-value", {}))
expect(res.getHeader("Set-Cookie")).toEqual(["A=new-a-value", "B=b-value"])
})
})
})

View File

@@ -385,7 +385,7 @@ const parseAnonymousSessionToken = (token: string) => {
}
}
const setCookie = (res: ServerResponse, cookieStr: string) => {
export const setCookie = (res: ServerResponse, cookieStr: string) => {
const getCookieName = (c: string) => c.split("=", 2)[0]
const appendCookie = () => append(res, "Set-Cookie", cookieStr)
@@ -407,7 +407,7 @@ const setCookie = (res: ServerResponse, cookieStr: string) => {
for (let i = 0; i < cookiesHeader.length; i++) {
if (cookieName === getCookieName(cookiesHeader[i] || "")) {
cookiesHeader[i] = cookieStr
res.setHeader("Set-Cookie", cookieStr)
res.setHeader("Set-Cookie", cookiesHeader)
return
}
}
@@ -801,30 +801,16 @@ async function refreshSession(
const expiresAt = addYears(new Date(), 30)
setAnonymousSessionCookie(req, res, anonymousSessionToken, expiresAt)
setPublicDataCookie(req, res, publicDataToken, expiresAt)
setCSRFCookie(req, res, sessionKernel.antiCSRFToken, expiresAt)
} else if (global.sessionConfig.method === "essential" && "sessionToken" in sessionKernel) {
const expiresAt = addMinutes(new Date(), global.sessionConfig.sessionExpiryMinutes as number)
const publicDataToken = createPublicDataToken(sessionKernel.publicData)
let sessionToken: string
// Only generate new session token if public data actually changed
// Otherwise if new session token is generated just for refresh, then
// we have race condition bugs
if (publicDataChanged) {
sessionToken = createSessionToken(sessionKernel.handle, sessionKernel.publicData)
} else {
sessionToken = sessionKernel.sessionToken
}
setSessionCookie(req, res, sessionToken, expiresAt)
setPublicDataCookie(req, res, publicDataToken, expiresAt)
setCSRFCookie(req, res, sessionKernel.antiCSRFToken, expiresAt)
debug("Updating session in db with", {expiresAt})
if (publicDataChanged) {
debug("Public data has changed")
const publicDataToken = createPublicDataToken(sessionKernel.publicData)
setPublicDataCookie(req, res, publicDataToken, expiresAt)
await global.sessionConfig.updateSession(sessionKernel.handle, {
expiresAt,
hashedSessionToken: hash256(sessionToken),
publicData: JSON.stringify(sessionKernel.publicData),
})
} else {

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

@@ -47,7 +47,7 @@ export interface SessionConfigMethods {
handle: string,
session: Partial<SessionModel>,
) => Promise<SessionModel | undefined>
deleteSession: (handle: string) => Promise<SessionModel>
deleteSession: (handle: string) => Promise<SessionModel | undefined>
}
export interface SessionConfig extends SessionConfigMethods {

View File

@@ -1,5 +1,65 @@
# @blitzjs/next
## 2.0.0-alpha.56
### Patch Changes
- d9fc5d8e: Allow prefetching multiple queries in gSSP and gSP
- @blitzjs/rpc@2.0.0-alpha.56
## 2.0.0-alpha.55
### Patch Changes
- 8d9ea00e: Fix prefetching multiple queries causes only the last one to be passed to page
- Updated dependencies [df7cee84]
- @blitzjs/rpc@2.0.0-alpha.55
## 2.0.0-alpha.54
### Patch Changes
- 348fd6f5: Fix redirectAuthenticatedTo errors
- 20fc9f80: Fix SSP / SP not prefetching queries correctly
- 80e1ead7: Add jest.config.js to newly generated typescript apps
- Updated dependencies [20fc9f80]
- @blitzjs/rpc@2.0.0-alpha.54
## 2.0.0-alpha.53
### Patch Changes
- a7e37c58: Export BlitzProvider from @blitzjs/next
- @blitzjs/rpc@2.0.0-alpha.53
## 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

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/next",
"version": "2.0.0-alpha.48",
"version": "2.0.0-alpha.56",
"scripts": {
"build": "unbuild",
"dev": "pnpm predev && pnpm watch unbuild src --wait=0.2",
@@ -18,12 +18,13 @@
"sideEffects": false,
"license": "MIT",
"files": [
"jest/**",
"dist/**",
"scripts/**",
"eslint.js"
],
"dependencies": {
"@blitzjs/rpc": "2.0.0-alpha.48",
"@blitzjs/rpc": "2.0.0-alpha.56",
"@types/hoist-non-react-statics": "3.3.1",
"debug": "4.3.3",
"fs-extra": "10.0.1",
@@ -32,7 +33,7 @@
"superjson": "1.8.0"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-alpha.48",
"@blitzjs/config": "workspace:2.0.0-alpha.56",
"@testing-library/dom": "8.13.0",
"@testing-library/jest-dom": "5.16.3",
"@testing-library/react": "13.0.0",
@@ -42,10 +43,10 @@
"@types/react": "18.0.1",
"@types/react-dom": "17.0.14",
"@types/testing-library__react-hooks": "4.0.0",
"blitz": "2.0.0-alpha.48",
"blitz": "2.0.0-alpha.56",
"cross-spawn": "7.0.3",
"find-up": "4.1.0",
"next": "12.1.6-canary.17",
"next": "12.2.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"resolve-from": "5.0.0",
@@ -58,7 +59,7 @@
"access": "public"
},
"peerDependencies": {
"next": "*",
"next": ">=12.2.0",
"react": "*"
}
}

View File

@@ -6,14 +6,15 @@ import type {
Simplify,
} from "blitz"
import Head from "next/head"
import React from "react"
import React, {ReactNode} from "react"
import {QueryClient, QueryClientProvider} from "react-query"
import {Hydrate, HydrateOptions} from "react-query/hydration"
import {withSuperJSONPage} from "./superjson"
import {Ctx} from "blitz"
import {UrlObject} from "url"
import {AppPropsType} from "next/dist/shared/lib/utils"
import {Router} from "next/router"
import {Router, useRouter} from "next/router"
import {RouterContext} from "./router-context"
export * from "./error-boundary"
export * from "./error-component"
@@ -35,11 +36,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")
@@ -51,7 +48,7 @@ const buildWithBlitz = <TPlugins extends readonly ClientPlugin<object>[]>(plugin
<>
{/* @ts-ignore todo */}
{props.Component.suppressFirstRenderFlicker && <NoPageFlicker />}
{mounted && <UserAppRoot {...props} Component={component} />}
<UserAppRoot {...props} Component={component} />
</>
</BlitzProvider>
)
@@ -71,6 +68,7 @@ export type BlitzProviderProps = {
interface RouteUrlObject extends Pick<UrlObject, "pathname" | "query"> {
pathname: string
}
type RedirectAuthenticatedTo = string | RouteUrlObject | false
type RedirectAuthenticatedToFnCtx = {
session: Ctx["session"]["$publicData"]
@@ -82,34 +80,38 @@ export type BlitzPage<P = {}> = React.ComponentType<P> & {
suppressFirstRenderFlicker?: boolean
redirectAuthenticatedTo?: RedirectAuthenticatedTo | RedirectAuthenticatedToFn
}
export type BlitzLayout<P = {}> = React.ComponentType<P> & {
export type BlitzLayout<P = {}> = React.ComponentType<P & {children: ReactNode}> & {
authenticate?: boolean | {redirectTo?: string | RouteUrlObject}
redirectAuthenticatedTo?: RedirectAuthenticatedTo | RedirectAuthenticatedToFn
}
export type AppProps<P = {}> = AppPropsType<Router, P> & {
Component: BlitzPage
}
const BlitzProvider = ({
client,
export const BlitzProvider = ({
client = globalThis.queryClient,
contextSharing = false,
dehydratedState,
hydrateOptions,
children,
}: BlitzProviderProps) => {
if (globalThis.queryClient) {
const router = useRouter()
if (client) {
return (
<QueryClientProvider
client={client || globalThis.queryClient}
contextSharing={contextSharing}
>
<Hydrate state={dehydratedState} options={hydrateOptions}>
{children}
</Hydrate>
</QueryClientProvider>
<RouterContext.Provider value={router}>
<QueryClientProvider
client={client || globalThis.queryClient}
contextSharing={contextSharing}
>
<Hydrate state={dehydratedState} options={hydrateOptions}>
{children}
</Hydrate>
</QueryClientProvider>
</RouterContext.Provider>
)
}
return children
return <RouterContext.Provider value={router}>{children}</RouterContext.Provider>
}
export type PluginsExports<TPlugins extends readonly ClientPlugin<object>[]> = Simplify<

View File

@@ -17,11 +17,17 @@ 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"
@@ -74,6 +80,27 @@ export type BlitzAPIHandler = (
ctx: Ctx,
) => ReturnType<NextApiHandler>
const prefetchQueryFactory = (
ctx: BlitzCtx,
): {
queryClient: QueryClient | null
prefetchQuery: AddParameters<PrefetchQueryFn, [boolean?]>
} => {
let queryClient: null | QueryClient = null
return {
queryClient,
prefetchQuery: async (fn, input, defaultOptions = {}, infinite = false) => {
if (!queryClient) {
queryClient = new QueryClient({defaultOptions})
}
const queryKey = infinite ? getInfiniteQueryKey(fn, input) : getQueryKey(fn, input)
await queryClient.prefetchQuery(queryKey, () => fn(input, ctx))
},
}
}
export const setupBlitzServer = ({plugins, onError}: SetupBlitzOptions) => {
const middlewares = plugins.flatMap((p) => p.requestMiddlewares)
const contextMiddleware = plugins.flatMap((p) => p.contextMiddleware).filter(Boolean)
@@ -88,19 +115,8 @@ export const setupBlitzServer = ({plugins, onError}: SetupBlitzOptions) => {
(y, f) => (f ? f(y) : y),
(res as MiddlewareResponse).blitzCtx,
)
let queryClient: null | QueryClient = null
const prefetchQuery: AddParameters<PrefetchQueryFn, [boolean?]> = async (
fn,
input,
defaultOptions = {},
infinite = false,
) => {
queryClient = new QueryClient({defaultOptions})
const queryKey = infinite ? getQueryKey(fn, input) : getInfiniteQueryKey(fn, input)
await queryClient.prefetchQuery(queryKey, () => fn(input, ctx))
}
const {queryClient, prefetchQuery} = prefetchQueryFactory(ctx)
ctx.prefetchQuery = prefetchQuery
ctx.prefetchInfiniteQuery = (...args) => prefetchQuery(...args, true)
@@ -120,19 +136,7 @@ export const setupBlitzServer = ({plugins, onError}: SetupBlitzOptions) => {
): GetStaticProps<TProps, Query, PD> =>
async (context) => {
const ctx = contextMiddleware.reduceRight((y, f) => (f ? f(y) : y), {} as Ctx)
let queryClient: null | QueryClient = null
const prefetchQuery: AddParameters<PrefetchQueryFn, [boolean?]> = async (
fn,
input,
defaultOptions = {},
infinite = false,
) => {
queryClient = new QueryClient({defaultOptions})
const queryKey = infinite ? getQueryKey(fn, input) : getInfiniteQueryKey(fn, input)
await queryClient.prefetchQuery(queryKey, () => fn(input, ctx))
}
const {queryClient, prefetchQuery} = prefetchQueryFactory(ctx)
ctx.prefetchQuery = prefetchQuery
ctx.prefetchInfiniteQuery = (...args) => prefetchQuery(...args, true)
@@ -163,59 +167,13 @@ export const setupBlitzServer = ({plugins, onError}: 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" &&
@@ -236,7 +194,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)
}
@@ -259,8 +222,8 @@ function withDehydratedState<T extends Result>(result: T, queryClient: QueryClie
if (!queryClient) {
return result
}
const dehydratedProps = dehydrate(queryClient)
return {...result, props: {...("props" in result ? result.props : undefined), dehydratedProps}}
const dehydratedState = dehydrate(queryClient)
return {...result, props: {...("props" in result ? result.props : undefined), dehydratedState}}
}
declare module "blitz" {

View File

@@ -1,5 +1,79 @@
# @blitzjs/rpc
## 2.0.0-alpha.56
### Patch Changes
- Updated dependencies [3f20a474]
- Updated dependencies [abb1ad5d]
- Updated dependencies [abe2afcc]
- Updated dependencies [0ac6e171]
- Updated dependencies [8bcb471a]
- @blitzjs/auth@2.0.0-alpha.56
- blitz@2.0.0-alpha.56
## 2.0.0-alpha.55
### Patch Changes
- df7cee84: Fix pipe resolver return type
- Updated dependencies [8f166a5d]
- Updated dependencies [54a66a95]
- Updated dependencies [1c809094]
- blitz@2.0.0-alpha.55
- @blitzjs/auth@2.0.0-alpha.55
## 2.0.0-alpha.54
### Patch Changes
- 20fc9f80: Fix SSP / SP not prefetching queries correctly
- Updated dependencies [f397cc20]
- Updated dependencies [cacb65d6]
- Updated dependencies [348fd6f5]
- Updated dependencies [20fc9f80]
- Updated dependencies [a3bbe6ce]
- Updated dependencies [ffa7b5cc]
- blitz@2.0.0-alpha.54
- @blitzjs/auth@2.0.0-alpha.54
## 2.0.0-alpha.53
### Patch Changes
- @blitzjs/auth@2.0.0-alpha.53
- blitz@2.0.0-alpha.53
## 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

View File

@@ -5,6 +5,7 @@ const config: BuildConfig = {
"./src/index-browser",
"./src/index-server",
"./src/loader-server",
"./src/loader-server-resolvers",
"./src/loader-client",
],
externals: [

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/rpc",
"version": "2.0.0-alpha.48",
"version": "2.0.0-alpha.56",
"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.48",
"@blitzjs/auth": "2.0.0-alpha.56",
"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.48",
"@blitzjs/config": "workspace:2.0.0-alpha.56",
"@types/debug": "4.1.7",
"@types/react": "18.0.1",
"@types/react-dom": "17.0.14",
"blitz": "2.0.0-alpha.48",
"next": "12.1.6-canary.17",
"blitz": "2.0.0-alpha.56",
"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.48",
"next": "*"
"blitz": "2.0.0-alpha.56",
"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, 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
@@ -26,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.
@@ -51,8 +50,58 @@ 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 loaderClient = resolve(dir, "./loader-client.cjs")
const loaderServer = resolve(dir, "./loader-server.cjs")
const loaderServerResolvers = resolve(dir, "./loader-server-resolvers.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,
},
{
loader: loaderServerResolvers,
options: webpackRuleOptions,
},
],
})
}
// ----------
// END LOADER

View File

@@ -42,7 +42,7 @@ export async function transformBlitzRpcResolverClient(
const resolverFilePath = "/" + posix.relative(root, id)
assertPosixPath(resolverFilePath)
const routePath = convertPageFilePathToRoutePath(resolverFilePath, options?.resolverBasePath)
const routePath = convertPageFilePathToRoutePath(resolverFilePath, options?.resolverPath)
const resolverName = convertFilePathToResolverName(resolverFilePath)
const resolverType = convertFilePathToResolverType(resolverFilePath)

View File

@@ -0,0 +1,50 @@
import {describe, expect, it} from "vitest"
import {transformBlitzRpcResolverServer} from "./loader-server-resolvers"
const META_TAGS_AND_EXPORT = `
__internal_rpcHandler._resolverName = 'test'
__internal_rpcHandler._resolverType = 'query'
__internal_rpcHandler._routePath = '/api/rpc/test'
export default __internal_rpcHandler
`.trim()
describe("transformBlitzRpcResolverServer", () => {
it("should compile for function", async () => {
const result = await transformBlitzRpcResolverServer(
"export default function test() { return 'test' }",
"queries/test.js",
"/",
)
expect(result).toBe(
`const __internal_rpcHandler = function test() { return 'test' }\n\n${META_TAGS_AND_EXPORT}`,
)
})
it("should compile with resolver", async () => {
const result = await transformBlitzRpcResolverServer(
`const test = resolver.pipe(() => Promise.resolve('test'))
export default test`,
"queries/test.js",
"/",
)
expect(result).toBe(
`const test = resolver.pipe(() => Promise.resolve('test'))
const __internal_rpcHandler = test\n\n${META_TAGS_AND_EXPORT}`,
)
})
it("should compile for plain lambda", async () => {
const result = await transformBlitzRpcResolverServer(
"export default () => Promise.resolve('test')",
"queries/test.js",
"/",
)
expect(result).toBe(
`const __internal_rpcHandler = () => Promise.resolve('test')\n\n${META_TAGS_AND_EXPORT}`,
)
})
})

View File

@@ -0,0 +1,68 @@
import {
assertPosixPath,
convertFilePathToResolverName,
convertFilePathToResolverType,
convertPageFilePathToRoutePath,
Loader,
LoaderOptions,
toPosixPath,
} from "./loader-utils"
import {normalizeApiRoute} from "./data-client"
import {posix} from "path"
// Subset of `import type { LoaderDefinitionFunction } from 'webpack'`
export async function loader(this: Loader, input: string): Promise<string> {
const compiler = this._compiler!
const id = this.resource
const root = this._compiler!.context
const isSSR = compiler.name === "server"
if (isSSR) {
return await transformBlitzRpcResolverServer(
input,
toPosixPath(id),
toPosixPath(root),
this.query,
)
}
return input
}
module.exports = loader
export async function transformBlitzRpcResolverServer(
src: string,
id: string,
root: string,
options?: LoaderOptions,
) {
assertPosixPath(id)
assertPosixPath(root)
const resolverFilePath = "/" + posix.relative(root, id)
assertPosixPath(resolverFilePath)
const routePath = convertPageFilePathToRoutePath(resolverFilePath, options?.resolverPath)
const resolverName = convertFilePathToResolverName(resolverFilePath)
const resolverType = convertFilePathToResolverType(resolverFilePath)
const fullRoutePath = normalizeApiRoute("/api/rpc" + routePath)
const lines = src.split("\n")
const newLines = lines.map((line) => {
if (line.trim().startsWith("export default")) {
return line.replace("export default", "const __internal_rpcHandler =")
}
return line
})
return `${newLines.join("\n")}
__internal_rpcHandler._resolverName = '${resolverName}'
__internal_rpcHandler._resolverType = '${resolverType}'
__internal_rpcHandler._routePath = '${fullRoutePath}'
export default __internal_rpcHandler`
}

View File

@@ -55,7 +55,7 @@ export async function transformBlitzRpcServer(
for (let resolverFilePath of resolvers) {
const relativeResolverPath = posix.relative(dirname(id), join(root, resolverFilePath))
const routePath = convertPageFilePathToRoutePath(resolverFilePath, options?.resolverBasePath)
const routePath = convertPageFilePathToRoutePath(resolverFilePath, options?.resolverPath)
code += `__internal_addBlitzRpcResolver('${routePath}', () => import('${relativeResolverPath}'));`
code += "\n"
}

View File

@@ -1,9 +1,9 @@
import {assert} from "blitz"
import {posix, sep, win32} from "path"
import {ResolverBasePath} from "./index-server"
import {ResolverPathOptions} from "./index-server"
export interface LoaderOptions {
resolverBasePath?: ResolverBasePath
resolverPath: ResolverPathOptions
}
export interface Loader {
@@ -51,9 +51,13 @@ const fileExtensionRegex = /\.([a-z]+)$/
export function convertPageFilePathToRoutePath(
filePath: string,
resolverBasePath: ResolverBasePath,
resolverPath?: ResolverPathOptions,
) {
if (resolverBasePath === "root") {
if (typeof resolverPath === "function") {
return resolverPath(filePath)
}
if (resolverPath === "root") {
return filePath.replace(fileExtensionRegex, "")
}

View File

@@ -54,7 +54,7 @@ function pipe<A, B, C, D, E, F, G, CA = Ctx, CB = CA, CC = CB, CD = CC, CE = CD,
de: PipeFn<D, E, CD, CE>,
ef: PipeFn<E, F, CE, CF>,
fg: PipeFn<F, G, CF, CG>,
): (input: A, ctx: CA) => EnsurePromise<CG>
): (input: A, ctx: CA) => EnsurePromise<G>
function pipe<
A,
B,

View File

@@ -1,5 +1,78 @@
# blitz
## 2.0.0-alpha.56
### Patch Changes
- abb1ad5d: Improve codemod utilities
- abe2afcc: Fix a long-standing issue with occasional blitz auth flakiness
This bug would sometimes cause users to be logged out or to experience an CSRFTokenMismatchError. This bug, when encountered, usually by lots of setPublicData or session.create calls, would not set the cookie headers correctly resulting in cookies being set to a previous state or in a possibly undefined state.
There are no security concerns as far as I can tell.
- 0ac6e171: fixes blitz not loading custom server
- 8bcb471a: Fix auth issue where session token and publicData cookie were updated unnecessarily, leading to potential user logout
- Previously, we were updating the session token each time public data changed. This is not needed, and it would cause race condition bugs where a user could be unexpectedly logged out because a request already in flight would not match the new session token.
- Previously, we were updating the publicData cookie even when it hadn't changed. This may reduce unnecessary re-renders on the client.
- @blitzjs/generator@2.0.0-alpha.56
## 2.0.0-alpha.55
### Patch Changes
- 8f166a5d: Check for new versions when running CLI
- 54a66a95: Show all blitz packages when running `blitz version` command
- Updated dependencies [ab4d9de7]
- @blitzjs/generator@2.0.0-alpha.55
## 2.0.0-alpha.54
### Patch Changes
- f397cc20: Fixes issue when generating a new blitz app with the form flag that ends up installing the wrong form library
- cacb65d6: Fixes wrong import of the db module in `blitz db seed` command function
- 348fd6f5: Fix redirectAuthenticatedTo errors
- 20fc9f80: Fix SSP / SP not prefetching queries correctly
- a3bbe6ce: Fix routes manifest showing duplicates for non queries|resolvers reso…
- ffa7b5cc: During `blitz new` if project name argument is set to "." change it to current folder name
- Updated dependencies [a961aff8]
- Updated dependencies [80e1ead7]
- @blitzjs/generator@2.0.0-alpha.54
## 2.0.0-alpha.53
### Patch Changes
- @blitzjs/generator@2.0.0-alpha.53
## 2.0.0-alpha.52
### Patch Changes
- Updated dependencies [12cb7a72]
- @blitzjs/generator@2.0.0-alpha.52
## 2.0.0-alpha.51
### Patch Changes
- @blitzjs/generator@2.0.0-alpha.51
## 2.0.0-alpha.50
### Patch Changes
- Updated dependencies [c11f0401]
- @blitzjs/generator@2.0.0-alpha.50
## 2.0.0-alpha.49
### Patch Changes
- @blitzjs/generator@2.0.0-alpha.49
## 2.0.0-alpha.48
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "blitz",
"version": "2.0.0-alpha.48",
"version": "2.0.0-alpha.56",
"scripts": {
"build": "unbuild",
"dev": "watch unbuild src --wait=0.2",
@@ -23,8 +23,9 @@
"blitz": "bin/blitz"
},
"dependencies": {
"@blitzjs/generator": "2.0.0-alpha.48",
"@blitzjs/generator": "2.0.0-alpha.56",
"arg": "5.0.1",
"boxen": "7.0.0",
"chalk": "^4.1.0",
"console-table-printer": "2.10.0",
"cross-spawn": "7.0.3",
@@ -37,6 +38,7 @@
"find-up": "4.1.0",
"fs-extra": "10.0.1",
"hasbin": "1.2.3",
"node-fetch": "3.2.3",
"npm-which": "3.0.1",
"ora": "5.3.0",
"os-name": "5.0.1",
@@ -52,7 +54,7 @@
"watchpack": "2.1.1"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-alpha.48",
"@blitzjs/config": "workspace:2.0.0-alpha.56",
"@types/cookie": "0.4.1",
"@types/cross-spawn": "6.0.2",
"@types/debug": "4.1.7",
@@ -69,13 +71,12 @@
"@types/test-listen": "1.1.0",
"@types/watchpack": "1.1.1",
"express": "4.17.3",
"node-fetch": "3.2.3",
"react": "18.0.0",
"test-listen": "1.1.0",
"typescript": "^4.5.3",
"unbuild": "0.6.9",
"watch": "1.0.2",
"zod": "3.10.1"
"zod": "3.17.3"
},
"peerDependencies": {
"react": "*"

View File

@@ -1,8 +1,30 @@
import {CliCommand} from "../index"
/* @ts-ignore */
import {generateManifest} from "../utils/routes-manifest"
import resolveCwd from "resolve-cwd"
import {join} from "path"
import fs from "fs-extra"
const codegen: CliCommand = async () => {
try {
/*
Updates the user's nextjs file and adds onRecoverableError to the hydrateRoot 3rd parameter object.
We can remove this when https://github.com/vercel/next.js/pull/38207 is merged into next.js
*/
const nextDir = await resolveCwd("next")
const nextClientIndex = join(nextDir, "../..", "client", "index.js")
const readFile = await fs.readFile(nextClientIndex)
const updatedFile = readFile
.toString()
.replace(
/ReactDOM\.hydrateRoot\(.*?\);/,
`ReactDOM.hydrateRoot(domEl, reactEl, process.env.NODE_ENV === 'development' ? {onRecoverableError: (err) => err.toString().includes("could not finish this Suspense boundary") ? null : console.error(err)} : undefined);`,
)
await fs.writeFile(nextClientIndex, updatedFile)
} catch (err) {
console.log(err)
}
try {
await generateManifest()
} catch (err) {

View File

@@ -51,7 +51,7 @@ const runSeed = async (seedBasePath: string) => {
throw err
}
const db = require(dbPath).db
const db = require(dbPath)
await db.$disconnect()
console.log("Done Seeding")
}

View File

@@ -7,6 +7,7 @@ import {CliCommand} from "../index"
import arg from "arg"
import {AppGenerator, AppGeneratorOptions, getLatestVersion} from "@blitzjs/generator"
import {runPrisma} from "../../prisma-utils"
import {checkLatestVersion} from "../utils/check-latest-version"
const forms = {
"react-final-form": "React Final Form" as const,
@@ -24,8 +25,13 @@ const language = {
type TLanguage = keyof typeof language
type TPkgManager = "npm" | "yarn" | "pnpm"
type TTemplate = "full" | "minimal"
const installCommandMap: Record<TPkgManager, string> = {
yarn: "yarn",
pnpm: "pnpm install",
npm: "npm install",
}
type TTemplate = "full" | "minimal"
const templates: {[key in TTemplate]: AppGeneratorOptions["template"]} = {
full: {
path: "app",
@@ -87,6 +93,10 @@ const determineProjectName = async () => {
projectPath = path.resolve(projectName)
} else {
projectName = args._.slice(1)[0] as string
if (projectName === ".") {
projectName = path.basename(process.cwd())
}
projectPath = path.resolve(projectName)
}
}
@@ -128,14 +138,7 @@ const determineFormLib = async () => {
projectFormLib = res.form
} else {
switch (args["--form"] as TForms) {
case "react-final-form":
projectFormLib = forms["react-final-form"]
case "react-hook-form":
projectFormLib = forms["react-hook-form"]
case "formik":
projectFormLib = forms["formik"]
}
projectFormLib = forms[args["--form"] as TForms]
}
}
@@ -202,11 +205,7 @@ const determinePkgManagerToInstallDeps = async () => {
projectPkgManger = res.pkgManager
if (res.pkgManager === "skip") {
shouldInstallDeps = false
} else {
shouldInstallDeps = true
}
shouldInstallDeps = res.pkgManager !== "skip"
} else {
const res = await prompts({
type: "confirm",
@@ -222,7 +221,7 @@ const determinePkgManagerToInstallDeps = async () => {
const newApp: CliCommand = async (argv) => {
const shouldUpgrade = !args["--skip-upgrade"]
if (shouldUpgrade) {
//TODO: Handle checking for updates
await checkLatestVersion()
}
await determineProjectName()
@@ -278,16 +277,7 @@ const newApp: CliCommand = async (argv) => {
await generator.run()
if (requireManualInstall) {
let cmd
switch (projectPkgManger) {
case "yarn":
cmd = "yarn"
case "npm":
cmd = "npm install"
case "pnpm":
cmd = "pnpm install"
}
postInstallSteps.push(cmd)
postInstallSteps.push(installCommandMap[projectPkgManger])
postInstallSteps.push(
"blitz prisma migrate dev (when asked, you can name the migration anything)",
)

View File

@@ -1,12 +1,12 @@
import {NON_STANDARD_NODE_ENV} from "./utils/constants"
import arg from "arg"
import {loadEnvConfig} from "../env-utils"
import {getCommandBin} from "./utils/config"
import spawn from "cross-spawn"
import {readdirSync} from "fs-extra"
import resolveFrom from "resolve-from"
import pkgDir from "pkg-dir"
import {join} from "path"
import {loadEnvConfig} from "../env-utils"
import {NON_STANDARD_NODE_ENV} from "./utils/constants"
import {getCommandBin} from "./utils/config"
import {readVersions} from "./utils/read-versions"
import {getPkgManager} from "./utils/helpers"
const commonArgs = {
// Flags
@@ -57,9 +57,6 @@ if (aliases[args._[0] as Alias]) {
const forwardedArgs = blitzCommand ? args._.slice(1) : args._
const globalBlitzPath = resolveFrom(__dirname, "blitz")
const localBlitzPath = resolveFrom.silent(process.cwd(), "blitz")
async function runCommandFromBin() {
if (!args._[0]) {
console.log("No command specified")
@@ -83,18 +80,17 @@ async function runCommandFromBin() {
async function printEnvInfo() {
const osName = await import("os-name")
const envinfo = await import("envinfo")
const pkgManager = readdirSync(process.cwd()).includes("pnpm-lock.yaml")
? "pnpm"
: readdirSync(process.cwd()).includes("yarn-lock.yaml")
? "yarn"
: "npm"
const pkgManager = getPkgManager()
const env = await envinfo.default.run(
{
System: ["OS", "CPU", "Memory", "Shell"],
Binaries: ["Node", "Yarn", "npm", "pnpm"],
npmPackages: [
"blitz",
"@blitzjs/rpc",
"@blitzjs/auth",
"@blitzjs/next",
"typescript",
"react",
"react-dom",
@@ -106,18 +102,13 @@ async function printEnvInfo() {
{showNotFound: true},
)
const globalBlitzPkgJsonPath = pkgDir.sync(globalBlitzPath)
const localBlitzPkgJsonPath = pkgDir.sync(localBlitzPath)
if (globalBlitzPkgJsonPath && globalBlitzPkgJsonPath !== localBlitzPkgJsonPath) {
// This branch won't run if user does `npx blitz` or `yarn blitz`
const globalVersion = require(join(globalBlitzPkgJsonPath, "package.json")).version
const {globalVersion, localVersions} = readVersions()
if (globalVersion) {
console.log(`Blitz version: ${globalVersion} (global)`)
}
if (localBlitzPkgJsonPath) {
const localVersion = require(join(localBlitzPkgJsonPath, "package.json")).version
console.log(`Blitz version: ${localVersion} (local)`)
if (localVersions.blitz) {
console.log(`Blitz version: ${localVersions.blitz} (local)`)
}
console.log(

View File

@@ -0,0 +1,185 @@
import findUp from "find-up"
import resolveFrom from "resolve-from"
import {join, dirname} from "path"
import fs from "fs"
import {readVersions, resolveVersionType} from "./read-versions"
import {getPkgManager} from "./helpers"
import superjson from "superjson"
const returnNpmEndpoint = (packageName: string) => {
return `https://registry.npmjs.org/-/package/${packageName}/dist-tags`
}
function getUpdateString(packageName: string, tag: string, isGlobal?: boolean) {
const pkgManager = getPkgManager()
switch (pkgManager) {
case "npm":
return `npm install${isGlobal ? " -g" : ""} ${packageName}@${tag}`
case "yarn":
return `yarn${isGlobal ? " global" : ""} add ${packageName}@${tag}`
case "pnpm":
return `pnpm install${isGlobal ? " -g" : ""} ${packageName}@${tag}`
}
}
const isInternalBlitzMonorepoDevelopment = fs.existsSync(
join(process.cwd(), "..", "..", "packages", "blitz", "dist", "chunks"),
)
async function findNodeModulesRoot(src: string) {
const blitzPkgLocation = dirname(
(await findUp("package.json", {
cwd: resolveFrom(src, "blitz"),
})) ?? "",
)
if (!blitzPkgLocation) {
throw new Error("Internal Blitz Error: unable to find 'blitz' package location")
}
return blitzPkgLocation.includes(".pnpm")
? join(blitzPkgLocation, "../../../../")
: join(blitzPkgLocation, "../")
}
export async function checkLatestVersion() {
if (!isInternalBlitzMonorepoDevelopment) {
const fetch = await import("node-fetch")
const boxen = await import("boxen")
const versions = readVersions()
const nodeModulesRoot = await findNodeModulesRoot(process.cwd())
const dotBlitzCacheExists = fs.existsSync(
join(nodeModulesRoot, ".blitz", "checkUpdateCache.json"),
)
let dotBlitzCache
let shouldRun = true
if (dotBlitzCacheExists) {
dotBlitzCache = fs.readFileSync(join(nodeModulesRoot, ".blitz", "checkUpdateCache.json"))
const now = new Date()
const msBetweenTimes = Math.abs(
superjson.parse<{lastUpdated: Date}>(dotBlitzCache.toString()).lastUpdated.getTime() -
now.getTime(),
)
const hoursBetweenTimes = msBetweenTimes / (60 * 60 * 1000)
shouldRun = hoursBetweenTimes > 24
}
if (shouldRun) {
let errors: {message: string; instructions: string}[] = []
try {
const blitzResponse = await fetch.default(returnNpmEndpoint("blitz"))
const remoteBlitzVersions = (await blitzResponse.json()) as Record<string, string>
const blitzNextResponse = await fetch.default(returnNpmEndpoint("@blitzjs/next"))
const remoteBlitzNextVersions = (await blitzNextResponse.json()) as Record<string, string>
const blitzAuthResponse = await fetch.default(returnNpmEndpoint("@blitzjs/auth"))
const remoteBlitzAuthVersions = (await blitzAuthResponse.json()) as Record<string, string>
const blitzRpcResponse = await fetch.default(returnNpmEndpoint("@blitzjs/rpc"))
const remoteBlitzRpcVersions = (await blitzRpcResponse.json()) as Record<string, string>
for (const version of Object.entries(versions)) {
if (version[0] === "globalVersion") {
const versionType = resolveVersionType(version[1] as string)
if (remoteBlitzVersions.hasOwnProperty("beta") && versionType !== "beta") {
errors.push({
message: `blitz(global) (current) ${version[1]} -> (latest) ${remoteBlitzVersions["beta"]}`,
instructions: `${getUpdateString("blitz", "beta", true)}`,
})
} else if (remoteBlitzVersions[versionType] !== version[1]) {
errors.push({
message: `blitz(global) (current) ${version[1]} -> (latest) ${remoteBlitzVersions[versionType]}`,
instructions: `${getUpdateString("blitz", versionType, true)}`,
})
}
} else if (version[0] === "localVersions") {
for (const localVersion of Object.entries(version[1])) {
const versionType = resolveVersionType(localVersion[1] as string)
switch (localVersion[0]) {
case "blitz":
if (remoteBlitzVersions.hasOwnProperty("beta") && versionType !== "beta") {
errors.push({
message: `blitz (current) ${localVersion[1]} -> (latest) ${remoteBlitzVersions["beta"]}`,
instructions: `${getUpdateString("blitz", "beta", false)}`,
})
} else if (remoteBlitzVersions[versionType] !== localVersion[1]) {
errors.push({
message: `blitz (current) ${localVersion[1]} -> (latest) ${remoteBlitzVersions[versionType]}`,
instructions: `${getUpdateString("blitz", versionType, false)}`,
})
}
break
case "blitzAuth":
if (remoteBlitzAuthVersions.hasOwnProperty("beta") && versionType !== "beta") {
errors.push({
message: `@blitzjs/auth (current) ${localVersion[1]} -> (latest) ${remoteBlitzAuthVersions["beta"]}`,
instructions: `${getUpdateString("@blitzjs/auth", "beta", false)}`,
})
} else if (remoteBlitzAuthVersions[versionType] !== localVersion[1]) {
errors.push({
message: `@blitzjs/auth (current) ${localVersion[1]} -> (latest) ${remoteBlitzAuthVersions[versionType]}`,
instructions: `${getUpdateString("@blitzjs/auth", versionType, false)}`,
})
}
break
case "blitzNext":
if (remoteBlitzNextVersions.hasOwnProperty("beta") && versionType !== "beta") {
errors.push({
message: `@blitzjs/next (current) ${localVersion[1]} -> (latest) ${remoteBlitzNextVersions["beta"]}`,
instructions: `${getUpdateString("@blitzjs/next", "beta", false)}`,
})
} else if (remoteBlitzNextVersions[versionType] !== localVersion[1]) {
errors.push({
message: `@blitzjs/next (current) ${localVersion[1]} -> (latest) ${remoteBlitzNextVersions[versionType]}`,
instructions: `${getUpdateString("@blitzjs/next", versionType, false)}`,
})
}
break
case "blitzRpc":
if (remoteBlitzRpcVersions.hasOwnProperty("beta") && versionType !== "beta") {
errors.push({
message: `@blitzjs/rpc (current) ${localVersion[1]} -> (latest) ${remoteBlitzRpcVersions["beta"]}`,
instructions: `${getUpdateString("@blitzjs/rpc", "beta", false)}`,
})
} else if (remoteBlitzRpcVersions[versionType] !== localVersion[1]) {
errors.push({
message: `@blitzjs/rpc (current) ${localVersion[1]} -> (latest) ${remoteBlitzRpcVersions[versionType]}`,
instructions: `${getUpdateString("@blitzjs/rpc", versionType, false)}`,
})
}
break
}
}
}
}
console.log(
boxen.default(
`You are running outdated blitz packages\n\n ${errors
.map((e) => e.message)
.join("\n")} \n\n Run the following to update:\n ${errors
.map((e) => e.instructions)
.join("\n")}`,
{padding: 1},
),
)
const dotBlitz = join(nodeModulesRoot, ".blitz")
fs.writeFileSync(
join(dotBlitz, "checkUpdateCache.json"),
superjson.stringify({lastUpdated: new Date()}),
)
} catch (err) {
if (err instanceof fetch.FetchError) {
// TODO: Check if network error and throw otherwise
// pass fetch error
} else {
console.log(err)
}
}
}
}
}

View File

@@ -0,0 +1,9 @@
import {readdirSync} from "fs-extra"
export function getPkgManager() {
return readdirSync(process.cwd()).includes("pnpm-lock.yaml")
? "pnpm"
: readdirSync(process.cwd()).includes("yarn-lock.yaml")
? "yarn"
: "npm"
}

View File

@@ -7,6 +7,7 @@ import {
startCustomServer,
buildCustomServer,
} from "./next-utils"
import {checkLatestVersion} from "./check-latest-version"
import {readBlitzConfig} from "../../server-utils"
export async function build(config: ServerConfig) {
@@ -18,7 +19,7 @@ export async function build(config: ServerConfig) {
export async function dev(config: ServerConfig) {
const {rootFolder, nextBin} = await normalize({...config, env: "dev"})
void checkLatestVersion()
if (customServerExists()) {
console.log("Using your custom server")

View File

@@ -10,7 +10,7 @@ import type {ServerConfig} from "./config"
const debug = require("debug")("blitz:utils")
export function getProjectRootSync() {
return path.dirname(process.cwd())
return process.cwd()
}
export function getCustomServerPath() {

View File

@@ -0,0 +1,79 @@
import {join} from "path"
import pkgDir from "pkg-dir"
import resolveFrom from "resolve-from"
const globalBlitzPath = resolveFrom(__dirname, "blitz")
const localBlitzPath = resolveFrom.silent(process.cwd(), "blitz")
const localBlitzAuthPath = resolveFrom.silent(process.cwd(), "@blitzjs/auth")
const localBlitzRpcPath = resolveFrom.silent(process.cwd(), "@blitzjs/rpc")
const localBlitzNextPath = resolveFrom.silent(process.cwd(), "@blitzjs/next")
export function readVersions() {
const globalBlitzPkgJsonPath = pkgDir.sync(globalBlitzPath)
const localBlitzPkgJsonPath = pkgDir.sync(localBlitzPath)
const localBlitzAuthPkgJsonPath = pkgDir.sync(localBlitzAuthPath)
const localBlitzNextPkgJsonPath = pkgDir.sync(localBlitzNextPath)
const localBlitzRpcPkgJsonPath = pkgDir.sync(localBlitzRpcPath)
const versions: {
globalVersion?: string
localVersions: {
blitz?: string
blitzAuth?: string
blitzRpc?: string
blitzNext?: string
}
} = {globalVersion: "", localVersions: {}}
// This branch won't run if user does `npx blitz` or `yarn blitz`
if (globalBlitzPkgJsonPath && globalBlitzPkgJsonPath !== localBlitzPkgJsonPath) {
versions.globalVersion = require(join(globalBlitzPkgJsonPath, "package.json")).version
}
if (localBlitzPkgJsonPath) {
versions.localVersions.blitz = require(join(localBlitzPkgJsonPath, "package.json")).version
}
if (localBlitzAuthPkgJsonPath) {
versions.localVersions.blitzAuth = require(join(
localBlitzAuthPkgJsonPath,
"package.json",
)).version
}
if (localBlitzNextPkgJsonPath) {
versions.localVersions.blitzNext = require(join(
localBlitzNextPkgJsonPath,
"package.json",
)).version
}
if (localBlitzRpcPkgJsonPath) {
versions.localVersions.blitzRpc = require(join(
localBlitzRpcPkgJsonPath,
"package.json",
)).version
}
return versions
}
export function resolveVersionType(version: string) {
if (version.includes("alpha")) {
return "alpha" as const
}
if (version.includes("beta")) {
return "beta" as const
}
if (version.includes("danger")) {
return "danger" as const
}
if (version.includes("canary")) {
return "canary" as const
}
return "latest" as const
}

View File

@@ -228,23 +228,39 @@ export function buildPageExtensionRegex(pageExtensions: string[]) {
type PagesMapping = {
[page: string]: string
}
export function convertPageFilePathToRoutePath(filePath: string, pageExtensions: string[]) {
return filePath
.replace(/^.*?[\\/]pages[\\/]/, "/")
.replace(/^.*?[\\/]api[\\/]/, "/api/")
.replace(/^.*?[\\/]queries[\\/]/, "/api/rpc/")
.replace(/^.*?[\\/]mutations[\\/]/, "/api/rpc/")
.replace(new RegExp(`\\.+(${pageExtensions.join("|")})$`), "")
function stripExtension(filePath: string, pageExtensions: string[]) {
return filePath.replace(new RegExp(`\\.+(${pageExtensions.join("|")})$`), "")
}
export function createPagesMapping(pagePaths: string[], pageExtensions: string[]) {
export function convertPageFilePathToRoutePath(filePath: string, pageExtensions: string[]) {
return stripExtension(
filePath
.replace(/^.*?[\\/]pages[\\/]/, "/")
.replace(/^.*?[\\/]api[\\/]/, "/api/")
.replace(/^.*?[\\/]queries[\\/]/, "/api/rpc/")
.replace(/^.*?[\\/]mutations[\\/]/, "/api/rpc/"),
pageExtensions,
)
}
export function createPagesMapping(pagePaths: string[], config: any) {
const {pageExtensions, blitz} = config
const resolverType = blitz?.resolverPath || "queries|mutations"
const previousPages: PagesMapping = {}
const pages = pagePaths.reduce((result: PagesMapping, pagePath): PagesMapping => {
const pages = pagePaths.reduce<PagesMapping>((result, pagePath) => {
let page = `${convertPageFilePathToRoutePath(pagePath, pageExtensions).replace(
/\\/g,
"/",
)}`.replace(/\/index$/, "")
let pageKey = page === "" ? "/" : page
const isResolver = pagePath.includes("/queries/") || pagePath.includes("/mutations/")
if (isResolver) {
if (typeof resolverType === "function") {
page = `/api/rpc${resolverType(pagePath)}`
} else if (resolverType === "root") {
page = `/api/rpc${stripExtension(pagePath, pageExtensions)}`
}
}
let pageKey = page === "" ? "/" : page
if (pageKey in result) {
console.warn(
`Duplicate page detected. ${previousPages[pageKey]} and ${pagePath} both resolve to ${pageKey}.`,
@@ -255,6 +271,7 @@ export function createPagesMapping(pagePaths: string[], pageExtensions: string[]
result[pageKey] = join(PAGES_DIR_ALIAS, pagePath).replace(/\\/g, "/")
return result
}, {})
pages["/_app"] = pages["/_app"] || "next/dist/pages/_app"
pages["/_error"] = pages["/_error"] || "next/dist/pages/_error"
pages["/_document"] = pages["/_document"] || "next/dist/pages/_document"
@@ -277,7 +294,7 @@ function getVerb(type: string) {
const apiPathRegex = /([\\/]api[\\/])/
export async function collectAllRoutes(directory: string, config: any) {
const routeFiles = await collectPages(directory, config.pageExtensions!)
const rawRouteMappings = createPagesMapping(routeFiles, config.pageExtensions!)
const rawRouteMappings = createPagesMapping(routeFiles, config)
const routes = []
for (const [route, filePath] of Object.entries(rawRouteMappings)) {
if (["/_app", "/_document", "/_error"].includes(route)) continue
@@ -515,15 +532,6 @@ export const isInternalBlitzMonorepoDevelopment = __dirname.match(
)
async function findNodeModulesRoot(src: string) {
/*
* Because of our package structure, and because of how things like pnpm link modules,
* we must first find blitz package, and then find `next` and then
* the root of `next`
*
* This is because we import from `.blitz` inside `next/stdlib`.
* If that changes, then this logic here will need to change
*/
let root: string
if (isInternalBlitzMonorepoDevelopment) {
root = join(__dirname, "..", "..", "..", "..", "/node_modules")

View File

@@ -78,7 +78,7 @@ describe("formatZodError", () => {
})
expect(formatZodError(result.error)).toEqual({
students: [undefined, {name: "Required"}, {name: "Expected string, received boolean"}],
data: [undefined, "Expected true, received undefined"],
data: [undefined, "Invalid literal value, expected true"],
})
})
})

View File

@@ -1,5 +1,79 @@
# @blitzjs/codemod
## 2.0.0-alpha.56
### Patch Changes
- Updated dependencies [abb1ad5d]
- Updated dependencies [abe2afcc]
- Updated dependencies [0ac6e171]
- Updated dependencies [8bcb471a]
- blitz@2.0.0-alpha.56
- @blitzjs/generator@2.0.0-alpha.56
## 2.0.0-alpha.55
### Patch Changes
- Updated dependencies [8f166a5d]
- Updated dependencies [54a66a95]
- Updated dependencies [ab4d9de7]
- blitz@2.0.0-alpha.55
- @blitzjs/generator@2.0.0-alpha.55
## 2.0.0-alpha.54
### Patch Changes
- Updated dependencies [f397cc20]
- Updated dependencies [cacb65d6]
- Updated dependencies [348fd6f5]
- Updated dependencies [20fc9f80]
- Updated dependencies [a961aff8]
- Updated dependencies [80e1ead7]
- Updated dependencies [a3bbe6ce]
- Updated dependencies [ffa7b5cc]
- blitz@2.0.0-alpha.54
- @blitzjs/generator@2.0.0-alpha.54
## 2.0.0-alpha.53
### Patch Changes
- @blitzjs/generator@2.0.0-alpha.53
- blitz@2.0.0-alpha.53
## 2.0.0-alpha.52
### Patch Changes
- Updated dependencies [12cb7a72]
- @blitzjs/generator@2.0.0-alpha.52
- blitz@2.0.0-alpha.52
## 2.0.0-alpha.51
### Patch Changes
- 70f9ae49: Handle next/dynamic default import in codemod
- @blitzjs/generator@2.0.0-alpha.51
- blitz@2.0.0-alpha.51
## 2.0.0-alpha.50
### Patch Changes
- Updated dependencies [c11f0401]
- @blitzjs/generator@2.0.0-alpha.50
- blitz@2.0.0-alpha.50
## 2.0.0-alpha.49
### Patch Changes
- @blitzjs/generator@2.0.0-alpha.49
- blitz@2.0.0-alpha.49
## 2.0.0-alpha.48
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/codemod",
"version": "2.0.0-alpha.48",
"version": "2.0.0-alpha.56",
"scripts": {
"build": "unbuild",
"dev": "watch unbuild src --wait=0.2",
@@ -25,9 +25,9 @@
"@babel/plugin-proposal-class-properties": "7.17.12",
"@babel/plugin-syntax-jsx": "7.17.12",
"@babel/plugin-syntax-typescript": "7.17.12",
"@blitzjs/generator": "2.0.0-alpha.48",
"@blitzjs/generator": "2.0.0-alpha.56",
"arg": "5.0.1",
"blitz": "2.0.0-alpha.48",
"blitz": "2.0.0-alpha.56",
"chalk": "^4.1.0",
"cross-spawn": "7.0.3",
"debug": "4.3.3",

View File

@@ -85,8 +85,8 @@ const upgradeLegacy = async () => {
packageJsonPath.dependencies["react"] = "latest"
packageJsonPath.dependencies["react-dom"] = "latest"
packageJsonPath.dependencies["@blitzjs/next"] = "alpha"
packageJsonPath.dependencies["@blitzjs/rpc"] = "latest"
packageJsonPath.dependencies["@blitzjs/auth"] = "latest"
packageJsonPath.dependencies["@blitzjs/rpc"] = "alpha"
packageJsonPath.dependencies["@blitzjs/auth"] = "alpha"
packageJsonPath.dependencies["blitz"] = "alpha"
packageJsonPath.dependencies["next"] = "latest"
packageJsonPath.dependencies["prisma"] = "latest"
@@ -223,6 +223,7 @@ const upgradeLegacy = async () => {
const nextImage = findImport(program, "next/image")
const nextLink = findImport(program, "next/link")
const nextHead = findImport(program, "next/head")
const dynamic = findImport(program, "next/dynamic")
if (nextImage?.length) {
nextImage.remove()
@@ -260,6 +261,18 @@ const upgradeLegacy = async () => {
)
}
if (dynamic?.length) {
dynamic.remove()
program
.get()
.value.program.body.unshift(
j.importDeclaration(
[j.importDefaultSpecifier(j.identifier("dynamic"))],
j.stringLiteral("next/dynamic"),
),
)
}
fs.writeFileSync(path.join(path.resolve(file)), program.toSource())
})
},
@@ -331,7 +344,6 @@ const upgradeLegacy = async () => {
(file) => {
const program = getCollectionFromSource(file)
// BlitzApiHandler -> NextApiHandler
replaceImport(program, "blitz", "BlitzApiHandler", "next", "NextApiHandler")
replaceIdentifiers(program, "BlitzApiHandler", "NextApiHandler")

View File

@@ -224,7 +224,16 @@ export function getAllFiles(
skipDirs?: string[],
allowedExt?: string[],
) {
let currentFiles = fs.readdirSync(dirPath)
let currentFiles: string[] = []
try {
currentFiles = fs.readdirSync(dirPath)
} catch (e: any) {
if (e.code === "ENOENT") {
return []
}
throw e
}
currentFiles.forEach((file) => {
if (fs.statSync(dirPath + "/" + file).isDirectory()) {

View File

@@ -1,5 +1,21 @@
# @blitzjs/config
## 2.0.0-alpha.56
## 2.0.0-alpha.55
## 2.0.0-alpha.54
## 2.0.0-alpha.53
## 2.0.0-alpha.52
## 2.0.0-alpha.51
## 2.0.0-alpha.50
## 2.0.0-alpha.49
## 2.0.0-alpha.48
## 2.0.0-alpha.47

View File

@@ -1,13 +1,13 @@
{
"name": "@blitzjs/config",
"private": true,
"version": "2.0.0-alpha.48",
"version": "2.0.0-alpha.56",
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "5.9.1",
"@typescript-eslint/parser": "5.9.1",
"eslint-config-next": "12.0.7",
"eslint-config-prettier": "8.3.0"
"eslint-config-next": "12.2.0",
"eslint-config-prettier": "8.5.0"
},
"devDependencies": {
"typescript": "^4.5.3"

View File

@@ -1,5 +1,38 @@
# @blitzjs/generator
## 2.0.0-alpha.56
## 2.0.0-alpha.55
### Patch Changes
- ab4d9de7: Don't try to copy RPC API endpoint in templates that don't have it
## 2.0.0-alpha.54
### Patch Changes
- a961aff8: Add missing lint deps to the new app templates
- 80e1ead7: Add jest.config.js to newly generated typescript apps
## 2.0.0-alpha.53
## 2.0.0-alpha.52
### Patch Changes
- 12cb7a72: Upgrade Prisma to v4.0.0
## 2.0.0-alpha.51
## 2.0.0-alpha.50
### Patch Changes
- c11f0401: Update Next.js version and addBasePath location
## 2.0.0-alpha.49
## 2.0.0-alpha.48
## 2.0.0-alpha.47

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/generator",
"version": "2.0.0-alpha.48",
"version": "2.0.0-alpha.56",
"scripts": {
"dev": "watch unbuild src --wait=0.2",
"build": "unbuild && pnpm build:templates",
@@ -45,7 +45,7 @@
"vinyl": "2.2.1"
},
"devDependencies": {
"@blitzjs/config": "2.0.0-alpha.48",
"@blitzjs/config": "2.0.0-alpha.56",
"@juanm04/cpx": "2.0.1",
"@types/babel__core": "7.1.19",
"@types/diff": "5.0.2",

View File

@@ -30,6 +30,7 @@ export interface AppGeneratorOptions extends GeneratorOptions {
form?: "React Final Form" | "React Hook Form" | "Formik"
onPostInstall?: () => Promise<void>
}
type PkgManager = "npm" | "yarn" | "pnpm"
export class AppGenerator extends Generator<AppGeneratorOptions> {
@@ -49,7 +50,7 @@ export class AppGenerator extends Generator<AppGeneratorOptions> {
"types.ts",
]
}
return ["jsconfig.json", "jest.config.js", "package.js.json", "pre-push-js"]
return ["jsconfig.json", "package.js.json", "pre-push-js"]
}
async getTemplateValues() {
@@ -76,10 +77,14 @@ export class AppGenerator extends Generator<AppGeneratorOptions> {
this.destinationPath(this.options.useTs ? "package.ts.json" : "package.js.json"),
this.destinationPath("package.json"),
)
this.fs.move(
this.destinationPath(`pages/api/rpc/blitzrpcroute.${this.options.useTs ? "ts" : "js"}`),
this.destinationPath(`pages/api/rpc/[[...blitz]].${this.options.useTs ? "ts" : "js"}`),
)
const rpcEndpointPath = `pages/api/rpc/blitzrpcroute.${this.options.useTs ? "ts" : "js"}`
if (this.fs.exists(rpcEndpointPath)) {
this.fs.move(
this.destinationPath(rpcEndpointPath),
this.destinationPath(`pages/api/rpc/[[...blitz]].${this.options.useTs ? "ts" : "js"}`),
)
}
if (!this.options.template.skipForms) {
this.updateForms()
@@ -286,6 +291,7 @@ export class AppGenerator extends Generator<AppGeneratorOptions> {
}
commitSpinner.succeed()
}
private updateForms() {
const pkg = this.fs.readJSON(this.destinationPath("package.json")) as
| Record<string, any>

View File

@@ -1,5 +1,3 @@
TODO
[![Blitz.js](https://raw.githubusercontent.com/blitz-js/art/master/github-cover-photo.png)](https://blitzjs.com)
This is a [Blitz.js](https://github.com/blitz-js/blitz) app.

View File

@@ -1,7 +1,8 @@
import Head from "next/head"
import React, { FC } from "react"
import React, {FC} from "react"
import {BlitzLayout} from "@blitzjs/next"
const Layout: FC<{ title?: string; children?: React.ReactNode }> = ({ title, children }) => {
const Layout: BlitzLayout<{title?: string; children?: React.ReactNode}> = ({title, children}) => {
return (
<>
<Head>

View File

@@ -22,16 +22,16 @@
"*.{js}": ["eslint --fix"]
},
"dependencies": {
"@blitzjs/auth": "latest",
"@blitzjs/auth": "alpha",
"@blitzjs/next": "alpha",
"@blitzjs/rpc": "latest",
"@blitzjs/rpc": "alpha",
"@prisma/client": "3.9.0",
"blitz": "alpha",
"next": "12.1.6",
"prisma": "3.9.0",
"next": "12.2.0",
"prisma": "4.0.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"zod": "3.10.1"
"zod": "3.17.3"
},
"devDependencies": {
"@next/bundle-analyzer": "12.0.8",
@@ -40,6 +40,8 @@
"@types/preview-email": "2.0.1",
"@types/react": "18.0.1",
"eslint": "7.32.0",
"eslint-config-next": "12.2.0",
"eslint-config-prettier": "8.5.0",
"husky": "7.0.4",
"jest": "27.5.1",
"lint-staged": "12.1.7",

View File

@@ -22,16 +22,16 @@
"*.{js,ts,tsx}": ["eslint --fix"]
},
"dependencies": {
"@blitzjs/auth": "latest",
"@blitzjs/auth": "alpha",
"@blitzjs/next": "alpha",
"@blitzjs/rpc": "latest",
"@blitzjs/rpc": "alpha",
"@prisma/client": "3.9.0",
"blitz": "alpha",
"next": "12.1.6",
"prisma": "3.9.0",
"next": "12.2.0",
"prisma": "4.0.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"zod": "3.10.1"
"zod": "3.17.3"
},
"devDependencies": {
"@next/bundle-analyzer": "12.0.8",
@@ -39,7 +39,10 @@
"@types/node": "17.0.16",
"@types/preview-email": "2.0.1",
"@types/react": "18.0.1",
"@typescript-eslint/eslint-plugin": "5.30.5",
"eslint": "7.32.0",
"eslint-config-next": "12.2.0",
"eslint-config-prettier": "8.5.0",
"husky": "7.0.4",
"jest": "27.5.1",
"lint-staged": "12.1.7",

View File

@@ -20,7 +20,7 @@
"dependencies": {
"@blitzjs/next": "alpha",
"blitz": "alpha",
"next": "12.1.6",
"next": "12.2.0",
"react": "18.0.0",
"react-dom": "18.0.0",
"ts-node": "10.7.0"
@@ -31,6 +31,8 @@
"@types/node": "17.0.16",
"@types/react": "18.0.1",
"eslint": "7.32.0",
"eslint-config-next": "12.2.0",
"eslint-config-prettier": "8.5.0",
"husky": "7.0.4",
"jest": "27.5.1",
"lint-staged": "12.1.7",

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