1
0
mirror of synced 2026-02-07 21:00:08 -05:00

Compare commits

...

5 Commits

Author SHA1 Message Date
Dillon Raphael
35214bf529 Revert "#3775 Only generate prisma client if it has not been generated (#3780)"
This reverts commit 161270e3b1.
2022-08-23 12:32:38 -04:00
Siddharth Suresh
161270e3b1 #3775 Only generate prisma client if it has not been generated (#3780) 2022-08-23 12:25:10 -04:00
Aleksandra
f6dac093d2 Improve RPC logging: print resolverName() insetad of /resolverName() (#3777)
* Remove  from RPC resolvers logging
2022-08-23 10:49:17 -04:00
Aleksandra
69fb280340 Copy App component properties inside withBlitz (#3778)
* Copy App component properties inside withBlitz
2022-08-23 10:24:28 -04:00
Kai Schlamp
7498aef4fc Replace blitz-env.d.ts with next-env.d.ts (#3773)
Co-authored-by: beerose <alexsandra.sikora@gmail.com>
2022-08-23 13:56:17 +02:00
31 changed files with 470 additions and 28 deletions

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/next": patch
---
Allow setting static page properties (e.g. `getInitialProps`) on the App component

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Fix tsconfig.json referencing blitz-env.d.ts insetad of next-env.d.ts in new app templates

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/rpc": patch
---
Improve RPC logging: print `resolverName()` insetad of `/resolverName()`

6
.gitignore vendored
View File

@@ -48,6 +48,7 @@ tsconfig.tsbuildinfo
.next
dist
.now
# local env files
**/.env.local
**/.env.*.local
@@ -64,7 +65,6 @@ db.sqlite-journal
**/db/db.sqlite
test/integration/**/db.json
test/**/*/out
test/**/blitz-env.d.ts
examples/**/blitz-env.d.ts
test/**/next-env.d.ts
examples/**/next-env.d.ts
.blitz**

View File

@@ -20,5 +20,5 @@
"tsBuildInfoFile": ".tsbuildinfo"
},
"exclude": ["node_modules", "**/*.e2e.ts", "cypress"],
"include": ["blitz-env.d.ts", "**/*.ts", "**/*.tsx", "types"]
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"]
}

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,14 @@
import {BlitzRpcPlugin} from "@blitzjs/rpc"
import {setupBlitzClient} from "@blitzjs/next"
import {AuthClientPlugin} from "@blitzjs/auth"
const {withBlitz} = setupBlitzClient({
plugins: [
AuthClientPlugin({
cookiePrefix: "trailing-slash-tests-cookie-prefix",
}),
BlitzRpcPlugin({}),
],
})
export {withBlitz}

View File

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

View File

@@ -0,0 +1,3 @@
export default async function getBasic() {
return "basic-result"
}

View File

@@ -0,0 +1,8 @@
import {enhancePrisma} from "blitz"
import {PrismaClient} from "@prisma/client"
const EnhancedPrisma = enhancePrisma(PrismaClient)
export * from "@prisma/client"
const prisma = new EnhancedPrisma()
export default prisma

View File

@@ -0,0 +1,47 @@
-- CreateTable
CREATE TABLE "User" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"name" TEXT,
"email" TEXT NOT NULL,
"hashedPassword" TEXT,
"role" TEXT NOT NULL DEFAULT 'user'
);
-- CreateTable
CREATE TABLE "Session" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"expiresAt" DATETIME,
"handle" TEXT NOT NULL,
"userId" INTEGER,
"hashedSessionToken" TEXT,
"antiCSRFToken" TEXT,
"publicData" TEXT,
"privateData" TEXT,
CONSTRAINT "Session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE SET NULL ON UPDATE CASCADE
);
-- CreateTable
CREATE TABLE "Token" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" DATETIME NOT NULL,
"hashedToken" TEXT NOT NULL,
"type" TEXT NOT NULL,
"expiresAt" DATETIME NOT NULL,
"sentTo" TEXT NOT NULL,
"userId" INTEGER NOT NULL,
CONSTRAINT "Token_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User" ("id") ON DELETE RESTRICT ON UPDATE CASCADE
);
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
-- CreateIndex
CREATE UNIQUE INDEX "Session_handle_key" ON "Session"("handle");
-- CreateIndex
CREATE UNIQUE INDEX "Token_hashedToken_type_key" ON "Token"("hashedToken", "type");

