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

Compare commits

...

28 Commits

Author SHA1 Message Date
github-actions[bot]
0959a11fc6 Version Packages (beta) (#3930)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-11-04 15:52:57 -04:00
Siddharth Suresh
4545912936 Include resolvers in src in blitz console (#3933)
* optimse only-db flag and add src directory to find resolvers in console

* default parameter
2022-11-04 12:32:45 -04:00
Brandon Bayer
55a43ce1f8 maybe fix anon session CSRF issue + add ability to customize anon session expiry time (#3945)
* maybe fix anon session CSRF issue + add ability to customize anon session expiry time
2022-11-04 12:12:15 -04:00
Aleksandra
1569bd53e0 Upgrade tslog to latest version (#3946)
* Upgrade tslog to latest version
2022-11-04 11:59:13 -04:00
Siddharth Suresh
8e5903c0fa Fix cannot find module db error in JavaScript template (#3940)
* use AST to parse the config and allow blitz server to be in `src`
2022-11-02 09:22:49 -04:00
Brandon Bayer
11b548edee make logger optional (will default to BlitzLogger) (#3939)
* make logger optional (will default to BlitzLogger)
2022-11-01 15:28:57 -04:00
Siddharth Suresh
ceb7db274f Add GET support to RPC specification (#3891) 2022-10-29 17:10:27 -04:00
github-actions[bot]
0ebdf3bc93 Version Packages (beta) (#3929)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-28 15:27:06 +08:00
Aleksandra
1b798d9a03 Export enhancePrisma from the server entry point (#3928)
* Export enhancePrisma from the server entry point

* Changeset

* Update pnpm lock
2022-10-27 10:04:31 -04:00
Blitz.js Bot
758ccbbbe5 (meta) added @joneskj55 as contributor 2022-10-25 06:38:44 -04:00
github-actions[bot]
d73b1d76ab Version Packages (beta) (#3916)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-25 18:32:26 +08:00
Dillon Raphael
78fd5c489b Fix Blitz Install (#3909) 2022-10-24 21:50:54 -04:00
Aleksandra
60de057477 Fix reset token being undefined when passed to the resetPassword mutation (#3922) 2022-10-22 11:23:51 +08:00
Siddharth Suresh
0a8b0cb350 Custom Server TS error (#3888) 2022-10-20 14:56:40 +08:00
Aleksandra
5476139375 Remove unnecessary as number assertions from new app templates (#3915) 2022-10-19 16:25:35 +08:00
github-actions[bot]
81dd346c85 Version Packages (beta) (#3907)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-19 14:56:44 +08:00
Aleksandra
6f4349896f Fix 'ambiguous class detected' errors (#3912) 2022-10-19 13:44:33 +08:00
Aleksandra
a6e81f156b Add BlitzLogger plugin and allow customizing logging (#3886) 2022-10-18 15:50:17 +08:00
Aleksandra
4e26ae21bc Upgrade eslint-config-next in new app templates to fix linting issues on blitz build (#3910) 2022-10-18 14:54:47 +08:00
Blitz.js Bot
70ca39e059 (meta) added @janvennemann as contributor 2022-10-17 04:06:03 -04:00
Jan Vennemann
7b63f0f1f2 fix(rpc): allow return undefined in setQueryData updater function (#3898)
Co-authored-by: Dillon Raphael <dillon@creatorsneverdie.com>
Co-authored-by: Aleksandra <alexsandra.sikora@gmail.com>
2022-10-17 16:05:57 +08:00
Siddharth Suresh
2e5d7ae40c Upgrade CI Syntax (#3906) 2022-10-17 15:33:36 +08:00
github-actions[bot]
67de028732 Version Packages (beta) (#3896)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2022-10-13 14:02:17 +08:00
Siddharth Suresh
f39ba1ff13 #3748 Add custom template option back to blitz generate command (#3866) 2022-10-12 11:46:24 -04:00
Blitz.js Bot
149b999f67 (meta) added @oloost as contributor 2022-10-12 06:13:22 -04:00
Aleksandra
3a602b613b Fix missing blitz/installer dependency in recipes (#3895) 2022-10-12 18:11:12 +08:00
github-actions[bot]
58bb38f809 Version Packages (beta) (#3893)
* Version Packages (beta)

* Fix version

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: beerose <alexsandra.sikora@gmail.com>
2022-10-11 17:48:40 +08:00
Aleksandra
1476a577bb Update PULL_REQUEST_TEMPLATE.md (#3878) 2022-10-11 17:32:21 +08:00
155 changed files with 2110 additions and 1205 deletions

View File

@@ -3714,8 +3714,36 @@
"contributions": [
"doc"
]
},
{
"login": "oloost",
"name": "oloost",
"avatar_url": "https://avatars.githubusercontent.com/u/72395941?v=4",
"profile": "https://github.com/oloost",
"contributions": [
"doc"
]
},
{
"login": "janvennemann",
"name": "Jan Vennemann",
"avatar_url": "https://avatars.githubusercontent.com/u/1406024?v=4",
"profile": "https://github.com/janvennemann",
"contributions": [
"doc",
"code"
]
},
{
"login": "joneskj55",
"name": "Kevin Jones",
"avatar_url": "https://avatars.githubusercontent.com/u/20748598?v=4",
"profile": "https://kevinjones.engineer",
"contributions": [
"doc"
]
}
],
"contributorsPerLine": 7,
"skipCi": true
}
}

View File

@@ -0,0 +1,6 @@
---
"blitz": patch
"@blitzjs/generator": patch
---
Upgrade `tslog` to the latest version

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Remove unnecessary `as number` assertions from new app templates

View File

@@ -2,21 +2,10 @@
"$schema": "https://unpkg.com/@changesets/config@2.0.0/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [
[
"blitz"
],
[
"@blitzjs/*"
]
],
"fixed": [["blitz"], ["@blitzjs/*"]],
"linked": [],
"access": "restricted",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [
"web",
"test-*",
"toolkit-*"
]
"ignore": ["web", "test-*", "toolkit-*", "@blitzjs/recipe-*"]
}

View File

@@ -0,0 +1,11 @@
---
"blitz": patch
"@blitzjs/auth": patch
"@blitzjs/next": patch
"@blitzjs/rpc": patch
"@blitzjs/codemod": patch
"@blitzjs/config": patch
"@blitzjs/generator": patch
---
Fix release

View File

@@ -0,0 +1,6 @@
---
"blitz": patch
"@blitzjs/next": patch
---
Add BlitzLogger plugin and allow customizing logging

View File

@@ -0,0 +1,6 @@
---
"@blitzjs/auth": minor
"@blitzjs/rpc": minor
---
maybe fix anon session CSRF issue + add ability to customize anon session expiry time

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Fix Blitz Install issue that gets stuck on "Generating file diff"

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Fix `blitz install` not working due to missing `blitz/installer` dependency

View File

@@ -0,0 +1,7 @@
---
"blitz": patch
"@blitzjs/rpc": patch
---
Add an opt-in GET request support to RPC specification by exporting a `config` object that has the `httpMethod` property.
from `query` files.

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/rpc": patch
---
Allow the updater function in setQueryData to return undefined to match react-query typings

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/generator": patch
---
Fix reset token being undefined when passed to the resetPassword mutation

View File

@@ -0,0 +1,6 @@
---
"blitz": patch
"@blitzjs/generator": patch
---
Fix `cannot find module db error` in JavaScript template. Replace requiring the config using `esbuild` with parsing using `jscodeshift` to get the `cliConfig` values. Added logic to find the `blitz-server` file in `src` directory

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Fix "Ambiguous class detected" errors reported by SuperJson by removing duplicated export from errors.ts file

View File

@@ -0,0 +1,6 @@
---
"@blitzjs/config": patch
"@blitzjs/generator": patch
---
Upgrade eslint-config-next in new app templates to fix linting issues on blitz build

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Fix Custom Server TS error - add `es6` target config to esbuild

View File

@@ -0,0 +1,5 @@
---
"@blitzjs/next": minor
---
Change setupBlitzServer logger config to be optional. Will default to BlitzLogger

View File

@@ -48,6 +48,7 @@
},
"changesets": [
"afraid-dancers-juggle",
"afraid-ears-repair",
"big-phones-bow",
"blue-flowers-peel",
"blue-pigs-tan",
@@ -61,6 +62,7 @@
"calm-nails-wait",
"calm-tomatoes-drive",
"chilled-carrots-own",
"chilly-nails-nail",
"clean-hats-pump",
"clean-walls-wink",
"clever-radios-lie",
@@ -97,6 +99,8 @@
"fuzzy-bees-warn",
"fuzzy-jars-admire",
"gentle-dogs-reply",
"gentle-lions-explode",
"giant-mails-tap",
"gold-horses-punch",
"good-apes-drum",
"good-insects-wink",
@@ -114,20 +118,28 @@
"healthy-rice-shout",
"heavy-apes-judge",
"heavy-cobras-own",
"heavy-students-buy",
"hip-buttons-dance",
"honest-candles-yawn",
"honest-cherries-push",
"honest-comics-vanish",
"hot-cups-rhyme",
"hot-drinks-approve",
"hungry-baboons-swim",
"hungry-pens-collect",
"itchy-cups-double",
"itchy-houses-marry",
"itchy-spoons-tan",
"khaki-ducks-cheer",
"kind-walls-suffer",
"late-steaks-give",
"lazy-maps-sort",
"lemon-games-press",
"lemon-pillows-switch",
"lemon-seas-push",
"light-donkeys-double",
"light-squids-draw",
"little-pears-ring",
"long-bees-hope",
"long-dancers-jog",
"long-lobsters-drop",
@@ -135,10 +147,12 @@
"lovely-colts-share",
"lucky-cows-try",
"lucky-months-guess",
"lucky-years-turn",
"mean-gorillas-reply",
"modern-cameras-pull",
"modern-ligers-behave",
"moody-bags-walk",
"moody-spoons-rhyme",
"moody-squids-cheer",
"nasty-suns-wash",
"nervous-beds-travel",
@@ -152,6 +166,7 @@
"ninety-lies-press",
"ninety-pets-heal",
"ninety-rice-tickle",
"odd-bears-run",
"olive-bees-buy",
"olive-feet-rhyme",
"olive-kings-invent",
@@ -185,11 +200,13 @@
"shy-olives-hang",
"shy-pumpkins-try",
"silent-colts-reply",
"silent-lies-run",
"silly-apricots-share",
"silly-shoes-agree",
"six-apricots-kick",
"slimy-humans-impress",
"slimy-needles-taste",
"slow-impalas-tap",
"slow-walls-camp",
"slow-walls-poke",
"small-socks-confess",
@@ -206,6 +223,7 @@
"spotty-peas-hope",
"spotty-zoos-film",
"stale-jobs-drum",
"stale-parents-yawn",
"strong-apes-reply",
"strong-keys-lie",
"stupid-walls-sell",

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Fix `useSession` hook by exporting `enhancePrisma` from the server entry point instead of server

View File

@@ -0,0 +1,6 @@
---
"blitz": patch
"@blitzjs/generator": patch
---
Allow passing custom templates to the `blitz generate` command. Extend the `generate` command with `custom-templates` to provide an easy starting point for users to customize the default templates: `blitz generate custom-templates`.

View File

@@ -0,0 +1,5 @@
---
"blitz": patch
---
Include resolvers in `src` directory in blitz console

View File

@@ -3,6 +3,11 @@ Thanks for opening a PR! Your contribution is much appreciated.
To make sure your PR is handled as smoothly as possible please:
- Link issue via "Closes #[issue_number]
- Choose & follow the right checklist for the change that you're making:
Please make sure to add a changeset. Run `pnpm changeset` in the root directory to do so.
Then select updated Blitz packages when prompted, and add a short message describing the changes.
The message should be user-facing — explain **what** was changed, not **how**.
Ignore if there are no user-facing changes.
-->
Closes: ?
@@ -11,9 +16,11 @@ Closes: ?
## Bug Checklist
- [ ] Changeset added (run `pnpm changeset` in the root directory)
- [ ] Integration test added (see [test docs](https://blitzjs.com/docs/contributing#running-tests) if needed)
## Feature Checklist
- [ ] Changeset added (run `pnpm changeset` in the root directory)
- [ ] Integration test added (see [test docs](https://blitzjs.com/docs/contributing#running-tests) if needed)
- [ ] Documentation added/updated (submit PR to [blitzjs.com repo `canary` branch](https://github.com/blitz-js/blitzjs.com/tree/canary))
- [ ] Documentation added/updated (submit PR to [blitzjs.com repo `main` branch](https://github.com/blitz-js/blitzjs.com))

View File

@@ -10,7 +10,7 @@ concurrency:
jobs:
changeset:
if: ${{ github.event.label.name != 'no-changeset' }}
if: ${{ !contains(github.event.pull_request.labels.*.name, 'no-changeset') && github.event.pull_request.merged == false }}
runs-on: ubuntu-latest
steps:
- name: Checkout Repo

View File

@@ -129,7 +129,7 @@ jobs:
cd ./integration-tests
tree -J -d -L 1 | jq -c '.[0].contents | map(.name | tostring) | map(select(. != "utils"))'
folders=$(tree -J -d -L 1 | jq -c '.[0].contents | map(.name | tostring) | map(select(. != "utils"))')
echo "::set-output name=folders::$folders"
echo "folders=$folders" >> $GITHUB_OUTPUT
Integration-Tests:
name: "Integration Test: ${{matrix.folder}} @ ${{ matrix.os }} "

View File

@@ -6,7 +6,7 @@
<img alt="" src="https://img.shields.io/badge/Join%20our%20community-6700EB.svg?style=for-the-badge&labelColor=000000&logoWidth=20&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAQ9SURBVHgB7d3dVdtAEIbhcSpICUoH0IEogQqSVBBSAU4FSSpIOoAORAfQgSghHXzZ1U/YcMD4R9rZmf2ec3y448LyiNf27iLiGIAmPLrweC9Un3DhrzG6EarLNP09nlwJ1SOZ/lQr5N80/S/p2QMVCBf5N17XCfm1Y/rBHqjAG9PPHvBsz+mf9WAP+HLA9M/YA14cOP2payH7jpj+VCtk1wnTP+vj7xCy6cTpn7EHLMLp059iD1iD8eveJbVCNsSLheX1YA/YgOWnf8YeKB3Wmf7Ud6Fy4f/FHmtpxbl3YlC4MJ/Cj0bWdwPnPbARg+L0S54XQHS32WwuxClzd4CM0z9rPfeAuTtA5ulPXYQ7wZ04Y+oOoDD9KZc9YOoOoDj9s4dwFzgXR6w1wIPoOvPWA9buAHEJ173o3gWiy3AnuBUHLEbgmYwvAk1/wuM8vAgexThzbwPDkx7/DHwVXfFOxP2GmsKd4Ab6zPeAyU8CI7AHFmH2BRCBPXAyk18GzUrqAXCTiR4ssyj0VFw/oCU8+e+RZ33AWz6KMaYbIIWxB+JSLs1bsbkeMN0AqakHvoku9oA2sAfqBvbAQdw0QArsgb25aYBUQT3QgT2gB+yBuqGcHij2UCqXDZACe2Anlw2QYg/QAOyBuoE98CL3DZDCuK4/rh/Q7oGL6U+TOvcNkJoijN8X1C48+T+g75eQDrAH/qmqAVJgDwyqaoAUe4AGYA/UDZX3QLUNkEIZPRCd5+6BahsgVUgPROwBTSijB7jpVAvGHriHvmw9wAZ4BpX1ABvgmakHtPcbRuwBTWAPULgAV9D/jKDY9YRvwvgEaurD44uQHvAol7qBW7WKluVtIHiUS7GyvA0s6CiXDnxrpQfsgbqBS7GKk/2jYHCrVlGyfxTMrVo0ALdq1Q3sgSKofh0M9oA61a+D2QM0AHugbmAPqClmSRjK2apVVQ8UsySsoK1aHdgDesCtWnUDeyCrIpeFg1u3sylyWTi3btMA7IG6gT2wuuK3hoE9sKrit4YVslWLPaAN7IG6ocKt2zmY2h4O9sDiTG0PZw/QANy6XTewBxZj9ogYVHy025LMHhEz9cBn0We6B0yfERReBLfhx0/R1YQHPx/QBPbA0VwcEwf2wNFcHBPHHjiem3MC2QPHcXdSaJjA+KfgTPQ8hhfjBzHC40mhlzJ+Xq9lK4a4PCs43AVaGTed5mZq+iOXZwWHi3AnOj2wFWNcnxYe7gTxLtBKHuamP/J+Wnh8a5irB7ZC5Yk9gPX1QuXC+usHWqGyhYvUYR0a7zboUOFCNVhnk0krZAOW7wFOvzXhom2xnEbIHizTA1wEYhWW6YFGyC6c1gOcfg9wfA80Qj7g8B7g9HuCww+haIR8wf49wOn3Cvv9k8tGyC/s7gFOv3fY3QONkH+v9MBWqB7PeqDn9FcIT//kcitUn6kHOu/T/xfWzlQy3dEHhwAAAABJRU5ErkJggg==">
</a>
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
<a aria-label="All Contributors" href="#contributors-"><img alt="" src="https://img.shields.io/badge/all_contributors-393-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-396-17BB8A.svg?style=for-the-badge&labelColor=000000"></a>
<!-- ALL-CONTRIBUTORS-BADGE:END -->
<a aria-label="License" href="https://github.com/blitz-js/blitz/blob/main/LICENSE">
<img alt="" src="https://img.shields.io/npm/l/blitz.svg?style=for-the-badge&labelColor=000000&color=blue">
@@ -723,11 +723,14 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
<td align="center"><a href="https://chaiwattsw.com/"><img src="https://avatars.githubusercontent.com/u/30198386?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Chaiwat Trisuwan</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=chaiwattsw" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=chaiwattsw" title="Code">💻</a></td>
<td align="center"><a href="oltdaniel.eu"><img src="https://avatars.githubusercontent.com/u/53529846?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Daniel Oltmanns</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=oltdaniel" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=oltdaniel" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/edrickleong"><img src="https://avatars.githubusercontent.com/u/10529706?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Edrick Leong</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=edrickleong" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=edrickleong" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=edrickleong" title="Tests">⚠️</a></td>
<td align="center"><a href="https://github.com/siddhsuresh"><img src="https://avatars.githubusercontent.com/u/83594610?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Siddharth Suresh</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=siddhsuresh" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=siddhsuresh" title="Code">💻</a><a href="https://github.com/blitz-js/blitz/commits?author=siddhsuresh" title="Tests">⚠️</a> <a href="#maintenance-siddhsuresh" title="Maintenance">🚧</a></td>
<td align="center"><a href="https://github.com/siddhsuresh"><img src="https://avatars.githubusercontent.com/u/83594610?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Siddharth Suresh</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=siddhsuresh" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=siddhsuresh" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=siddhsuresh" title="Tests">⚠️</a> <a href="#maintenance-siddhsuresh" title="Maintenance">🚧</a></td>
<td align="center"><a href="http://jins.dev"><img src="https://avatars.githubusercontent.com/u/39466936?v=4?s=100" width="100px;" alt=""/><br /><sub><b>JH.Lee</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=orionmiz" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=orionmiz" title="Tests">⚠️</a> <a href="#maintenance-orionmiz" title="Maintenance">🚧</a> <a href="https://github.com/blitz-js/blitz/commits?author=orionmiz" title="Documentation">📖</a></td>
</tr>
<tr>
<td align="center"><a href="https://github.com/corydeppen"><img src="https://avatars.githubusercontent.com/u/313264?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Cory Deppen</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=corydeppen" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/oloost"><img src="https://avatars.githubusercontent.com/u/72395941?v=4?s=100" width="100px;" alt=""/><br /><sub><b>oloost</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=oloost" title="Documentation">📖</a></td>
<td align="center"><a href="https://github.com/janvennemann"><img src="https://avatars.githubusercontent.com/u/1406024?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Jan Vennemann</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=janvennemann" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=janvennemann" title="Code">💻</a></td>
<td align="center"><a href="https://kevinjones.engineer"><img src="https://avatars.githubusercontent.com/u/20748598?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Kevin Jones</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=joneskj55" title="Documentation">📖</a></td>
</tr>
</table>

View File

@@ -9,7 +9,7 @@ export default resolver.pipe(
resolver.zod(ChangePassword),
resolver.authorize(),
async ({ currentPassword, newPassword }, ctx) => {
const user = await db.user.findFirst({ where: { id: ctx.session.userId as number } })
const user = await db.user.findFirst({ where: { id: ctx.session.userId } })
if (!user) throw new NotFoundError()
await authenticateUser(user.email, currentPassword)

View File

@@ -2,6 +2,7 @@ import { setupBlitzServer } from "@blitzjs/next"
import { AuthServerPlugin, PrismaStorage } from "@blitzjs/auth"
import db from "db"
import { simpleRolesIsAuthorized } from "@blitzjs/auth"
import { BlitzLogger } from "blitz"
const { gSSP, gSP, api } = setupBlitzServer({
plugins: [
@@ -11,6 +12,7 @@ const { gSSP, gSP, api } = setupBlitzServer({
isAuthorized: simpleRolesIsAuthorized,
}),
],
logger: BlitzLogger({}),
})
export { gSSP, gSP, api }

View File

@@ -5,7 +5,7 @@ export default async function getCurrentUser(_ = null, { session }: Ctx) {
if (!session.userId) return null
const user = await db.user.findFirst({
where: { id: session.userId as number },
where: { id: session.userId },
select: { id: true, name: true, email: true, role: true },
})

View File

@@ -29,7 +29,7 @@
"@blitzjs/rpc": "workspace:*",
"@hookform/resolvers": "2.8.8",
"@prisma/client": "4.0.0",
"blitz": "workspace:2.0.0-beta.5",
"blitz": "workspace:2.0.0-beta.16",
"next": "12.2.5",
"openid-client": "5.1.8",
"prisma": "4.0.0",
@@ -49,7 +49,7 @@
"@types/react": "18.0.17",
"@typescript-eslint/eslint-plugin": "5.9.1",
"eslint": "7.32.0",
"eslint-config-next": "12.2.0",
"eslint-config-next": "12.3.1",
"eslint-config-prettier": "8.5.0",
"husky": "7.0.4",
"jest": "27.5.1",

View File

@@ -9,7 +9,7 @@ export default resolver.pipe(
resolver.zod(ChangePassword),
resolver.authorize(),
async ({ currentPassword, newPassword }, ctx) => {
const user = await db.user.findFirst({ where: { id: ctx.session.userId as number } })
const user = await db.user.findFirst({ where: { id: ctx.session.userId } })
if (!user) throw new NotFoundError()
await authenticateUser(user.email, currentPassword)

View File

@@ -1,7 +1,9 @@
import type { BlitzCliConfig } from "blitz"
import { setupBlitzServer } from "@blitzjs/next"
import { AuthServerPlugin, PrismaStorage } from "@blitzjs/auth"
import db from "db"
import { simpleRolesIsAuthorized } from "@blitzjs/auth"
import { BlitzLogger } from "blitz"
const { gSSP, gSP, api } = setupBlitzServer({
plugins: [
@@ -11,6 +13,11 @@ const { gSSP, gSP, api } = setupBlitzServer({
isAuthorized: simpleRolesIsAuthorized,
}),
],
logger: BlitzLogger({}),
})
export { gSSP, gSP, api }
export const cliConfig: BlitzCliConfig = {
customTemplates: "app/templates",
}

View File

@@ -5,9 +5,13 @@ export default async function getCurrentUser(_ = null, { session }: Ctx) {
if (!session.userId) return null
const user = await db.user.findFirst({
where: { id: session.userId as number },
where: { id: session.userId },
select: { id: true, name: true, email: true, role: true },
})
return user
}
export const config = {
httpMethod: "GET",
}

View File

@@ -29,7 +29,7 @@
"@blitzjs/rpc": "workspace:*",
"@hookform/resolvers": "2.8.8",
"@prisma/client": "4.0.0",
"blitz": "workspace:2.0.0-beta.5",
"blitz": "workspace:2.0.0-beta.16",
"next": "12.2.5",
"prisma": "4.0.0",
"react": "18.2.0",
@@ -48,7 +48,7 @@
"@types/react": "18.0.17",
"@typescript-eslint/eslint-plugin": "5.9.1",
"eslint": "7.32.0",
"eslint-config-next": "12.2.0",
"eslint-config-next": "12.3.1",
"eslint-config-prettier": "8.5.0",
"husky": "7.0.4",
"jest": "27.5.1",

View File

@@ -1,3 +1,4 @@
import { useEffect, useState } from "react"
import Layout from "app/core/layouts/Layout"
import { LabeledTextField } from "app/core/components/LabeledTextField"
import { Form, FORM_ERROR } from "app/core/components/Form"
@@ -9,9 +10,14 @@ import { useMutation } from "@blitzjs/rpc"
import Link from "next/link"
const ResetPasswordPage: BlitzPage = () => {
const [token, setToken] = useState("")
const router = useRouter()
const [resetPasswordMutation, { isSuccess }] = useMutation(resetPassword)
useEffect(() => {
setToken(router.query.token as string)
}, [router.isReady])
return (
<div>
<h1>Set a New Password</h1>
@@ -30,11 +36,11 @@ const ResetPasswordPage: BlitzPage = () => {
initialValues={{
password: "",
passwordConfirmation: "",
token: router.query.token as string,
token,
}}
onSubmit={async (values) => {
try {
await resetPasswordMutation(values)
await resetPasswordMutation({ ...values, token })
} catch (error: any) {
if (error.name === "ResetPasswordError") {
return {

View File

@@ -7,6 +7,7 @@ import logout from "app/auth/mutations/logout"
import logo from "public/logo.png"
import { useMutation } from "@blitzjs/rpc"
import { Routes, BlitzPage } from "@blitzjs/next"
import { getSession, useSession } from "@blitzjs/auth"
/*
* This file is just for a pleasant getting started page for your new app.
@@ -271,6 +272,4 @@ const Home: BlitzPage = () => {
)
}
Home.authenticate = true
export default Home

View File

@@ -1,7 +1,8 @@
import {setupBlitzServer} from "@blitzjs/next"
import {AuthServerPlugin, PrismaStorage} from "@blitzjs/auth"
import db from "db"
import {simpleRolesIsAuthorized} from "@blitzjs/auth"
import {BlitzLogger} from "blitz"
import db from "db"
const {gSSP, gSP, api} = setupBlitzServer({
plugins: [
@@ -11,6 +12,10 @@ const {gSSP, gSP, api} = setupBlitzServer({
isAuthorized: simpleRolesIsAuthorized,
}),
],
logger: BlitzLogger({
colorizePrettyLogs: true,
prefix: ["[blitz]>>>>>"],
}),
})
export {gSSP, gSP, api}

View File

@@ -2,6 +2,7 @@ import {setupBlitzServer} from "@blitzjs/next"
import {AuthServerPlugin, PrismaStorage} from "@blitzjs/auth"
import {simpleRolesIsAuthorized} from "@blitzjs/auth"
import db from "../db/index"
import {BlitzLogger} from "blitz"
const {gSSP, gSP, api} = setupBlitzServer({
plugins: [
@@ -11,6 +12,7 @@ const {gSSP, gSP, api} = setupBlitzServer({
isAuthorized: simpleRolesIsAuthorized,
}),
],
logger: BlitzLogger({}),
})
export {gSSP, gSP, api}

View File

@@ -21,7 +21,7 @@
"@blitzjs/config": "workspace:*",
"@blitzjs/next": "workspace:*",
"@prisma/client": "4.0.0",
"blitz": "workspace:2.0.0-beta.5",
"blitz": "workspace:2.0.0-beta.16",
"lowdb": "3.0.0",
"next": "12.2.5",
"prisma": "4.0.0",

View File

@@ -2,6 +2,7 @@ import {setupBlitzServer} from "@blitzjs/next"
import {AuthServerPlugin, PrismaStorage} from "@blitzjs/auth"
import {simpleRolesIsAuthorized} from "@blitzjs/auth"
import db from "../db"
import {BlitzLogger} from "blitz"
const {gSSP, gSP, api} = setupBlitzServer({
plugins: [
@@ -11,6 +12,7 @@ const {gSSP, gSP, api} = setupBlitzServer({
isAuthorized: simpleRolesIsAuthorized,
}),
],
logger: BlitzLogger({}),
})
export {gSSP, gSP, api}

View File

@@ -1,7 +1,9 @@
import {setupBlitzServer} from "@blitzjs/next"
import {BlitzLogger} from "blitz"
const {gSSP, gSP, api} = setupBlitzServer({
plugins: [],
logger: BlitzLogger({}),
})
export {gSSP, gSP, api}

View File

@@ -2,6 +2,7 @@ import {setupBlitzServer} from "@blitzjs/next"
import {AuthServerPlugin, PrismaStorage} from "@blitzjs/auth"
import {simpleRolesIsAuthorized} from "@blitzjs/auth"
import db from "../db/index"
import {BlitzLogger} from "blitz"
const {gSSP, gSP, api} = setupBlitzServer({
plugins: [
@@ -11,6 +12,7 @@ const {gSSP, gSP, api} = setupBlitzServer({
isAuthorized: simpleRolesIsAuthorized,
}),
],
logger: BlitzLogger({}),
})
export {gSSP, gSP, api}

View File

@@ -2,6 +2,7 @@ import {setupBlitzServer} from "@blitzjs/next"
import {AuthServerPlugin, PrismaStorage} from "@blitzjs/auth"
import {simpleRolesIsAuthorized} from "@blitzjs/auth"
import db from "../db"
import {BlitzLogger} from "blitz"
const {gSSP, gSP, api} = setupBlitzServer({
plugins: [
@@ -11,6 +12,7 @@ const {gSSP, gSP, api} = setupBlitzServer({
isAuthorized: simpleRolesIsAuthorized,
}),
],
logger: BlitzLogger({}),
})
export {gSSP, gSP, api}

View File

@@ -0,0 +1,16 @@
if (typeof window !== "undefined") {
throw new Error("This should not be loaded on the client")
}
export default async function getBasicWithGET() {
if (typeof window !== "undefined") {
throw new Error("This should not be loaded on the client")
}
global.basic ??= "basic-result"
return global.basic
}
export const config = {
httpMethod: "GET",
}

View File

@@ -9,13 +9,10 @@ import {
nextBuild,
nextStart,
nextExport,
getPageFileFromBuildManifest,
getPageFileFromPagesManifest,
} from "../../utils/next-test-utils"
// jest.setTimeout(1000 * 60 * 2)
const appDir = join(__dirname, "../")
const nextConfig = join(appDir, "next.config.js")
let appPort
let mode
let app
@@ -33,17 +30,6 @@ function runTests(dev = false) {
5000 * 60 * 2,
)
it(
"returns 404 for GET",
async () => {
const res = await fetchViaHTTP(appPort, "/api/rpc/getBasic", null, {
method: "GET",
})
expect(res.status).toEqual(404)
},
5000 * 60 * 2,
)
it(
"requires params",
async () => {
@@ -58,6 +44,71 @@ function runTests(dev = false) {
5000 * 60 * 2,
)
it(
"GET - returns 200 only when enabled",
async () => {
const res = await fetchViaHTTP(
appPort,
"/api/rpc/getBasicWithGET?params=%7B%7D&meta=%7B%7D",
null,
{
method: "GET",
},
)
expect(res.status).toEqual(200)
},
5000 * 60 * 2,
)
it(
"GET - returns 404 otherwise",
async () => {
const res = await fetchViaHTTP(
appPort,
"/api/rpc/getBasic?params=%7B%7D&meta=%7B%7D",
null,
{
method: "GET",
},
)
expect(res.status).toEqual(404)
},
5000 * 60 * 2,
)
it(
"query works - GET",
async () => {
const res = await fetchViaHTTP(
appPort,
"/api/rpc/getBasicWithGET?params=%7B%7D&meta=%7B%7D",
null,
{
method: "GET",
},
)
const json = await res.json()
expect(json).toEqual({result: "basic-result", error: null, meta: {}})
expect(res.status).toEqual(200)
},
5000 * 60 * 2,
)
it(
"requires params - GET",
async () => {
const res = await fetchViaHTTP(appPort, "/api/rpc/getBasicWithGET", null, {
method: "GET",
})
const json = await res.json()
expect(res.status).toEqual(400)
expect(json.error.message).toBe(
"Request query is missing the required `params` and `meta` keys",
)
},
5000 * 60 * 2,
)
it(
"query works",
async () => {

View File

@@ -2,6 +2,7 @@ import {setupBlitzServer} from "@blitzjs/next"
import {AuthServerPlugin, PrismaStorage} from "@blitzjs/auth"
import {simpleRolesIsAuthorized} from "@blitzjs/auth"
import db from "../db"
import {BlitzLogger} from "blitz"
const {gSSP, gSP, api} = setupBlitzServer({
plugins: [
@@ -11,6 +12,7 @@ const {gSSP, gSP, api} = setupBlitzServer({
isAuthorized: simpleRolesIsAuthorized,
}),
],
logger: BlitzLogger({}),
})
export {gSSP, gSP, api}

View File

@@ -1,5 +1,58 @@
# @blitzjs/auth
## 2.0.0-beta.16
### Minor Changes
- 55a43ce1: maybe fix anon session CSRF issue + add ability to customize anon session expiry time
### Patch Changes
- Updated dependencies [1569bd53]
- Updated dependencies [ceb7db27]
- Updated dependencies [8e5903c0]
- Updated dependencies [45459129]
- blitz@2.0.0-beta.16
## 2.0.0-beta.15
### Patch Changes
- Updated dependencies [1b798d9a]
- blitz@2.0.0-beta.15
## 2.0.0-beta.14
### Patch Changes
- Updated dependencies [78fd5c48]
- Updated dependencies [0a8b0cb3]
- blitz@2.0.0-beta.14
## 2.0.0-beta.13
### Patch Changes
- Updated dependencies [a6e81f15]
- Updated dependencies [6f434989]
- blitz@2.0.0-beta.13
## 2.0.0-beta.12
### Patch Changes
- Updated dependencies [3a602b61]
- Updated dependencies [f39ba1ff]
- blitz@2.0.0-beta.12
## 2.0.0-beta.11
### Patch Changes
- 1476a577: Fix release
- Updated dependencies [1476a577]
- blitz@2.0.0-beta.11
## 2.0.0-beta.10
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/auth",
"version": "2.0.0-beta.10",
"version": "2.0.0-beta.16",
"scripts": {
"build": "unbuild",
"predev": "wait-on -d 250 ../blitz/dist/index-server.d.ts",
@@ -26,7 +26,7 @@
"@types/secure-password": "3.1.1",
"b64-lite": "1.4.0",
"bad-behavior": "1.0.1",
"blitz": "2.0.0-beta.5",
"blitz": "2.0.0-beta.16",
"cookie": "0.4.1",
"cookie-session": "2.0.0",
"debug": "4.3.3",
@@ -40,7 +40,7 @@
"url": "0.11.0"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.10",
"@blitzjs/config": "workspace:2.0.0-beta.16",
"@testing-library/react": "13.0.0",
"@testing-library/react-hooks": "7.0.2",
"@types/cookie": "0.4.1",

View File

@@ -116,10 +116,17 @@ export const getPublicDataStore = (): PublicDataStore => {
return (window as any).__publicDataStore
}
export const getAntiCSRFToken = () => {
// because safari automatically deletes non-httponly cookies after 7 days
export const backupAntiCSRFTokenToLocalStorage = () => {
const cookieValue = readCookie(COOKIE_CSRF_TOKEN())
if (cookieValue) {
localStorage.setItem(LOCALSTORAGE_CSRF_TOKEN(), cookieValue)
}
}
export const getAntiCSRFToken = () => {
const cookieValue = readCookie(COOKIE_CSRF_TOKEN())
if (cookieValue) {
return cookieValue
} else {
return localStorage.getItem(LOCALSTORAGE_CSRF_TOKEN())

View File

@@ -1,7 +1,8 @@
import {SessionConfig} from "./shared/types"
import {AuthPluginOptions} from "./server"
import {SessionConfigMethods} from "./shared"
declare global {
var sessionConfig: SessionConfig
var sessionConfig: AuthPluginOptions & SessionConfigMethods
var __BLITZ_SESSION_COOKIE_PREFIX: string | undefined
var __BLITZ_SUSPENSE_ENABLED: boolean
}

View File

@@ -7,6 +7,7 @@ import {getSession} from "./auth-sessions"
interface SessionConfigOptions {
cookiePrefix?: string
sessionExpiryMinutes?: number
anonSessionExpiryMinutes?: number
method?: "essential" | "advanced"
sameSite?: "none" | "lax" | "strict"
secureCookies?: boolean
@@ -69,13 +70,14 @@ export const PrismaStorage = <Client extends PrismaClientWithSession>(
const defaultConfig_: SessionConfigOptions = {
sessionExpiryMinutes: 30 * 24 * 60, // Sessions expire after 30 days of being idle
anonSessionExpiryMinutes: 5 * 365 * 24 * 60, // Sessions expire after 5 years of being idle
method: "essential",
sameSite: "lax",
publicDataKeysToSyncAcrossSessions: ["role", "roles"],
secureCookies: !process.env.DISABLE_SECURE_COOKIES && process.env.NODE_ENV === "production",
}
interface AuthPluginOptions extends Partial<SessionConfigOptions>, IsAuthorized {
export interface AuthPluginOptions extends Partial<SessionConfigOptions>, IsAuthorized {
storage: SessionConfigMethods
}

View File

@@ -690,7 +690,10 @@ async function createNewSession(
const anonymousSessionToken = createAnonymousSessionToken(payload)
const publicDataToken = createPublicDataToken(args.publicData)
const expiresAt = addYears(new Date(), 30)
const expiresAt = addMinutes(
new Date(),
global.sessionConfig.anonSessionExpiryMinutes as number,
)
setAnonymousSessionCookie(req, res, anonymousSessionToken, expiresAt)
setCSRFCookie(req, res, antiCSRFToken, expiresAt)
setPublicDataCookie(req, res, publicDataToken, expiresAt)

View File

@@ -50,17 +50,6 @@ export interface SessionConfigMethods {
deleteSession: (handle: string) => Promise<SessionModel | undefined>
}
export interface SessionConfig extends SessionConfigMethods {
cookiePrefix?: string
sessionExpiryMinutes?: number
method?: "essential" | "advanced"
sameSite?: "none" | "lax" | "strict"
secureCookies?: boolean
domain?: string
publicDataKeysToSyncAcrossSessions?: string[]
isAuthorized: (data: {ctx: BlitzCtx; args: any}) => boolean
}
export interface SessionContextBase {
$handle: string | null
$publicData: unknown

View File

@@ -1,5 +1,51 @@
# @blitzjs/next
## 2.0.0-beta.16
### Minor Changes
- 11b548ed: Change setupBlitzServer logger config to be optional. Will default to BlitzLogger
### Patch Changes
- Updated dependencies [55a43ce1]
- Updated dependencies [ceb7db27]
- @blitzjs/rpc@2.0.0-beta.16
## 2.0.0-beta.15
### Patch Changes
- @blitzjs/rpc@2.0.0-beta.15
## 2.0.0-beta.14
### Patch Changes
- @blitzjs/rpc@2.0.0-beta.14
## 2.0.0-beta.13
### Patch Changes
- a6e81f15: Add BlitzLogger plugin and allow customizing logging
- Updated dependencies [7b63f0f1]
- @blitzjs/rpc@2.0.0-beta.13
## 2.0.0-beta.12
### Patch Changes
- @blitzjs/rpc@2.0.0-beta.12
## 2.0.0-beta.11
### Patch Changes
- 1476a577: Fix release
- Updated dependencies [1476a577]
- @blitzjs/rpc@2.0.0-beta.11
## 2.0.0-beta.10
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/next",
"version": "2.0.0-beta.10",
"version": "2.0.0-beta.16",
"scripts": {
"build": "unbuild",
"dev": "pnpm predev && pnpm watch unbuild src --wait=0.2",
@@ -24,7 +24,7 @@
"eslint.js"
],
"dependencies": {
"@blitzjs/rpc": "2.0.0-beta.10",
"@blitzjs/rpc": "2.0.0-beta.16",
"@tanstack/react-query": "4.0.10",
"@types/hoist-non-react-statics": "3.3.1",
"debug": "4.3.3",
@@ -34,7 +34,7 @@
"supports-color": "8.1.1"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.10",
"@blitzjs/config": "workspace:2.0.0-beta.16",
"@testing-library/dom": "8.13.0",
"@testing-library/jest-dom": "5.16.3",
"@testing-library/react": "13.0.0",
@@ -44,7 +44,7 @@
"@types/react": "18.0.17",
"@types/react-dom": "17.0.14",
"@types/testing-library__react-hooks": "4.0.0",
"blitz": "2.0.0-beta.5",
"blitz": "2.0.0-beta.16",
"cross-spawn": "7.0.3",
"find-up": "4.1.0",
"next": "12.2.5",

View File

@@ -7,7 +7,7 @@ import type {
NextApiRequest,
NextApiResponse,
} from "next"
import type {
import {
AddParameters,
AsyncFunc,
BlitzServerPlugin,
@@ -15,6 +15,8 @@ import type {
FirstParam,
RequestMiddleware,
MiddlewareResponse,
BlitzLogger,
initializeLogger,
} from "blitz"
import {handleRequestWithMiddleware, startWatcher, stopWatcher} from "blitz"
import {
@@ -50,6 +52,7 @@ export type NextApiHandler<TResult> = (
type SetupBlitzOptions = {
plugins: BlitzServerPlugin<RequestMiddleware, Ctx>[]
onError?: (err: Error) => void
logger?: ReturnType<typeof BlitzLogger>
}
export type Redirect =
@@ -127,7 +130,9 @@ const prefetchQueryFactory = (
}
}
export const setupBlitzServer = ({plugins, onError}: SetupBlitzOptions) => {
export const setupBlitzServer = ({plugins, onError, logger}: SetupBlitzOptions) => {
initializeLogger(logger ?? BlitzLogger())
const middlewares = plugins.flatMap((p) => p.requestMiddlewares)
const contextMiddleware = plugins.flatMap((p) => p.contextMiddleware).filter(Boolean)

View File

@@ -1,5 +1,51 @@
# @blitzjs/rpc
## 2.0.0-beta.16
### Minor Changes
- 55a43ce1: maybe fix anon session CSRF issue + add ability to customize anon session expiry time
### Patch Changes
- ceb7db27: Add an opt-in GET request support to RPC specification by exporting a `config` object that has the `httpMethod` property.
from `query` files.
- Updated dependencies [55a43ce1]
- @blitzjs/auth@2.0.0-beta.16
## 2.0.0-beta.15
### Patch Changes
- @blitzjs/auth@2.0.0-beta.15
## 2.0.0-beta.14
### Patch Changes
- @blitzjs/auth@2.0.0-beta.14
## 2.0.0-beta.13
### Patch Changes
- 7b63f0f1: Allow the updater function in setQueryData to return undefined to match react-query typings
- @blitzjs/auth@2.0.0-beta.13
## 2.0.0-beta.12
### Patch Changes
- @blitzjs/auth@2.0.0-beta.12
## 2.0.0-beta.11
### Patch Changes
- 1476a577: Fix release
- Updated dependencies [1476a577]
- @blitzjs/auth@2.0.0-beta.11
## 2.0.0-beta.10
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/rpc",
"version": "2.0.0-beta.10",
"version": "2.0.0-beta.16",
"scripts": {
"build": "unbuild",
"predev": "wait-on -d 400 ../blitz/dist/index-server.d.ts && wait-on -d 400 ../blitz-auth/dist/index-browser.d.ts",
@@ -20,7 +20,8 @@
"dist/**"
],
"dependencies": {
"@blitzjs/auth": "2.0.0-beta.10",
"@blitzjs/auth": "2.0.0-beta.16",
"@swc/core": "1.3.7",
"@tanstack/react-query": "4.0.10",
"b64-lite": "1.4.0",
"bad-behavior": "1.0.1",
@@ -30,11 +31,11 @@
"supports-color": "8.1.1"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.10",
"@blitzjs/config": "workspace:2.0.0-beta.16",
"@types/debug": "4.1.7",
"@types/react": "18.0.17",
"@types/react-dom": "17.0.14",
"blitz": "2.0.0-beta.5",
"blitz": "2.0.0-beta.16",
"next": "12.2.5",
"react": "18.2.0",
"react-dom": "18.2.0",

View File

@@ -186,7 +186,7 @@ export const invalidateQuery: InvalidateQueryType = (resolver, ...params: []) =>
export function setQueryData<TInput, TResult, T extends AsyncFunc>(
resolver: T | Resolver<TInput, TResult> | RpcClient<TInput, TResult>,
params: TInput,
newData: TResult | ((oldData: TResult | undefined) => TResult),
newData: TResult | ((oldData: TResult | undefined) => TResult | undefined),
opts: MutateOptions = {refetch: true},
): Promise<void | ReturnType<ReturnType<typeof getQueryClient>["invalidateQueries"]>> {
if (typeof resolver === "undefined") {

View File

@@ -4,9 +4,11 @@ import {deserialize, serialize} from "superjson"
import {SuperJSONResult} from "superjson/dist/types"
import {CSRFTokenMismatchError, isServer} from "blitz"
import {getQueryKeyFromUrlAndParams, getQueryClient} from "./react-query-utils"
import {stringify} from "superjson"
import {
getAntiCSRFToken,
getPublicDataStore,
backupAntiCSRFTokenToLocalStorage,
HEADER_CSRF,
HEADER_CSRF_ERROR,
HEADER_PUBLIC_DATA_TOKEN,
@@ -23,6 +25,7 @@ export interface BuildRpcClientParams {
resolverName: string
resolverType: ResolverType
routePath: string
httpMethod: string
}
export interface RpcOptions {
@@ -54,9 +57,10 @@ export function __internal_buildRpcClient({
resolverName,
resolverType,
routePath,
httpMethod,
}: BuildRpcClientParams): RpcClient {
const fullRoutePath = normalizeApiRoute("/api/rpc" + routePath)
const routePathURL = new URL(fullRoutePath, window.location.origin)
const httpClient: RpcClientBase = async (params, opts = {}, signal = undefined) => {
const debug = (await import("debug")).default("blitz:rpc")
if (!opts.fromQueryHook && !opts.fromInvoke) {
@@ -93,23 +97,32 @@ export function __internal_buildRpcClient({
serialized = serialize(params)
}
if (httpMethod === "GET") {
routePathURL.searchParams.set("params", stringify(serialized.json))
routePathURL.searchParams.set("meta", stringify(serialized.meta))
}
const promise = window
.fetch(fullRoutePath, {
method: "POST",
.fetch(routePathURL, {
method: httpMethod,
headers,
credentials: "include",
redirect: "follow",
body: JSON.stringify({
params: serialized.json,
meta: {
params: serialized.meta,
},
}),
body:
httpMethod === "POST"
? JSON.stringify({
params: serialized.json,
meta: {
params: serialized.meta,
},
})
: undefined,
signal,
})
.then(async (response) => {
debug("Received request for", routePath)
if (response.headers) {
backupAntiCSRFTokenToLocalStorage()
if (response.headers.get(HEADER_PUBLIC_DATA_TOKEN)) {
getPublicDataStore().updateState()
debug("Public data updated")

View File

@@ -1,6 +1,6 @@
import {assert, baseLogger, Ctx, newLine, prettyMs} from "blitz"
import {assert, baseLogger, Ctx, newLine, prettyMs, ResolverConfig} from "blitz"
import {NextApiRequest, NextApiResponse} from "next"
import {deserialize, serialize as superjsonSerialize} from "superjson"
import {deserialize, serialize as superjsonSerialize, parse} from "superjson"
import {resolve} from "path"
import chalk from "chalk"
@@ -14,6 +14,10 @@ function isObject(value: unknown): value is Record<string | symbol, unknown> {
return typeof value === "object" && value !== null
}
const defaultConfig: ResolverConfig = {
httpMethod: "POST",
}
function getGlobalObject<T extends Record<string, unknown>>(key: string, defaultValue: T): T {
assert(key.startsWith("__internal_blitz"), "unsupported key")
if (typeof global === "undefined") {
@@ -25,7 +29,7 @@ function getGlobalObject<T extends Record<string, unknown>>(key: string, default
}
type Resolver = (...args: unknown[]) => Promise<unknown>
type ResolverFiles = Record<string, () => Promise<{default?: Resolver}>>
type ResolverFiles = Record<string, () => Promise<{default?: Resolver; config?: ResolverConfig}>>
export type ResolverPathOptions = "queries|mutations" | "root" | ((path: string) => string)
// We define `global.__internal_blitzRpcResolverFiles` to ensure we use the same global object.
@@ -43,7 +47,7 @@ export function loadBlitzRpcResolverFilesWithInternalMechanism() {
export function __internal_addBlitzRpcResolver(
routePath: string,
resolver: () => Promise<{default?: Resolver}>,
resolver: () => Promise<{default?: Resolver; config?: ResolverConfig}>,
) {
g.blitzRpcResolverFilesLoaded = g.blitzRpcResolverFilesLoaded || {}
g.blitzRpcResolverFilesLoaded[routePath] = resolver
@@ -169,19 +173,33 @@ export function rpcHandler(config: RpcConfig) {
throw new Error("No resolver for path: " + routePath)
}
const resolver = (await loadableResolver()).default
const {default: resolver, config: resolverConfig} = await loadableResolver()
if (!resolver) {
throw new Error("No default export for resolver path: " + routePath)
}
const resolverConfigWithDefaults = {...defaultConfig, ...resolverConfig}
if (req.method === "HEAD") {
// We used to initiate database connection here
res.status(200).end()
return
} else if (req.method === "POST") {
// Handle RPC call
if (typeof req.body.params === "undefined") {
} else if (
req.method === "POST" ||
(req.method === "GET" && resolverConfigWithDefaults.httpMethod === "GET")
) {
if (req.method === "GET") {
if (Object.keys(req.query).length === 1 && req.query.blitz) {
const error = {message: "Request query is missing the required `params` and `meta` keys"}
log.error(error.message)
res.status(400).json({
result: null,
error,
})
return
}
} else if (typeof req.body.params === "undefined") {
const error = {message: "Request body is missing the `params` key"}
log.error(error.message)
res.status(400).json({
@@ -193,10 +211,9 @@ export function rpcHandler(config: RpcConfig) {
try {
const data = deserialize({
json: req.body.params,
meta: req.body.meta?.params,
json: req.method === "POST" ? req.body.params : parse(`${req.query.params}`),
meta: req.method === "POST" ? req.body.meta?.params : parse(`${req.query.meta}`),
})
log.info(customChalk.dim("Starting with input:"), data ? data : JSON.stringify(data))
const startTime = Date.now()
const result = await resolver(data, (res as any).blitzCtx)

View File

@@ -8,6 +8,8 @@ import {
toPosixPath,
} from "./loader-utils"
import {posix} from "path"
import {log, ResolverConfig} from "blitz"
import {getResolverConfig} from "./parse-rpc-config"
// Subset of `import type { LoaderDefinitionFunction } from 'webpack'`
@@ -39,12 +41,24 @@ export async function transformBlitzRpcResolverClient(
) {
assertPosixPath(id)
assertPosixPath(root)
const resolverFilePath = "/" + posix.relative(root, id)
assertPosixPath(resolverFilePath)
const routePath = convertPageFilePathToRoutePath(resolverFilePath, options?.resolverPath)
const resolverName = convertFilePathToResolverName(resolverFilePath)
const resolverType = convertFilePathToResolverType(resolverFilePath)
const resolverConfig: ResolverConfig = {
httpMethod: "POST",
}
if (resolverType === "query") {
try {
const {httpMethod} = getResolverConfig(_src)
if (httpMethod) {
resolverConfig.httpMethod = httpMethod
}
} catch (e) {
log.error(e as string)
}
}
const code = `
// @ts-nocheck
@@ -53,6 +67,7 @@ export async function transformBlitzRpcResolverClient(
resolverName: "${resolverName}",
resolverType: "${resolverType}",
routePath: "${routePath}",
httpMethod: "${resolverConfig.httpMethod}",
});
`

View File

@@ -1,4 +1,4 @@
import {dirname, join, posix, relative} from "path"
import {dirname, join, relative} from "path"
import {promises} from "fs"
import {
assertPosixPath,
@@ -52,18 +52,15 @@ export async function transformBlitzRpcServer(
assertPosixPath(root)
const blitzImport = 'import { __internal_addBlitzRpcResolver } from "@blitzjs/rpc";'
// No break line between `blitzImport` and `src` in order to preserve the source map's line mapping
let code = blitzImport + src
code += "\n\n"
for (let resolverFilePath of resolvers) {
const relativeResolverPath = slash(relative(dirname(id), join(root, resolverFilePath)))
const routePath = convertPageFilePathToRoutePath(resolverFilePath, options?.resolverPath)
code += `__internal_addBlitzRpcResolver('${routePath}', () => import('${relativeResolverPath}'));`
code += `__internal_addBlitzRpcResolver('${routePath}',() => import('${relativeResolverPath}'));`
code += "\n"
}
// console.log("NEW CODE", code)
return code
}

View File

@@ -0,0 +1,57 @@
import {parseSync} from "@swc/core"
import {ResolverConfig} from "blitz"
type _ResolverType = "GET" | "POST"
const defaultResolverConfig: ResolverConfig = {
httpMethod: "POST",
}
export function getResolverConfig(content: string): ResolverConfig {
const resolverConfig = defaultResolverConfig
const resolver = parseSync(content, {
syntax: "typescript",
target: "es2020",
})
const exportDelaration = resolver.body.find((node) => {
if (node.type === "ExportDeclaration") {
if (node.declaration.type === "VariableDeclaration") {
if (node.declaration.declarations[0]?.id.type === "Identifier") {
if (node.declaration.declarations[0].id.value === "config") {
return true
}
}
}
}
return false
})
if (exportDelaration && exportDelaration.type == "ExportDeclaration") {
const declaration = exportDelaration.declaration
if (declaration && declaration.type == "VariableDeclaration") {
const declarator = declaration.declarations[0]
if (declarator && declarator.type == "VariableDeclarator") {
const variable = declarator.init
if (variable && variable.type == "ObjectExpression") {
const properties = variable.properties
if (properties) {
const httpMethodProperty = properties.find((property) => {
if (property.type == "KeyValueProperty") {
if (property.key.type == "Identifier") {
return property.key.value == "httpMethod"
}
}
return false
})
if (httpMethodProperty && httpMethodProperty.type == "KeyValueProperty") {
const value = httpMethodProperty.value
if (value && value.type == "StringLiteral") {
resolverConfig.httpMethod = value.value as _ResolverType
}
}
}
}
}
}
}
return resolverConfig
}

View File

@@ -1,5 +1,61 @@
# blitz
## 2.0.0-beta.16
### Patch Changes
- 1569bd53: Upgrade `tslog` to the latest version
- ceb7db27: Add an opt-in GET request support to RPC specification by exporting a `config` object that has the `httpMethod` property.
from `query` files.
- 8e5903c0: Fix `cannot find module db error` in JavaScript template. Replace requiring the config using `esbuild` with parsing using `jscodeshift` to get the `cliConfig` values. Added logic to find the `blitz-server` file in `src` directory
- 45459129: Include resolvers in `src` directory in blitz console
- Updated dependencies [1569bd53]
- Updated dependencies [8e5903c0]
- @blitzjs/generator@2.0.0-beta.16
## 2.0.0-beta.15
### Patch Changes
- 1b798d9a: Fix `useSession` hook by exporting `enhancePrisma` from the server entry point instead of server
- @blitzjs/generator@2.0.0-beta.15
## 2.0.0-beta.14
### Patch Changes
- 78fd5c48: Fix Blitz Install issue that gets stuck on "Generating file diff"
- 0a8b0cb3: Fix Custom Server TS error - add `es6` target config to esbuild
- Updated dependencies [54761393]
- Updated dependencies [60de0574]
- @blitzjs/generator@2.0.0-beta.14
## 2.0.0-beta.13
### Patch Changes
- a6e81f15: Add BlitzLogger plugin and allow customizing logging
- 6f434989: Fix "Ambiguous class detected" errors reported by SuperJson by removing duplicated export from errors.ts file
- Updated dependencies [4e26ae21]
- @blitzjs/generator@2.0.0-beta.13
## 2.0.0-beta.12
### Patch Changes
- 3a602b61: Fix `blitz install` not working due to missing `blitz/installer` dependency
- f39ba1ff: Allow passing custom templates to the `blitz generate` command. Extend the `generate` command with `custom-templates` to provide an easy starting point for users to customize the default templates: `blitz generate custom-templates`.
- Updated dependencies [f39ba1ff]
- @blitzjs/generator@2.0.0-beta.12
## 2.0.0-beta.11
### Patch Changes
- 1476a577: Fix release
- Updated dependencies [1476a577]
- @blitzjs/generator@2.0.0-beta.11
## 2.0.0-beta.5
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "blitz",
"version": "2.0.0-beta.5",
"version": "2.0.0-beta.16",
"scripts": {
"build": "unbuild",
"dev": "pnpm run predev && watch unbuild src --wait=0.2",
@@ -17,6 +17,7 @@
"sideEffects": false,
"license": "MIT",
"files": [
"installer.*",
"dist/**",
"bin/**"
],
@@ -24,7 +25,7 @@
"blitz": "bin/blitz"
},
"dependencies": {
"@blitzjs/generator": "2.0.0-beta.10",
"@blitzjs/generator": "2.0.0-beta.16",
"@mrleebo/prisma-ast": "0.2.6",
"@types/global-agent": "2.1.1",
"arg": "5.0.1",
@@ -62,16 +63,17 @@
"recast": "0.20.5",
"resolve-cwd": "3.0.0",
"resolve-from": "5.0.0",
"rimraf": "3.0.2",
"superjson": "1.9.1",
"supports-color": "8.1.1",
"tar": "6.1.11",
"ts-node": "10.7.0",
"tsconfig-paths": "4.0.0",
"tslog": "3.3.1",
"tslog": "3.3.4",
"watchpack": "2.1.1"
},
"devDependencies": {
"@blitzjs/config": "workspace:2.0.0-beta.10",
"@blitzjs/config": "workspace:2.0.0-beta.16",
"@types/cookie": "0.4.1",
"@types/cross-spawn": "6.0.2",
"@types/debug": "4.1.7",

View File

@@ -15,7 +15,9 @@ import {
MutationsGenerator,
ModelGenerator,
QueryGenerator,
customTemplatesBlitzConfig,
} from "@blitzjs/generator"
import {log} from "../../logging"
const getIsTypeScript = async () =>
require("fs").existsSync(require("path").join(process.cwd(), "tsconfig.json"))
@@ -30,6 +32,7 @@ enum ResourceType {
Mutations = "mutations",
Mutation = "mutation",
Resource = "resource",
CustomTemplates = "custom-templates",
}
function modelName(input: string = "") {
@@ -45,6 +48,39 @@ function ModelNames(input: string = "") {
return pluralPascal(input)
}
const createCustomTemplates = async () => {
const continuePrompt = await prompts({
type: "confirm",
name: "value",
message: `This will copy the default templates to your app/templates folder. Do you want to continue?`,
})
if (!continuePrompt.value) {
process.exit(0)
}
const templatesPath = await prompts({
type: "text",
name: "value",
message: `Enter the path to save the custom templates folder`,
initial: "app/templates",
})
const templatesPathValue: string = templatesPath.value
const isTypeScript = await getIsTypeScript()
await customTemplatesBlitzConfig(isTypeScript, templatesPathValue, true) // to run the codemod
log.success(`🚀 Custom templates path added/updated in app/blitz-server file`)
const customTemplatesPath = require("path").join(process.cwd(), templatesPathValue)
const fsExtra = await import("fs-extra")
const blitzGeneratorPath = require.resolve("@blitzjs/generator")
const templateFolder = ["form", "page", "query", "mutation", "queries", "mutations"]
for (const template of templateFolder) {
await fsExtra.copy(
require("path").join(blitzGeneratorPath, "..", "templates", template),
require("path").join(customTemplatesPath, template),
)
}
log.success(`🚀 Custom templates created in ${templatesPathValue} directory`)
process.exit(0)
}
const generatorMap = {
[ResourceType.All]: [
PageGenerator,
@@ -61,6 +97,7 @@ const generatorMap = {
[ResourceType.Mutations]: [MutationsGenerator],
[ResourceType.Mutation]: [MutationGenerator],
[ResourceType.Resource]: [QueriesGenerator, MutationsGenerator, ModelGenerator],
[ResourceType.CustomTemplates]: [],
}
const args = arg(
@@ -199,6 +236,13 @@ const getHelp = async () => {
> blitz generate all tasks --parent=projects
# To customize the templates used by the blitz generate command,
> blitz generate custom-templates
This command will copy the default templates to your app and update the app/blitz-server file to enable
the custom templating feature of the blitz CLI
# Database models can also be generated directly from the CLI.
Model fields can be specified with any generator that generates a database model ("all", "model", "resource").
Both of the commands below will generate the proper database model for a Task.
@@ -216,6 +260,9 @@ const getHelp = async () => {
const generate: CliCommand = async () => {
await getHelp()
await determineType()
if (selectedType === "custom-templates") {
await createCustomTemplates()
}
if (!selectedModelName) {
await determineName()
}
@@ -227,9 +274,13 @@ const generate: CliCommand = async () => {
const generators = generatorMap[selectedType as keyof typeof generatorMap]
const isTypeScript = await getIsTypeScript()
const cliConfig = await customTemplatesBlitzConfig(isTypeScript)
for (const GeneratorClass of generators) {
const generator = new GeneratorClass({
destinationRoot: require("path").resolve(),
templateDir: cliConfig,
extraArgs: args["_"].slice(3) as string[],
modelName: singularRootContext,
modelNames: modelNames(singularRootContext),

View File

@@ -4,11 +4,14 @@ import prompts from "prompts"
import {bootstrap} from "global-agent"
import {baseLogger, log} from "../../logging"
const debug = require("debug")("blitz:cli")
import {join, resolve} from "path"
import {join, resolve, dirname} from "path"
import {Stream} from "stream"
import {promisify} from "util"
import {RecipeCLIFlags, RecipeExecutor} from "../../installer"
import {setupTsnode} from "../utils/setup-ts-node"
import {isInternalBlitzMonorepoDevelopment} from "../utils/helpers"
import findUp from "find-up"
import resolveFrom from "resolve-from"
interface GlobalAgent {
HTTP_PROXY?: string
@@ -62,8 +65,9 @@ const requireJSON = (file: string) => {
return JSON.parse(require("fs-extra").readFileSync(file).toString("utf-8"))
}
const checkLockFileExists = (filename: string) => {
return require("fs-extra").existsSync(resolve(filename))
const checkLockFileExists = async (filename: string) => {
const dotBlitz = join(await findNodeModulesRoot(process.cwd()), ".blitz")
return require("fs-extra").existsSync(resolve(join(dotBlitz, "..", "..", filename)))
}
const GH_ROOT = "https://github.com/"
@@ -153,13 +157,39 @@ const normalizeRecipePath = (recipeArg: string): RecipeMeta => {
}
}
async function findNodeModulesRoot(src: string) {
let root: string
if (isInternalBlitzMonorepoDevelopment) {
root = join(__dirname, "..", "..", "..", "..", "/node_modules")
} else {
const blitzPkgLocation = dirname(
(await findUp("package.json", {
cwd: resolveFrom(src, "blitz"),
})) ?? "",
)
if (!blitzPkgLocation) {
throw new Error("Internal Blitz Error: unable to find 'blitz' package location")
}
if (blitzPkgLocation.includes(".pnpm")) {
root = join(blitzPkgLocation, "../../../../")
} else {
root = join(blitzPkgLocation, "../")
}
}
return root
}
const cloneRepo = async (
repoFullName: string,
defaultBranch: string,
subdirectory?: string,
): Promise<string> => {
debug("[cloneRepo] starting...")
const recipeDir = join(process.cwd(), ".blitz", "recipe-install")
const dotBlitz = join(await findNodeModulesRoot(process.cwd()), ".blitz")
const recipeDir = join(dotBlitz, "..", "..", "recipe-install")
// clean up from previous run in case of error
require("rimraf").sync(recipeDir)
require("fs-extra").mkdirsSync(recipeDir)
@@ -206,7 +236,6 @@ const setupProxySupport = async () => {
const install: CliCommand = async () => {
setupTsnode()
let selectedRecipe: string | null = args._[1] ? `${args._[1]}` : null
await setupProxySupport()
@@ -281,10 +310,10 @@ ${chalk.dim("- Available recipes listed at https://github.com/blitz-js/blitz/tre
let pkgManager = "npm"
let installArgs = ["install", "--legacy-peer-deps", "--ignore-scripts"]
if (checkLockFileExists("yarn.lock")) {
if (await checkLockFileExists("yarn.lock")) {
pkgManager = "yarn"
installArgs = ["install", "--ignore-scripts"]
} else if (checkLockFileExists("pnpm-lock.yaml")) {
} else if (await checkLockFileExists("pnpm-lock.yaml")) {
pkgManager = "pnpm"
installArgs = ["install", "--ignore-scripts"]
}
@@ -297,7 +326,7 @@ ${chalk.dim("- Available recipes listed at https://github.com/blitz-js/blitz/tre
const recipePackageMain = requireJSON("./package.json").main
const recipeEntry = resolve(recipePackageMain)
process.chdir(process.cwd())
process.chdir(join(process.cwd(), ".."))
await installRecipeAtPath(recipeEntry, cliArgs, cliFlags)

View File

@@ -4,6 +4,7 @@ import os from "os"
import path from "path"
import * as REPL from "repl"
import {REPLCommand, REPLServer} from "repl"
// eslint-disable-next-line @next/next/no-assign-module-variable
const debug = require("debug")("blitz:repl")
import ProgressBar from "progress"
import {log} from "../../logging"
@@ -58,6 +59,7 @@ export const forceRequire = (modulePath: string) => {
})
if (isTypeScript) {
// eslint-disable-next-line @next/next/no-assign-module-variable
const module = require(modulePath)
unregister()
return module
@@ -69,32 +71,30 @@ export const forceRequire = (modulePath: string) => {
}
}
export async function getBlitzModulePaths() {
export async function getBlitzModulePaths(onlyDb = false) {
const projectRoot = getProjectRootSync()
const {globby} = await import("globby")
const paths = await globby(
[
"app/**/{queries,mutations}/**/*.{js,ts,tsx}",
"utils/*.{js,ts,tsx}",
"jobs/**/*.{js,ts,tsx}",
"integrations/**/*.{js,ts,tsx}",
"!**/*.test.*",
"!**/*.spec.*",
],
{cwd: projectRoot, gitignore: true},
)
paths.push(getDbFolder())
debug("Paths", paths)
const paths = [getDbFolder()]
if (!onlyDb) {
const {globby} = await import("globby")
paths.push(
...(await globby(
[
"{app,src}/**/{queries,mutations}/**/*.{js,ts,tsx}",
"utils/*.{js,ts,tsx}",
"jobs/**/*.{js,ts,tsx}",
"integrations/**/*.{js,ts,tsx}",
"!**/*.test.*",
"!**/*.spec.*",
],
{cwd: projectRoot, gitignore: true},
)),
)
}
return [...paths.map((p: string) => path.join(projectRoot, p))]
}
export const loadBlitz = async (onlyDb: boolean, module = "") => {
let paths = await getBlitzModulePaths()
if (onlyDb) {
paths = paths.filter((p) => p.includes(getDbFolder()))
}
let paths = await getBlitzModulePaths(onlyDb)
if (module) {
paths = paths.filter((p) => module.includes(p) || p.includes(module))
@@ -115,6 +115,7 @@ export const loadBlitz = async (onlyDb: boolean, module = "") => {
try {
debug("Loading", modulePath)
// eslint-disable-next-line @next/next/no-assign-module-variable
const module = forceRequire(modulePath)
const contextObj = module.default || module
// debug("ContextObj", contextObj)
@@ -172,7 +173,7 @@ const setupSelfRolledHistory = (repl: any, path: string) => {
const history = fs.readFileSync(path, {encoding: "utf8"})
const nonEmptyLines = history.split(os.EOL).filter((line) => line.trim())
repl.history.push(...nonEmptyLines.reverse())
} catch (err: any) {
} catch (err) {
if (err.code !== "ENOENT") {
throw err
}

View File

@@ -55,6 +55,7 @@ const getEsbuildOptions = (): esbuild.BuildOptions => {
entryPoints: [getCustomServerPath()],
outfile: getCustomServerBuildPath(),
format: "cjs",
target: "es6",
bundle: true,
platform: "node",
external: [

View File

@@ -1,7 +1,22 @@
import "./global"
import {ComponentType} from "react"
import {IncomingMessage, ServerResponse} from "http"
import {AuthenticationError, AuthorizationError, NotFoundError, RedirectError} from "./errors"
import {
AuthenticationError,
AuthorizationError,
CSRFTokenMismatchError,
NotFoundError,
PaginationArgumentError,
RedirectError,
} from "./errors"
export {
AuthenticationError,
AuthorizationError,
CSRFTokenMismatchError,
NotFoundError,
PaginationArgumentError,
RedirectError,
}
export type BlitzProviderComponentType = <TProps = any>(
component: ComponentType<TProps>,
@@ -80,6 +95,4 @@ if (typeof window !== "undefined" && process.env.NODE_ENV === "development") {
export * from "./utils"
export * from "./types"
export * from "./errors"
export * from "./utils/zod"
export * from "./utils/prisma"

View File

@@ -5,9 +5,11 @@ import {Ctx} from "./types"
export * from "./index-browser"
export * from "./types"
export * from "./utils/run-prisma"
export * from "./utils/enhance-prisma"
export * from "./middleware"
export * from "./paginate"
export {baseLogger, newLine, log} from "./logging"
export * from "./logging"
export {startWatcher, stopWatcher} from "./cli/utils/routes-manifest"
export interface MiddlewareResponse<C extends Ctx = Ctx> extends ServerResponse {

View File

@@ -1,47 +1,29 @@
import {ISettingsParam, Logger} from "tslog"
import {ISettingsParam, Logger, TLogLevelName} from "tslog"
import c from "chalk"
import {Table} from "console-table-printer"
import ora from "ora"
import readline from "readline"
export type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal"
export type BlitzLoggerSettings = ISettingsParam
export type BlitzLogLevel = TLogLevelName
declare module globalThis {
declare namespace globalThis {
let _blitz_baseLogger: Logger
let _blitz_logLevel: LogLevel
let _blitz_logLevel: BlitzLogLevel
}
export const newLine = () => {
const logLevel: LogLevel = globalThis._blitz_logLevel
switch (logLevel) {
case "trace":
case "debug":
case "info":
console.log(" ")
break
case "warn":
case "error":
case "fatal":
default:
//nothing
break
}
}
export const baseLogger = (options?: ISettingsParam): Logger => {
export const baseLogger = (options: BlitzLoggerSettings = {}): Logger => {
if (globalThis._blitz_baseLogger) return globalThis._blitz_baseLogger
let config
try {
config = {} as any // todo: loadConfigAtRuntime()
} catch {
config = {}
}
globalThis._blitz_baseLogger = BlitzLogger(options)
globalThis._blitz_baseLogger = new Logger({
minLevel: config?.log?.level || "info",
type: config?.log?.type || "pretty",
return globalThis._blitz_baseLogger
}
export const BlitzLogger = (settings: BlitzLoggerSettings = {}) => {
const baseLogger = new Logger({
minLevel: "info",
type: "pretty",
dateTimePattern:
process.env.NODE_ENV === "production"
? "year-month-day hour:minute:second.millisecond"
@@ -61,10 +43,14 @@ export const baseLogger = (options?: ISettingsParam): Logger => {
},
maskValuesOfKeys: ["password", "passwordConfirmation"],
exposeErrorCodeFrame: process.env.NODE_ENV !== "production",
...options,
...settings,
})
return globalThis._blitz_baseLogger
return baseLogger
}
export const initializeLogger = (logger: Logger) => {
globalThis._blitz_baseLogger = logger
}
export const table = Table
@@ -76,6 +62,24 @@ const blitzBrightBrandColor = "8a3df0"
// Using bright brand color so it's better for dark terminals
const brandColor = blitzBrightBrandColor
export const newLine = () => {
const logLevel: BlitzLogLevel = globalThis._blitz_logLevel
switch (logLevel) {
case "trace":
case "debug":
case "info":
console.log(" ")
break
case "warn":
case "error":
case "fatal":
default:
//nothing
break
}
}
const withBrand = (str: string) => {
return c.hex(brandColor).bold(str)
}

View File

@@ -56,61 +56,6 @@ export async function handleRequestWithMiddleware<
}
}
// export type InvokeWithMiddlewareConfig = {
// req: IncomingMessage
// res: ServerResponse
// middleware?: Middleware[]
// [prop: string]: any
// }
// export async function invokeWithMiddleware<
// T extends AsyncFunc,
// TInput = FirstParam<T>,
// TResult = PromiseReturnType<T>
// >(
// resolver: T,
// params: TInput,
// ctx: InvokeWithMiddlewareConfig
// ): Promise<TResult> {
// if (!ctx.req) {
// throw new Error(
// 'You must provide `req` in third argument of invokeWithMiddleware()'
// )
// }
// if (!ctx.res) {
// throw new Error(
// 'You must provide `res` in third argument of invokeWithMiddleware()'
// )
// }
// const rpcResolver = (resolver as unknown) as any // todo: as RpcResolver
// const resolverName =
// rpcResolver._resolverName ?? (rpcResolver as any).default?._resolverName
// try {
// // todo
// // const log = baseLogger().getChildLogger({
// // prefix: [resolverName + '()'],
// // })
// console.log("\n")
// console.info(chalk.dim('Starting with input:'), params)
// const startTime = Date.now()
// const result = await interopDefault(rpcResolver)(params, res.blitzCtx)
// const duration = Date.now() - startTime
// console.info(chalk.dim(`Finished in ${prettyMs(duration)}`))
// console.log("/n")
// res.blitzResult = result // todo: remove?
// } catch (error) {
// throw error
// }
// return (ctx.res as MiddlewareResponse).blitzResult as TResult
// }
/**
* If the middleware function doesn't declare receiving the `next` callback
* assume that it's synchronous and invoke `next` ourselves

View File

@@ -6,6 +6,14 @@ export interface RouteUrlObject extends Pick<UrlObject, "pathname" | "query"> {
pathname: string
}
export type ResolverConfig = {
httpMethod: "GET" | "POST"
}
export type BlitzCliConfig = {
customTemplates?: string
}
export const isRouteUrlObject = (x: any): x is RouteUrlObject => {
return typeof x === "object" && "pathname" in x && typeof x.pathname === "string"
}

View File

@@ -1,5 +1,63 @@
# @blitzjs/codemod
## 2.0.0-beta.16
### Patch Changes
- Updated dependencies [1569bd53]
- Updated dependencies [ceb7db27]
- Updated dependencies [8e5903c0]
- Updated dependencies [45459129]
- blitz@2.0.0-beta.16
- @blitzjs/generator@2.0.0-beta.16
## 2.0.0-beta.15
### Patch Changes
- Updated dependencies [1b798d9a]
- blitz@2.0.0-beta.15
- @blitzjs/generator@2.0.0-beta.15
## 2.0.0-beta.14
### Patch Changes
- Updated dependencies [54761393]
- Updated dependencies [78fd5c48]
- Updated dependencies [60de0574]
- Updated dependencies [0a8b0cb3]
- @blitzjs/generator@2.0.0-beta.14
- blitz@2.0.0-beta.14
## 2.0.0-beta.13
### Patch Changes
- Updated dependencies [a6e81f15]
- Updated dependencies [6f434989]
- Updated dependencies [4e26ae21]
- blitz@2.0.0-beta.13
- @blitzjs/generator@2.0.0-beta.13
## 2.0.0-beta.12
### Patch Changes
- Updated dependencies [3a602b61]
- Updated dependencies [f39ba1ff]
- blitz@2.0.0-beta.12
- @blitzjs/generator@2.0.0-beta.12
## 2.0.0-beta.11
### Patch Changes
- 1476a577: Fix release
- Updated dependencies [1476a577]
- blitz@2.0.0-beta.11
- @blitzjs/generator@2.0.0-beta.11
## 2.0.0-beta.10
### Patch Changes

View File

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

View File

@@ -1,5 +1,25 @@
# @blitzjs/config
## 2.0.0-beta.16
## 2.0.0-beta.15
## 2.0.0-beta.14
## 2.0.0-beta.13
### Patch Changes
- 4e26ae21: Upgrade eslint-config-next in new app templates to fix linting issues on blitz build
## 2.0.0-beta.12
## 2.0.0-beta.11
### Patch Changes
- 1476a577: Fix release
## 2.0.0-beta.10
## 2.0.0-beta.4

View File

@@ -1,12 +1,12 @@
{
"name": "@blitzjs/config",
"private": true,
"version": "2.0.0-beta.10",
"version": "2.0.0-beta.16",
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "5.9.1",
"@typescript-eslint/parser": "5.9.1",
"eslint-config-next": "12.2.0",
"eslint-config-next": "12.3.1",
"eslint-config-prettier": "8.5.0"
},
"devDependencies": {

View File

@@ -1,5 +1,39 @@
# @blitzjs/generator
## 2.0.0-beta.16
### Patch Changes
- 1569bd53: Upgrade `tslog` to the latest version
- 8e5903c0: Fix `cannot find module db error` in JavaScript template. Replace requiring the config using `esbuild` with parsing using `jscodeshift` to get the `cliConfig` values. Added logic to find the `blitz-server` file in `src` directory
## 2.0.0-beta.15
## 2.0.0-beta.14
### Patch Changes
- 54761393: Remove unnecessary `as number` assertions from new app templates
- 60de0574: Fix reset token being undefined when passed to the resetPassword mutation
## 2.0.0-beta.13
### Patch Changes
- 4e26ae21: Upgrade eslint-config-next in new app templates to fix linting issues on blitz build
## 2.0.0-beta.12
### Patch Changes
- f39ba1ff: Allow passing custom templates to the `blitz generate` command. Extend the `generate` command with `custom-templates` to provide an easy starting point for users to customize the default templates: `blitz generate custom-templates`.
## 2.0.0-beta.11
### Patch Changes
- 1476a577: Fix release
## 2.0.0-beta.10
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@blitzjs/generator",
"version": "2.0.0-beta.10",
"version": "2.0.0-beta.16",
"scripts": {
"dev": "watch unbuild src --wait=0.2",
"build": "unbuild && pnpm build:templates",
@@ -31,6 +31,7 @@
"diff": "5.0.0",
"enquirer": "2.3.6",
"fs-extra": "10.0.1",
"globby": "13.1.2",
"got": "^11.8.1",
"jscodeshift": "0.13.0",
"mem-fs": "1.2.0",
@@ -41,12 +42,12 @@
"prettier": "^2.5.1",
"recast": "0.20.5",
"supports-color": "8.1.1",
"tslog": "3.3.1",
"tslog": "3.3.4",
"username": "5.1.0",
"vinyl": "2.2.1"
},
"devDependencies": {
"@blitzjs/config": "2.0.0-beta.10",
"@blitzjs/config": "2.0.0-beta.16",
"@juanm04/cpx": "2.0.1",
"@types/babel__core": "7.1.19",
"@types/diff": "5.0.2",

View File

@@ -16,6 +16,112 @@ import {readdirRecursive} from "./utils/readdir-recursive"
import prettier from "prettier"
const debug = require("debug")("blitz:generator")
export function getProjectRootSync() {
return path.dirname(getConfigSrcPath())
}
export function getConfigSrcPath() {
const jsPath = path.resolve(path.join(process.cwd(), "next.config.js"))
return jsPath
}
export const customTemplatesBlitzConfig = async (
isTypeScript: boolean,
customTemplatesPath = "",
codemod = false,
) => {
const {globby} = await import("globby")
const blitzServer = await globby(["{app,src}/**/blitz-server.{ts,js}"], {
cwd: getProjectRootSync(),
})
if (blitzServer.length === 0) {
throw new Error("Could not find blitz-server.js or blitz-server.ts in app or src folder")
}
if (blitzServer.length > 1) {
throw new Error("Found more than one blitz-server.js or blitz-server.ts in app or src folder")
}
const blitzServerPath = require("path").join(process.cwd(), blitzServer.at(0))
const userConfigModuleSource = fs.readFileSync(blitzServerPath, {encoding: "utf-8"})
const userConfigModule = j(userConfigModuleSource, {parser: customTsParser})
const program = userConfigModule.get()
const cliConfigDeclaration = userConfigModule
.find(j.ExportNamedDeclaration, {
declaration: {
type: "VariableDeclaration",
declarations: [
{
id: {
name: "cliConfig",
},
},
],
},
})
.paths()
.at(0)
if (!cliConfigDeclaration) {
const config = j.identifier("cliConfig")
const configVariable = j.variableDeclaration("const", [
j.variableDeclarator(
config,
j.objectExpression([
j.objectProperty(j.identifier("customTemplates"), j.literal(customTemplatesPath)),
]),
),
])
if (isTypeScript) {
const type = j.tsTypeAnnotation(j.tsTypeReference(j.identifier("BlitzCliConfig")))
const declaration: any = configVariable?.declarations
declaration[0].id.typeAnnotation = type
const typeImport = j.importDeclaration(
[j.importSpecifier(j.identifier("BlitzCliConfig"))],
j.literal("blitz"),
)
typeImport.importKind = "type"
program.node.program.body.unshift(typeImport)
}
const exportConfig = j.exportNamedDeclaration(configVariable)
program.node.program.body.push(exportConfig)
} else {
const configType = cliConfigDeclaration.value.declaration?.type
if (configType === "VariableDeclaration") {
const config = cliConfigDeclaration.value.declaration.declarations[0]
if (config?.type === "VariableDeclarator") {
const configProperties = config.init
if (configProperties?.type === "ObjectExpression") {
const customTemplatesProperty = configProperties.properties.find((property) => {
if (property.type === "ObjectProperty") {
const key = property.key
if (key.type === "Identifier") {
return key.name === "customTemplates"
}
}
})
if (!customTemplatesProperty) {
configProperties.properties.push(
j.objectProperty(j.identifier("customTemplates"), j.literal(customTemplatesPath)),
)
} else {
if (customTemplatesProperty.type === "ObjectProperty") {
const customValue = customTemplatesProperty.value
if (customValue.type === "StringLiteral") {
if (!codemod) {
return customValue.value
}
customValue.value = customTemplatesPath
}
}
}
}
}
}
}
if (codemod) {
const newSource = userConfigModule.toSource()
fs.writeFileSync(blitzServerPath, newSource)
}
}
export const customTsParser = {
parse(source: string, options?: Overrides) {
const babelOptions = getBabelOptions(options)

View File

@@ -1,22 +1,22 @@
import { NotFoundError, AuthenticationError } from "blitz"
import { resolver } from "@blitzjs/rpc"
import { SecurePassword } from "@blitzjs/auth"
import db from "db"
import { authenticateUser } from "./login"
import { ChangePassword } from "../validations"
import { NotFoundError, AuthenticationError } from 'blitz'
import { resolver } from '@blitzjs/rpc'
import { SecurePassword } from '@blitzjs/auth'
import db from 'db'
import { authenticateUser } from './login'
import { ChangePassword } from '../validations'
export default resolver.pipe(
resolver.zod(ChangePassword),
resolver.authorize(),
async ({ currentPassword, newPassword }, ctx) => {
const user = await db.user.findFirst({ where: { id: ctx.session.userId as number } })
const user = await db.user.findFirst({ where: { id: ctx.session.userId } })
if (!user) throw new NotFoundError()
try {
try {
await authenticateUser(user.email, currentPassword)
} catch (error: any) {
} catch (error) {
if (error instanceof AuthenticationError) {
throw new Error("Invalid Password")
throw new Error('Invalid Password')
}
throw error
}
@@ -28,5 +28,5 @@ export default resolver.pipe(
})
return true
}
},
)

View File

@@ -1,16 +1,17 @@
import { setupBlitzServer } from "@blitzjs/next"
import { AuthServerPlugin, PrismaStorage } from "@blitzjs/auth"
import { simpleRolesIsAuthorized } from "@blitzjs/auth"
import db from "db"
import { authConfig } from "./blitz-client"
import { setupBlitzServer } from '@blitzjs/next';
import { AuthServerPlugin, PrismaStorage } from '@blitzjs/auth';
import { simpleRolesIsAuthorized } from '@blitzjs/auth';
import { BlitzLogger } from 'blitz';
import db from 'db';
import { authConfig } from './blitz-client';
export const { gSSP, gSP, api } = setupBlitzServer({
plugins: [
AuthServerPlugin({
...authConfig,
storage: PrismaStorage(db),
isAuthorized: simpleRolesIsAuthorized,
}),
],
})
plugins: [
AuthServerPlugin({
...authConfig,
storage: PrismaStorage(db),
isAuthorized: simpleRolesIsAuthorized
})
],
logger: BlitzLogger({})
});

View File

@@ -1,11 +1,11 @@
import { Ctx } from "blitz"
import db from "db"
import { Ctx } from 'blitz'
import db from 'db'
export default async function getCurrentUser(_ = null, { session }: Ctx) {
if (!session.userId) return null
const user = await db.user.findFirst({
where: { id: session.userId as number },
where: { id: session.userId },
select: { id: true, name: true, email: true, role: true },
})

View File

@@ -37,13 +37,13 @@
"@next/bundle-analyzer": "12.0.8",
"@testing-library/jest-dom": "5.16.3",
"@testing-library/react": "13.4.0",
"@testing-library/react-hooks": "8.0.1",
"@testing-library/react-hooks": "8.0.1",
"@types/jest": "27.4.1",
"@types/node": "17.0.16",
"@types/preview-email": "2.0.1",
"@types/react": "18.0.17",
"@types/react": "18.0.17",
"eslint": "7.32.0",
"eslint-config-next": "12.2.0",
"eslint-config-next": "12.3.1",
"eslint-config-prettier": "8.5.0",
"husky": "7.0.4",
"jest": "27.5.1",

View File

@@ -37,14 +37,14 @@
"@next/bundle-analyzer": "12.0.8",
"@testing-library/jest-dom": "5.16.3",
"@testing-library/react": "13.4.0",
"@testing-library/react-hooks": "8.0.1",
"@testing-library/react-hooks": "8.0.1",
"@types/jest": "27.4.1",
"@types/node": "17.0.16",
"@types/preview-email": "2.0.1",
"@types/react": "18.0.17",
"@types/react": "18.0.17",
"@typescript-eslint/eslint-plugin": "5.30.5",
"eslint": "7.32.0",
"eslint-config-next": "12.2.0",
"eslint-config-next": "12.3.1",
"eslint-config-prettier": "8.5.0",
"husky": "7.0.4",
"jest": "27.5.1",

View File

@@ -1,3 +1,4 @@
import { useEffect, useState } from "react"
import Layout from "app/core/layouts/Layout"
import { LabeledTextField } from "app/core/components/LabeledTextField"
import { Form, FORM_ERROR } from "app/core/components/Form"
@@ -9,9 +10,14 @@ import { useMutation } from "@blitzjs/rpc"
import Link from "next/link"
const ResetPasswordPage: BlitzPage = () => {
const [token, setToken] = useState("")
const router = useRouter()
const [resetPasswordMutation, { isSuccess }] = useMutation(resetPassword)
useEffect(() => {
setToken(router.query.token as string)
}, [router.isReady])
return (
<div>
<h1>Set a New Password</h1>
@@ -27,10 +33,14 @@ const ResetPasswordPage: BlitzPage = () => {
<Form
submitText="Reset Password"
schema={ResetPassword}
initialValues={{ password: "", passwordConfirmation: "", token: router.query.token as string }}
initialValues={{
password: "",
passwordConfirmation: "",
token,
}}
onSubmit={async (values) => {
try {
await resetPasswordMutation(values)
await resetPasswordMutation({...values, token})
} catch (error: any) {
if (error.name === "ResetPasswordError") {
return {

View File

@@ -30,9 +30,9 @@
"@testing-library/jest-dom": "5.16.3",
"@types/jest": "27.4.1",
"@types/node": "17.0.16",
"@types/react": "18.0.17",
"@types/react": "18.0.17",
"eslint": "7.32.0",
"eslint-config-next": "12.2.0",
"eslint-config-next": "12.3.1",
"eslint-config-prettier": "8.5.0",
"husky": "7.0.4",
"jest": "27.5.1",

View File

@@ -15,9 +15,7 @@
"printWidth": 100
},
"lint-staged": {
"*.{js,ts,tsx}": [
"eslint --fix"
]
"*.{js,ts,tsx}": ["eslint --fix"]
},
"dependencies": {
"@blitzjs/next": "latest",
@@ -32,11 +30,11 @@
"@testing-library/jest-dom": "5.16.3",
"@types/jest": "27.4.1",
"@types/node": "17.0.16",
"@types/react": "18.0.17",
"@types/react": "18.0.17",
"@typescript-eslint/eslint-plugin": "5.30.5",
"eslint": "7.32.0",
"eslint-config-prettier": "8.5.0",
"eslint-config-next": "12.2.0",
"eslint-config-next": "12.3.1",
"husky": "7.0.4",
"jest": "27.5.1",
"lint-staged": "12.1.7",

View File

@@ -25,7 +25,7 @@
"@typescript-eslint/parser": "5.9.1"
},
"devDependencies": {
"@blitzjs/config": "2.0.0-beta.10",
"@blitzjs/config": "2.0.0-beta.16",
"@types/react": "18.0.17",
"@types/react-dom": "17.0.14",
"react": "18.2.0",

922
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,12 @@
# @blitzjs/recipe-base-web
## 2.0.0-beta.11
### Patch Changes
- Updated dependencies [1476a577]
- blitz@2.0.0-beta.11
## 2.0.0-beta.10
### Patch Changes

View File

@@ -12,9 +12,11 @@ export default RecipeBuilder()
stepName: "Add dependencies",
explanation: `Add 'baseui' and Styletron as a dependency too -- it's a toolkit for CSS in JS styling which Base Web relies on.`,
packages: [
{name: "baseui", version: "10.x"},
{name: "styletron-engine-atomic", version: "1.x"},
{name: "styletron-react", version: "6.x"},
{name: "baseui", version: "^10.5.0"},
{name: "styletron-engine-atomic", version: "^1.4.8"},
{name: "styletron-react", version: "^6.0.2"},
{name: "@types/styletron-engine-atomic", version: "^1.1.1"},
{name: "@types/styletron-react", version: "^5.0.3"},
],
})
.addNewFilesStep({
@@ -54,43 +56,40 @@ export default RecipeBuilder()
addImport(program, themeAndBaseProviderImport)
program
.find(j.JSXElement)
.filter(
(path) =>
path.parent?.parent?.parent?.value?.id?.name === "App" &&
path.parent?.value.type === j.ReturnStatement.toString(),
)
.find(j.FunctionDeclaration, (node) => node.id.name === "MyApp")
.forEach((path) => {
const {node} = path
path.replace(
j.jsxElement(
j.jsxOpeningElement(j.jsxIdentifier("StyletronProvider"), [
j.jsxAttribute(
j.jsxIdentifier("value"),
j.jsxExpressionContainer(j.identifier("styletron")),
),
j.jsxAttribute(
j.jsxIdentifier("debug"),
j.jsxExpressionContainer(j.identifier("debug")),
),
j.jsxAttribute(j.jsxIdentifier("debugAfterHydration")),
]),
j.jsxClosingElement(j.jsxIdentifier("StyletronProvider")),
[
j.literal("\n"),
j.jsxElement(
j.jsxOpeningElement(j.jsxIdentifier("BaseProvider"), [
j.jsxAttribute(
j.jsxIdentifier("theme"),
j.jsxExpressionContainer(j.identifier("LightTheme")),
),
]),
j.jsxClosingElement(j.jsxIdentifier("BaseProvider")),
[j.literal("\n"), node, j.literal("\n")],
),
j.literal("\n"),
],
),
const statement = path.value.body.body.filter(
(b) => b.type === "ReturnStatement",
)[0] as j.ReturnStatement
const argument = statement?.argument as j.JSXElement
statement.argument = j.jsxElement(
j.jsxOpeningElement(j.jsxIdentifier("StyletronProvider"), [
j.jsxAttribute(
j.jsxIdentifier("value"),
j.jsxExpressionContainer(j.identifier("styletron")),
),
j.jsxAttribute(
j.jsxIdentifier("debug"),
j.jsxExpressionContainer(j.identifier("debug")),
),
j.jsxAttribute(j.jsxIdentifier("debugAfterHydration")),
]),
j.jsxClosingElement(j.jsxIdentifier("StyletronProvider")),
[
j.literal("\n"),
j.jsxElement(
j.jsxOpeningElement(j.jsxIdentifier("BaseProvider"), [
j.jsxAttribute(
j.jsxIdentifier("theme"),
j.jsxExpressionContainer(j.identifier("LightTheme")),
),
]),
j.jsxClosingElement(j.jsxIdentifier("BaseProvider")),
[j.literal("\n"), argument, j.literal("\n")],
),
j.literal("\n"),
],
)
})
@@ -109,7 +108,7 @@ export default RecipeBuilder()
)
const styletronServerAndSheetImport = j.importDeclaration(
[j.importSpecifier(j.identifier("Sheet"))],
[j.importSpecifier(j.identifier("Server")), j.importSpecifier(j.identifier("Sheet"))],
j.literal("styletron-engine-atomic"),
)
@@ -122,16 +121,18 @@ export default RecipeBuilder()
addImport(program, styletronServerAndSheetImport)
addImport(program, styletronImport)
program.find(j.ImportDeclaration, {source: {value: "blitz"}}).forEach((blitzImportPath) => {
let specifiers = blitzImportPath.value.specifiers || []
if (
!specifiers
.filter((spec) => j.ImportSpecifier.check(spec))
.some((node) => (node as j.ImportSpecifier)?.imported?.name === "DocumentContext")
) {
specifiers.push(j.importSpecifier(j.identifier("DocumentContext")))
}
})
program
.find(j.ImportDeclaration, {source: {value: "next/document"}})
.forEach((nextDocumentImportPath) => {
let specifiers = nextDocumentImportPath.value.specifiers || []
if (
!specifiers
.filter((spec) => j.ImportSpecifier.check(spec))
.some((node) => (node as j.ImportSpecifier)?.imported?.name === "DocumentContext")
) {
specifiers.push(j.importSpecifier(j.identifier("DocumentContext")))
}
})
program.find(j.ClassDeclaration).forEach((path) => {
const props = j.typeAlias(
@@ -233,7 +234,15 @@ export default RecipeBuilder()
j.logicalExpression(
"||",
j.callExpression(
j.memberExpression(j.identifier("styletron"), j.identifier("getStylesheets")),
j.memberExpression(
j.parenthesizedExpression(
j.tsAsExpression(
j.identifier("styletron"),
j.tsTypeReference(j.identifier("Server")),
),
),
j.identifier("getStylesheets"),
),
[],
),
j.arrayExpression([]),
@@ -263,93 +272,82 @@ export default RecipeBuilder()
node.body.splice(0, 0, getInitialPropsMethod)
})
program
.find(j.JSXElement, {openingElement: {name: {name: "DocumentHead"}}})
.forEach((path) => {
const {node} = path
path.replace(
j.jsxElement(
j.jsxOpeningElement(j.jsxIdentifier("DocumentHead")),
j.jsxClosingElement(j.jsxIdentifier("DocumentHead")),
[
...(node.children || []),
j.literal("\n"),
j.jsxExpressionContainer(
j.callExpression(
program.find(j.JSXElement, {openingElement: {name: {name: "Head"}}}).forEach((path) => {
const {node} = path
path.replace(
j.jsxElement(
j.jsxOpeningElement(j.jsxIdentifier("Head")),
j.jsxClosingElement(j.jsxIdentifier("Head")),
[
...(node.children || []),
j.literal("\n"),
j.jsxExpressionContainer(
j.callExpression(
j.memberExpression(
j.memberExpression(
j.memberExpression(
j.memberExpression(j.thisExpression(), j.identifier("props")),
j.identifier("stylesheets"),
),
j.identifier("map"),
j.memberExpression(j.thisExpression(), j.identifier("props")),
j.identifier("stylesheets"),
),
[
j.arrowFunctionExpression(
[j.identifier("sheet"), j.identifier("i")],
j.jsxElement(
j.jsxOpeningElement(
j.jsxIdentifier("style"),
[
j.jsxAttribute(
j.jsxIdentifier("className"),
j.literal("_styletron_hydrate_"),
),
j.jsxAttribute(
j.jsxIdentifier("dangerouslySetInnerHTML"),
j.jsxExpressionContainer(
j.objectExpression([
j.objectProperty(
j.identifier("__html"),
j.memberExpression(
j.identifier("sheet"),
j.identifier("css"),
),
),
]),
),
),
j.jsxAttribute(
j.jsxIdentifier("media"),
j.jsxExpressionContainer(
j.memberExpression(
j.memberExpression(
j.identifier("sheet"),
j.identifier("attrs"),
),
j.identifier("media"),
j.identifier("map"),
),
[
j.arrowFunctionExpression(
[j.identifier("sheet"), j.identifier("i")],
j.jsxElement(
j.jsxOpeningElement(
j.jsxIdentifier("style"),
[
j.jsxAttribute(
j.jsxIdentifier("className"),
j.literal("_styletron_hydrate_"),
),
j.jsxAttribute(
j.jsxIdentifier("dangerouslySetInnerHTML"),
j.jsxExpressionContainer(
j.objectExpression([
j.objectProperty(
j.identifier("__html"),
j.memberExpression(j.identifier("sheet"), j.identifier("css")),
),
]),
),
),
j.jsxAttribute(
j.jsxIdentifier("media"),
j.jsxExpressionContainer(
j.memberExpression(
j.memberExpression(j.identifier("sheet"), j.identifier("attrs")),
j.identifier("media"),
),
),
j.jsxAttribute(
j.jsxIdentifier("data-hydrate"),
j.jsxExpressionContainer(
j.memberExpression(
j.memberExpression(
j.identifier("sheet"),
j.identifier("attrs"),
),
j.stringLiteral("data-hydrate"),
true,
),
),
j.jsxAttribute(
j.jsxIdentifier("data-hydrate"),
j.jsxExpressionContainer(
j.memberExpression(
j.memberExpression(j.identifier("sheet"), j.identifier("attrs")),
j.stringLiteral("data-hydrate"),
true,
),
),
j.jsxAttribute(
j.jsxIdentifier("key"),
j.jsxExpressionContainer(j.jsxIdentifier("i")),
),
],
true,
),
),
j.jsxAttribute(
j.jsxIdentifier("key"),
j.jsxExpressionContainer(j.jsxIdentifier("i")),
),
],
true,
),
),
],
),
),
],
),
j.literal("\n"),
],
),
)
})
),
j.literal("\n"),
],
),
)
})
return program
},

View File

@@ -1,7 +1,7 @@
{
"name": "@blitzjs/recipe-base-web",
"private": true,
"version": "2.0.0-beta.10",
"version": "2.0.0-beta.11",
"description": "The Blitz Recipe for installing Base Web",
"main": "index.ts",
"scripts": {
@@ -23,7 +23,7 @@
},
"homepage": "https://github.com/blitz-js/blitz#readme",
"dependencies": {
"blitz": "workspace:2.0.0-beta.5",
"blitz": "2.0.0-beta.16",
"jscodeshift": "0.13.0"
},
"devDependencies": {

View File

@@ -1,7 +1,8 @@
import {Client, Server} from "styletron-engine-atomic"
import {DebugEngine} from "styletron-react"
const getHydrateClass = () => document.getElementsByClassName("_styletron_hydrate_")
const getHydrateClass = () =>
document.getElementsByClassName("_styletron_hydrate_") as HTMLCollectionOf<HTMLStyleElement>
export const styletron =
typeof window === "undefined"

View File

@@ -1,5 +1,12 @@
# @blitzjs/recipe-bulma
## 2.0.0-beta.11
### Patch Changes
- Updated dependencies [1476a577]
- blitz@2.0.0-beta.11
## 2.0.0-beta.10
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"name": "@blitzjs/recipe-bulma",
"private": true,
"version": "2.0.0-beta.10",
"version": "2.0.0-beta.11",
"description": "The Blitz Recipe for installing Bulma CSS",
"main": "index.ts",
"scripts": {
@@ -22,7 +22,7 @@
},
"homepage": "https://github.com/blitz-js/blitz#readme",
"dependencies": {
"blitz": "workspace:2.0.0-beta.5",
"blitz": "2.0.0-beta.16",
"jscodeshift": "0.13.0"
},
"devDependencies": {

View File

@@ -1,5 +1,12 @@
# @blitzjs/recipe-bumbag-ui
## 2.0.0-beta.11
### Patch Changes
- Updated dependencies [1476a577]
- blitz@2.0.0-beta.11
## 2.0.0-beta.10
### Patch Changes

View File

@@ -4,21 +4,18 @@ import j from "jscodeshift"
function wrapComponentWithBumbagProvider(program: Program) {
program
.find(j.JSXElement)
.filter(
(path) =>
path.parent?.parent?.parent?.value?.id?.name === "App" &&
path.parent?.value.type === j.ReturnStatement.toString(),
)
.forEach((path: NodePath) => {
const {node} = path
.find(j.FunctionDeclaration, (node) => node.id.name === "MyApp")
.forEach((path) => {
const statement = path.value.body.body.filter(
(b) => b.type === "ReturnStatement",
)[0] as j.ReturnStatement
const argument = statement?.argument as j.JSXElement
try {
path.replace(
j.jsxElement(
j.jsxOpeningElement(j.jsxIdentifier("BumbagProvider isSSR")),
j.jsxClosingElement(j.jsxIdentifier("BumbagProvider")),
[j.jsxText("\n"), node, j.jsxText("\n")],
),
statement.argument = j.jsxElement(
j.jsxOpeningElement(j.jsxIdentifier("BumbagProvider isSSR")),
j.jsxClosingElement(j.jsxIdentifier("BumbagProvider")),
[j.jsxText("\n"), argument, j.jsxText("\n")],
)
} catch {
console.error("Already installed recipe")

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