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

Compare commits

..

22 Commits

Author SHA1 Message Date
Siddharth Suresh
ee99c5739c start adding index page / twoslash and add community docs 2023-03-02 23:27:22 +05:30
Siddharth Suresh
de5b6eb9a9 add introduction pages 2023-03-02 17:57:53 +05:30
Siddharth Suresh
d86bb0cf83 init nextra 2023-03-02 15:12:27 +05:30
Blitz.js Bot
f443118b9d (meta) added @exKAZUu as contributor 2023-02-16 12:17:01 -05:00
Sakamoto, Kazunori
e228ba5dee fix: type error in reset-password.tsx (#4081) 2023-02-17 00:16:55 +07:00
Tobias
430f0b52dd Update to "prisma": "4.6.1" (#4062)
Co-authored-by: Brandon Bayer <b@bayer.ws>
Co-authored-by: Siddharth Suresh <siddh.suresh@gmail.com>
2023-02-13 18:47:50 +05:30
Marcus Reinhardt
6e88a847fe fix: vulnerabilities in @blitz/auth (#4082)
* fix vulnerabilities

* Update .changeset/strong-chicken-study.md

---------

Co-authored-by: Brandon Bayer <b@bayer.ws>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2023-02-13 10:20:10 +00:00
Brandon Bayer
1db963a8ca update readme 2023-02-13 17:12:26 +07:00
github-actions[bot]
6374f2ff0c Version Packages (beta) (#4055)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Siddharth Suresh <siddh.suresh@gmail.com>
2023-02-09 21:44:34 +05:30
Tobias
6ec020c6d6 Remove useEffect from reset password templates (#4051)
Co-authored-by: Siddharth Suresh <siddh.suresh@gmail.com>
Co-authored-by: Brandon Bayer <b@bayer.ws>
2023-02-09 11:19:10 +05:30
Blitz.js Bot
a3d8b287f1 (meta) added @sweetliquid as contributor 2023-02-07 03:24:20 -05:00
sweetliquid
4ed1fc1233 docs: delete duplicates of the in comments (#4073)
Co-authored-by: Brandon Bayer <b@bayer.ws>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2023-02-07 08:24:14 +00:00
Siddharth Suresh
3fa3c70b39 internal: Readme for the packages (#4052) 2023-02-07 15:14:58 +07:00
Blitz.js Bot
a9b1989bb0 (meta) added @jhonnymichel as contributor 2023-02-06 10:47:34 -05:00
Jhonny Michel
c3c789740a Fixing tests for blitz apps that use vitest (#4072)
Co-authored-by: Siddharth Suresh <siddh.suresh@gmail.com>
Closes https://github.com/blitz-js/blitz/issues/4065
2023-02-06 21:17:28 +05:30
Siddharth Suresh
42a2cf951a Add secure-password as an Optional peerDependency (#4067)
Co-authored-by: Brandon Bayer <b@bayer.ws>
2023-02-06 19:11:42 +05:30
Tobias
d316d0db7f Next 13: Remove anchor tags from Link component (#4071)
Co-authored-by: Siddharth Suresh <siddh.suresh@gmail.com>
Closes https://github.com/blitz-js/blitz/issues/4066
2023-02-06 18:52:49 +05:30
Siddharth Suresh
a8ce2325fc Fix max-width of body in new app template (#4068)
Co-authored-by: Brandon Bayer <b@bayer.ws>
2023-01-27 20:41:15 +05:30
Blitz.js Bot
f58a0e42f7 (meta) updated @tordans contributions 2023-01-26 05:23:14 -05:00
Tobias
cb63a0ea5b Guard blitz generate input against unwanted characters (#4024)
Co-authored-by: Dillon Raphael <dillon@creatorsneverdie.com>
Co-authored-by: Siddharth Suresh <siddh.suresh@gmail.com>
Closes https://github.com/blitz-js/blitz/issues/4021
2023-01-26 15:53:08 +05:30
Siddharth Suresh
a78bd33706 internal: Publish PRs to npm (#4050) 2023-01-14 20:39:16 +05:30
bravo-kernel
79c5e86d71 Add missing Layout.tsx for generated mimimalapp (#4054) 2023-01-13 17:28:53 -05:00
145 changed files with 14343 additions and 10908 deletions

View File

@@ -3794,7 +3794,8 @@
"profile": "http://tobiasjordans.de",
"contributions": [
"code",
"doc"
"doc",
"test"
]
},
{
@@ -3816,6 +3817,36 @@
"doc",
"code"
]
},
{
"login": "jhonnymichel",
"name": "Jhonny Michel",
"avatar_url": "https://avatars.githubusercontent.com/u/7006387?v=4",
"profile": "https://github.com/jhonnymichel",
"contributions": [
"doc",
"code",
"test"
]
},
{
"login": "sweetliquid",
"name": "sweetliquid",
"avatar_url": "https://avatars.githubusercontent.com/u/18693190?v=4",
"profile": "sweetliquid.me",
"contributions": [
"code"
]
},
{
"login": "exKAZUu",
"name": "Sakamoto, Kazunori",
"avatar_url": "https://avatars.githubusercontent.com/u/436237?v=4",
"profile": "https://github.com/exKAZUu",
"contributions": [
"doc",
"code"
]
}
],
"contributorsPerLine": 7,

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Guard `blitz g` input via an allow-list of characters; throw if unwanted characters are found. Prevents to break the blitz command by accident (https://github.com/blitz-js/blitz/issues/4021).

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Fix a type error in reset password templates.

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
For new applications, update Prisma (`prisma` and `@prisma/client`) from `4.6.0` to `4.6.1` to solve enum issue with postgresql https://github.com/prisma/prisma/issues/16180

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Remove useEffect from reset password templates.

View File

@@ -0,0 +1,6 @@
---
"blitz": patch
"@blitzjs/rpc": patch
---
Updates internal functions and tests to support blitz apps that run tests with vitest

View File

@@ -51,6 +51,7 @@
"changesets": [
"afraid-dancers-juggle",
"afraid-ears-repair",
"big-boats-lay",
"big-phones-bow",
"blue-flowers-peel",
"blue-pigs-tan",
@@ -195,9 +196,11 @@
"olive-sheep-rhyme",
"orange-mirrors-tap",
"orange-zebras-reflect",
"perfect-baboons-relate",
"perfect-eyes-repeat",
"perfect-trains-double",
"plenty-bottles-swim",
"plenty-kiwis-greet",
"polite-lizards-love",
"poor-peas-lick",
"poor-penguins-look",
@@ -260,18 +263,21 @@
"stupid-walls-sell",
"sweet-kiwis-cross",
"swift-drinks-dress",
"swift-glasses-laugh",
"swift-poets-travel",
"tall-meals-learn",
"tame-keys-reply",
"tame-pumpkins-nail",
"tasty-maps-fetch",
"tasty-news-collect",
"tasty-squids-sin",
"ten-hairs-listen",
"ten-rivers-burn",
"tender-cooks-tie",
"tender-pianos-check",
"thick-moons-fry",
"thick-parrots-float",
"thick-peas-jog",
"thirty-countries-build",
"thirty-spies-applaud",
"three-lies-pull",

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/auth": patch
---
Fixed security vulnerabilities in passport-adapter by upgrading `passport` and `jsonwebtoken`

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Update all links to follow Next 13 format without a child anchor tag.

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Add missing Layout.tsx for generated mimimalapp

View File

@@ -0,0 +1,7 @@
---
"@blitzjs/auth": major
---
BREAKING CHANGE: secure-password is now an `optional peerDependency`, if you are using `SecurePassword` api, you need to now install `secure-password` in your application.
This helps users who do not use SecurePassword from having native package build issues.

View File

@@ -7,6 +7,9 @@ on:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
jobs:
lint:
@@ -136,8 +139,6 @@ jobs:
- name: Install dependencies
run: pnpm install --frozen-lockfile
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
shell: bash
- name: Install playwright

102
.github/workflows/pr-release.yml vendored Normal file
View File

@@ -0,0 +1,102 @@
# https://github.com/withastro/astro/blob/main/.github/workflows/snapshot-release.yml
name: Create a Snapshot Release
on:
issue_comment:
types: [created]
defaults:
run:
shell: bash
jobs:
snapshot-release:
name: Create a snapshot release of a pull request
if: ${{ github.repository_owner == 'blitz-js' && github.event.issue.pull_request && startsWith(github.event.comment.body, '!preview') }}
runs-on: ubuntu-latest
steps:
- name: "Check if user has admin access (only admins can publish snapshot releases)."
uses: "lannonbr/repo-permission-check-action@2.0.0"
with:
permission: "admin"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: resolve pr refs
id: refs
uses: eficode/resolve-pr-refs@main
with:
token: ${{ secrets.GITHUB_TOKEN }}
- uses: actions/checkout@v3
with:
ref: ${{ steps.refs.outputs.head_ref }}
- name: Setup PNPM
uses: pnpm/action-setup@v2.2.1
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 16
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
- name: Short SHA
id: vars
run: echo "sha_short=$(git rev-parse --short "$GITHUB_SHA")" >> $GITHUB_OUTPUT
- name: Extract the snapshot name from comment body
id: getSnapshotName
uses: actions/github-script@v6
with:
script: |
const splitComment = context.payload.comment.body.split(' ');
if(splitComment.length !== 2) {
return "${{ steps.vars.outputs.sha_short }}";
}
return splitComment[1].trim();
result-encoding: string
- name: Install dependencies
run: pnpm install
env:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
- name: Build Packages
run: pnpm run build
- name: Bump Package Versions
id: changesets
run: |
pnpm changeset pre exit
pnpm changeset version --snapshot ${{ steps.getSnapshotName.outputs.result }} > changesets.output.txt 2>&1
echo ::set-output name=result::`cat changesets.output.txt`
env:
# Needs access to run the script
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish Release
id: publish
run: |
pnpm run release --tag next--${{ steps.getSnapshotName.outputs.result }} > publish.output.txt 2>&1
echo ::set-output name=result::`cat publish.output.txt`
env:
# Needs access to publish to npm
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Pull Request Notification
uses: actions/github-script@v6
env:
MESSAGE: ${{ steps.publish.outputs.result }}
with:
script: |
console.log(process.env.MESSAGE);
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '```\n' + process.env.MESSAGE + '\n```',
})

View File

@@ -1,6 +1,6 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
pnpm manypkg check
pnpm lint
pnpm pretty-quick --staged
# pnpm manypkg check
# pnpm lint
# pnpm pretty-quick --staged

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-403-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-406-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/main/LICENSE">
<img alt="" src="https://img.shields.io/npm/l/blitz.svg?style=for-the-badge&labelColor=000000&color=blue">
@@ -135,7 +135,15 @@ Your financial contributions help ensure Blitz continues to be developed and mai
<table>
<tr>
<td align="center"><a href="https://twitter.com/flybayer"><img src="https://avatars3.githubusercontent.com/u/8813276?v=4" width="100px;" alt=""/><br /><sub><b>Brandon Bayer</b></sub></a><br />Creator</td>
<td align="center"><a href="http://twitter.com/dillonraphael"><img src="https://avatars.githubusercontent.com/u/3496193?v=4" width="100px;" alt=""/><br /><sub><b>Dillon Raphael</b></sub></a><br />Lead Maintainer</td>
<td align="center"><a href="http://twitter.com/dillonraphael"><img src="https://avatars.githubusercontent.com/u/3496193?v=4" width="100px;" alt=""/><br /><sub><b>Dillon Raphael</b></sub></a><br /></td>
<td align="center">
<a href="https://siddharthsuresh.vercel.app/">
<img src="https://avatars.githubusercontent.com/u/83594610?v=4" width="100px;" alt="Siddharth Suresh avatar" /><br />
<sub>
<b>Siddharth Suresh</b>
</sub>
</a>
</td>
</tr>
</table>
@@ -155,7 +163,6 @@ _Code ownership, pull request approvals and merging, etc_ (see [Maintainers L2](
<tr>
<td align="center"><a href="http://simonknott.de"><img src="https://avatars1.githubusercontent.com/u/14912729?v=4" width="100px;" alt=""/><br /><sub><b>Simon Knott</b></sub></a><br />SuperJSON</td>
<td align="center"><a href="http://jins.dev"><img src="https://avatars.githubusercontent.com/u/39466936?v=4" width="100px;" alt=""/><br /><sub><b>JH.Lee</b></sub></a><br />SuperJSON</td>
<td align="center"><a href="https://juanm04.com"><img src="https://avatars0.githubusercontent.com/u/16712703?v=4" width="100px;" alt=""/><br /><sub><b>Juan Martín Seery</b></sub></a><br />Website/Docs</td>
</tr>
</table>
<!-- markdownlint-enable -->
@@ -173,38 +180,6 @@ _Issue triage, pull request triage, community encouragement and moderation, etc_
<table>
<tr>
<td align="center"><a href="http://jeremyliberman.com/"><img src="https://avatars3.githubusercontent.com/u/2754163?v=4" width="100px;" alt=""/><br /><sub><b>Jeremy Liberman</b></td>
<td align="center">
<a href="https://mina.ca">
<img src="https://avatars.githubusercontent.com/mabadir" width="100px;" alt="Mina Abadir avatar" /><br />
<sub>
<b>Mina Abadir</b>
</sub>
</a>
</td>
<td align="center">
<a href="https://builtforfifty.com">
<img src="https://avatars.githubusercontent.com/abuuzayr" width="100px;" alt="Abu Uzayr avatar" /><br />
<sub>
<b>Abu Uzayr</b>
</sub>
</a>
</td>
<td align="center">
<a href="https://damilolarandolph.com/">
<img src="https://avatars.githubusercontent.com/damilolarandolph" width="100px;" alt="Damilola Randolph avatar" /><br />
<sub>
<b>Damilola Randolph</b>
</sub>
</a>
</td>
<td align="center">
<a href="https://siddharthsuresh.vercel.app/">
<img src="https://avatars.githubusercontent.com/u/83594610?v=4" width="100px;" alt="Siddharth Suresh avatar" /><br />
<sub>
<b>Siddharth Suresh</b>
</sub>
</a>
</td>
</tr>
</table>
<!-- markdownlint-enable -->
@@ -736,9 +711,12 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
</tr>
<tr>
<td align="center"><a href="a11rew.dev"><img src="https://avatars.githubusercontent.com/u/87580113?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrew Glago</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=a11rew" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=a11rew" title="Code">💻</a></td>
<td align="center"><a href="http://tobiasjordans.de"><img src="https://avatars.githubusercontent.com/u/111561?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tobias</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=tordans" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=tordans" title="Documentation">📖</a></td>
<td align="center"><a href="http://tobiasjordans.de"><img src="https://avatars.githubusercontent.com/u/111561?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tobias</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=tordans" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=tordans" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=tordans" title="Tests">⚠️</a></td>
<td align="center"><a href="https://www.linkedin.com/in/iagor-moraes/"><img src="https://avatars.githubusercontent.com/u/13892132?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Iagor Moraes</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=iagormoraes" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=iagormoraes" title="Code">💻</a></td>
<td align="center"><a href="https://twitter.com/trensik"><img src="https://avatars.githubusercontent.com/u/18584155?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Dawid Urbaniak</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Trancever" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=Trancever" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/jhonnymichel"><img src="https://avatars.githubusercontent.com/u/7006387?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jhonny Michel</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jhonnymichel" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=jhonnymichel" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=jhonnymichel" title="Tests">⚠️</a></td>
<td align="center"><a href="sweetliquid.me"><img src="https://avatars.githubusercontent.com/u/18693190?v=4?s=100" width="100px;" alt=""/><br /><sub><b>sweetliquid</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=sweetliquid" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/exKAZUu"><img src="https://avatars.githubusercontent.com/u/436237?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Sakamoto, Kazunori</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=exKAZUu" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=exKAZUu" title="Code">💻</a></td>
</tr>
</table>

View File

@@ -29,11 +29,11 @@
"@blitzjs/rpc": "workspace:*",
"@hookform/error-message": "2.0.0",
"@hookform/resolvers": "2.9.10",
"@prisma/client": "4.6.0",
"blitz": "workspace:2.0.0-beta.22",
"@prisma/client": "4.6.1",
"blitz": "workspace:2.0.0-beta.23",
"next": "12.2.5",
"openid-client": "5.2.1",
"prisma": "4.6.0",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hook-form": "7.39.1",

View File

@@ -40,16 +40,16 @@ export const LoginForm = (props: LoginFormProps) => {
<LabeledTextField name="email" label="Email" placeholder="Email" />
<LabeledTextField name="password" label="Password" placeholder="Password" type="password" />
<div>
<Link href={Routes.ForgotPasswordPage()} passHref>
<a>Forgot your password?</a>
<Link href={Routes.ForgotPasswordPage()}>
Forgot your password?
</Link>
</div>
</Form>
<div style={{ marginTop: "1rem" }}>
Or{" "}
<Link href={Routes.SignupPage()} passHref>
<a>Sign Up</a>
<Link href={Routes.SignupPage()}>
Sign Up
</Link>
</div>
</div>

View File

@@ -38,15 +38,11 @@ const UserInfo = () => {
} else {
return (
<>
<Link href={Routes.SignupPage()} passHref>
<a className="button small">
<strong>Sign Up</strong>
</a>
<Link href={Routes.SignupPage()}className="button small">
<strong>Sign Up</strong>
</Link>
<Link href={Routes.LoginPage()} passHref>
<a className="button small">
<strong>Login</strong>
</a>
<Link href={Routes.LoginPage()} className="button small">
<strong>Login</strong>
</Link>
</>
)
@@ -90,10 +86,7 @@ const Home: BlitzPage = () => {
<code>blitz dev</code>
</pre>
<p>
and go to{" "}
<Link href="/projects">
<a>/projects</a>
</Link>
and go to <Link href="/projects">/projects</Link>
</p>
</div>
<div className="buttons" style={{ marginTop: "5rem" }}>

View File

@@ -30,10 +30,10 @@
"@blitzjs/rpc": "workspace:*",
"@hookform/error-message": "2.0.0",
"@hookform/resolvers": "2.9.10",
"@prisma/client": "4.6.0",
"blitz": "workspace:2.0.0-beta.22",
"@prisma/client": "4.6.1",
"blitz": "workspace:2.0.0-beta.23",
"next": "12.2.5",
"prisma": "4.6.0",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hook-form": "7.39.1",

View File

@@ -40,16 +40,16 @@ export const LoginForm = (props: LoginFormProps) => {
<LabeledTextField name="email" label="Email" placeholder="Email" />
<LabeledTextField name="password" label="Password" placeholder="Password" type="password" />
<div>
<Link href={Routes.ForgotPasswordPage()} passHref>
<a>Forgot your password?</a>
<Link href={Routes.ForgotPasswordPage()}>
Forgot your password?
</Link>
</div>
</Form>
<div style={{ marginTop: "1rem" }}>
Or{" "}
<Link href={Routes.SignupPage()} passHref>
<a>Sign Up</a>
<Link href={Routes.SignupPage()}>
Sign Up
</Link>
</div>
</div>

View File

@@ -1,6 +1,6 @@
import { ErrorFallbackProps, ErrorComponent, ErrorBoundary, AppProps } from "@blitzjs/next"
import { AuthenticationError, AuthorizationError } from "blitz"
import React from "react"
import "src/styles/globals.css"
import { withBlitz } from "src/blitz-client"
function RootErrorFallback({ error }: ErrorFallbackProps) {

View File

@@ -10,14 +10,10 @@ import { useMutation } from "@blitzjs/rpc"
import Link from "next/link"
const ResetPasswordPage: BlitzPage = () => {
const [token, setToken] = useState("")
const router = useRouter()
const token = router.query.token?.toString()
const [resetPasswordMutation, { isSuccess }] = useMutation(resetPassword)
useEffect(() => {
setToken(router.query.token as string)
}, [router.isReady])
return (
<div>
<h1>Set a New Password</h1>

View File

@@ -1,12 +1,11 @@
import { Suspense } from "react"
import Image from "next/image"
import Link from "next/link"
import Layout from "src/core/layouts/Layout"
import { useCurrentUser } from "src/users/hooks/useCurrentUser"
import logout from "src/auth/mutations/logout"
import logo from "public/logo.png"
import { useMutation } from "@blitzjs/rpc"
import { Routes, BlitzPage } from "@blitzjs/next"
import styles from "src/styles/Home.module.css"
/*
* This file is just for a pleasant getting started page for your new app.
@@ -21,7 +20,7 @@ const UserInfo = () => {
return (
<>
<button
className="button small"
className={styles.button}
onClick={async () => {
await logoutMutation()
}}
@@ -38,15 +37,11 @@ const UserInfo = () => {
} else {
return (
<>
<Link href={Routes.SignupPage()} passHref>
<a className="button small">
<strong>Sign Up</strong>
</a>
<Link href={Routes.SignupPage()} className={styles.button}>
<strong>Sign Up</strong>
</Link>
<Link href={Routes.LoginPage()} passHref>
<a className="button small">
<strong>Login</strong>
</a>
<Link href={Routes.LoginPage()} className={styles.loginButton}>
<strong>Login</strong>
</Link>
</>
)
@@ -56,216 +51,142 @@ const UserInfo = () => {
const Home: BlitzPage = () => {
return (
<Layout title="Home">
<div className="container">
<main>
<div className="logo">
<Image src={`${logo.src}`} alt="blitzjs" width="256px" height="118px" layout="fixed" />
</div>
<div className={styles.globe} />
<div className={styles.container}>
<div className={styles.toastContainer}>
<p>
<strong>Congrats!</strong> Your app is ready, including user sign-up and log-in.
</p>
<div className="buttons" style={{ marginTop: "1rem", marginBottom: "1rem" }}>
<Suspense fallback="Loading...">
<UserInfo />
</Suspense>
</div>
<p>
<strong>
To add a new model to your app, <br />
run the following in your terminal:
</strong>
</p>
<pre>
<code>blitz generate all project name:string</code>
</pre>
<div style={{ marginBottom: "1rem" }}>(And select Yes to run prisma migrate)</div>
<div>
<p>
Then <strong>restart the server</strong>
</p>
<pre>
<code>Ctrl + c</code>
</pre>
<pre>
<code>blitz dev</code>
</pre>
<p>
and go to{" "}
<Link href="/projects">
<a>/projects</a>
</Link>
</p>
</div>
<div className="buttons" style={{ marginTop: "5rem" }}>
<a
className="button"
href="https://blitzjs.com/docs/getting-started?utm_source=blitz-new&utm_medium=app-template&utm_campaign=blitz-new"
target="_blank"
rel="noopener noreferrer"
>
Documentation
</a>
<a
className="button-outline"
href="https://github.com/blitz-js/blitz"
target="_blank"
rel="noopener noreferrer"
>
Github Repo
</a>
<a
className="button-outline"
href="https://discord.blitzjs.com"
target="_blank"
rel="noopener noreferrer"
>
Discord Community
</a>
</div>
<main className={styles.main}>
<div className={styles.wrapper}>
<div className={styles.header}>
<div className={styles.logo}>
<svg viewBox="0 0 165 66">
<path d="M104.292 56.033C104.292 56.408 104.206 56.6636 104.036 56.8C103.9 56.9363 103.627 57.0045 103.218 57.0045H99.7409C99.4001 57.0045 99.1615 56.9533 99.0251 56.8511C98.8888 56.7147 98.8206 56.4932 98.8206 56.1864L98.9229 19.8324C98.9229 19.3211 99.1444 19.0654 99.5876 19.0654H103.627C103.839 19.0654 104.292 19.0672 104.292 19.0672V19.8324V56.033ZM64.3531 57.0081C64.1145 57.0081 63.927 56.9399 63.7906 56.8035C63.6543 56.6672 63.5861 56.4968 63.5861 56.2922V19.9383C63.5861 19.3588 63.8588 19.069 64.4042 19.069H76.829C81.533 19.069 85.1463 19.9212 87.6687 21.6256C90.1912 23.2958 91.4524 25.7331 91.4524 28.9373C91.4524 30.9484 90.924 32.6528 89.8673 34.0504C88.8106 35.4138 87.1063 36.5217 84.7543 37.3739C84.6179 37.4079 84.5497 37.4932 84.5497 37.6295C84.5497 37.7318 84.6179 37.7999 84.7543 37.834C87.2767 38.5158 89.1686 39.5895 90.4298 41.0553C91.7251 42.521 92.3727 44.4469 92.3727 46.833C92.3727 50.2418 91.0945 52.7983 88.5379 54.5027C85.9814 56.1729 82.2318 57.0081 77.2892 57.0081H64.3531ZM77.5448 35.5843C79.6923 35.5843 81.516 35.1071 83.0158 34.1526C84.5157 33.1982 85.2656 31.6983 85.2656 29.6531C85.2656 27.6079 84.5157 26.0569 83.0158 25.0002C81.5501 23.9435 79.5219 23.4151 76.9313 23.4151H70.5399C70.0286 23.4151 69.7729 23.6367 69.7729 24.0798V34.8684C69.7729 35.3457 69.9604 35.5843 70.3354 35.5843H77.5448ZM77.0335 52.662C82.9647 52.662 85.9303 50.5997 85.9303 46.4751C85.9303 44.3276 85.1633 42.7255 83.6294 41.6688C82.0955 40.6121 80.0673 40.0838 77.5448 40.0838H70.591C70.2843 40.0838 70.0627 40.1349 69.9263 40.2372C69.8241 40.3394 69.7729 40.5099 69.7729 40.7485V51.895C69.7729 52.4063 69.9604 52.662 70.3354 52.662H77.0335ZM142.707 56.8624C142.81 56.9647 142.997 57.0158 143.27 57.0158H163.876C164.387 57.0158 164.643 56.7772 164.643 56.3V53.948V53.3344H163.978H149.866C149.593 53.3344 149.457 53.2492 149.457 53.0788C149.457 52.9765 149.508 52.8572 149.61 52.7208L163.876 33.8536C164.251 33.2741 164.438 32.7628 164.438 32.3197V30.479V29.9144C164.438 29.9144 164.051 29.9165 163.876 29.9165H144.241C143.866 29.9165 143.679 30.121 143.679 30.5301V32.831C143.679 33.1037 143.713 33.2911 143.781 33.3934C143.883 33.4957 144.071 33.5468 144.344 33.5468H157.075C157.382 33.5468 157.535 33.632 157.535 33.8025L157.382 34.1092L143.219 52.9765C142.946 53.3515 142.759 53.6412 142.656 53.8457C142.588 54.0502 142.554 54.3059 142.554 54.6127V56.3C142.554 56.5727 142.605 56.7602 142.707 56.8624ZM116.929 19.0676H111.51V27.7684C114.503 27.7684 116.929 25.3419 116.929 22.3486V19.0676ZM116.926 56.0308C116.926 56.4058 116.841 56.6614 116.67 56.7978C116.534 56.9341 116.278 57.0023 115.903 57.0023H112.427C112.086 57.0023 111.847 56.9512 111.711 56.8489C111.574 56.7126 111.506 56.491 111.506 56.1842V30.6699C111.506 30.3972 111.557 30.2098 111.66 30.1075C111.762 29.9712 111.949 29.903 112.222 29.903H117.028L116.926 56.0308ZM132.183 34.3137C132.183 33.9728 132.336 33.8024 132.643 33.8024H138.779C139.256 33.8024 139.495 33.5979 139.495 33.1888V30.4789V29.9165H138.881H132.745C132.439 29.9165 132.285 29.7631 132.285 29.4563V21.531V20.713L131.621 20.7129H128.093C127.752 20.7129 127.547 20.9515 127.479 21.4288L126.865 29.4563C126.865 29.7631 126.729 29.9165 126.456 29.9165H122.366C121.957 29.9165 121.752 30.1039 121.752 30.4789V33.1888C121.752 33.5979 121.974 33.8024 122.417 33.8024H126.252C126.593 33.8024 126.763 34.0069 126.763 34.416V50.6244C126.763 52.806 127.309 54.4252 128.399 55.4819C129.49 56.5045 131.16 57.0158 133.41 57.0158C135.796 57.0158 137.535 56.9306 138.625 56.7601C139.137 56.6579 139.392 56.3681 139.392 55.8909V53.6923V53.0787H138.779H135.507C134.348 53.0787 133.495 52.806 132.95 52.2606C132.439 51.7152 132.183 50.7267 132.183 49.295V34.3137Z"></path>
<path d="M0.241243 33.2639H10.9742C15.0585 33.2639 18.9054 35.1835 21.3612 38.4471L31.9483 52.5165C32.1484 52.7824 32.1786 53.1393 32.026 53.435L25.9232 65.2592C25.6304 65.8265 24.8455 65.8932 24.4612 65.3835L0.241243 33.2639Z"></path>
<path d="M42.4727 33.2822H31.7398C27.6555 33.2822 23.8086 31.3626 21.3528 28.0991L10.7656 14.0297C10.5656 13.7638 10.5354 13.4068 10.688 13.1111L16.7908 1.28696C17.0836 0.719654 17.8684 0.652924 18.2528 1.16266L42.4727 33.2822Z"></path>
</svg>
</div>
<h1>Your database & authentication is ready. Try it by signing up.</h1>
{/* Auth */}
<div className={styles.buttonContainer}>
<Suspense fallback="Loading...">
<UserInfo />
</Suspense>
</div>
</div>
<div className={styles.body}>
{/* Instructions */}
<div className={styles.instructions}>
<p>
<strong>Add a new model by running the following in your terminal:</strong>
</p>
<div>
<div className={styles.code}>
<span>1</span>
<pre>
<code>blitz generate all project</code>
</pre>
</div>
<div className={styles.code}>
<span>2</span>
<pre>
<code>Ctrl + c</code>
</pre>
</div>
<div className={styles.code}>
<span>3</span>
<pre>
<code>blitz dev</code>
</pre>
</div>
<div className={styles.code}>
<span>4</span>
<pre>
<code>
Go to{" "}
<Link href="/projects" className={styles.textLink}>
/projects
</Link>
</code>
</pre>
</div>
</div>
</div>
{/* Links */}
<div className={styles.linkGrid}>
<a
href="https://blitzjs.com/docs/getting-started?utm_source=blitz-new&utm_medium=app-template&utm_campaign=blitz-new"
target="_blank"
rel="noopener noreferrer"
className={styles.card}
>
Blitz Docs
<span className={styles.arrowIcon} />
</a>
<a
href="https://nextjs.org/docs/getting-started"
target="_blank"
rel="noopener noreferrer"
className={styles.card}
>
Next.js Docs
<span className={styles.arrowIcon} />
</a>
<a
href="https://github.com/blitz-js/blitz"
target="_blank"
rel="noopener noreferrer"
className={styles.card}
>
Github Repo
<span className={styles.arrowIcon} />
</a>
<a
href="https://twitter.com/blitz_js"
target="_blank"
rel="noopener noreferrer"
className={styles.card}
>
Blitz Twitter
<span className={styles.arrowIcon} />
</a>
<a
href="https://discord.blitzjs.com"
target="_blank"
rel="noopener noreferrer"
className={styles.card}
>
Discord Community
<span className={styles.arrowIcon} />
</a>
</div>
</div>
</div>
</main>
<footer>
<footer className={styles.footer}>
<span>Powered by</span>
<a
href="https://blitzjs.com?utm_source=blitz-new&utm_medium=app-template&utm_campaign=blitz-new"
target="_blank"
rel="noopener noreferrer"
className={styles.textLink}
>
Powered by Blitz.js
Blitz.js
</a>
</footer>
<style jsx global>{`
@import url("https://fonts.googleapis.com/css2?family=Libre+Franklin:wght@300;700&display=swap");
html,
body {
padding: 0;
margin: 0;
font-family: "Libre Franklin", -apple-system, BlinkMacSystemFont, Segoe UI, Roboto,
Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
* {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
box-sizing: border-box;
}
.container {
min-height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
main {
padding: 5rem 0;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
main p {
font-size: 1.2rem;
}
p {
text-align: center;
}
footer {
width: 100%;
height: 60px;
border-top: 1px solid #eaeaea;
display: flex;
justify-content: center;
align-items: center;
background-color: #45009d;
}
footer a {
display: flex;
justify-content: center;
align-items: center;
}
footer a {
color: #f4f4f4;
text-decoration: none;
}
.logo {
margin-bottom: 2rem;
}
.logo img {
width: 300px;
}
.buttons {
display: grid;
grid-auto-flow: column;
grid-gap: 0.5rem;
}
.button {
font-size: 1rem;
background-color: #6700eb;
padding: 1rem 2rem;
color: #f4f4f4;
text-align: center;
}
.button.small {
padding: 0.5rem 1rem;
}
.button:hover {
background-color: #45009d;
}
.button-outline {
border: 2px solid #6700eb;
padding: 1rem 2rem;
color: #6700eb;
text-align: center;
}
.button-outline:hover {
border-color: #45009d;
color: #45009d;
}
pre {
background: #fafafa;
border-radius: 5px;
padding: 0.75rem;
text-align: center;
}
code {
font-size: 0.9rem;
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
Bitstream Vera Sans Mono, Courier New, monospace;
}
.grid {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
max-width: 800px;
margin-top: 3rem;
}
@media (max-width: 600px) {
.grid {
width: 100%;
flex-direction: column;
}
}
`}</style>
</div>
</Layout>
)

View File

@@ -0,0 +1,304 @@
.container {
display: flex;
flex-direction: column;
height: 100vh;
}
.main {
flex: 1;
padding: 0rem 1rem;
display: flex;
flex-direction: column;
justify-content: space-evenly;
}
.wrapper {
display: flex;
flex-direction: column;
gap: 2rem;
}
.frost {
background: rgba(255, 255, 255, 0.2);
border-radius: 16px;
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
backdrop-filter: blur(5px);
-webkit-backdrop-filter: blur(5px);
border: 1px solid rgba(255, 255, 255, 0.31);
}
.header {
display: flex;
flex-direction: column;
padding: 4rem 0rem 2rem 0rem;
text-align: center;
gap: 2rem;
}
.header h1 {
max-width: 620px;
align-self: center;
}
.body {
composes: frost;
border-radius: var(--border-radius);
display: flex;
padding: 1rem;
width: 100%;
flex-direction: row;
align-self: center;
max-width: calc(min(var(--screen-width), 700px));
}
.instructions {
display: inline-flex;
flex-direction: column;
padding: 1rem;
width: 100%;
}
.globe {
position: fixed;
width: 350vmin;
height: 75vmin;
left: 20%;
top: 50%;
transform: translate(-50%, calc(-50% + 40px));
z-index: -1;
border-radius: 100%;
background-image: radial-gradient(
95.63% 95.63% at 95.92% 0%,
rgba(255, 255, 255, 0.62) 0%,
#8155ff38 60.42%,
#002fff5c 169%
);
filter: blur(8vmin);
}
.footer {
display: flex;
padding: 2rem 0;
justify-content: center;
align-items: center;
}
.footer span {
margin-right: 0.2rem;
}
.code {
display: flex;
align-items: center;
gap: 0.5rem;
}
.code span {
background: rgba(124, 58, 237, 50%);
border-radius: 50rem;
font-size: 14px;
font-weight: 500;
padding: 17px;
width: 20px;
height: 20px;
display: flex;
align-items: center;
justify-content: center;
color: rgb(57, 33, 97);
}
.code pre {
background: rgba(124, 58, 237, 12%);
border-radius: 4px;
padding: 0.7em 1.4em;
text-align: center;
}
.code code {
font-size: 0.86em;
font-weight: bold;
color: rgb(124, 58, 237);
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
Bitstream Vera Sans Mono, Courier New, monospace;
}
.toastContainer {
border: 1px solid #edff;
padding: 0 1rem;
background: #eeff;
color: #62af;
text-align: center;
}
.toastContainer strong {
color: rgb(124, 58, 237);
}
.textLink {
color: rgb(124, 58, 237);
background: linear-gradient(to right, rgba(231, 216, 246, 1), rgba(231, 216, 246, 1)),
linear-gradient(to right, rgba(99, 1, 235, 1), rgba(124, 58, 237, 1), rgba(231, 216, 246, 1));
background-size: 100% 1px, 0 1px;
background-position: 100% 100%, 0 100%;
background-repeat: no-repeat;
transition: background-size 400ms;
}
.textLink:hover,
.textLink:focus,
.textLink:active {
background-size: 0 1px, 100% 1px;
}
.arrowIcon {
box-sizing: border-box;
display: block;
width: 8px;
height: 8px;
border-top: 2px solid;
transform: scale(var(--ggs, 1));
border-right: 2px solid;
position: absolute;
right: 6px;
top: 6px;
color: #b1a5c4;
}
.arrowIcon::after {
content: "";
display: block;
box-sizing: border-box;
position: absolute;
width: 8px;
height: 2px;
background: currentColor;
transform: rotate(-45deg);
top: 2px;
right: -1px;
}
.buttonContainer {
display: flex;
flex-direction: row;
gap: 1rem;
justify-content: center;
align-items: center;
flex: 1;
}
.button {
background: linear-gradient(to top, rgb(124, 58, 237), rgb(117, 81, 236));
border: 1px solid rgb(231, 216, 246);
color: white;
text-shadow: rgba(0, 0, 0, 0.25) 0px 3px 8px;
padding: 0 24px;
height: 48px;
width: 200px;
max-width: 300px;
position: relative;
display: inline-flex;
justify-content: center;
align-items: center;
flex-shrink: 0;
user-select: none;
white-space: nowrap;
border-radius: 0.75rem;
border-bottom-left-radius: 0px;
font-size: 15px;
transition: all 0.3s ease 0s;
cursor: pointer;
}
.button:hover {
color: white;
text-shadow: rgb(0 0 0 / 56%) 0px 3px 12px;
box-shadow: rgb(80 63 205 / 50%) 0px 1px 40px;
}
.loginButton {
composes: button;
background: rgb(248 250 252);
border: 1px solid rgb(231, 216, 246);
color: rgb(30 41 59);
text-shadow: none;
}
.loginButton:hover {
color: rgb(30 41 59);
text-shadow: none;
}
.card:hover .arrowIcon {
color: #7450ec;
}
.linkGrid {
display: flex;
flex-direction: column;
flex-wrap: wrap;
gap: 1rem;
}
.card {
composes: frost;
padding: 1rem 0rem;
text-align: center;
color: inherit;
text-decoration: none;
border-radius: 10px;
border-bottom-left-radius: 0px;
transition: color 0.15s ease, border-color 0.15s ease;
max-width: 200px;
min-width: 200px;
display: flex;
flex-direction: row;
justify-content: center;
}
.card:hover,
.card:focus,
.card:active {
color: #7450ec;
border-color: #7450ec;
}
.card h2 {
margin: 0 0 1rem 0;
font-size: 1.5rem;
}
.card p {
margin: 0;
font-size: 1.25rem;
line-height: 1.5;
}
.logo {
flex: 1;
padding: 1rem 2rem;
}
.logo svg {
height: 100%;
width: 200px;
fill: #7450ec;
}
/* MOBILE */
@media (max-width: 800px) {
.linkGrid {
width: 100%;
}
.card {
max-width: 100%;
}
.body {
flex-wrap: wrap;
}
.buttonContainer {
flex-wrap: wrap;
}
}

View File

@@ -0,0 +1,25 @@
:root {
--border-radius: 0.75rem;
--screen-width: 90vmin;
}
html,
body {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell,
Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
}
a {
color: inherit;
text-decoration: none;
}
i {
font-size: 0.8rem;
}
* {
box-sizing: border-box;
}

View File

@@ -14,7 +14,7 @@ vi.mock("public/logo.png", () => ({
test.skip("renders blitz documentation link", () => {
// This is an example of how to ensure a specific item is in the document
// But it's disabled by default (by test.skip) so the test doesn't fail
// when you remove the the default content from the page
// when you remove the default content from the page
// This is an example on how to mock api hooks when testing
vi.mock("src/users/hooks/useCurrentUser", () => ({
@@ -27,6 +27,6 @@ test.skip("renders blitz documentation link", () => {
}))
const { getByText } = render(<Home />)
const linkElement = getByText(/Documentation/i)
const linkElement = getByText(/Blitz Docs/i)
expect(linkElement).toBeInTheDocument()
})

View File

@@ -20,7 +20,7 @@
"@blitzjs/config": "workspace:*",
"@blitzjs/next": "workspace:*",
"@blitzjs/rpc": "workspace:*",
"@prisma/client": "4.6.0",
"@prisma/client": "4.6.1",
"@types/jest": "29.2.2",
"@types/passport-twitter": "1.0.37",
"blitz": "workspace:*",
@@ -29,7 +29,7 @@
"next": "12.2.5",
"passport-mock-strategy": "2.0.0",
"passport-twitter": "1.0.4",
"prisma": "4.6.0",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"ts-node": "10.9.1"

BIN
docs/.github/screenshot.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 KiB

2
docs/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
.next
node_modules

21
docs/LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Shu Ding
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

23
docs/README.md Normal file
View File

@@ -0,0 +1,23 @@
# Nextra Docs Template
This is a template for creating documentation with [Nextra](https://nextra.site).
[**Live Demo →**](https://nextra-docs-template.vercel.app)
[![](.github/screenshot.png)](https://nextra-docs-template.vercel.app)
## Quick Start
Click the button to clone this repository and deploy it on Vercel:
[![](https://vercel.com/button)](https://vercel.com/new/clone?s=https%3A%2F%2Fgithub.com%2Fshuding%2Fnextra-docs-template&showOptionalTeamCreation=false)
## Local Development
First, run `pnpm i` to install the dependencies.
Then, run `pnpm dev` to start the development server and visit localhost:3000.
## License
This project is licensed under the MIT License.

5
docs/next-env.d.ts vendored Normal file
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.

14
docs/next.config.js Normal file
View File

@@ -0,0 +1,14 @@
const remarkShikiTwoslash = require('remark-shiki-twoslash')
const withNextra = require('nextra')({
theme: 'nextra-theme-docs',
themeConfig: './theme.config.tsx',
// Not working yet
remarkPlugins: [
[
remarkShikiTwoslash
]
]
})
module.exports = withNextra()

43
docs/package.json Normal file
View File

@@ -0,0 +1,43 @@
{
"name": "nextra-docs-template",
"version": "0.0.1",
"description": "Nextra docs template",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
},
"repository": {
"type": "git",
"url": "git+https://github.com/shuding/nextra-docs-template.git"
},
"author": "Shu Ding <g@shud.in>",
"license": "MIT",
"bugs": {
"url": "https://github.com/shuding/nextra-docs-template/issues"
},
"homepage": "https://github.com/shuding/nextra-docs-template#readme",
"dependencies": {
"@blitzjs/auth": "workspace:2.0.0-beta.23",
"@blitzjs/next": "workspace:2.0.0-beta.23",
"@blitzjs/rpc": "workspace:2.0.0-beta.23",
"@mdx-js/loader": "2.3.0",
"@mdx-js/react": "2.3.0",
"@next/mdx": "13.2.3",
"@octokit/rest": "19.0.7",
"blitz": "workspace:2.0.0-beta.23",
"next": "^13.0.6",
"nextra": "latest",
"nextra-theme-docs": "latest",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"remark-shiki-twoslash": "3.1.1"
},
"devDependencies": {
"@types/node": "18.11.10",
"autoprefixer": "10.4.13",
"postcss": "8.4.21",
"tailwindcss": "3.2.7",
"typescript": "^4.9.3"
}
}

2172
docs/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

6
docs/postcss.config.js Normal file
View File

@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

View File

@@ -0,0 +1,6 @@
.counter {
border: 1px solid #ccc;
border-radius: 5px;
padding: 2px 6px;
margin: 12px 0 0;
}

View File

@@ -0,0 +1,24 @@
// Example from https://beta.reactjs.org/learn
import { useState } from 'react'
import styles from './counters.module.css'
function MyButton() {
const [count, setCount] = useState(0)
function handleClick() {
setCount(count + 1)
}
return (
<div>
<button onClick={handleClick} className={styles.counter}>
Clicked {count} times
</button>
</div>
)
}
export default function MyApp() {
return <MyButton />
}

5
docs/src/pages/_app.mdx Normal file
View File

@@ -0,0 +1,5 @@
import "../styles/nextra.css";
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
}

38
docs/src/pages/_meta.json Normal file
View File

@@ -0,0 +1,38 @@
{
"index": {
"title": "Home",
"theme": {
"layout": "raw"
}
},
"docs": {
"title": "Documentation",
"type": "page"
},
"tutorial": {
"title": "Tutorial",
"type": "page"
},
"showcase": {
"title": "Showcase",
"type": "page"
},
"releases": {
"title": "Releases ↗",
"type": "page",
"href": "https://github.com/blitz-js/blitz/releases",
"newWindow": true
},
"swag": {
"title": "Swag ↗",
"type": "page",
"href": "https://store.blitzjs.com/",
"newWindow": true
},
"deploy": {
"title": "Deploy With Flightcontrol ↗",
"type": "page",
"href": "https://flightcontrol.dev/?ref=blitzjs",
"newWindow": true
}
}

View File

@@ -0,0 +1,44 @@
{
"introduction": "Introduction",
"community": "Community",
"basics": "Basics",
"framweworks": "Framework Adapters",
"blitz-auth": "Blitz Auth",
"blitz-rpc": "Blitz RPC",
"blitz-recipies": "Blitz Recipies",
"blitz-generator": "Blitz Generator",
"backend-architecture": "Backend Architecture",
"databse": "Database",
"cli" : "CLI",
"migration":"Migration Guides",
"docs": {
"title": "Documentation",
"type": "page"
},
"tutorial": {
"title": "Tutorial",
"type": "page"
},
"showcase": {
"title": "Showcase",
"type": "page"
},
"releases": {
"title": "Releases ↗",
"type": "page",
"href" : "https://github.com/blitz-js/blitz/releases",
"newWindow": true
},
"swag": {
"title": "Swag ↗",
"type": "page",
"href" : "https://store.blitzjs.com/",
"newWindow": true
},
"deploy": {
"title": "Deploy With Flightcontrol ↗",
"type": "page",
"href": "https://flightcontrol.dev/?ref=blitzjs",
"newWindow": true
}
}

View File

@@ -0,0 +1,9 @@
{
"how-the-community-operates": "How the Community Operates",
"manifesto": "Manifesto",
"history": "History",
"contributing": "How to Contribute",
"maintainers": "Being a Maintainers",
"code-of-conduct": "Code of Conduct",
"translations": "Doc Translations"
}

View File

@@ -0,0 +1,111 @@
# The Blitz Community Code of Conduct
The Blitz core members take this CoC very serious. All members,
contributors and volunteers in this community are required to act
according to the following Code of Conduct to keep Blitz a positive,
growing project and community and help us provide and ensure a safe
environment for everyone.
## When Something Happens
If you see a Code of Conduct violation, follow these steps:
1. Let the person know that what they did is not appropriate and ask them
to stop and/or edit their message(s).
2. That person should immediately stop the behavior and correct the issue.
3. If this doesnt happen, or if youre uncomfortable speaking up, contact
Brandon Bayer ([Twitter](https://twitter.com/flybayer) |
[Email](mailto:b@bayer.ws)).
When reporting, please include any relevant details, links, screenshots,
context, or other information that may be used to better understand and
resolve the situation.
The core members will prioritize the well-being and comfort of the
recipients of the violation over the comfort of the violator.
## What We Believe and How We Act
- We are committed to providing a friendly, safe and welcoming environment
for everyone, regardless of age, body size, culture, ethnicity, gender
expression, gender identity, level of experience, nationality, personal
ability or disability, physical appearance, physical or mental
difference, race, religion, set of skills, sexual orientation,
socio-economic status, and subculture. We welcome people regardless of
these or other attributes.
- We are better together. We are more alike than different.
- Our community is based on mutual respect, tolerance, and encouragement.
- We believe that a diverse community where people treat each other with
respect is stronger, more vibrant and has more potential contributors
and more sources for ideas. We aim for more diversity.
- We are kind, welcoming and courteous to everyone.
- Were respectful of others, their positions, their skills, their
commitments and their efforts.
- Were attentive in our communications, whether in person or online, and
were tactful when approaching differing views.
- We are aware that language shapes reality. Thus, we use inclusive,
gender-neutral language in the documents we provide and when we talk to
people. When referring to a group of people, we aim to use
gender-neutral terms like “team”, “folks”, “everyone”. (For details, we
recommend
[this post](https://modelviewculture.com/pieces/gendered-language-feature-or-bug-in-software-documentation)).
- We respect that people have differences of opinion and criticize
constructively.
- We value people over code.
## Don'ts
- Dont discriminate against anyone.
- Sexism and racism of any kind (including sexist and racist “jokes”),
demeaning or insulting behaviour and harassment are seen as direct
violations to this Code of Conduct. Harassment includes offensive verbal
comments related to age, body size, culture, ethnicity, gender
expression, gender identity, level of experience, nationality, personal
ability or disability, physical appearance, physical or mental
difference, race, religion, set of skills, sexual orientation,
socio-economic status, and subculture. Harassment also includes sexual
images in public spaces, deliberate intimidation, stalking, following,
harassing photography or recording, inappropriate physical contact, and
unwelcome sexual attention.
- On Discord and other online or offline communications channels, don't
use overtly sexual nicknames or other nicknames that might detract from
a friendly, safe and welcoming environment for all.
- Dont be mean or rude.
- Respect that some individuals and cultures consider the casual use of
profanity offensive and off-putting.
- Unwelcome / non-consensual sexual advances over Discord or any other
channels related with this community are not okay.
- Derailing, tone arguments and otherwise playing on peoples desires to
be nice are not welcome, especially in discussions about violations to
this Code of Conduct.
- Please avoid unstructured critique.
- Likewise any spamming, trolling, flaming, baiting or other
attention-stealing behavior is not welcome.
- Sponsors of Blitz are also subject to this Code of Conduct. In
particular, sponsors are required to not use sexualized images,
activities, or other material which is not according to this Code of
Conduct.
## Consequences for Violations to this Code of Conduct
If a participant engages in any behavior violating this Code of Conduct,
the core members of this community will take any action they deem
appropriate, starting with a gentle warning and then escalating as needed
to expulsion from the community, exclusion from any interaction and loss
of all rights in this community.
## Decisions About Consequences of Violations
Decisions about consequences of violations of this Code of Conduct are
made by this communitys core members and may not be discussed with the
person responsible for the violation.
## For Questions or Feedback
If you have any questions or feedback on this Code of Conduct, were happy
to hear from you.
## Thanks for Inspiration
- [Hoodie](https://github.com/hoodiehq/hoodie)
- [WeAllJS](https://wealljs.org/code-of-conduct)

View File

@@ -0,0 +1,268 @@
# How to Contribute
import { Callout, Tab, Tabs, Steps } from 'nextra-theme-docs'
👋 We're so excited you're interested in helping with Blitz! We happy to
help you get started, even if you don't have any previous open-source
experience
## First Things First
1. New to open source? take a look at
[How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github)
2. Familiarize yourself with the
[Blitz Code of Conduct](./code-of-conduct)
3. Learn [how the community operates](./how-the-community-operates)
## What to Work On?
Issues with the label
[`status/ready-to-work-on`](https://github.com/blitz-js/blitz/labels/status%2Fready-to-work-on)
are the best place to start.
We also label issues as `good first issue` and `good second issue` when
appropriate.
If you find one that looks interesting and no one else is already working
on it, comment in the issue that you are going to work on it. But only
claim an issue if you can start work on it within a couple days.
Please ask as many questions as you need, either directly in the issue or
in Discord. We're happy to help!
The Blitzjs.com website and documentation repo also has issues with
[`ready to work on | help wanted`](https://github.com/blitz-js/blitzjs.com/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22ready+to+work+on+%7C+help+wanted%22).
### Things that are ALWAYS welcome
- Adding tests
- Improved documentation
- Improved error messages
- Improved logging (i.e. more clear, more beautiful)
- Performance or security improvements
- Educational content like blogs, videos, courses
If there's some other way you'd like to contribute, ask us about it in
Discord!
After you contribute in any way, please add yourself as a contributor via
the
[@all-contributors bot](https://allcontributors.org/docs/en/bot/usage)!
## Our Codebase is a Garden
The Blitz codebase is like a community garden. There's a lot of beautiful
plants and vegetables, but it won't take long until you find some weeds!
When you find weeds, please remove them. Minor refactoring is always
encouraged. If you'd like to do some major refactoring, it's best to first
either open an issue or check with us in Discord. Most likely we'll agree
with you.
## What to Expect After Submitting a PR
A Blitz maintainer will review your PR, usually within a couple days.
If your PR changes user facing code, make sure you also made a PR to the
docs repo, otherwise this will block your PR from being merged.
You also need to add tests to cover the changes you made.
Once all the requirements are met and the maintainer is happy with your
code, they will merge it to the canary branch. It will then be included in
the next Blitz release.
Lastly, you will be added the all-contributors list as an official Blitz
contributor. **Congratulations!!**
## Project Management
We use a
[GitHub Project Board](https://github.com/blitz-js/blitz/projects/4) to
track all issues and PRs.
## Commit Access
We give liberal commit access to the Blitz repo to anyone who is a
half-way regular contributor. This allows you to push branches directly to
the Blitz repo without using a fork.
We'll often give someone access if we notice they are regularly
contributing. But you're also welcome to ask for access if you are
regularly helping but haven't been given access yet.
In the main Blitz repo, code reviews by code owners are required to merge
PRs.
But in the docs repo, anyone can merge PRs once someone else has approved
the PR.
## Development Setup
Make sure you're using Node 14 — Next uses `node-sass` which does not work
with newer Node versions.
<Steps>
### Fork [the blitz repo](https://github.com/blitz-js/blitz)
### Clone your forked repo
```sh
# replace USERNAME below with your GitHub username
git clone git@github.com:USERNAME/blitz.git
cd blitz
```
### (Optional, macOS only) Install required packages for
`sodium-native`
If you spot any issues related to `sodium-native`, run the following
command to fix it:
```sh
brew install autoconf automake
```
### Install dependencies
```sh
pnpm i
```
### Start the package server. This **must be running** for any package
development or example development
```sh
pnpm dev
```
</Steps>
## Running Tests
### Blitz.js Tests
#### Unit Tests
Most Blitz packages in `packages/` have vitest unit tests.
- Run tests in a single package by running `pnpm test` inside that package
folder (like `packages/blitz-next`)
- Run all unit tests from the repo root by running `pnpm test`. (Make sure
you have ran `pnpm build` or `pnpm dev` prior to running this). Note:
this will run all tests, including integration tests.
#### Integration Tests
Blitz integration tests are inside the root `integration-tests/` folder.
Make sure you have `chromedriver` installed for your Chrome version. You
can install it with
- `brew install --cask chromedriver` on Mac OS X
- `chocolatey install chromedriver` on Windows
- Or manually download the version that matches your installed chrome
version (if there's no match, download a version under it, but not
above) from the
[chromedriver repo](https://chromedriver.storage.googleapis.com/index.html)
and add the binary to `<blitz-repo>/node_modules/.bin`
You can run all tests (both unit tests and integration tests) by running
`pnpm test` from the repo root.
You can manually run the integration app by running `blitz dev` inside the
integration test folder, like `integration-tests/auth/`.
### Testing Development Version of Blitz Inside an App
<Callout>
Currently, to test the local dev version of Blitz, you can test an app
inside the `blitz/apps/` folder. In there, the blitz dependency will
automatically use the local dev version. We use it for development
testing. You must also make sure you are running `pnpm dev` in the `blitz`
folder at the same time.
</Callout>
#### Link the Blitz CLI (Optional)
The following will link the development CLI as a local binary so you can
use it anywhere for testing.
```sh
pnpm link ./packages/blitz
```
## Doing A Releas
We use the [changesets](https://github.com/changesets/changesets) package
& a forked version of their GitHub action which can be found here:
[GitHub - blitz-js/changesets-action](https://github.com/blitz-js/changesets-action).
Every user facing PR should have a changeset. When that PR gets approved
and merged to the `main` branch the "release" PR with the name
`Version packages (beta)` is automatically created or updated. This PR
updates each internal package's changelog & each blitz package's version
by incrementing it in the `package.json` files.
Once the auto generated PR accumulates enough changesets, It's time to do
a release by merging this PR into the `main` branch. To trigger the
release action, you must squash and merge the PR without waiting for the
requirements to be met, bypassing the branch protections rule. This is
because the CI doesn't run on PR's generated by a github action. Once you
merge this PR, it will generate the release action and publish on npm &
create a release on GitHub.
The auto generated release on GitHub, still requires some manual cleaning.
It's recommended to remove some "fluff" like:
```
Updated dependencies [3b213a3]
@blitzjs/rpc@2.0.0-beta.18
```
It's also important to note, that since we haven't done a stable release
yet that we're in a pre-release mode set with the `changesets` package. So
with that being said, you will need to uncheck the `Set as a pre-release`
checkbox while editing the release on Github, and selecting
`Set as the latest release` checkbox.
While on the category of being in prerelease mode with the `changesets`
package, when published to npm we also want to ensure that each package
gets tagged with `latest`. This requires manual work and the correct npm
permissions. _This is mostly for our internal team._ For each package run:
```shell
npm dist-tag add blitz@2.0.0-beta.18 latest
npm dist-tag add @blitzs/auth@2.0.0-beta.18 latest
npm dist-tag add @blitzs/rpc@2.0.0-beta.18 latest
npm dist-tag add @blitzs/next@2.0.0-beta.18 latest
```
For more information about `changesets` pre-release mode, you can read
their documentation here:
[changesets/prereleases.md at main · changesets/changesets · GitHub](https://github.com/changesets/changesets/blob/main/docs/prereleases.md)
## Troubleshooting
If you run into issues that should be documented here, please submit a PR!
❤️
#### Git errors
Are you unable to commit? Do you get errors like `command not found` or
`stdin is not a tty`? That's probably a Husky error! Try checking their
[troubleshoot guide](https://typicode.github.io/husky/#/?id=troubleshoot).
#### Preconstruct errors
If you run into symlink and EPERM errors when trying to run Preconstruct
on Windows, you may need to enable
[Windows Developer Mode](https://www.howtogeek.com/292914/what-is-developer-mode-in-windows-10/)
so that Preconstruct can create symlinks.
#### Missing files in Windows
If you have errors about missing files even after you run `pnpm build`,
try cloning again your repository with the configuration `core.symlinks`
set to `true` like this: `git clone -c core.symlinks=true <URL>`.

View File

@@ -0,0 +1,47 @@
# Community History
All throughout 2019, Brandon Bayer was wanting something like Ruby on
Rails but for Javascript and React. If you search Twitter history, you'll
see him tweeting about this every so often, saying things like "_someone
please make this so I don't have to._" 😂
Finally in February 2020, Brandon had a phone call with a Ruby on Rails
developer friend. This call sparked him to finally try making Rails for
React. It seemed like good timing with all the new features in Next.js and
Prisma 2 being released in beta.
One week later, Brandon
[officially announced Blitz on February 17, 2020](https://twitter.com/flybayer/status/1229425878481793024).
At the time he only had a couple hundred lines of prototype code. But the
idea resonated with so many people, that many jumped in and helped
architect and build the very first alpha version.
In other words, Brandon essentially built the Blitz community before
building the project.
This turned out to be a great decision.
[38 amazing people](https://github.com/blitz-js/blitz/tree/ab6f60571ad61eef6be55e9684f2e243fa902e8d#contributors-)
contributed to the first alpha which was
[released on April 24, 2020](https://twitter.com/flybayer/status/1253649008540569600).
**The official beta version, 0.30.0, was
[released on the 1 year anniversary, February 17, 2021](https://twitter.com/flybayer/status/1362048912476016642)!**
In March 2021, we made the decision to fork Next.js, with an expectation
that Blitz would start to carve out a small portion of Next.js users. But
that hasn't happened. In fact, we think the fork has hurt adoption and our
growth has stagnated that year.
In December 2021, we proposed to pivot Blitz to a fullstack,
framework-agnostic toolkit that preserves the world-class DX and features
we adore but brings it to all Next.js users and optionally Remix,
SvelteKit, Nuxt, etc. You can read the RFC
[here](https://github.com/blitz-js/blitz/discussions/3075).
Soon after the pivot proposal, we started working on it, and released the
first alpha version in May 2022. Brandon has announced it for the first
time during React Miami conference. You can check out the recording
[here](https://www.youtube.com/watch?v=TWkjl_jg3Jk&ab_channel=JSWORLDConference).
Currently the core team is working towards the stable version of the
Blitz.js Toolkit.

View File

@@ -0,0 +1,151 @@
# How the Community Operates
## 🤝 Blitz is a Community Project
Blitz [was initially started by Brandon Bayer](./community-history), but
from the very beginning it's always been a community project. 38 people
contributed to the very first alpha version!
All other contributors help in their free time. We now have
[over 350 total contributors](https://github.com/blitz-js/blitz#contributors-)!
**Because Blitz is a community project, the entire community gets to help
shape Blitz and where it goes in the future.**
## Where to Ask Questions
First, search [the Blitz Discord](https://discord.blitzjs.com) and
[the GitHub repo](https://github.com/blitz-js/blitz) to see if someone has
already asked your question.
Next,
[post your question in our Discussion Forum](https://github.com/blitz-js/blitz/discussions).
This is much better than Discord as it's easier for people to find and
link to.
Then you're welcome to post a link to your Discussion thread in Discord,
because GitHub Discussions don't have a Discord notification integration
yet.
🙏 As you gain experience with Blitz, please help answer other peoples
questions!
## How to Report a Bug
First,
[search existing GitHub issues](https://github.com/blitz-js/blitz/issues?q=is%3Aissue)
so see if someone has already reported your issue.
If not, then please
[open a new issue](https://github.com/blitz-js/blitz/issues/new/choose)!
Someone will usually reply to your new issue within a day or two.
If you want to report an issue for the legacy Blitz framework, please do
it in [this repository](https://github.com/blitz-js/legacy-framework).
## Roadmap
Currently the core team is working on getting the Blitz Toolkit to the
stable version, which mostly means smoothing rough edges and fixing bugs.
However, anyone else is more than welcome to continue adding major
features!
Our [GitHub issues](https://github.com/blitz-js/blitz/issues) are where
you can find our roadmap. Many planned features have GitHub issues, but
not necessarily all of them do.
## How to Propose Features/Changes
We love ideas and suggestions for how to make Blitz better! But please
keep in mind we have a lot more feature ideas than contributor time to
make them all happen. So it'd be great if you can make a PR too!
### Minor Changes
For minor changes like adding a new CLI flag or something, simply
[open a new GitHub issue](https://github.com/blitz-js/blitz/issues/new/choose).
### Everything Else: RFCs
For any other features, even as small as adding a single new React hook,
please post your request as an RFC (Request for Comments) as a
[GitHub Discussion Thread](https://github.com/blitz-js/blitz/discussions/category_choices).
To post an RFC, do the following:
- Start the title with `[RFC]`
- Include the following sections
- `### What do you want and why?`
- `### How is this different from what you are currently doing?`
- `### Possible implementation(s)`
- After posting, please also share it in Discord in
`#request-for-comments`.
## Your Role
As a member of the Blitz community, we value your input, ideas,
suggestions, and help!
Please feel very welcome to comment on any GitHub issue, pull request,
RFC, etc! The community as a whole gets to shape where Blitz goes!
As you gain experience, we greatly appreciate your help including but not
limited to, answering people's questions, reviewing PRs, improving
documentation, submitting PRs, etc.
## How to Level Up in the Community
You can gain respect and influence in our community by being regularly
involved, being helpful, and being nice.
We have two official maintainer levels you can read about below, but you
are more than welcome to do the work of a maintainer before being
acknowledged as such. In fact doing the work of a maintainer is one of the
best ways to level up in the community.
Another great way to level up is by teaching people about Blitz and
helping them be successful Blitz developers. This can by blog posts,
videos, courses, etc.
## NPM Releases
Currently we have automated alpha releases for every commit to the `main``
barnch.
## Finances
[Flightcontrol](http://flightcontrol.dev/) is paying Aleksandra Sikora for
her Lead Maintainer role, and Dillon Raphael for his Senior Blitz.js
Maintainer role.
We also **really appreciate when companies who use Blitz pay their
employees** to contribute to Blitz, either part-time or full-time!
## Core Team
The Blitz core team consists of people who are deeply invested in Blitz.
The core team has GitHub, Discord, and npm admin permissions. People can
become core members by starting as a level 1 maintainer, becoming a level
2 maintainer, and then on to the core team.
## L2 Maintainers
Level 2 maintainers are the backbone of the community and are responsible
for reviewing and merging PRs. They are watchdogs over the code, ensuring
code quality, correctness, and security. They also help facilitate a rapid
pace of progress.
For more details, see [Being an L2 Maintainer](./maintainers)
## L1 Maintainers
Level 1 maintainers primarily help manage the community and triage issues.
They are critical for a healthy Blitz community. They take a lot of burden
off the core team and level 2 maintainers so they can focus on higher
level things with longer term impact.
For more details, see [Being an L1 Maintainer](./maintainers)

View File

@@ -0,0 +1,167 @@
# ❤️ Blitz Maintainers
Aside from the core team, there are two levels of maintainers, described
below.
## Becoming a Maintainer
We always need more level 1 maintainers! The main requirement is that you
can show empathy when communicating online. We'll train you as needed on
the other specifics. **This is a great role if you have limited time,
because you can spend as much time as you have without any ongoing
responsibilities (unlike level 2)**
Level 2 maintainers have a much higher responsibility, so usually you will
spend time as a level 1 maintainer before moving to level 2.
Please DM a core team member (Brandon Bayer) in Discord if you're
interested in becoming an official maintainer!
## Level 1 Maintainers
Level 1 maintainers are critical for a healthy Blitz community and
project. They take a lot of burden off the core team and level 2
maintainers so they can focus on higher level things with longer term
impact.
The primary responsibilities of level 1 maintainers are:
- Being a friendly, welcoming voice for the Blitz community
- Issue triage
- Pull request triage
- Monitor and answer the Discord help channels
- Following up on assigned issues to make sure they are being worked on
- Following up on in-progress PRs to make sure they don't get stuck
- Community encouragement
- Community moderation
## Level 2 Maintainers
Level 2 maintainers are the backbone of the project. They are watchdogs
over the code, ensuring code quality, correctness, and security. They also
facilitate a rapid pace of progress.
The primary responsibilities of level 2 maintainers are:
- Code ownership over specific parts of the project
- Maintaining and improving the architecture of what they own
- Final pull request reviews
- Merging pull requests
- Tracking and ensuring progress of open pull requests
## Retiring
Maintainers may retire from their role at any time without any shame or
guilt. Simply let a core team member know!
## ⚠️ Fundamentals
Maintainers are the face of the project and the front-line touch point for
the community. Therefore maintainers have the very important
responsibility of making people feel welcome, valued, understood, and
appreciated.
**Please take time to read and understand everything outlined in this
[guide on building welcoming communities](https://opensource.guide/building-community)**
Some especially important points:
- **Gratitude:** immediately express gratitude when someone opens an issue
or PR. This takes effort/time and we appreciate it
- **Responsiveness:** during issue/PR triage, even if we cant do a full
review right away, leave a comment thanking them and saying well review
it soon
- Our goal is to respond to all issues and PRs within 2 days, but
ideally within 1 day.
- **Understanding:** it's critical to ensure you understand exactly what
someone is saying before you respond. Ask plenty of questions if needed.
It's very bad if someone has to reply to your response and say "actually
I was asking about X"
- In fact, at least one question is almost always required before you
can respond appropriately  — whether in GitHub or in Discord
### Resources
- [How to Be Helpful Online](https://nedbatchelder.com/blog/202009/how_to_be_helpful_online.html)
- [How to Start Reviewing Code](https://shubheksha.com/posts/2019/03/how-to-start-reviewing-code/)
## Monitoring Discord
- We want every single question to get a response, ideally within a day,
or 2 at max. But this doesn't mean you have to solve their problem. For
example, if they ask about some random library you know nothing about,
you can respond saying you aren't familiar with that, but that they
could try looking for examples/docs on using it with nextjs, since the
integration would the same.
- Ensure threads are used as much as possible to keep channels organized.
Even if there are a few messages about a topic in the main channel and
the issue/question is not resolved, go ahead and create a thread and
respond in the thread.
- If someone reports something that's likely a bug, kindly ask them to
open an issue on Github
- If someone requests a feature or change, kindly ask them to open a
feature request issue on Github
- If you notice some type of DX issue or opportunity for improvement in
any conversation, please open an issue on Github for this. Making lots
of tiny improvements over the long has compounding returns
- If someone asks a question about something that either doesn't have docs
or isn't documented well, then take a minute to go add the docs for
that. And then paste a link to the new docs you added.
## Issue Triage
#### If a bug report:
- Does it have enough information? Versions? Logs? Some way to reproduce?
- Has this already been fixed in a previous release?
- Is there already an existing issue for this?
### If a feature/change request:
- Is it clear what the request is and what the benefit will be?
- Is this an obvious win for Blitz? Then accept it
- If not obvious, then pull in a core team member or level 2 maintainer
for more review
### Actions
1. Add tags:
- Add a `status/*` tag
- Add a `kind/*` tag
- Add a `scope/*` tag
- Add a good first/second issue tag if appropriate
## Pull Request Triage
- Are the changes covered by tests?
- Do the changes look ok? Make sure there's no obvious issues
- If applicable, has a PR been opened to update the docs?
### Actions
1. Kindly request any changes if needed
2. Else add a GitHub approval so that level 2 maintainers know it's
already had an initial review
## Final PR Review & Merging (Level 2 maintainers)
As a level 2 maintainer, it is your responsibility to make sure broken
code and regressions never reach the canary branch.
1. Ensure the PR'ed code fully works as intended and that there are no
regressions in related code
1. If not fully covered by automated tests, you need to pull down the
code locally and manually verify everything (the GitHub CLI helps
with this!)
2. During squash & merge:
1. Change the commit title to be public friendly - this exact text will
go in the release notes
2. Add the commit type in the description, in parenthesis like
`(patch)`. Commit types:
- `major` - major breaking change
- `minor` - minor feature addition
- `patch` - patches, bug fixes, perf improvements, etc
- `newapp` - changes to the new app template
- `recipe` - changes to a Blitz recipe
- `example` - change to an example app
- `meta` - internal meta change related to the Blitz repo/project

View File

@@ -0,0 +1,95 @@
# The Blitz.js Manifesto
## Background
Technology follows a repeating cycle of bundling and unbundling. Created
in 2005, Ruby on Rails became a major bundling force. It made web
application development easier and more accessible than ever before. This
benefited everyone, from those learning programming to seniors building
production systems.
A major unbundling happened in 2013 with the release of React because it
is hyper focused on the rendering layer. As React grew in popularity, so
did the choices for all the other parts, leaving developers with hundreds
of decisions to make when starting a new app. While this has contributed
to JavaScript Fatigue, it's been a powerful driving force for rapid
frontend innovation.
Now, in 2020, is the perfect time for another major bundling. Developers
are yearning for an easier, simpler way to build web applications.
Beginners want a guiding hand for building a robust app. And seniors want
a framework that removes mundane tasks and provides a highly scalable
architecture.
Hence the creation of Blitz.
## What is Blitz For?
Blitz is for building tiny to large fullstack database-backed applications
that have one or more graphical user interfaces like web or mobile apps.
## Foundational Principles
1. Fullstack & Monolithic
2. Convention over Configuration
3. Loose Opinions
4. Easy to Start, Easy to Scale
5. Community over Code
### 1. Fullstack & Monolithic
A fullstack, monolithic application is simpler than an application where
frontend and backend are developed and deployed separately. Monolithic
doesn't mean it will be slow or hard to scale to large teams. Monolithic
doesn't mean there isn't separation of concerns. Monolithic means you can
reason about your app as a single entity.
### 2. Convention over Configuration
Starting a new fullstack React app is currently too hard. You have to
spend days on things like configuring eslint, prettier, husky, vitest,
cypress, typescript, deciding on a file structure, setting up a database,
adding authentication and authorization, setting up a router, defining
routing conventions, and setting up your styling library.
Blitz makes as many decisions and does as much work for you as possible.
This makes it lightning fast to start real development. It also greatly
benefits the community. Common project structure and architectural
patterns make it easy to move from Blitz app to Blitz app and immediately
feel at home.
Convention over configuration doesn't mean no configuration. It means
configuration is optional. Blitz will provide all the escape hatches you
need for bespoke customization.
### 3. Loose Opinions
Blitz is opinionated. The out-of-the-box experience guides you on a path
perfect for most applications. However, Blitz isn't arrogant. It
understands there are very good reasons for deviating from convention, and
it allows you to do so. For example, Blitz has a conventional file
structure, but, with few exceptions, doesn't _enforce_ it.
And when there's not community consensus, `blitz new` prompts you to
choose.
### 4. Easy to Start, Easy to Scale
A framework that's only easy for one end of an application lifecycle is
not a good framework. Both starting and scaling must be easy.
Easy to start includes being easy for beginners and being easy to migrate
existing Next.js apps to Blitz.
Scaling is important in all forms: lines of code, number of people working
in the codebase, and code execution.
### 5. Community over Code
The Blitz community is the most important aspect of the framework, by far.
We have a comprehensive [Code of Conduct](./code-of-conduct).
We are all in this together, from the youngest to the oldest. We are all
more similar than we are different. We can and should solve problems
together. We should learn from other communities, not compete against
them.

View File

@@ -0,0 +1,11 @@
# Help Us Translate Blitz Docs
Blitz.js is used by many people arround the world, and we want them to be
comfortable navigating the documentation and using Blitz.
In the [languages](/languages) page, you'll see the translation progress
of each language. You can click on **Contribute** and create a Pull
Request with your contribution!
If your language isn't being translated and you want to work on it, read
[these instructions](https://github.com/blitz-js/blitzjs.com-translation/blob/main/README.md).

View File

@@ -0,0 +1,5 @@
{
"why-blitz": "Why Blitz?",
"learning": "Learning Path",
"nextjs": "With Existing Nextjs App"
}

View File

@@ -0,0 +1,110 @@
import { Callout } from 'nextra-theme-docs'
# Learning Path
Want to get better at developing applications using Blitz, but don't know
where to start? You've come to the right spot.
This document is inspired by the
[Frontend Developer Roadmap](https://roadmap.sh/frontend). It curates
material on concepts & ideas, tools & libraries and history & trivia
useful to become better at building applications. It is tailored to Blitz,
but most will happily apply elsewhere.
<Callout>
Links marked with 🥷 are advanced. If you're dipping your toes into web
development, it's totally OK to skip them.
</Callout>
## React
- [React for Beginners A React.js Handbook for Front End Developers](https://www.freecodecamp.org/news/react-beginner-handbook) -
Big introduction into React, including Function Components and Hooks.
- 📺
[freeCodeCamp's Full React Course 2020](https://www.youtube.com/watch?v=4UZrsTqkcW4) -
10hrs video introduction to React.
- 📺
[The Beginner's Guide to React](https://egghead.io/courses/the-beginner-s-guide-to-react) -
Kent C. Dodds short introduction to React, including Function
Components.
## Databases & Data Modeling
- [Prisma's Data Guide: Data Modeling](https://www.prisma.io/dataguide/datamodeling) -
A great introduction on constructing a good database schema for your
application.
- [What is Prisma?](https://www.prisma.io/docs/concepts/overview/what-is-prisma) -
A high-level overview on what Prisma is & how it works.
- 🥷
[Zero-Downtime Deployments with Data Migrations](https://engineering.wework.com/zero-downtime-deployments-with-data-migrations-2e337df48b8f) -
How to change your database schema without causing downtimes.
- Want to contribute to this part? Submit your favourite learning
materials in a PR! Here's some ideas for content we know we're missing:
- a guide on building multi-tenant applications
## Integrations
- Want to contribute to this part? Submit your favourite learning
materials in a PR! Here's some ideas for content we know we're missing:
- sending emails
- how to hook up stripe
- how to hook up Paddle
- what payment provider to choose
## Background Processing & Cron Jobs
- Want to contribute to this part? Submit your favourite learning
materials in a PR! Here's some ideas for content we know we're missing:
- how Cron expressions work
- what to use background processing for
- implementing cron jobs
## Testing
Automated tests are a great way of verifying that your application works -
and who doesn't want working software?
- 💸 [Testing Javascript](https://testingjavascript.com) - A thorough
curriculum on everything test-related. By Kent C. Dodds.
- Want to contribute to this part? Submit your favourite learning
materials in a PR! Here's some ideas for content we know we're missing:
- Introduction to the testing pyramid
- unit testing using Vitest
- writing code to be testable
- cypress guide
## Software Architecture
As your application grows bigger, some structure may be neccessary.
There's a million ways on how to structure your project, here's some good
guidance:
- Want to contribute to this part? Submit your favourite learning
materials in a PR! Here's some ideas for content we know we're missing:
- 🥷 TODO: a good guide on onion / clear architecture
## Soft Skills
Building software is highly communicative and rarely a solo effort.
Working in a team requires soft skills.
- [How to Make Your Code Reviewer Fall in Love with You](https://mtlynch.io/code-review-love/) -
Code Reviews are a great when done well, and awful when not. Read this
article to 1-up your own PRs!
- Want to contribute to this part? Submit your favourite learning
materials in a PR!
## Building Products
Building a product is more than building an application. Finding the right
business model, evaluating ideas, getting valuable feedback, building a
customer base - all of this is very different from building software. If
you're building a product (there's a fair share of entrepreneurs amongst
Blitz users!), this is for you:
- [The Mom Test](http://momtestbook.com) - A book on getting honest
customer feedback.
- Want to contribute to this part? Submit your favourite learning
materials in a PR!

View File

@@ -0,0 +1,123 @@
# Add Blitz.js to an Existing Next.js Project
import {Callout, Tab, Tabs, Steps} from "nextra-theme-docs"
If you have an existing Next.js project and would like to use some or all
of Blitz Toolkit, this page will provide you with information on setting
it up. A few steps are required, and we'll go through them one by one.
## Installing Blitz
<Steps>
### Adding required dependencies
<Tabs items={["pnpm", "npm", "yarn"]}>
<Tab>
```sh
pnpm add blitz @blitzjs/next
```
</Tab>
<Tab>
```sh
npm i blitz @blitzjs/next
```
</Tab>
<Tab>
```sh
yarn add blitz @blitzjs/next
```
</Tab>
</Tabs>
### Blitz server setup
If you want to use Blitz's server functionalities like auth, middlewares,
rpc, you'd need to create a `blitz-server.ts` file somewhere in your
project, e.g. in `src/blitz-server.ts`. We'll cover how to add plugins
later.
```ts twoslash
import {setupBlitzServer} from "@blitzjs/next"
const {
/* plugins' exports */
} = setupBlitzServer({
plugins: [
// plugins will go here
],
})
```
### Blitz client setup
Now, if you want Blitz's client functionalities, you'll have to create a
`blitz-client.ts` file. It can be next to the `blitz-server.ts` in
`src/blitz-client.ts`.
```ts twoslash
import {setupBlitzClient} from "@blitzjs/next"
export const {withBlitz} = setupBlitzClient({
plugins: [
// plugins will go here
],
})
```
The `withBlitz` function will be needed to wrap your components with
Blitz's client side functionality.
### Use `withBlitz` in your App component
To use Blitz on the client, you also have to use the `withBlitz` function
in your App component.
```ts twoslash
import {withBlitz} from "src/blitz-client"
function App({Component, pageProps}: AppProps) {
return <Component {...pageProps} />
}
export default withBlitz(App)
```
### Modifying `next.config.js` file
Next.js requires you to manually type out page locations. Blitz comes with
a [Route Manifest](./route-manifest), so you can do:
```ts twoslashx
<Link href={Routes.ProductsPage({ productId: 123 })} />
// instead of
<Link href={`/products/${123}`} />
```
To enable it, you have to wrap your config with `withBlitz` in the
`next.config.js` file:
```js
const {withBlitz} = require("@blitzjs/next")
module.exports = withBlitz()
```
### Adding plugins
Now that you're all set with the basic setup, you can add plugins that you
want to use in your app. There are a few places to check out:
1. [`@blitzjs/auth`](./auth-setup) — it covers how to setup auth plugin as
well as how to use Blitz auth system.
2. [`@blitzjs/rpc`](./rpc-setup) — check it out to learn how to set up
Blitz's Zero API Layer and to learn more about it.
</Steps>
Finally, you can check out more detailed information about the
[`@blitzjs/next` adapter](./blitzjs-next) to learn how to use Blitz
functionalities inside of `getServerSideProps`, `getStaticProps`, Next API
Routes, and other places.

View File

@@ -0,0 +1,72 @@
import { Callout, Tab, Tabs, Steps } from 'nextra-theme-docs'
## Get Started With Blitz
### Set Up Your Computer
You need Node.js 16 or newer. You can verify this by running `node -v` in
your terminal. If you don't have Node or need a newer version, we
recommend using a node version manager like
[fnm](https://github.com/Schniz/fnm). That will allow you to change node
versions and even have different versions for each project.
### Install Blitz
<Tabs items={['pnpm', 'npm', 'yarn']}>
<Tab>
```bash
pnpm add -g blitz
```
</Tab>
<Tab>
```bash
npm i -g blitz
```
</Tab>
<Tab>
```bash
yarn add -g blitz
```
</Tab>
</Tabs>
### Create a New App
1. `blitz new myAppName`
2. `cd myAppName`
3. `blitz dev`
4. View your brand new app at
[http://localhost:3000](http://localhost:3000)
## 👋 Welcome to the Blitz Community
The Blitz community is warm, safe, diverse, inclusive, and fun!
[Join our Discord Community](https://discord.blitzjs.com) where we help
each other build Blitz apps. It's also where we collaborate on building
Blitz itself.
For questions and longer form discussions,
[post in our forum.](https://github.com/blitz-js/blitz/discussions)
For a full introduction, read
[How the Community Operates](./how-the-community-operates). This details
everything, including how to get help, how to report bugs, how to suggest
new features, etc.
#### 🤝 You are invited to help make Blitz the best it can be!
We have an awesome community that's working together to make Blitz the
best framework the world has ever seen.
How you can help:
1. Report bugs by
[opening an issue on GitHub](https://github.com/blitz-js/blitz/issues/new/choose)
1. Contribute code:
[Read the contributing guide so see how to get started](./contributing).
1. [Sponsorships & donations](https://github.com/blitz-js/blitz#financial-contributors),
which start at $5/month
1. Any other way you want! We totally appreciate any type of contribution,
such as documentation, videos, blog posts, etc. If you have an unusual
idea, feel free to run it past us in Discord! :)

View File

@@ -0,0 +1,3 @@
{
"v2": "Upgrading to v2 - Blitz Toolkit"
}

View File

@@ -0,0 +1,281 @@
# Upgrading Your Blitz App to Blitz 2.0
If you have an existing Blitz.js app, and would like to upgrade it to the
Blitz 2.0, you can use our `@blitzjs/codemod` package:
```sh
npx @blitzjs/codemod upgrade-legacy
```
After running the above command, your Blitz app will be upgraded to the
Blitz 2.0. If you face any issues with the codemod — let us know! You can
also check out the manual upgrade guide below.
## Manual Upgrade Steps
Below, we're going to list down the steps performed by the codemod in case
you want to do some of them or all of them manually. Also, in case
something goes wrong with the codemod tool, you can follow these steps to
upgrade your app:
### Rename the `blitz.config.ts` file to `next.config.js`
Inside of the config file, you'll also need to wrap the config with
`withBlitz` function imported from `@blitzjs/next`:
```js
// @ts-check
const { withBlitz } = require("@blitzjs/next")
/**
* @type {import('@blitzjs/next').BlitzConfig}
**/
const config = {}
module.exports = withBlitz(config)
```
### Update dependencies in `package.json`
1. Update `react`, `react-dom` to the latest versions.
2. Install `@blitzjs/next`, `@blitzjs/rpc`, `@blitzjs/auth`.
3. Set `blitz` version to `latest`.
4. Upgrade `next` to the latest version.
### Update project's named imports
Now, for most of the things previously imported from `blitz` package,
you'd need to update the import to the new packages. Use the following
list as a reference:
| Import | Source Package |
| ----------------------------- | --------------- |
| `NextApiHandler` | `next` |
| `NextApiRequest` | `next` |
| `NextApiResponse` | `next` |
| `GetServerSideProps` | `next` |
| `InferGetServerSidePropsType` | `next` |
| `GetServerSidePropsContext` | `next` |
| `useRouterQuery`: | `next/router` |
| `useRouter` | `next/router` |
| `Router` | `next/router` |
| `Link` | `next/link` |
| `Image` | `next/image` |
| `Script` | `next/script` |
| `Document` | `next/document` |
| `DocumentHead` | `next/document` |
| `Html` | `next/document` |
| `Main` | `next/document` |
| `Head` | `next/head` |
| `App` | `next/app` |
| `dynamic` | `next/dynamic` |
| `noSSR` | `next/dynamic` |
| `getConfig` | `next/config` |
| `setConfig` | `next/config` |
| `ErrorBoundary` | `@blitzjs/next` |
| `ErrorFallbackProps` | `@blitzjs/next` |
| `useParam` | `@blitzjs/next` |
| `Routes` | `@blitzjs/next` |
| `ErrorComponent` | `@blitzjs/next` |
| `AppProps` | `@blitzjs/next` |
| `BlitzPage` | `@blitzjs/next` |
| `BlitzLayout` | `@blitzjs/next` |
| `invokeWithMiddleware` | `@blitzjs/rpc` |
| `resolver` | `@blitzjs/rpc` |
| `useQuery` | `@blitzjs/rpc` |
| `usePaginatedQuery` | `@blitzjs/rpc` |
| `useInfiniteQuery` | `@blitzjs/rpc` |
| `useMutation` | `@blitzjs/rpc` |
| `queryClient` | `@blitzjs/rpc` |
| `getQueryKey` | `@blitzjs/rpc` |
| `getInfiniteQueryKey` | `@blitzjs/rpc` |
| `invalidateQuery` | `@blitzjs/rpc` |
| `setQueryData` | `@blitzjs/rpc` |
| `useQueryErrorResetBoundary` | `@blitzjs/rpc` |
| `QueryClient` | `@blitzjs/rpc` |
| `dehydrate` | `@blitzjs/rpc` |
| `invoke` | `@blitzjs/rpc` |
| `getAntiCSRFToken` | `@blitzjs/auth` |
| `passportAuth` | `@blitzjs/auth` |
| `sessionMiddleware` | `@blitzjs/auth` |
| `simpleRolesIsAuthorized` | `@blitzjs/auth` |
| `getSession` | `@blitzjs/auth` |
| `setPublicDataForUser` | `@blitzjs/auth` |
| `SecurePassword` | `@blitzjs/auth` |
| `hash256` | `@blitzjs/auth` |
| `generateToken` | `@blitzjs/auth` |
| `useAuthenticatedSession` | `@blitzjs/auth` |
| `useRedirectAuthenticated` | `@blitzjs/auth` |
| `useSession` | `@blitzjs/auth` |
| `useAuthorize` | `@blitzjs/auth` |
| `AuthenticatedSessionContext` | `@blitzjs/auth` |
### Update project's default imports
There are also some default imports that you'll need to update. Use the
following list as a reference:
| Default Import | Source Package |
| -------------- | -------------- |
| `Link` | `next/link` |
| `Image` | `next/image` |
| `Head` | `next/head` |
| `dynamic` | `next/dynamic` |
### Change `queryClient` import to `getQueryClient`
If you imported `queryClient` from `blitz`, you'd need to change it to the
following code:
```diff
- import { queryClient } from 'blitz'
+ import { getQueryClient } from '@blitzjs/rpc'
+ const queryClient = getQueryClient()
```
### Update `BlitzApiRequest`, `BlitzApiResponse`, `BlitzApiHandler`
`blitz` no longer exports `BlitzApiRequest`, `BlitzApiResponse`,
`BlitzApiHandler`. You'll need to update your imports to the following:
```diff
- import { BlitzApiRequest } from 'blitz'
+ import { NextApiRequest } from 'next'
- import { BlitzApiResponse } from 'blitz'
+ import { NextApiResponse } from 'next'
- import { BlitzApiHandler } from 'blitz'
+ import { NextApiHandler } from 'next'
```
### Create `blitz-server.ts` and `blitz-client.ts`
To configure the plugins, you'd need to add the following files to your
project:
1. `blitz-server.ts`:
```ts
import { setupBlitzServer } from "@blitzjs/next"
import {
AuthServerPlugin,
PrismaStorage,
simpleRolesIsAuthorized,
} from "@blitzjs/auth"
import { db } from "db"
const { gSSP, gSP, api } = setupBlitzServer({
plugins: [
AuthServerPlugin({
cookiePrefix: "blitz-app",
storage: PrismaStorage(db),
isAuthorized: simpleRolesIsAuthorized,
}),
],
})
export { gSSP, gSP, api }
```
2. `blitz-client.ts`:
```ts
import { AuthClientPlugin } from "@blitzjs/auth"
import { setupBlitzClient } from "@blitzjs/next"
import { BlitzRpcPlugin } from "@blitzjs/rpc"
export const { withBlitz } = setupBlitzClient({
plugins: [
AuthClientPlugin({
cookiePrefix: "blitz-app",
}),
BlitzRpcPlugin(),
],
})
```
### Create API Route for the Zero-API Layer
To setup the Zero-API layer, you'd need to create a
`src/pages/api/rpc/[[...blitz]].ts` file with the following content:
```ts
import { rpcHandler } from "@blitzjs/rpc"
import { api } from "src/blitz-server"
export default api(rpcHandler())
```
### Remove `babel.config.js`
It's not needed anymore.
### Move all pages to `src/pages` directory
Having pages in separate directories in not supported with Next.js. They
now have to be consolidated in the top level `pages` directory, or we
recommend placing it in the `src` directory.
### Move API Routes to `src/pages/api` directory
All your API Routes have to be inside of the `src/pages/api` directory.
### Wrap your App component with `withBlitz`
To use Blitz on the client, you also have to use the `withBlitz` function
in your App component.
```ts
import { withBlitz } from "src/blitz-client"
function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />
}
export default withBlitz(App)
```
### Convert `useRouterQuery` to `useRouter`
Blitz no longer exports `useRouterQuery`. You'll need to use the
`useRouter` function instead.
```ts
import { useRouter } from "next/router"
```
### Wrapping `getServerSideProps`, `getStaticProps`, and API Routes
If you want to access the Blitz context inside of the
`getServerSideProps`, `getStaticProps`, and API Routes, you'll need to
wrap them with corresponding functions: `gSSP`, `gSP`, and `api` imported
from `@blitzjs/next`.
To learn more about it, follow the [`@blitzjs/next` docs](./blitzjs-next).
### Replacing `queryClient` with `getQueryClient` function
If you're using `queryClient` in your code, you can replace it with the
following code:
```ts
import { getQueryClient } from "@blitzjs/rpc"
const queryClient = getQueryClient()
```
### `types.ts` changes
In your `types.ts` file, you'll need to change the module that is being
augmented:
```diff
- declare module "@blitzjs/auth" {
+ declare module "@blitzjs/auth" {
export interface Session {
// ...
}
}
```

440
docs/src/pages/index.tsx Normal file
View File

@@ -0,0 +1,440 @@
import {Octokit} from "@octokit/rest"
import Image from "next/image"
import Link from "next/link"
import {useEffect, useState} from "react"
import {ButtonLink} from "@/components/ButtonLink"
import {Header} from "@/components/Header"
import {Feature} from "@/components/home/Feature"
import {FeatureIcon} from "@/components/home/FeatureIcon"
import {FeatureIconTitle} from "@/components/home/FeatureIconTitle"
import {Footer} from "@/components/home/Footer"
import {Hand} from "@/components/home/Hand"
import {HeroCode} from "@/components/home/HeroCode"
import {StyledLink} from "@/components/home/StyledLink"
import {VideoPlayer} from "@/components/home/VideoPlayer"
import Scrollbar from "@/components/Scrollbar"
import {SocialCards} from "@/components/SocialCards"
import {SponsorPack} from "@/components/SponsorPack"
import {getGitHubFile} from "@/utils/getGitHubFile"
const Home = ({randomContributors}) => {
const [navIsOpen, setNavIsOpen] = useState(false)
useEffect(() => {
document.body.style.overflow = navIsOpen ? "hidden" : "unset"
}, [navIsOpen])
return (
<div>
<SocialCards imageUrl="/social-homepage.png" />
<div className="overflow-hidden">
<div>
<a name="top" aria-hidden>
{null}
</a>
<div className="relative grid grid-cols-1 pb-1 md:pb-3 gap-y-24 xl:gap-y-44">
<div className="z-30 text-white col-span-full">
<Header
className="px-6 mx-auto max-w-7xl"
onNavToggle={(isOpen) => {
setNavIsOpen(isOpen)
}}
/>
</div>
<div
className={
"absolute w-full h-full row-start-1 row-end-5 background-to-video rounded-bl-3xl xl:rounded-bl-4xl bg-gradient-to-b from-purple-mid to-purple-primary dark:from-black dark:to-purple-off-black " +
(navIsOpen ? "z-20 fixed" : "-z-10")
}
></div>
<div className="relative -mt-6 text-white col-span-full">
<div className="grid grid-cols-1 gap-10 px-6 mx-auto max-w-7xl lg:grid-cols-2 md:gap-6 xl:-mt-10">
<div className="z-10 lg:w-full">
<div className="flex flex-col -mt-8 lg:mt-16 xl:mt-10">
{/* html is ordered for SEO, then we use flex to flip display order for design */}
<h2 className="order-last font-medium text-2xl xl:text-3xl font-secondary xl:font-medium text-transparent bg-clip-text bg-gradient-to-r from-yellow-200 to-yellow-400 dark:from-yellow-100 dark:to-yellow-300">
The Missing Fullstack Toolkit for Next.js
</h2>
<h3 className="font-medium text-7xl font-secondary xl:text-8xl xl:font-medium text-transparent bg-clip-text bg-gradient-to-r from-blue-gradient-white to-blue-gradient-light-blue tracking-tight xl:tracking-tighter mb-4 xl:mb-8 ">
Ship. Fast.
</h3>
</div>
<p className="mt-6 xl:mt-8 text-lg xl:text-2xl xl:font-medium text-off-white lg:text-transparent lg:bg-clip-text lg:bg-gradient-to-r lg:from-blue-gradient-white lg:to-blue-gradient-light-blue ">
Blitz picks up where Next.js leaves off, providing battle-tested libraries and
conventions for shipping and scaling world wide applications.
</p>
<div className="flex space-x-4 mt-10">
<ButtonLink className="w-2/3 lg:w-auto rounded-tl-xl" href="/docs/why-blitz">
Learn to Blitz
</ButtonLink>
<ButtonLink
href="https://github.com/blitz-js/blitz"
target="_blank"
rel="noopener noreferrer"
variant="outline"
className="w-1/3 lg:w-auto rounded-r-xl"
>
GitHub
</ButtonLink>
</div>
</div>
<div className="relative lg:col-span-1">
<Hand variant="hero-squiggle" className="lg:hidden -right-6 -top-36" />
<Hand variant="hero-rightarm" className="hidden lg:block -left-36 top-32" />
<Hand
variant="hero-righthand"
className="z-20 hidden lg:block -left-4"
style={{top: "15.2rem"}}
/>
<Hand
variant="hero-leftarm"
className="hidden lg:block"
style={{top: "30rem", right: "-4.8rem"}}
/>
<Hand
variant="hero-lefthand"
style={{top: "26.6rem", right: "-2.2em"}}
className="z-20 hidden lg:block"
/>
<HeroCode className="z-10" />
</div>
</div>
</div>
<div className="z-10 px-6 mx-auto space-y-12 text-lg text-center text-white lg:space-y-0 lg:space-x-12 lg:flex lg:text-left max-w-7xl xl:font-mediumxl:text-xl">
<FeatureIcon icon="layers" heading="Typesafe API Layer">
Build and iterate on features 10x faster with Blitz RPC than REST, GraphQL, or
vanilla API routes. Read and write data from the client with full typesafety and
without messing with HTTP or serialization.
</FeatureIcon>
<FeatureIcon icon="lighteningBolt" heading="Authentication">
Powerful, flexible, and battle tested authentication and authorization for Next.js.
You get more control with simpler APIs than alternatives. Easily add social third
party integrations like Google, Github, and Auth0.
</FeatureIcon>
<FeatureIcon icon="graphUp" heading="Conventions & Codegen">
Set up a new app in 2 mins instead of 2 weeks. Everything will be set up for you
including auth, user signup, forgot password, and your form library of choice.
</FeatureIcon>
</div>
<div className="grid w-full gap-5 px-6 mx-auto text-white xl:gap-10 max-w-7xl lg:grid-cols-2">
<Link href="/#" passHref>
<StyledLink className="flex items-center justify-between pb-1 text-lg border-b border-opacity-50 border-blue-mid lg:col-span-2 font-secondary xl:text-xl">
<span>Top Videos</span>
{/*
<span className="flex items-center">
<span className="hidden mr-2 lg:block">View News</span>{" "}
<BsArrowRight size="1.5rem" />
</span>
*/}
</StyledLink>
</Link>
<VideoPlayer url="https://www.youtube.com/watch?v=8D8yox2clug" />
<VideoPlayer url="https://www.youtube.com/watch?v=TWkjl_jg3Jk" />
</div>
<div className="relative w-full mx-auto space-y-10 lg:space-y-20 xl:space-y-36 max-w-7xl">
<h2 className="px-6 text-3xl font-semibold xl:text-5xl xl:w-1/2">
Everything You Need For Production Apps
</h2>
<div className="w-full">
<Hand
variant="concepts-right"
className="hidden lg:block lg:-top-24 lg:-right-96 lg:w-8/12 xl:-top-14"
/>
<Scrollbar className="lg:hidden" thumbHeight="4px">
<div className="grid pb-4 ml-6 features-grid lg:gap-y-14">
<Feature title="Built for Monoliths and Services">
<p>
You can manage everything from the database to your frontend all inside a
single app. Only one thing to develop. Only one thing to deploy.
</p>
<p>Or not. Your choice.</p>
</Feature>
<Feature title="Loose Opinions">
<p>
The out-of-the-box experience guides you on a path perfect for most
applications. But when you need to go off the beaten path, you are totally
free to do so.
</p>
<p>
And nearly everything is pluggable. For example, we don&apos;t mandate which
styling or form libraries you use.
</p>
</Feature>
<Feature title="Convention over Configuration">
<p>
Blitz does all the boring set up and configuration for you. The common
project structure and architectural patterns make it easy to move from one
Blitz app to another and immediately feel at home.
</p>
</Feature>
<Feature title="Easy to Start, Easy to Scale">
<p>Easy for beginners and easy to migrate existing Next.js apps to Blitz.</p>
<p>
Easy to scale in all forms: lines of code, number of people working in the
codebase, and code execution.
</p>
</Feature>
</div>
</Scrollbar>
</div>
</div>
<div className="absolute w-full h-full row-start-6 lg:h-codesandbox lg:mt-80 row-end-10 md:row-end-10 rounded-bl-3xl rounded-tr-3xl lg:rounded-bl-4xl lg:rounded-tr-4xl bg-gradient-to-b from-purple-mid to-purple-primary dark:from-purple-off-black dark:to-black"></div>
<div className="relative hidden w-full px-6 mx-auto space-y-10 max-w-7xl lg:block">
<h3 className="pb-1 text-xs border-b border-opacity-50 font-secondary border-blue-mid">
Blitz CodeSandbox Example
</h3>
<div>
<Hand variant="sandbox-right" style={{right: "-13.2rem", bottom: "-35rem"}} />
<a
target="_blank"
rel="noopener noreferrer"
href="https://codesandbox.io/s/blitzjs-2-0-codesandbox-demo-b5v8xy?file=/app/blitz-server.ts"
className="h-sandbox xl:h-xl-sandbox block relative"
>
<Image
src="/img/sandbox-pic.png"
layout="fill"
className="object-cover"
alt="Codesandbox placeholder"
/>
<div className="absolute inset-0 bg-gray-800 opacity-0 hover:opacity-70 flex items-center justify-center text-white text-6xl font-bold">
Click to Open in New Tab
</div>
</a>
</div>
</div>
<div className="lg:hidden">{/*spacer div*/}</div>
<div className="relative flex flex-col px-6 mx-auto text-white lg:flex-row max-w-7xl space-y-14 lg:space-x-24 lg:space-y-0 xl:space-x-40">
<div className="space-y-14 lg:w-1/2">
<h2 className="z-10 font-medium text-transparent text-5xl-squashed font-secondary bg-clip-text bg-gradient-to-r from-blue-gradient-white to-blue-gradient-light-blue xl:text-6xl">
We Love Our Community!
</h2>
<div className="z-10 grid grid-cols-5 gap-1 md:grid-cols-6 lg:grid-cols-5 grid-rows-8 overflow-clip">
{randomContributors.map((contributor, i) => (
<a
href={`https://github.com/${contributor.login}`}
key={i}
target="_blank"
rel="noopener noreferrer"
>
<Image
layout="intrinsic"
width="100%"
height="100%"
src={contributor.avatar_url}
alt={contributor.name}
title={contributor.name}
className="w-full"
/>
</a>
))}
</div>
</div>
<div className="grid grid-cols-1 text-lg lg:relative gap-14 md:grid-cols-2 lg:row-span-2 lg:grid-cols-1 xl:text-xl lg:w-1/2">
<Hand variant="community-squiggle" className="xl:hidden -right-18" />
<div className="z-10 flex flex-col justify-between space-y-6 lg:justify-end">
<div className="flex flex-col space-y-6 lg:h-auto lg:text-transparent text-off-white">
<p className="lg:bg-gradient-to-r lg:from-blue-gradient-white lg:to-blue-gradient-light-blue lg:bg-clip-text">
Our community is warm, safe, inclusive, and fun!
<br />
Please read our{" "}
<Link href="/docs/code-of-conduct" passHref>
<StyledLink className="underline text-off-white hover:text-blue-light">
Code of Conduct
</StyledLink>
</Link>
.
</p>
</div>
<ButtonLink
href="https://discord.blitzjs.com/"
target="_blank"
rel="noopener noreferrer"
className="rounded-bl-none rounded-xl lg:w-max"
>
Join our Discord Community
</ButtonLink>
</div>
<div className="z-10 flex flex-col justify-between space-y-6 lg:justify-start">
<div className="flex flex-col space-y-6 lg:h-auto lg:text-transparent text-off-white lg:bg-clip-text lg:bg-gradient-to-r lg:from-blue-gradient-white lg:to-blue-gradient-light-blue">
<p className="lg:bg-gradient-to-r lg:from-blue-gradient-white lg:to-blue-gradient-light-blue lg:bg-clip-text">
We are all in this together, from the youngest to the oldest. We are all more
similar than we are different. We love to work together.
</p>
<p className="lg:bg-gradient-to-r lg:from-blue-gradient-white lg:to-blue-gradient-light-blue lg:bg-clip-text">
We invite you to help make Blitz the best JavaScript application layer
we&apos;ve ever had!
</p>
</div>
<Link href="/docs/contributing" passHref>
<ButtonLink className="rounded-bl-none rounded-xl lg:w-max">
Learn How to Contribute
</ButtonLink>
</Link>
</div>
</div>
</div>
<div className="z-10 w-full mx-auto text-white space-y-7 max-w-7xl">
<h2 className="px-6 text-2xl font-medium text-white font-secondary lg:text-3xl">
Architecture Diagram
</h2>
<div className="w-full">
<Scrollbar className="lg:hidden" thumbHeight="4px" thumbColor="white">
<div className="px-6 architecture-diagram" style={{paddingBottom: "2px"}}>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src="img/architecture.svg" alt="Architecture diagram" />
</div>
</Scrollbar>
</div>
</div>
<div className="relative col-span-full">
<Hand variant="features-squiggle" className="-right-6 -top-10 xl:hidden -z-10" />
</div>
<div className="absolute w-full h-full row-start-8 row-end-19 xl:row-end-19 -z-20 bg-purple-mid dark:bg-purple-off-black"></div>
<div className="relative px-6 mx-auto my-6 space-y-12 text-white xl:my-0 max-w-7xl xl:space-y-36">
<h2 className="text-3xl font-semibold lg:text-transparent lg:bg-clip-text lg:bg-gradient-to-r lg:from-blue-gradient-white lg:to-blue-gradient-light-blue xl:text-5xl">
Everything End-to-End From <br className="hidden xl:block" />
the Database to the Frontend
</h2>
<div className="grid gap-12 md:grid-cols-2 xl:grid-cols-3">
<Hand
variant="features-right"
className="hidden xl:block xl:-top-40 xl:-right-52"
/>
<FeatureIconTitle icon="thumbsUp" title="Authentication & Authorization">
Blitz authentication is super easy and secure. Works with any identity provider,
including self-hosted username and password and third-parties like Auth0.
</FeatureIconTitle>
<FeatureIconTitle icon="database" title="Database Agnostic">
You can use any database you want. Prisma is the default database client, but you
can remove that and use anything else like Fauna or DynamoDB.
</FeatureIconTitle>
<FeatureIconTitle icon="fileCode" title="Recipes">
One command to install code and/or packages into your blitz app. Examples: `blitz
install tailwind` or `blitz install chakra-ui`. Recipes can be created by anyone.
</FeatureIconTitle>
<FeatureIconTitle icon="plugin" title="Backend Architecture">
Blitz is set up for server intensive tasks like sending emails, cron jobs,
background processing, generating PDFs, etc. Currently we have minimal backend
guides, but are working on developing more patterns and adding more docs.
</FeatureIconTitle>
<FeatureIconTitle icon="typescript" title="First Class TypeScript Support">
Blitz is built with TypeScript and the Blitz data layer is fully end-to-end
typesafe. All types are completely static without needing a separate type
generation process!
</FeatureIconTitle>
<FeatureIconTitle icon="scaffolding" title="Code Scaffolding">
Blitz code scaffolding is great for both prototyping and for building real apps!
You can override templates with your own.
</FeatureIconTitle>
</div>
</div>
<div className="absolute w-full h-full bg-white dark:bg-black row-start-11 row-end-13 rounded-tr-3xl xl:rounded-tr-4xl -z-10" />
<div className="relative col-span-full">
<Hand
variant="sponsors-squiggle"
className="-right-24 xl:hidden"
style={{top: "-5.3rem"}}
/>
</div>
<div className="px-6 mx-auto text-center max-w-7xl ">
<div className="space-y-7 xl:space-y-10">
<h2 className="relative text-3xl font-semibold xl:text-5xl">
<Hand
variant="sponsors-left"
className="hidden xl:block -left-80 pointer-events-none"
style={{top: "-18.05rem"}}
/>
Our Sponsors
</h2>
<p className="text-lg xl:text-xl">
Your financial contributions help ensure Blitz continues to be developed and{" "}
<br className="hidden lg:block" />
maintained! We have monthly sponsorship options starting at $5/month.
</p>
<div>
<ButtonLink
variant="solid-dark"
href="https://github.com/sponsors/blitz-js"
className="mx-auto rounded-bl-none rounded-xl lg:w-max md:w-1/3 lg:m-auto lg:mt-4 xl:mt-18"
target="_blank"
rel="noopener noreferrer"
>
Support Blitz
</ButtonLink>
</div>
</div>
<div className="xl:max-w-2xl mx-auto">
<SponsorPack />
</div>
</div>
<div className="w-full px-6 mx-auto space-y-12 text-white lg:space-x-4 lg:space-y-0 lg:flex lg:items-center max-w-7xl">
<h2 className="pr-2 text-3xl font-semibold lg:w-full lg:text-transparent lg:bg-clip-text lg:bg-gradient-to-r lg:from-blue-gradient-white lg:to-blue-gradient-light-blue xl:text-5xl">
So What Should I Do Now?
</h2>
<div className="flex flex-col w-full space-y-4 md:flex-row md:space-y-0 md:space-x-2 min-h-10">
<ButtonLink
href="/docs/get-started"
className="w-full text-lg py-18 rounded-t-2xl md:rounded-tr-none"
>
Try Blitz in Under 5 Mins
</ButtonLink>
<ButtonLink
target="_blank"
rel="noopener noreferrer"
href="https://discord.blitzjs.com"
className="w-full text-lg py-18 rounded-br-2xl md:rounded-tr-2xl"
>
Join Discord
</ButtonLink>
</div>
</div>
<Footer className="dark:bg-purple-off-black bg-purple-mid text-white" />
</div>
</div>
</div>
</div>
)
}
const getStaticProps = async () => {
const MAX_CONTRIBUTORS = 30
const octokit = new Octokit({
auth: process.env.GITHUB_AUTH_TOKEN,
})
const {contributors} = await getGitHubFile({
octokit,
owner: "blitz-js",
repo: "blitz",
path: ".all-contributorsrc",
json: true,
})
let randomIndexes = []
while (randomIndexes.length < MAX_CONTRIBUTORS) {
var r = Math.floor(Math.random() * contributors.length)
if (randomIndexes.indexOf(r) === -1) randomIndexes.push(r)
}
let randomContributors = randomIndexes.map((i) => contributors[i])
return {
props: {randomContributors},
revalidate: 60 * 30, // 30 minutes
}
}
Home.meta = {
title: "Blitz.js - The Missing Fullstack Toolkit for Next.js",
description: `Blitz picks up where Next.js leaves off, providing battle-tested libraries and conventions for shipping and scaling world wide applications.`,
}
export default Home
export {getStaticProps}

828
docs/src/styles/nextra.css Normal file
View File

@@ -0,0 +1,828 @@
:root {
--docs-accent-color: #9580ff;
--docs-accent-color-opacity: #9580ff60;
--docs-accent-color-link: #9580ff;
--docs-light-bg: #e5e5e560;
--docs-light-bg-hover: #d0d0d060;
--docs-dark-bg: #2a2a2a90;
--docs-dark-bg-hover: #2a2a2a60;
--nextra-navbar-height: 8rem;
}
html[class~="dark"] {
--nextra-primary-hue: 267;
--nextra-primary-hue-saturation: 100%;
--nextra-primary-hue-lightness: 75%;
--docs-secondary-bg: var(--docs-dark-bg);
--docs-secondary-bg-hover: var(--docs-dark-bg-hover);
}
html[class~="light"] {
--docs-accent-color: #644be1;
--docs-dark-bg: #e5e5e560;
--docs-secondary-bg: var(--docs-light-bg);
--docs-secondary-bg-hover: var(--docs-light-bg-hover);
}
/* General
------------------------ */
html,
body,
kbd {
font-family: "Inter", "Helvetica Neue", "Helvetica", "Arial", "sans-serif";
-webkit-font-smoothing: "antialiased";
}
html {
font-size: 17px;
}
.nextra-nav-container nav {
height: 7rem;
}
aside {
height: calc(100vh - 7rem);
top: calc(7rem + 4px) !important;
}
.nextra-nav-container nav {
box-sizing: border-box;
padding: 0 2.5rem;
}
.nextra-sidebar-container {
box-sizing: border-box;
padding-left: 1rem;
}
.nextra-toc {
padding-right: 1rem;
}
@media (max-width: 640px) {
.nextra-nav-container {
padding: 0;
}
.nextra-nav-container nav {
padding: 0 2rem;
}
aside {
top: 0;
height: 100%;
}
.nextra-sidebar-container {
padding-top: 0;
}
}
.nextra-breadcrumb {
display: none !important;
}
/* General colors
------------------------ */
html[class~="dark"] .dark\:nx-text-gray-400,
html[class~="dark"] .nx-text-gray-500 {
color: #999 !important;
}
html[class~=dark] .folderAsHeader .nextra-sidebar-container ul li a {
color: #c5c5c5;
font-size: 1.05rem;
}
html[class~=dark] .dark\:nx-bg-\[linear-gradient\(1deg\,\#383838\,\#212121\)\]{
background: rgba(14,0,29)
}
html[class~="dark"] .dark\:bg-dark {
background-color: #0e0e0e;
}
html[class~="light"] body {
color: #0e0e0e;
}
html[class~="dark"] body {
color: #c5c5c5;
}
html[class~="dark"] p strong,
html[class~="dark"] h1,
html[class~="dark"] h2,
html[class~="dark"] h3,
html[class~="dark"] h4 {
color: #fff;
}
/* Link
------------------------ */
p a,
p li a {
text-decoration: underline;
text-decoration-thickness: 1px;
text-underline-offset: 0.01em;
text-decoration-color: var(--docs-accent-color-opacity);
}
p a:hover,
p li a:hover {
text-decoration-color: var(--docs-accent-color-link);
}
/* Nav
------------------------ */
.nextra-nav-container {
border-top: 4px solid var(--docs-accent-color);
}
.nextra-nav-container .nextra-nav-container-blur {
border: none;
box-shadow: none !important;
}
.nx-max-w-\[90rem\] {
max-width: 164rem !important;
}
/* Search Input
------------------------ */
html[class~="dark"] .nextra-search input,
html[class~="dark"] .nextra-search input:focus {
background-color: #110024;
border-color: #252525ff;
}
html[class~="dark"] .nextra-search input::placeholder {
color: #e5e5e560;
}
/* Sidebar
------------------------ */
.nextra-sidebar-container-menu {
border: none;
}
.nextra-sidebar-container > div {
margin-top: 10px;
padding-top: 0;
}
.nextra-toc-meta,
.nextra-sidebar-container-menu {
box-shadow: none !important;
}
.nextra-sidebar-container .nextra-scrollbar + div {
border-width: 0;
height: 4rem;
}
.nextra-toc ul li a,
.nextra-sidebar-container ul li.active > a,
.nextra-sidebar-container ul li.active > a:hover {
font-weight: normal;
}
html[class~="light"] .nextra-sidebar-container ul li a {
color: #0e0e0e;
}
html[class~="light"] .nextra-sidebar-container ul li a:hover,
html[class~="light"] .nextra-sidebar-container ul li.active > a:hover {
background-color: var(--docs-light-bg);
}
html[class~="dark"] .nextra-sidebar-container ul li a:hover,
html[class~="dark"] .nextra-sidebar-container ul li.active > a:hover {
background-color: var(--docs-dark-bg);
}
html[class~="dark"] .folderAsHeader .nextra-sidebar-container ul li a {
color: rgb(197, 197, 197);
font-size: 1.05rem;
}
html[class~="dark"] .folderAsHeader .nextra-sidebar-container ul li ul li a {
color: #999999;
font-size: 0.875rem;
}
html[class~="dark"] .folderAsHeader .nextra-sidebar-container ul li.active > a,
html[class~="dark"] .nextra-toc ul li a[aria-selected="true"],
html[class~="light"] .folderAsHeader .nextra-sidebar-container ul li.active > a,
html[class~="light"] .nextra-toc ul li a[aria-selected="true"] {
color: var(--docs-accent-color);
background-color: transparent;
}
html[class~="dark"] .nextra-sidebar-container ul li.active > a:hover,
html[class~="dark"] .nextra-toc ul li a[aria-selected="true"]:hover {
color: var(--docs-accent-color);
}
html[class~="dark"] .nx-text-primary-500,
html[class~="dark"] .nx-text-primary-600 {
color: var(--docs-accent-color);
}
html[class~="light"] .nx-text-primary-500,
html[class~="light"] .nx-text-primary-600 {
color: var(--docs-accent-color);
}
@media (max-width: 640px) {
html[class~="dark"] .folderAsHeader .nextra-sidebar-container ul li.active > a {
color: currentColor;
text-align: left;
}
.folderAsHeader .nextra-sidebar-container ul ul li a {
justify-content: normal;
}
}
/* Remove lines when you apply `.folderAsHeader` the class in the doc
*/
.folderAsHeader .nextra-sidebar-container ul ul {
padding-left: 0;
margin-left: 0;
margin: 0.3rem 0 1.2rem 0;
}
.folderAsHeader .nextra-sidebar-container ul div {
padding-left: 0;
}
.folderAsHeader .nextra-sidebar-container ul ul::before {
content: none;
}
.folderAsHeader .nextra-sidebar-container ul li a {
font-size: 16px;
}
/* arrow dropdown */
.folderAsHeader .nextra-sidebar-container a svg {
transition: opacity 100ms;
opacity: 0;
}
.folderAsHeader .nextra-sidebar-container a:hover svg {
opacity: 1;
}
svg:hover {
background: transparent !important;
}
/* Bold only on the header */
.folderAsHeader .nextra-sidebar-container ul > li > a,
.folderAsHeader .nextra-sidebar-container ul > li > a:hover {
font-weight: 600;
cursor: default;
line-height: 1.3;
}
.folderAsHeader .nextra-sidebar-container ul > li li a,
.folderAsHeader .nextra-sidebar-container ul > li li a:hover {
font-weight: normal;
cursor: pointer;
}
.folderAsHeader .nextra-sidebar-container ul li ul li a {
font-size: 14px;
}
.wip {
position: relative;
display: flex;
opacity: 0.5;
}
.wip:after {
content: "WIP";
border-radius: 2px;
padding: 2px;
font-size: 9px;
line-height: 13px;
position: absolute;
right: 0;
top: 50%;
transform: translate(0, -35%);
opacity: 0.6;
}
/* Content
------------------------ */
main div.mt-12 {
display: none;
}
.nextra-breadcrumb {
pointer-events: none;
display: none;
}
.nextra-navigation-links {
margin-top: 6rem;
padding-bottom: 4rem;
border: none;
}
html[class~="dark"] article p a,
html[class~="dark"] article li a,
html[class~="dark"] .dark\:hover\:text-primary-500:hover,
html[class~="light"] article p a,
html[class~="light"] article li a,
html[class~="light"] .dark\:hover\:text-primary-500:hover {
color: var(--docs-accent-color-link) !important;
}
/* Keyboard Shortcut
------------------------ */
p kbd {
border-radius: 4px;
font-size: 13px;
padding: 6px;
padding-bottom: 7px;
line-height: 14px;
font-weight: bold;
}
html[class~="light"] p kbd {
color: rgb(75, 85, 99);
background: rgb(75 85 99 / 12%);
box-shadow: rgb(75 85 99 / 24%) 0px -2px 0px inset;
}
html[class~="dark"] p kbd {
background: rgb(42 42 42);
box-shadow: rgb(255 255 255 / 12%) 0px -2px 0px inset;
color: #c5c5c5;
}
/* Inline Code Snippet
------------------------ */
html[class~="light"] p code {
background-color: var(--docs-light-bg);
border: solid 1px #e5e7eb;
}
html[class~="dark"] p code {
background-color: var(--docs-dark-bg);
border: solid 1px #373737;
color: #c5c5c5;
}
/* Callout
------------------------ */
.nextra-callout {
box-sizing: border-box;
border-radius: 6px;
padding: 16px;
display: flex;
align-items: flex-start;
}
.nextra-callout .pr-2 {
padding-right: 1rem;
}
html[class~="light"] .nextra-callout {
color: rgb(65 65 65 / 90%);
background-color: var(--docs-light-bg);
border: none !important;
}
html[class~="dark"] .nextra-callout {
border: none !important;
background: var(--docs-dark-bg) !important;
color: #999999 !important;
}
html[class~="dark"] .nextra-callout h4 {
color: #fff;
}
html[class~="light"] .nextra-callout h4 {
color: #000;
}
/* CTA Container
------------------------ */
.ctaContainer {
display: flex;
gap: 1.3rem;
margin: 2rem 0;
}
@media (max-width: 920px) {
.ctaContainer {
flex-direction: column;
}
}
/* Headings
------------------------ */
.cbs article h1 {
font-size: 3.5rem;
margin-top: 0;
line-height: 100%;
letter-spacing: -0.05em;
font-weight: bold;
}
@media (max-width: 640px) {
.cbs article h1 {
font-size: 3rem;
}
}
.cbs article h2 {
border: none;
font-size: 2rem;
line-height: 120%;
letter-spacing: -0.025em;
font-weight: bold;
}
.cbs article h2 .nx-absolute,
.cbs article h3 .nx-absolute {
margin-top: -7rem;
}
.cbs article h1:first-of-type {
margin-top: -0.16em;
}
.cbs article h2 {
margin-top: 2em;
}
.cbs article h2 + p:not(:first-child),
.cbs article h3 + p:not(:first-child) {
margin-top: 0.6rem;
}
.cbs article h3 {
margin-top: 1.5em;
}
.cbs article img {
border-radius: 4px;
}
.cbs article .subheading-anchor {
margin-top: -110px;
}
/* Code Snippet
------------------------ */
html[class~="light"] article pre {
background-color: var(--docs-light-bg);
border: solid 1px #e5e7eb;
}
html[class~="dark"] article pre {
background-color: var(--docs-dark-bg);
border: solid 1px #2a2a2a;
}
.blitz-logo {
display: inline;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
width: auto;
height: 3rem;
fill: currentColor;
}
html[class~=dark] body {
background-color: rgba(14,0,29,var(--tw-bg-opacity))
}
html[class~=dark] .dark\:nx-bg-dark{
background-color: rgba(14,0,29,var(--tw-bg-opacity)) !important;
}
/* Start of Shiki Twoslash CSS:
Code blocks structurally look like:
<pre class='shiki lsp twoslash [theme-name]'>
<div class='language-id'>[lang-id]</div>
<div class='code-container'>
<code>[the code as a series of spans]</code>
<a href='playground...'>Try</a> (optional)
</div>
</pre>
*/
pre {
/* In theory shiki will overwrite these, but this is to make sure there are defaults regardless */
background-color: white;
color: black;
/* Give it some space to breathe */
padding: 12px;
/* All code samples get a grey border, twoslash ones get a different color */
border-left: 1px solid #999;
border-bottom: 1px solid #999;
margin-bottom: 3rem;
/* Important to allow the code to move horizontally; */
overflow-x: auto;
position: relative;
}
pre.shiki {
overflow-x: auto;
}
pre.shiki:hover .dim {
opacity: 1;
}
pre.shiki div.dim {
opacity: 0.5;
}
pre.shiki div.dim, pre.shiki div.highlight {
margin: 0;
padding: 0;
}
pre.shiki div.highlight {
opacity: 1;
background-color: #f1f8ff;
}
pre.shiki div.line {
min-height: 1rem;
}
/** Don't show the language identifiers */
pre.shiki .language-id{
display: none;
}
/* Visually differentiates twoslash code samples */
pre.twoslash {
border-color: #719af4;
}
/** When you mouse over the pre, show the underlines */
pre.twoslash:hover data-lsp {
border-color: #747474;
}
/** The tooltip-like which provides the LSP response */
pre.twoslash data-lsp:hover::before {
content: attr(lsp);
position: absolute;
transform: translate(0, 1rem);
background-color: #3f3f3f;
color: #fff;
text-align: left;
padding: 5px 8px;
border-radius: 2px;
font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, monospace;
font-size: 14px;
white-space: pre-wrap;
z-index: 100;
}
pre .code-container {
overflow: auto;
}
/* The try button */
pre .code-container > a {
position: absolute;
right: 8px;
bottom: 8px;
border-radius: 4px;
border: 1px solid #719af4;
padding: 0 8px;
color: #719af4;
text-decoration: none;
opacity: 0;
transition-timing-function: ease;
transition: opacity 0.3s;
}
/* Respect no animations */
@media (prefers-reduced-motion: reduce) {
pre .code-container > a {
transition: none;
}
}
pre .code-container > a:hover {
color: white;
background-color: #719af4;
}
pre .code-container:hover a {
opacity: 1;
}
pre code {
font-size: 15px;
font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, monospace;;
white-space: pre;
-webkit-overflow-scrolling: touch;
}
pre code a {
text-decoration: none;
}
pre data-err {
/* Extracted from VS Code */
background: url("data:image/svg+xml,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%206%203'%20enable-background%3D'new%200%200%206%203'%20height%3D'3'%20width%3D'6'%3E%3Cg%20fill%3D'%23c94824'%3E%3Cpolygon%20points%3D'5.5%2C0%202.5%2C3%201.1%2C3%204.1%2C0'%2F%3E%3Cpolygon%20points%3D'4%2C0%206%2C2%206%2C0.6%205.4%2C0'%2F%3E%3Cpolygon%20points%3D'0%2C2%201%2C3%202.4%2C3%200%2C0.6'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E") repeat-x bottom left;
padding-bottom: 3px;
}
pre .query {
margin-bottom: 10px;
color: #137998;
display: inline-block;
}
/* In order to have the 'popped out' style design and to not break the layout
/* we need to place a fake and un-selectable copy of the error which _isn't_ broken out
/* behind the actual error message.
/* This sections keeps both of those two in in sync */
pre .error, pre .error-behind {
margin-left: -14px;
margin-top: 8px;
margin-bottom: 4px;
padding: 6px;
padding-left: 14px;
width: calc(100% - 20px);
white-space: pre-wrap;
display: block;
}
pre .error {
position: absolute;
background-color: #fee;
border-left: 2px solid #bf1818;
/* Give the space to the error code */
display: flex;
align-items: center;
color: black;
}
pre .error .code {
display: none;
}
pre .error-behind {
user-select: none;
visibility: transparent;
color: #fee;
}
/* Queries */
pre .arrow {
/* Transparent background */
background-color: #eee;
position: relative;
top: -7px;
margin-left: 0.1rem;
/* Edges */
border-left: 1px solid #eee;
border-top: 1px solid #eee;
transform: translateY(25%) rotate(45deg);
/* Size */
height: 8px;
width: 8px;
}
pre .popover {
margin-bottom: 10px;
background-color: #eee;
display: inline-block;
padding: 0 0.5rem 0.3rem;
margin-top: 10px;
border-radius: 3px;
}
/* Completion */
pre .inline-completions ul.dropdown {
display: inline-block;
position: absolute;
width: 240px;
background-color: gainsboro;
color: grey;
padding-top: 4px;
font-family: var(--code-font);
font-size: 0.8rem;
margin: 0;
padding: 0;
border-left: 4px solid #4b9edd;
}
pre .inline-completions ul.dropdown::before {
background-color: #4b9edd;
width: 2px;
position: absolute;
top: -1.2rem;
left: -3px;
content: " ";
}
pre .inline-completions ul.dropdown li {
overflow-x: hidden;
padding-left: 4px;
margin-bottom: 4px;
}
pre .inline-completions ul.dropdown li.deprecated {
text-decoration: line-through;
}
pre .inline-completions ul.dropdown li span.result-found {
color: #4b9edd;
}
pre .inline-completions ul.dropdown li span.result {
width: 100px;
color: black;
display: inline-block;
}
.dark-theme .markdown pre {
background-color: #d8d8d8;
border-color: #ddd;
filter: invert(98%) hue-rotate(180deg);
}
data-lsp {
/* Ensures there's no 1px jump when the hover happens */
border-bottom: 1px dotted transparent;
/* Fades in unobtrusively */
transition-timing-function: ease;
transition: border-color 0.3s;
}
/* Respect people's wishes to not have animations */
@media (prefers-reduced-motion: reduce) {
data-lsp {
transition: none;
}
}
/** Annotations support, providing a tool for meta commentary */
.tag-container {
position: relative;
}
.tag-container .twoslash-annotation {
position: absolute;
font-family: "JetBrains Mono", Menlo, Monaco, Consolas, Courier New, monospace;
right: -10px;
/** Default annotation text to 200px */
width: 200px;
color: #187abf;
background-color: #fcf3d9 bb;
}
.tag-container .twoslash-annotation p {
text-align: left;
font-size: 0.8rem;
line-height: 0.9rem;
}
.tag-container .twoslash-annotation svg {
float: left;
margin-left: -44px;
}
.tag-container .twoslash-annotation.left {
right: auto;
left: -200px;
}
.tag-container .twoslash-annotation.left svg {
float: right;
margin-right: -5px;
}
/** Support for showing console log/warn/errors inline */
pre .logger {
display: flex;
align-items: center;
color: black;
padding: 6px;
padding-left: 8px;
width: calc(100% - 19px);
white-space: pre-wrap;
}
pre .logger svg {
margin-right: 9px;
}
pre .logger.error-log {
background-color: #fee;
border-left: 2px solid #bf1818;
}
pre .logger.warn-log {
background-color: #ffe;
border-left: 2px solid #eae662;
}
pre .logger.log-log {
background-color: #e9e9e9;
border-left: 2px solid #ababab;
}
pre .logger.log-log svg {
margin-left: 6px;
margin-right: 9px;
}

6
docs/tailwind.config.js Normal file
View File

@@ -0,0 +1,6 @@
module.exports = {
content: [
"./src/**/*.{md,mdx,css,js,jsx}",
"./theme.config.jsx",
],
};

85
docs/theme.config.tsx Normal file
View File

@@ -0,0 +1,85 @@
const Logo = (props) => {
return (
<svg viewBox="0 0 165 66">
<path d="M104.292 56.033C104.292 56.408 104.206 56.6636 104.036 56.8C103.9 56.9363 103.627 57.0045 103.218 57.0045H99.7409C99.4001 57.0045 99.1615 56.9533 99.0251 56.8511C98.8888 56.7147 98.8206 56.4932 98.8206 56.1864L98.9229 19.8324C98.9229 19.3211 99.1444 19.0654 99.5876 19.0654H103.627C103.839 19.0654 104.292 19.0672 104.292 19.0672V19.8324V56.033ZM64.3531 57.0081C64.1145 57.0081 63.927 56.9399 63.7906 56.8035C63.6543 56.6672 63.5861 56.4968 63.5861 56.2922V19.9383C63.5861 19.3588 63.8588 19.069 64.4042 19.069H76.829C81.533 19.069 85.1463 19.9212 87.6687 21.6256C90.1912 23.2958 91.4524 25.7331 91.4524 28.9373C91.4524 30.9484 90.924 32.6528 89.8673 34.0504C88.8106 35.4138 87.1063 36.5217 84.7543 37.3739C84.6179 37.4079 84.5497 37.4932 84.5497 37.6295C84.5497 37.7318 84.6179 37.7999 84.7543 37.834C87.2767 38.5158 89.1686 39.5895 90.4298 41.0553C91.7251 42.521 92.3727 44.4469 92.3727 46.833C92.3727 50.2418 91.0945 52.7983 88.5379 54.5027C85.9814 56.1729 82.2318 57.0081 77.2892 57.0081H64.3531ZM77.5448 35.5843C79.6923 35.5843 81.516 35.1071 83.0158 34.1526C84.5157 33.1982 85.2656 31.6983 85.2656 29.6531C85.2656 27.6079 84.5157 26.0569 83.0158 25.0002C81.5501 23.9435 79.5219 23.4151 76.9313 23.4151H70.5399C70.0286 23.4151 69.7729 23.6367 69.7729 24.0798V34.8684C69.7729 35.3457 69.9604 35.5843 70.3354 35.5843H77.5448ZM77.0335 52.662C82.9647 52.662 85.9303 50.5997 85.9303 46.4751C85.9303 44.3276 85.1633 42.7255 83.6294 41.6688C82.0955 40.6121 80.0673 40.0838 77.5448 40.0838H70.591C70.2843 40.0838 70.0627 40.1349 69.9263 40.2372C69.8241 40.3394 69.7729 40.5099 69.7729 40.7485V51.895C69.7729 52.4063 69.9604 52.662 70.3354 52.662H77.0335ZM142.707 56.8624C142.81 56.9647 142.997 57.0158 143.27 57.0158H163.876C164.387 57.0158 164.643 56.7772 164.643 56.3V53.948V53.3344H163.978H149.866C149.593 53.3344 149.457 53.2492 149.457 53.0788C149.457 52.9765 149.508 52.8572 149.61 52.7208L163.876 33.8536C164.251 33.2741 164.438 32.7628 164.438 32.3197V30.479V29.9144C164.438 29.9144 164.051 29.9165 163.876 29.9165H144.241C143.866 29.9165 143.679 30.121 143.679 30.5301V32.831C143.679 33.1037 143.713 33.2911 143.781 33.3934C143.883 33.4957 144.071 33.5468 144.344 33.5468H157.075C157.382 33.5468 157.535 33.632 157.535 33.8025L157.382 34.1092L143.219 52.9765C142.946 53.3515 142.759 53.6412 142.656 53.8457C142.588 54.0502 142.554 54.3059 142.554 54.6127V56.3C142.554 56.5727 142.605 56.7602 142.707 56.8624ZM116.929 19.0676H111.51V27.7684C114.503 27.7684 116.929 25.3419 116.929 22.3486V19.0676ZM116.926 56.0308C116.926 56.4058 116.841 56.6614 116.67 56.7978C116.534 56.9341 116.278 57.0023 115.903 57.0023H112.427C112.086 57.0023 111.847 56.9512 111.711 56.8489C111.574 56.7126 111.506 56.491 111.506 56.1842V30.6699C111.506 30.3972 111.557 30.2098 111.66 30.1075C111.762 29.9712 111.949 29.903 112.222 29.903H117.028L116.926 56.0308ZM132.183 34.3137C132.183 33.9728 132.336 33.8024 132.643 33.8024H138.779C139.256 33.8024 139.495 33.5979 139.495 33.1888V30.4789V29.9165H138.881H132.745C132.439 29.9165 132.285 29.7631 132.285 29.4563V21.531V20.713L131.621 20.7129H128.093C127.752 20.7129 127.547 20.9515 127.479 21.4288L126.865 29.4563C126.865 29.7631 126.729 29.9165 126.456 29.9165H122.366C121.957 29.9165 121.752 30.1039 121.752 30.4789V33.1888C121.752 33.5979 121.974 33.8024 122.417 33.8024H126.252C126.593 33.8024 126.763 34.0069 126.763 34.416V50.6244C126.763 52.806 127.309 54.4252 128.399 55.4819C129.49 56.5045 131.16 57.0158 133.41 57.0158C135.796 57.0158 137.535 56.9306 138.625 56.7601C139.137 56.6579 139.392 56.3681 139.392 55.8909V53.6923V53.0787H138.779H135.507C134.348 53.0787 133.495 52.806 132.95 52.2606C132.439 51.7152 132.183 50.7267 132.183 49.295V34.3137Z" />
<path d="M0.241243 33.2639H10.9742C15.0585 33.2639 18.9054 35.1835 21.3612 38.4471L31.9483 52.5165C32.1484 52.7824 32.1786 53.1393 32.026 53.435L25.9232 65.2592C25.6304 65.8265 24.8455 65.8932 24.4612 65.3835L0.241243 33.2639Z" />
<path d="M42.4727 33.2822H31.7398C27.6555 33.2822 23.8086 31.3626 21.3528 28.0991L10.7656 14.0297C10.5656 13.7638 10.5354 13.4068 10.688 13.1111L16.7908 1.28696C17.0836 0.719654 17.8684 0.652924 18.2528 1.16266L42.4727 33.2822Z" />
</svg>
)
}
import {useConfig} from "nextra-theme-docs"
const OG_IMAGE_URL = "https://codesandbox.io/docs/projects/og-image.jpg"
export default {
project: {
link: 'https://github.com/blitz-js/blitz',
},
footer: {component: null},
feedback: {content: null},
editLink: {text: "Edit this page on GitHub →"},
docsRepositoryBase: "https://github.com/blitz-js/blitz",
useNextSeoProps() {
return {
titleTemplate: "%s Blitzjs",
}
},
head() {
const {frontMatter} = useConfig()
return (
<>
{/* Favicons, meta */}
<meta httpEquiv="Content-Language" content="en" />
<meta
name="description"
content={
frontMatter.description ||
"Experience the future of web development and build projects anywhere and anytime with your team."
}
/>
<meta
name="og:description"
content={
frontMatter.description ||
"Experience the future of web development and build projects anywhere and anytime with your team."
}
/>
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@blitzjs" />
<meta name="twitter:image" content={OG_IMAGE_URL} />
<meta
name="og:title"
content={frontMatter.title ? frontMatter.title + " Blitz" : "Blitz Documentation"}
/>
<meta name="og:image" content={OG_IMAGE_URL} />
</>
)
},
logo: (
<svg viewBox="0 0 165 66" className="blitz-logo">
<path d="M104.292 56.033C104.292 56.408 104.206 56.6636 104.036 56.8C103.9 56.9363 103.627 57.0045 103.218 57.0045H99.7409C99.4001 57.0045 99.1615 56.9533 99.0251 56.8511C98.8888 56.7147 98.8206 56.4932 98.8206 56.1864L98.9229 19.8324C98.9229 19.3211 99.1444 19.0654 99.5876 19.0654H103.627C103.839 19.0654 104.292 19.0672 104.292 19.0672V19.8324V56.033ZM64.3531 57.0081C64.1145 57.0081 63.927 56.9399 63.7906 56.8035C63.6543 56.6672 63.5861 56.4968 63.5861 56.2922V19.9383C63.5861 19.3588 63.8588 19.069 64.4042 19.069H76.829C81.533 19.069 85.1463 19.9212 87.6687 21.6256C90.1912 23.2958 91.4524 25.7331 91.4524 28.9373C91.4524 30.9484 90.924 32.6528 89.8673 34.0504C88.8106 35.4138 87.1063 36.5217 84.7543 37.3739C84.6179 37.4079 84.5497 37.4932 84.5497 37.6295C84.5497 37.7318 84.6179 37.7999 84.7543 37.834C87.2767 38.5158 89.1686 39.5895 90.4298 41.0553C91.7251 42.521 92.3727 44.4469 92.3727 46.833C92.3727 50.2418 91.0945 52.7983 88.5379 54.5027C85.9814 56.1729 82.2318 57.0081 77.2892 57.0081H64.3531ZM77.5448 35.5843C79.6923 35.5843 81.516 35.1071 83.0158 34.1526C84.5157 33.1982 85.2656 31.6983 85.2656 29.6531C85.2656 27.6079 84.5157 26.0569 83.0158 25.0002C81.5501 23.9435 79.5219 23.4151 76.9313 23.4151H70.5399C70.0286 23.4151 69.7729 23.6367 69.7729 24.0798V34.8684C69.7729 35.3457 69.9604 35.5843 70.3354 35.5843H77.5448ZM77.0335 52.662C82.9647 52.662 85.9303 50.5997 85.9303 46.4751C85.9303 44.3276 85.1633 42.7255 83.6294 41.6688C82.0955 40.6121 80.0673 40.0838 77.5448 40.0838H70.591C70.2843 40.0838 70.0627 40.1349 69.9263 40.2372C69.8241 40.3394 69.7729 40.5099 69.7729 40.7485V51.895C69.7729 52.4063 69.9604 52.662 70.3354 52.662H77.0335ZM142.707 56.8624C142.81 56.9647 142.997 57.0158 143.27 57.0158H163.876C164.387 57.0158 164.643 56.7772 164.643 56.3V53.948V53.3344H163.978H149.866C149.593 53.3344 149.457 53.2492 149.457 53.0788C149.457 52.9765 149.508 52.8572 149.61 52.7208L163.876 33.8536C164.251 33.2741 164.438 32.7628 164.438 32.3197V30.479V29.9144C164.438 29.9144 164.051 29.9165 163.876 29.9165H144.241C143.866 29.9165 143.679 30.121 143.679 30.5301V32.831C143.679 33.1037 143.713 33.2911 143.781 33.3934C143.883 33.4957 144.071 33.5468 144.344 33.5468H157.075C157.382 33.5468 157.535 33.632 157.535 33.8025L157.382 34.1092L143.219 52.9765C142.946 53.3515 142.759 53.6412 142.656 53.8457C142.588 54.0502 142.554 54.3059 142.554 54.6127V56.3C142.554 56.5727 142.605 56.7602 142.707 56.8624ZM116.929 19.0676H111.51V27.7684C114.503 27.7684 116.929 25.3419 116.929 22.3486V19.0676ZM116.926 56.0308C116.926 56.4058 116.841 56.6614 116.67 56.7978C116.534 56.9341 116.278 57.0023 115.903 57.0023H112.427C112.086 57.0023 111.847 56.9512 111.711 56.8489C111.574 56.7126 111.506 56.491 111.506 56.1842V30.6699C111.506 30.3972 111.557 30.2098 111.66 30.1075C111.762 29.9712 111.949 29.903 112.222 29.903H117.028L116.926 56.0308ZM132.183 34.3137C132.183 33.9728 132.336 33.8024 132.643 33.8024H138.779C139.256 33.8024 139.495 33.5979 139.495 33.1888V30.4789V29.9165H138.881H132.745C132.439 29.9165 132.285 29.7631 132.285 29.4563V21.531V20.713L131.621 20.7129H128.093C127.752 20.7129 127.547 20.9515 127.479 21.4288L126.865 29.4563C126.865 29.7631 126.729 29.9165 126.456 29.9165H122.366C121.957 29.9165 121.752 30.1039 121.752 30.4789V33.1888C121.752 33.5979 121.974 33.8024 122.417 33.8024H126.252C126.593 33.8024 126.763 34.0069 126.763 34.416V50.6244C126.763 52.806 127.309 54.4252 128.399 55.4819C129.49 56.5045 131.16 57.0158 133.41 57.0158C135.796 57.0158 137.535 56.9306 138.625 56.7601C139.137 56.6579 139.392 56.3681 139.392 55.8909V53.6923V53.0787H138.779H135.507C134.348 53.0787 133.495 52.806 132.95 52.2606C132.439 51.7152 132.183 50.7267 132.183 49.295V34.3137Z" />
<path d="M0.241243 33.2639H10.9742C15.0585 33.2639 18.9054 35.1835 21.3612 38.4471L31.9483 52.5165C32.1484 52.7824 32.1786 53.1393 32.026 53.435L25.9232 65.2592C25.6304 65.8265 24.8455 65.8932 24.4612 65.3835L0.241243 33.2639Z" />
<path d="M42.4727 33.2822H31.7398C27.6555 33.2822 23.8086 31.3626 21.3528 28.0991L10.7656 14.0297C10.5656 13.7638 10.5354 13.4068 10.688 13.1111L16.7908 1.28696C17.0836 0.719654 17.8684 0.652924 18.2528 1.16266L42.4727 33.2822Z" />
</svg>
),
banner: {
key: "2.0-release",
text: (
<a href="https://flightcontrol.dev/?ref=blitzjs" target="_blank">
🚀 Announcing Flightcontrol - Easily Deploy Blitz.js and Next.js to AWS 🚀
</a>
),
dismissible: false
},
sidebar: {
toggleButton: true,
},
chat: {
link: 'https://discord.blitzjs.com',
},
}

20
docs/tsconfig.json Normal file
View File

@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"incremental": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve"
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules"]
}

View File

@@ -17,17 +17,17 @@
"prisma:studio": "prisma studio"
},
"dependencies": {
"@blitzjs/auth": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/next": "workspace:2.0.0-beta.22",
"@blitzjs/rpc": "workspace:2.0.0-beta.22",
"@blitzjs/auth": "workspace:2.0.0-beta.23",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@blitzjs/next": "workspace:2.0.0-beta.23",
"@blitzjs/rpc": "workspace:2.0.0-beta.23",
"@hookform/error-message": "2.0.0",
"@hookform/resolvers": "2.9.10",
"@prisma/client": "4.6.0",
"blitz": "workspace:2.0.0-beta.22",
"@prisma/client": "4.6.1",
"blitz": "workspace:2.0.0-beta.23",
"delay": "5.0.0",
"next": "12.2.5",
"prisma": "4.6.0",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hook-form": "7.39.1",

View File

@@ -17,14 +17,14 @@
"prisma:studio": "prisma studio"
},
"dependencies": {
"@blitzjs/auth": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/next": "workspace:2.0.0-beta.22",
"@prisma/client": "4.6.0",
"blitz": "workspace:2.0.0-beta.22",
"@blitzjs/auth": "workspace:2.0.0-beta.23",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@blitzjs/next": "workspace:2.0.0-beta.23",
"@prisma/client": "4.6.1",
"blitz": "workspace:2.0.0-beta.23",
"lowdb": "3.0.0",
"next": "12.2.5",
"prisma": "4.6.0",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"
},

View File

@@ -16,19 +16,19 @@
"schema": "db/schema.prisma"
},
"dependencies": {
"@blitzjs/auth": "workspace:2.0.0-beta.22",
"@blitzjs/next": "workspace:2.0.0-beta.22",
"@blitzjs/rpc": "workspace:2.0.0-beta.22",
"@prisma/client": "4.6.0",
"blitz": "workspace:2.0.0-beta.22",
"@blitzjs/auth": "workspace:2.0.0-beta.23",
"@blitzjs/next": "workspace:2.0.0-beta.23",
"@blitzjs/rpc": "workspace:2.0.0-beta.23",
"@prisma/client": "4.6.1",
"blitz": "workspace:2.0.0-beta.23",
"lowdb": "3.0.0",
"next": "12.2.5",
"prisma": "4.6.0",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@next/bundle-analyzer": "12.0.8",
"@types/express": "4.17.13",
"@types/fs-extra": "9.0.13",

View File

@@ -1,2 +1,3 @@
SESSION_SECRET_KEY=hsdenhJfpLHrGjgdgg3jdF8g2bYD2PaQ
HEADLESS=true
HEADLESS=true
VITE_BLITZ_TEST_ENVIRONMENT=true

View File

@@ -11,10 +11,10 @@
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next"
},
"dependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/next": "workspace:2.0.0-beta.22",
"@blitzjs/rpc": "workspace:2.0.0-beta.22",
"blitz": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@blitzjs/next": "workspace:2.0.0-beta.23",
"@blitzjs/rpc": "workspace:2.0.0-beta.23",
"blitz": "workspace:2.0.0-beta.23",
"next": "12.2.5",
"react": "18.2.0",
"react-dom": "18.2.0"

View File

@@ -16,19 +16,19 @@
"prisma:studio": "prisma studio"
},
"dependencies": {
"@blitzjs/auth": "workspace:2.0.0-beta.22",
"@blitzjs/next": "workspace:2.0.0-beta.22",
"@blitzjs/rpc": "workspace:2.0.0-beta.22",
"@prisma/client": "4.6.0",
"blitz": "workspace:2.0.0-beta.22",
"@blitzjs/auth": "workspace:2.0.0-beta.23",
"@blitzjs/next": "workspace:2.0.0-beta.23",
"@blitzjs/rpc": "workspace:2.0.0-beta.23",
"@prisma/client": "4.6.1",
"blitz": "workspace:2.0.0-beta.23",
"lowdb": "3.0.0",
"next": "12.2.5",
"prisma": "4.6.0",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@next/bundle-analyzer": "12.0.8",
"@types/express": "4.17.13",
"@types/fs-extra": "9.0.13",

View File

@@ -0,0 +1 @@
VITE_BLITZ_TEST_ENVIRONMENT=true

View File

@@ -8,15 +8,15 @@
"clean": "rm -rf .turbo && rm -rf node_modules"
},
"dependencies": {
"@blitzjs/auth": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/next": "workspace:2.0.0-beta.22",
"@blitzjs/rpc": "workspace:2.0.0-beta.22",
"@prisma/client": "4.6.0",
"@blitzjs/auth": "workspace:2.0.0-beta.23",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@blitzjs/next": "workspace:2.0.0-beta.23",
"@blitzjs/rpc": "workspace:2.0.0-beta.23",
"@prisma/client": "4.6.1",
"@tanstack/react-query": "4.0.10",
"blitz": "workspace:2.0.0-beta.22",
"blitz": "workspace:2.0.0-beta.23",
"next": "12.2.5",
"prisma": "4.6.0",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"
},

View File

@@ -16,18 +16,18 @@
"schema": "db/schema.prisma"
},
"dependencies": {
"@blitzjs/next": "workspace:2.0.0-beta.22",
"@blitzjs/rpc": "workspace:2.0.0-beta.22",
"@prisma/client": "4.6.0",
"blitz": "workspace:2.0.0-beta.22",
"@blitzjs/next": "workspace:2.0.0-beta.23",
"@blitzjs/rpc": "workspace:2.0.0-beta.23",
"@prisma/client": "4.6.1",
"blitz": "workspace:2.0.0-beta.23",
"lowdb": "3.0.0",
"next": "12.2.5",
"prisma": "4.6.0",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@next/bundle-analyzer": "12.0.8",
"@types/express": "4.17.13",
"@types/fs-extra": "9.0.13",

View File

@@ -7,10 +7,10 @@
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next"
},
"dependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/next": "workspace:2.0.0-beta.22",
"@blitzjs/rpc": "workspace:2.0.0-beta.22",
"blitz": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@blitzjs/next": "workspace:2.0.0-beta.23",
"@blitzjs/rpc": "workspace:2.0.0-beta.23",
"blitz": "workspace:2.0.0-beta.23",
"next": "12.2.5",
"react": "18.2.0",
"react-dom": "18.2.0"

View File

@@ -0,0 +1 @@
VITE_BLITZ_TEST_ENVIRONMENT=true

View File

@@ -7,10 +7,10 @@
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next"
},
"dependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/next": "workspace:2.0.0-beta.22",
"@blitzjs/rpc": "workspace:2.0.0-beta.22",
"blitz": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@blitzjs/next": "workspace:2.0.0-beta.23",
"@blitzjs/rpc": "workspace:2.0.0-beta.23",
"blitz": "workspace:2.0.0-beta.23",
"next": "12.2.5",
"react": "18.2.0",
"react-dom": "18.2.0"

View File

@@ -16,19 +16,19 @@
"schema": "db/schema.prisma"
},
"dependencies": {
"@blitzjs/auth": "workspace:2.0.0-beta.22",
"@blitzjs/next": "workspace:2.0.0-beta.22",
"@blitzjs/rpc": "workspace:2.0.0-beta.22",
"@prisma/client": "4.6.0",
"blitz": "workspace:2.0.0-beta.22",
"@blitzjs/auth": "workspace:2.0.0-beta.23",
"@blitzjs/next": "workspace:2.0.0-beta.23",
"@blitzjs/rpc": "workspace:2.0.0-beta.23",
"@prisma/client": "4.6.1",
"blitz": "workspace:2.0.0-beta.23",
"lowdb": "3.0.0",
"next": "12.2.5",
"prisma": "4.6.0",
"prisma": "4.6.1",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@next/bundle-analyzer": "12.0.8",
"@types/express": "4.17.13",
"@types/fs-extra": "9.0.13",

View File

@@ -3,6 +3,7 @@
"version": "0.0.0",
"private": true,
"workspaces": [
"docs/*",
"apps/*",
"packages/*",
"integration-tests/*",
@@ -19,7 +20,7 @@
"clean": "turbo run clean && rm -rf node_modules",
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
"pre-publish": "changeset add && changeset version && pnpm build && git add . && git commit -v",
"release": "pnpm build && changeset publish",
"release": "cp README.md packages/blitz && pnpm build && changeset publish",
"publish-release": "changeset publish && git push --follow-tags"
},
"dependencies": {

View File

@@ -1,5 +1,18 @@
# @blitzjs/auth
## 2.0.0-beta.23
### Major Changes
- 42a2cf951: BREAKING CHANGE: secure-password is now an `optional peerDependency`, if you are using `SecurePassword` api, you need to now install `secure-password` in your application.
This helps users who do not use SecurePassword from having native package build issues.
### Patch Changes
- Updated dependencies [c3c789740]
- blitz@2.0.0-beta.23
## 2.0.0-beta.22
### Minor Changes

View File

@@ -0,0 +1,90 @@
[![Blitz.js](https://raw.githubusercontent.com/blitz-js/art/master/github-cover-photo.png)](https://blitzjs.com)
<!-- prettier-ignore-start -->
<p align="center">
<a aria-label="Join our Discord Community" href="https://discord.blitzjs.com">
<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-403-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/main/LICENSE">
<img alt="" src="https://img.shields.io/npm/l/blitz.svg?style=for-the-badge&labelColor=000000&color=blue">
</a>
<a aria-label="NPM version" href="https://www.npmjs.com/package/@blitzjs/auth">
<img alt="" src="https://img.shields.io/npm/v/blitz.svg?style=for-the-badge&labelColor=000000&color=E65528">
</a>
</p>
<!-- prettier-ignore-end -->
<br>
<h1 align="center">
Blitz Auth - Framework Agnostic Authentication
</h1>
<br>
### [Documentation Link](https://blitzjs.com/docs/auth)
### [GitHub Link](https://github.com/blitz-js/blitz/tree/main/packages/blitz-auth)
### Quick Start
#### Install Blitz Auth
```bash
`npm i @blitzjs/auth`
# yarn add @blitzjs/auth
# pnpm add @blitzjs/auth
```
_You can alternatively use [`npx`](https://www.npmjs.com/package/npx)_
### Framework Support
Currently Blitz Auth usage is only documented with Next.js. We are working on adding additional support for other frameworks.
#### Setup Blitz Auth in Next.js
##### Client setup
Add the following to your blitz-client.ts file:
```ts
import {AuthClientPlugin} from "@blitzjs/auth"
import {setupBlitzClient} from "@blitzjs/next"
export const authConfig = {
cookiePrefix: "testapp",
}
const {withBlitz} = setupBlitzClient({
plugins: [AuthClientPlugin(authConfig)],
})
export {withBlitz}
```
##### Server setup
Then, add the following to the blitz-server.ts file:
```ts
import {setupBlitzServer} from "@blitzjs/next"
import {AuthServerPlugin, PrismaStorage, simpleRolesIsAuthorized} from "@blitzjs/auth"
import {db} from "db"
import {authConfig} from "./blitz-client"
const {gSSP, gSP, api} = setupBlitzServer({
plugins: [
AuthServerPlugin({
...authConfig,
storage: PrismaStorage(db),
isAuthorized: simpleRolesIsAuthorized,
}),
],
})
export {gSSP, gSP, api}
```

View File

@@ -1,6 +1,11 @@
{
"name": "@blitzjs/auth",
"version": "2.0.0-beta.22",
"version": "2.0.0-beta.23",
"homepage": "https://blitzjs.com/",
"repository": {
"type": "git",
"url": "https://github.com/blitz-js/blitz.git"
},
"scripts": {
"build": "unbuild",
"predev": "wait-on -d 250 ../blitz/dist/index-server.d.ts",
@@ -30,19 +35,24 @@
"cookie-session": "2.0.0",
"debug": "4.3.3",
"http": "0.0.1-security",
"jsonwebtoken": "8.5.1",
"jsonwebtoken": "9.0.0",
"nanoid": "3.2.0",
"passport": "0.5.2",
"passport": "0.6.0",
"path": "0.12.7",
"secure-password": "4.0.0",
"supports-color": "8.1.1",
"url": "0.11.0"
},
"peerDependencies": {
"blitz": "2.0.0-beta.22"
"blitz": "2.0.0-beta.23",
"secure-password": "4.0.0"
},
"peerDependenciesMeta": {
"secure-password": {
"optional": true
}
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@testing-library/react": "13.4.0",
"@testing-library/react-hooks": "8.0.1",
"@types/cookie": "0.4.1",
@@ -50,9 +60,10 @@
"@types/jsonwebtoken": "8.5.8",
"@types/react": "18.0.25",
"@types/react-dom": "17.0.14",
"blitz": "2.0.0-beta.22",
"blitz": "2.0.0-beta.23",
"react": "18.2.0",
"react-dom": "18.2.0",
"secure-password": "4.0.0",
"typescript": "^4.8.4",
"unbuild": "0.7.6",
"watch": "1.0.2"

View File

@@ -1,43 +1,8 @@
import * as crypto from "crypto"
import {nanoid} from "nanoid"
import SecurePasswordLib from "secure-password"
import {AuthenticationError} from "blitz"
export const hash256 = (input: string = "") => {
return crypto.createHash("sha256").update(input).digest("hex")
}
export const generateToken = (numberOfCharacters: number = 32) => nanoid(numberOfCharacters)
const SP = () => new SecurePasswordLib()
export const SecurePassword = {
...SecurePasswordLib,
async hash(password: string | null | undefined) {
if (!password) {
throw new AuthenticationError()
}
const hashedBuffer = await SP().hash(Buffer.from(password))
return hashedBuffer.toString("base64")
},
async verify(hashedPassword: string | null | undefined, password: string | null | undefined) {
if (!hashedPassword || !password) {
throw new AuthenticationError()
}
try {
const result = await SP().verify(Buffer.from(password), Buffer.from(hashedPassword, "base64"))
// Return result for valid results.
switch (result) {
case SecurePassword.VALID:
case SecurePassword.VALID_NEEDS_REHASH:
return result
default:
// For everything else throw AuthenticationError
throw new AuthenticationError()
}
} catch (error) {
// Could be error like failed to hash password
throw new AuthenticationError()
}
},
}

View File

@@ -2,3 +2,4 @@ export * from "./auth-sessions"
export * from "./auth-utils"
export * from "./auth-plugin"
export * from "./passport-adapter"
export * from "./secure-password"

View File

@@ -1,5 +1,5 @@
import {expect, describe, it} from "vitest"
import {SecurePassword} from "./auth-utils"
import {SecurePassword} from "./secure-password"
describe("SecurePassword", () => {
describe("hash", () => {

View File

@@ -0,0 +1,35 @@
import SecurePasswordLib from "secure-password"
import {AuthenticationError} from "blitz"
const SP = () => new SecurePasswordLib()
export const SecurePassword = {
...SecurePasswordLib,
async hash(password: string | null | undefined) {
if (!password) {
throw new AuthenticationError()
}
const hashedBuffer = await SP().hash(Buffer.from(password))
return hashedBuffer.toString("base64")
},
async verify(hashedPassword: string | null | undefined, password: string | null | undefined) {
if (!hashedPassword || !password) {
throw new AuthenticationError()
}
try {
const result = await SP().verify(Buffer.from(password), Buffer.from(hashedPassword, "base64"))
// Return result for valid results.
switch (result) {
case SecurePassword.VALID:
case SecurePassword.VALID_NEEDS_REHASH:
return result
default:
// For everything else throw AuthenticationError
throw new AuthenticationError()
}
} catch (error) {
// Could be error like failed to hash password
throw new AuthenticationError()
}
},
}

View File

@@ -1,5 +1,13 @@
# @blitzjs/next
## 2.0.0-beta.23
### Patch Changes
- Updated dependencies [c3c789740]
- blitz@2.0.0-beta.23
- @blitzjs/rpc@2.0.0-beta.23
## 2.0.0-beta.22
### Patch Changes

View File

@@ -0,0 +1,394 @@
[![Blitz.js](https://raw.githubusercontent.com/blitz-js/art/master/github-cover-photo.png)](https://blitzjs.com)
<!-- prettier-ignore-start -->
<p align="center">
<a aria-label="Join our Discord Community" href="https://discord.blitzjs.com">
<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-403-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/main/LICENSE">
<img alt="" src="https://img.shields.io/npm/l/blitz.svg?style=for-the-badge&labelColor=000000&color=blue">
</a>
<a aria-label="NPM version" href="https://www.npmjs.com/package/@blitzjs/next">
<img alt="" src="https://img.shields.io/npm/v/blitz.svg?style=for-the-badge&labelColor=000000&color=E65528">
</a>
</p>
<!-- prettier-ignore-end -->
<br>
<h1 align="center">
Blitz Adapter for Next.js
</h1>
<br>
### [Blitzjs Website](https://blitzjs.com)
### [GitHub](https://github.com/blitz-js/blitz/tree/main/packages/blitz-next)
## Overview
The `@blitzjs/next` adapter exposes functions & components specific for
the Next.js framework.
## Setup
You can install `@blitzjs/next` by running the following command:
```bash
npm i @blitzjs/next # yarn add @blitzjs/next # pnpm add @blitzjs/next
```
### Next Config
Blitz.js extends the `next.config.js` file by accepting a `blitz`
property.
```ts
blitz?: {
resolverPath?: ResolverPathOptions;
customServer?: {
hotReload?: boolean;
};
};
```
<Card type="note">
For more information on setting a custom `resolverPath`, read more at
the [RPC Specification](/docs/rpc-specification#url)
</Card>
## Client
### Example
Inside `src/blitz-client.ts`:
```ts
import {setupBlitzClient} from "@blitzjs/next"
export const {withBlitz} = setupBlitzClient({
plugins: [],
})
```
Then inside `src/pages/_app.tsx` wrap `MyApp` function with the
`withBlitz` HOC component.
```ts
import {ErrorFallbackProps, ErrorComponent, ErrorBoundary} from "@blitzjs/next"
import {AuthenticationError, AuthorizationError} from "blitz"
import type {AppProps} from "next/app"
import React, {Suspense} from "react"
import {withBlitz} from "src/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}: AppProps) {
return (
<ErrorBoundary FallbackComponent={RootErrorFallback}>
<Component {...pageProps} />
</ErrorBoundary>
)
}
export default withBlitz(MyApp)
```
<Card type="note">
An `<ErrorBoundary />` provider and `<ErrorComponent />` component is
supplied by `@blitzjs/next`
</Card>
### API
```ts
setupBlitzClient({
plugins: [],
})
```
#### Arguments
- `plugins:` An array of Blitz.js plugins
- **Required**
#### Returns
An object with the `withBlitz` HOC wrapper
## Server
### Example
Inside `src/blitz-server.ts`
```ts
import {setupBlitzServer} from "@blitzjs/next"
export const {gSSP, gSP, api} = setupBlitzServer({
plugins: [],
})
```
### API
```ts
setupBlitzServer({
plugins: [],
onError?: (err) => void
})
```
#### Arguments
- `plugins:` An array of Blitz.js plugins
- **Required**
- `onError:` Catch all errors _(Great for services like sentry)_
#### Returns
An object with the [`gSSP`](#blitzjs-next-gssp),
[`gSP`](#blitzjs-next-gsp) & [`api`](#blitzjs-next-api) wrappers.
### Custom Server
The Blitz CLI supports running custom Next.js servers. This means you can
compile both javascript & typescript while using the Blitz.js CLI to
inject env variables. By default, the CLI checks for
`src/server/index.[ts | js]` or `src/server.[ts | js]`
For more information about custom Next.js servers, check the
[`official docs`](https://nextjs.org/docs/advanced-features/custom-server)
## Wrappers
All Next.js wrapper functions are serialized with
[`superjson`](https://github.com/blitz-js/superjson). That means you can
use `Date`, `Map`, `Set` & `BigInt` when returning data. Another thing to
note is that Blitz runs the middlewares from plugins before calling the
Next.js request handler.
<Card type="note">
The `gSSP`, `gSP` & `api` functions all pass down the context of the
session if you're using the auth plugin. Read more about the auth plugin
here [@blitzjs/auth](/docs/auth).
</Card>
### Examples
#### getStaticProps
```ts
import {gSP} from "src/blitz-server"
export const getStaticProps = gSP(async ({ctx}) => {
return {
props: {
data: {
userId: ctx?.session.userId,
session: {
id: ctx?.session.userId,
publicData: ctx?.session.$publicData,
},
},
},
}
})
```
#### getServerSideProps
```ts
import {gSSP} from "src/blitz-server"
export const getServerSideProps = gSSP(async ({ctx}) => {
return {
props: {
userId: ctx?.session.userId,
publicData: ctx?.session.$publicData,
},
}
})
```
#### api
```ts
import {api} from "src/blitz-server"
export default api(async (req, res, ctx) => {
res.status(200).json({userId: ctx?.session.userId})
})
```
_For more information about Next.js API routes, visit their docs at
[https://nextjs.org/docs/api-routes/introduction](https://nextjs.org/docs/api-routes/introduction)_
## Concepts
### Authenticate user before page loads
You may want to check if the user is logged in before your page loads.
Were going to use the `getCurrentUser` query inside
`getServerSideProps()` by calling the query directly. Then you can check
if the user is logged in on the server and use the built-in Next.js
redirect property.
```ts
import {Routes, BlitzPage} from "@blitzjs/next"
import {gSSP} from "src/blitz-server"
import getCurrentUser from "src/users/queries/getCurrentUser"
export const getServerSideProps = gSSP(async ({ctx}) => {
const currentUser = await getCurrentUser(null, ctx)
if (currentUser) {
return {
props: {
user: currentUser,
},
}
} else {
return {
redirect: {
destination: Routes.LoginPage(),
permanent: false,
},
}
}
})
```
### Return types when data fetching on the server
You can set the types returned from the Next.js data fetching functions.
All Blitz.js wrappers for the Next.js functions accept a generic. Same
with the `BlitzPage` type.
So for example, we can use some typescript utilities to help use get the
types returned by `getCurrentUser()`
```ts
import {Routes, BlitzPage} from "@blitzjs/next"
import {gSSP} from "src/blitz-server"
import getCurrentUser from "src/users/queries/getCurrentUser"
type TCurrentUser = Awaited<ReturnType<typeof getCurrentUser>>
export const getServerSideProps = gSSP<{user: TCurrentUser}>(async ({ctx}) => {
const currentUser = await getCurrentUser(null, ctx)
if (currentUser) {
return {
props: {
user: currentUser,
},
}
} else {
return {
redirect: {
destination: Routes.LoginPage(),
permanent: false,
},
}
}
})
const Page: BlitzPage<{user: TCurrentUser}> = ({user}) => {
return (
<Layout title="Page">
<div className="container">
<p>User Page</p>
{user && <p>{user.email}</p>}
</div>
</Layout>
)
}
export default Page
```
### Handling errors on initial page load
Theres an edge case where you may be throwing an error in a query thats
being called on an initial page load, causing a server error instead of
hitting the `<ErrorBoundary />`. This is because when initially loading
the page, there is no ErrorBoundary component rendered until `_app.tsx` is
mounted. Though, this is expected behaviour, there is a workaround.
For an example, in a query where the user is not found you can create a
`NotFoundError()` then return the status code.
```ts
export default resolver.pipe(resolver.zod(GetUser), async (input) => {
const {id} = input
const user = await db.user.findFirst({where: {id}})
if (!user) {
const userError = new NotFoundError("User not found")
return {
error: userError.statusCode,
}
} else {
return {
user,
}
}
})
```
Then on the server (in this case `getServerSideProps()`) you can call the
query and if the error key is found in the return object then show an
error.
```ts
export const getServerSideProps = gSSP(async ({ ctx }) => {
const user = await getUser({ 1 }, ctx)
if("error" in user) {
return { props: { error: user.error}}
} else {
return { props: { user }}
}
})
```
You can also catch server errors in `_app.tsx` and show the errors with a
toast component.
```tsx
function MyApp({Component, pageProps}: AppProps) {
const getLayout = Component.getLayout || ((page) => page)
if (pageProps.error) {
return <ToastComponent>{pageProps.error.statusCode}</ToastComponent>
}
return (
<ErrorBoundary FallbackComponent={RootErrorFallback}>
{getLayout(<Component {...pageProps} />)}
</ErrorBoundary>
)
}
```

View File

@@ -1,6 +1,11 @@
{
"name": "@blitzjs/next",
"version": "2.0.0-beta.22",
"version": "2.0.0-beta.23",
"homepage": "https://blitzjs.com/",
"repository": {
"type": "git",
"url": "https://github.com/blitz-js/blitz.git"
},
"scripts": {
"build": "unbuild",
"dev": "pnpm predev && pnpm watch unbuild src --wait=0.2",
@@ -24,7 +29,7 @@
"eslint.js"
],
"dependencies": {
"@blitzjs/rpc": "2.0.0-beta.22",
"@blitzjs/rpc": "2.0.0-beta.23",
"@tanstack/react-query": "4.0.10",
"@types/hoist-non-react-statics": "3.3.1",
"debug": "4.3.3",
@@ -34,12 +39,12 @@
"supports-color": "8.1.1"
},
"peerDependencies": {
"blitz": "2.0.0-beta.22",
"blitz": "2.0.0-beta.23",
"next": "*",
"react": "*"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@testing-library/dom": "8.13.0",
"@testing-library/jest-dom": "5.16.3",
"@testing-library/react": "13.4.0",
@@ -49,7 +54,7 @@
"@types/react": "18.0.25",
"@types/react-dom": "17.0.14",
"@types/testing-library__react-hooks": "4.0.0",
"blitz": "2.0.0-beta.22",
"blitz": "2.0.0-beta.23",
"cross-spawn": "7.0.3",
"find-up": "4.1.0",
"next": "12.2.5",

View File

@@ -1,5 +1,13 @@
# @blitzjs/rpc
## 2.0.0-beta.23
### Patch Changes
- c3c789740: Updates internal functions and tests to support blitz apps that run tests with vitest
- Updated dependencies [c3c789740]
- blitz@2.0.0-beta.23
## 2.0.0-beta.22
### Minor Changes

View File

@@ -0,0 +1,61 @@
[![Blitz.js](https://raw.githubusercontent.com/blitz-js/art/master/github-cover-photo.png)](https://blitzjs.com)
<!-- prettier-ignore-start -->
<p align="center">
<a aria-label="Join our Discord Community" href="https://discord.blitzjs.com">
<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-403-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/main/LICENSE">
<img alt="" src="https://img.shields.io/npm/l/blitz.svg?style=for-the-badge&labelColor=000000&color=blue">
</a>
<a aria-label="NPM version" href="https://www.npmjs.com/package/@blitzjs/auth">
<img alt="" src="https://img.shields.io/npm/v/blitz.svg?style=for-the-badge&labelColor=000000&color=E65528">
</a>
</p>
<!-- prettier-ignore-end -->
<br>
<h1 align="center">
Blitz "Zero-API" data layer (Blitz RPC)
</h1>
<br>
### [Documentation Link](https://blitzjs.com/docs/rpc-overview)
### [GitHub Link](https://github.com/blitz-js/blitz/tree/main/packages/blitz-rpc)
### Quick Start
#### Install Blitz RPC
```bash
`npm i @blitzjs/rpc`
# yarn add @blitzjs/rpc
# pnpm add @blitzjs/rpc
```
_You can alternatively use [`npx`](https://www.npmjs.com/package/npx)_
### Overview
Blitz "Zero-API" data layer (Blitz RPC) is focused on making the communication between server and client seamless. It lets you
import server code directly into your components instead of having to manually add API endpoints and do client-side fetching and caching.
Here's a quick overview:
![Blitz RPC Overview](https://blitzjs.com/img/architecture-alt.png)
#### Queries and mutations
Queries and mutations only run on the server — at build time, the direct function import is replaced with an RPC network call. So the query function code is never included in your client code. It's instead moved to an API layer.
### Framework Support
Currently Blitz RPC is only supported in Next.js. We are working on adding support for other frameworks.
### [Setup Blitz RPC in Next.js](https://blitzjs.com/docs/rpc-setup)

View File

@@ -1,6 +1,11 @@
{
"name": "@blitzjs/rpc",
"version": "2.0.0-beta.22",
"version": "2.0.0-beta.23",
"homepage": "https://blitzjs.com/",
"repository": {
"type": "git",
"url": "https://github.com/blitz-js/blitz.git"
},
"scripts": {
"build": "unbuild",
"predev": "wait-on -d 400 ../blitz/dist/index-server.d.ts && wait-on -d 400 ../blitz-auth/dist/index-browser.d.ts",
@@ -30,17 +35,17 @@
"supports-color": "8.1.1"
},
"peerDependencies": {
"blitz": "2.0.0-beta.22",
"blitz": "2.0.0-beta.23",
"next": "*",
"react": "*"
},
"devDependencies": {
"@blitzjs/auth": "2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/auth": "2.0.0-beta.23",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@types/debug": "4.1.7",
"@types/react": "18.0.25",
"@types/react-dom": "17.0.14",
"blitz": "2.0.0-beta.22",
"blitz": "2.0.0-beta.23",
"next": "12.2.5",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -1,7 +1,7 @@
import {describe, expect, it} from "vitest"
import {describe, expect, it, vi} from "vitest"
import superJson from "superjson"
import {getQueryKey, getQueryKeyFromUrlAndParams} from "./react-query-utils"
import {getQueryKey, getQueryKeyFromUrlAndParams, validateQueryFn} from "./react-query-utils"
import {RpcClient} from "./rpc"
const API_ENDPOINT = "http://localhost:3000"
@@ -74,4 +74,65 @@ describe("react-query-utils", () => {
expect(queryKey).toEqual([API_ENDPOINT])
})
})
describe("validateQueryFn", () => {
const originalEnv = process.env
function mockEnv() {
const originalEnv = process.env
process.env = {
...originalEnv,
}
delete process.env.JEST_WORKER_ID
delete process.env.VITEST_WORKER_ID
delete process.env.BLITZ_TEST_ENVIRONMENT
return process.env
}
function restoreEnv() {
process.env = originalEnv
}
const notAQuery = vi.fn()
const realQuery = vi.fn()
//@ts-ignore
realQuery._isRpcClient = true
vi.mock("blitz", async () => {
const actualBlitz = await import("blitz")
return {
...actualBlitz,
isClient: true,
}
})
describe("when called from test environments", () => {
it("always validate as true, allowing query functions to be mocked in tests")
const jestEnv = mockEnv()
jestEnv.JEST_WORKER_ID = "123"
expect(() => validateQueryFn(notAQuery)).not.toThrowError()
expect(() => validateQueryFn(realQuery)).not.toThrowError()
restoreEnv()
const vitestEnv = mockEnv()
vitestEnv.VITEST_WORKER_ID = "123"
expect(() => validateQueryFn(notAQuery)).not.toThrowError()
expect(() => validateQueryFn(realQuery)).not.toThrowError()
restoreEnv()
})
describe("when called from outside of test environments", () => {
it("throws an error when the passed function is not a query function")
// removes jest and vitest env vars
mockEnv()
expect(() => validateQueryFn(notAQuery)).toThrowError()
expect(() => validateQueryFn(realQuery)).not.toThrowError()
restoreEnv()
})
})
})

View File

@@ -1,6 +1,6 @@
import {QueryClient} from "@tanstack/react-query"
import {serialize} from "superjson"
import {isClient, isServer, AsyncFunc} from "blitz"
import {isClient, isServer, AsyncFunc, isNotInUserTestEnvironment} from "blitz"
import {ResolverType, RpcClient} from "./rpc"
export type Resolver<TInput, TResult> = (input: TInput, ctx?: any) => Promise<TResult>
@@ -83,13 +83,6 @@ export const emptyQueryFn: RpcClient<unknown, unknown> = (() => {
return fn
})()
const isNotInUserTestEnvironment = () => {
if (process.env.JEST_WORKER_ID === undefined) return true
if (process.env.VITEST_WORKER_ID === undefined) return true
if (process.env.BLITZ_TEST_ENVIRONMENT !== undefined) return true
return false
}
export const validateQueryFn = <TInput, TResult>(
queryFn: Resolver<TInput, TResult> | RpcClient<TInput, TResult>,
) => {

View File

@@ -1,5 +1,16 @@
# blitz
## 2.0.0-beta.23
### Patch Changes
- c3c789740: Updates internal functions and tests to support blitz apps that run tests with vitest
- Updated dependencies [cb63a0ea5]
- Updated dependencies [6ec020c6d]
- Updated dependencies [d316d0db7]
- Updated dependencies [79c5e86d7]
- @blitzjs/generator@2.0.0-beta.23
## 2.0.0-beta.22
### Minor Changes

View File

@@ -1,6 +1,11 @@
{
"name": "blitz",
"version": "2.0.0-beta.22",
"version": "2.0.0-beta.23",
"homepage": "https://blitzjs.com/",
"repository": {
"type": "git",
"url": "https://github.com/blitz-js/blitz.git"
},
"scripts": {
"build": "unbuild",
"dev": "rm -rf dist && pnpm run predev && watch unbuild src --wait=0.2",
@@ -25,7 +30,7 @@
"blitz": "bin/blitz"
},
"dependencies": {
"@blitzjs/generator": "2.0.0-beta.22",
"@blitzjs/generator": "2.0.0-beta.23",
"@mrleebo/prisma-ast": "0.2.6",
"@types/global-agent": "2.1.1",
"arg": "5.0.1",
@@ -74,7 +79,7 @@
"watchpack": "2.1.1"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.22",
"@blitzjs/config": "workspace:2.0.0-beta.23",
"@types/cookie": "0.4.1",
"@types/cross-spawn": "6.0.2",
"@types/debug": "4.1.7",

View File

@@ -1,5 +1,6 @@
import _SuperJson from "superjson"
import type {UrlObject} from "url"
import {isNotInUserTestEnvironment} from "./utils"
declare module globalThis {
let _BLITZ_ERROR_CLASS_REGISTERED: boolean
@@ -9,7 +10,7 @@ const SuperJson: typeof _SuperJson =
"default" in _SuperJson ? (_SuperJson as any).default : _SuperJson
const errorProps = ["name", "message", "code", "statusCode", "meta", "url"]
if (process.env.JEST_WORKER_ID === undefined) {
if (isNotInUserTestEnvironment()) {
SuperJson.allowErrorProps(...errorProps)
}
@@ -75,7 +76,7 @@ export class PaginationArgumentError extends Error {
}
}
if (process.env.JEST_WORKER_ID === undefined && !globalThis._BLITZ_ERROR_CLASS_REGISTERED) {
if (isNotInUserTestEnvironment() && !globalThis._BLITZ_ERROR_CLASS_REGISTERED) {
SuperJson.registerClass(AuthenticationError, {
identifier: "BlitzAuthenticationError",
allowProps: errorProps,

View File

@@ -1,5 +1,6 @@
import {spawn} from "cross-spawn"
import which from "npm-which"
import {isNotInUserTestEnvironment} from "../index-browser"
export interface Constructor<T = unknown> {
new (...args: never[]): T
@@ -19,7 +20,7 @@ export const enhancePrisma = <TPrismaClientCtor extends Constructor>(
): EnhancedPrismaClientConstructor<TPrismaClientCtor> => {
return new Proxy(client as EnhancedPrismaClientConstructor<TPrismaClientCtor>, {
construct(target, args) {
if (typeof window !== "undefined" && process.env.JEST_WORKER_ID === undefined) {
if (typeof window !== "undefined" && isNotInUserTestEnvironment()) {
// Return object with $use method if in the browser
// Skip in Jest tests because window is defined in Jest tests
return {$use: () => {}}

View File

@@ -143,3 +143,11 @@ export function interopDefault(mod: any) {
export function truncateString(str: string, maxLength: number): string {
return str.length > maxLength ? str.substring(0, maxLength - 3) + "..." : str
}
export function isNotInUserTestEnvironment() {
if (process.env.VITE_BLITZ_TEST_ENVIRONMENT) {
return true
}
return process.env.JEST_WORKER_ID === undefined && process.env.VITEST_WORKER_ID === undefined
}

View File

@@ -1,5 +1,17 @@
# @blitzjs/codemod
## 2.0.0-beta.23
### Patch Changes
- Updated dependencies [cb63a0ea5]
- Updated dependencies [6ec020c6d]
- Updated dependencies [c3c789740]
- Updated dependencies [d316d0db7]
- Updated dependencies [79c5e86d7]
- @blitzjs/generator@2.0.0-beta.23
- blitz@2.0.0-beta.23
## 2.0.0-beta.22
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/codemod",
"version": "2.0.0-beta.22",
"version": "2.0.0-beta.23",
"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-beta.22",
"@blitzjs/generator": "2.0.0-beta.23",
"arg": "5.0.1",
"blitz": "2.0.0-beta.22",
"blitz": "2.0.0-beta.23",
"chalk": "^4.1.0",
"cross-spawn": "7.0.3",
"debug": "4.3.3",

View File

@@ -1,5 +1,7 @@
# @blitzjs/config
## 2.0.0-beta.23
## 2.0.0-beta.22
## 2.0.0-beta.21

View File

@@ -1,7 +1,7 @@
{
"name": "@blitzjs/config",
"private": true,
"version": "2.0.0-beta.22",
"version": "2.0.0-beta.23",
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "5.42.1",

View File

@@ -1,5 +1,14 @@
# @blitzjs/generator
## 2.0.0-beta.23
### Patch Changes
- cb63a0ea5: Guard `blitz g` input via an allow-list of characters; throw if unwanted characters are found. Prevents to break the blitz command by accident (https://github.com/blitz-js/blitz/issues/4021).
- 6ec020c6d: Remove useEffect from reset password templates.
- d316d0db7: Update all links to follow Next 13 format without a child anchor tag.
- 79c5e86d7: Add missing Layout.tsx for generated mimimalapp
## 2.0.0-beta.22
### Minor Changes

View File

@@ -1,4 +1,29 @@
# `generator`
[![Blitz.js](https://raw.githubusercontent.com/blitz-js/art/master/github-cover-photo.png)](https://blitzjs.com)
<!-- prettier-ignore-start -->
<p align="center">
<a aria-label="Join our Discord Community" href="https://discord.blitzjs.com">
<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-403-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/main/LICENSE">
<img alt="" src="https://img.shields.io/npm/l/blitz.svg?style=for-the-badge&labelColor=000000&color=blue">
</a>
<a aria-label="NPM version" href="https://www.npmjs.com/package/blitz">
<img alt="" src="https://img.shields.io/npm/v/blitz.svg?style=for-the-badge&labelColor=000000&color=E65528">
</a>
</p>
<!-- prettier-ignore-end -->
<br>
<h1 align="center">The Missing Fullstack Toolkit for Next.js</h1>
# Blitz Generator
## `Generator`
This package houses all files related to Blitz codegen. In the main `src` directory you'll find the base `generator` class and a directory of `generators` that extend it. The subclasses aren't terribly interesting, most of the fun happens in the abstract parent class. Each generator may (depending on whether it's a net new addition or modifying existing files) have a corresponding template defined in the `templates` directory.
@@ -33,3 +58,5 @@ if (process.env.someValue === "some test") {
console.log("dynamic condition")
}
```
<br>

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