View File

@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "sqlite"

View File

@@ -0,0 +1,50 @@
datasource sqlite {
provider = "sqlite"
url = "file:./db.sqlite"
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
name String?
email String @unique
hashedPassword String?
role String @default("user")
sessions Session[]
tokens Token[]
}
model Session {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
expiresAt DateTime?
handle String @unique
user User? @relation(fields: [userId], references: [id])
userId Int?
hashedSessionToken String?
antiCSRFToken String?
publicData String?
privateData String?
}
model Token {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
hashedToken String
type String
expiresAt DateTime
sentTo String
user User @relation(fields: [userId], references: [id])
userId Int
@@unique([hashedToken, type])
}

View File

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

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,4 @@
const {withBlitz} = require("@blitzjs/next")
module.exports = withBlitz({
trailingSlash: true,
})

View File

@@ -0,0 +1,44 @@
{
"name": "test-trailing-slash",
"version": "0.0.0",
"private": true,
"scripts": {
"start:dev": "pnpm run prisma:start && next dev",
"test": "pnpm run prisma:start && vitest run",
"test-watch": "vitest",
"start": "next start",
"lint": "next lint",
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next",
"prisma:start": "prisma generate && prisma migrate deploy",
"prisma:studio": "prisma studio"
},
"prisma": {
"schema": "db/schema.prisma"
},
"dependencies": {
"@blitzjs/auth": "workspace:*",
"@blitzjs/next": "workspace:*",
"@blitzjs/rpc": "workspace:*",
"@prisma/client": "4.0.0",
"blitz": "workspace:*",
"lowdb": "3.0.0",
"next": "12.2.5",
"prisma": "4.0.0",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@blitzjs/config": "workspace:*",
"@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.17",
"b64-lite": "1.4.0",
"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,46 @@
import {ErrorFallbackProps, ErrorComponent, ErrorBoundary, AppProps} from "@blitzjs/next"
import {AuthenticationError, AuthorizationError} from "blitz"
import App, {AppContext} from "next/app"
import React, {Suspense} from "react"
import {withBlitz} from "../app/blitz-client"
function RootErrorFallback({error}: ErrorFallbackProps) {
if (error instanceof AuthenticationError) {
return <div>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, testProp}: AppProps & {testProp: any}) {
return (
<Suspense fallback="Loading...">
<ErrorBoundary FallbackComponent={RootErrorFallback}>
<Component {...pageProps} testProp={testProp} />
</ErrorBoundary>
</Suspense>
)
}
MyApp.getInitialProps = async (context: AppContext) => {
const props = await App.getInitialProps(context)
return {
...props,
testProp: "_app.tsx: testing getInitialProps",
}
}
export default withBlitz(MyApp)

View File

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

View File

@@ -0,0 +1,22 @@
import {NextPage} from "next"
import {Suspense} from "react"
const Page: NextPage = (props) => {
return (
<div id="page">
<Suspense fallback={"Loading..."}>
<div id="content">{JSON.stringify(props, null, 2)}</div>
</Suspense>
</div>
)
}
Page.getInitialProps = async (context) => {
return {
props: {
anotherTestProp: "index.tsx: testing getInitialProps",
},
}
}
export default Page

View File

@@ -0,0 +1,67 @@
import {describe, it, expect, beforeAll, afterAll} from "vitest"
import {killApp, findPort, launchApp, nextBuild, nextStart} from "../../utils/next-test-utils"
import webdriver from "../../utils/next-webdriver"
import {join} from "path"
let app: any
let appPort: number
const appDir = join(__dirname, "../")
const runTests = (mode?: string) => {
describe("getInitialProps", () => {
it(
"should render a custom prop provided in getInitialProps in _app.tsx",
async () => {
const browser = await webdriver(appPort, "/")
await browser.waitForElementByCss("#content", 0)
const text = await browser.elementByCss("#content").text()
expect(text).toMatch(/_app.tsx: testing getInitialProps/)
if (browser) await browser.close()
},
5000 * 60 * 2,
)
it(
"should render custom props provided in getInitialProps in both _app.tsx and index.tsx",
async () => {
const browser = await webdriver(appPort, "/")
await browser.waitForElementByCss("#content", 0)
const text = await browser.elementByCss("#content").text()
expect(text).toMatch(/_app.tsx: testing getInitialProps/)
expect(text).toMatch(/index.tsx: testing getInitialProps/)
if (browser) await browser.close()
},
5000 * 60 * 2,
)
})
}
describe("getInitialProps 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

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

@@ -30,9 +30,10 @@ const buildWithBlitz = <TPlugins extends readonly ClientPlugin<object>[]>(plugin
const providers = plugins.reduce((acc, plugin) => {
return plugin.withProvider ? acc.concat(plugin.withProvider) : acc
}, [] as BlitzProviderType[])
const withPlugins = compose(...providers)
return function withBlitzAppRoot(UserAppRoot: React.ComponentType<any>) {
return function withBlitzAppRoot(UserAppRoot: React.ComponentType<AppProps>) {
const BlitzOuterRoot = (props: AppProps) => {
const component = React.useMemo(() => withPlugins(props.Component), [props.Component])
@@ -52,6 +53,8 @@ const buildWithBlitz = <TPlugins extends readonly ClientPlugin<object>[]>(plugin
</BlitzProvider>
)
}
Object.assign(BlitzOuterRoot, UserAppRoot)
return withSuperJSONPage(BlitzOuterRoot)
}
}
@@ -145,10 +148,9 @@ const setupBlitzClient = <TPlugins extends readonly ClientPlugin<object>[]>({
// todo: finish this
// Used to build BlitzPage type
const types = {} as {plugins: typeof plugins}
// const types = {} as {plugins: typeof plugins}
return {
types,
withBlitz,
...(exports as PluginsExports<TPlugins>),
}

View File

@@ -158,7 +158,7 @@ export function rpcHandler(config: RpcConfig) {
const routePath = "/" + relativeRoutePath
const log = baseLogger().getChildLogger({
prefix: [routePath.replace("/api/rpc/", "") + "()"],
prefix: [routePath.replace(/(\/api\/rpc)?\//, "") + "()"],
})
const customChalk = new chalk.Instance({
level: log.settings.type === "json" ? 0 : chalk.level,

View File

@@ -43,7 +43,7 @@ export class AppGenerator extends Generator<AppGeneratorOptions> {
if (!this.options.useTs) {
return [
"tsconfig.json",
"blitz-env.d.ts",
"next-env.d.ts",
"jest.config.ts",
"package.ts.json",
"pre-push-ts",

View File

@@ -20,5 +20,5 @@
"tsBuildInfoFile": ".tsbuildinfo"
},
"exclude": ["node_modules", "**/*.e2e.ts", "cypress"],
"include": ["blitz-env.d.ts", "**/*.ts", "**/*.tsx", "types"]
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"]
}

View File

@@ -20,5 +20,5 @@
"tsBuildInfoFile": ".tsbuildinfo"
},
"exclude": ["node_modules", "**/*.e2e.ts", "cypress"],
"include": ["blitz-env.d.ts", "**/*.ts", "**/*.tsx"]
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

87
pnpm-lock.yaml generated
View File

@@ -49,7 +49,7 @@ importers:
"@types/preview-email": 2.0.1
"@types/react": 18.0.17
"@typescript-eslint/eslint-plugin": 5.9.1
blitz: workspace:2.0.0-beta.2
blitz: workspace:2.0.0-beta.3
eslint: 7.32.0
eslint-config-next: 12.2.0
eslint-config-prettier: 8.5.0
@@ -196,6 +196,55 @@ importers:
node-fetch: 3.2.3
typescript: 4.6.3
integration-tests/get-initial-props:
specifiers:
"@blitzjs/auth": workspace:*
"@blitzjs/config": workspace:*
"@blitzjs/next": workspace:*
"@blitzjs/rpc": workspace:*
"@next/bundle-analyzer": 12.0.8
"@prisma/client": 4.0.0
"@types/express": 4.17.13
"@types/fs-extra": 9.0.13
"@types/node-fetch": 2.6.1
"@types/react": 18.0.17
b64-lite: 1.4.0
blitz: workspace:*
eslint: 7.32.0
fs-extra: 10.0.1
get-port: 6.1.2
lowdb: 3.0.0
next: 12.2.5
node-fetch: 3.2.3
prisma: 4.0.0
react: 18.2.0
react-dom: 18.2.0
typescript: ^4.5.3
dependencies:
"@blitzjs/auth": link:../../packages/blitz-auth
"@blitzjs/next": link:../../packages/blitz-next
"@blitzjs/rpc": link:../../packages/blitz-rpc
"@prisma/client": 4.0.0_prisma@4.0.0
blitz: link:../../packages/blitz
lowdb: 3.0.0
next: 12.2.5_biqbaboplfbrettd7655fr4n2y
prisma: 4.0.0
react: 18.2.0
react-dom: 18.2.0_react@18.2.0
devDependencies:
"@blitzjs/config": link:../../packages/config
"@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.17
b64-lite: 1.4.0
eslint: 7.32.0
fs-extra: 10.0.1
get-port: 6.1.2
node-fetch: 3.2.3
typescript: 4.7.4
integration-tests/middleware:
specifiers:
"@blitzjs/config": workspace:*
@@ -524,8 +573,8 @@ importers:
packages/blitz:
specifiers:
"@blitzjs/config": workspace:2.0.0-beta.2
"@blitzjs/generator": 2.0.0-beta.2
"@blitzjs/config": workspace:2.0.0-beta.3
"@blitzjs/generator": 2.0.0-beta.3
"@types/cookie": 0.4.1
"@types/cross-spawn": 6.0.2
"@types/debug": 4.1.7
@@ -635,7 +684,7 @@ importers:
packages/blitz-auth:
specifiers:
"@blitzjs/config": workspace:2.0.0-beta.2
"@blitzjs/config": workspace:2.0.0-beta.3
"@testing-library/react": 13.0.0
"@testing-library/react-hooks": 7.0.2
"@types/b64-lite": 1.3.0
@@ -649,7 +698,7 @@ importers:
"@types/secure-password": 3.1.1
b64-lite: 1.4.0
bad-behavior: 1.0.1
blitz: 2.0.0-beta.2
blitz: 2.0.0-beta.3
cookie: 0.4.1
cookie-session: 2.0.0
debug: 4.3.3
@@ -702,8 +751,8 @@ importers:
packages/blitz-next:
specifiers:
"@blitzjs/config": workspace:2.0.0-beta.2
"@blitzjs/rpc": 2.0.0-beta.2
"@blitzjs/config": workspace:2.0.0-beta.3
"@blitzjs/rpc": 2.0.0-beta.3
"@tanstack/react-query": 4.0.10
"@testing-library/dom": 8.13.0
"@testing-library/jest-dom": 5.16.3
@@ -715,7 +764,7 @@ importers:
"@types/react": 18.0.17
"@types/react-dom": 17.0.14
"@types/testing-library__react-hooks": 4.0.0
blitz: 2.0.0-beta.2
blitz: 2.0.0-beta.3
cross-spawn: 7.0.3
debug: 4.3.3
find-up: 4.1.0
@@ -765,15 +814,15 @@ importers:
packages/blitz-rpc:
specifiers:
"@blitzjs/auth": 2.0.0-beta.2
"@blitzjs/config": workspace:2.0.0-beta.2
"@blitzjs/auth": 2.0.0-beta.3
"@blitzjs/config": workspace:2.0.0-beta.3
"@tanstack/react-query": 4.0.10
"@types/debug": 4.1.7
"@types/react": 18.0.17
"@types/react-dom": 17.0.14
b64-lite: 1.4.0
bad-behavior: 1.0.1
blitz: 2.0.0-beta.2
blitz: 2.0.0-beta.3
chalk: ^4.1.0
debug: 4.3.3
next: 12.2.5
@@ -816,12 +865,12 @@ importers:
"@babel/plugin-syntax-typescript": 7.17.12
"@babel/preset-env": 7.12.10
"@blitzjs/config": workspace:*
"@blitzjs/generator": 2.0.0-beta.2
"@blitzjs/generator": 2.0.0-beta.3
"@types/jscodeshift": 0.11.2
"@types/node": 17.0.16
arg: 5.0.1
ast-types: 0.14.2
blitz: 2.0.0-beta.2
blitz: 2.0.0-beta.3
chalk: ^4.1.0
cross-spawn: 7.0.3
debug: 4.3.3
@@ -876,7 +925,7 @@ importers:
"@babel/plugin-transform-typescript": 7.12.1
"@babel/preset-env": 7.12.10
"@babel/types": 7.12.10
"@blitzjs/config": 2.0.0-beta.2
"@blitzjs/config": 2.0.0-beta.3
"@juanm04/cpx": 2.0.1
"@mrleebo/prisma-ast": 0.2.6
"@types/babel__core": 7.1.19
@@ -969,7 +1018,7 @@ importers:
packages/pkg-template:
specifiers:
"@blitzjs/config": 2.0.0-beta.2
"@blitzjs/config": 2.0.0-beta.3
"@types/react": 18.0.17
"@types/react-dom": 17.0.14
"@typescript-eslint/eslint-plugin": 5.9.1
@@ -3109,6 +3158,7 @@ packages:
semver: 5.7.1
transitivePeerDependencies:
- supports-color
dev: false
/@babel/preset-flow/7.17.12_@babel+core@7.18.2:
resolution:
@@ -5539,6 +5589,7 @@ packages:
typescript: 4.6.3
transitivePeerDependencies:
- supports-color
dev: false
/@typescript-eslint/experimental-utils/5.28.0_hrkuebk64jiu2ut2d2sm4oylnu:
resolution:
@@ -9365,6 +9416,7 @@ packages:
transitivePeerDependencies:
- eslint-import-resolver-webpack
- supports-color
dev: false
/eslint-config-next/12.2.5_hrkuebk64jiu2ut2d2sm4oylnu:
resolution:
@@ -9402,6 +9454,7 @@ packages:
hasBin: true
peerDependencies:
eslint: ">=7.0.0"
dev: false
/eslint-config-prettier/8.5.0_eslint@7.32.0:
resolution:
@@ -12066,7 +12119,7 @@ packages:
pretty-format: 27.5.1
slash: 3.0.0
strip-json-comments: 3.1.1
ts-node: 10.7.0_fxg3r7oju3tntkxsvleuiot4fa
ts-node: 10.7.0_typescript@4.6.3
transitivePeerDependencies:
- bufferutil
- canvas
@@ -17340,6 +17393,7 @@ packages:
typescript: 4.6.3
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
dev: false
/ts-node/10.7.0_typescript@4.6.3:
resolution:
@@ -17372,7 +17426,6 @@ packages:
typescript: 4.6.3
v8-compile-cache-lib: 3.0.1
yn: 3.1.1
dev: false
/tsconfig-paths/3.14.1:
resolution: