Compare commits
66 Commits
@blitzjs/c
...
@blitzjs/c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
107254ece9 | ||
|
|
816330b9d0 | ||
|
|
18decd1558 | ||
|
|
1610c73f99 | ||
|
|
0a257e9150 | ||
|
|
2661bcd98d | ||
|
|
11c9f00eb9 | ||
|
|
ce1a603b26 | ||
|
|
125370a1d0 | ||
|
|
39c8c0ab80 | ||
|
|
fbf5e51a78 | ||
|
|
9cda1be11b | ||
|
|
5b20ce6282 | ||
|
|
0fc2d71a18 | ||
|
|
3fa3a4ef30 | ||
|
|
565db3c5a8 | ||
|
|
ae04524b4c | ||
|
|
38d320fd28 | ||
|
|
8723d0053c | ||
|
|
ce23d4ed09 | ||
|
|
b6c9c4ae6d | ||
|
|
0b3286468b | ||
|
|
50f17d21ce | ||
|
|
57add5f1c5 | ||
|
|
3f239e78b6 | ||
|
|
3bf90c167c | ||
|
|
56bd32b553 | ||
|
|
2711291e97 | ||
|
|
ab29c5bf3f | ||
|
|
a096f2cd80 | ||
|
|
ded16b325b | ||
|
|
4494662d6d | ||
|
|
9a0ba87d15 | ||
|
|
c80ce51d36 | ||
|
|
b505933a16 | ||
|
|
d53da39cbf | ||
|
|
e1055f7366 | ||
|
|
3b10b13e6b | ||
|
|
25601754a4 | ||
|
|
e0cfa328ec | ||
|
|
f02469aac8 | ||
|
|
2f3c552ac3 | ||
|
|
721461a7b9 | ||
|
|
3193bdea48 | ||
|
|
318e9740d6 | ||
|
|
0df368308b | ||
|
|
ad94bee56a | ||
|
|
5a14306f7b | ||
|
|
6e8eeb1514 | ||
|
|
5e61a16815 | ||
|
|
77555468f3 | ||
|
|
22e402af01 | ||
|
|
19afc57530 | ||
|
|
b7dab1d800 | ||
|
|
ee7bf87ec0 | ||
|
|
451ead089c | ||
|
|
5d9570f7f4 | ||
|
|
178c152b2c | ||
|
|
bbe1a54d7a | ||
|
|
9b075dbb47 | ||
|
|
60a4d90c86 | ||
|
|
a674897601 | ||
|
|
5a587a6c31 | ||
|
|
744242f25b | ||
|
|
0f5297f1aa | ||
|
|
76a2544f9d |
@@ -4034,6 +4034,116 @@
|
|||||||
"doc",
|
"doc",
|
||||||
"code"
|
"code"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "lmisea",
|
||||||
|
"name": "Luis Isea",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/106825636?v=4",
|
||||||
|
"profile": "https://github.com/lmisea",
|
||||||
|
"contributions": [
|
||||||
|
"doc",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "gengjiawen",
|
||||||
|
"name": "Jiawen Geng",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/3759816?v=4",
|
||||||
|
"profile": "https://www.gengjiawen.com",
|
||||||
|
"contributions": [
|
||||||
|
"doc",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "timneutkens",
|
||||||
|
"name": "Tim Neutkens",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/6324199?v=4",
|
||||||
|
"profile": "https://timn.tech",
|
||||||
|
"contributions": [
|
||||||
|
"doc",
|
||||||
|
"code",
|
||||||
|
"test"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "RedYetiDev",
|
||||||
|
"name": "Aviv Keller",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/38299977?v=4",
|
||||||
|
"profile": "https://redyetidev.github.io",
|
||||||
|
"contributions": [
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "bezalel6",
|
||||||
|
"name": "bezalel6",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/51681171?v=4",
|
||||||
|
"profile": "https://github.com/bezalel6",
|
||||||
|
"contributions": [
|
||||||
|
"doc",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "cherniavskii",
|
||||||
|
"name": "Andrew Cherniavskii",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/13808724?v=4",
|
||||||
|
"profile": "cherniavskii.com",
|
||||||
|
"contributions": [
|
||||||
|
"doc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "doe-base",
|
||||||
|
"name": "Daniel Idoko",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/95912955?v=4",
|
||||||
|
"profile": "https://danielidoko-r3zt.vercel.app/",
|
||||||
|
"contributions": [
|
||||||
|
"doc",
|
||||||
|
"code",
|
||||||
|
"test"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "fungilation",
|
||||||
|
"name": "Gary Fung",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/3803466?v=4",
|
||||||
|
"profile": "https://garyfung.medium.com",
|
||||||
|
"contributions": [
|
||||||
|
"doc",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "rene-demonsters",
|
||||||
|
"name": "René Vlugt",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/20322259?v=4",
|
||||||
|
"profile": "https://github.com/rene-demonsters",
|
||||||
|
"contributions": [
|
||||||
|
"doc",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "kksandr7",
|
||||||
|
"name": "Ksandr",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/132560756?v=4",
|
||||||
|
"profile": "https://www.drupal.org/u/kksandr",
|
||||||
|
"contributions": [
|
||||||
|
"doc",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"login": "Daidalos117",
|
||||||
|
"name": "Roman Rajchert",
|
||||||
|
"avatar_url": "https://avatars.githubusercontent.com/u/15905269?v=4",
|
||||||
|
"profile": "https://github.com/Daidalos117",
|
||||||
|
"contributions": [
|
||||||
|
"doc",
|
||||||
|
"code"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"contributorsPerLine": 7,
|
"contributorsPerLine": 7,
|
||||||
|
|||||||
@@ -7,5 +7,5 @@
|
|||||||
"access": "restricted",
|
"access": "restricted",
|
||||||
"baseBranch": "main",
|
"baseBranch": "main",
|
||||||
"updateInternalDependencies": "patch",
|
"updateInternalDependencies": "patch",
|
||||||
"ignore": ["web", "test-*", "toolkit-*", "@blitzjs/recipe-*"]
|
"ignore": ["web", "test-*", "toolkit-*", "next-blitz-auth"]
|
||||||
}
|
}
|
||||||
|
|||||||
26
.github/workflows/main.yml
vendored
26
.github/workflows/main.yml
vendored
@@ -17,13 +17,13 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: pnpm/action-setup@v2.2.4
|
- uses: pnpm/action-setup@v4.0.0
|
||||||
with:
|
with:
|
||||||
version: 8.6.5
|
version: 8.6.6
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: pnpm install --frozen-lockfile
|
run: pnpm install --frozen-lockfile
|
||||||
@@ -38,13 +38,13 @@ jobs:
|
|||||||
name: Build
|
name: Build
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- uses: pnpm/action-setup@v2.2.4
|
- uses: pnpm/action-setup@v4.0.0
|
||||||
with:
|
with:
|
||||||
version: 8.6.5
|
version: 8.6.6
|
||||||
- name: Setup node
|
- name: Setup node
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
- run: pnpm install --frozen-lockfile
|
- run: pnpm install --frozen-lockfile
|
||||||
- name: Build
|
- name: Build
|
||||||
@@ -68,14 +68,14 @@ jobs:
|
|||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Setup PNPM
|
- name: Setup PNPM
|
||||||
uses: pnpm/action-setup@v2.2.4
|
uses: pnpm/action-setup@v4.0.0
|
||||||
with:
|
with:
|
||||||
version: 8.6.5
|
version: 8.6.6
|
||||||
|
|
||||||
- name: Setup node@16
|
- name: Setup node@16
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@@ -129,15 +129,15 @@ jobs:
|
|||||||
|
|
||||||
- name: Setup PNPM
|
- name: Setup PNPM
|
||||||
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
|
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
|
||||||
uses: pnpm/action-setup@v2.2.4
|
uses: pnpm/action-setup@v4.0.0
|
||||||
with:
|
with:
|
||||||
version: 8.6.5
|
version: 8.6.6
|
||||||
|
|
||||||
- name: Setup node@18
|
- name: Setup node@18
|
||||||
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
|
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v2
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 20
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
@@ -148,7 +148,7 @@ jobs:
|
|||||||
- name: Install playwright
|
- name: Install playwright
|
||||||
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
|
if: matrix.folder != 'next-13-app-dir' || matrix.os != 'windows-latest'
|
||||||
run: |
|
run: |
|
||||||
pnpx playwright@1.28.0 install --with-deps
|
pnpx playwright@1.49.1 install --with-deps
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
|
|||||||
26
.github/workflows/pr-release.yml
vendored
26
.github/workflows/pr-release.yml
vendored
@@ -22,23 +22,29 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
- name: resolve pr refs
|
- name: Fetch PR information
|
||||||
id: refs
|
id: pr_info
|
||||||
uses: eficode/resolve-pr-refs@main
|
env:
|
||||||
with:
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
token: ${{ secrets.GITHUB_TOKEN }}
|
run: |
|
||||||
|
pr="$(gh api repos/${{ github.repository }}/pulls/${{ github.event.issue.number }})"
|
||||||
|
head_sha="$(echo "$pr" | jq -r .head.sha)"
|
||||||
|
|
||||||
- uses: actions/checkout@v3
|
echo "head_sha=$head_sha" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: ${{ steps.refs.outputs.head_ref }}
|
ref: ${{ steps.pr_info.outputs.head_sha }}
|
||||||
|
|
||||||
- name: Setup PNPM
|
- name: Setup PNPM
|
||||||
uses: pnpm/action-setup@v2.2.1
|
uses: pnpm/action-setup@646cdf48217256a3d0b80361c5a50727664284f2
|
||||||
|
with:
|
||||||
|
version: 8.6.6
|
||||||
|
|
||||||
- name: Setup Node
|
- name: Setup Node
|
||||||
uses: actions/setup-node@v3
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 16
|
node-version: 20
|
||||||
registry-url: "https://registry.npmjs.org"
|
registry-url: "https://registry.npmjs.org"
|
||||||
cache: "pnpm"
|
cache: "pnpm"
|
||||||
|
|
||||||
|
|||||||
21
.github/workflows/release.yml
vendored
21
.github/workflows/release.yml
vendored
@@ -19,12 +19,12 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Repo
|
- name: Checkout Repo
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Node.js 16.x
|
- name: Setup Node.js 20.x
|
||||||
uses: actions/setup-node@v2
|
uses: actions/setup-node@v4
|
||||||
with:
|
with:
|
||||||
node-version: 16.x
|
node-version: 20.x
|
||||||
|
|
||||||
- name: Creating .npmrc
|
- name: Creating .npmrc
|
||||||
run: |
|
run: |
|
||||||
@@ -37,8 +37,10 @@ jobs:
|
|||||||
- name: Pre-publish
|
- name: Pre-publish
|
||||||
uses: pnpm/action-setup@646cdf48217256a3d0b80361c5a50727664284f2
|
uses: pnpm/action-setup@646cdf48217256a3d0b80361c5a50727664284f2
|
||||||
with:
|
with:
|
||||||
version: 6.32.6
|
version: 8.6.6
|
||||||
- run: pnpm install --no-frozen-lockfile
|
- run: pnpm install
|
||||||
|
env:
|
||||||
|
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: 1
|
||||||
- run: pnpm build
|
- run: pnpm build
|
||||||
|
|
||||||
- name: Create Release Pull Request
|
- name: Create Release Pull Request
|
||||||
@@ -49,10 +51,3 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
|
||||||
# - name: Github Release
|
|
||||||
# uses: release-drafter/release-drafter@v5.19.0
|
|
||||||
# with:
|
|
||||||
# config-name: release-drafter.yml
|
|
||||||
# env:
|
|
||||||
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
16.13.2
|
|
||||||
20
README.md
20
README.md
@@ -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==">
|
<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>
|
</a>
|
||||||
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
|
<!-- 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-425-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-436-17BB8A.svg?style=for-the-badge&labelColor=000000"></a>
|
||||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||||
<a aria-label="License" href="https://github.com/blitz-js/blitz/blob/main/LICENSE">
|
<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">
|
<img alt="" src="https://img.shields.io/npm/l/blitz.svg?style=for-the-badge&labelColor=000000&color=blue">
|
||||||
@@ -79,6 +79,9 @@ Your financial contributions help ensure Blitz continues to be developed and mai
|
|||||||
</a></td>
|
</a></td>
|
||||||
<td><a aria-label="Simon Lammes" href="https://github.com/simon-lammes">
|
<td><a aria-label="Simon Lammes" href="https://github.com/simon-lammes">
|
||||||
<img alt="" src="https://avatars.githubusercontent.com/u/46446421?v=4" width="40px"/>
|
<img alt="" src="https://avatars.githubusercontent.com/u/46446421?v=4" width="40px"/>
|
||||||
|
</a></td>
|
||||||
|
<td><a aria-label="Route Optimizer and Route Planning Software" href="https://route4me.com">
|
||||||
|
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/main/assets/route4me.png" width="40px"/>
|
||||||
</a></td>
|
</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
@@ -749,6 +752,21 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
|
|||||||
<td align="center"><a href="https://github.com/papsavas"><img src="https://avatars.githubusercontent.com/u/50584606?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Savvas Papageorgiadis</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=papsavas" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=papsavas" title="Code">💻</a></td>
|
<td align="center"><a href="https://github.com/papsavas"><img src="https://avatars.githubusercontent.com/u/50584606?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Savvas Papageorgiadis</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=papsavas" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=papsavas" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://flow-office.eu/"><img src="https://avatars.githubusercontent.com/u/77194479?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Leonidas</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=LeonMueller-OneAndOnly" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=LeonMueller-OneAndOnly" title="Code">💻</a></td>
|
<td align="center"><a href="https://flow-office.eu/"><img src="https://avatars.githubusercontent.com/u/77194479?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Leonidas</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=LeonMueller-OneAndOnly" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=LeonMueller-OneAndOnly" title="Code">💻</a></td>
|
||||||
<td align="center"><a href="https://hacknex.us"><img src="https://avatars.githubusercontent.com/u/19937034?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Doc0x1</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Doc0x1" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=Doc0x1" title="Code">💻</a></td>
|
<td align="center"><a href="https://hacknex.us"><img src="https://avatars.githubusercontent.com/u/19937034?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Doc0x1</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Doc0x1" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=Doc0x1" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/lmisea"><img src="https://avatars.githubusercontent.com/u/106825636?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Luis Isea</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=lmisea" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=lmisea" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://www.gengjiawen.com"><img src="https://avatars.githubusercontent.com/u/3759816?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jiawen Geng</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=gengjiawen" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=gengjiawen" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://timn.tech"><img src="https://avatars.githubusercontent.com/u/6324199?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Tim Neutkens</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=timneutkens" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=timneutkens" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=timneutkens" title="Tests">⚠️</a></td>
|
||||||
|
<td align="center"><a href="https://redyetidev.github.io"><img src="https://avatars.githubusercontent.com/u/38299977?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Aviv Keller</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=RedYetiDev" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/bezalel6"><img src="https://avatars.githubusercontent.com/u/51681171?v=4?s=100" width="100px;" alt=""/><br /><sub><b>bezalel6</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=bezalel6" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=bezalel6" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="cherniavskii.com"><img src="https://avatars.githubusercontent.com/u/13808724?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Andrew Cherniavskii</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=cherniavskii" title="Documentation">📖</a></td>
|
||||||
|
<td align="center"><a href="https://danielidoko-r3zt.vercel.app/"><img src="https://avatars.githubusercontent.com/u/95912955?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daniel Idoko</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=doe-base" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=doe-base" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=doe-base" title="Tests">⚠️</a></td>
|
||||||
|
<td align="center"><a href="https://garyfung.medium.com"><img src="https://avatars.githubusercontent.com/u/3803466?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Gary Fung</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=fungilation" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=fungilation" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/rene-demonsters"><img src="https://avatars.githubusercontent.com/u/20322259?v=4?s=100" width="100px;" alt=""/><br /><sub><b>René Vlugt</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=rene-demonsters" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=rene-demonsters" title="Code">💻</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center"><a href="https://www.drupal.org/u/kksandr"><img src="https://avatars.githubusercontent.com/u/132560756?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ksandr</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=kksandr7" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=kksandr7" title="Code">💻</a></td>
|
||||||
|
<td align="center"><a href="https://github.com/Daidalos117"><img src="https://avatars.githubusercontent.com/u/15905269?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Roman Rajchert</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Daidalos117" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=Daidalos117" title="Code">💻</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,141 @@
|
|||||||
# next-blitz-auth
|
# next-blitz-auth
|
||||||
|
|
||||||
|
## 0.1.18
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- blitz@2.2.1
|
||||||
|
- @blitzjs/auth@2.2.1
|
||||||
|
- @blitzjs/next@2.2.1
|
||||||
|
- @blitzjs/rpc@2.2.1
|
||||||
|
- @blitzjs/config@2.2.1
|
||||||
|
|
||||||
|
## 0.1.17
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [565db3c5a]
|
||||||
|
- Updated dependencies [3fa3a4ef3]
|
||||||
|
- blitz@2.2.0
|
||||||
|
- @blitzjs/auth@2.2.0
|
||||||
|
- @blitzjs/next@2.2.0
|
||||||
|
- @blitzjs/rpc@2.2.0
|
||||||
|
- @blitzjs/config@2.2.0
|
||||||
|
|
||||||
|
## 0.1.16
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [ce23d4ed0]
|
||||||
|
- @blitzjs/next@2.1.4
|
||||||
|
- blitz@2.1.4
|
||||||
|
- @blitzjs/auth@2.1.4
|
||||||
|
- @blitzjs/rpc@2.1.4
|
||||||
|
- @blitzjs/config@2.1.4
|
||||||
|
|
||||||
|
## 0.1.15
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [0b3286468]
|
||||||
|
- Updated dependencies [50f17d21c]
|
||||||
|
- @blitzjs/auth@2.1.3
|
||||||
|
- @blitzjs/next@2.1.3
|
||||||
|
- @blitzjs/rpc@2.1.3
|
||||||
|
- blitz@2.1.3
|
||||||
|
- @blitzjs/config@2.1.3
|
||||||
|
|
||||||
|
## 0.1.14
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- blitz@2.1.2
|
||||||
|
- @blitzjs/auth@2.1.2
|
||||||
|
- @blitzjs/next@2.1.2
|
||||||
|
- @blitzjs/rpc@2.1.2
|
||||||
|
- @blitzjs/config@2.1.2
|
||||||
|
|
||||||
|
## 0.1.13
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [9a0ba87d1]
|
||||||
|
- @blitzjs/rpc@2.1.1
|
||||||
|
- blitz@2.1.1
|
||||||
|
- @blitzjs/next@2.1.1
|
||||||
|
- @blitzjs/auth@2.1.1
|
||||||
|
- @blitzjs/config@2.1.1
|
||||||
|
|
||||||
|
## 0.1.12
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [d53da39cb]
|
||||||
|
- Updated dependencies [3b10b13e6]
|
||||||
|
- blitz@2.1.0
|
||||||
|
- @blitzjs/auth@2.1.0
|
||||||
|
- @blitzjs/next@2.1.0
|
||||||
|
- @blitzjs/rpc@2.1.0
|
||||||
|
- @blitzjs/config@2.1.0
|
||||||
|
|
||||||
|
## 0.1.11
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [318e9740d]
|
||||||
|
- @blitzjs/auth@2.0.10
|
||||||
|
- blitz@2.0.10
|
||||||
|
- @blitzjs/rpc@2.0.10
|
||||||
|
- @blitzjs/next@2.0.10
|
||||||
|
- @blitzjs/config@2.0.10
|
||||||
|
|
||||||
|
## 0.1.10
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [5a14306f7]
|
||||||
|
- @blitzjs/next@2.0.9
|
||||||
|
- @blitzjs/rpc@2.0.9
|
||||||
|
- blitz@2.0.9
|
||||||
|
- @blitzjs/auth@2.0.9
|
||||||
|
- @blitzjs/config@2.0.9
|
||||||
|
|
||||||
|
## 0.1.9
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [5e61a1681]
|
||||||
|
- Updated dependencies [77555468f]
|
||||||
|
- @blitzjs/next@2.0.8
|
||||||
|
- blitz@2.0.8
|
||||||
|
- @blitzjs/auth@2.0.8
|
||||||
|
- @blitzjs/rpc@2.0.8
|
||||||
|
- @blitzjs/config@2.0.8
|
||||||
|
|
||||||
|
## 0.1.8
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [ee7bf87ec]
|
||||||
|
- Updated dependencies [178c152b2]
|
||||||
|
- blitz@2.0.7
|
||||||
|
- @blitzjs/next@2.0.7
|
||||||
|
- @blitzjs/rpc@2.0.7
|
||||||
|
- @blitzjs/auth@2.0.7
|
||||||
|
- @blitzjs/config@2.0.7
|
||||||
|
|
||||||
|
## 0.1.7
|
||||||
|
|
||||||
|
### Patch Changes
|
||||||
|
|
||||||
|
- Updated dependencies [76a2544f9]
|
||||||
|
- Updated dependencies [5a587a6c3]
|
||||||
|
- blitz@2.0.6
|
||||||
|
- @blitzjs/auth@2.0.6
|
||||||
|
- @blitzjs/next@2.0.6
|
||||||
|
- @blitzjs/rpc@2.0.6
|
||||||
|
- @blitzjs/config@2.0.6
|
||||||
|
|
||||||
## 0.1.6
|
## 0.1.6
|
||||||
|
|
||||||
### Patch Changes
|
### Patch Changes
|
||||||
|
|||||||
@@ -1,5 +1,13 @@
|
|||||||
const {withBlitz} = require("@blitzjs/next")
|
const {withBlitz} = require("@blitzjs/next")
|
||||||
|
|
||||||
|
const loaderClient = require.resolve("@blitzjs/rpc/dist/loader-client.cjs")
|
||||||
|
const loaderServer = require.resolve("@blitzjs/rpc/dist/loader-server.cjs")
|
||||||
|
const loaderServerResolvers = require.resolve("@blitzjs/rpc/dist/loader-server-resolvers.cjs")
|
||||||
|
|
||||||
|
console.log("loaderClient", loaderClient)
|
||||||
|
console.log("loaderServer", loaderServer)
|
||||||
|
console.log("loaderServerResolvers", loaderServerResolvers)
|
||||||
|
|
||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {}
|
const nextConfig = {}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "next-blitz-auth",
|
"name": "next-blitz-auth",
|
||||||
"version": "0.1.6",
|
"version": "0.1.18",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"blitz:dev": "next dev",
|
"blitz:dev": "next dev",
|
||||||
@@ -12,28 +12,28 @@
|
|||||||
"schema": "prisma/schema.prisma"
|
"schema": "prisma/schema.prisma"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzjs/auth": "2.0.5",
|
"@blitzjs/auth": "3.0.1",
|
||||||
"@blitzjs/config": "2.0.5",
|
"@blitzjs/config": "3.0.1",
|
||||||
"@blitzjs/next": "2.0.5",
|
"@blitzjs/next": "3.0.1",
|
||||||
"@blitzjs/rpc": "2.0.5",
|
"@blitzjs/rpc": "3.0.1",
|
||||||
"@hookform/error-message": "2.0.0",
|
"@hookform/error-message": "2.0.0",
|
||||||
"@hookform/resolvers": "2.9.10",
|
"@hookform/resolvers": "2.9.10",
|
||||||
"@prisma/client": "^4.5.0",
|
"@prisma/client": "^4.5.0",
|
||||||
"@tanstack/react-query": "4.0.10",
|
"@tanstack/react-query": "5.51.1",
|
||||||
"blitz": "2.0.5",
|
"blitz": "3.0.1",
|
||||||
"flatted": "3.2.7",
|
"flatted": "3.2.7",
|
||||||
"next": "14.0.4",
|
"next": "15.0.1",
|
||||||
"prisma": "^4.5.0",
|
"prisma": "^4.5.0",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "19.0.0",
|
||||||
"react-hook-form": "7.39.1",
|
"react-hook-form": "7.39.1",
|
||||||
"superjson": "1.11.0",
|
"superjson": "1.11.0",
|
||||||
"zod": "3.20.2"
|
"zod": "3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "18.11.7",
|
"@types/node": "18.11.7",
|
||||||
"@types/react": "18.0.23",
|
"@types/react": "npm:types-react@19.0.0",
|
||||||
"@types/react-dom": "18.0.7",
|
"@types/react-dom": "npm:types-react-dom@19.0.0",
|
||||||
"eslint": "8.26.0",
|
"eslint": "8.26.0",
|
||||||
"eslint-config-next": "13.0.0",
|
"eslint-config-next": "13.0.0",
|
||||||
"typescript": "4.8.4"
|
"typescript": "4.8.4"
|
||||||
|
|||||||
Binary file not shown.
4
apps/next13/src/app/api/rpc/[[...blitz]]/route.ts
Normal file
4
apps/next13/src/app/api/rpc/[[...blitz]]/route.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
import {rpcAppHandler} from "@blitzjs/rpc"
|
||||||
|
import {withBlitzAuth} from "src/blitz-server"
|
||||||
|
|
||||||
|
export const {GET, POST, HEAD} = withBlitzAuth(rpcAppHandler())
|
||||||
4
apps/next13/src/app/loading.tsx
Normal file
4
apps/next13/src/app/loading.tsx
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export default function Loading() {
|
||||||
|
// You can add any UI inside Loading, including a Skeleton.
|
||||||
|
return "Loading..."
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import {useQuery, useMutation} from "@blitzjs/rpc"
|
import {useQuery, useMutation, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import logout from "../auth/mutations/logout"
|
import logout from "../auth/mutations/logout"
|
||||||
import getCurrentUser from "../users/queries/getCurrentUser"
|
import getCurrentUser from "../users/queries/getCurrentUser"
|
||||||
import {useTransition} from "react"
|
import {useTransition} from "react"
|
||||||
@@ -8,7 +8,7 @@ import {useRouter} from "next/navigation"
|
|||||||
|
|
||||||
export default function Test() {
|
export default function Test() {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const [user] = useQuery(getCurrentUser, null)
|
const [user] = useSuspenseQuery(getCurrentUser, null)
|
||||||
const [isPending, startTransition] = useTransition()
|
const [isPending, startTransition] = useTransition()
|
||||||
const [logoutMutation] = useMutation(logout)
|
const [logoutMutation] = useMutation(logout)
|
||||||
console.log(user)
|
console.log(user)
|
||||||
|
|||||||
@@ -6,26 +6,27 @@ import {simpleRolesIsAuthorized} from "@blitzjs/auth"
|
|||||||
import {BlitzLogger} from "blitz"
|
import {BlitzLogger} from "blitz"
|
||||||
import {RpcServerPlugin} from "@blitzjs/rpc"
|
import {RpcServerPlugin} from "@blitzjs/rpc"
|
||||||
|
|
||||||
const {api, getBlitzContext, useAuthenticatedBlitzContext, invoke} = setupBlitzServer({
|
const {api, getBlitzContext, useAuthenticatedBlitzContext, invoke, withBlitzAuth} =
|
||||||
plugins: [
|
setupBlitzServer({
|
||||||
AuthServerPlugin({
|
plugins: [
|
||||||
cookiePrefix: "web-cookie-prefix",
|
AuthServerPlugin({
|
||||||
storage: PrismaStorage(db),
|
cookiePrefix: "web-cookie-prefix",
|
||||||
isAuthorized: simpleRolesIsAuthorized,
|
storage: PrismaStorage(db),
|
||||||
}),
|
isAuthorized: simpleRolesIsAuthorized,
|
||||||
RpcServerPlugin({
|
}),
|
||||||
logging: {
|
RpcServerPlugin({
|
||||||
disablelevel: "debug",
|
logging: {
|
||||||
},
|
disablelevel: "debug",
|
||||||
onInvokeError(error) {
|
},
|
||||||
console.log("onInvokeError", error)
|
onInvokeError(error) {
|
||||||
},
|
console.log("onInvokeError", error)
|
||||||
}),
|
},
|
||||||
],
|
}),
|
||||||
logger: BlitzLogger({}),
|
],
|
||||||
})
|
logger: BlitzLogger({}),
|
||||||
|
})
|
||||||
|
|
||||||
export {api, getBlitzContext, useAuthenticatedBlitzContext, invoke}
|
export {api, getBlitzContext, useAuthenticatedBlitzContext, invoke, withBlitzAuth}
|
||||||
|
|
||||||
export const cliConfig: BlitzCliConfig = {
|
export const cliConfig: BlitzCliConfig = {
|
||||||
customTemplates: "src/templates",
|
customTemplates: "src/templates",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {zodResolver} from "@hookform/resolvers/zod"
|
|||||||
import {z} from "zod"
|
import {z} from "zod"
|
||||||
|
|
||||||
export interface FormProps<S extends z.ZodType<any, any>>
|
export interface FormProps<S extends z.ZodType<any, any>>
|
||||||
extends Omit<PropsWithoutRef<JSX.IntrinsicElements["form"]>, "onSubmit"> {
|
extends Omit<PropsWithoutRef<React.JSX.IntrinsicElements["form"]>, "onSubmit"> {
|
||||||
/** All your form fields */
|
/** All your form fields */
|
||||||
children?: ReactNode
|
children?: ReactNode
|
||||||
/** Text to display in the submit button */
|
/** Text to display in the submit button */
|
||||||
|
|||||||
@@ -2,14 +2,15 @@ import {forwardRef, PropsWithoutRef, ComponentPropsWithoutRef} from "react"
|
|||||||
import {useFormContext} from "react-hook-form"
|
import {useFormContext} from "react-hook-form"
|
||||||
import {ErrorMessage} from "@hookform/error-message"
|
import {ErrorMessage} from "@hookform/error-message"
|
||||||
|
|
||||||
export interface LabeledTextFieldProps extends PropsWithoutRef<JSX.IntrinsicElements["input"]> {
|
export interface LabeledTextFieldProps
|
||||||
|
extends PropsWithoutRef<React.JSX.IntrinsicElements["input"]> {
|
||||||
/** Field name. */
|
/** Field name. */
|
||||||
name: string
|
name: string
|
||||||
/** Field label. */
|
/** Field label. */
|
||||||
label: string
|
label: string
|
||||||
/** Field type. Doesn't include radio buttons and checkboxes */
|
/** Field type. Doesn't include radio buttons and checkboxes */
|
||||||
type?: "text" | "password" | "email" | "number"
|
type?: "text" | "password" | "email" | "number"
|
||||||
outerProps?: PropsWithoutRef<JSX.IntrinsicElements["div"]>
|
outerProps?: PropsWithoutRef<React.JSX.IntrinsicElements["div"]>
|
||||||
labelProps?: ComponentPropsWithoutRef<"label">
|
labelProps?: ComponentPropsWithoutRef<"label">
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
import {rpcHandler} from "@blitzjs/rpc"
|
|
||||||
import {api} from "../../../blitz-server"
|
|
||||||
|
|
||||||
export default api(rpcHandler({onError: (error, ctx) => console.log(error)}))
|
|
||||||
@@ -12,5 +12,5 @@ export default async function getCurrentUser(input: null, ctx: Ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const config = {
|
export const config = {
|
||||||
httpMethod: "GET",
|
httpMethod: "POST",
|
||||||
}
|
}
|
||||||
|
|||||||
2
apps/toolkit-app-passportjs/next-env.d.ts
vendored
2
apps/toolkit-app-passportjs/next-env.d.ts
vendored
@@ -2,4 +2,4 @@
|
|||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
|
||||||
|
|||||||
@@ -23,31 +23,30 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzjs/auth": "2.0.5",
|
"@blitzjs/auth": "3.0.1",
|
||||||
"@blitzjs/config": "2.0.5",
|
"@blitzjs/config": "3.0.1",
|
||||||
"@blitzjs/next": "2.0.5",
|
"@blitzjs/next": "3.0.1",
|
||||||
"@blitzjs/rpc": "2.0.5",
|
"@blitzjs/rpc": "3.0.1",
|
||||||
"@hookform/error-message": "2.0.0",
|
"@hookform/error-message": "2.0.0",
|
||||||
"@hookform/resolvers": "2.9.10",
|
"@hookform/resolvers": "2.9.10",
|
||||||
"@prisma/client": "4.6.1",
|
"@prisma/client": "6.1.0",
|
||||||
"blitz": "2.0.5",
|
"blitz": "3.0.1",
|
||||||
"next": "14.0.4",
|
"next": "15.0.1",
|
||||||
"openid-client": "5.2.1",
|
"openid-client": "5.2.1",
|
||||||
"prisma": "4.6.1",
|
"prisma": "6.1.0",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "19.0.0",
|
||||||
"react-hook-form": "7.39.1",
|
"react-hook-form": "7.39.1",
|
||||||
"ts-node": "10.9.1",
|
"ts-node": "10.9.1",
|
||||||
"zod": "3.20.2"
|
"zod": "3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@next/bundle-analyzer": "12.0.8",
|
"@next/bundle-analyzer": "12.0.8",
|
||||||
"@testing-library/react": "13.4.0",
|
"@testing-library/react": "16.0.1",
|
||||||
"@testing-library/react-hooks": "8.0.1",
|
|
||||||
"@types/jest": "29.2.2",
|
"@types/jest": "29.2.2",
|
||||||
"@types/node": "18.11.9",
|
"@types/node": "18.11.9",
|
||||||
"@types/preview-email": "2.0.1",
|
"@types/preview-email": "2.0.1",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "npm:types-react@19.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "5.42.1",
|
"@typescript-eslint/eslint-plugin": "5.42.1",
|
||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
"eslint-config-next": "12.3.1",
|
"eslint-config-next": "12.3.1",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { zodResolver } from "@hookform/resolvers/zod"
|
|||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
export interface FormProps<S extends z.ZodType<any, any>>
|
export interface FormProps<S extends z.ZodType<any, any>>
|
||||||
extends Omit<PropsWithoutRef<JSX.IntrinsicElements["form"]>, "onSubmit"> {
|
extends Omit<PropsWithoutRef<React.JSX.IntrinsicElements["form"]>, "onSubmit"> {
|
||||||
/** All your form fields */
|
/** All your form fields */
|
||||||
children?: ReactNode
|
children?: ReactNode
|
||||||
/** Text to display in the submit button */
|
/** Text to display in the submit button */
|
||||||
|
|||||||
@@ -2,14 +2,15 @@ import { forwardRef, PropsWithoutRef, ComponentPropsWithoutRef } from "react"
|
|||||||
import { useFormContext } from "react-hook-form"
|
import { useFormContext } from "react-hook-form"
|
||||||
import { ErrorMessage } from "@hookform/error-message"
|
import { ErrorMessage } from "@hookform/error-message"
|
||||||
|
|
||||||
export interface LabeledTextFieldProps extends PropsWithoutRef<JSX.IntrinsicElements["input"]> {
|
export interface LabeledTextFieldProps
|
||||||
|
extends PropsWithoutRef<React.JSX.IntrinsicElements["input"]> {
|
||||||
/** Field name. */
|
/** Field name. */
|
||||||
name: string
|
name: string
|
||||||
/** Field label. */
|
/** Field label. */
|
||||||
label: string
|
label: string
|
||||||
/** Field type. Doesn't include radio buttons and checkboxes */
|
/** Field type. Doesn't include radio buttons and checkboxes */
|
||||||
type?: "text" | "password" | "email" | "number"
|
type?: "text" | "password" | "email" | "number"
|
||||||
outerProps?: PropsWithoutRef<JSX.IntrinsicElements["div"]>
|
outerProps?: PropsWithoutRef<React.JSX.IntrinsicElements["div"]>
|
||||||
labelProps?: ComponentPropsWithoutRef<"label">
|
labelProps?: ComponentPropsWithoutRef<"label">
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ declare module "@blitzjs/auth" {
|
|||||||
PublicData: {
|
PublicData: {
|
||||||
userId: User["id"]
|
userId: User["id"]
|
||||||
role: Role
|
role: Role
|
||||||
views?: number
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
apps/toolkit-app/next-env.d.ts
vendored
2
apps/toolkit-app/next-env.d.ts
vendored
@@ -2,4 +2,4 @@
|
|||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
const { withNextAuthAdapter } = require("@blitzjs/auth/next-auth")
|
|
||||||
const { withBlitz } = require("@blitzjs/next")
|
const { withBlitz } = require("@blitzjs/next")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,4 +10,4 @@ const config = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = withBlitz(withNextAuthAdapter(config))
|
module.exports = withBlitz(config)
|
||||||
|
|||||||
@@ -24,31 +24,30 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzjs/auth": "2.0.5",
|
"@blitzjs/auth": "3.0.1",
|
||||||
"@blitzjs/config": "2.0.5",
|
"@blitzjs/config": "3.0.1",
|
||||||
"@blitzjs/next": "2.0.5",
|
"@blitzjs/next": "3.0.1",
|
||||||
"@blitzjs/rpc": "2.0.5",
|
"@blitzjs/rpc": "3.0.1",
|
||||||
"@hookform/error-message": "2.0.0",
|
"@hookform/error-message": "2.0.0",
|
||||||
"@hookform/resolvers": "2.9.10",
|
"@hookform/resolvers": "2.9.10",
|
||||||
"@prisma/client": "4.6.1",
|
"@prisma/client": "6.1.0",
|
||||||
"blitz": "2.0.5",
|
"blitz": "3.0.1",
|
||||||
"next": "14.0.4",
|
"next": "15.0.1",
|
||||||
"next-auth": "4.18.7",
|
"next-auth": "4.24.7",
|
||||||
"prisma": "4.6.1",
|
"prisma": "6.1.0",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "19.0.0",
|
||||||
"react-hook-form": "7.39.1",
|
"react-hook-form": "7.39.1",
|
||||||
"ts-node": "10.9.1",
|
"ts-node": "10.9.1",
|
||||||
"zod": "3.20.2"
|
"zod": "3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@next/bundle-analyzer": "12.0.8",
|
"@next/bundle-analyzer": "12.0.8",
|
||||||
"@testing-library/jest-dom": "5.16.5",
|
"@testing-library/jest-dom": "5.16.5",
|
||||||
"@testing-library/react": "13.4.0",
|
"@testing-library/react": "16.0.1",
|
||||||
"@testing-library/react-hooks": "8.0.1",
|
|
||||||
"@types/node": "18.11.9",
|
"@types/node": "18.11.9",
|
||||||
"@types/preview-email": "2.0.1",
|
"@types/preview-email": "2.0.1",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "npm:types-react@19.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "5.42.1",
|
"@typescript-eslint/eslint-plugin": "5.42.1",
|
||||||
"@vitejs/plugin-react": "2.2.0",
|
"@vitejs/plugin-react": "2.2.0",
|
||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { zodResolver } from "@hookform/resolvers/zod"
|
|||||||
import { z } from "zod"
|
import { z } from "zod"
|
||||||
|
|
||||||
export interface FormProps<S extends z.ZodType<any, any>>
|
export interface FormProps<S extends z.ZodType<any, any>>
|
||||||
extends Omit<PropsWithoutRef<JSX.IntrinsicElements["form"]>, "onSubmit"> {
|
extends Omit<PropsWithoutRef<React.JSX.IntrinsicElements["form"]>, "onSubmit"> {
|
||||||
/** All your form fields */
|
/** All your form fields */
|
||||||
children?: ReactNode
|
children?: ReactNode
|
||||||
/** Text to display in the submit button */
|
/** Text to display in the submit button */
|
||||||
|
|||||||
@@ -2,14 +2,15 @@ import { ComponentPropsWithoutRef, forwardRef, PropsWithoutRef } from "react"
|
|||||||
import { useFormContext } from "react-hook-form"
|
import { useFormContext } from "react-hook-form"
|
||||||
import { ErrorMessage } from "@hookform/error-message"
|
import { ErrorMessage } from "@hookform/error-message"
|
||||||
|
|
||||||
export interface LabeledSelectFieldProps extends PropsWithoutRef<JSX.IntrinsicElements["select"]> {
|
export interface LabeledSelectFieldProps
|
||||||
|
extends PropsWithoutRef<React.JSX.IntrinsicElements["select"]> {
|
||||||
/** Field name. */
|
/** Field name. */
|
||||||
name: string
|
name: string
|
||||||
/** Field label. */
|
/** Field label. */
|
||||||
label: string
|
label: string
|
||||||
/** Field type. Doesn't include radio buttons and checkboxes */
|
/** Field type. Doesn't include radio buttons and checkboxes */
|
||||||
options: any[]
|
options: any[]
|
||||||
outerProps?: PropsWithoutRef<JSX.IntrinsicElements["div"]>
|
outerProps?: PropsWithoutRef<React.JSX.IntrinsicElements["div"]>
|
||||||
labelProps?: ComponentPropsWithoutRef<"label">
|
labelProps?: ComponentPropsWithoutRef<"label">
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,15 @@ import { forwardRef, PropsWithoutRef, ComponentPropsWithoutRef } from "react"
|
|||||||
import { useFormContext } from "react-hook-form"
|
import { useFormContext } from "react-hook-form"
|
||||||
import { ErrorMessage } from "@hookform/error-message"
|
import { ErrorMessage } from "@hookform/error-message"
|
||||||
|
|
||||||
export interface LabeledTextFieldProps extends PropsWithoutRef<JSX.IntrinsicElements["input"]> {
|
export interface LabeledTextFieldProps
|
||||||
|
extends PropsWithoutRef<React.JSX.IntrinsicElements["input"]> {
|
||||||
/** Field name. */
|
/** Field name. */
|
||||||
name: string
|
name: string
|
||||||
/** Field label. */
|
/** Field label. */
|
||||||
label: string
|
label: string
|
||||||
/** Field type. Doesn't include radio buttons and checkboxes */
|
/** Field type. Doesn't include radio buttons and checkboxes */
|
||||||
type?: "text" | "password" | "email" | "number"
|
type?: "text" | "password" | "email" | "number"
|
||||||
outerProps?: PropsWithoutRef<JSX.IntrinsicElements["div"]>
|
outerProps?: PropsWithoutRef<React.JSX.IntrinsicElements["div"]>
|
||||||
labelProps?: ComponentPropsWithoutRef<"label">
|
labelProps?: ComponentPropsWithoutRef<"label">
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +0,0 @@
|
|||||||
import { api } from "src/blitz-server"
|
|
||||||
import GithubProvider from "next-auth/providers/github"
|
|
||||||
import EmailProvider from "next-auth/providers/email"
|
|
||||||
import { NextAuthAdapter, BlitzNextAuthOptions } from "@blitzjs/auth/next-auth"
|
|
||||||
import db, { User } from "db"
|
|
||||||
import { Role } from "types"
|
|
||||||
|
|
||||||
// Has to be defined separately for `profile` to be correctly typed below
|
|
||||||
const providers = [
|
|
||||||
GithubProvider({
|
|
||||||
clientId: process.env.GITHUB_CLIENT_ID as string,
|
|
||||||
clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
|
|
||||||
}),
|
|
||||||
EmailProvider({
|
|
||||||
from: process.env.GITHUB_CLIENT_ID as string,
|
|
||||||
server: process.env.GITHUB_CLIENT_SECRET as string,
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
|
|
||||||
export default api(
|
|
||||||
NextAuthAdapter({
|
|
||||||
successRedirectUrl: "/",
|
|
||||||
errorRedirectUrl: "/error",
|
|
||||||
providers,
|
|
||||||
callback: async (user, account, profile, session) => {
|
|
||||||
console.log("USER SIDE PROFILE_DATA", { user, account, profile })
|
|
||||||
let newUser: User
|
|
||||||
try {
|
|
||||||
newUser = await db.user.findFirstOrThrow({ where: { name: { equals: user.name } } })
|
|
||||||
} catch (e) {
|
|
||||||
newUser = await db.user.create({
|
|
||||||
data: {
|
|
||||||
email: user.email as string,
|
|
||||||
name: user.name as string,
|
|
||||||
role: "USER",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
const publicData = {
|
|
||||||
userId: newUser.id,
|
|
||||||
role: newUser.role as Role,
|
|
||||||
source: "github",
|
|
||||||
}
|
|
||||||
await session.$create(publicData)
|
|
||||||
return { redirectUrl: "/" }
|
|
||||||
},
|
|
||||||
})
|
|
||||||
)
|
|
||||||
@@ -44,11 +44,6 @@ const UserInfo = () => {
|
|||||||
<Link href={"/auth/login"} className={styles.loginButton}>
|
<Link href={"/auth/login"} className={styles.loginButton}>
|
||||||
<strong>Login</strong>
|
<strong>Login</strong>
|
||||||
</Link>
|
</Link>
|
||||||
<Link href="/api/auth/github/login" passHref legacyBehavior>
|
|
||||||
<a className="button small">
|
|
||||||
<strong>Sign in with GitHub</strong>
|
|
||||||
</a>
|
|
||||||
</Link>
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,15 +11,11 @@ const LoginPage: BlitzPage = () => {
|
|||||||
<LoginForm
|
<LoginForm
|
||||||
onSuccess={(_user) => {
|
onSuccess={(_user) => {
|
||||||
const next = router.query.next ? decodeURIComponent(router.query.next as string) : "/"
|
const next = router.query.next ? decodeURIComponent(router.query.next as string) : "/"
|
||||||
// return router.push(next)
|
return router.push(next)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Layout>
|
</Layout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
LoginPage.authenticate = {
|
|
||||||
redirectTo: "/",
|
|
||||||
}
|
|
||||||
|
|
||||||
export default LoginPage
|
export default LoginPage
|
||||||
@@ -9,7 +9,6 @@ declare module "@blitzjs/auth" {
|
|||||||
PublicData: {
|
PublicData: {
|
||||||
userId: User["id"]
|
userId: User["id"]
|
||||||
role: Role
|
role: Role
|
||||||
views?: number
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
apps/web/next-env.d.ts
vendored
2
apps/web/next-env.d.ts
vendored
@@ -2,4 +2,4 @@
|
|||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
|
||||||
|
|||||||
@@ -16,27 +16,27 @@
|
|||||||
"schema": "./db/schema.prisma"
|
"schema": "./db/schema.prisma"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzjs/auth": "2.0.5",
|
"@blitzjs/auth": "3.0.1",
|
||||||
"@blitzjs/config": "2.0.5",
|
"@blitzjs/config": "3.0.1",
|
||||||
"@blitzjs/next": "2.0.5",
|
"@blitzjs/next": "3.0.1",
|
||||||
"@blitzjs/rpc": "2.0.5",
|
"@blitzjs/rpc": "3.0.1",
|
||||||
"@prisma/client": "4.6.1",
|
"@prisma/client": "6.1.0",
|
||||||
"@types/jest": "29.2.2",
|
"@types/jest": "29.2.2",
|
||||||
"@types/passport-twitter": "1.0.37",
|
"@types/passport-twitter": "1.0.37",
|
||||||
"blitz": "2.0.5",
|
"blitz": "3.0.1",
|
||||||
"jest": "29.3.0",
|
"jest": "29.3.0",
|
||||||
"jest-environment-jsdom": "29.3.0",
|
"jest-environment-jsdom": "29.3.0",
|
||||||
"next": "14.0.4",
|
"next": "15.0.1",
|
||||||
"passport-mock-strategy": "2.0.0",
|
"passport-mock-strategy": "2.0.0",
|
||||||
"passport-twitter": "1.0.4",
|
"passport-twitter": "1.0.4",
|
||||||
"prisma": "4.6.1",
|
"prisma": "6.1.0",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "19.0.0",
|
||||||
"ts-node": "10.9.1"
|
"ts-node": "10.9.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@next/bundle-analyzer": "12.0.8",
|
"@next/bundle-analyzer": "12.0.8",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "npm:types-react@19.0.0",
|
||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
import {passportAuth} from "@blitzjs/auth"
|
|
||||||
import {api} from "src/blitz-server"
|
|
||||||
import db from "db"
|
|
||||||
import {Strategy as TwitterStrategy} from "passport-twitter"
|
|
||||||
|
|
||||||
export default api(
|
|
||||||
passportAuth({
|
|
||||||
successRedirectUrl: "/",
|
|
||||||
errorRedirectUrl: "/",
|
|
||||||
strategies: [
|
|
||||||
{
|
|
||||||
strategy: new TwitterStrategy(
|
|
||||||
{
|
|
||||||
consumerKey: process.env.TWITTER_CONSUMER_KEY as string,
|
|
||||||
consumerSecret: process.env.TWITTER_CONSUMER_SECRET as string,
|
|
||||||
accessTokenURL: "https://api.twitter.com/oauth/access_token",
|
|
||||||
callbackURL: "http://127.0.0.1:3000/api/auth/twitter/callback",
|
|
||||||
includeEmail: true,
|
|
||||||
},
|
|
||||||
async function (_token, _tokenSecret, profile, done) {
|
|
||||||
const email = profile.emails?.[0]?.value ?? "blitz@test.com"
|
|
||||||
|
|
||||||
const user = await db.user.upsert({
|
|
||||||
where: {email},
|
|
||||||
create: {
|
|
||||||
email,
|
|
||||||
name: profile.displayName,
|
|
||||||
},
|
|
||||||
update: {email},
|
|
||||||
})
|
|
||||||
|
|
||||||
const publicData = {
|
|
||||||
userId: user.id,
|
|
||||||
roles: [user.role],
|
|
||||||
source: "twitter",
|
|
||||||
}
|
|
||||||
|
|
||||||
done(undefined, {publicData})
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
90
apps/web/src/pages/page-with-inf-mutate.tsx
Normal file
90
apps/web/src/pages/page-with-inf-mutate.tsx
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import {useSuspenseInfiniteQuery} from "@blitzjs/rpc"
|
||||||
|
import getInfiniteUsers from "src/queries/getInfiniteUsers"
|
||||||
|
import {useActionState} from "react"
|
||||||
|
|
||||||
|
function PageWithInfiniteQueryMutate(props) {
|
||||||
|
const [usersPages, extraInfo] = useSuspenseInfiniteQuery(
|
||||||
|
getInfiniteUsers,
|
||||||
|
(page = {take: 3, skip: 0}) => page,
|
||||||
|
{
|
||||||
|
getNextPageParam: (lastPage) => lastPage.nextPage,
|
||||||
|
initialPageParam: {take: 3, skip: 0},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
const {isFetchingNextPage, fetchNextPage, hasNextPage, setQueryData} = extraInfo
|
||||||
|
|
||||||
|
const onOnContactSave = async (previousState, formData: FormData) => {
|
||||||
|
const name = formData.get("name") as string | null
|
||||||
|
|
||||||
|
await setQueryData(
|
||||||
|
(oldData) => {
|
||||||
|
if (!oldData) {
|
||||||
|
return {
|
||||||
|
pages: [],
|
||||||
|
pageParams: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...oldData,
|
||||||
|
pages: oldData.pages.map((page, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
return {
|
||||||
|
...page,
|
||||||
|
users: [
|
||||||
|
{
|
||||||
|
id: Math.random(),
|
||||||
|
name,
|
||||||
|
role: "user",
|
||||||
|
email: `${name}@yopmail.com`,
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date(),
|
||||||
|
hashedPassword: "alsdklaskdoaskdokdo",
|
||||||
|
},
|
||||||
|
...page.users,
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return page
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{refetch: false},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const [, formAction] = useActionState(onOnContactSave, {name: ""})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<form action={formAction}>
|
||||||
|
<input type="text" name="name" placeholder="User name" />
|
||||||
|
<button type="submit">Add user</button>
|
||||||
|
</form>
|
||||||
|
{usersPages.map((usersPage) => (
|
||||||
|
<>
|
||||||
|
{usersPage?.users.map((u) => (
|
||||||
|
<div key={u.name}>
|
||||||
|
<p>name: {u.name}</p>
|
||||||
|
<p>role: {u.role}</p>
|
||||||
|
<p>email: {u.email}</p>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{usersPage.hasMore && (
|
||||||
|
<button onClick={() => fetchNextPage()} disabled={!hasNextPage || !!isFetchingNextPage}>
|
||||||
|
{isFetchingNextPage
|
||||||
|
? "Loading more..."
|
||||||
|
: hasNextPage
|
||||||
|
? "Load More"
|
||||||
|
: "Nothing more to load"}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PageWithInfiniteQueryMutate
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import {useInfiniteQuery} from "@blitzjs/rpc"
|
import {useSuspenseInfiniteQuery} from "@blitzjs/rpc"
|
||||||
import {gSSP} from "src/blitz-server"
|
import {gSSP} from "src/blitz-server"
|
||||||
import getInfiniteUsers from "src/queries/getInfiniteUsers"
|
import getInfiniteUsers from "src/queries/getInfiniteUsers"
|
||||||
|
|
||||||
@@ -10,9 +10,14 @@ export const getServerSideProps = gSSP(async ({ctx}) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function PageWithPrefetchInfiniteQuery(props) {
|
function PageWithPrefetchInfiniteQuery(props) {
|
||||||
const [usersPages] = useInfiniteQuery(getInfiniteUsers, (page = {take: 3, skip: 0}) => page, {
|
const [usersPages] = useSuspenseInfiniteQuery(
|
||||||
getNextPageParam: (lastPage) => lastPage.nextPage,
|
getInfiniteUsers,
|
||||||
})
|
(page = {take: 3, skip: 0}) => page,
|
||||||
|
{
|
||||||
|
getNextPageParam: (lastPage) => lastPage.nextPage,
|
||||||
|
initialPageParam: {take: 3, skip: 0},
|
||||||
|
},
|
||||||
|
)
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{usersPages.map((usersPage) =>
|
{usersPages.map((usersPage) =>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {useQuery} from "@blitzjs/rpc"
|
import {useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import {gSSP} from "src/blitz-server"
|
import {gSSP} from "src/blitz-server"
|
||||||
import getUsers from "src/queries/getUsers"
|
import getUsers from "src/queries/getUsers"
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ export const getServerSideProps = gSSP(async ({ctx}) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function PageWithPrefetch(props) {
|
function PageWithPrefetch(props) {
|
||||||
const [users] = useQuery(getUsers, {})
|
const [users] = useSuspenseQuery(getUsers, {})
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{users.map((u) => (
|
{users.map((u) => (
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ function UsersPage() {
|
|||||||
<div>
|
<div>
|
||||||
Users:
|
Users:
|
||||||
<ul>
|
<ul>
|
||||||
{users.map((user) => (
|
{users?.map((user) => (
|
||||||
<li key={user.id}>
|
<li key={user.id}>
|
||||||
{user.name} - {user.email}
|
{user.name} - {user.email}
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ declare module "@blitzjs/auth" {
|
|||||||
PublicData: {
|
PublicData: {
|
||||||
userId: User["id"]
|
userId: User["id"]
|
||||||
role: Role
|
role: Role
|
||||||
views?: number
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
assets/route4me.png
Normal file
BIN
assets/route4me.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
@@ -2,4 +2,4 @@
|
|||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
|
||||||
|
|||||||
@@ -17,31 +17,30 @@
|
|||||||
"prisma:studio": "prisma studio"
|
"prisma:studio": "prisma studio"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzjs/auth": "2.0.5",
|
"@blitzjs/auth": "3.0.1",
|
||||||
"@blitzjs/config": "2.0.5",
|
"@blitzjs/config": "3.0.1",
|
||||||
"@blitzjs/next": "2.0.5",
|
"@blitzjs/next": "3.0.1",
|
||||||
"@blitzjs/rpc": "2.0.5",
|
"@blitzjs/rpc": "3.0.1",
|
||||||
"@hookform/error-message": "2.0.0",
|
"@hookform/error-message": "2.0.0",
|
||||||
"@hookform/resolvers": "2.9.10",
|
"@hookform/resolvers": "2.9.10",
|
||||||
"@prisma/client": "4.6.1",
|
"@prisma/client": "6.1.0",
|
||||||
"blitz": "2.0.5",
|
"blitz": "3.0.1",
|
||||||
"delay": "5.0.0",
|
"delay": "5.0.0",
|
||||||
"next": "14.0.4",
|
"next": "15.0.1",
|
||||||
"prisma": "4.6.1",
|
"prisma": "6.1.0",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "19.0.0",
|
||||||
"react-hook-form": "7.39.1",
|
"react-hook-form": "7.39.1",
|
||||||
"ts-node": "10.9.1",
|
"ts-node": "10.9.1",
|
||||||
"zod": "3.20.2"
|
"zod": "3.23.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@next/bundle-analyzer": "12.0.8",
|
"@next/bundle-analyzer": "12.0.8",
|
||||||
"@testing-library/jest-dom": "5.16.5",
|
"@testing-library/jest-dom": "5.16.5",
|
||||||
"@testing-library/react": "13.4.0",
|
"@testing-library/react": "16.0.1",
|
||||||
"@testing-library/react-hooks": "8.0.1",
|
|
||||||
"@types/node": "18.11.9",
|
"@types/node": "18.11.9",
|
||||||
"@types/preview-email": "2.0.1",
|
"@types/preview-email": "2.0.1",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "npm:types-react@19.0.0",
|
||||||
"@typescript-eslint/eslint-plugin": "5.42.1",
|
"@typescript-eslint/eslint-plugin": "5.42.1",
|
||||||
"@vitejs/plugin-react": "2.2.0",
|
"@vitejs/plugin-react": "2.2.0",
|
||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
@@ -50,7 +49,7 @@
|
|||||||
"husky": "8.0.2",
|
"husky": "8.0.2",
|
||||||
"jsdom": "20.0.3",
|
"jsdom": "20.0.3",
|
||||||
"lint-staged": "13.0.3",
|
"lint-staged": "13.0.3",
|
||||||
"playwright": "1.28.0",
|
"playwright": "1.49.1",
|
||||||
"prettier": "^2.7.1",
|
"prettier": "^2.7.1",
|
||||||
"prettier-plugin-prisma": "4.4.0",
|
"prettier-plugin-prisma": "4.4.0",
|
||||||
"pretty-quick": "3.1.3",
|
"pretty-quick": "3.1.3",
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import {useMutation, useQuery} from "@blitzjs/rpc"
|
import {QueryClient, useMutation, useQuery} from "@blitzjs/rpc"
|
||||||
import logout from "../mutations/logout"
|
import logout from "../mutations/logout"
|
||||||
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
||||||
import {Suspense} from "react"
|
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
const [result] = useQuery(getAuthenticatedBasic, undefined)
|
const [result, {isLoading, isError, error}] = useQuery(getAuthenticatedBasic, undefined)
|
||||||
const [logoutMutation] = useMutation(logout)
|
const [logoutMutation] = useMutation(logout)
|
||||||
|
if (isError) throw error
|
||||||
|
if (isLoading || !result) return <div>Loading...</div>
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
<div id="content">{result}</div>
|
<div id="content">{result}</div>
|
||||||
<button
|
<button
|
||||||
id="logout"
|
id="logout"
|
||||||
@@ -17,16 +18,14 @@ function Content() {
|
|||||||
>
|
>
|
||||||
logout
|
logout
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function AuthenticatedQuery() {
|
function AuthenticatedQuery() {
|
||||||
return (
|
return (
|
||||||
<div id="page">
|
<div id="page">
|
||||||
<Suspense fallback={"Loading..."}>
|
<Content />
|
||||||
<Content />
|
|
||||||
</Suspense>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {useMutation, useQuery} from "@blitzjs/rpc"
|
import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import {BlitzPage} from "@blitzjs/next"
|
import {BlitzPage} from "@blitzjs/next"
|
||||||
import AuthenticateRedirectLayout from "../layouts/AuthenticateRedirectLayout"
|
import AuthenticateRedirectLayout from "../layouts/AuthenticateRedirectLayout"
|
||||||
import logout from "../mutations/logout"
|
import logout from "../mutations/logout"
|
||||||
@@ -6,7 +6,7 @@ import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
|||||||
import {Suspense} from "react"
|
import {Suspense} from "react"
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
const [result] = useQuery(getAuthenticatedBasic, undefined)
|
const [result] = useSuspenseQuery(getAuthenticatedBasic, undefined)
|
||||||
const [logoutMutation] = useMutation(logout)
|
const [logoutMutation] = useMutation(logout)
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import {useRouter} from "next/router"
|
import {useRouter} from "next/router"
|
||||||
import {useMutation, useQuery} from "@blitzjs/rpc"
|
import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import login from "../mutations/login"
|
import login from "../mutations/login"
|
||||||
import logout from "../mutations/logout"
|
import logout from "../mutations/logout"
|
||||||
import getCurrentUser from "../queries/getCurrentUser"
|
import getCurrentUser from "../queries/getCurrentUser"
|
||||||
@@ -8,7 +8,7 @@ import {Suspense, useState} from "react"
|
|||||||
function Content() {
|
function Content() {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const [error, setError] = useState(null)
|
const [error, setError] = useState(null)
|
||||||
const [userId] = useQuery(getCurrentUser, null)
|
const [userId] = useSuspenseQuery(getCurrentUser, null)
|
||||||
const [loginMutation] = useMutation(login)
|
const [loginMutation] = useMutation(login)
|
||||||
const [logoutMutation] = useMutation(logout)
|
const [logoutMutation] = useMutation(logout)
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {useQuery} from "@blitzjs/rpc"
|
import {useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import getNoauthBasic from "../queries/getNoauthBasic"
|
import getNoauthBasic from "../queries/getNoauthBasic"
|
||||||
import {Suspense} from "react"
|
import {Suspense} from "react"
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
const [result] = useQuery(getNoauthBasic, undefined)
|
const [result] = useSuspenseQuery(getNoauthBasic, undefined)
|
||||||
return <div id="content">{result}</div>
|
return <div id="content">{result}</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {useMutation, useQuery} from "@blitzjs/rpc"
|
import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import {BlitzPage} from "@blitzjs/next"
|
import {BlitzPage} from "@blitzjs/next"
|
||||||
import logout from "../mutations/logout"
|
import logout from "../mutations/logout"
|
||||||
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
||||||
import {Suspense} from "react"
|
import {Suspense} from "react"
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
const [result] = useQuery(getAuthenticatedBasic, undefined)
|
const [result] = useSuspenseQuery(getAuthenticatedBasic, undefined)
|
||||||
const [logoutMutation] = useMutation(logout)
|
const [logoutMutation] = useMutation(logout)
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {useMutation, useQuery} from "@blitzjs/rpc"
|
import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import {BlitzPage} from "@blitzjs/next"
|
import {BlitzPage} from "@blitzjs/next"
|
||||||
import logout from "../mutations/logout"
|
import logout from "../mutations/logout"
|
||||||
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
||||||
import {Suspense} from "react"
|
import {Suspense} from "react"
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
const [result] = useQuery(getAuthenticatedBasic, undefined)
|
const [result] = useSuspenseQuery(getAuthenticatedBasic, undefined)
|
||||||
const [logoutMutation] = useMutation(logout)
|
const [logoutMutation] = useMutation(logout)
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {useMutation, useQuery} from "@blitzjs/rpc"
|
import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import {BlitzPage} from "@blitzjs/next"
|
import {BlitzPage} from "@blitzjs/next"
|
||||||
import logout from "../mutations/logout"
|
import logout from "../mutations/logout"
|
||||||
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
||||||
import {Suspense} from "react"
|
import {Suspense} from "react"
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
const [result] = useQuery(getAuthenticatedBasic, undefined)
|
const [result] = useSuspenseQuery(getAuthenticatedBasic, undefined)
|
||||||
const [logoutMutation] = useMutation(logout)
|
const [logoutMutation] = useMutation(logout)
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {useMutation, useQuery} from "@blitzjs/rpc"
|
import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import {BlitzPage} from "@blitzjs/next"
|
import {BlitzPage} from "@blitzjs/next"
|
||||||
import logout from "../mutations/logout"
|
import logout from "../mutations/logout"
|
||||||
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
||||||
import {Suspense} from "react"
|
import {Suspense} from "react"
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
const [result] = useQuery(getAuthenticatedBasic, undefined)
|
const [result] = useSuspenseQuery(getAuthenticatedBasic, undefined)
|
||||||
const [logoutMutation] = useMutation(logout)
|
const [logoutMutation] = useMutation(logout)
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import {useMutation, useQuery} from "@blitzjs/rpc"
|
import {useMutation, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import {BlitzPage} from "@blitzjs/next"
|
import {BlitzPage} from "@blitzjs/next"
|
||||||
import logout from "../mutations/logout"
|
import logout from "../mutations/logout"
|
||||||
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
import getAuthenticatedBasic from "../queries/getAuthenticatedBasic"
|
||||||
import {Suspense} from "react"
|
import {Suspense} from "react"
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
const [result] = useQuery(getAuthenticatedBasic, undefined)
|
const [result] = useSuspenseQuery(getAuthenticatedBasic, undefined)
|
||||||
const [logoutMutation] = useMutation(logout)
|
const [logoutMutation] = useMutation(logout)
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ type Props = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getServerSideProps = gSSP<Props>(async ({ctx}) => {
|
export const getServerSideProps = gSSP<Props>(async ({ctx}) => {
|
||||||
await getQueryClient().prefetchQuery(getQueryKey(getNoauthBasic, null), () =>
|
await getQueryClient().prefetchQuery({
|
||||||
getNoauthBasic(null, ctx),
|
queryKey: getQueryKey(getNoauthBasic),
|
||||||
)
|
})
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
dehydratedState: dehydrate(queryClient),
|
dehydratedState: dehydrate(queryClient),
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import {invalidateQuery, useMutation, useQuery} from "@blitzjs/rpc"
|
import {invalidateQuery, useMutation, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import changeRole from "../mutations/changeRole"
|
import changeRole from "../mutations/changeRole"
|
||||||
import getPublicDataForUser from "../queries/getPublicDataForUser"
|
import getPublicDataForUser from "../queries/getPublicDataForUser"
|
||||||
import {Suspense} from "react"
|
import {Suspense} from "react"
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
const [publicData] = useQuery(getPublicDataForUser, {userId: 1})
|
const [publicData] = useSuspenseQuery(getPublicDataForUser, {userId: 1})
|
||||||
return (
|
return (
|
||||||
<div id="session">
|
<div id="session">
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -79,11 +79,13 @@ const runTests = () => {
|
|||||||
let text = await browser.elementByCss("#content").text()
|
let text = await browser.elementByCss("#content").text()
|
||||||
expect(text).toMatch(/logged-out/)
|
expect(text).toMatch(/logged-out/)
|
||||||
await browser.elementByCss("#login").click()
|
await browser.elementByCss("#login").click()
|
||||||
await waitFor(200)
|
await waitFor(7500)
|
||||||
text = await browser.elementByCss("#content").text()
|
text = await browser.elementByCss("#content").text()
|
||||||
|
|
||||||
expect(text).toMatch(/logged-in/)
|
expect(text).toMatch(/logged-in/)
|
||||||
|
|
||||||
await browser.elementByCss("#logout").click()
|
await browser.elementByCss("#logout").click()
|
||||||
await waitFor(250)
|
await waitFor(5000)
|
||||||
text = await browser.elementByCss("#content").text()
|
text = await browser.elementByCss("#content").text()
|
||||||
expect(text).toMatch(/logged-out/)
|
expect(text).toMatch(/logged-out/)
|
||||||
|
|
||||||
@@ -93,16 +95,16 @@ const runTests = () => {
|
|||||||
it("should logout without infinite loop #2233", async () => {
|
it("should logout without infinite loop #2233", async () => {
|
||||||
// Login
|
// Login
|
||||||
let browser = await webdriver(appPort, "/login")
|
let browser = await webdriver(appPort, "/login")
|
||||||
await waitFor(200)
|
await waitFor(5000)
|
||||||
await browser.elementByCss("#login").click()
|
await browser.elementByCss("#login").click()
|
||||||
await waitFor(200)
|
await waitFor(5000)
|
||||||
|
|
||||||
await browser.eval(`window.location = "/authenticated-query"`)
|
await browser.eval(`window.location = "/authenticated-query"`)
|
||||||
await browser.waitForElementByCss("#content")
|
await browser.waitForElementByCss("#content")
|
||||||
let text = await browser.elementByCss("#content").text()
|
let text = await browser.elementByCss("#content").text()
|
||||||
expect(text).toMatch(/authenticated-basic-result/)
|
expect(text).toMatch(/authenticated-basic-result/)
|
||||||
await browser.elementByCss("#logout").click()
|
await browser.elementByCss("#logout").click()
|
||||||
await waitFor(200)
|
await waitFor(5000)
|
||||||
await browser.waitForElementByCss("#error")
|
await browser.waitForElementByCss("#error")
|
||||||
text = await browser.elementByCss("#error").text()
|
text = await browser.elementByCss("#error").text()
|
||||||
if (mode === "server") {
|
if (mode === "server") {
|
||||||
@@ -115,9 +117,9 @@ const runTests = () => {
|
|||||||
|
|
||||||
it("Page.authenticate = {role} should throw authentication error ", async () => {
|
it("Page.authenticate = {role} should throw authentication error ", async () => {
|
||||||
let browser = await webdriver(appPort, "/login")
|
let browser = await webdriver(appPort, "/login")
|
||||||
await waitFor(200)
|
await waitFor(5000)
|
||||||
await browser.elementByCss("#login").click()
|
await browser.elementByCss("#login").click()
|
||||||
await waitFor(200)
|
await waitFor(5000)
|
||||||
await browser.eval(`window.location = "/page-dot-authenticate-role"`)
|
await browser.eval(`window.location = "/page-dot-authenticate-role"`)
|
||||||
await browser.waitForElementByCss("#error")
|
await browser.waitForElementByCss("#error")
|
||||||
let text = await browser.elementByCss("#error").text()
|
let text = await browser.elementByCss("#error").text()
|
||||||
@@ -169,7 +171,7 @@ const runTests = () => {
|
|||||||
let text = await browser.elementByCss("#content").text()
|
let text = await browser.elementByCss("#content").text()
|
||||||
expect(text).toMatch(/authenticated-basic-result/)
|
expect(text).toMatch(/authenticated-basic-result/)
|
||||||
await browser.elementByCss("#logout").click()
|
await browser.elementByCss("#logout").click()
|
||||||
await waitFor(500)
|
await waitFor(5000)
|
||||||
|
|
||||||
expect(await browser.url()).toMatch(/\/login/)
|
expect(await browser.url()).toMatch(/\/login/)
|
||||||
if (browser) await browser.close()
|
if (browser) await browser.close()
|
||||||
@@ -275,7 +277,7 @@ const runTests = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe("Auth Tests", () => {
|
describe("Auth Tests", () => {
|
||||||
describe("dev mode", () => {
|
describe("dev mode - webpack", () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
mode = "dev"
|
mode = "dev"
|
||||||
try {
|
try {
|
||||||
@@ -290,6 +292,21 @@ describe("Auth Tests", () => {
|
|||||||
runTests()
|
runTests()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("dev mode - turbo", () => {
|
||||||
|
beforeAll(async () => {
|
||||||
|
mode = "dev"
|
||||||
|
try {
|
||||||
|
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||||
|
appPort = await findPort()
|
||||||
|
app = await blitzLaunchApp(appPort, {cwd: process.cwd()}, true)
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}, 5000 * 60 * 2)
|
||||||
|
afterAll(async () => await killApp(app))
|
||||||
|
runTests()
|
||||||
|
})
|
||||||
|
|
||||||
describe("server mode", () => {
|
describe("server mode", () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
mode = "server"
|
mode = "server"
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ declare module "@blitzjs/auth" {
|
|||||||
PublicData: {
|
PublicData: {
|
||||||
userId: User["id"]
|
userId: User["id"]
|
||||||
role: Role
|
role: Role
|
||||||
views?: number
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
integration-tests/auth/next-env.d.ts
vendored
2
integration-tests/auth/next-env.d.ts
vendored
@@ -2,4 +2,4 @@
|
|||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
|
||||||
|
|||||||
@@ -17,16 +17,16 @@
|
|||||||
"prisma:studio": "prisma studio"
|
"prisma:studio": "prisma studio"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzjs/auth": "2.0.5",
|
"@blitzjs/auth": "3.0.1",
|
||||||
"@blitzjs/config": "2.0.5",
|
"@blitzjs/config": "3.0.1",
|
||||||
"@blitzjs/next": "2.0.5",
|
"@blitzjs/next": "3.0.1",
|
||||||
"@prisma/client": "4.6.1",
|
"@prisma/client": "6.1.0",
|
||||||
"blitz": "2.0.5",
|
"blitz": "3.0.1",
|
||||||
"lowdb": "3.0.0",
|
"lowdb": "3.0.0",
|
||||||
"next": "14.0.4",
|
"next": "15.0.1",
|
||||||
"prisma": "4.6.1",
|
"prisma": "6.1.0",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "19.0.0",
|
||||||
"secure-password": "4.0.0",
|
"secure-password": "4.0.0",
|
||||||
"wait-port": "1.0.4"
|
"wait-port": "1.0.4"
|
||||||
},
|
},
|
||||||
@@ -36,13 +36,13 @@
|
|||||||
"@types/fs-extra": "9.0.13",
|
"@types/fs-extra": "9.0.13",
|
||||||
"@types/node": "18.7.13",
|
"@types/node": "18.7.13",
|
||||||
"@types/node-fetch": "2.6.1",
|
"@types/node-fetch": "2.6.1",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "npm:types-react@19.0.0",
|
||||||
"b64-lite": "1.4.0",
|
"b64-lite": "1.4.0",
|
||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
"fs-extra": "10.0.1",
|
"fs-extra": "10.0.1",
|
||||||
"get-port": "6.1.2",
|
"get-port": "6.1.2",
|
||||||
"node-fetch": "3.2.3",
|
"node-fetch": "3.2.3",
|
||||||
"playwright": "1.28.0",
|
"playwright": "1.49.1",
|
||||||
"ts-node": "10.9.1",
|
"ts-node": "10.9.1",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.8.4"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,14 +21,11 @@ export const authenticateUser = async (email: string, password: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default api(async (req, res, ctx) => {
|
export default api(async (req, res, ctx) => {
|
||||||
const blitzContext = ctx
|
|
||||||
|
|
||||||
const user = await authenticateUser(req.query.email as string, req.query.password as string)
|
const user = await authenticateUser(req.query.email as string, req.query.password as string)
|
||||||
|
await ctx.session.$create({
|
||||||
await blitzContext.session.$create({
|
|
||||||
userId: user.id,
|
userId: user.id,
|
||||||
role: user.role as Role,
|
role: user.role as Role,
|
||||||
})
|
})
|
||||||
|
|
||||||
res.status(200).json({email: req.query.email, userId: blitzContext.session.userId})
|
res.status(200).json({email: req.query.email, userId: ctx.session.userId})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ declare module "@blitzjs/auth" {
|
|||||||
PublicData: {
|
PublicData: {
|
||||||
userId: User["id"]
|
userId: User["id"]
|
||||||
role: Role
|
role: Role
|
||||||
views?: number
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
/// <reference types="next" />
|
/// <reference types="next" />
|
||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
/// <reference types="next/navigation-types/compat/navigation" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
||||||
|
|||||||
@@ -16,24 +16,24 @@
|
|||||||
"schema": "db/schema.prisma"
|
"schema": "db/schema.prisma"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzjs/auth": "2.0.5",
|
"@blitzjs/auth": "3.0.1",
|
||||||
"@blitzjs/next": "2.0.5",
|
"@blitzjs/next": "3.0.1",
|
||||||
"@blitzjs/rpc": "2.0.5",
|
"@blitzjs/rpc": "3.0.1",
|
||||||
"@prisma/client": "4.6.1",
|
"@prisma/client": "6.1.0",
|
||||||
"blitz": "2.0.5",
|
"blitz": "3.0.1",
|
||||||
"lowdb": "3.0.0",
|
"lowdb": "2.1.0",
|
||||||
"next": "14.0.4",
|
"next": "15.0.1",
|
||||||
"prisma": "4.6.1",
|
"prisma": "6.1.0",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0"
|
"react-dom": "19.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@blitzjs/config": "2.0.5",
|
"@blitzjs/config": "3.0.1",
|
||||||
"@next/bundle-analyzer": "12.0.8",
|
"@next/bundle-analyzer": "12.0.8",
|
||||||
"@types/express": "4.17.13",
|
"@types/express": "4.17.13",
|
||||||
"@types/fs-extra": "9.0.13",
|
"@types/fs-extra": "9.0.13",
|
||||||
"@types/node-fetch": "2.6.1",
|
"@types/node-fetch": "2.6.1",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "npm:types-react@19.0.0",
|
||||||
"b64-lite": "1.4.0",
|
"b64-lite": "1.4.0",
|
||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
"fs-extra": "10.0.1",
|
"fs-extra": "10.0.1",
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
{
|
{
|
||||||
"extends": "@blitzjs/config/tsconfig.nextjs.json",
|
"extends": "@blitzjs/config/tsconfig.nextjs.json",
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"],
|
"include": ["**/*.ts", "**/*.tsx", "next-env.d.ts", "types", ".next/types/**/*.ts"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"paths": {
|
"paths": {
|
||||||
"react": ["./node_modules/@types/react"]
|
"react": ["./node_modules/@types/react"]
|
||||||
}
|
},
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"strictNullChecks": true
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules"],
|
"exclude": ["node_modules"],
|
||||||
"baseUrl": "."
|
"baseUrl": "."
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ declare module "@blitzjs/auth" {
|
|||||||
PublicData: {
|
PublicData: {
|
||||||
userId: User["id"]
|
userId: User["id"]
|
||||||
role: Role
|
role: Role
|
||||||
views?: number
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
integration-tests/middleware/next-env.d.ts
vendored
2
integration-tests/middleware/next-env.d.ts
vendored
@@ -3,4 +3,4 @@
|
|||||||
/// <reference types="next/navigation-types/compat/navigation" />
|
/// <reference types="next/navigation-types/compat/navigation" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
||||||
|
|||||||
@@ -11,20 +11,20 @@
|
|||||||
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next"
|
"clean": "rm -rf .turbo && rm -rf node_modules && rm -rf .next"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzjs/config": "2.0.5",
|
"@blitzjs/config": "3.0.1",
|
||||||
"@blitzjs/next": "2.0.5",
|
"@blitzjs/next": "3.0.1",
|
||||||
"@blitzjs/rpc": "2.0.5",
|
"@blitzjs/rpc": "3.0.1",
|
||||||
"blitz": "2.0.5",
|
"blitz": "3.0.1",
|
||||||
"next": "14.0.4",
|
"next": "15.0.1",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0"
|
"react-dom": "19.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@next/bundle-analyzer": "12.0.8",
|
"@next/bundle-analyzer": "12.0.8",
|
||||||
"@types/express": "4.17.13",
|
"@types/express": "4.17.13",
|
||||||
"@types/fs-extra": "9.0.13",
|
"@types/fs-extra": "9.0.13",
|
||||||
"@types/node-fetch": "2.6.1",
|
"@types/node-fetch": "2.6.1",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "npm:types-react@19.0.0",
|
||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
"fs-extra": "10.0.1",
|
"fs-extra": "10.0.1",
|
||||||
"get-port": "6.1.2",
|
"get-port": "6.1.2",
|
||||||
|
|||||||
15
integration-tests/next-13-app-dir/app/api/logout/route.ts
Normal file
15
integration-tests/next-13-app-dir/app/api/logout/route.ts
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import {withBlitzAuth} from "../../../src/blitz-server"
|
||||||
|
|
||||||
|
export const {POST} = withBlitzAuth({
|
||||||
|
POST: async (_request, _params, ctx) => {
|
||||||
|
const session = ctx.session
|
||||||
|
await session.$revoke()
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({
|
||||||
|
userId: session.userId,
|
||||||
|
}),
|
||||||
|
{status: 200},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
11
integration-tests/next-13-app-dir/app/api/noauth/route.ts
Normal file
11
integration-tests/next-13-app-dir/app/api/noauth/route.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import {H} from "@blitzjs/auth/dist/index-0ecbee46"
|
||||||
|
import {withBlitzAuth} from "../../../src/blitz-server"
|
||||||
|
|
||||||
|
const emptyResponse = async () => {
|
||||||
|
return new Response(null, {status: 200})
|
||||||
|
}
|
||||||
|
|
||||||
|
export const {POST, HEAD} = withBlitzAuth({
|
||||||
|
POST: emptyResponse,
|
||||||
|
HEAD: emptyResponse,
|
||||||
|
})
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import {rpcAppHandler} from "@blitzjs/rpc"
|
||||||
|
import {withBlitzAuth} from "../../../../src/blitz-server"
|
||||||
|
|
||||||
|
export const {GET, POST, HEAD} = withBlitzAuth(rpcAppHandler())
|
||||||
38
integration-tests/next-13-app-dir/app/api/signin/route.ts
Normal file
38
integration-tests/next-13-app-dir/app/api/signin/route.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import {withBlitzAuth} from "../../../src/blitz-server"
|
||||||
|
import prisma from "../../../db/index"
|
||||||
|
import {Role} from "../../../types"
|
||||||
|
|
||||||
|
export const authenticateUser = async (email: string, password: string) => {
|
||||||
|
const user = await prisma.user.findFirst({where: {email}})
|
||||||
|
|
||||||
|
if (!user) throw new Error("Authentication Error")
|
||||||
|
await prisma.user.update({where: {id: user.id}, data: {hashedPassword: password}})
|
||||||
|
|
||||||
|
const {hashedPassword, ...rest} = user
|
||||||
|
return rest
|
||||||
|
}
|
||||||
|
|
||||||
|
export const {POST} = withBlitzAuth({
|
||||||
|
POST: async (request: Request, context, ctx) => {
|
||||||
|
const {searchParams} = new URL(request.url)
|
||||||
|
const user = await authenticateUser(
|
||||||
|
searchParams.get("email") as string,
|
||||||
|
searchParams.get("password") as string,
|
||||||
|
)
|
||||||
|
|
||||||
|
await ctx.session.$create({
|
||||||
|
userId: user.id,
|
||||||
|
role: user.role as Role,
|
||||||
|
})
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify({email: searchParams.get("email"), userId: ctx.session.userId}),
|
||||||
|
{
|
||||||
|
status: 200,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
"use client"
|
|
||||||
|
|
||||||
import {useQuery, useMutation} from "@blitzjs/rpc"
|
|
||||||
import logout from "../src/auth/mutations/logout"
|
|
||||||
import getCurrentUser from "../src/users/queries/getCurrentUser"
|
|
||||||
import {useTransition} from "react"
|
|
||||||
import {useRouter} from "next/navigation"
|
|
||||||
|
|
||||||
export default function Test() {
|
|
||||||
const router = useRouter()
|
|
||||||
const [user] = useQuery(getCurrentUser, null)
|
|
||||||
const [isPending, startTransition] = useTransition()
|
|
||||||
const [logoutMutation] = useMutation(logout)
|
|
||||||
console.log(user)
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h1>Test</h1>
|
|
||||||
<p>{user?.email}</p>
|
|
||||||
<button
|
|
||||||
className="button small"
|
|
||||||
onClick={async () => {
|
|
||||||
await logoutMutation()
|
|
||||||
startTransition(() => {
|
|
||||||
// Refresh the current route and fetch new data from the server without
|
|
||||||
// losing client-side browser or React state.
|
|
||||||
router.refresh()
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Logout
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
"use client"
|
"use client"
|
||||||
import {getQueryData, useQuery} from "@blitzjs/rpc"
|
import {getQueryData, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import {Suspense, useState} from "react"
|
import {Suspense, useState} from "react"
|
||||||
import getBasic from "../../src/queries/getBasic"
|
import getBasic from "../../src/queries/getBasic"
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
const [data] = useQuery(getBasic, undefined)
|
const [data] = useSuspenseQuery(getBasic, undefined)
|
||||||
const [newData, setNewData] = useState<string>()
|
const [newData, setNewData] = useState<string>()
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
/// <reference types="next" />
|
/// <reference types="next" />
|
||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
/// <reference types="next/navigation-types/compat/navigation" />
|
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
||||||
|
|||||||
@@ -17,17 +17,17 @@
|
|||||||
"prisma:studio": "prisma studio"
|
"prisma:studio": "prisma studio"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzjs/auth": "2.0.5",
|
"@blitzjs/auth": "3.0.1",
|
||||||
"@blitzjs/config": "2.0.5",
|
"@blitzjs/config": "3.0.1",
|
||||||
"@blitzjs/next": "2.0.5",
|
"@blitzjs/next": "3.0.1",
|
||||||
"@blitzjs/rpc": "2.0.5",
|
"@blitzjs/rpc": "3.0.1",
|
||||||
"@prisma/client": "4.6.1",
|
"@prisma/client": "6.1.0",
|
||||||
"blitz": "2.0.5",
|
"blitz": "3.0.1",
|
||||||
"lowdb": "3.0.0",
|
"lowdb": "2.1.0",
|
||||||
"next": "14.0.4",
|
"next": "15.0.1",
|
||||||
"prisma": "4.6.1",
|
"prisma": "6.1.0",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "19.0.0",
|
||||||
"secure-password": "4.0.0",
|
"secure-password": "4.0.0",
|
||||||
"wait-port": "1.0.4"
|
"wait-port": "1.0.4"
|
||||||
},
|
},
|
||||||
@@ -37,14 +37,14 @@
|
|||||||
"@types/fs-extra": "9.0.13",
|
"@types/fs-extra": "9.0.13",
|
||||||
"@types/node": "18.7.13",
|
"@types/node": "18.7.13",
|
||||||
"@types/node-fetch": "2.6.1",
|
"@types/node-fetch": "2.6.1",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "npm:types-react@19.0.0",
|
||||||
"b64-lite": "1.4.0",
|
"b64-lite": "1.4.0",
|
||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
"fs-extra": "10.0.1",
|
"fs-extra": "10.0.1",
|
||||||
"get-port": "6.1.2",
|
"get-port": "6.1.2",
|
||||||
"node-fetch": "3.2.3",
|
"node-fetch": "3.2.3",
|
||||||
"playwright": "1.28.0",
|
"playwright": "1.49.1",
|
||||||
"ts-node": "10.9.1",
|
"ts-node": "10.9.1",
|
||||||
"typescript": "^4.8.4"
|
"typescript": "^4.9.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
import {api} from "../../src/blitz-server"
|
|
||||||
|
|
||||||
export default api(async (_req, res, ctx) => {
|
|
||||||
const blitzContext = ctx
|
|
||||||
|
|
||||||
await blitzContext.session.$revoke()
|
|
||||||
|
|
||||||
res.status(200).json({userId: blitzContext.session.userId})
|
|
||||||
})
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
import {api} from "../../src/blitz-server"
|
|
||||||
|
|
||||||
export default api(async (_req, res, ctx) => {
|
|
||||||
res.status(200).end()
|
|
||||||
})
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
import {rpcHandler} from "@blitzjs/rpc"
|
|
||||||
import {api} from "../../../src/blitz-server"
|
|
||||||
|
|
||||||
export default api(rpcHandler({onError: (error, ctx) => console.log(error)}))
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
import {api} from "../../src/blitz-server"
|
|
||||||
import prisma from "../../db/index"
|
|
||||||
import {SecurePassword} from "@blitzjs/auth/secure-password"
|
|
||||||
import {Role} from "../../types"
|
|
||||||
|
|
||||||
export const authenticateUser = async (email: string, password: string) => {
|
|
||||||
const user = await prisma.user.findFirst({where: {email}})
|
|
||||||
|
|
||||||
if (!user) throw new Error("Authentication Error")
|
|
||||||
|
|
||||||
const result = await SecurePassword.verify(user.hashedPassword, password)
|
|
||||||
|
|
||||||
if (result === SecurePassword.VALID_NEEDS_REHASH) {
|
|
||||||
// Upgrade hashed password with a more secure hash
|
|
||||||
const improvedHash = await SecurePassword.hash(password)
|
|
||||||
await prisma.user.update({where: {id: user.id}, data: {hashedPassword: improvedHash}})
|
|
||||||
}
|
|
||||||
|
|
||||||
const {hashedPassword, ...rest} = user
|
|
||||||
return rest
|
|
||||||
}
|
|
||||||
|
|
||||||
export default api(async (req, res, ctx) => {
|
|
||||||
const blitzContext = ctx
|
|
||||||
|
|
||||||
const user = await authenticateUser(req.query.email as string, req.query.password as string)
|
|
||||||
|
|
||||||
await blitzContext.session.$create({
|
|
||||||
userId: user.id,
|
|
||||||
role: user.role as Role,
|
|
||||||
})
|
|
||||||
|
|
||||||
res.status(200).json({email: req.query.email, userId: blitzContext.session.userId})
|
|
||||||
})
|
|
||||||
@@ -3,16 +3,16 @@ import {AuthServerPlugin, PrismaStorage} from "@blitzjs/auth"
|
|||||||
import db from "../db"
|
import db from "../db"
|
||||||
import {simpleRolesIsAuthorized} from "@blitzjs/auth"
|
import {simpleRolesIsAuthorized} from "@blitzjs/auth"
|
||||||
import {BlitzLogger} from "blitz"
|
import {BlitzLogger} from "blitz"
|
||||||
|
import {RpcServerPlugin} from "@blitzjs/rpc"
|
||||||
|
|
||||||
const {api, getBlitzContext} = setupBlitzServer({
|
export const {api, getBlitzContext, withBlitzAuth} = setupBlitzServer({
|
||||||
plugins: [
|
plugins: [
|
||||||
AuthServerPlugin({
|
AuthServerPlugin({
|
||||||
cookiePrefix: "auth-tests-cookie-prefix",
|
cookiePrefix: "auth-tests-cookie-prefix",
|
||||||
storage: PrismaStorage(db),
|
storage: PrismaStorage(db),
|
||||||
isAuthorized: simpleRolesIsAuthorized,
|
isAuthorized: simpleRolesIsAuthorized,
|
||||||
}),
|
}),
|
||||||
|
RpcServerPlugin({}),
|
||||||
],
|
],
|
||||||
logger: BlitzLogger({}),
|
logger: BlitzLogger({}),
|
||||||
})
|
})
|
||||||
|
|
||||||
export {api, getBlitzContext}
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ const runTests = (mode?: string) => {
|
|||||||
"should render result for open query",
|
"should render result for open query",
|
||||||
async () => {
|
async () => {
|
||||||
const res = await fetch(`http://localhost:${appPort}/api/noauth`, {
|
const res = await fetch(`http://localhost:${appPort}/api/noauth`, {
|
||||||
method: "GET",
|
method: "POST",
|
||||||
headers: {"Content-Type": "application/json; charset=utf-8"},
|
headers: {"Content-Type": "application/json; charset=utf-8"},
|
||||||
})
|
})
|
||||||
expect(res.status).toBe(200)
|
expect(res.status).toBe(200)
|
||||||
@@ -67,7 +67,7 @@ const runTests = (mode?: string) => {
|
|||||||
|
|
||||||
it("sets correct cookie", async () => {
|
it("sets correct cookie", async () => {
|
||||||
const res = await fetch(`http://localhost:${appPort}/api/noauth`, {
|
const res = await fetch(`http://localhost:${appPort}/api/noauth`, {
|
||||||
method: "GET",
|
method: "POST",
|
||||||
headers: {"Content-Type": "application/json; charset=utf-8"},
|
headers: {"Content-Type": "application/json; charset=utf-8"},
|
||||||
})
|
})
|
||||||
const cookieHeader = res.headers.get("Set-Cookie")
|
const cookieHeader = res.headers.get("Set-Cookie")
|
||||||
@@ -94,6 +94,8 @@ const runTests = (mode?: string) => {
|
|||||||
async () => {
|
async () => {
|
||||||
const browser = await webdriver(appPort, "/react-query")
|
const browser = await webdriver(appPort, "/react-query")
|
||||||
|
|
||||||
|
await browser.refresh()
|
||||||
|
|
||||||
browser.waitForElementByCss("#button", 0)
|
browser.waitForElementByCss("#button", 0)
|
||||||
await browser.elementByCss("#button").click()
|
await browser.elementByCss("#button").click()
|
||||||
|
|
||||||
@@ -133,7 +135,7 @@ const runTests = (mode?: string) => {
|
|||||||
|
|
||||||
it("does not require CSRF header on HEAD requests", async () => {
|
it("does not require CSRF header on HEAD requests", async () => {
|
||||||
const res = await fetch(`http://localhost:${appPort}/api/noauth`, {
|
const res = await fetch(`http://localhost:${appPort}/api/noauth`, {
|
||||||
method: "GET",
|
method: "POST",
|
||||||
headers: {"Content-Type": "application/json; charset=utf-8"},
|
headers: {"Content-Type": "application/json; charset=utf-8"},
|
||||||
})
|
})
|
||||||
const cookieHeader = res.headers.get("Set-Cookie")
|
const cookieHeader = res.headers.get("Set-Cookie")
|
||||||
@@ -153,7 +155,7 @@ const runTests = (mode?: string) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
describe("Auth Tests", () => {
|
describe("Auth Tests", () => {
|
||||||
describe("dev mode", async () => {
|
describe("dev mode - webpack", async () => {
|
||||||
beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
try {
|
try {
|
||||||
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||||
@@ -169,19 +171,19 @@ describe("Auth Tests", () => {
|
|||||||
runTests()
|
runTests()
|
||||||
})
|
})
|
||||||
|
|
||||||
// describe("server mode", () => {
|
describe("dev mode - turbo", async () => {
|
||||||
// beforeAll(async () => {
|
beforeAll(async () => {
|
||||||
// try {
|
try {
|
||||||
// await runBlitzCommand(["prisma", "generate"])
|
await runBlitzCommand(["prisma", "migrate", "reset", "--force"])
|
||||||
// await runBlitzCommand(["prisma", "migrate", "deploy"])
|
appPort = await findPort()
|
||||||
// await blitzBuild()
|
app = await blitzLaunchApp(appPort, {cwd: process.cwd()}, true)
|
||||||
// // appPort = await findPort()
|
} catch (error) {
|
||||||
// app = await blitzStart(appPort, {cwd: process.cwd()})
|
console.log(error)
|
||||||
// } catch (err) {
|
}
|
||||||
// console.log(err)
|
}, 5000 * 60 * 2)
|
||||||
// }
|
afterAll(async () => {
|
||||||
// }, 5000 * 60 * 2)
|
await killApp(app)
|
||||||
// afterAll(async () => await killApp(app))
|
})
|
||||||
// runTests()
|
runTests()
|
||||||
// })
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ declare module "@blitzjs/auth" {
|
|||||||
PublicData: {
|
PublicData: {
|
||||||
userId: User["id"]
|
userId: User["id"]
|
||||||
role: Role
|
role: Role
|
||||||
views?: number
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
3
integration-tests/no-suspense/next-env.d.ts
vendored
3
integration-tests/no-suspense/next-env.d.ts
vendored
@@ -1,5 +1,6 @@
|
|||||||
/// <reference types="next" />
|
/// <reference types="next" />
|
||||||
/// <reference types="next/image-types/global" />
|
/// <reference types="next/image-types/global" />
|
||||||
|
/// <reference types="next/navigation-types/compat/navigation" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
||||||
|
|||||||
@@ -16,24 +16,24 @@
|
|||||||
"prisma:studio": "prisma studio"
|
"prisma:studio": "prisma studio"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzjs/auth": "2.0.5",
|
"@blitzjs/auth": "3.0.1",
|
||||||
"@blitzjs/next": "2.0.5",
|
"@blitzjs/next": "3.0.1",
|
||||||
"@blitzjs/rpc": "2.0.5",
|
"@blitzjs/rpc": "3.0.1",
|
||||||
"@prisma/client": "4.6.1",
|
"@prisma/client": "6.1.0",
|
||||||
"blitz": "2.0.5",
|
"blitz": "3.0.1",
|
||||||
"lowdb": "3.0.0",
|
"lowdb": "3.0.0",
|
||||||
"next": "14.0.4",
|
"next": "15.0.1",
|
||||||
"prisma": "4.6.1",
|
"prisma": "6.1.0",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0"
|
"react-dom": "19.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@blitzjs/config": "2.0.5",
|
"@blitzjs/config": "3.0.1",
|
||||||
"@next/bundle-analyzer": "12.0.8",
|
"@next/bundle-analyzer": "12.0.8",
|
||||||
"@types/express": "4.17.13",
|
"@types/express": "4.17.13",
|
||||||
"@types/fs-extra": "9.0.13",
|
"@types/fs-extra": "9.0.13",
|
||||||
"@types/node-fetch": "2.6.1",
|
"@types/node-fetch": "2.6.1",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "npm:types-react@19.0.0",
|
||||||
"b64-lite": "1.4.0",
|
"b64-lite": "1.4.0",
|
||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
"fs-extra": "10.0.1",
|
"fs-extra": "10.0.1",
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
{
|
{
|
||||||
"extends": "@blitzjs/config/tsconfig.nextjs.json",
|
"extends": "@blitzjs/config/tsconfig.nextjs.json",
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "types"],
|
"include": ["**/*.ts", "**/*.tsx", "next-env.d.ts", "types", ".next/types/**/*.ts"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"paths": {
|
"paths": {
|
||||||
"react": ["./node_modules/@types/react"]
|
"react": ["./node_modules/@types/react"]
|
||||||
}
|
},
|
||||||
|
"plugins": [
|
||||||
|
{
|
||||||
|
"name": "next"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"strictNullChecks": true
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules"],
|
"exclude": ["node_modules"],
|
||||||
"baseUrl": "."
|
"baseUrl": "."
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ declare module "@blitzjs/auth" {
|
|||||||
PublicData: {
|
PublicData: {
|
||||||
userId: User["id"]
|
userId: User["id"]
|
||||||
role: Role
|
role: Role
|
||||||
views?: number
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,21 +8,21 @@
|
|||||||
"clean": "rm -rf .turbo && rm -rf node_modules"
|
"clean": "rm -rf .turbo && rm -rf node_modules"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzjs/auth": "2.0.5",
|
"@blitzjs/auth": "3.0.1",
|
||||||
"@blitzjs/config": "2.0.5",
|
"@blitzjs/config": "3.0.1",
|
||||||
"@blitzjs/next": "2.0.5",
|
"@blitzjs/next": "3.0.1",
|
||||||
"@blitzjs/rpc": "2.0.5",
|
"@blitzjs/rpc": "3.0.1",
|
||||||
"@prisma/client": "4.6.1",
|
"@prisma/client": "6.1.0",
|
||||||
"@tanstack/react-query": "4.0.10",
|
"@tanstack/react-query": "5.51.1",
|
||||||
"blitz": "2.0.5",
|
"blitz": "3.0.1",
|
||||||
"next": "14.0.4",
|
"next": "15.0.1",
|
||||||
"prisma": "4.6.1",
|
"prisma": "6.1.0",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0"
|
"react-dom": "19.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@testing-library/react": "13.4.0",
|
"@testing-library/react": "16.0.1",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "npm:types-react@19.0.0",
|
||||||
"@vitejs/plugin-react": "1.3.0",
|
"@vitejs/plugin-react": "1.3.0",
|
||||||
"delay": "5.0.0",
|
"delay": "5.0.0",
|
||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
|
|||||||
@@ -3,3 +3,7 @@
|
|||||||
exports[`useQuery > a "query" that converts the string parameter to uppercase > shouldn't work with mutation function 1`] = `"\\"useQuery\\" was expected to be called with a query but was called with a \\"mutation\\""`;
|
exports[`useQuery > a "query" that converts the string parameter to uppercase > shouldn't work with mutation function 1`] = `"\\"useQuery\\" was expected to be called with a query but was called with a \\"mutation\\""`;
|
||||||
|
|
||||||
exports[`useQuery > a "query" that converts the string parameter to uppercase > shouldn't work with regular functions 1`] = `"Either the file path to your resolver is incorrect (must be in a \\"queries\\" or \\"mutations\\" folder that isn't nested inside \\"pages\\" or \\"api\\") or you are trying to use Blitz's useQuery to fetch from third-party APIs (to do that, import useQuery directly from \\"@tanstack/react-query\\")."`;
|
exports[`useQuery > a "query" that converts the string parameter to uppercase > shouldn't work with regular functions 1`] = `"Either the file path to your resolver is incorrect (must be in a \\"queries\\" or \\"mutations\\" folder that isn't nested inside \\"pages\\" or \\"api\\") or you are trying to use Blitz's useQuery to fetch from third-party APIs (to do that, import useQuery directly from \\"@tanstack/react-query\\")."`;
|
||||||
|
|
||||||
|
exports[`useSuspenseQuery > a "query" that converts the string parameter to uppercase > shouldn't work with mutation function 1`] = `"\\"useQuery\\" was expected to be called with a query but was called with a \\"mutation\\""`;
|
||||||
|
|
||||||
|
exports[`useSuspenseQuery > a "query" that converts the string parameter to uppercase > shouldn't work with regular functions 1`] = `"Either the file path to your resolver is incorrect (must be in a \\"queries\\" or \\"mutations\\" folder that isn't nested inside \\"pages\\" or \\"api\\") or you are trying to use Blitz's useQuery to fetch from third-party APIs (to do that, import useQuery directly from \\"@tanstack/react-query\\")."`;
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import {describe, it, expect, beforeAll, vi} from "vitest"
|
import {describe, it, expect, beforeAll, vi} from "vitest"
|
||||||
import {act, screen, waitForElementToBeRemoved} from "@testing-library/react"
|
import {act, screen, waitForElementToBeRemoved} from "@testing-library/react"
|
||||||
import {useQuery, useInfiniteQuery, BlitzRpcPlugin, BlitzProvider} from "@blitzjs/rpc"
|
import {
|
||||||
|
useSuspenseQuery,
|
||||||
|
useQuery,
|
||||||
|
useSuspenseInfiniteQuery,
|
||||||
|
BlitzRpcPlugin,
|
||||||
|
BlitzProvider,
|
||||||
|
} from "@blitzjs/rpc"
|
||||||
import React from "react"
|
import React from "react"
|
||||||
import delay from "delay"
|
import delay from "delay"
|
||||||
import {buildMutationRpc, buildQueryRpc, mockRouter, render} from "../../utils/blitz-test-utils"
|
import {buildMutationRpc, buildQueryRpc, mockRouter, render} from "../../utils/blitz-test-utils"
|
||||||
@@ -11,19 +17,18 @@ beforeAll(() => {
|
|||||||
globalThis.IS_REACT_ACT_ENVIRONMENT = true
|
globalThis.IS_REACT_ACT_ENVIRONMENT = true
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("useQuery", () => {
|
describe("useSuspenseQuery", () => {
|
||||||
const setupHook = (
|
const setupHook = (
|
||||||
ID: string,
|
ID: string,
|
||||||
params: any,
|
params: any,
|
||||||
queryFn: (...args: any) => any,
|
queryFn: (...args: any) => any,
|
||||||
options: Parameters<typeof useQuery>[2] = {} as any,
|
options: Parameters<typeof useSuspenseQuery>[2] = {} as any,
|
||||||
): [{data?: any; setQueryData?: any}, Function] => {
|
): [{data?: any; setQueryData?: any}, Function] => {
|
||||||
let res = {}
|
let res = {}
|
||||||
const qc = BlitzRpcPlugin({})
|
const qc = BlitzRpcPlugin({})
|
||||||
|
|
||||||
function TestHarness() {
|
function TestSuspenseHarness() {
|
||||||
const [data, {setQueryData}] = useQuery(queryFn, params, {
|
const [data, {setQueryData}] = useSuspenseQuery(queryFn, params, {
|
||||||
suspense: true,
|
|
||||||
...(options as any),
|
...(options as any),
|
||||||
} as any)
|
} as any)
|
||||||
|
|
||||||
@@ -38,7 +43,7 @@ describe("useQuery", () => {
|
|||||||
|
|
||||||
const ui = () => (
|
const ui = () => (
|
||||||
<React.Suspense fallback="Loading...">
|
<React.Suspense fallback="Loading...">
|
||||||
<TestHarness />
|
<TestSuspenseHarness />
|
||||||
</React.Suspense>
|
</React.Suspense>
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -90,27 +95,9 @@ describe("useQuery", () => {
|
|||||||
expect(() => setupHook("5", "test", buildMutationRpc(upcase))).toThrowErrorMatchingSnapshot()
|
expect(() => setupHook("5", "test", buildMutationRpc(upcase))).toThrowErrorMatchingSnapshot()
|
||||||
})
|
})
|
||||||
|
|
||||||
it("suspense disabled if enabled is false", async () => {
|
|
||||||
setupHook("6", "test", buildQueryRpc(upcase), {enabled: false})
|
|
||||||
await screen.findByText("No data")
|
|
||||||
})
|
|
||||||
|
|
||||||
it("suspense disabled if enabled is undefined", async () => {
|
|
||||||
setupHook("7", "test", buildQueryRpc(upcase), {enabled: undefined})
|
|
||||||
await screen.findByText("No data")
|
|
||||||
})
|
|
||||||
|
|
||||||
// it("suspense disabled if enabled is false and suspense set", async () => {
|
|
||||||
// setupHook("8", "test", buildQueryRpc(upcase), {
|
|
||||||
// enabled: false,
|
|
||||||
// suspense: true,
|
|
||||||
// })
|
|
||||||
// await screen.findByText("No data")
|
|
||||||
// })
|
|
||||||
|
|
||||||
it("works with options other than enabled & suspense without type error", () => {
|
it("works with options other than enabled & suspense without type error", () => {
|
||||||
const Demo = () => {
|
const Demo = () => {
|
||||||
useQuery(buildQueryRpc(upcase), undefined, {refetchInterval: 10000})
|
useSuspenseQuery(buildQueryRpc(upcase), undefined, {refetchInterval: 10000})
|
||||||
return <div></div>
|
return <div></div>
|
||||||
}
|
}
|
||||||
const ui = () => <Demo />
|
const ui = () => <Demo />
|
||||||
@@ -126,7 +113,112 @@ describe("useQuery", () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("useInfiniteQuery", () => {
|
describe("useQuery", () => {
|
||||||
|
const setupHook = (
|
||||||
|
ID: string,
|
||||||
|
params: any,
|
||||||
|
queryFn: (...args: any) => any,
|
||||||
|
options: Parameters<typeof useQuery>[2] = {} as any,
|
||||||
|
): [{data?: any; setQueryData?: any}, Function] => {
|
||||||
|
let res = {}
|
||||||
|
const qc = BlitzRpcPlugin({})
|
||||||
|
|
||||||
|
function TestHarness() {
|
||||||
|
const [data, {setQueryData, isLoading}] = useQuery(queryFn, params, {
|
||||||
|
...(options as any),
|
||||||
|
} as any)
|
||||||
|
|
||||||
|
Object.assign(res, {data, setQueryData})
|
||||||
|
if (isLoading) {
|
||||||
|
return <div>Loading...</div>
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div id={`harness-${ID}`}>
|
||||||
|
<span>{data ? `Ready${ID}` : "No data"}</span>
|
||||||
|
<span>{data}</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const ui = () => <TestHarness />
|
||||||
|
|
||||||
|
const {rerender} = render(ui(), {
|
||||||
|
wrapper: ({children}) => (
|
||||||
|
<BlitzProvider>
|
||||||
|
<RouterContext.Provider value={mockRouter}>{children}</RouterContext.Provider>
|
||||||
|
</BlitzProvider>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
return [res, () => rerender(ui())]
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('a "query" that converts the string parameter to uppercase', () => {
|
||||||
|
const upcase = async (args: string) => {
|
||||||
|
await delay(500)
|
||||||
|
return args.toUpperCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
it("should work with Blitz queries", async () => {
|
||||||
|
const [res] = setupHook("2", "test", buildQueryRpc(upcase))
|
||||||
|
await waitForElementToBeRemoved(() => screen.getByText("Loading..."))
|
||||||
|
await act(async () => {
|
||||||
|
await screen.queryAllByText("Ready2")[0]
|
||||||
|
expect(res.data).toBe("TEST")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it("should be able to change the data with setQueryData", async () => {
|
||||||
|
const [res] = setupHook("3", "fooBar", buildQueryRpc(upcase))
|
||||||
|
await waitForElementToBeRemoved(() => screen.getByText("Loading..."))
|
||||||
|
await act(async () => {
|
||||||
|
await screen.queryAllByText("Ready3")[0]
|
||||||
|
expect(res.data).toBe("FOOBAR")
|
||||||
|
res.setQueryData((p: string) => p.substr(3, 3), {refetch: false})
|
||||||
|
await delay(100)
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(res.data).toBe("BAR")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("shouldn't work with regular functions", () => {
|
||||||
|
console.error = vi.fn()
|
||||||
|
expect(() => setupHook("4", "test", upcase)).toThrowErrorMatchingSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("shouldn't work with mutation function", () => {
|
||||||
|
console.error = vi.fn()
|
||||||
|
expect(() => setupHook("5", "test", buildMutationRpc(upcase))).toThrowErrorMatchingSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("suspense disabled if enabled is false", async () => {
|
||||||
|
setupHook("6", "test", buildQueryRpc(upcase), {enabled: false})
|
||||||
|
await screen.findByText("No data")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("suspense disabled if enabled is undefined", async () => {
|
||||||
|
setupHook("7", "test", buildQueryRpc(upcase), {enabled: undefined})
|
||||||
|
await screen.findByText("No data")
|
||||||
|
})
|
||||||
|
|
||||||
|
it("works with options other than enabled & suspense without type error", () => {
|
||||||
|
const Demo = () => {
|
||||||
|
useSuspenseQuery(buildQueryRpc(upcase), undefined, {refetchInterval: 10000})
|
||||||
|
return <div></div>
|
||||||
|
}
|
||||||
|
const ui = () => <Demo />
|
||||||
|
|
||||||
|
const {rerender} = render(ui(), {
|
||||||
|
wrapper: ({children}) => (
|
||||||
|
<BlitzProvider>
|
||||||
|
<RouterContext.Provider value={mockRouter}>{children}</RouterContext.Provider>
|
||||||
|
</BlitzProvider>
|
||||||
|
),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("useSuspenseInfiniteQuery", () => {
|
||||||
const setupHook = (
|
const setupHook = (
|
||||||
ID: string,
|
ID: string,
|
||||||
params: (arg?: any) => any,
|
params: (arg?: any) => any,
|
||||||
@@ -138,7 +230,7 @@ describe("useInfiniteQuery", () => {
|
|||||||
function TestHarness() {
|
function TestHarness() {
|
||||||
// TODO - fix typing
|
// TODO - fix typing
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
const [groupedData] = useInfiniteQuery(queryFn, params, {
|
const [groupedData] = useSuspenseInfiniteQuery(queryFn, params, {
|
||||||
suspense: true,
|
suspense: true,
|
||||||
getNextPageParam: () => {},
|
getNextPageParam: () => {},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
/// <reference types="next/navigation-types/compat/navigation" />
|
/// <reference types="next/navigation-types/compat/navigation" />
|
||||||
|
|
||||||
// NOTE: This file should not be edited
|
// NOTE: This file should not be edited
|
||||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
|
||||||
|
|||||||
@@ -16,23 +16,23 @@
|
|||||||
"schema": "db/schema.prisma"
|
"schema": "db/schema.prisma"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@blitzjs/next": "2.0.5",
|
"@blitzjs/next": "3.0.1",
|
||||||
"@blitzjs/rpc": "2.0.5",
|
"@blitzjs/rpc": "3.0.1",
|
||||||
"@prisma/client": "4.6.1",
|
"@prisma/client": "6.1.0",
|
||||||
"blitz": "2.0.5",
|
"blitz": "3.0.1",
|
||||||
"lowdb": "3.0.0",
|
"lowdb": "3.0.0",
|
||||||
"next": "14.0.4",
|
"next": "15.0.1",
|
||||||
"prisma": "4.6.1",
|
"prisma": "6.1.0",
|
||||||
"react": "18.2.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "18.2.0"
|
"react-dom": "19.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@blitzjs/config": "2.0.5",
|
"@blitzjs/config": "3.0.1",
|
||||||
"@next/bundle-analyzer": "12.0.8",
|
"@next/bundle-analyzer": "12.0.8",
|
||||||
"@types/express": "4.17.13",
|
"@types/express": "4.17.13",
|
||||||
"@types/fs-extra": "9.0.13",
|
"@types/fs-extra": "9.0.13",
|
||||||
"@types/node-fetch": "2.6.1",
|
"@types/node-fetch": "2.6.1",
|
||||||
"@types/react": "18.0.25",
|
"@types/react": "npm:types-react@19.0.0",
|
||||||
"b64-lite": "1.4.0",
|
"b64-lite": "1.4.0",
|
||||||
"eslint": "8.27.0",
|
"eslint": "8.27.0",
|
||||||
"fs-extra": "10.0.1",
|
"fs-extra": "10.0.1",
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {getQueryData, useQuery} from "@blitzjs/rpc"
|
import {getQueryData, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import {Suspense, useState} from "react"
|
import {Suspense, useState} from "react"
|
||||||
import getBasic from "../app/queries/getBasic"
|
import getBasic from "../app/queries/getBasic"
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
const [data] = useQuery(getBasic, undefined)
|
const [data] = useSuspenseQuery(getBasic, undefined)
|
||||||
const [newData, setNewData] = useState<string>()
|
const [newData, setNewData] = useState<string>()
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import React, {Suspense} from "react"
|
import React, {Suspense} from "react"
|
||||||
import {BlitzPage} from "@blitzjs/next"
|
import {BlitzPage} from "@blitzjs/next"
|
||||||
import {invalidateQuery, useQuery} from "@blitzjs/rpc"
|
import {invalidateQuery, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import getSequence from "../app/queries/getSequence"
|
import getSequence from "../app/queries/getSequence"
|
||||||
|
|
||||||
const useQueryOptions = {
|
const useSuspenseQueryOptions = {
|
||||||
refetchInterval: 0,
|
refetchInterval: 0,
|
||||||
refetchOnMount: false,
|
refetchOnMount: false,
|
||||||
refetchOnReconnect: false,
|
refetchOnReconnect: false,
|
||||||
@@ -11,8 +11,16 @@ const useQueryOptions = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PageWithInvalidateQuery: React.FC = () => {
|
const PageWithInvalidateQuery: React.FC = () => {
|
||||||
const [query1, {isFetching: isQ1Fetching}] = useQuery(getSequence, "query1", useQueryOptions)
|
const [query1, {isFetching: isQ1Fetching}] = useSuspenseQuery(
|
||||||
const [query2, {isFetching: isQ2Fetching}] = useQuery(getSequence, "query2", useQueryOptions)
|
getSequence,
|
||||||
|
"query1",
|
||||||
|
useSuspenseQueryOptions,
|
||||||
|
)
|
||||||
|
const [query2, {isFetching: isQ2Fetching}] = useSuspenseQuery(
|
||||||
|
getSequence,
|
||||||
|
"query2",
|
||||||
|
useSuspenseQueryOptions,
|
||||||
|
)
|
||||||
|
|
||||||
const isFetching = isQ1Fetching || isQ2Fetching
|
const isFetching = isQ1Fetching || isQ2Fetching
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import {getQueryData, useQuery} from "@blitzjs/rpc"
|
import {getQueryData, useSuspenseQuery} from "@blitzjs/rpc"
|
||||||
import {Suspense, useState} from "react"
|
import {Suspense, useState} from "react"
|
||||||
import getNoSuspenseBasic from "../../no-suspense/app/queries/getNoSuspenseBasic"
|
import getNoSuspenseBasic from "../../no-suspense/app/queries/getNoSuspenseBasic"
|
||||||
|
|
||||||
function Content() {
|
function Content() {
|
||||||
const [data] = useQuery(getNoSuspenseBasic, undefined)
|
const [data] = useSuspenseQuery(getNoSuspenseBasic, undefined)
|
||||||
const [newData, setNewData] = useState<string>()
|
const [newData, setNewData] = useState<string>()
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {useInfiniteQuery} from "@blitzjs/rpc"
|
import {useSuspenseInfiniteQuery} from "@blitzjs/rpc"
|
||||||
import {gSSP} from "../app/blitz-server"
|
import {gSSP} from "../app/blitz-server"
|
||||||
import testQuery from "../app/queries/getInfiniteData"
|
import testQuery from "../app/queries/getInfiniteData"
|
||||||
|
|
||||||
@@ -12,12 +12,12 @@ export const getServerSideProps = gSSP(async ({ctx}) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const PageWithPrefetchInfQuery = () => {
|
const PageWithPrefetchInfQuery = () => {
|
||||||
const [data] = useInfiniteQuery(
|
const [data] = useSuspenseInfiniteQuery(
|
||||||
testQuery,
|
testQuery,
|
||||||
(pageParams) => ({...pageParams, name: "hello world"}),
|
(pageParams) => ({...pageParams, name: "hello world"}),
|
||||||
{
|
{
|
||||||
suspense: false,
|
|
||||||
getNextPageParam: (lastPage) => lastPage,
|
getNextPageParam: (lastPage) => lastPage,
|
||||||
|
initialPageParam: {name: "hello world"},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return <div id="data">{data ? data : "no-data"}</div>
|
return <div id="data">{data ? data : "no-data"}</div>
|
||||||
|
|||||||
@@ -51,22 +51,22 @@ const runTests = () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("prefetch infinite query", () => {
|
// describe("prefetch infinite query", () => {
|
||||||
it(
|
// it(
|
||||||
"should work",
|
// "should work",
|
||||||
async () => {
|
// async () => {
|
||||||
const browser = await webdriver(appPort, "/page-with-prefetch-inf-query")
|
// const browser = await webdriver(appPort, "/page-with-prefetch-inf-query")
|
||||||
|
|
||||||
browser.waitForElementByCss("#data", 0)
|
// browser.waitForElementByCss("#data", 0)
|
||||||
const newText = await browser.elementByCss("#data").text()
|
// const newText = await browser.elementByCss("#data").text()
|
||||||
expect(newText).not.toMatch("no-data")
|
// expect(newText).not.toMatch("no-data")
|
||||||
expect(newText).toMatch("thanks")
|
// expect(newText).toMatch("thanks")
|
||||||
|
|
||||||
if (browser) await browser.close()
|
// if (browser) await browser.close()
|
||||||
},
|
// },
|
||||||
5000 * 60 * 2,
|
// 5000 * 60 * 2,
|
||||||
)
|
// )
|
||||||
})
|
// })
|
||||||
|
|
||||||
describe("invalidate query", () => {
|
describe("invalidate query", () => {
|
||||||
it(
|
it(
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user