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

Compare commits

...

19 Commits

Author SHA1 Message Date
Brandon Bayer
d953ef795a v0.22.1 2020-09-12 14:03:09 -04:00
Brandon Bayer
7fcb0945a2 Fix bug in default _app.tsx where Links inside ErrorBoundary don't work (#1054)
(patch)
2020-09-12 13:54:49 -04:00
Brandon Bayer
ab4670c21b v0.22.0 2020-09-11 17:48:30 -04:00
Brandon Bayer
1ae7bf77b2 Tiny tweak to Layout component in new apps (#1051)
(minor)
2020-09-11 17:46:35 -04:00
Brandon Bayer
63e3fe1ccb Add link to signup page to login form for new apps (#1050)
(minor)
2020-09-11 17:03:14 -04:00
Jirka Svoboda
280a2b5c4f refactor(server): Added isTypescript explicit flag, config refactored (#1014)
Co-authored-by: Rudi Yardley <contact@rudiyardley.com> (meta)
2020-09-11 11:16:45 -04:00
Brandon Bayer
bf2734d907 v0.21.2-canary.2 2020-09-11 11:10:32 -04:00
Sigurd Moland Wahl
07341c14d3 Fix bug where test files would cause blitz build to fail (#1045)
(patch)
2020-09-11 11:07:46 -04:00
allcontributors[bot]
e150b67cf4 docs: add PixelsCommander as a contributor (#1048)
Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> (meta)
2020-09-11 11:04:47 -04:00
Denis Radin
1a1722168c Add secureProxy option the the Passport.js adapter (#1033)
(minor)
2020-09-11 11:04:33 -04:00
dependabot[bot]
7f266b0c98 Bump node-fetch from 2.6.0 to 2.6.1 in /packages/generator (#1042)
Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
- [Release notes](https://github.com/bitinn/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (meta)
2020-09-11 09:35:50 -04:00
engelkes-finstreet
6e92a2dfde Update dependencies in new app template (#1036)
(patch)
2020-09-10 22:17:43 -04:00
Ante Primorac
66cd1ec650 Fix: export AppProps as a generic type (#1034)
(patch)
2020-09-10 22:16:51 -04:00
allcontributors[bot]
7c4916324e docs: add engelkes-finstreet as a contributor (#1041)
Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> (meta)
2020-09-10 22:12:32 -04:00
engelkes-finstreet
d747e34853 Add ability to set custom authenticateOptions for the Passport.js adapter (#1024)
(minor)
2020-09-10 22:10:37 -04:00
Brandon Bayer
3afab440c8 Add @sirmyron as a contributor 2020-09-10 22:05:04 -04:00
allcontributors[bot]
e576e6332c docs: add nitaking as a contributor (#1040)
Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> (meta)
2020-09-10 22:03:49 -04:00
Satoshi Nitawaki
60d0c9d0bf Enable passing extra prisma args to blitz db migrate(#1012)
(minor)
2020-09-10 22:03:34 -04:00
Brandon Bayer
8f800d388b Fix UnhandledPromiseRejectionWarning from useQuery during static pre-rendering (#1038)
(patch)
2020-09-10 09:59:38 -04:00
51 changed files with 509 additions and 258 deletions

View File

@@ -990,6 +990,45 @@
"contributions": [
"doc"
]
},
{
"login": "nitaking",
"name": "Satoshi Nitawaki",
"avatar_url": "https://avatars2.githubusercontent.com/u/10850034?v=4",
"profile": "https://twitter.com/nitaking_",
"contributions": [
"code"
]
},
{
"login": "sirmyron",
"name": "sirmyron",
"avatar_url": "https://avatars2.githubusercontent.com/u/1430136?v=4",
"profile": "https://github.com/sirmyron",
"contributions": [
"doc"
]
},
{
"login": "engelkes-finstreet",
"name": "engelkes-finstreet",
"avatar_url": "https://avatars1.githubusercontent.com/u/36962022?v=4",
"profile": "https://github.com/engelkes-finstreet",
"contributions": [
"code",
"doc"
]
},
{
"login": "PixelsCommander",
"name": "Denis Radin",
"avatar_url": "https://avatars2.githubusercontent.com/u/810671?v=4",
"profile": "http://twitter.com/pixelscommander",
"contributions": [
"review",
"code",
"doc"
]
}
],
"contributorsPerLine": 7,

View File

@@ -6,7 +6,7 @@
<img alt="" src="https://img.shields.io/badge/Join%20our%20community-6700EB.svg?style=for-the-badge&labelColor=000000&logoWidth=20&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAQ9SURBVHgB7d3dVdtAEIbhcSpICUoH0IEogQqSVBBSAU4FSSpIOoAORAfQgSghHXzZ1U/YcMD4R9rZmf2ec3y448LyiNf27iLiGIAmPLrweC9Un3DhrzG6EarLNP09nlwJ1SOZ/lQr5N80/S/p2QMVCBf5N17XCfm1Y/rBHqjAG9PPHvBsz+mf9WAP+HLA9M/YA14cOP2payH7jpj+VCtk1wnTP+vj7xCy6cTpn7EHLMLp059iD1iD8eveJbVCNsSLheX1YA/YgOWnf8YeKB3Wmf7Ud6Fy4f/FHmtpxbl3YlC4MJ/Cj0bWdwPnPbARg+L0S54XQHS32WwuxClzd4CM0z9rPfeAuTtA5ulPXYQ7wZ04Y+oOoDD9KZc9YOoOoDj9s4dwFzgXR6w1wIPoOvPWA9buAHEJ173o3gWiy3AnuBUHLEbgmYwvAk1/wuM8vAgexThzbwPDkx7/DHwVXfFOxP2GmsKd4Ab6zPeAyU8CI7AHFmH2BRCBPXAyk18GzUrqAXCTiR4ssyj0VFw/oCU8+e+RZ33AWz6KMaYbIIWxB+JSLs1bsbkeMN0AqakHvoku9oA2sAfqBvbAQdw0QArsgb25aYBUQT3QgT2gB+yBuqGcHij2UCqXDZACe2Anlw2QYg/QAOyBuoE98CL3DZDCuK4/rh/Q7oGL6U+TOvcNkJoijN8X1C48+T+g75eQDrAH/qmqAVJgDwyqaoAUe4AGYA/UDZX3QLUNkEIZPRCd5+6BahsgVUgPROwBTSijB7jpVAvGHriHvmw9wAZ4BpX1ABvgmakHtPcbRuwBTWAPULgAV9D/jKDY9YRvwvgEaurD44uQHvAol7qBW7WKluVtIHiUS7GyvA0s6CiXDnxrpQfsgbqBS7GKk/2jYHCrVlGyfxTMrVo0ALdq1Q3sgSKofh0M9oA61a+D2QM0AHugbmAPqClmSRjK2apVVQ8UsySsoK1aHdgDesCtWnUDeyCrIpeFg1u3sylyWTi3btMA7IG6gT2wuuK3hoE9sKrit4YVslWLPaAN7IG6ocKt2zmY2h4O9sDiTG0PZw/QANy6XTewBxZj9ogYVHy025LMHhEz9cBn0We6B0yfERReBLfhx0/R1YQHPx/QBPbA0VwcEwf2wNFcHBPHHjiem3MC2QPHcXdSaJjA+KfgTPQ8hhfjBzHC40mhlzJ+Xq9lK4a4PCs43AVaGTed5mZq+iOXZwWHi3AnOj2wFWNcnxYe7gTxLtBKHuamP/J+Wnh8a5irB7ZC5Yk9gPX1QuXC+usHWqGyhYvUYR0a7zboUOFCNVhnk0krZAOW7wFOvzXhom2xnEbIHizTA1wEYhWW6YFGyC6c1gOcfg9wfA80Qj7g8B7g9HuCww+haIR8wf49wOn3Cvv9k8tGyC/s7gFOv3fY3QONkH+v9MBWqB7PeqDn9FcIT//kcitUn6kHOu/T/xfWzlQy3dEHhwAAAABJRU5ErkJggg==">
</a>
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<a aria-label="All Contributors" href="#contributors-"><img alt="" src="https://img.shields.io/badge/all_contributors-103-17BB8A.svg?style=for-the-badge&labelColor=000000"></a>
<a aria-label="All Contributors" href="#contributors-"><img alt="" src="https://img.shields.io/badge/all_contributors-107-17BB8A.svg?style=for-the-badge&labelColor=000000"></a>
<!-- ALL-CONTRIBUTORS-BADGE:END -->
<a aria-label="License" href="https://github.com/blitz-js/blitz/blob/canary/LICENSE">
<img alt="" src="https://img.shields.io/npm/l/blitz.svg?style=for-the-badge&labelColor=000000&color=blue">
@@ -336,12 +336,17 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<td align="center"><a href="https://twitter.com/dillonraphael"><img src="https://avatars0.githubusercontent.com/u/3496193?v=4" width="100px;" alt=""/><br /><sub><b>Dillon Raphael</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=dillonraphael" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/clgeoio"><img src="https://avatars2.githubusercontent.com/u/37571416?v=4" width="100px;" alt=""/><br /><sub><b>Cody G</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=clgeoio" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/madflow"><img src="https://avatars0.githubusercontent.com/u/183248?v=4" width="100px;" alt=""/><br /><sub><b>madflow</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=madflow" title="Documentation">📖</a></td>
<td align="center"><a href="https://twitter.com/nitaking_"><img src="https://avatars2.githubusercontent.com/u/10850034?v=4" width="100px;" alt=""/><br /><sub><b>Satoshi Nitawaki</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=nitaking" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/sirmyron"><img src="https://avatars2.githubusercontent.com/u/1430136?v=4" width="100px;" alt=""/><br /><sub><b>sirmyron</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=sirmyron" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/engelkes-finstreet"><img src="https://avatars1.githubusercontent.com/u/36962022?v=4" width="100px;" alt=""/><br /><sub><b>engelkes-finstreet</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=engelkes-finstreet" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=engelkes-finstreet" title="Documentation">📖</a></td>
<td align="center"><a href="http://twitter.com/pixelscommander"><img src="https://avatars2.githubusercontent.com/u/810671?v=4" width="100px;" alt=""/><br /><sub><b>Denis Radin</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/pulls?q=is%3Apr+reviewed-by%3APixelsCommander" title="Reviewed Pull Requests">👀</a> <a href="https://github.com/blitz-js/blitz/commits?author=PixelsCommander" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=PixelsCommander" title="Documentation">📖</a></td>
</tr>
</table>
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

View File

@@ -2,6 +2,7 @@ import {passportAuth} from "blitz"
import db from "db"
import {Strategy as TwitterStrategy} from "passport-twitter"
import {Strategy as GitHubStrategy} from "passport-github2"
import {Strategy as Auth0Strategy} from "passport-auth0"
function assert(condition: any, message: string): asserts condition {
if (!condition) throw new Error(message)
@@ -16,8 +17,13 @@ assert(
assert(process.env.GITHUB_CLIENT_ID, "You must provide the GITHUB_CLIENT_ID env variable")
assert(process.env.GITHUB_CLIENT_SECRET, "You must provide the GITHUB_CLIENT_SECRET env variable")
assert(process.env.AUTH0_DOMAIN, "You must provide the AUTH0_DOMAIN env variable")
assert(process.env.AUTH0_CLIENT_ID, "You must provide the AUTH0_CLIENT_ID env variable")
assert(process.env.AUTH0_CLIENT_SECRET, "You must provide the AUTH0_CLIENT_SECRET env variable")
export default passportAuth({
successRedirectUrl: "/",
authenticateOptions: {scope: "openid email profile"}, //used for Auth0Strategy - without an empty profile is returned
strategies: [
new TwitterStrategy(
{
@@ -85,5 +91,41 @@ export default passportAuth({
done(null, {publicData})
},
),
new Auth0Strategy(
{
domain: process.env.AUTH0_DOMAIN,
clientID: process.env.AUTH0_CLIENT_ID,
clientSecret: process.env.AUTH0_CLIENT_SECRET,
callbackURL:
process.env.NODE_ENV === "production"
? "https://auth-example-flybayer.blitzjs.vercel.app/api/auth/auth0/callback"
: "http://localhost:3000/api/auth/auth0/callback",
},
async function (_token, _tokenSecret, extraParams, profile, done) {
const email = profile.emails && profile.emails[0]?.value
if (!email) {
// This can happen if you haven't enabled email access in your twitter app permissions
return done(new Error("GitHub OAuth response doesn't have email."))
}
const user = await db.user.upsert({
where: {email},
create: {
email,
name: profile.displayName,
},
update: {email},
})
const publicData = {
userId: user.id,
roles: [user.role],
source: "auth0",
githubUsername: profile.username,
}
done(undefined, {publicData})
},
),
],
})

View File

@@ -1,4 +1,5 @@
import React from "react"
import {Link} from "blitz"
import {LabeledTextField} from "app/components/LabeledTextField"
import {Form, FORM_ERROR} from "app/components/Form"
import login from "app/auth/mutations/login"
@@ -12,7 +13,6 @@ export const LoginForm = (props: LoginFormProps) => {
return (
<div>
<h1>Login</h1>
<Form<LoginInputType>
submitText="Log In"
schema={LoginInput}
@@ -36,6 +36,9 @@ export const LoginForm = (props: LoginFormProps) => {
<LabeledTextField name="email" label="Email" placeholder="Email" />
<LabeledTextField name="password" label="Password" placeholder="Password" type="password" />
</Form>
<div style={{marginTop: "1rem"}}>
Or <Link href="/signup">Sign Up</Link>
</div>
</div>
)
}

View File

@@ -1,12 +1,14 @@
import {AppProps, ErrorComponent} from "blitz"
import {AppProps, ErrorComponent, useRouter} from "blitz"
import {ErrorBoundary} from "react-error-boundary"
import {queryCache} from "react-query"
import LoginForm from "app/auth/components/LoginForm"
export default function App({Component, pageProps}: AppProps) {
const router = useRouter()
return (
<ErrorBoundary
FallbackComponent={RootErrorFallback}
resetKeys={[router.asPath]}
onReset={() => {
// This ensures the Blitz useQuery hooks will automatically refetch
// data any time you reset the error boundary

View File

@@ -15,7 +15,7 @@ export default async function getUsers(
{where, orderBy, cursor, take, skip}: GetUsersInput,
ctx: {session?: SessionContext} = {},
) {
ctx.session?.authorize(["admin"])
ctx.session!.authorize(["admin"])
const users = await db.user.findMany({
where,

View File

@@ -1,6 +1,6 @@
{
"name": "@examples/auth",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"scripts": {
"start": "blitz start",
"studio": "blitz db studio",
@@ -35,8 +35,9 @@
"dependencies": {
"@prisma/cli": "2.4.1",
"@prisma/client": "2.4.1",
"blitz": "0.21.2-canary.1",
"blitz": "0.22.1",
"final-form": "4.20.1",
"passport-auth0": "1.3.3",
"passport-github2": "0.1.11",
"passport-twitter": "1.0.4",
"react": "0.0.0-experimental-7f28234f8",
@@ -49,6 +50,7 @@
"devDependencies": {
"@cypress/skip-test": "2.5.0",
"@next/bundle-analyzer": "latest",
"@types/passport-auth0": "1.0.4",
"@types/passport-github2": "1.2.4",
"@types/passport-twitter": "1.0.36",
"@types/react": "16.9.38",

View File

@@ -1,6 +1,6 @@
{
"name": "no-prisma",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"scripts": {
"start": "blitz start",
"build": "blitz build",
@@ -26,7 +26,7 @@
]
},
"dependencies": {
"blitz": "0.21.2-canary.1",
"blitz": "0.22.1",
"knex": "0.21.2",
"react": "0.0.0-experimental-7f28234f8",
"react-dom": "0.0.0-experimental-7f28234f8",

View File

@@ -1,6 +1,6 @@
{
"name": "@examples/plain-js",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"scripts": {
"start": "blitz start",
"build": "blitz db migrate && blitz build",
@@ -31,7 +31,7 @@
"dependencies": {
"@prisma/cli": "2.4.1",
"@prisma/client": "2.4.1",
"blitz": "0.21.2-canary.1",
"blitz": "0.22.1",
"react": "0.0.0-experimental-7f28234f8",
"react-dom": "0.0.0-experimental-7f28234f8"
},

View File

@@ -1,6 +1,6 @@
{
"name": "@examples/store",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"private": true,
"scripts": {
"build": "blitz db migrate && blitz build",
@@ -18,7 +18,7 @@
"dependencies": {
"@prisma/cli": "2.4.1",
"@prisma/client": "2.4.1",
"blitz": "0.21.2-canary.1",
"blitz": "0.22.1",
"final-form": "4.19.1",
"react": "0.0.0-experimental-7f28234f8",
"react-dom": "0.0.0-experimental-7f28234f8",

View File

@@ -1,6 +1,6 @@
{
"name": "tailwind",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"scripts": {
"build": "blitz db migrate && blitz build",
"lint": "eslint --ignore-path .gitignore --ext .js,.ts,.tsx .",
@@ -30,7 +30,7 @@
"dependencies": {
"@prisma/cli": "2.4.1",
"@prisma/client": "2.4.1",
"blitz": "0.21.2-canary.1",
"blitz": "0.22.1",
"react": "0.0.0-experimental-7f28234f8",
"react-dom": "0.0.0-experimental-7f28234f8",
"typescript": "3.8.3"

View File

@@ -1,5 +1,5 @@
{
"version": "0.21.2-canary.1",
"version": "0.22.1",
"packages": ["packages/*"],
"npmClient": "yarn",
"useWorkspaces": true,

View File

@@ -1,7 +1,7 @@
{
"name": "blitz",
"description": "Blitz is a Rails-like framework for monolithic, full-stack React apps — built on Next.js",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"license": "MIT",
"scripts": {
"clean": "rimraf dist",
@@ -39,11 +39,11 @@
"url": "https://github.com/blitz-js/blitz"
},
"dependencies": {
"@blitzjs/cli": "0.21.2-canary.1",
"@blitzjs/core": "0.21.2-canary.1",
"@blitzjs/generator": "0.21.2-canary.1",
"@blitzjs/installer": "0.21.2-canary.1",
"@blitzjs/server": "0.21.2-canary.1",
"@blitzjs/cli": "0.22.1",
"@blitzjs/core": "0.22.1",
"@blitzjs/generator": "0.22.1",
"@blitzjs/installer": "0.22.1",
"@blitzjs/server": "0.22.1",
"envinfo": "7.7.2",
"os-name": "3.1.0",
"pkg-dir": "4.2.0",

View File

@@ -1,7 +1,7 @@
{
"name": "@blitzjs/cli",
"description": "Blitz.js CLI",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"license": "MIT",
"scripts": {
"b": "./bin/run",
@@ -30,8 +30,8 @@
"/lib"
],
"dependencies": {
"@blitzjs/display": "0.21.2-canary.1",
"@blitzjs/repl": "0.21.2-canary.1",
"@blitzjs/display": "0.22.1",
"@blitzjs/repl": "0.22.1",
"@oclif/command": "1.5.20",
"@oclif/config": "1.15.1",
"@oclif/plugin-autocomplete": "0.2.0",
@@ -57,9 +57,9 @@
"tsconfig-paths": "3.9.0"
},
"devDependencies": {
"@blitzjs/generator": "0.21.2-canary.1",
"@blitzjs/installer": "0.21.2-canary.1",
"@blitzjs/server": "0.21.2-canary.1",
"@blitzjs/generator": "0.22.1",
"@blitzjs/installer": "0.22.1",
"@blitzjs/server": "0.22.1",
"@oclif/dev-cli": "1.22.2",
"@oclif/test": "1.2.5",
"@prisma/cli": "2.4.1",

View File

@@ -69,16 +69,17 @@ const runMigrateUp = async ({silent = false} = {}) => {
return runPrismaGeneration({silent})
}
export const runMigrate = async (name?: string) => {
export const runMigrate = async (flags: object = {}) => {
if (process.env.NODE_ENV === "production") {
return runMigrateUp()
}
// @ts-ignore escape:TS7053
const nestedFlags = Object.keys(flags).map(key => [`--${key}`, flags[key]])
const options = ([] as string[]).concat(...nestedFlags)
const silent = Boolean(name)
const args = ["migrate", "save", schemaArg, "--create-db", "--experimental"]
if (name) {
args.push("--name", name)
}
const silent = options.includes('name')
const args = ["migrate", "save", schemaArg, "--create-db", "--experimental", ...options]
const success = await runPrisma(args, silent)
@@ -184,6 +185,8 @@ ${chalk.bold("reset")} Reset the database and run a fresh migration via Prisma
name: flags.string({hidden: true}),
}
static strict = false
async run() {
const {args, flags} = this.parse(Db)
const command = args["command"]
@@ -194,9 +197,9 @@ ${chalk.bold("reset")} Reset the database and run a fresh migration via Prisma
if (command === "migrate" || command === "m") {
try {
return await runMigrate(flags.name)
return await runMigrate(flags)
} catch (error) {
if (flags.name) {
if (Object.keys(flags).length > 0) {
throw error
} else {
process.exit(1)

View File

@@ -1,13 +1,7 @@
import {dev, prod} from "@blitzjs/server"
import {Command, flags} from "@oclif/command"
import fs from "fs"
import path from "path"
import pkgDir from "pkg-dir"
import {runPrismaGeneration} from "./db"
const projectRoot = pkgDir.sync() || process.cwd()
const isTypescript = fs.existsSync(path.join(projectRoot, "tsconfig.json"))
export class Start extends Command {
static description = "Start a development server"
static aliases = ["s"]
@@ -27,14 +21,12 @@ export class Start extends Command {
}
async run() {
const {flags} = this.parse(Start)
const config = {
rootFolder: process.cwd(),
port: flags.port,
hostname: flags.hostname,
isTypescript,
}
try {

View File

@@ -17,6 +17,7 @@ let migrateSaveParams: any[]
let migrateUpDevParams: any[]
let migrateUpProdParams: any[]
let migrateSaveWithNameParams: any[]
let migrateSaveWithUnknownParams: any[]
beforeAll(async () => {
schemaArg = `--schema=${path.join(process.cwd(), "db", "schema.prisma")}`
prismaBin = await resolveBinAsync("@prisma/cli", "prisma")
@@ -41,6 +42,11 @@ beforeAll(async () => {
["migrate", "save", schemaArg, "--create-db", "--experimental", "--name", "name"],
{stdio: "ignore", env: process.env},
]
migrateSaveWithUnknownParams = [
prismaBin,
["migrate", "save", schemaArg, "--create-db", "--experimental"],
{stdio: "inherit", env: process.env},
]
})
describe("Db command", () => {
@@ -76,6 +82,13 @@ describe("Db command", () => {
expect(onSpy).toHaveBeenCalledTimes(3)
}
function expectDbMigrateWithUnknownFlag() {
expect(spawn).toBeCalledWith(...migrateSaveWithUnknownParams)
expect(spawn).toHaveBeenCalledTimes(3)
expect(onSpy).toHaveBeenCalledTimes(3)
}
it("runs db help when no command given", async () => {
// When running the help command oclif exits with code 0
// Unfortantely it treats this as an exception and throws accordingly
@@ -137,6 +150,18 @@ describe("Db command", () => {
expectProductionDbMigrateOutcome()
})
it("runs db migrate silently with the right args when name flag is used", async () => {
await Db.run(["migrate", "--name", "name"])
expectDbMigrateWithNameOutcome()
})
it("runs db migrate. (with unknown flags)", async () => {
await Db.run(["migrate", "--hoge", 'aaa'])
expectDbMigrateWithUnknownFlag()
})
it("runs db introspect", async () => {
await Db.run(["introspect"])
@@ -164,10 +189,4 @@ describe("Db command", () => {
expect(spawn.mock.calls.length).toBe(0)
})
it("runs db migrate silently with the right args when name flag is used", async () => {
await Db.run(["migrate", "--name", "name"])
expectDbMigrateWithNameOutcome()
})
})

View File

@@ -7,7 +7,7 @@
"config"
],
"author": "Fran Zekan <zekan.fran369@gmail.com>",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"license": "MIT",
"scripts": {
"clean": "rimraf dist",

View File

@@ -1,7 +1,7 @@
{
"name": "@blitzjs/core",
"description": "Blitz.js core functionality",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"license": "MIT",
"scripts": {
"clean": "rimraf dist",
@@ -40,8 +40,8 @@
"url": "https://github.com/blitz-js/blitz"
},
"dependencies": {
"@blitzjs/config": "0.21.2-canary.1",
"@blitzjs/display": "0.21.2-canary.1",
"@blitzjs/config": "0.22.1",
"@blitzjs/display": "0.22.1",
"bad-behavior": "1.0.1",
"cookie-session": "1.4.0",
"deepmerge": "4.2.2",

View File

@@ -1,4 +1,4 @@
import {NextPage, NextComponentType} from "next"
import {NextPage, NextComponentType, NextPageContext} from "next"
import {AppProps as NextAppProps} from "next/app"
export * from "./use-query"
@@ -49,10 +49,10 @@ export {default as dynamic} from "next/dynamic"
export {default as ErrorComponent} from "next/error"
export type BlitzComponentType = NextComponentType
export type BlitzComponentType<C = NextPageContext, IP = {}, P = {}> = NextComponentType<C, IP, P>
export interface AppProps extends NextAppProps {
Component: BlitzComponentType & {
export interface AppProps<P = {}> extends NextAppProps<P> {
Component: BlitzComponentType<NextPageContext, any, P> & {
getLayout?: (component: JSX.Element) => JSX.Element
}
}

View File

@@ -4,7 +4,9 @@ import {EnhancedResolverModule} from "./rpc"
import {getConfig} from "@blitzjs/config"
import {log} from "@blitzjs/display"
export interface MiddlewareRequest extends BlitzApiRequest {}
export interface MiddlewareRequest extends BlitzApiRequest {
protocol?: string
}
export interface MiddlewareResponse extends BlitzApiResponse {
/**
* This will be passed as the second argument to Blitz queries/mutations.

View File

@@ -1,4 +1,4 @@
import {BlitzApiRequest, BlitzApiResponse} from "."
import {BlitzApiRequest, BlitzApiResponse, ConnectMiddleware} from "."
import {
getAllMiddlewareForModule,
handleRequestWithMiddleware,
@@ -7,14 +7,17 @@ import {
} from "./middleware"
import {SessionContext, PublicData} from "./supertokens"
import {log} from "@blitzjs/display"
import passport, {Strategy} from "passport"
import passport, {AuthenticateOptions, Strategy} from "passport"
import cookieSession from "cookie-session"
import {isLocalhost} from "./utils/index"
import {secureProxyMiddleware} from "./secure-proxy-middleware"
export type BlitzPassportConfig = {
successRedirectUrl?: string
errorRedirectUrl?: string
authenticateOptions?: AuthenticateOptions
strategies: Required<Strategy>[]
secureProxy?: boolean
}
export type VerifyCallbackResult = {
@@ -34,19 +37,23 @@ const INTERNAL_REDIRECT_URL_KEY = "_redirectUrl"
export function passportAuth(config: BlitzPassportConfig) {
return async function authHandler(req: BlitzApiRequest, res: BlitzApiResponse) {
const cookieSessionMiddleware = cookieSession({
secret: process.env.SESSION_SECRET_KEY || "default-dev-secret",
secure: process.env.NODE_ENV === "production" && !isLocalhost(req),
})
const passportMiddleware = passport.initialize()
const middleware: Middleware[] = [
// TODO - fix TS type - shouldn't need `any` here
connectMiddleware(
cookieSession({
secret: process.env.SESSION_SECRET_KEY || "default-dev-secret",
secure: process.env.NODE_ENV === "production" && !isLocalhost(req),
}) as any,
),
// TODO - fix TS type - shouldn't need `any` here
connectMiddleware(passport.initialize() as any),
connectMiddleware(cookieSessionMiddleware as ConnectMiddleware),
connectMiddleware(passportMiddleware as ConnectMiddleware),
connectMiddleware(passport.session()),
]
if (config.secureProxy) {
middleware.push(secureProxyMiddleware)
}
if (!req.query.auth.length) {
return res.status(404).end()
}
@@ -71,7 +78,9 @@ export function passportAuth(config: BlitzPassportConfig) {
return next()
})
}
middleware.push(connectMiddleware(passport.authenticate(strategy.name)))
middleware.push(
connectMiddleware(passport.authenticate(strategy.name, {...config.authenticateOptions})),
)
} else if (req.query.auth[1] === "callback") {
log.info(`Processing callback for ${strategy.name}...`)
middleware.push(

View File

@@ -0,0 +1,54 @@
// @ts-ignore
import {Request} from "express"
import {secureProxyMiddleware} from "./secure-proxy-middleware"
import {Socket} from "net"
// @ts-ignore
let reqSecure: Request = {
connection: new Socket(),
method: "GET",
url: "/stuff?q=thing",
headers: {
"x-forwarded-proto": "https",
},
}
// @ts-ignore
let reqHttp: Request = {
connection: new Socket(),
method: "GET",
url: "/stuff?q=thing",
headers: {
"x-forwarded-proto": "http",
},
}
// @ts-ignore
let reqNoHeader: Request = {
connection: new Socket(),
method: "GET",
url: "/stuff?q=thing",
}
const res = {}
describe("secure proxy middleware", () => {
it("should set https protocol if X-Forwarded-Proto is https", () => {
// @ts-ignore
secureProxyMiddleware(reqSecure, res, () => null)
expect(reqSecure.protocol).toEqual("https")
})
it("should set http protocol if X-Forwarded-Proto is absent", () => {
// @ts-ignore
secureProxyMiddleware(reqNoHeader, res, () => null)
expect(reqNoHeader.protocol).toEqual("http")
})
it("should set http protocol if X-Forwarded-Proto is http", () => {
// @ts-ignore
secureProxyMiddleware(reqHttp, res, () => null)
expect(reqHttp.protocol).toEqual("http")
})
})

View File

@@ -0,0 +1,23 @@
import {Middleware, MiddlewareRequest, MiddlewareResponse} from "middleware"
export const secureProxyMiddleware: Middleware = function (
req: MiddlewareRequest,
_res: MiddlewareResponse,
next: (error?: Error) => void,
) {
req.protocol = getProtocol(req)
next()
}
function getProtocol(req: MiddlewareRequest) {
// @ts-ignore
// For some reason there is no encrypted on socket while it is expected
if (req.connection.encrypted) {
return "https"
}
const forwardedProto = req.headers && (req.headers["x-forwarded-proto"] as string)
if (forwardedProto) {
return forwardedProto.split(/\s*,\s*/)[0]
}
return "http"
}

View File

@@ -3,7 +3,7 @@ import {
InfiniteQueryResult,
InfiniteQueryOptions,
} from "react-query"
import {useIsDevPrerender, emptyQueryFn, retryFunction} from "./use-query"
import {emptyQueryFn, retryFunction} from "./use-query"
import {PromiseReturnType, InferUnaryParam, QueryFn} from "./types"
import {getQueryCacheFunctions, QueryCacheFunctions, getInfiniteQueryKey} from "./utils/query-cache"
import {EnhancedRpcFunction} from "./rpc"
@@ -14,6 +14,8 @@ type RestQueryResult<T extends QueryFn> = Omit<
> &
QueryCacheFunctions<PromiseReturnType<T>[]>
const isServer = typeof window === "undefined"
export function useInfiniteQuery<T extends QueryFn>(
queryFn: T,
params: InferUnaryParam<T> | (() => InferUnaryParam<T>),
@@ -29,9 +31,7 @@ export function useInfiniteQuery<T extends QueryFn>(
)
}
const queryRpcFn = useIsDevPrerender()
? emptyQueryFn
: ((queryFn as unknown) as EnhancedRpcFunction)
const queryRpcFn = isServer ? emptyQueryFn : ((queryFn as unknown) as EnhancedRpcFunction)
const queryKey = getInfiniteQueryKey(queryFn, params)

View File

@@ -3,7 +3,7 @@ import {
PaginatedQueryResult,
QueryOptions,
} from "react-query"
import {useIsDevPrerender, emptyQueryFn, retryFunction} from "./use-query"
import {emptyQueryFn, retryFunction} from "./use-query"
import {PromiseReturnType, InferUnaryParam, QueryFn} from "./types"
import {QueryCacheFunctions, getQueryCacheFunctions, getQueryKey} from "./utils/query-cache"
import {EnhancedRpcFunction} from "./rpc"
@@ -14,6 +14,8 @@ type RestQueryResult<T extends QueryFn> = Omit<
> &
QueryCacheFunctions<PromiseReturnType<T>>
const isServer = typeof window === "undefined"
export function usePaginatedQuery<T extends QueryFn>(
queryFn: T,
params: InferUnaryParam<T> | (() => InferUnaryParam<T>),
@@ -29,9 +31,7 @@ export function usePaginatedQuery<T extends QueryFn>(
)
}
const queryRpcFn = useIsDevPrerender()
? emptyQueryFn
: ((queryFn as unknown) as EnhancedRpcFunction)
const queryRpcFn = isServer ? emptyQueryFn : ((queryFn as unknown) as EnhancedRpcFunction)
const queryKey = getQueryKey(queryFn, params)

View File

@@ -19,17 +19,6 @@ export const emptyQueryFn: EnhancedRpcFunction = (() => {
const isServer = typeof window === "undefined"
// NOTE - this is only for use inside useQuery
export const useIsDevPrerender = () => {
if (process.env.NODE_ENV === "production") {
return false
} else {
// useQuery is only for client-side data fetching, so if it's running on the
// server, it's for pre-render
return isServer
}
}
export const retryFunction = (failureCount: number, error: any) => {
if (process.env.NODE_ENV !== "production") return false
@@ -54,9 +43,7 @@ export function useQuery<T extends QueryFn>(
)
}
const queryRpcFn = useIsDevPrerender()
? emptyQueryFn
: ((queryFn as unknown) as EnhancedRpcFunction)
const queryRpcFn = isServer ? emptyQueryFn : ((queryFn as unknown) as EnhancedRpcFunction)
const queryKey = getQueryKey(queryFn, params)

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/display",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"description": "Display package for the Blitz CLI",
"homepage": "https://github.com/blitz-js/blitz#readme",
"license": "MIT",

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/file-pipeline",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"description": "Display package for the Blitz CLI",
"homepage": "https://github.com/blitz-js/blitz#readme",
"license": "MIT",

View File

@@ -1,11 +1,10 @@
import {pipe} from "../streams"
import {createPipeline} from "../pipeline"
import {pathExists, ensureDir, remove} from "fs-extra"
import {through} from "../streams"
import {createDisplay} from "../display"
import {READY, ERROR_THROWN} from "../events"
import {Stage} from "../types"
import {ensureDir, pathExists, remove} from "fs-extra"
import {Transform} from "stream"
import {createDisplay} from "../display"
import {ERROR_THROWN, READY} from "../events"
import {createPipeline} from "../pipeline"
import {pipe, through} from "../streams"
import {Stage} from "../types"
type FSStreamer = {stream: NodeJS.ReadWriteStream}
@@ -17,7 +16,6 @@ type SynchronizeFilesOptions = {
source?: FSStreamer
writer?: FSStreamer
noclean?: boolean
isTypescript?: boolean
}
const defaultBus = through.obj()
@@ -42,7 +40,6 @@ export async function transformFiles(
source,
writer,
noclean = false,
isTypescript = true,
} = options
// HACK: cleaning the dev folder on every restart means we do more work than necessary
@@ -59,7 +56,6 @@ export async function transformFiles(
include,
ignore,
watch,
isTypescript,
}
const fileTransformPipeline = createPipeline(config, stages, bus, source, writer)

View File

@@ -1,6 +1,6 @@
import {Writable} from "stream"
import {FileCache} from "./helpers/file-cache"
import File from "vinyl"
import {FileCache} from "./helpers/file-cache"
export type EventedFile = {
event: "add" | "change" | "unlink" | "unlinkDir"
@@ -21,7 +21,6 @@ export type StageConfig = {
include: string[]
ignore: string[]
watch: boolean
isTypescript: boolean
}
/**

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/generator",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"description": "File generation for the Blitz CLI",
"homepage": "https://github.com/blitz-js/blitz#readme",
"license": "MIT",
@@ -36,7 +36,7 @@
"dependencies": {
"@babel/core": "7.9.0",
"@babel/plugin-transform-typescript": "7.9.4",
"@blitzjs/display": "0.21.2-canary.1",
"@blitzjs/display": "0.22.1",
"@types/jscodeshift": "0.7.1",
"chalk": "4.0.0",
"cross-spawn": "7.0.3",
@@ -48,7 +48,7 @@
"jscodeshift": "0.10.0",
"mem-fs": "1.1.3",
"mem-fs-editor": "6.0.0",
"node-fetch": "2.6.0",
"node-fetch": "2.6.1",
"pluralize": "8.0.0",
"recast": "0.19.1",
"username": "5.1.0",

View File

@@ -1,4 +1,5 @@
import React from "react"
import { Link } from "blitz"
import { LabeledTextField } from "app/components/LabeledTextField"
import { Form, FORM_ERROR } from "app/components/Form"
import login from "app/auth/mutations/login"
@@ -36,6 +37,10 @@ export const LoginForm = (props: LoginFormProps) => {
<LabeledTextField name="email" label="Email" placeholder="Email" />
<LabeledTextField name="password" label="Password" placeholder="Password" type="password" />
</Form>
<div style={{ marginTop: "1rem" }}>
Or <Link href="/signup">Sign Up</Link>
</div>
</div>
)
}

View File

@@ -6,15 +6,17 @@ type LayoutProps = {
children: ReactNode
}
const Layout = ({ title, children }: LayoutProps) => (
<>
<Head>
<title>{title || "__name__"}</title>
<link rel="icon" href="/favicon.ico" />
</Head>
const Layout = ({ title, children }: LayoutProps) => {
return (
<>
<Head>
<title>{title || "__name__"}</title>
<link rel="icon" href="/favicon.ico" />
</Head>
{children}
</>
)
{children}
</>
)
}
export default Layout

View File

@@ -1,14 +1,16 @@
import { AppProps, ErrorComponent } from "blitz"
import { AppProps, ErrorComponent, useRouter } from "blitz"
import { ErrorBoundary, FallbackProps } from "react-error-boundary"
import { queryCache } from "react-query"
import LoginForm from "app/auth/components/LoginForm"
export default function App({ Component, pageProps }: AppProps) {
const getLayout = Component.getLayout || ((page) => page)
const router = useRouter()
return (
<ErrorBoundary
FallbackComponent={RootErrorFallback}
resetKeys={[router.asPath]}
onReset={() => {
// This ensures the Blitz useQuery hooks will automatically refetch
// data any time you reset the error boundary

View File

@@ -39,13 +39,13 @@
},
"devDependencies": {
"@testing-library/jest-dom": "5.x",
"@testing-library/react": "10.x",
"@testing-library/react": "11.x",
"@testing-library/react-hooks": "3.x",
"@types/jest": "26.x",
"@types/react": "16.x",
"@types/secure-password": "3.x",
"@typescript-eslint/eslint-plugin": "3.x",
"@typescript-eslint/parser": "3.x",
"@typescript-eslint/eslint-plugin": "4.x",
"@typescript-eslint/parser": "4.x",
"babel-eslint": "10.x",
"eslint": "7.x",
"eslint-config-react-app": "5.x",
@@ -61,8 +61,8 @@
"react-test-renderer": "16.x",
"lint-staged": "10.x",
"prettier": "2.x",
"pretty-quick": "2.x",
"typescript": "3.x",
"pretty-quick": "3.x",
"typescript": "4.x",
"ts-jest": "26.x"
},
"private": true

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/installer",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"description": "Package installation for the Blitz CLI",
"homepage": "https://github.com/blitz-js/blitz#readme",
"license": "MIT",
@@ -36,8 +36,8 @@
"dependencies": {
"@babel/core": "7.9.0",
"@babel/plugin-transform-typescript": "7.9.4",
"@blitzjs/display": "0.21.2-canary.1",
"@blitzjs/generator": "0.21.2-canary.1",
"@blitzjs/display": "0.22.1",
"@blitzjs/generator": "0.22.1",
"@types/jscodeshift": "0.7.1",
"chokidar": "3.4.2",
"cross-spawn": "7.0.3",

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/repl",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"description": "Repl package for Blitz CLI",
"homepage": "https://github.com/blitz-js/blitz/packages/repl/#readme",
"license": "MIT",

View File

@@ -1,7 +1,7 @@
{
"name": "@blitzjs/server",
"description": "Blitz.js server functionality",
"version": "0.21.2-canary.1",
"version": "0.22.1",
"license": "MIT",
"bin": {
"next-patched": "./bin/next-patched"
@@ -29,9 +29,9 @@
"module": "dist/server.esm.js",
"types": "dist/packages/server/src/index.d.ts",
"dependencies": {
"@blitzjs/config": "0.21.2-canary.1",
"@blitzjs/display": "0.21.2-canary.1",
"@blitzjs/file-pipeline": "0.21.2-canary.1",
"@blitzjs/config": "0.22.1",
"@blitzjs/display": "0.22.1",
"@blitzjs/file-pipeline": "0.22.1",
"b64-lite": "1.4.0",
"cookie": "0.4.1",
"cross-spawn": "7.0.3",
@@ -66,7 +66,7 @@
"vinyl-fs": "3.0.3"
},
"devDependencies": {
"@blitzjs/core": "0.21.2-canary.1",
"@blitzjs/core": "0.22.1",
"next-transpile-modules": "3.2.0"
},
"gitHead": "d3b9fce0bdd251c2b1890793b0aa1cd77c1c0922"

View File

@@ -1,8 +1,8 @@
import {move, pathExists, remove} from "fs-extra"
import {resolve} from "path"
import {move, remove, pathExists} from "fs-extra"
import {ServerConfig, normalize} from "./config"
import {nextBuild} from "./next-utils"
import {saveBuild} from "./build-hash"
import {normalize, ServerConfig} from "./config"
import {nextBuild} from "./next-utils"
import {configureStages} from "./stages"
export async function build(
@@ -18,19 +18,19 @@ export async function build(
include,
watch,
isTypescript,
...stageConfig
writeManifestFile,
} = await normalize(config)
const src = rootFolder
const stages = configureStages(stageConfig)
const dest = buildFolder
const options = {
ignore,
include,
watch,
isTypescript,
}
await Promise.all([transformFiles(src, stages, dest, options), readyForNextBuild])
const stages = configureStages({isTypescript, writeManifestFile})
await Promise.all([
transformFiles(rootFolder, stages, buildFolder, {
ignore,
include,
watch,
}),
readyForNextBuild,
])
await nextBuild(nextBin, buildFolder)

View File

@@ -1,36 +1,54 @@
import {resolve} from "path"
import {resolveBinAsync} from "./resolve-bin-async"
import {transformFiles} from "@blitzjs/file-pipeline"
import {promises} from "fs"
import {join, resolve} from "path"
import {parseChokidarRulesFromGitignore} from "./parse-chokidar-rules-from-gitignore"
import {resolveBinAsync} from "./resolve-bin-async"
type Synchronizer = typeof transformFiles
type ServerEnvironment = "dev" | "prod"
export type ServerConfig = {
rootFolder: string
buildFolder?: string
devFolder?: string
// -
isTypescript?: boolean
watch?: boolean
// -
transformFiles?: Synchronizer
writeManifestFile?: boolean
// -
port?: number
hostname?: string
interceptNextErrors?: boolean
devFolder?: string
buildFolder?: string
writeManifestFile?: boolean
watch?: boolean
transformFiles?: Synchronizer
isTypescript?: boolean
//
env?: ServerEnvironment
}
type NormalizedConfig = Omit<ServerConfig, "interceptNextErrors"> & {
ignore: string[]
include: string[]
nextBin: string
devFolder: string
type NormalizedConfig = ServerConfig & {
buildFolder: string
devFolder: string
// -
isTypescript: boolean
watch: boolean
// -
transformFiles: Synchronizer
writeManifestFile: boolean
watch: boolean
isTypescript: boolean
// -
ignore: string[]
include: string[]
// -
nextBin: string
env: ServerEnvironment
}
const defaults = {
env: "prod" as ServerEnvironment,
// -
buildFolder: ".blitz/caches/build",
devFolder: ".blitz/caches/dev",
// -
writeManifestFile: true,
// -
ignoredPaths: [
"./build/**/*",
"./.blitz-*/**/*",
@@ -50,29 +68,56 @@ const defaults = {
"dist/**/*",
"node_modules/**/*",
"cypress/**/*",
"test/**/*",
"tests/**/*",
"spec/**/*",
"specs/**/*",
"**/*.test.*",
"**/*.spec.*",
],
includePaths: ["**/*"],
devFolder: ".blitz/caches/dev",
buildFolder: ".blitz/caches/build",
nextBinPatched: "./node_modules/.bin/next-patched",
writeManifestFile: true,
}
export async function normalize(config: ServerConfig): Promise<NormalizedConfig> {
const nextBinOrig = await resolveBinAsync("next")
const nextBinPatched = await resolveBinAsync("@blitzjs/server", "next-patched")
const git = parseChokidarRulesFromGitignore(resolve(process.cwd(), config.rootFolder))
const rootFolder = resolve(process.cwd(), config.rootFolder)
const git = parseChokidarRulesFromGitignore(rootFolder)
const env = config.env || defaults.env
return {
...config,
buildFolder: resolve(config.rootFolder, config.buildFolder ?? defaults.buildFolder),
devFolder: resolve(config.rootFolder, config.devFolder ?? defaults.devFolder),
env,
// -
rootFolder,
buildFolder: resolve(rootFolder, config.buildFolder ?? defaults.buildFolder),
devFolder: resolve(rootFolder, config.devFolder ?? defaults.devFolder),
// -
isTypescript: config.isTypescript ?? (await getIsTypescript(rootFolder)),
watch: config.watch ?? env === "dev",
// -
transformFiles: config.transformFiles ?? transformFiles,
writeManifestFile: config.writeManifestFile ?? defaults.writeManifestFile,
// -
ignore: defaults.ignoredPaths.concat(git.ignoredPaths),
include: defaults.includePaths.concat(git.includePaths),
nextBin: resolve(config.rootFolder, config.interceptNextErrors ? nextBinPatched : nextBinOrig),
transformFiles: config.transformFiles ?? transformFiles,
watch: config.watch ?? false,
writeManifestFile: config.writeManifestFile ?? defaults.writeManifestFile,
isTypescript: config.isTypescript ?? true,
// -
nextBin: await getNextBin(rootFolder, env === "dev"),
}
}
async function getNextBin(rootFolder: string, usePatched: boolean = false): Promise<string> {
// do not await for both bin-pkg because just one is used at a time
const nextBinPkg = usePatched ? "@blitzjs/server" : "next"
const nextBinExec = usePatched ? "next-patched" : undefined
const nextBin = await resolveBinAsync(nextBinPkg, nextBinExec)
return resolve(rootFolder, nextBin)
}
async function getIsTypescript(rootFolder: string): Promise<boolean> {
try {
await promises.access(join(rootFolder, "tsconfig.json"))
return true
} catch {
return false
}
}

View File

@@ -1,14 +1,9 @@
import {resolve} from "path"
import {ServerConfig, normalize} from "./config"
import {normalize, ServerConfig} from "./config"
import {nextStartDev} from "./next-utils"
import {configureStages} from "./stages"
export async function dev(
{watch = true, ...config}: ServerConfig,
readyForNextDev: Promise<any> = Promise.resolve(),
) {
export async function dev(config: ServerConfig, readyForNextDev: Promise<any> = Promise.resolve()) {
const {
//
rootFolder,
transformFiles,
nextBin,
@@ -16,27 +11,21 @@ export async function dev(
ignore,
include,
isTypescript,
...stagesConfig
} = await normalize({
...config,
interceptNextErrors: true,
})
const src = resolve(rootFolder)
const stages = configureStages(stagesConfig)
const dest = resolve(rootFolder, devFolder)
const options = {
ignore,
include,
writeManifestFile,
watch,
isTypescript,
}
} = await normalize({...config, env: "dev"})
const stages = configureStages({writeManifestFile, isTypescript})
const [{manifest}] = await Promise.all([
transformFiles(src, stages, dest, options),
transformFiles(rootFolder, stages, devFolder, {
ignore,
include,
watch,
}),
// Ensure next does not start until parallel processing completes
readyForNextDev,
])
await nextStartDev(nextBin, dest, manifest, devFolder, config)
await nextStartDev(nextBin, devFolder, manifest, devFolder, config)
}

View File

@@ -1,16 +1,18 @@
import {createStageRelative} from "./relative"
import {createStagePages} from "./pages"
import {createStageRpc} from "./rpc"
import {createStageConfig} from "./config"
import {createStageManifest} from "./manifest"
import {createStagePages} from "./pages"
import {createStageRelative} from "./relative"
import {createStageRpc} from "./rpc"
type StagesConfig = {writeManifestFile: boolean; isTypescript: boolean}
// These create pipeline stages that are run as the business rules for Blitz
// Read this folders README for more information
export const configureStages = (config: {writeManifestFile: boolean}) => [
export const configureStages = (config: StagesConfig) => [
// Order is important
createStageRelative,
createStagePages,
createStageRpc,
createStageRpc(config.isTypescript),
createStageConfig,
createStageManifest(config.writeManifestFile),
]

View File

@@ -59,51 +59,52 @@ export const config = {
/**
* Returns a Stage that manages generating the internal RPC commands and handlers
*/
export const createStageRpc: Stage = function configure({config: {src, isTypescript = true}}) {
const fileTransformer = absolutePathTransform(src)
export const createStageRpc = (isTypescript = true): Stage =>
function configure({config: {src}}) {
const fileTransformer = absolutePathTransform(src)
const getResolverPath = fileTransformer(resolverPath)
const getApiHandlerPath = fileTransformer(apiHandlerPath)
const getResolverPath = fileTransformer(resolverPath)
const getApiHandlerPath = fileTransformer(apiHandlerPath)
const stream = transform.file((file, {next, push}) => {
if (!isResolverPath(file.path)) {
return file
}
const stream = transform.file((file, {next, push}) => {
if (!isResolverPath(file.path)) {
return file
}
const originalPath = resolutionPath(src, file.path)
const resolverImportPath = resolverPath(originalPath)
const {resolverType, resolverName} = extractTemplateVars(resolverImportPath)
const originalPath = resolutionPath(src, file.path)
const resolverImportPath = resolverPath(originalPath)
const {resolverType, resolverName} = extractTemplateVars(resolverImportPath)
// Original function -> _resolvers path
push(
new File({
path: getResolverPath(file.path),
contents: file.contents,
hash: file.hash + ":1",
}),
)
// Original function -> _resolvers path
push(
new File({
path: getResolverPath(file.path),
contents: file.contents,
hash: file.hash + ":1",
}),
)
// File API route handler
push(
new File({
path: getApiHandlerPath(file.path),
contents: Buffer.from(apiHandlerTemplate(originalPath, isTypescript)),
hash: file.hash + ":2",
}),
)
// File API route handler
push(
new File({
path: getApiHandlerPath(file.path),
contents: Buffer.from(apiHandlerTemplate(originalPath, isTypescript)),
hash: file.hash + ":2",
}),
)
// Isomorphic client
const isomorphicHandlerFile = file.clone()
isomorphicHandlerFile.contents = Buffer.from(
isomorhicHandlerTemplate(resolverImportPath, resolverName, resolverType, isTypescript),
)
push(isomorphicHandlerFile)
// Isomorphic client
const isomorphicHandlerFile = file.clone()
isomorphicHandlerFile.contents = Buffer.from(
isomorhicHandlerTemplate(resolverImportPath, resolverName, resolverType, isTypescript),
)
push(isomorphicHandlerFile)
return next()
})
return next()
})
return {stream}
}
return {stream}
}
function removeExt(filePath: string) {
return filePath.replace(/[.][^./\s]+$/, "")

View File

@@ -1,7 +1,6 @@
import {StageConfig, StageArgs} from "@blitzjs/file-pipeline/dist/packages/file-pipeline/src/types"
import {FileCache} from "@blitzjs/file-pipeline"
import {through, pipeline} from "../streams"
import {StageArgs, StageConfig} from "@blitzjs/file-pipeline/dist/packages/file-pipeline/src/types"
import {pipeline, through} from "../streams"
export function mockStageArgs(a: {entries?: string[]; cwd?: string}): StageArgs {
const config: StageConfig = {
@@ -11,7 +10,6 @@ export function mockStageArgs(a: {entries?: string[]; cwd?: string}): StageArgs
include: [],
src: "",
watch: false,
isTypescript: true,
}
return {
getInputCache() {

View File

@@ -1,7 +1,7 @@
{
"name": "@blitzjs/recipe-chakra",
"private": true,
"version": "0.21.2-canary.1",
"version": "0.22.1",
"description": "The Blitz Recipe for installing Chakra UI",
"main": "index.ts",
"scripts": {
@@ -23,7 +23,7 @@
},
"homepage": "https://github.com/blitz-js/blitz#readme",
"dependencies": {
"@blitzjs/installer": "0.21.2-canary.1",
"@blitzjs/installer": "0.22.1",
"jscodeshift": "0.10.0"
},
"devDependencies": {

View File

@@ -1,7 +1,7 @@
{
"name": "@blitzjs/recipe-emotion",
"private": true,
"version": "0.21.2-canary.1",
"version": "0.22.1",
"description": "The Blitz Recipe for installing Emotion",
"main": "index.ts",
"scripts": {
@@ -22,7 +22,7 @@
},
"homepage": "https://github.com/blitz-js/blitz#readme",
"dependencies": {
"@blitzjs/installer": "0.21.2-canary.1",
"@blitzjs/installer": "0.22.1",
"jscodeshift": "0.10.0"
},
"devDependencies": {

View File

@@ -1,7 +1,7 @@
{
"name": "@blitzjs/recipe-material-ui",
"private": true,
"version": "0.21.2-canary.1",
"version": "0.22.1",
"description": "The Blitz Recipe for installing Material-UI",
"main": "index.ts",
"scripts": {
@@ -23,7 +23,7 @@
},
"homepage": "https://github.com/blitz-js/blitz#readme",
"dependencies": {
"@blitzjs/installer": "0.21.2-canary.1",
"@blitzjs/installer": "0.22.1",
"jscodeshift": "0.10.0"
},
"devDependencies": {

View File

@@ -1,7 +1,7 @@
{
"name": "@blitzjs/recipe-render",
"private": true,
"version": "0.21.2-canary.1",
"version": "0.22.1",
"description": "The Blitz Recipe for adding render.yaml",
"main": "index.ts",
"scripts": {
@@ -22,6 +22,6 @@
},
"homepage": "https://github.com/blitz-js/blitz#readme",
"dependencies": {
"@blitzjs/installer": "0.21.2-canary.1"
"@blitzjs/installer": "0.22.1"
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "@blitzjs/recipe-tailwind",
"private": true,
"version": "0.21.2-canary.1",
"version": "0.22.1",
"description": "The Blitz Recipe for installing Tailwind CSS",
"main": "index.ts",
"scripts": {
@@ -22,7 +22,7 @@
},
"homepage": "https://github.com/blitz-js/blitz#readme",
"dependencies": {
"@blitzjs/installer": "0.21.2-canary.1",
"@blitzjs/installer": "0.22.1",
"jscodeshift": "0.10.0"
},
"devDependencies": {

View File

@@ -4191,6 +4191,14 @@
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
"@types/passport-auth0@1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/passport-auth0/-/passport-auth0-1.0.4.tgz#f92c357a3a2a6fa5f10744555a45c5e9a6e36469"
integrity sha512-Qq1YRz1kuhFMHn43btY/RZ3pxV84ogOwhDfPWVcgGqgHYRWf5rTtV3tvcwPRFFh3Z72JkJhQ/9bbxnTFoV2ytg==
dependencies:
"@types/express" "*"
"@types/passport" "*"
"@types/passport-github2@1.2.4":
version "1.2.4"
resolved "https://registry.yarnpkg.com/@types/passport-github2/-/passport-github2-1.2.4.tgz#f56c386d1fe6435e359430e57adc1747a627bd86"
@@ -13672,6 +13680,11 @@ node-fetch@2.6.0, node-fetch@^2.1.1, node-fetch@^2.2.0, node-fetch@^2.3.0, node-
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
node-fetch@2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
node-gyp-build@^4.2.0:
version "4.2.2"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.2.tgz#3f44b65adaafd42fb6c3d81afd630e45c847eb66"
@@ -14642,6 +14655,15 @@ pascalcase@^0.1.1:
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=
passport-auth0@1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/passport-auth0/-/passport-auth0-1.3.3.tgz#d377f9aea2f6e89af0318a6364a847e80966bb88"
integrity sha512-rcjT0fV6HnJuSb8REwREl42/K5LpGK+doekDgEQbtT/pNwLAjfobSMiQ3RbTP1CkiEcDVRucGucuDSfgqHX/Vg==
dependencies:
passport-oauth "^1.0.0"
passport-oauth2 "^1.5.0"
request "^2.88.0"
passport-github2@0.1.11:
version "0.1.11"
resolved "https://registry.yarnpkg.com/passport-github2/-/passport-github2-0.1.11.tgz#c92b56f3c38a44e766aac7e9e7c1384c5e93c999"
@@ -14658,7 +14680,7 @@ passport-oauth1@1.x.x:
passport-strategy "1.x.x"
utils-merge "1.x.x"
passport-oauth2@1.x.x:
passport-oauth2@1.x.x, passport-oauth2@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.5.0.tgz#64babbb54ac46a4dcab35e7f266ed5294e3c4108"
integrity sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==
@@ -14669,6 +14691,14 @@ passport-oauth2@1.x.x:
uid2 "0.0.x"
utils-merge "1.x.x"
passport-oauth@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/passport-oauth/-/passport-oauth-1.0.0.tgz#90aff63387540f02089af28cdad39ea7f80d77df"
integrity sha1-kK/2M4dUDwIImvKM2tOep/gNd98=
dependencies:
passport-oauth1 "1.x.x"
passport-oauth2 "1.x.x"
passport-strategy@1.x.x:
version "1.0.0"
resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4"