Compare commits
79 Commits
fix-instal
...
db
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
767926b34a | ||
|
|
c700ee4b9a | ||
|
|
da2916fccf | ||
|
|
59c839c65f | ||
|
|
1341b10e57 | ||
|
|
da678523d8 | ||
|
|
34145212ad | ||
|
|
e4fd4a8990 | ||
|
|
682664bd0c | ||
|
|
384b847b39 | ||
|
|
db0cddf5ed | ||
|
|
01754dcbbd | ||
|
|
387ffc6a80 | ||
|
|
303fad2853 | ||
|
|
a1227ee37a | ||
|
|
b31e1ac245 | ||
|
|
4e79196222 | ||
|
|
9b57078d31 | ||
|
|
cb80788734 | ||
|
|
845d171721 | ||
|
|
5f57f3c9ea | ||
|
|
96a0fffa00 | ||
|
|
6d71a60154 | ||
|
|
dd5a6b8273 | ||
|
|
a3452937c3 | ||
|
|
6826920184 | ||
|
|
0dc9feeb1e | ||
|
|
12b5161918 | ||
|
|
e72b602600 | ||
|
|
a271fe9267 | ||
|
|
75758f8130 | ||
|
|
d48161d203 | ||
|
|
1682ce0474 | ||
|
|
bc7970690c | ||
|
|
d9c5299436 | ||
|
|
bc829d6bd4 | ||
|
|
ec71d2ad0d | ||
|
|
b18393bcab | ||
|
|
2eb26617bc | ||
|
|
95988755ed | ||
|
|
87ad97ce2b | ||
|
|
a58685229f | ||
|
|
2ad5b68eab | ||
|
|
8ac511aba3 | ||
|
|
12d93c7532 | ||
|
|
e53f1b21bc | ||
|
|
b0a4bed5e3 | ||
|
|
a4a672645c | ||
|
|
88f9b4b5e5 | ||
|
|
b62dce39dd | ||
|
|
2b9b79ca2d | ||
|
|
aba8492fc0 | ||
|
|
34f5b08101 | ||
|
|
322fc6d0a9 | ||
|
|
34ee44e0bf | ||
|
|
4517a675a5 | ||
|
|
6ce248f694 | ||
|
|
e68eb6d118 | ||
|
|
ab81073003 | ||
|
|
78410abe82 | ||
|
|
7d76f646d0 | ||
|
|
e97e964099 | ||
|
|
fa358cd328 | ||
|
|
5360a839d8 | ||
|
|
a7493258eb | ||
|
|
909f3b3392 | ||
|
|
688b05df78 | ||
|
|
ec301dc22e | ||
|
|
df5271c1f0 | ||
|
|
bad2e3758e | ||
|
|
23b36b83f8 | ||
|
|
94d9daf215 | ||
|
|
aae261c589 | ||
|
|
4e3261d776 | ||
|
|
74083f704c | ||
|
|
68e1abf727 | ||
|
|
1d3ca10164 | ||
|
|
0c1cd9cc3f | ||
|
|
e186f86389 |
@@ -1302,7 +1302,8 @@
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/6379824?v=4",
|
||||
"profile": "https://oesterkilde.dk/",
|
||||
"contributions": [
|
||||
"doc"
|
||||
"doc",
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1576,7 +1577,8 @@
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/4437323?v=4",
|
||||
"profile": "https://github.com/rayandrews",
|
||||
"contributions": [
|
||||
"code"
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -1641,6 +1643,106 @@
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "Khaledgarbaya",
|
||||
"name": "Khaled Garbaya",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/1156093?v=4",
|
||||
"profile": "https://khaledgarbaya.net",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "tundera",
|
||||
"name": "tundera",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/61833561?v=4",
|
||||
"profile": "https://tundera.dev",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "markylaing",
|
||||
"name": "markylaing",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/41469221?v=4",
|
||||
"profile": "https://github.com/markylaing",
|
||||
"contributions": [
|
||||
"code",
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "AkifumiSato",
|
||||
"name": "Akifumi Sato",
|
||||
"avatar_url": "https://avatars2.githubusercontent.com/u/25711332?v=4",
|
||||
"profile": "https://akfm.dev/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "beeplin",
|
||||
"name": "Beep LIN",
|
||||
"avatar_url": "https://avatars3.githubusercontent.com/u/13058150?v=4",
|
||||
"profile": "https://github.com/beeplin",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "mattfwood",
|
||||
"name": "Matt Wood",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/22530815?v=4",
|
||||
"profile": "https://mattwood.tech/",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "jackbravo",
|
||||
"name": "Joaquin Bravo Contreras",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/15214?v=4",
|
||||
"profile": "http://joaquin.axai.mx",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "arjundubey-cr",
|
||||
"name": "Arjun Dubey",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/40758425?v=4",
|
||||
"profile": "https://github.com/arjundubey-cr",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "chanand",
|
||||
"name": "chanand",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/1317789?v=4",
|
||||
"profile": "https://github.com/chanand",
|
||||
"contributions": [
|
||||
"code"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "phillipkregg",
|
||||
"name": "phillipkregg",
|
||||
"avatar_url": "https://avatars0.githubusercontent.com/u/1066044?v=4",
|
||||
"profile": "https://github.com/phillipkregg",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"login": "timReynolds",
|
||||
"name": "Tim Reynolds",
|
||||
"avatar_url": "https://avatars1.githubusercontent.com/u/168870?v=4",
|
||||
"profile": "http://timothyreynolds.co.uk",
|
||||
"contributions": [
|
||||
"doc"
|
||||
]
|
||||
}
|
||||
],
|
||||
"contributorsPerLine": 7,
|
||||
|
||||
@@ -30,7 +30,7 @@ module.exports = {
|
||||
// note you must disable the base rule as it can report incorrect errors
|
||||
"no-redeclare": "off",
|
||||
"@typescript-eslint/no-redeclare": ["error"],
|
||||
"simple-import-sort/sort": [
|
||||
"simple-import-sort/imports": [
|
||||
"warn",
|
||||
{
|
||||
groups: [
|
||||
|
||||
6
.github/CODEOWNERS
vendored
6
.github/CODEOWNERS
vendored
@@ -2,7 +2,7 @@
|
||||
|
||||
* @flybayer
|
||||
|
||||
packages/cli/**/* @aem
|
||||
packages/generator/**/* @aem
|
||||
packages/cli/**/* @aem, @flybayer
|
||||
packages/generator/**/* @aem @flybayer
|
||||
packages/generator/templates**/* @flybayer
|
||||
packages/installer/**/* @aem
|
||||
packages/installer/**/* @aem @flybayer
|
||||
|
||||
7
.github/workflows/compressed.yml
vendored
7
.github/workflows/compressed.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Compressed Size
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -6,14 +6,15 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Compressed Size
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node and Yarn
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: "12.x"
|
||||
node-version: "14"
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
yarn && yarn build
|
||||
|
||||
33
.github/workflows/main.yml
vendored
33
.github/workflows/main.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Continuous Integration
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -17,9 +17,9 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: "12.16.1"
|
||||
node-version: "14"
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
@@ -32,9 +32,9 @@ jobs:
|
||||
**/node_modules
|
||||
/home/runner/.cache/Cypress
|
||||
C:\Users\runneradmin\AppData\Local\Cypress\Cache
|
||||
key: ${{ runner.os }}-yarn-v4-${{ hashFiles('yarn.lock') }}
|
||||
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v4-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-v4-
|
||||
${{ runner.os }}-${{ runner.node_version}}-yarn-v4-
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile --silent
|
||||
env:
|
||||
@@ -44,17 +44,18 @@ jobs:
|
||||
env:
|
||||
CI: true
|
||||
build_and_test_pkgs:
|
||||
name: Build & Test Packages
|
||||
name: Packages Tests
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
node_version: [12, 14]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: "12.16.1"
|
||||
node-version: ${{ matrix.node_version }}
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
@@ -66,9 +67,9 @@ jobs:
|
||||
${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
/home/runner/.cache/Cypress
|
||||
C:\Users\runneradmin\AppData\Local\Cypress\Cache
|
||||
key: ${{ runner.os }}-yarn-v4-${{ hashFiles('yarn.lock') }}
|
||||
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v4-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-v4-
|
||||
${{ runner.os }}-${{ runner.node_version}}-yarn-v4-
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile --silent
|
||||
env:
|
||||
@@ -85,17 +86,19 @@ jobs:
|
||||
env:
|
||||
CI: true
|
||||
build_and_test_examples:
|
||||
name: Build & Test Examples
|
||||
timeout-minutes: 30
|
||||
name: Example Apps Tests
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
node_version: [12, 14]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: "12.16.1"
|
||||
node-version: ${{ matrix.node_version }}
|
||||
- name: Get yarn cache directory path
|
||||
id: yarn-cache-dir-path
|
||||
run: echo "::set-output name=dir::$(yarn cache dir)"
|
||||
@@ -107,9 +110,9 @@ jobs:
|
||||
${{ steps.yarn-cache-dir-path.outputs.dir }}
|
||||
/home/runner/.cache/Cypress
|
||||
C:\Users\runneradmin\AppData\Local\Cypress\Cache
|
||||
key: ${{ runner.os }}-yarn-v4-${{ hashFiles('yarn.lock') }}
|
||||
key: ${{ runner.os }}-${{ runner.node_version}}-yarn-v4-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-yarn-v4-
|
||||
${{ runner.os }}-${{ runner.node_version}}-yarn-v4-
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile --silent
|
||||
env:
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -22,3 +22,5 @@ dist
|
||||
.blitz-cli-cache
|
||||
.vscode
|
||||
.tsbuildinfo
|
||||
.nvmrc
|
||||
**/.test*
|
||||
|
||||
@@ -1 +1 @@
|
||||
12.16.1
|
||||
12.20.0
|
||||
|
||||
39
README.md
39
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==">
|
||||
</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-173-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-184-17BB8A.svg?style=for-the-badge&labelColor=000000"></a>
|
||||
<!-- ALL-CONTRIBUTORS-BADGE:END -->
|
||||
<a aria-label="License" href="https://github.com/blitz-js/blitz/blob/canary/LICENSE">
|
||||
<img alt="" src="https://img.shields.io/npm/l/blitz.svg?style=for-the-badge&labelColor=000000&color=blue">
|
||||
@@ -128,13 +128,17 @@ Your financial contributions help ensure Blitz continues to be developed and mai
|
||||
### 🌱 Seedling Sponsors
|
||||
|
||||
<a aria-label="React Bricks" href="https://reactbricks.com/?utm_source=blitzjs&utm_medium=sponsorship&utm_campaign=blitzjs_sponsorship">
|
||||
<img alt="" src="https://reactbricks.com/reactbricks_icon.svg" width="30px">
|
||||
<img alt="" src="https://reactbricks.com/reactbricks_icon.svg" width="30px"/>
|
||||
</a>
|
||||
<a aria-label="Andreas Asprou" href="https://andreas.fyi">
|
||||
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/andreas.jpg" width="30px"/>
|
||||
</a>
|
||||
|
||||
|
||||
### 🥉 Bronze Sponsors
|
||||
|
||||
<a aria-label="Your Company" href="#">
|
||||
<img alt="" src="https://dummyimage.com/1000x330/efe8ff/000000.png&text=Your+Logo+Here" width="100px">
|
||||
<a aria-label="Render.com" href="https://render.com?utm_source=BlitzJS&utm_medium=sponsorship&utm_campaign=BlitzJS_Sponsorship_2020">
|
||||
<img alt="" src="https://raw.githubusercontent.com/blitz-js/blitz/canary/assets/render-logo-color2.png" width="110px">
|
||||
</a>
|
||||
|
||||
### 🥈 Silver Sponsors
|
||||
@@ -145,9 +149,11 @@ Your financial contributions help ensure Blitz continues to be developed and mai
|
||||
|
||||
### 🏆 Gold Sponsors
|
||||
|
||||
<a aria-label="Your Company" href="#">
|
||||
<img alt="" src="https://dummyimage.com/1000x330/efe8ff/000000.png&text=Your+Logo+Here" width="300px">
|
||||
<div>
|
||||
<a aria-label="G2i" href="http://g2i.co/sign-up?utm_source=blitz&utm_medium=referral&utm_campaign=blitz2020">
|
||||
<img alt="" src="https://files-5oz00y7xp.vercel.app/G2i_Logo_wwords.png" width="160px">
|
||||
</a>
|
||||
</div>
|
||||
|
||||
### 💎 Diamond Sponsors
|
||||
|
||||
@@ -163,7 +169,6 @@ Your financial contributions help ensure Blitz continues to be developed and mai
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center"><a href="https://twitter.com/flybayer"><img src="https://avatars3.githubusercontent.com/u/8813276?v=4" width="100px;" alt=""/><br /><sub><b>Brandon Bayer</b></sub></a><br />Creator</td>
|
||||
<td align="center"><a href="https://merelinguist.now.sh"><img src="https://avatars3.githubusercontent.com/u/24858006?v=4" width="100px;" alt=""/><br /><sub><b>Dylan Brookes</b></sub></a><br />Friendly Generalist</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- markdownlint-enable -->
|
||||
@@ -211,6 +216,7 @@ _Issue triage, pull request triage, community encouragement and moderation, etc_
|
||||
<td align="center"><a href="https://twitter.com/jdavenport97"><img src="https://avatars2.githubusercontent.com/u/1329874?v=4" width="100px;" alt=""/><br /><sub><b>Jamie Davenport</b></sub></a></td>
|
||||
<td align="center"><a href="https://twitter.com/myrondavis"><img src="https://avatars2.githubusercontent.com/u/1430136?v=4" width="100px;" alt=""/><br /><sub><b>Myron Davis</b></sub></a></td>
|
||||
<td align="center"><a href="https://flavioander.com/"><img src="https://avatars2.githubusercontent.com/u/14948074?s=460&u=31d7ea58b5c5cd9f724d684ed578f68896c4af71&v=4" width="100px;" alt=""/><br /><sub><b>Flavio Andrade</b></sub></a></td>
|
||||
<td align="center"><a href="https://twitter.com/NaReto1125_"><img src="https://avatars.githubusercontent.com/reo777" width="100px;" alt=""/><br /><sub><b>Reo Ishiyama</b></sub></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<!-- markdownlint-enable -->
|
||||
@@ -401,7 +407,7 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/aericson"><img src="https://avatars3.githubusercontent.com/u/692542?v=4" width="100px;" alt=""/><br /><sub><b>André Ericson</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=aericson" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=aericson" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="http://Cajotafer.com"><img src="https://avatars2.githubusercontent.com/u/41461969?v=4" width="100px;" alt=""/><br /><sub><b>Carlos Fernández</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=cajotafer" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://oesterkilde.dk/"><img src="https://avatars1.githubusercontent.com/u/6379824?v=4" width="100px;" alt=""/><br /><sub><b>Kevin Østerkilde</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Kosai106" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://oesterkilde.dk/"><img src="https://avatars1.githubusercontent.com/u/6379824?v=4" width="100px;" alt=""/><br /><sub><b>Kevin Østerkilde</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Kosai106" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=Kosai106" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/aaronfulkerson"><img src="https://avatars0.githubusercontent.com/u/31112737?v=4" width="100px;" alt=""/><br /><sub><b>aaronfulkerson</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=aaronfulkerson" title="Code">💻</a> <a href="#question-aaronfulkerson" title="Answering Questions">💬</a></td>
|
||||
<td align="center"><a href="https://github.com/alexnaiman"><img src="https://avatars3.githubusercontent.com/u/25799714?v=4" width="100px;" alt=""/><br /><sub><b>Alexandru Naiman</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=alexnaiman" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://davidlutta.github.io/portfolio/"><img src="https://avatars2.githubusercontent.com/u/14890315?v=4" width="100px;" alt=""/><br /><sub><b>David Ezekiel Lutta</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=davidlutta" title="Code">💻</a></td>
|
||||
@@ -439,7 +445,7 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
|
||||
<td align="center"><a href="http://raph.site"><img src="https://avatars3.githubusercontent.com/u/1575946?v=4" width="100px;" alt=""/><br /><sub><b>Raphaël Huchet</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=rap2hpoutre" title="Documentation">📖</a> <a href="https://github.com/blitz-js/blitz/commits?author=rap2hpoutre" title="Tests">⚠️</a> <a href="https://github.com/blitz-js/blitz/commits?author=rap2hpoutre" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://kattcorp.com"><img src="https://avatars1.githubusercontent.com/u/459267?v=4" width="100px;" alt=""/><br /><sub><b>Alex Johansson</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=KATT" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://davidmazza.com"><img src="https://avatars0.githubusercontent.com/u/120893?v=4" width="100px;" alt=""/><br /><sub><b>David Mazza</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=dmzza" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/rayandrews"><img src="https://avatars1.githubusercontent.com/u/4437323?v=4" width="100px;" alt=""/><br /><sub><b>Ray Andrew</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=rayandrews" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/rayandrews"><img src="https://avatars1.githubusercontent.com/u/4437323?v=4" width="100px;" alt=""/><br /><sub><b>Ray Andrew</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=rayandrews" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=rayandrews" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="http://Dal.Design"><img src="https://avatars3.githubusercontent.com/u/43112535?v=4" width="100px;" alt=""/><br /><sub><b>Abdullah Mzaien</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Mzaien" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://kwao.io"><img src="https://avatars2.githubusercontent.com/u/8839514?v=4" width="100px;" alt=""/><br /><sub><b>William Kwao</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=williamkwao" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
@@ -449,6 +455,21 @@ Thanks to these wonderful people ([emoji key](https://allcontributors.org/docs/e
|
||||
<td align="center"><a href="http://jonstuebe.com"><img src="https://avatars0.githubusercontent.com/u/156722?v=4" width="100px;" alt=""/><br /><sub><b>Jon Stuebe</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jonstuebe" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://ugogo.dev"><img src="https://avatars2.githubusercontent.com/u/5040476?v=4" width="100px;" alt=""/><br /><sub><b>Ugo Onali</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=ugogo" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://saintmalik.me"><img src="https://avatars1.githubusercontent.com/u/37118134?v=4" width="100px;" alt=""/><br /><sub><b>SaintMalik</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=saintmalik" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://khaledgarbaya.net"><img src="https://avatars1.githubusercontent.com/u/1156093?v=4" width="100px;" alt=""/><br /><sub><b>Khaled Garbaya</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=Khaledgarbaya" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://tundera.dev"><img src="https://avatars0.githubusercontent.com/u/61833561?v=4" width="100px;" alt=""/><br /><sub><b>tundera</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=tundera" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/markylaing"><img src="https://avatars2.githubusercontent.com/u/41469221?v=4" width="100px;" alt=""/><br /><sub><b>markylaing</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=markylaing" title="Code">💻</a> <a href="https://github.com/blitz-js/blitz/commits?author=markylaing" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="https://akfm.dev/"><img src="https://avatars2.githubusercontent.com/u/25711332?v=4" width="100px;" alt=""/><br /><sub><b>Akifumi Sato</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=AkifumiSato" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/beeplin"><img src="https://avatars3.githubusercontent.com/u/13058150?v=4" width="100px;" alt=""/><br /><sub><b>Beep LIN</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=beeplin" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://mattwood.tech/"><img src="https://avatars1.githubusercontent.com/u/22530815?v=4" width="100px;" alt=""/><br /><sub><b>Matt Wood</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=mattfwood" title="Code">💻</a></td>
|
||||
<td align="center"><a href="http://joaquin.axai.mx"><img src="https://avatars1.githubusercontent.com/u/15214?v=4" width="100px;" alt=""/><br /><sub><b>Joaquin Bravo Contreras</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=jackbravo" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/arjundubey-cr"><img src="https://avatars0.githubusercontent.com/u/40758425?v=4" width="100px;" alt=""/><br /><sub><b>Arjun Dubey</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=arjundubey-cr" title="Code">💻</a></td>
|
||||
<td align="center"><a href="https://github.com/chanand"><img src="https://avatars0.githubusercontent.com/u/1317789?v=4" width="100px;" alt=""/><br /><sub><b>chanand</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=chanand" title="Code">💻</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align="center"><a href="https://github.com/phillipkregg"><img src="https://avatars0.githubusercontent.com/u/1066044?v=4" width="100px;" alt=""/><br /><sub><b>phillipkregg</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=phillipkregg" title="Documentation">📖</a></td>
|
||||
<td align="center"><a href="http://timothyreynolds.co.uk"><img src="https://avatars1.githubusercontent.com/u/168870?v=4" width="100px;" alt=""/><br /><sub><b>Tim Reynolds</b></sub></a><br /><a href="https://github.com/blitz-js/blitz/commits?author=timReynolds" title="Documentation">📖</a></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
BIN
assets/andreas.jpg
Normal file
BIN
assets/andreas.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
BIN
assets/render-logo-color2.png
Normal file
BIN
assets/render-logo-color2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.9 KiB |
@@ -23,109 +23,115 @@ assert(process.env.AUTH0_CLIENT_SECRET, "You must provide the AUTH0_CLIENT_SECRE
|
||||
|
||||
export default passportAuth({
|
||||
successRedirectUrl: "/",
|
||||
authenticateOptions: {scope: "openid email profile"}, //used for Auth0Strategy - without an empty profile is returned
|
||||
strategies: [
|
||||
new TwitterStrategy(
|
||||
{
|
||||
consumerKey: process.env.TWITTER_CONSUMER_KEY,
|
||||
consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
|
||||
callbackURL:
|
||||
process.env.NODE_ENV === "production"
|
||||
? "https://auth-example-flybayer.blitzjs.vercel.app/api/auth/twitter/callback"
|
||||
: "http://localhost:3000/api/auth/twitter/callback",
|
||||
includeEmail: true,
|
||||
},
|
||||
async function (_token, _tokenSecret, profile, done) {
|
||||
const email = profile.emails && profile.emails[0]?.value
|
||||
{
|
||||
strategy: new TwitterStrategy(
|
||||
{
|
||||
consumerKey: process.env.TWITTER_CONSUMER_KEY,
|
||||
consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
|
||||
callbackURL:
|
||||
process.env.NODE_ENV === "production"
|
||||
? "https://auth-example-flybayer.blitzjs.vercel.app/api/auth/twitter/callback"
|
||||
: "http://localhost:3000/api/auth/twitter/callback",
|
||||
includeEmail: true,
|
||||
},
|
||||
async function (_token, _tokenSecret, profile, done) {
|
||||
const email = profile.emails && profile.emails[0]?.value
|
||||
|
||||
if (!email) {
|
||||
// This can happen if you haven't enabled email access in your twitter app permissions
|
||||
return done(new Error("Twitter OAuth response doesn't have email."))
|
||||
}
|
||||
if (!email) {
|
||||
// This can happen if you haven't enabled email access in your twitter app permissions
|
||||
return done(new Error("Twitter OAuth response doesn't have email."))
|
||||
}
|
||||
|
||||
const user = await db.user.upsert({
|
||||
where: {email},
|
||||
create: {
|
||||
email,
|
||||
name: profile.displayName,
|
||||
},
|
||||
update: {email},
|
||||
})
|
||||
const user = await db.user.upsert({
|
||||
where: {email},
|
||||
create: {
|
||||
email,
|
||||
name: profile.displayName,
|
||||
},
|
||||
update: {email},
|
||||
})
|
||||
|
||||
const publicData = {userId: user.id, roles: [user.role], source: "twitter"}
|
||||
done(null, {publicData})
|
||||
},
|
||||
),
|
||||
new GitHubStrategy(
|
||||
{
|
||||
clientID: process.env.GITHUB_CLIENT_ID,
|
||||
clientSecret: process.env.GITHUB_CLIENT_SECRET,
|
||||
callbackURL:
|
||||
process.env.NODE_ENV === "production"
|
||||
? "https://auth-example-flybayer.blitzjs.vercel.app/api/auth/github/callback"
|
||||
: "http://localhost:3000/api/auth/github/callback",
|
||||
},
|
||||
async function (_token, _tokenSecret, profile, done) {
|
||||
const email = profile.emails && profile.emails[0]?.value
|
||||
const publicData = {userId: user.id, roles: [user.role], source: "twitter"}
|
||||
done(null, {publicData})
|
||||
},
|
||||
),
|
||||
},
|
||||
{
|
||||
strategy: new GitHubStrategy(
|
||||
{
|
||||
clientID: process.env.GITHUB_CLIENT_ID,
|
||||
clientSecret: process.env.GITHUB_CLIENT_SECRET,
|
||||
callbackURL:
|
||||
process.env.NODE_ENV === "production"
|
||||
? "https://auth-example-flybayer.blitzjs.vercel.app/api/auth/github/callback"
|
||||
: "http://localhost:3000/api/auth/github/callback",
|
||||
},
|
||||
async function (_token, _tokenSecret, profile, done) {
|
||||
const email = profile.emails && profile.emails[0]?.value
|
||||
|
||||
if (!email) {
|
||||
// This can happen if you haven't enabled email access in your twitter app permissions
|
||||
return done(new Error("Twitter OAuth response doesn't have email."))
|
||||
}
|
||||
if (!email) {
|
||||
// This can happen if you haven't enabled email access in your twitter app permissions
|
||||
return done(new Error("Twitter OAuth response doesn't have email."))
|
||||
}
|
||||
|
||||
const user = await db.user.upsert({
|
||||
where: {email},
|
||||
create: {
|
||||
email,
|
||||
name: profile.displayName,
|
||||
},
|
||||
update: {email},
|
||||
})
|
||||
const user = await db.user.upsert({
|
||||
where: {email},
|
||||
create: {
|
||||
email,
|
||||
name: profile.displayName,
|
||||
},
|
||||
update: {email},
|
||||
})
|
||||
|
||||
const publicData = {
|
||||
userId: user.id,
|
||||
roles: [user.role],
|
||||
source: "github",
|
||||
githubUsername: profile.username,
|
||||
}
|
||||
done(null, {publicData})
|
||||
},
|
||||
),
|
||||
new Auth0Strategy(
|
||||
{
|
||||
domain: process.env.AUTH0_DOMAIN,
|
||||
clientID: process.env.AUTH0_CLIENT_ID,
|
||||
clientSecret: process.env.AUTH0_CLIENT_SECRET,
|
||||
callbackURL:
|
||||
process.env.NODE_ENV === "production"
|
||||
? "https://auth-example-flybayer.blitzjs.vercel.app/api/auth/auth0/callback"
|
||||
: "http://localhost:3000/api/auth/auth0/callback",
|
||||
},
|
||||
async function (_token, _tokenSecret, extraParams, profile, done) {
|
||||
const email = profile.emails && profile.emails[0]?.value
|
||||
const publicData = {
|
||||
userId: user.id,
|
||||
roles: [user.role],
|
||||
source: "github",
|
||||
githubUsername: profile.username,
|
||||
}
|
||||
done(null, {publicData})
|
||||
},
|
||||
),
|
||||
},
|
||||
{
|
||||
authenticateOptions: {scope: "openid email profile"},
|
||||
strategy: new Auth0Strategy(
|
||||
{
|
||||
domain: process.env.AUTH0_DOMAIN,
|
||||
clientID: process.env.AUTH0_CLIENT_ID,
|
||||
clientSecret: process.env.AUTH0_CLIENT_SECRET,
|
||||
callbackURL:
|
||||
process.env.NODE_ENV === "production"
|
||||
? "https://auth-example-flybayer.blitzjs.vercel.app/api/auth/auth0/callback"
|
||||
: "http://localhost:3000/api/auth/auth0/callback",
|
||||
},
|
||||
async function (_token, _tokenSecret, extraParams, profile, done) {
|
||||
const email = profile.emails && profile.emails[0]?.value
|
||||
|
||||
if (!email) {
|
||||
// This can happen if you haven't enabled email access in your twitter app permissions
|
||||
return done(new Error("GitHub OAuth response doesn't have email."))
|
||||
}
|
||||
if (!email) {
|
||||
// This can happen if you haven't enabled email access in your twitter app permissions
|
||||
return done(new Error("Auth0 response doesn't have email."))
|
||||
}
|
||||
|
||||
const user = await db.user.upsert({
|
||||
where: {email},
|
||||
create: {
|
||||
email,
|
||||
name: profile.displayName,
|
||||
},
|
||||
update: {email},
|
||||
})
|
||||
const user = await db.user.upsert({
|
||||
where: {email},
|
||||
create: {
|
||||
email,
|
||||
name: profile.displayName,
|
||||
},
|
||||
update: {email},
|
||||
})
|
||||
|
||||
const publicData = {
|
||||
userId: user.id,
|
||||
roles: [user.role],
|
||||
source: "auth0",
|
||||
githubUsername: profile.username,
|
||||
}
|
||||
done(undefined, {publicData})
|
||||
},
|
||||
),
|
||||
const publicData = {
|
||||
userId: user.id,
|
||||
roles: [user.role],
|
||||
source: "auth0",
|
||||
githubUsername: profile.username,
|
||||
}
|
||||
done(undefined, {publicData})
|
||||
},
|
||||
),
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
@@ -18,7 +18,7 @@ export const verifyPassword = async (hashedPassword: string, password: string) =
|
||||
}
|
||||
|
||||
export const authenticateUser = async (email: string, password: string) => {
|
||||
const user = await db.user.findFirst({where: {email}})
|
||||
const user = await db().user.findFirst({where: {email}})
|
||||
|
||||
if (!user || !user.hashedPassword) throw new AuthenticationError()
|
||||
|
||||
@@ -28,7 +28,7 @@ export const authenticateUser = async (email: string, password: string) => {
|
||||
case SecurePassword.VALID_NEEDS_REHASH:
|
||||
// Upgrade hashed password with a more secure hash
|
||||
const improvedHash = await hashPassword(password)
|
||||
await db.user.update({where: {id: user.id}, data: {hashedPassword: improvedHash}})
|
||||
await db().user.update({where: {id: user.id}, data: {hashedPassword: improvedHash}})
|
||||
break
|
||||
default:
|
||||
throw new AuthenticationError()
|
||||
|
||||
@@ -14,7 +14,7 @@ export default async function signup(input: SignupInputType, {session}: Ctx) {
|
||||
const {email, password} = SignupInput.parse(input)
|
||||
|
||||
const hashedPassword = await hashPassword(password)
|
||||
const user = await db.user.create({
|
||||
const user = await db().user.create({
|
||||
data: {email, hashedPassword, role: "user"},
|
||||
select: {id: true, name: true, email: true, role: true},
|
||||
})
|
||||
|
||||
@@ -4,7 +4,7 @@ import db from "db"
|
||||
export default async function getCurrentUser(_ = null, ctx: Ctx) {
|
||||
if (!ctx.session.userId) return null
|
||||
|
||||
const user = await db.user.findFirst({
|
||||
const user = await db().user.findFirst({
|
||||
where: {id: ctx.session.userId},
|
||||
select: {id: true, name: true, email: true, role: true},
|
||||
})
|
||||
|
||||
@@ -8,7 +8,7 @@ type GetUserInput = {
|
||||
export default async function getUser({where}: GetUserInput, ctx: Ctx) {
|
||||
ctx.session.authorize()
|
||||
|
||||
const user = await db.user.findFirst({where})
|
||||
const user = await db().user.findFirst({where})
|
||||
|
||||
if (!user) throw new NotFoundError(`User with id ${where.id} does not exist`)
|
||||
|
||||
|
||||
@@ -6,14 +6,14 @@ type GetUsersInput = Pick<FindManyUserArgs, "where" | "orderBy" | "skip" | "take
|
||||
export default async function getUsers({where, orderBy, skip = 0, take}: GetUsersInput, ctx: Ctx) {
|
||||
ctx.session.authorize()
|
||||
|
||||
const users = await db.user.findMany({
|
||||
const users = await db().user.findMany({
|
||||
where,
|
||||
orderBy,
|
||||
take,
|
||||
skip,
|
||||
})
|
||||
|
||||
const count = await db.user.count()
|
||||
const count = await db().user.count()
|
||||
const hasMore = typeof take === "number" ? skip + take < count : false
|
||||
const nextPage = hasMore ? {take, skip: skip + take!} : null
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const {sessionMiddleware, unstable_simpleRolesIsAuthorized} = require("@blitzjs/server")
|
||||
const {sessionMiddleware, simpleRolesIsAuthorized} = require("@blitzjs/server")
|
||||
const withBundleAnalyzer = require("@next/bundle-analyzer")({
|
||||
enabled: process.env.ANALYZE === "true",
|
||||
})
|
||||
@@ -6,13 +6,16 @@ const withBundleAnalyzer = require("@next/bundle-analyzer")({
|
||||
module.exports = withBundleAnalyzer({
|
||||
middleware: [
|
||||
sessionMiddleware({
|
||||
unstable_isAuthorized: unstable_simpleRolesIsAuthorized,
|
||||
isAuthorized: simpleRolesIsAuthorized,
|
||||
sessionExpiryMinutes: 4,
|
||||
}),
|
||||
],
|
||||
log: {
|
||||
level: "trace",
|
||||
},
|
||||
experimental: {
|
||||
isomorphicResolverImports: true,
|
||||
},
|
||||
/*
|
||||
webpack: (config, {buildId, dev, isServer, defaultLoaders, webpack}) => {
|
||||
// Note: we provide webpack above so you should not `require` it
|
||||
|
||||
@@ -1,15 +1,7 @@
|
||||
import {PrismaClient} from "@prisma/client"
|
||||
export * from "@prisma/client"
|
||||
|
||||
let prisma: PrismaClient
|
||||
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
prisma = new PrismaClient()
|
||||
} else {
|
||||
// Ensure the prisma instance is re-used during hot-reloading
|
||||
// Otherwise, a new client will be created on every reload
|
||||
globalThis["prisma"] = globalThis["prisma"] || new PrismaClient()
|
||||
prisma = globalThis["prisma"]
|
||||
export default function db(): PrismaClient {
|
||||
globalThis.prisma = globalThis.prisma || new PrismaClient()
|
||||
return globalThis.prisma
|
||||
}
|
||||
|
||||
export default prisma
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@examples/auth",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"scripts": {
|
||||
"start": "blitz start",
|
||||
"studio": "blitz db studio",
|
||||
@@ -11,7 +11,7 @@
|
||||
"cy:run": "cypress run",
|
||||
"test": "prisma generate && yarn test:jest && yarn test:e2e",
|
||||
"test:jest": "jest",
|
||||
"test:server": "blitz db migrate && blitz start --production -p 3099",
|
||||
"test:server": "blitz db migrate && blitz build && blitz start --production -p 3099",
|
||||
"test:e2e": "cross-env NODE_ENV=test start-server-and-test test:server http://localhost:3099 cy:run"
|
||||
},
|
||||
"browserslist": [
|
||||
@@ -40,53 +40,53 @@
|
||||
"dependencies": {
|
||||
"@prisma/cli": "2.12.0",
|
||||
"@prisma/client": "2.12.0",
|
||||
"blitz": "0.27.0-canary.1",
|
||||
"blitz": "0.28.0-canary.1",
|
||||
"final-form": "4.20.1",
|
||||
"passport-auth0": "1.3.3",
|
||||
"passport-github2": "0.1.11",
|
||||
"passport-auth0": "1.4.0",
|
||||
"passport-github2": "0.1.12",
|
||||
"passport-twitter": "1.0.4",
|
||||
"react": "0.0.0-experimental-4ead6b530",
|
||||
"react-dom": "0.0.0-experimental-4ead6b530",
|
||||
"react-error-boundary": "2.3.1",
|
||||
"react-final-form": "6.5.1",
|
||||
"react": "0.0.0-experimental-3310209d0",
|
||||
"react-dom": "0.0.0-experimental-3310209d0",
|
||||
"react-error-boundary": "3.1.0",
|
||||
"react-final-form": "6.5.2",
|
||||
"secure-password": "4.0.0",
|
||||
"zod": "1.10.0"
|
||||
"zod": "1.11.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@cypress/skip-test": "2.5.0",
|
||||
"@cypress/skip-test": "2.5.1",
|
||||
"@next/bundle-analyzer": "latest",
|
||||
"@testing-library/jest-dom": "5.11.4",
|
||||
"@testing-library/react": "11.1.0",
|
||||
"@testing-library/react-hooks": "3.4.2",
|
||||
"@types/jest": "26.0.14",
|
||||
"@testing-library/jest-dom": "5.11.8",
|
||||
"@testing-library/react": "11.2.2",
|
||||
"@testing-library/react-hooks": "3.7.0",
|
||||
"@types/jest": "26.0.19",
|
||||
"@types/passport-auth0": "1.0.4",
|
||||
"@types/passport-github2": "1.2.4",
|
||||
"@types/passport-twitter": "1.0.36",
|
||||
"@types/react": "16.9.38",
|
||||
"@types/react": "17.0.0",
|
||||
"@types/secure-password": "3.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "2.34.1-alpha.2",
|
||||
"@typescript-eslint/parser": "2.34.1-alpha.2",
|
||||
"@typescript-eslint/eslint-plugin": "4.11.1",
|
||||
"@typescript-eslint/parser": "4.11.1",
|
||||
"babel-eslint": "10.1.0",
|
||||
"cross-env": "latest",
|
||||
"cypress": "4.11.0",
|
||||
"eslint": "7.6.0",
|
||||
"eslint-config-react-app": "5.2.1",
|
||||
"eslint-plugin-cypress": "2.11.1",
|
||||
"cross-env": "7.0.3",
|
||||
"cypress": "6.2.0",
|
||||
"eslint": "7.16.0",
|
||||
"eslint-config-react-app": "6.0.0",
|
||||
"eslint-plugin-cypress": "2.11.2",
|
||||
"eslint-plugin-flowtype": "5.2.0",
|
||||
"eslint-plugin-import": "2.22.0",
|
||||
"eslint-plugin-jsx-a11y": "6.3.1",
|
||||
"eslint-plugin-react": "7.20.5",
|
||||
"eslint-plugin-react-hooks": "4.0.8",
|
||||
"husky": "4.2.5",
|
||||
"jest": "26.5.3",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eslint-plugin-jsx-a11y": "6.4.1",
|
||||
"eslint-plugin-react": "7.22.0",
|
||||
"eslint-plugin-react-hooks": "4.2.0",
|
||||
"husky": "4.3.6",
|
||||
"jest": "26.6.3",
|
||||
"jest-environment-jsdom-fourteen": "1.0.1",
|
||||
"jest-watch-typeahead": "0.6.1",
|
||||
"lint-staged": "10.2.13",
|
||||
"prettier": "2.0.5",
|
||||
"pretty-quick": "2.0.1",
|
||||
"start-server-and-test": "1.11.2",
|
||||
"ts-jest": "26.4.1",
|
||||
"typescript": "3.9.5"
|
||||
"lint-staged": "10.5.3",
|
||||
"prettier": "2.2.1",
|
||||
"pretty-quick": "3.1.0",
|
||||
"start-server-and-test": "1.11.7",
|
||||
"ts-jest": "26.4.4",
|
||||
"typescript": "4.1.3"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const { sessionMiddleware, unstable_simpleRolesIsAuthorized } = require("@blitzjs/server")
|
||||
const { sessionMiddleware, simpleRolesIsAuthorized } = require("@blitzjs/server")
|
||||
const { GraphQLClient, gql } = require("graphql-request")
|
||||
|
||||
const graphQLClient = new GraphQLClient("https://graphql.fauna.com/graphql", {
|
||||
@@ -20,7 +20,7 @@ const normalizeSession = (faunaSession) => {
|
||||
module.exports = {
|
||||
middleware: [
|
||||
sessionMiddleware({
|
||||
unstable_isAuthorized: unstable_simpleRolesIsAuthorized,
|
||||
isAuthorized: simpleRolesIsAuthorized,
|
||||
getSession: async (handle) => {
|
||||
const { findSessionByHandle: session } = await graphQLClient.request(
|
||||
gql`
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@examples/fauna",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"scripts": {
|
||||
"start": "blitz start",
|
||||
"studio": "blitz db studio",
|
||||
@@ -27,44 +27,44 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"blitz": "0.27.0-canary.1",
|
||||
"blitz": "0.28.0-canary.1",
|
||||
"final-form": "4.20.1",
|
||||
"graphql": "15.3.0",
|
||||
"graphql-request": "3.1.0",
|
||||
"react": "0.0.0-experimental-4ead6b530",
|
||||
"react-dom": "0.0.0-experimental-4ead6b530",
|
||||
"react-error-boundary": "2.3.1",
|
||||
"react-final-form": "6.5.1",
|
||||
"graphql": "15.4.0",
|
||||
"graphql-request": "3.4.0",
|
||||
"react": "0.0.0-experimental-3310209d0",
|
||||
"react-dom": "0.0.0-experimental-3310209d0",
|
||||
"react-error-boundary": "3.1.0",
|
||||
"react-final-form": "6.5.2",
|
||||
"secure-password": "4.0.0",
|
||||
"zod": "1.10.0"
|
||||
"zod": "1.11.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/jest-dom": "5.11.4",
|
||||
"@testing-library/react": "11.1.0",
|
||||
"@testing-library/react-hooks": "3.4.2",
|
||||
"@types/jest": "26.0.14",
|
||||
"@types/react": "16.9.38",
|
||||
"@testing-library/jest-dom": "5.11.8",
|
||||
"@testing-library/react": "11.2.2",
|
||||
"@testing-library/react-hooks": "3.7.0",
|
||||
"@types/jest": "26.0.19",
|
||||
"@types/react": "17.0.0",
|
||||
"@types/secure-password": "3.1.0",
|
||||
"@typescript-eslint/eslint-plugin": "2.34.1-alpha.2",
|
||||
"@typescript-eslint/parser": "2.34.1-alpha.2",
|
||||
"@typescript-eslint/eslint-plugin": "4.11.1",
|
||||
"@typescript-eslint/parser": "4.11.1",
|
||||
"babel-eslint": "10.1.0",
|
||||
"eslint": "7.6.0",
|
||||
"eslint-config-react-app": "5.2.1",
|
||||
"eslint": "7.16.0",
|
||||
"eslint-config-react-app": "6.0.0",
|
||||
"eslint-plugin-flowtype": "5.2.0",
|
||||
"eslint-plugin-import": "2.22.0",
|
||||
"eslint-plugin-jsx-a11y": "6.3.1",
|
||||
"eslint-plugin-react": "7.20.5",
|
||||
"eslint-plugin-react-hooks": "4.0.8",
|
||||
"husky": "4.2.5",
|
||||
"jest": "26.5.3",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eslint-plugin-jsx-a11y": "6.4.1",
|
||||
"eslint-plugin-react": "7.22.0",
|
||||
"eslint-plugin-react-hooks": "4.2.0",
|
||||
"husky": "4.3.6",
|
||||
"jest": "26.6.3",
|
||||
"jest-environment-jsdom-fourteen": "1.0.1",
|
||||
"jest-watch-typeahead": "0.6.1",
|
||||
"lint-staged": "10.2.13",
|
||||
"prettier": "2.0.5",
|
||||
"pretty-quick": "2.0.1",
|
||||
"start-server-and-test": "1.11.2",
|
||||
"ts-jest": "26.4.1",
|
||||
"typescript": "3.9.5"
|
||||
"lint-staged": "10.5.3",
|
||||
"prettier": "2.2.1",
|
||||
"pretty-quick": "3.1.0",
|
||||
"start-server-and-test": "1.11.7",
|
||||
"ts-jest": "26.4.4",
|
||||
"typescript": "4.1.3"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "no-prisma",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"scripts": {
|
||||
"start": "blitz start",
|
||||
"build": "blitz build",
|
||||
@@ -26,29 +26,29 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"blitz": "0.27.0-canary.1",
|
||||
"knex": "0.21.2",
|
||||
"react": "0.0.0-experimental-4ead6b530",
|
||||
"react-dom": "0.0.0-experimental-4ead6b530",
|
||||
"blitz": "0.28.0-canary.1",
|
||||
"knex": "0.21.15",
|
||||
"react": "0.0.0-experimental-3310209d0",
|
||||
"react-dom": "0.0.0-experimental-3310209d0",
|
||||
"sqlite3": "5.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "16.9.43",
|
||||
"@typescript-eslint/eslint-plugin": "2.34.1-alpha.2",
|
||||
"@typescript-eslint/parser": "2.34.1-alpha.2",
|
||||
"@types/react": "17.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.11.1",
|
||||
"@typescript-eslint/parser": "4.11.1",
|
||||
"babel-eslint": "10.1.0",
|
||||
"eslint": "7.6.0",
|
||||
"eslint-config-react-app": "5.2.1",
|
||||
"eslint": "7.16.0",
|
||||
"eslint-config-react-app": "6.0.0",
|
||||
"eslint-plugin-flowtype": "5.2.0",
|
||||
"eslint-plugin-import": "2.22.0",
|
||||
"eslint-plugin-jsx-a11y": "6.3.1",
|
||||
"eslint-plugin-react": "7.20.5",
|
||||
"eslint-plugin-react-hooks": "4.0.8",
|
||||
"husky": "4.2.5",
|
||||
"lint-staged": "10.2.13",
|
||||
"prettier": "2.0.5",
|
||||
"pretty-quick": "2.0.1",
|
||||
"typescript": "3.9.6"
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eslint-plugin-jsx-a11y": "6.4.1",
|
||||
"eslint-plugin-react": "7.22.0",
|
||||
"eslint-plugin-react-hooks": "4.2.0",
|
||||
"husky": "4.3.6",
|
||||
"lint-staged": "10.5.3",
|
||||
"prettier": "2.2.1",
|
||||
"pretty-quick": "3.1.0",
|
||||
"typescript": "4.1.3"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@examples/plain-js",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"scripts": {
|
||||
"start": "blitz start",
|
||||
"build": "blitz db migrate && blitz build",
|
||||
@@ -31,27 +31,26 @@
|
||||
"dependencies": {
|
||||
"@prisma/cli": "2.12.0",
|
||||
"@prisma/client": "2.12.0",
|
||||
"blitz": "0.27.0-canary.1",
|
||||
"react": "0.0.0-experimental-4ead6b530",
|
||||
"react-dom": "0.0.0-experimental-4ead6b530"
|
||||
"blitz": "0.28.0-canary.1",
|
||||
"react": "0.0.0-experimental-3310209d0",
|
||||
"react-dom": "0.0.0-experimental-3310209d0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "16.9.35",
|
||||
"@typescript-eslint/eslint-plugin": "2.31.0",
|
||||
"@typescript-eslint/parser": "2.31.0",
|
||||
"@typescript-eslint/eslint-plugin": "4.11.1",
|
||||
"@typescript-eslint/parser": "4.11.1",
|
||||
"babel-eslint": "10.1.0",
|
||||
"eslint": "7.6.0",
|
||||
"eslint-config-react-app": "5.2.1",
|
||||
"eslint": "7.16.0",
|
||||
"eslint-config-react-app": "6.0.0",
|
||||
"eslint-plugin-flowtype": "5.2.0",
|
||||
"eslint-plugin-import": "2.22.0",
|
||||
"eslint-plugin-jsx-a11y": "6.3.1",
|
||||
"eslint-plugin-react": "7.20.5",
|
||||
"eslint-plugin-react-hooks": "4.0.8",
|
||||
"husky": "4.2.5",
|
||||
"lint-staged": "10.2.2",
|
||||
"prettier": "2.0.5",
|
||||
"pretty-quick": "2.0.1",
|
||||
"typescript": "3.9.2"
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eslint-plugin-jsx-a11y": "6.4.1",
|
||||
"eslint-plugin-react": "7.22.0",
|
||||
"eslint-plugin-react-hooks": "4.2.0",
|
||||
"husky": "4.3.6",
|
||||
"lint-staged": "10.5.3",
|
||||
"prettier": "2.2.1",
|
||||
"pretty-quick": "3.1.0",
|
||||
"typescript": "4.1.3"
|
||||
},
|
||||
"private": true
|
||||
}
|
||||
|
||||
@@ -1483,7 +1483,6 @@
|
||||
expand-tilde "2.0.2"
|
||||
fast-glob "3.2.2"
|
||||
flush-write-stream "2.0.0"
|
||||
folder-hash "3.3.1"
|
||||
from2 "2.3.0"
|
||||
gulp-if "3.0.0"
|
||||
hasha "5.2.0"
|
||||
@@ -4943,15 +4942,6 @@ flush-write-stream@^1.0.0, flush-write-stream@^1.0.2:
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^2.3.6"
|
||||
|
||||
folder-hash@3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/folder-hash/-/folder-hash-3.3.1.tgz#72ca3593a43c3873e27a8edce2423f30f8ee6096"
|
||||
integrity sha512-M5Rxur/jgIWfr0gbJBRY9aMLXCieM6Gy1xB/KqC2Nd4ZvxZJAccWvg+7SmbfALntmYj51wHWzcE4cqgXQPWaBA==
|
||||
dependencies:
|
||||
debug "^4.1.1"
|
||||
graceful-fs "~4.2.0"
|
||||
minimatch "~3.0.4"
|
||||
|
||||
for-in@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
|
||||
4
examples/store/app/admin/pages/admin/index.module.scss
Normal file
4
examples/store/app/admin/pages/admin/index.module.scss
Normal file
@@ -0,0 +1,4 @@
|
||||
/* integration test for scss modules */
|
||||
.red {
|
||||
border: 2px solid red;
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
import {Link} from "blitz"
|
||||
|
||||
import styles from "./index.module.scss"
|
||||
|
||||
function StoreAdminPage() {
|
||||
return (
|
||||
<div>
|
||||
<h1>Store Admin</h1>
|
||||
<h1 className={styles.red}>Store Admin</h1>
|
||||
<div>
|
||||
<p>
|
||||
<Link href="/admin/products">
|
||||
|
||||
5
examples/store/app/products/api.ts
Normal file
5
examples/store/app/products/api.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
// this file acts as a regression test for #1646
|
||||
|
||||
export function getMeSomeQualityHumor() {
|
||||
return "https://xkcd.com/" + Math.floor(Math.random() * 2402)
|
||||
}
|
||||
@@ -4,6 +4,10 @@ import getProducts, {averagePrice} from "../../queries/getProducts"
|
||||
import {Product} from "db"
|
||||
import superjson from "superjson"
|
||||
|
||||
// regression test for #1646
|
||||
import {getMeSomeQualityHumor} from "../../api"
|
||||
console.log("Attention! Must read: " + getMeSomeQualityHumor())
|
||||
|
||||
type StaticProps = {
|
||||
dataString: string
|
||||
}
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
#!/usr/bin/env node
|
||||
if (process.platform !== "win32") {
|
||||
const glob = require("glob")
|
||||
const fs = require("fs")
|
||||
|
||||
const glob = require("glob")
|
||||
const fs = require("fs")
|
||||
|
||||
glob("./.next/static/chunks/**/*", {nodir: true}, (err, matches) => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
|
||||
const offenders = []
|
||||
|
||||
for (const match of matches) {
|
||||
const content = fs.readFileSync(match).toString()
|
||||
|
||||
if (content.includes("this line should not be included in the frontend bundle")) {
|
||||
offenders.push(match)
|
||||
glob("./.next/static/chunks/**/*", {nodir: true}, (err, matches) => {
|
||||
if (err) {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
if (offenders.length > 0) {
|
||||
console.error(`tree-shaking failed: ${offenders} includes the forbidden words.`)
|
||||
process.exit(1)
|
||||
}
|
||||
})
|
||||
const offenders = []
|
||||
|
||||
for (const match of matches) {
|
||||
const content = fs.readFileSync(match).toString()
|
||||
|
||||
if (content.includes("this line should not be included in the frontend bundle")) {
|
||||
offenders.push(match)
|
||||
}
|
||||
}
|
||||
|
||||
if (offenders.length > 0) {
|
||||
console.error(`tree-shaking failed: ${offenders} includes the forbidden words.`)
|
||||
process.exit(1)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ module.exports = {
|
||||
return next()
|
||||
},
|
||||
],
|
||||
experimental: {
|
||||
isomorphicResolverImports: true,
|
||||
},
|
||||
// webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
|
||||
// // Note: we provide webpack above so you should not `require` it
|
||||
// // Perform customizations to webpack config
|
||||
|
||||
@@ -3,6 +3,15 @@ describe("products#index page", () => {
|
||||
cy.visit("/products")
|
||||
cy.contains("h1", "Products")
|
||||
})
|
||||
|
||||
it("Logs the XKCD (Regression #1646)", () => {
|
||||
cy.visit("/products", {
|
||||
onBeforeLoad(win) {
|
||||
cy.stub(win.console, "log").as("consoleLog")
|
||||
},
|
||||
})
|
||||
cy.get("@consoleLog").should("be.calledWithMatch", /Attention! Must read: .*/)
|
||||
})
|
||||
})
|
||||
|
||||
describe("products#show page", () => {
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
{
|
||||
"name": "@examples/store",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "blitz db migrate && blitz build",
|
||||
"cy:open": "cypress open",
|
||||
"cy:run": "cypress run",
|
||||
"test:server": "blitz db migrate && blitz db seed && blitz start --production -p 3099",
|
||||
"test": "./assert-tree-shaking-works.js && start-server-and-test test:server http://localhost:3099 cy:run"
|
||||
"test:server": "blitz db migrate && blitz db seed && blitz build && blitz start --production -p 3099",
|
||||
"test": "cross-env NODE_ENV=test start-server-and-test test:server http://localhost:3099 cy:run",
|
||||
"posttest": "node assert-tree-shaking-works.js"
|
||||
},
|
||||
"prisma": {
|
||||
"schema": "db/schema.prisma"
|
||||
@@ -21,19 +22,19 @@
|
||||
"dependencies": {
|
||||
"@prisma/cli": "2.12.0",
|
||||
"@prisma/client": "2.12.0",
|
||||
"blitz": "0.27.0-canary.1",
|
||||
"final-form": "4.19.1",
|
||||
"react": "0.0.0-experimental-4ead6b530",
|
||||
"react-dom": "0.0.0-experimental-4ead6b530",
|
||||
"react-error-boundary": "2.3.1",
|
||||
"react-final-form": "6.4.0",
|
||||
"typescript": "3.8.3"
|
||||
"blitz": "0.28.0-canary.1",
|
||||
"final-form": "4.20.1",
|
||||
"react": "0.0.0-experimental-3310209d0",
|
||||
"react-dom": "0.0.0-experimental-3310209d0",
|
||||
"react-error-boundary": "3.1.0",
|
||||
"react-final-form": "6.5.2",
|
||||
"typescript": "4.1.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "16.9.34",
|
||||
"cypress": "4.11.0",
|
||||
"eslint-plugin-cypress": "2.10.3",
|
||||
"sass": "1.29.0",
|
||||
"start-server-and-test": "1.11.2"
|
||||
"@types/react": "17.0.0",
|
||||
"cypress": "6.2.0",
|
||||
"eslint-plugin-cypress": "2.11.2",
|
||||
"sass": "1.32.0",
|
||||
"start-server-and-test": "1.11.7"
|
||||
}
|
||||
}
|
||||
|
||||
8
examples/store/types.d.ts
vendored
Normal file
8
examples/store/types.d.ts
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
declare module "*.scss" {
|
||||
const content: {[className: string]: string}
|
||||
export default content
|
||||
}
|
||||
declare module "*.css" {
|
||||
const content: {[className: string]: string}
|
||||
export default content
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"packages": ["packages/*"],
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
|
||||
123
package.json
123
package.json
@@ -13,7 +13,7 @@
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 10.13.0"
|
||||
"node": ">=12.20.0"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "npm rebuild husky && patch-package",
|
||||
@@ -39,105 +39,106 @@
|
||||
"publish-danger": "lerna publish --canary --pre-dist-tag danger --preid danger.$(git rev-parse --short HEAD) --allow-branch * --force-publish",
|
||||
"danger:push-all": "git push --no-verify && git push --no-verify --tags"
|
||||
},
|
||||
"resolutions": {},
|
||||
"devDependencies": {
|
||||
"@rollup/pluginutils": "3.0.8",
|
||||
"@testing-library/jest-dom": "5.5.0",
|
||||
"@testing-library/react": "10.0.3",
|
||||
"@testing-library/react-hooks": "3.3.0",
|
||||
"@rollup/pluginutils": "4.1.0",
|
||||
"@testing-library/jest-dom": "5.11.8",
|
||||
"@testing-library/react": "11.2.2",
|
||||
"@testing-library/react-hooks": "3.7.0",
|
||||
"@types/b64-lite": "1.3.0",
|
||||
"@types/cookie": "0.4.0",
|
||||
"@types/cookie-session": "2.0.41",
|
||||
"@types/cookie-session": "2.0.42",
|
||||
"@types/cross-spawn": "6.0.2",
|
||||
"@types/debug": "4.1.5",
|
||||
"@types/detect-port": "1.3.0",
|
||||
"@types/diff": "4.0.2",
|
||||
"@types/dotenv-flow": "3.0.1",
|
||||
"@types/diff": "5.0.0",
|
||||
"@types/dotenv-flow": "3.1.0",
|
||||
"@types/flush-write-stream": "1.0.0",
|
||||
"@types/from2": "2.3.0",
|
||||
"@types/fs-extra": "8.1.0",
|
||||
"@types/fs-extra": "9.0.6",
|
||||
"@types/fs-readdir-recursive": "1.0.0",
|
||||
"@types/gulp-if": "0.0.33",
|
||||
"@types/ink-spinner": "3.0.0",
|
||||
"@types/jest": "25.1.3",
|
||||
"@types/jest": "26.0.19",
|
||||
"@types/jsonwebtoken": "8.5.0",
|
||||
"@types/lodash": "4.14.150",
|
||||
"@types/lodash": "4.14.166",
|
||||
"@types/mem-fs": "1.1.2",
|
||||
"@types/mem-fs-editor": "5.1.1",
|
||||
"@types/mem-fs-editor": "7.0.0",
|
||||
"@types/merge-stream": "1.1.2",
|
||||
"@types/mock-fs": "4.10.0",
|
||||
"@types/node": "13.13.2",
|
||||
"@types/mock-fs": "4.13.0",
|
||||
"@types/node": "14.14.17",
|
||||
"@types/node-fetch": "2.5.7",
|
||||
"@types/parallel-transform": "1.1.0",
|
||||
"@types/passport": "1.0.4",
|
||||
"@types/passport": "1.0.5",
|
||||
"@types/pluralize": "0.0.29",
|
||||
"@types/prettier": "2.0.0",
|
||||
"@types/prettier": "2.1.6",
|
||||
"@types/pump": "1.1.0",
|
||||
"@types/pumpify": "1.4.1",
|
||||
"@types/react": "16.9.34",
|
||||
"@types/readable-stream": "2.3.5",
|
||||
"@types/react": "17.0.0",
|
||||
"@types/react-dom": "17.0.0",
|
||||
"@types/readable-stream": "2.3.9",
|
||||
"@types/rimraf": "3.0.0",
|
||||
"@types/tar": "4.0.3",
|
||||
"@types/tar": "4.0.4",
|
||||
"@types/test-listen": "1.1.0",
|
||||
"@types/through2": "2.0.34",
|
||||
"@types/through2": "2.0.36",
|
||||
"@types/vinyl": "2.0.4",
|
||||
"@types/vinyl-fs": "2.4.11",
|
||||
"@types/webpack": "4.41.13",
|
||||
"@typescript-eslint/eslint-plugin": "4.3.1-alpha.1",
|
||||
"@typescript-eslint/parser": "4.3.1-alpha.1",
|
||||
"@types/webpack": "4.41.25",
|
||||
"@typescript-eslint/eslint-plugin": "4.11.1",
|
||||
"@typescript-eslint/parser": "4.11.1",
|
||||
"@wessberg/cjs-to-esm-transformer": "0.0.22",
|
||||
"@wessberg/rollup-plugin-ts": "1.3.3",
|
||||
"@wessberg/rollup-plugin-ts": "1.3.8",
|
||||
"babel-eslint": "10.x",
|
||||
"babel-jest": "26.3.0",
|
||||
"babel-jest": "26.6.3",
|
||||
"concurrently": "5.3.0",
|
||||
"cpy-cli": "3.1.1",
|
||||
"cross-env": "7.0.2",
|
||||
"debug": "4.1.1",
|
||||
"yalc": "1.0.0-pre.47",
|
||||
"delay": "4.3.0",
|
||||
"directory-tree": "2.2.4",
|
||||
"eslint": "7.7.0",
|
||||
"eslint-config-react-app": "5.2.1",
|
||||
"eslint-plugin-es": "mysticatea/eslint-plugin-es",
|
||||
"cross-env": "7.0.3",
|
||||
"debug": "4.3.1",
|
||||
"delay": "4.4.0",
|
||||
"directory-tree": "2.2.5",
|
||||
"eslint": "7.16.0",
|
||||
"eslint-config-react-app": "6.0.0",
|
||||
"eslint-plugin-es": "4.1.0",
|
||||
"eslint-plugin-es5": "1.5.0",
|
||||
"eslint-plugin-flowtype": "5.2.0",
|
||||
"eslint-plugin-import": "2.22.0",
|
||||
"eslint-plugin-jsx-a11y": "6.3.1",
|
||||
"eslint-plugin-prettier": "3.1.4",
|
||||
"eslint-plugin-react": "7.20.6",
|
||||
"eslint-plugin-react-hooks": "4.1.0",
|
||||
"eslint-plugin-simple-import-sort": "5.0.3",
|
||||
"eslint-plugin-unicorn": "21.0.0",
|
||||
"husky": "4.2.5",
|
||||
"isomorphic-unfetch": "3.0.0",
|
||||
"jest": "24.9.0",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eslint-plugin-jsx-a11y": "6.4.1",
|
||||
"eslint-plugin-prettier": "3.3.0",
|
||||
"eslint-plugin-react": "7.22.0",
|
||||
"eslint-plugin-react-hooks": "4.2.0",
|
||||
"eslint-plugin-simple-import-sort": "7.0.0",
|
||||
"eslint-plugin-unicorn": "25.0.1",
|
||||
"husky": "4.3.6",
|
||||
"jest": "26.6.3",
|
||||
"jest-environment-jsdom-sixteen": "1.0.3",
|
||||
"lerna": "3.22.1",
|
||||
"lint-staged": "10.2.13",
|
||||
"lint-staged": "10.5.3",
|
||||
"mock-fs": "4.13.0",
|
||||
"nock": "12.0.3",
|
||||
"nock": "13.0.5",
|
||||
"npm-run-all": "4.1.5",
|
||||
"patch-package": "6.2.2",
|
||||
"postinstall-postinstall": "2.1.0",
|
||||
"prettier": "2.1.1",
|
||||
"pretty-quick": "2.0.1",
|
||||
"prompt": "1.0.0",
|
||||
"react-test-renderer": "16.13.1",
|
||||
"release": "6.1.0",
|
||||
"prettier": "2.2.1",
|
||||
"pretty-quick": "3.1.0",
|
||||
"prompt": "1.1.0",
|
||||
"react-test-renderer": "17.0.1",
|
||||
"release": "6.3.0",
|
||||
"rimraf": "3.0.2",
|
||||
"rollup": "2.26.8",
|
||||
"rollup": "2.35.1",
|
||||
"rollup-plugin-commonjs": "10.1.0",
|
||||
"rollup-plugin-json": "4.0.0",
|
||||
"rollup-plugin-node-polyfills": "0.2.1",
|
||||
"rollup-plugin-node-resolve": "5.2.0",
|
||||
"rollup-plugin-peer-deps-external": "2.2.3",
|
||||
"semver": "7.3.2",
|
||||
"rollup-plugin-peer-deps-external": "2.2.4",
|
||||
"semver": "7.3.4",
|
||||
"stdout-stderr": "0.1.13",
|
||||
"test-listen": "1.1.0",
|
||||
"ts-jest": "24.3.0",
|
||||
"tsdx": "0.13.3",
|
||||
"tslib": "1.11.1",
|
||||
"typescript": "4.0.3",
|
||||
"wait-on": "4.0.2"
|
||||
"ts-jest": "26.4.4",
|
||||
"tsdx": "0.14.1",
|
||||
"tslib": "2.0.3",
|
||||
"typescript": "4.1.3",
|
||||
"wait-on": "5.2.1",
|
||||
"yalc": "1.0.0-pre.49"
|
||||
},
|
||||
"husky": {
|
||||
"hooks": {
|
||||
@@ -151,11 +152,5 @@
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"resolutions": {
|
||||
"jest": "24.9.0",
|
||||
"@types/react": "16.9.34",
|
||||
"@types/react-dom": "16.9.8",
|
||||
"ts-jest": "24.3.0"
|
||||
},
|
||||
"version": "0.0.0"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "blitz",
|
||||
"description": "Blitz is a Rails-like framework for monolithic, full-stack React apps — built on Next.js",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
@@ -40,16 +40,16 @@
|
||||
"url": "https://github.com/blitz-js/blitz"
|
||||
},
|
||||
"dependencies": {
|
||||
"@blitzjs/cli": "0.27.0-canary.1",
|
||||
"@blitzjs/config": "0.27.0-canary.1",
|
||||
"@blitzjs/core": "0.27.0-canary.1",
|
||||
"@blitzjs/display": "0.27.0-canary.1",
|
||||
"@blitzjs/generator": "0.27.0-canary.1",
|
||||
"@blitzjs/installer": "0.27.0-canary.1",
|
||||
"@blitzjs/server": "0.27.0-canary.1",
|
||||
"envinfo": "7.7.2",
|
||||
"os-name": "3.1.0",
|
||||
"pkg-dir": "4.2.0",
|
||||
"@blitzjs/cli": "0.28.0-canary.1",
|
||||
"@blitzjs/config": "0.28.0-canary.1",
|
||||
"@blitzjs/core": "0.28.0-canary.1",
|
||||
"@blitzjs/display": "0.28.0-canary.1",
|
||||
"@blitzjs/generator": "0.28.0-canary.1",
|
||||
"@blitzjs/installer": "0.28.0-canary.1",
|
||||
"@blitzjs/server": "0.28.0-canary.1",
|
||||
"envinfo": "7.7.3",
|
||||
"os-name": "4.0.0",
|
||||
"pkg-dir": "5.0.0",
|
||||
"resolve-from": "5.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
|
||||
@@ -10,7 +10,7 @@ async function main() {
|
||||
if (options._[0] !== "autocomplete:script" || Object.keys(options).length > 1) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
`You are using alpha software - if you have any problems, please open an issue here:
|
||||
`You are using beta software - if you have any problems, please open an issue here:
|
||||
https://github.com/blitz-js/blitz/issues/new/choose\n`,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@blitzjs/cli",
|
||||
"description": "Blitz.js CLI",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"b": "./bin/run",
|
||||
@@ -30,42 +30,42 @@
|
||||
"/lib"
|
||||
],
|
||||
"dependencies": {
|
||||
"@blitzjs/display": "0.27.0-canary.1",
|
||||
"@blitzjs/repl": "0.27.0-canary.1",
|
||||
"@oclif/command": "1.5.20",
|
||||
"@oclif/config": "1.15.1",
|
||||
"@oclif/plugin-autocomplete": "0.2.0",
|
||||
"@oclif/plugin-help": "2.2.3",
|
||||
"@oclif/plugin-not-found": "1.2.3",
|
||||
"@blitzjs/display": "0.28.0-canary.1",
|
||||
"@blitzjs/repl": "0.28.0-canary.1",
|
||||
"@oclif/command": "1.8.0",
|
||||
"@oclif/config": "1.17.0",
|
||||
"@oclif/plugin-autocomplete": "0.3.0",
|
||||
"@oclif/plugin-help": "3.2.1",
|
||||
"@oclif/plugin-not-found": "1.2.4",
|
||||
"@prisma/sdk": "2.12.0",
|
||||
"@salesforce/lazy-require": "0.3.2",
|
||||
"camelcase": "6.0.0",
|
||||
"chalk": "4.0.0",
|
||||
"@salesforce/lazy-require": "0.3.3",
|
||||
"camelcase": "6.2.0",
|
||||
"chalk": "4.1.0",
|
||||
"cross-spawn": "7.0.3",
|
||||
"dotenv-expand": "5.1.0",
|
||||
"dotenv-flow": "3.2.0",
|
||||
"enquirer": "2.3.4",
|
||||
"got": "11.1.3",
|
||||
"enquirer": "2.3.6",
|
||||
"got": "11.8.1",
|
||||
"has-yarn": "2.1.0",
|
||||
"hasbin": "1.2.3",
|
||||
"minimist": "1.2.5",
|
||||
"p-event": "4.2.0",
|
||||
"pkg-dir": "4.2.0",
|
||||
"pkg-dir": "5.0.0",
|
||||
"pluralize": "8.0.0",
|
||||
"rimraf": "3.0.2",
|
||||
"tar": "6.0.2",
|
||||
"ts-node": "8.9.0",
|
||||
"tar": "6.0.5",
|
||||
"ts-node": "9.1.1",
|
||||
"tsconfig-paths": "3.9.0",
|
||||
"v8-compile-cache": "2.1.1"
|
||||
"v8-compile-cache": "2.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blitzjs/generator": "0.27.0-canary.1",
|
||||
"@blitzjs/installer": "0.27.0-canary.1",
|
||||
"@blitzjs/server": "0.27.0-canary.1",
|
||||
"@oclif/dev-cli": "1.22.2",
|
||||
"@oclif/test": "1.2.5",
|
||||
"@blitzjs/generator": "0.28.0-canary.1",
|
||||
"@blitzjs/installer": "0.28.0-canary.1",
|
||||
"@blitzjs/server": "0.28.0-canary.1",
|
||||
"@oclif/dev-cli": "1.26.0",
|
||||
"@oclif/test": "1.2.8",
|
||||
"@prisma/cli": "2.12.0",
|
||||
"nock": "13.0.0-beta.3",
|
||||
"nock": "13.0.5",
|
||||
"stdout-stderr": "0.1.13"
|
||||
},
|
||||
"jest": {
|
||||
|
||||
@@ -9,10 +9,8 @@ const runPrisma = async (args: string[], silent = false) => {
|
||||
if (!prismaBin) {
|
||||
try {
|
||||
prismaBin = await getPrismaBin()
|
||||
} catch {
|
||||
throw new Error(
|
||||
"Oops, we can't find Prisma Client. Please make sure it's installed in your project",
|
||||
)
|
||||
} catch (err) {
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
76
packages/cli/src/commands/routes.ts
Normal file
76
packages/cli/src/commands/routes.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import {Command, flags} from "@oclif/command"
|
||||
import {ServerConfig} from "@blitzjs/server"
|
||||
import {log, table as Table} from "@blitzjs/display"
|
||||
|
||||
export class Routes extends Command {
|
||||
static description = "Display all Blitz URL Routes"
|
||||
static aliases = ["r"]
|
||||
|
||||
static flags = {
|
||||
help: flags.help({char: "h"}),
|
||||
}
|
||||
|
||||
getColor(type: string) {
|
||||
switch (type) {
|
||||
case "rpc":
|
||||
return "magenta"
|
||||
case "api":
|
||||
return "blue"
|
||||
default:
|
||||
return "green"
|
||||
}
|
||||
}
|
||||
|
||||
async run() {
|
||||
const config: ServerConfig = {
|
||||
rootFolder: process.cwd(),
|
||||
}
|
||||
this.parse(Routes)
|
||||
|
||||
try {
|
||||
const {routes} = await import("@blitzjs/server")
|
||||
const routesResult = await routes(config)
|
||||
log.newline()
|
||||
const table = new Table({
|
||||
columns: [
|
||||
{name: "HTTP", alignment: "center"},
|
||||
{name: "Source File", alignment: "left"},
|
||||
{name: "URI", alignment: "left"},
|
||||
{name: "Type", alignment: "center"},
|
||||
],
|
||||
sort: (q, r) => {
|
||||
// Sort pages to the top
|
||||
if (q.Type === "PAGE" && r.Type !== "PAGE") {
|
||||
return -1
|
||||
}
|
||||
if (q.Type !== "PAGE" && r.Type === "PAGE") {
|
||||
return 1
|
||||
}
|
||||
|
||||
if (q.Type > r.Type) {
|
||||
return 1
|
||||
}
|
||||
if (q.Type < r.Type) {
|
||||
return -1
|
||||
}
|
||||
return 0
|
||||
},
|
||||
})
|
||||
routesResult.forEach(({path, uri, verb, type}: any) => {
|
||||
table.addRow(
|
||||
{
|
||||
[table.table.columns[0].name]: verb.toUpperCase(),
|
||||
[table.table.columns[1].name]: path,
|
||||
[table.table.columns[2].name]: uri,
|
||||
[table.table.columns[3].name]: type.toUpperCase(),
|
||||
},
|
||||
{color: this.getColor(type)},
|
||||
)
|
||||
})
|
||||
console.log(table.render())
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import fetch from "node-fetch"
|
||||
import nock from "nock"
|
||||
import rimraf from "rimraf"
|
||||
import {stdout} from "stdout-stderr"
|
||||
import pkgDir from "pkg-dir"
|
||||
|
||||
jest.setTimeout(120 * 1000)
|
||||
const blitzCliPackageJson = require("../../package.json")
|
||||
@@ -34,6 +35,15 @@ jest.mock("enquirer", () => {
|
||||
})
|
||||
})
|
||||
|
||||
const tempDir = path.join(__dirname, ".test")
|
||||
|
||||
beforeEach(() => {
|
||||
fs.mkdirSync(tempDir)
|
||||
})
|
||||
afterEach(() => {
|
||||
rimraf.sync(tempDir)
|
||||
})
|
||||
|
||||
describe("`new` command", () => {
|
||||
describe("when scaffolding new project", () => {
|
||||
beforeEach(() => {
|
||||
@@ -45,7 +55,7 @@ describe("`new` command", () => {
|
||||
stdout.stop()
|
||||
})
|
||||
|
||||
jest.setTimeout(120 * 1000)
|
||||
jest.setTimeout(200 * 1000)
|
||||
|
||||
function makeTempDir() {
|
||||
const tmpDirPath = path.join(os.tmpdir(), "blitzjs-test-")
|
||||
@@ -112,11 +122,24 @@ describe("`new` command", () => {
|
||||
)
|
||||
|
||||
testIfNotWindows("performs all steps on a full install", async () => {
|
||||
const tempDir = makeTempDir()
|
||||
await whileStayingInCWD(() => New.run([tempDir]))
|
||||
rimraf.sync(tempDir)
|
||||
const currentBlitzWorkspaceVersion = require(path.join(
|
||||
await pkgDir(__dirname),
|
||||
"package.json",
|
||||
)).version
|
||||
|
||||
expect(getStepsFromOutput()).toStrictEqual([`cd ${tempDir}`, "blitz start"])
|
||||
jest.mock("@blitzjs/generator/src/utils/get-blitz-dependency-version", () => {
|
||||
return jest.fn().mockImplementation(() => {
|
||||
return {
|
||||
value: currentBlitzWorkspaceVersion,
|
||||
fallback: false,
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const newAppDir = fs.mkdtempSync(path.join(tempDir, "full-install-"))
|
||||
await whileStayingInCWD(() => New.run([newAppDir, "--skip-upgrade"]))
|
||||
|
||||
expect(getStepsFromOutput()).toStrictEqual([`cd ${newAppDir}`, "blitz start"])
|
||||
})
|
||||
|
||||
it("fetches latest version from template", async () => {
|
||||
|
||||
17
packages/cli/test/commands/routes.test.ts
Normal file
17
packages/cli/test/commands/routes.test.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import {Routes} from "../../src/commands/routes"
|
||||
|
||||
const routes = jest.fn(() => {
|
||||
return []
|
||||
})
|
||||
jest.mock("@blitzjs/server", () => ({routes}))
|
||||
|
||||
describe("Routes command", () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
it("runs the routes script", async () => {
|
||||
await Routes.run([])
|
||||
expect(routes).toBeCalled()
|
||||
})
|
||||
})
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@blitzjs/config",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"description": "Loads the blitz app config",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,17 +1,26 @@
|
||||
import {existsSync} from "fs"
|
||||
import {PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_SERVER} from "next/constants"
|
||||
import {join} from "path"
|
||||
import pkgDir from "pkg-dir"
|
||||
|
||||
const configFiles = ["blitz.config.js", "next.config.js"]
|
||||
|
||||
export interface BlitzConfig extends Record<string, unknown> {
|
||||
target?: string
|
||||
experimental?: {
|
||||
isomorphicResolverImports?: boolean
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {boolean | undefined} reload - reimport config files to reset global cache
|
||||
*/
|
||||
export const getConfig = (reload?: boolean): Record<string, unknown> => {
|
||||
export const getConfig = (reload?: boolean): BlitzConfig => {
|
||||
if (global.blitzConfig && Object.keys(global.blitzConfig).length > 0 && !reload) {
|
||||
return global.blitzConfig
|
||||
}
|
||||
|
||||
const {PHASE_DEVELOPMENT_SERVER, PHASE_PRODUCTION_SERVER} = require("next/constants")
|
||||
|
||||
let blitzConfig = {}
|
||||
const projectRoot = pkgDir.sync() || process.cwd()
|
||||
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
{
|
||||
"name": "@blitzjs/core",
|
||||
"description": "Blitz.js core functionality",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"clean": "rimraf dist",
|
||||
"wait:display": "wait-on ../display/dist/packages/display/src/index.d.ts",
|
||||
"predev": "yarn wait:display",
|
||||
"dev": "tsdx watch --verbose",
|
||||
"prebuild": "yarn predev",
|
||||
"build": "tsdx build",
|
||||
"test": "tsdx test --env=jest-environment-jsdom-sixteen",
|
||||
"test:watch": "tsdx test --watch --env=jest-environment-jsdom-sixteen"
|
||||
@@ -41,17 +40,15 @@
|
||||
"url": "https://github.com/blitz-js/blitz"
|
||||
},
|
||||
"dependencies": {
|
||||
"@blitzjs/display": "0.28.0-canary.1",
|
||||
"b64-lite": "1.4.0",
|
||||
"bad-behavior": "1.0.1",
|
||||
"cookie-session": "1.4.0",
|
||||
"deepmerge": "4.2.2",
|
||||
"lodash": "^4.17.19",
|
||||
"lodash-es": "^4.17.15",
|
||||
"lodash": "^4.17.20",
|
||||
"lodash-es": "^4.17.20",
|
||||
"passport": "0.4.1",
|
||||
"pretty-ms": "6.0.1",
|
||||
"react-query": "2.5.12",
|
||||
"superjson": "1.3.0",
|
||||
"url": "0.11.0"
|
||||
"superjson": "1.4.1"
|
||||
},
|
||||
"gitHead": "d3b9fce0bdd251c2b1890793b0aa1cd77c1c0922"
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ export {passportAuth} from "./passport-adapter"
|
||||
export {getIsomorphicEnhancedResolver} from "./rpc"
|
||||
export {useMutation} from "./use-mutation"
|
||||
export {invoke, invokeWithMiddleware} from "./invoke"
|
||||
|
||||
export {
|
||||
getAllMiddlewareForModule,
|
||||
handleRequestWithMiddleware,
|
||||
@@ -44,11 +45,11 @@ export {
|
||||
|
||||
export {default as Head} from "next/head"
|
||||
|
||||
export {default as Link} from "next/link"
|
||||
export {default as Link, LinkProps} from "next/link"
|
||||
|
||||
export {default as Router} from "next/router"
|
||||
|
||||
export {default as Image} from "next/image"
|
||||
export {default as Image, ImageProps} from "next/image"
|
||||
|
||||
export {
|
||||
default as Document,
|
||||
@@ -62,7 +63,7 @@ export {
|
||||
|
||||
export {default as dynamic} from "next/dynamic"
|
||||
|
||||
export {default as ErrorComponent} from "next/error"
|
||||
export {default as ErrorComponent, ErrorProps} from "next/error"
|
||||
|
||||
export {default as getConfig} from "next/config"
|
||||
|
||||
@@ -77,3 +78,4 @@ export type BlitzPage<P = {}, IP = P> = NextPage<P, IP> & {
|
||||
getLayout?: (component: JSX.Element) => JSX.Element
|
||||
}
|
||||
export {isLocalhost} from "./utils/index"
|
||||
export {prettyMs} from "./utils/pretty-ms"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import delay from "delay"
|
||||
import http, {IncomingMessage, ServerResponse} from "http"
|
||||
import fetch from "isomorphic-unfetch"
|
||||
import fetch from "node-fetch"
|
||||
import listen from "test-listen"
|
||||
import {invokeWithMiddleware} from "./invoke"
|
||||
import {EnhancedResolver} from "./types"
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {baseLogger, chalk, log as displayLog} from "@blitzjs/display"
|
||||
import prettyMs from "pretty-ms"
|
||||
import {getAllMiddlewareForModule, handleRequestWithMiddleware} from "./middleware"
|
||||
import {
|
||||
EnhancedResolver,
|
||||
@@ -12,6 +11,7 @@ import {
|
||||
Resolver,
|
||||
} from "./types"
|
||||
import {isClient} from "./utils"
|
||||
import {prettyMs} from "./utils/pretty-ms"
|
||||
|
||||
export function invoke<T extends QueryFn, TInput = FirstParam<T>, TResult = PromiseReturnType<T>>(
|
||||
queryFn: T,
|
||||
@@ -56,12 +56,12 @@ export async function invokeWithMiddleware<TInput, TResult>(
|
||||
displayLog.newline()
|
||||
try {
|
||||
log.info(chalk.dim("Starting with input:"), params)
|
||||
const startTime = new Date().getTime()
|
||||
const startTime = Date.now()
|
||||
|
||||
const result = await enhancedResolver(params, res.blitzCtx)
|
||||
|
||||
const duration = prettyMs(new Date().getTime() - startTime)
|
||||
log.info(chalk.dim("Finished", "in", duration))
|
||||
const duration = Date.now() - startTime
|
||||
log.info(chalk.dim(`Finished in ${prettyMs(duration)}`))
|
||||
displayLog.newline()
|
||||
|
||||
res.blitzResult = result
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import http from "http"
|
||||
import fetch from "isomorphic-unfetch"
|
||||
import {apiResolver} from "next/dist/next-server/server/api-utils"
|
||||
import fetch from "node-fetch"
|
||||
import listen from "test-listen"
|
||||
import {BlitzApiRequest, BlitzApiResponse} from "."
|
||||
import {handleRequestWithMiddleware} from "./middleware"
|
||||
@@ -65,7 +65,6 @@ describe("handleRequestWithMiddleware", () => {
|
||||
})
|
||||
})
|
||||
|
||||
// Failing on windows for unknown reason
|
||||
it("middleware can throw", async () => {
|
||||
console.log = jest.fn()
|
||||
console.error = jest.fn()
|
||||
@@ -106,7 +105,7 @@ describe("handleRequestWithMiddleware", () => {
|
||||
async function mockServer(middleware: Middleware[], callback: (url: string) => Promise<void>) {
|
||||
const apiEndpoint = async (req: BlitzApiRequest, res: BlitzApiResponse) => {
|
||||
try {
|
||||
await handleRequestWithMiddleware(req, res, middleware)
|
||||
await handleRequestWithMiddleware(req, res, middleware, {stackPrintOnError: false})
|
||||
} catch (err) {
|
||||
res.status(500)
|
||||
} finally {
|
||||
|
||||
@@ -39,7 +39,13 @@ export async function handleRequestWithMiddleware(
|
||||
req: BlitzApiRequest | IncomingMessage,
|
||||
res: BlitzApiResponse | ServerResponse,
|
||||
middleware: Middleware | Middleware[],
|
||||
{throwOnError = true}: {throwOnError?: boolean} = {},
|
||||
{
|
||||
throwOnError = true,
|
||||
stackPrintOnError = true,
|
||||
}: {
|
||||
throwOnError?: boolean
|
||||
stackPrintOnError?: boolean
|
||||
} = {},
|
||||
) {
|
||||
if (!(res as MiddlewareResponse).blitzCtx) {
|
||||
;(res as MiddlewareResponse).blitzCtx = {}
|
||||
@@ -78,7 +84,11 @@ export async function handleRequestWithMiddleware(
|
||||
if (error._clearStack) {
|
||||
delete error.stack
|
||||
}
|
||||
baseLogger().prettyError(error)
|
||||
if (stackPrintOnError) {
|
||||
baseLogger().prettyError(error)
|
||||
} else {
|
||||
baseLogger().prettyError(error, true, false, false)
|
||||
}
|
||||
log.newline()
|
||||
if (throwOnError) throw error
|
||||
}
|
||||
|
||||
@@ -51,13 +51,18 @@ export function passportAuth(config: BlitzPassportConfig) {
|
||||
"No Passport strategies found! Please add at least one strategy.",
|
||||
)
|
||||
|
||||
const strategy = config.strategies.find((strategy) => strategy.name === req.query.auth[0])
|
||||
assert(strategy, `A passport strategy was not found for: ${req.query.auth[0]}`)
|
||||
const blitzStrategy = config.strategies.find(
|
||||
({strategy}) => strategy.name === req.query.auth[0],
|
||||
)
|
||||
assert(blitzStrategy, `A passport strategy was not found for: ${req.query.auth[0]}`)
|
||||
|
||||
const {strategy, authenticateOptions} = blitzStrategy
|
||||
|
||||
passport.use(strategy)
|
||||
const strategyName = strategy.name as string
|
||||
|
||||
if (req.query.auth.length === 1) {
|
||||
log.info(`Starting authentication via ${strategy.name}...`)
|
||||
log.info(`Starting authentication via ${strategyName}...`)
|
||||
if (req.query.redirectUrl) {
|
||||
middleware.push(async (req, res, next) => {
|
||||
const session = res.blitzCtx.session as SessionContext
|
||||
@@ -67,33 +72,33 @@ export function passportAuth(config: BlitzPassportConfig) {
|
||||
})
|
||||
}
|
||||
middleware.push(
|
||||
connectMiddleware(passport.authenticate(strategy.name, {...config.authenticateOptions})),
|
||||
connectMiddleware(passport.authenticate(strategyName, {...authenticateOptions})),
|
||||
)
|
||||
} else if (req.query.auth[1] === "callback") {
|
||||
log.info(`Processing callback for ${strategy.name}...`)
|
||||
log.info(`Processing callback for ${strategyName}...`)
|
||||
middleware.push(
|
||||
connectMiddleware((req, res, next) => {
|
||||
const session = (res as any).blitzCtx.session as SessionContext
|
||||
assert(session, "Missing Blitz sessionMiddleware!")
|
||||
|
||||
passport.authenticate(strategy.name, async (err: any, result: unknown) => {
|
||||
passport.authenticate(strategyName, async (err: any, result: unknown) => {
|
||||
try {
|
||||
let error = err
|
||||
|
||||
if (!error) {
|
||||
if (result === false) {
|
||||
log.warning(
|
||||
`Login via ${strategy.name} failed - usually this means the user did not authenticate properly with the provider`,
|
||||
`Login via ${strategyName} failed - usually this means the user did not authenticate properly with the provider`,
|
||||
)
|
||||
error = `Login failed`
|
||||
}
|
||||
assert(
|
||||
typeof result === "object" && result !== null,
|
||||
`Your '${strategy.name}' passport verify callback returned empty data. Ensure you call 'done(null, {publicData: {userId: 1, roles: ['myRole']}})')`,
|
||||
`Your '${strategyName}' passport verify callback returned empty data. Ensure you call 'done(null, {publicData: {userId: 1, roles: ['myRole']}})')`,
|
||||
)
|
||||
assert(
|
||||
(result as any).publicData,
|
||||
`'publicData' is missing from your '${strategy.name}' passport verify callback. Ensure you call 'done(null, {publicData: {userId: 1, roles: ['myRole']}})')`,
|
||||
`'publicData' is missing from your '${strategyName}' passport verify callback. Ensure you call 'done(null, {publicData: {userId: 1, roles: ['myRole']}})')`,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ export type SessionConfig = {
|
||||
createSession: (session: SessionModel) => Promise<SessionModel>
|
||||
updateSession: (handle: string, session: Partial<SessionModel>) => Promise<SessionModel>
|
||||
deleteSession: (handle: string) => Promise<SessionModel>
|
||||
unstable_isAuthorized: (userRoles: string[], input?: any) => boolean
|
||||
isAuthorized: (userRoles: string[], input?: any) => boolean
|
||||
}
|
||||
|
||||
export interface SessionContextBase {
|
||||
|
||||
@@ -81,11 +81,15 @@ export type ConnectMiddleware = (
|
||||
next: (error?: Error) => void,
|
||||
) => void
|
||||
|
||||
export type BlitzPassportStrategy = {
|
||||
authenticateOptions?: AuthenticateOptions
|
||||
strategy: Strategy
|
||||
}
|
||||
|
||||
export type BlitzPassportConfig = {
|
||||
successRedirectUrl?: string
|
||||
errorRedirectUrl?: string
|
||||
authenticateOptions?: AuthenticateOptions
|
||||
strategies: Required<Strategy>[]
|
||||
strategies: BlitzPassportStrategy[]
|
||||
secureProxy?: boolean
|
||||
}
|
||||
|
||||
|
||||
20
packages/core/src/utils/pretty-ms.test.ts
Normal file
20
packages/core/src/utils/pretty-ms.test.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import {prettyMs} from "./pretty-ms"
|
||||
|
||||
describe("prettyMs", () => {
|
||||
it("returns pretty strings", () => {
|
||||
// ms
|
||||
expect(prettyMs(0)).toMatchInlineSnapshot(`"0ms"`)
|
||||
expect(prettyMs(200)).toMatchInlineSnapshot(`"200ms"`)
|
||||
|
||||
// seconds
|
||||
expect(prettyMs(1000)).toMatchInlineSnapshot(`"1s"`)
|
||||
expect(prettyMs(1000)).toMatchInlineSnapshot(`"1s"`)
|
||||
expect(prettyMs(1600)).toMatchInlineSnapshot(`"1.6s"`)
|
||||
expect(prettyMs(1500)).toMatchInlineSnapshot(`"1.5s"`)
|
||||
expect(prettyMs(1666)).toMatchInlineSnapshot(`"1.7s"`)
|
||||
|
||||
// negative
|
||||
expect(prettyMs(-1)).toMatchInlineSnapshot(`"-1ms"`)
|
||||
expect(prettyMs(-2000)).toMatchInlineSnapshot(`"-2s"`)
|
||||
})
|
||||
})
|
||||
20
packages/core/src/utils/pretty-ms.ts
Normal file
20
packages/core/src/utils/pretty-ms.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
function round(num: number, decimalPlaces: number) {
|
||||
const p = Math.pow(10, decimalPlaces)
|
||||
const m = num * p * (1 + Number.EPSILON)
|
||||
return Math.round(m) / p
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats milliseconds to a string
|
||||
* If more than 1s, it'll return seconds instead
|
||||
* @example
|
||||
* prettyMs(100) // -> `100ms`
|
||||
* prettyMs(1200) // -> `1.2s`
|
||||
* @param ms
|
||||
*/
|
||||
export function prettyMs(ms: number): string {
|
||||
if (Math.abs(ms) >= 1000) {
|
||||
return `${round(ms / 1000, 1)}s`
|
||||
}
|
||||
return `${ms}ms`
|
||||
}
|
||||
@@ -50,7 +50,7 @@ export const validateQueryFn = <TInput, TResult>(
|
||||
) => {
|
||||
if (!isEnhancedResolverRpcClient(queryFn) && isNotInUserTestEnvironment()) {
|
||||
throw new Error(
|
||||
`It looks like you are trying to use Blitz's useQuery to fetch from third-party APIs. To do that, import useQuery directly from "react-query"`,
|
||||
`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 "react-query")`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`useMutation useMutation calls the resolver with the argument shouldn't work with regular functions 1`] = `"It looks like you are trying to use Blitz's useQuery to fetch from third-party APIs. To do that, import useQuery directly from \\"react-query\\""`;
|
||||
exports[`useMutation useMutation calls the resolver with the argument 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 \\"react-query\\")"`;
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`useQuery a "query" that converts the string parameter to uppercase shouldn't work with regular functions 1`] = `"It looks like you are trying to use Blitz's useQuery to fetch from third-party APIs. To do that, import useQuery directly from \\"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 \\"react-query\\")"`;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@blitzjs/display",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"description": "Display package for the Blitz CLI",
|
||||
"homepage": "https://github.com/blitz-js/blitz#readme",
|
||||
"license": "MIT",
|
||||
@@ -9,7 +9,6 @@
|
||||
"wait:config": "wait-on ../config/dist/packages/config/src/index.d.ts",
|
||||
"predev": "yarn wait:config",
|
||||
"dev": "tsdx watch --verbose",
|
||||
"prebuild": "yarn predev",
|
||||
"build": "tsdx build",
|
||||
"test": "tsdx test",
|
||||
"test:watch": "tsdx test --watch"
|
||||
@@ -34,8 +33,10 @@
|
||||
"url": "git+https://github.com/blitz-js/blitz.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "4.0.0",
|
||||
"ora": "4.0.4",
|
||||
"tslog": "2.9.1"
|
||||
"@blitzjs/display": "0.28.0-canary.1",
|
||||
"chalk": "4.1.0",
|
||||
"console-table-printer": "2.7.5",
|
||||
"ora": "5.2.0",
|
||||
"tslog": "3.0.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {getConfig} from "@blitzjs/config"
|
||||
import c from "chalk"
|
||||
import {Table} from "console-table-printer"
|
||||
import ora from "ora"
|
||||
import readline from "readline"
|
||||
import {Logger} from "tslog"
|
||||
@@ -23,6 +24,7 @@ const getLogConfig = (): LogConfig => {
|
||||
return defaultConfig
|
||||
}
|
||||
|
||||
export const table = Table
|
||||
export const chalk = c
|
||||
|
||||
// const blitzTrueBrandColor = '6700AB'
|
||||
@@ -220,4 +222,5 @@ export const log = {
|
||||
variable,
|
||||
info,
|
||||
debug,
|
||||
Table,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@blitzjs/file-pipeline",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"description": "Display package for the Blitz CLI",
|
||||
"homepage": "https://github.com/blitz-js/blitz#readme",
|
||||
"license": "MIT",
|
||||
@@ -8,7 +8,6 @@
|
||||
"wait:display": "wait-on ../display/dist/packages/display/src/index.d.ts",
|
||||
"predev": "yarn wait:display",
|
||||
"dev": "tsdx watch --verbose",
|
||||
"prebuild": "yarn predev",
|
||||
"build": "tsdx build",
|
||||
"test": "tsdx test",
|
||||
"test:watch": "tsdx test --watch"
|
||||
@@ -33,20 +32,19 @@
|
||||
"url": "git+https://github.com/blitz-js/blitz.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": "4.0.0",
|
||||
"chokidar": "3.4.2",
|
||||
"@blitzjs/display": "0.28.0-canary.1",
|
||||
"chalk": "4.1.0",
|
||||
"chokidar": "3.4.3",
|
||||
"flush-write-stream": "2.0.0",
|
||||
"from2": "2.3.0",
|
||||
"fs-extra": "9.0.0",
|
||||
"fs-extra": "9.0.1",
|
||||
"gulp-if": "3.0.0",
|
||||
"merge-stream": "2.0.0",
|
||||
"ora": "4.0.4",
|
||||
"parallel-transform": "1.2.0",
|
||||
"pump": "3.0.0",
|
||||
"pumpify": "2.0.1",
|
||||
"slash": "3.0.0",
|
||||
"through2": "3.0.1",
|
||||
"vinyl": "2.2.0",
|
||||
"through2": "4.0.2",
|
||||
"vinyl": "2.2.1",
|
||||
"vinyl-file": "3.0.0",
|
||||
"vinyl-fs": "3.0.3"
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import {through} from "./streams"
|
||||
export function createDisplay() {
|
||||
let lastEvent: Event<any> = {type: INIT, payload: null}
|
||||
|
||||
let spinner = log.spinner("Preparing for launch").start()
|
||||
let spinner = log.spinner("Compiling").start()
|
||||
|
||||
const stream = through({objectMode: true}, (event: Event<File>, _, next) => {
|
||||
switch (event.type) {
|
||||
@@ -30,7 +30,7 @@ export function createDisplay() {
|
||||
}
|
||||
|
||||
case READY: {
|
||||
spinner.succeed(chalk.green.bold("Prepped for launch"))
|
||||
spinner.succeed(chalk.green.bold("Compiled"))
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,16 @@ import {resolve} from "path"
|
||||
import {testStreamItems} from "../../test-utils"
|
||||
import {agnosticSource} from "."
|
||||
|
||||
const debug = require("debug")("blitz:test:agnostic-source")
|
||||
|
||||
const cwd = resolve(__dirname, "fixtures")
|
||||
|
||||
/**
|
||||
* FIXME temporarily disabled as the test is flaky on windows
|
||||
* @link https://github.com/blitz-js/blitz/pull/1635
|
||||
*/
|
||||
const testIfNotWindows = process.platform === "win32" ? test.skip : test
|
||||
|
||||
function logItem(fileOrString: {path: string} | string) {
|
||||
if (typeof fileOrString === "string") {
|
||||
return fileOrString
|
||||
@@ -13,17 +21,13 @@ function logItem(fileOrString: {path: string} | string) {
|
||||
}
|
||||
|
||||
describe("agnosticSource", () => {
|
||||
afterEach(() => {
|
||||
try {
|
||||
if (fs.existsSync(resolve(cwd, "three"))) {
|
||||
fs.unlinkSync(resolve(cwd, "three"))
|
||||
}
|
||||
} catch {
|
||||
// Ignore any errors like ENOENT: no such file or directory
|
||||
beforeEach(() => {
|
||||
if (fs.existsSync(resolve(cwd, "three"))) {
|
||||
fs.unlinkSync(resolve(cwd, "three"))
|
||||
}
|
||||
})
|
||||
|
||||
test("when watching = false", (done) => {
|
||||
testIfNotWindows("when watching = false", (done) => {
|
||||
const expected = [resolve(cwd, "one"), resolve(cwd, "two")]
|
||||
const {stream} = agnosticSource({ignore: [], include: ["**/*"], cwd, watch: false})
|
||||
const log: any[] = []
|
||||
@@ -37,7 +41,7 @@ describe("agnosticSource", () => {
|
||||
})
|
||||
})
|
||||
|
||||
test("when watching = true", async () => {
|
||||
testIfNotWindows("when watching = true", async () => {
|
||||
const expected = [resolve(cwd, "one"), resolve(cwd, "two"), "ready", resolve(cwd, "three")]
|
||||
const {stream, close} = agnosticSource({ignore: [], include: ["**/*"], cwd, watch: true})
|
||||
|
||||
@@ -51,23 +55,24 @@ describe("agnosticSource", () => {
|
||||
await close()
|
||||
})
|
||||
|
||||
test("include a folder that doesn't exist", (done) => {
|
||||
console.log("Starting test: include a folder doesn't exist")
|
||||
testIfNotWindows("include a folder that doesn't exist", (done) => {
|
||||
debug("Starting test: include a folder doesn't exist")
|
||||
const expected = [resolve(cwd, "one"), resolve(cwd, "two")]
|
||||
console.log("expected", expected)
|
||||
debug("expected", expected)
|
||||
const {stream} = agnosticSource({
|
||||
ignore: [],
|
||||
include: ["**/*", "folder-that-doesnt-exist/"],
|
||||
cwd,
|
||||
watch: false,
|
||||
})
|
||||
console.log("started stream")
|
||||
debug("started stream")
|
||||
const log: any[] = []
|
||||
stream.on("data", (data) => {
|
||||
debug("got data", data)
|
||||
if (data === "ready") {
|
||||
console.log("stream ready")
|
||||
debug("stream ready")
|
||||
stream.end()
|
||||
console.log("stream ended")
|
||||
debug("stream ended")
|
||||
expect(log).toEqual(expected)
|
||||
return done()
|
||||
}
|
||||
@@ -75,7 +80,7 @@ describe("agnosticSource", () => {
|
||||
})
|
||||
})
|
||||
|
||||
test("ignore a file", (done) => {
|
||||
testIfNotWindows("ignore a file", (done) => {
|
||||
const expected = [resolve(cwd, "one")]
|
||||
const {stream} = agnosticSource({ignore: ["two"], include: ["**/*"], cwd, watch: false})
|
||||
const log: any[] = []
|
||||
|
||||
118
packages/file-pipeline/src/helpers/route-cache.ts
Normal file
118
packages/file-pipeline/src/helpers/route-cache.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import path from "path"
|
||||
import File from "vinyl"
|
||||
import {RouteCacheEntry, RouteCacheInterface, RouteType, RouteVerb} from "../types"
|
||||
|
||||
export class RouteCache implements RouteCacheInterface {
|
||||
static singleton: RouteCache | null = null
|
||||
|
||||
routeCache: Record<string, RouteCacheEntry> = {}
|
||||
lengthOfHTTPErrorURI = 4
|
||||
|
||||
normalizePath(input: string) {
|
||||
if (path.sep === path.posix.sep) return input
|
||||
return input.split(path.sep).join(path.posix.sep)
|
||||
}
|
||||
|
||||
getUrifromPath(path: string) {
|
||||
const findStr = "/pages"
|
||||
const findStrIdx = path.indexOf(findStr)
|
||||
const uri = path.substring(findStrIdx + findStr.length, path.lastIndexOf("."))
|
||||
const uriWithoutIndex = uri.replace("/index", "")
|
||||
return uriWithoutIndex.length > 0 ? uriWithoutIndex : "/"
|
||||
}
|
||||
|
||||
getVerb(type: RouteType): RouteVerb {
|
||||
switch (type) {
|
||||
case "api":
|
||||
return "*"
|
||||
case "rpc":
|
||||
return "post"
|
||||
default:
|
||||
return "get"
|
||||
}
|
||||
}
|
||||
|
||||
isErrorCode(uri: string) {
|
||||
if (uri.length === this.lengthOfHTTPErrorURI) {
|
||||
// need better way to check HTTP error code
|
||||
const regex = /^[1-5][0-9][0-9]$/
|
||||
return regex.test(uri.substring(1))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
add(file: File, type: RouteType) {
|
||||
if (this.routeCache[file.orginalRelative]) return
|
||||
|
||||
const uri = this.getUrifromPath(this.normalizePath(file.path))
|
||||
const isErrorCode = this.isErrorCode(uri)
|
||||
if (!isErrorCode) {
|
||||
this.routeCache[file.originalRelative] = {
|
||||
path: file.originalRelative,
|
||||
uri,
|
||||
verb: this.getVerb(type),
|
||||
type,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete(file: File) {
|
||||
delete this.routeCache[file.originalRelative]
|
||||
}
|
||||
|
||||
filterByPath(filterFn: (givenPath: string) => boolean) {
|
||||
const found = []
|
||||
for (let path in this.routeCache) {
|
||||
if (filterFn(path)) {
|
||||
found.push(this.routeCache[path])
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
filter(filterFn: (entry: RouteCacheEntry) => boolean) {
|
||||
let found = []
|
||||
for (let path in this.routeCache) {
|
||||
if (filterFn(this.routeCache[path])) {
|
||||
found.push(this.routeCache[path])
|
||||
}
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
get(): Record<string, RouteCacheEntry>
|
||||
get(key: string): RouteCacheEntry
|
||||
get(key?: string) {
|
||||
if (key) return this.routeCache[key]
|
||||
return this.routeCache
|
||||
}
|
||||
|
||||
set(key: string, value: RouteCacheEntry) {
|
||||
this.routeCache[key] = {
|
||||
...value,
|
||||
path: value.path ?? "-",
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
return JSON.stringify(this.routeCache, null, 2)
|
||||
}
|
||||
|
||||
toArray() {
|
||||
return Object.values(this.routeCache)
|
||||
}
|
||||
|
||||
static create() {
|
||||
if (RouteCache.singleton) return RouteCache.singleton
|
||||
RouteCache.singleton = new RouteCache()
|
||||
return RouteCache.singleton
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a route cache of the files running through the stream
|
||||
*/
|
||||
export function createRouteCache() {
|
||||
const cache = RouteCache.create()
|
||||
return {cache}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ const defaultSaveCache = debounce((filePath: string, data: object) => {
|
||||
return writeFile(filePath, Buffer.from(JSON.stringify(data, null, 2)))
|
||||
.then(() => {})
|
||||
.catch(() => {})
|
||||
}, 500)
|
||||
}, 500) as (filePath: string, data: object) => Promise<void>
|
||||
|
||||
const defaultReadCache = (filePath: string) => {
|
||||
// We need to do sync file reading here as this cache
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
export {transformFiles} from "./transform-files"
|
||||
export {Stage, PipelineItem} from "./types"
|
||||
export {Stage, PipelineItem, RouteCacheEntry} from "./types"
|
||||
export * from "./events"
|
||||
export {transform} from "./transform"
|
||||
export {FileCache} from "./helpers/file-cache"
|
||||
export {RouteCache} from "./helpers/route-cache"
|
||||
|
||||
@@ -6,6 +6,7 @@ import {agnosticSource} from "./helpers/agnostic-source"
|
||||
import {createEnrichFiles} from "./helpers/enrich-files"
|
||||
import {createFileCache, FileCache} from "./helpers/file-cache"
|
||||
import {createIdleHandler} from "./helpers/idle-handler"
|
||||
import {createRouteCache, RouteCache} from "./helpers/route-cache"
|
||||
import {createWorkOptimizer} from "./helpers/work-optimizer"
|
||||
import {createWrite} from "./helpers/writer"
|
||||
import {pipeline, through} from "./streams"
|
||||
@@ -14,13 +15,19 @@ export function isSourceFile(file: File) {
|
||||
return file.hash?.indexOf(":") === -1
|
||||
}
|
||||
|
||||
export function isPageFile(file: File) {
|
||||
return file.path
|
||||
}
|
||||
|
||||
function createStageArgs(
|
||||
config: StageConfig,
|
||||
input: Writable,
|
||||
bus: Writable,
|
||||
cache: FileCache,
|
||||
fileCache: FileCache,
|
||||
routeCache: RouteCache,
|
||||
): StageArgs {
|
||||
const getInputCache = () => cache
|
||||
const getInputCache = () => fileCache
|
||||
const getRouteCache = () => routeCache
|
||||
|
||||
function processNewFile(file: File) {
|
||||
if (!file.stat) {
|
||||
@@ -54,6 +61,7 @@ function createStageArgs(
|
||||
input,
|
||||
bus,
|
||||
getInputCache,
|
||||
getRouteCache,
|
||||
processNewFile,
|
||||
processNewChildFile,
|
||||
}
|
||||
@@ -79,10 +87,11 @@ export function createPipeline(
|
||||
const optimizer = createWorkOptimizer(config.src, config.dest)
|
||||
const enrichFiles = createEnrichFiles()
|
||||
const srcCache = createFileCache(isSourceFile)
|
||||
const routeCache = createRouteCache()
|
||||
const idleHandler = createIdleHandler(bus)
|
||||
|
||||
// Send this object to every stage
|
||||
const api = createStageArgs(config, input, bus, srcCache.cache)
|
||||
const api = createStageArgs(config, input, bus, srcCache.cache, routeCache.cache)
|
||||
|
||||
// Initialize each stage
|
||||
const initializedStages = stages.map((stage) => stage(api))
|
||||
|
||||
@@ -8,7 +8,7 @@ export function testStreamItems(
|
||||
expected: any[],
|
||||
logger: (a: any) => any = defaultLogger,
|
||||
) {
|
||||
return new Promise((done) => {
|
||||
return new Promise<void>((done) => {
|
||||
const log: string[] = []
|
||||
|
||||
const st = pipeline(
|
||||
|
||||
@@ -3,6 +3,15 @@ import File from "vinyl"
|
||||
|
||||
export type FileCacheEntry = {path: string}
|
||||
|
||||
export type RouteType = "page" | "rpc" | "api"
|
||||
export type RouteVerb = "get" | "post" | "patch" | "head" | "delete" | "*"
|
||||
export type RouteCacheEntry = {
|
||||
path: string
|
||||
uri: string
|
||||
verb: string
|
||||
type: RouteType
|
||||
}
|
||||
|
||||
abstract class AbstractFileCache {
|
||||
static create: () => AbstractFileCache
|
||||
}
|
||||
@@ -16,6 +25,22 @@ export interface FileCacheInterface extends AbstractFileCache {
|
||||
toPaths: () => string[]
|
||||
}
|
||||
|
||||
export interface RouteCacheInterface extends AbstractFileCache {
|
||||
delete(file: File): void
|
||||
add(file: File, type: RouteType): void
|
||||
|
||||
get(): Record<string, RouteCacheEntry>
|
||||
get(key: string): RouteCacheEntry
|
||||
|
||||
set(key: string, value: RouteCacheEntry): void
|
||||
|
||||
filterByPath: (filterFn: (a: string) => boolean) => RouteCacheEntry[]
|
||||
filter: (filterFn: (a: RouteCacheEntry) => boolean) => RouteCacheEntry[]
|
||||
|
||||
toString: () => string
|
||||
toArray: () => RouteCacheEntry[]
|
||||
}
|
||||
|
||||
export type EventedFile = {
|
||||
event: "add" | "change" | "unlink" | "unlinkDir"
|
||||
hash: string
|
||||
@@ -45,6 +70,7 @@ export type StageArgs = {
|
||||
input: Writable
|
||||
bus: Writable
|
||||
getInputCache: () => FileCacheInterface
|
||||
getRouteCache: () => RouteCacheInterface
|
||||
processNewFile: (file: File) => void
|
||||
processNewChildFile: (a: {
|
||||
parent: EventedFile
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@blitzjs/generator",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"description": "File generation for the Blitz CLI",
|
||||
"homepage": "https://github.com/blitz-js/blitz#readme",
|
||||
"license": "MIT",
|
||||
@@ -34,25 +34,24 @@
|
||||
"url": "git+https://github.com/blitz-js/blitz.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "7.9.0",
|
||||
"@babel/plugin-transform-typescript": "7.9.4",
|
||||
"@blitzjs/display": "0.27.0-canary.1",
|
||||
"@types/jscodeshift": "0.7.1",
|
||||
"chalk": "4.0.0",
|
||||
"@babel/core": "7.12.10",
|
||||
"@babel/plugin-transform-typescript": "7.12.1",
|
||||
"@blitzjs/display": "0.28.0-canary.1",
|
||||
"@types/jscodeshift": "0.7.2",
|
||||
"chalk": "4.1.0",
|
||||
"cross-spawn": "7.0.3",
|
||||
"diff": "4.0.2",
|
||||
"enquirer": "2.3.5",
|
||||
"fs-extra": "9.0.0",
|
||||
"diff": "5.0.0",
|
||||
"enquirer": "2.3.6",
|
||||
"fs-extra": "9.0.1",
|
||||
"fs-readdir-recursive": "1.1.0",
|
||||
"got": "11.1.3",
|
||||
"jscodeshift": "0.10.0",
|
||||
"mem-fs": "1.1.3",
|
||||
"mem-fs-editor": "6.0.0",
|
||||
"node-fetch": "2.6.1",
|
||||
"got": "11.8.1",
|
||||
"jscodeshift": "0.11.0",
|
||||
"mem-fs": "1.2.0",
|
||||
"mem-fs-editor": "8.0.0",
|
||||
"pluralize": "8.0.0",
|
||||
"recast": "0.19.1",
|
||||
"recast": "0.20.4",
|
||||
"username": "5.1.0",
|
||||
"vinyl": "2.2.0"
|
||||
"vinyl": "2.2.1"
|
||||
},
|
||||
"gitHead": "d3b9fce0bdd251c2b1890793b0aa1cd77c1c0922"
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ export abstract class Generator<
|
||||
if (!this.options.destinationRoot) this.options.destinationRoot = process.cwd()
|
||||
}
|
||||
|
||||
abstract async getTemplateValues(): Promise<any>
|
||||
abstract getTemplateValues(): Promise<any>
|
||||
|
||||
abstract getTargetDirectory(): string
|
||||
|
||||
@@ -292,7 +292,7 @@ export abstract class Generator<
|
||||
}
|
||||
})
|
||||
} else {
|
||||
await new Promise((resolve, reject) => {
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
const conflictChecker = new ConflictChecker({
|
||||
dryRun: this.options.dryRun,
|
||||
})
|
||||
|
||||
@@ -8,6 +8,10 @@ import {Generator, GeneratorOptions} from "../generator"
|
||||
import {fetchLatestVersionsFor} from "../utils/fetch-latest-version-for"
|
||||
import {getBlitzDependencyVersion} from "../utils/get-blitz-dependency-version"
|
||||
|
||||
function assert(condition: any, message: string): asserts condition {
|
||||
if (!condition) throw new Error(message)
|
||||
}
|
||||
|
||||
export interface AppGeneratorOptions extends GeneratorOptions {
|
||||
appName: string
|
||||
useTs: boolean
|
||||
@@ -46,7 +50,10 @@ export class AppGenerator extends Generator<AppGeneratorOptions> {
|
||||
// eslint-disable-next-line require-await
|
||||
async preCommit() {
|
||||
this.fs.move(this.destinationPath("gitignore"), this.destinationPath(".gitignore"))
|
||||
const pkg = this.fs.readJSON(this.destinationPath("package.json"))
|
||||
const pkg = this.fs.readJSON(this.destinationPath("package.json")) as
|
||||
| Record<string, any>
|
||||
| undefined
|
||||
assert(pkg, "couldn't find package.json")
|
||||
const ext = this.options.useTs ? "tsx" : "js"
|
||||
let type: string
|
||||
|
||||
@@ -120,7 +127,7 @@ export class AppGenerator extends Generator<AppGeneratorOptions> {
|
||||
if (!fallbackUsed && !this.options.skipInstall) {
|
||||
spinner.succeed()
|
||||
|
||||
await new Promise((resolve) => {
|
||||
await new Promise<void>((resolve) => {
|
||||
const logFlag = this.options.yarn ? "--json" : "--loglevel=error"
|
||||
const cp = spawn(this.options.yarn ? "yarn" : "npm", ["install", logFlag], {
|
||||
stdio: ["inherit", "pipe", "pipe"],
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {join} from "path"
|
||||
import {Generator, GeneratorOptions} from "../generator"
|
||||
import {camelCaseToKebabCase} from "../utils/kebab-case"
|
||||
|
||||
export interface FormGeneratorOptions extends GeneratorOptions {
|
||||
ModelName: string
|
||||
@@ -45,7 +46,7 @@ export class FormGenerator extends Generator<FormGeneratorOptions> {
|
||||
}
|
||||
|
||||
getTargetDirectory() {
|
||||
const context = this.options.context ? `${this.options.context}/` : ""
|
||||
const context = this.options.context ? `${camelCaseToKebabCase(this.options.context)}/` : ""
|
||||
return `app/${context}${this.options.modelNames}/components`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {join} from "path"
|
||||
import {Generator, GeneratorOptions} from "../generator"
|
||||
import {camelCaseToKebabCase} from "../utils/kebab-case"
|
||||
|
||||
export interface MutationGeneratorOptions extends GeneratorOptions {
|
||||
ModelName: string
|
||||
@@ -45,7 +46,7 @@ export class MutationGenerator extends Generator<MutationGeneratorOptions> {
|
||||
}
|
||||
|
||||
getTargetDirectory() {
|
||||
const context = this.options.context ? `${this.options.context}/` : ""
|
||||
const context = this.options.context ? `${camelCaseToKebabCase(this.options.context)}/` : ""
|
||||
return `app/${context}${this.options.modelNames}/mutations`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {join} from "path"
|
||||
import {Generator, GeneratorOptions} from "../generator"
|
||||
import {camelCaseToKebabCase} from "../utils/kebab-case"
|
||||
|
||||
export interface QueriesGeneratorOptions extends GeneratorOptions {
|
||||
ModelName: string
|
||||
@@ -45,7 +46,7 @@ export class QueriesGenerator extends Generator<QueriesGeneratorOptions> {
|
||||
}
|
||||
|
||||
getTargetDirectory() {
|
||||
const context = this.options.context ? `${this.options.context}/` : ""
|
||||
const context = this.options.context ? `${camelCaseToKebabCase(this.options.context)}/` : ""
|
||||
return `app/${context}${this.options.modelNames}/queries`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {join} from "path"
|
||||
import {Generator, GeneratorOptions} from "../generator"
|
||||
import {camelCaseToKebabCase} from "../utils/kebab-case"
|
||||
|
||||
export interface QueryGeneratorOptions extends GeneratorOptions {
|
||||
rawInput: string
|
||||
@@ -17,7 +18,7 @@ export class QueryGenerator extends Generator<QueryGeneratorOptions> {
|
||||
}
|
||||
|
||||
getTargetDirectory() {
|
||||
const context = this.options.context ? `${this.options.context}` : ""
|
||||
const context = this.options.context ? `${camelCaseToKebabCase(this.options.context)}` : ""
|
||||
return `app/${context}/queries`
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ export class Field {
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!/^[A-Za-z]*$/.test(fieldName)) {
|
||||
if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(fieldName)) {
|
||||
// modelName should be just alpha characters at this point, validate
|
||||
throw new Error(
|
||||
`[Field.parse]: received unknown special character in field name: ${fieldName}`,
|
||||
|
||||
@@ -16,7 +16,9 @@ export const LabeledTextField = React.forwardRef<HTMLInputElement, LabeledTextFi
|
||||
const {
|
||||
input,
|
||||
meta: {touched, error, submitError, submitting},
|
||||
} = useField(name)
|
||||
} = useField(name, {
|
||||
parse: props.type === "number" ? Number : undefined
|
||||
})
|
||||
|
||||
const normalizedError = Array.isArray(error) ? error.join(", ") : error || submitError
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
const { sessionMiddleware, unstable_simpleRolesIsAuthorized } = require("@blitzjs/server")
|
||||
const { sessionMiddleware, simpleRolesIsAuthorized } = require("@blitzjs/server")
|
||||
|
||||
module.exports = {
|
||||
middleware: [
|
||||
sessionMiddleware({
|
||||
unstable_isAuthorized: unstable_simpleRolesIsAuthorized,
|
||||
isAuthorized: simpleRolesIsAuthorized,
|
||||
}),
|
||||
],
|
||||
/* Uncomment this to customize the webpack config
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@prisma/cli": "2.x",
|
||||
"@prisma/client": "2.x",
|
||||
"@prisma/cli": "~2.12",
|
||||
"@prisma/client": "~2.12",
|
||||
"blitz": "canary",
|
||||
"react": "0.0.0-experimental-4ead6b530",
|
||||
"react-dom": "0.0.0-experimental-4ead6b530",
|
||||
"react-error-boundary": "2.x",
|
||||
"react": "0.0.0-experimental-3310209d0",
|
||||
"react-dom": "0.0.0-experimental-3310209d0",
|
||||
"react-error-boundary": "3.x",
|
||||
"secure-password": "4.x",
|
||||
"typescript": "4.x",
|
||||
"zod": "1.x"
|
||||
@@ -46,13 +46,13 @@
|
||||
"@testing-library/react": "11.x",
|
||||
"@testing-library/react-hooks": "3.x",
|
||||
"@types/jest": "26.x",
|
||||
"@types/react": "16.x",
|
||||
"@types/react": "17.x",
|
||||
"@types/secure-password": "3.x",
|
||||
"@typescript-eslint/eslint-plugin": "4.x",
|
||||
"@typescript-eslint/parser": "4.x",
|
||||
"babel-eslint": "10.x",
|
||||
"eslint": "7.x",
|
||||
"eslint-config-react-app": "5.x",
|
||||
"eslint-config-react-app": "6.x",
|
||||
"eslint-plugin-flowtype": "5.x",
|
||||
"eslint-plugin-import": "2.x",
|
||||
"eslint-plugin-jsx-a11y": "6.x",
|
||||
@@ -62,7 +62,7 @@
|
||||
"jest": "26.x",
|
||||
"jest-environment-jsdom-fourteen": "1.x",
|
||||
"jest-watch-typeahead": "0.x",
|
||||
"react-test-renderer": "16.x",
|
||||
"react-test-renderer": "17.x",
|
||||
"lint-staged": "10.x",
|
||||
"prettier": "2.x",
|
||||
"pretty-quick": "3.x",
|
||||
|
||||
@@ -46,6 +46,22 @@ describe("Field model", () => {
|
||||
expect(Field.parse("name").toString()).toMatchInlineSnapshot(`"name String"`)
|
||||
})
|
||||
|
||||
it("allow number characters in model name", () => {
|
||||
expect(Field.parse("name2").toString()).toMatchInlineSnapshot(`"name2 String"`)
|
||||
})
|
||||
|
||||
it("allow underscore characters in model name", () => {
|
||||
expect(Field.parse("first_name").toString()).toMatchInlineSnapshot(`"first_name String"`)
|
||||
})
|
||||
|
||||
it("disallows number as a first character in model name", () => {
|
||||
expect(() => Field.parse("2first").toString()).toThrow()
|
||||
})
|
||||
|
||||
it("disallows underscore as a first character in model name", () => {
|
||||
expect(() => Field.parse("_first").toString()).toThrow()
|
||||
})
|
||||
|
||||
it("disallows special characters in model name", () => {
|
||||
expect(() => Field.parse("app-user:int")).toThrow()
|
||||
})
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@blitzjs/installer",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"description": "Package installation for the Blitz CLI",
|
||||
"homepage": "https://github.com/blitz-js/blitz#readme",
|
||||
"license": "MIT",
|
||||
@@ -34,25 +34,23 @@
|
||||
"url": "git+https://github.com/blitz-js/blitz.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "7.9.0",
|
||||
"@babel/plugin-transform-typescript": "7.9.4",
|
||||
"@blitzjs/config": "0.27.0-canary.1",
|
||||
"@blitzjs/display": "0.27.0-canary.1",
|
||||
"@blitzjs/generator": "0.27.0-canary.1",
|
||||
"@types/jscodeshift": "0.7.1",
|
||||
"chokidar": "3.4.2",
|
||||
"@babel/core": "7.12.10",
|
||||
"@babel/plugin-transform-typescript": "7.12.1",
|
||||
"@blitzjs/config": "0.28.0-canary.1",
|
||||
"@blitzjs/display": "0.28.0-canary.1",
|
||||
"@blitzjs/generator": "0.28.0-canary.1",
|
||||
"@types/jscodeshift": "0.7.2",
|
||||
"cross-spawn": "7.0.3",
|
||||
"diff": "4.0.2",
|
||||
"enquirer": "2.3.5",
|
||||
"fs-extra": "9.0.0",
|
||||
"globby": "11.0.0",
|
||||
"ink": "3.0.7",
|
||||
"ink-link": "2.0.0",
|
||||
"diff": "5.0.0",
|
||||
"enquirer": "2.3.6",
|
||||
"fs-extra": "9.0.1",
|
||||
"globby": "11.0.1",
|
||||
"ink": "3.0.8",
|
||||
"ink-spinner": "4.0.1",
|
||||
"jscodeshift": "0.10.0",
|
||||
"react": "0.0.0-experimental-4ead6b530",
|
||||
"recast": "0.19.1",
|
||||
"ts-node": "8.9.1"
|
||||
"jscodeshift": "0.11.0",
|
||||
"react": "0.0.0-experimental-3310209d0",
|
||||
"recast": "0.20.4",
|
||||
"ts-node": "9.1.1"
|
||||
},
|
||||
"gitHead": "d3b9fce0bdd251c2b1890793b0aa1cd77c1c0922"
|
||||
}
|
||||
|
||||
@@ -29,13 +29,12 @@ export class RecipeExecutor<Options extends RecipeMeta> {
|
||||
<RecipeRenderer cliArgs={cliArgs} steps={this.steps} recipeMeta={this.options} />,
|
||||
)
|
||||
await waitUntilExit()
|
||||
log.info(
|
||||
`\n🎉 The recipe for ${this.options.name} completed successfully! Its functionality is now fully configured in your Blitz app.\n`,
|
||||
)
|
||||
} catch (e) {
|
||||
log.error(e)
|
||||
return
|
||||
}
|
||||
|
||||
log.info(
|
||||
`\n🎉 The recipe for ${this.options.name} completed successfully! Its functionality is now fully configured in your Blitz app.\n`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ import * as fs from "fs-extra"
|
||||
|
||||
jest.mock("fs-extra")
|
||||
|
||||
const testIfNotWindows = process.platform === "win32" ? test.skip : test
|
||||
|
||||
describe("path utils", () => {
|
||||
it("returns proper file paths in a TS project", () => {
|
||||
fs.existsSync.mockReturnValue(true)
|
||||
@@ -15,7 +17,7 @@ describe("path utils", () => {
|
||||
})
|
||||
|
||||
// SKIP test because the fs mock is failing on windows
|
||||
it.skip("returns proper file paths in a JS project", () => {
|
||||
testIfNotWindows("returns proper file paths in a JS project", () => {
|
||||
fs.existsSync.mockReturnValue(false)
|
||||
expect(paths.document()).toBe("app/pages/_document.js")
|
||||
expect(paths.app()).toBe("app/pages/_app.js")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@blitzjs/repl",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"description": "Repl package for Blitz CLI",
|
||||
"homepage": "https://github.com/blitz-js/blitz/packages/repl/#readme",
|
||||
"license": "MIT",
|
||||
@@ -31,9 +31,9 @@
|
||||
"url": "git+https://github.com/blitz-js/blitz.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"chokidar": "3.4.2",
|
||||
"globby": "11.0.0",
|
||||
"pkg-dir": "4.2.0",
|
||||
"chokidar": "3.4.3",
|
||||
"globby": "11.0.1",
|
||||
"pkg-dir": "5.0.0",
|
||||
"progress": "^2.0.3"
|
||||
},
|
||||
"gitHead": "d3b9fce0bdd251c2b1890793b0aa1cd77c1c0922",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@blitzjs/server",
|
||||
"description": "Blitz.js server functionality",
|
||||
"version": "0.27.0-canary.1",
|
||||
"version": "0.28.0-canary.1",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"next-patched": "./bin/next-patched"
|
||||
@@ -17,7 +17,6 @@
|
||||
"wait:config": "wait-on ../config/dist/packages/config/src/index.d.ts",
|
||||
"predev": "yarn wait:config && yarn wait:file-pipeline && yarn wait:core",
|
||||
"dev": "tsdx watch --verbose",
|
||||
"prebuild": "yarn predev",
|
||||
"build": "tsdx build",
|
||||
"test": "tsdx test"
|
||||
},
|
||||
@@ -35,45 +34,39 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@blitzjs/file-pipeline": "0.27.0-canary.1",
|
||||
"@blitzjs/file-pipeline": "0.28.0-canary.1",
|
||||
"b64-lite": "1.4.0",
|
||||
"cookie": "0.4.1",
|
||||
"cross-spawn": "7.0.3",
|
||||
"date-fns": "2.14.0",
|
||||
"date-fns": "2.16.1",
|
||||
"detect-port": "1.3.0",
|
||||
"expand-tilde": "2.0.2",
|
||||
"fast-glob": "3.2.2",
|
||||
"fast-glob": "3.2.4",
|
||||
"flush-write-stream": "2.0.0",
|
||||
"folder-hash": "3.3.1",
|
||||
"from2": "2.3.0",
|
||||
"gulp-if": "3.0.0",
|
||||
"hasha": "5.2.0",
|
||||
"jsonwebtoken": "8.5.1",
|
||||
"lodash": "^4.17.19",
|
||||
"lodash-es": "^4.17.15",
|
||||
"merge-stream": "2.0.0",
|
||||
"nanoid": "3.1.10",
|
||||
"next": "10.0.2",
|
||||
"null-loader": "4.0.0",
|
||||
"ora": "4.0.4",
|
||||
"lodash": "^4.17.20",
|
||||
"lodash-es": "^4.17.20",
|
||||
"nanoid": "3.1.20",
|
||||
"next": "10.0.4",
|
||||
"null-loader": "4.0.1",
|
||||
"ora": "5.2.0",
|
||||
"parallel-transform": "1.2.0",
|
||||
"parse-gitignore": "1.0.1",
|
||||
"pirates": "4.0.1",
|
||||
"pkg-dir": "4.2.0",
|
||||
"pretty-ms": "6.0.1",
|
||||
"pkg-dir": "5.0.0",
|
||||
"pumpify": "2.0.1",
|
||||
"readable-stream": "3.6.0",
|
||||
"resolve-cwd": "3.0.0",
|
||||
"slash": "3.0.0",
|
||||
"superjson": "1.3.0",
|
||||
"through2": "3.0.1",
|
||||
"vinyl": "2.2.0",
|
||||
"vinyl-file": "3.0.0",
|
||||
"vinyl-fs": "3.0.3"
|
||||
"superjson": "1.4.1",
|
||||
"through2": "4.0.2",
|
||||
"vinyl": "2.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@blitzjs/core": "0.27.0-canary.1",
|
||||
"next-transpile-modules": "3.2.0"
|
||||
"@blitzjs/core": "0.28.0-canary.1",
|
||||
"next-transpile-modules": "6.0.0"
|
||||
},
|
||||
"gitHead": "d3b9fce0bdd251c2b1890793b0aa1cd77c1c0922"
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import {hashElement} from "folder-hash"
|
||||
import {pathExists, readFile, writeFile} from "fs-extra"
|
||||
import {resolve} from "path"
|
||||
|
||||
export async function getInputArtefactsHash() {
|
||||
const options = {
|
||||
algo: "md5",
|
||||
folders: {
|
||||
exclude: [".*", "node_modules", "cypress", "test", "tests", "spec", "specs"],
|
||||
},
|
||||
}
|
||||
const tree = await hashElement(".", options)
|
||||
return tree.hash
|
||||
}
|
||||
|
||||
export async function alreadyBuilt(buildFolder: string = ".blitz/caches") {
|
||||
const hashStore = resolve(buildFolder, "last-build")
|
||||
if (!(await pathExists(hashStore))) return false
|
||||
|
||||
try {
|
||||
const buffer = await readFile(hashStore)
|
||||
const hash = await getInputArtefactsHash()
|
||||
const read = buffer.toString().replace("\n", "")
|
||||
return read === hash
|
||||
} catch (err) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export async function saveBuild(buildFolder: string = ".blitz/caches") {
|
||||
const hashStore = resolve(buildFolder, "last-build")
|
||||
const hash = await getInputArtefactsHash()
|
||||
await writeFile(hashStore, hash)
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import {copy, pathExists, remove} from "fs-extra"
|
||||
import {resolve} from "path"
|
||||
import {saveBuild} from "./build-hash"
|
||||
import {normalize, ServerConfig} from "./config"
|
||||
import {nextBuild} from "./next-utils"
|
||||
import {configureStages} from "./stages"
|
||||
@@ -39,6 +38,4 @@ export async function build(config: ServerConfig) {
|
||||
if (await pathExists(buildNextFolder)) {
|
||||
await copy(buildNextFolder, rootNextFolder)
|
||||
}
|
||||
|
||||
await saveBuild(buildFolder)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ export type ServerConfig = {
|
||||
rootFolder: string
|
||||
buildFolder?: string
|
||||
devFolder?: string
|
||||
routeFolder?: string
|
||||
clean?: boolean
|
||||
// -
|
||||
isTypescript?: boolean
|
||||
@@ -29,6 +30,7 @@ export type ServerConfig = {
|
||||
type NormalizedConfig = ServerConfig & {
|
||||
buildFolder: string
|
||||
devFolder: string
|
||||
routeFolder: string
|
||||
clean?: boolean
|
||||
// -
|
||||
isTypescript: boolean
|
||||
@@ -49,6 +51,7 @@ const defaults = {
|
||||
// -
|
||||
buildFolder: ".blitz/caches/build",
|
||||
devFolder: ".blitz/caches/dev",
|
||||
routeFolder: ".blitz/caches/routes",
|
||||
// -
|
||||
writeManifestFile: true,
|
||||
// -
|
||||
@@ -68,6 +71,7 @@ const defaults = {
|
||||
"**/.now/**/*",
|
||||
"**/*.pnp.js",
|
||||
"coverage/**/*",
|
||||
".coverage/**/*",
|
||||
"dist/**/*",
|
||||
"**/node_modules/**/*",
|
||||
"cypress/**/*",
|
||||
@@ -94,6 +98,7 @@ export async function normalize(config: ServerConfig): Promise<NormalizedConfig>
|
||||
rootFolder,
|
||||
buildFolder: resolve(rootFolder, config.buildFolder ?? defaults.buildFolder),
|
||||
devFolder: resolve(rootFolder, config.devFolder ?? defaults.devFolder),
|
||||
routeFolder: resolve(rootFolder, config.routeFolder ?? defaults.routeFolder),
|
||||
// -
|
||||
isTypescript: config.isTypescript ?? (await getIsTypescript(rootFolder)),
|
||||
watch: config.watch ?? env === "dev",
|
||||
|
||||
3
packages/server/src/folder-hash.d.ts
vendored
3
packages/server/src/folder-hash.d.ts
vendored
@@ -1,3 +0,0 @@
|
||||
declare module "folder-hash" {
|
||||
export function hashElement(s: string, options: any): any
|
||||
}
|
||||
@@ -2,6 +2,7 @@ export {withBlitz} from "./with-blitz"
|
||||
export {build} from "./build"
|
||||
export {dev} from "./dev"
|
||||
export {prod} from "./prod"
|
||||
export {routes} from "./routes"
|
||||
export {normalize, ServerConfig} from "./config"
|
||||
export {resolveBinAsync} from "./resolve-bin-async"
|
||||
export {ManifestLoader} from "./manifest-loader"
|
||||
|
||||
@@ -59,7 +59,7 @@ export async function nextStartDev(
|
||||
const transform = createOutputTransformer(manifest, devFolder).stream
|
||||
const {spawnCommand, spawnEnv, availablePort} = await createCommandAndPort(config, "dev")
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
return new Promise<void>((res, rej) => {
|
||||
if (config.port && availablePort !== config.port) {
|
||||
log.error(`Couldn't start server on port ${config.port} because it's already in use`)
|
||||
rej("")
|
||||
@@ -79,7 +79,7 @@ export async function nextStartDev(
|
||||
}
|
||||
|
||||
export function nextBuild(nextBin: string, cwd: string) {
|
||||
return new Promise((res, rej) => {
|
||||
return new Promise<void>((res, rej) => {
|
||||
spawn(nextBin, ["build"], {
|
||||
cwd,
|
||||
stdio: "inherit",
|
||||
@@ -94,7 +94,7 @@ export function nextBuild(nextBin: string, cwd: string) {
|
||||
export async function nextStart(nextBin: string, cwd: string, config: ServerConfig) {
|
||||
const {spawnCommand, spawnEnv, availablePort} = await createCommandAndPort(config, "start")
|
||||
|
||||
return new Promise((res, rej) => {
|
||||
return new Promise<void>((res, rej) => {
|
||||
if (config.port && availablePort !== config.port) {
|
||||
log.error(`Couldn't start server on port ${config.port} because it's already in use`)
|
||||
rej("")
|
||||
|
||||
@@ -19,7 +19,7 @@ function globalGitIgnore() {
|
||||
stdio: "pipe",
|
||||
})
|
||||
if (!(configResult.status === 0)) {
|
||||
log.warning("Git config core.excludesFile is unset. Inferring .gitignore file locations.")
|
||||
// Git config core.excludesFile is unset. Inferring .gitignore file locations.
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import {build} from "./build"
|
||||
import {alreadyBuilt} from "./build-hash"
|
||||
import {log} from "@blitzjs/display"
|
||||
import * as fs from "fs"
|
||||
import {normalize, ServerConfig} from "./config"
|
||||
import {nextStart} from "./next-utils"
|
||||
|
||||
export async function prod(config: ServerConfig) {
|
||||
const {buildFolder, nextBin} = await normalize(config)
|
||||
if (!(await alreadyBuilt(buildFolder))) {
|
||||
await build(config)
|
||||
if (!fs.existsSync(buildFolder)) {
|
||||
log.error("Build folder not found, make sure to run `blitz build` before starting")
|
||||
process.exit(1)
|
||||
}
|
||||
await nextStart(nextBin, buildFolder, config)
|
||||
}
|
||||
|
||||
39
packages/server/src/routes.ts
Normal file
39
packages/server/src/routes.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
import {getConfig} from "@blitzjs/config"
|
||||
import type {RouteCache, RouteCacheEntry} from "@blitzjs/file-pipeline"
|
||||
import {normalize, ServerConfig} from "./config"
|
||||
import {configureRouteStages} from "./stages"
|
||||
|
||||
function defaultSitemapFunction(_: RouteCache): RouteCacheEntry[] {
|
||||
return []
|
||||
}
|
||||
|
||||
export async function routes(config: ServerConfig) {
|
||||
const {
|
||||
rootFolder,
|
||||
routeFolder,
|
||||
transformFiles,
|
||||
ignore,
|
||||
include,
|
||||
isTypescript,
|
||||
writeManifestFile,
|
||||
} = await normalize({...config, env: "dev"})
|
||||
|
||||
const {sitemap = defaultSitemapFunction} = getConfig() as Record<string, unknown> & {
|
||||
sitemap: typeof defaultSitemapFunction
|
||||
}
|
||||
|
||||
const stages = configureRouteStages({writeManifestFile, isTypescript})
|
||||
|
||||
const {routeCache} = (await transformFiles(rootFolder, stages, routeFolder, {
|
||||
ignore,
|
||||
include,
|
||||
watch: false,
|
||||
clean: true,
|
||||
})) as {routeCache: RouteCache}
|
||||
|
||||
sitemap(routeCache).forEach((sitemap_) => {
|
||||
routeCache.set(sitemap_.uri, sitemap_)
|
||||
})
|
||||
|
||||
return Object.values(routeCache.get())
|
||||
}
|
||||
@@ -4,10 +4,10 @@ import {
|
||||
EnhancedResolver,
|
||||
handleRequestWithMiddleware,
|
||||
Middleware,
|
||||
prettyMs,
|
||||
} from "@blitzjs/core"
|
||||
import {baseLogger, log as displayLog} from "@blitzjs/display"
|
||||
import chalk from "chalk"
|
||||
import prettyMs from "pretty-ms"
|
||||
import {deserialize, serialize} from "superjson"
|
||||
|
||||
const rpcMiddleware = <TInput, TResult>(
|
||||
@@ -40,14 +40,14 @@ const rpcMiddleware = <TInput, TResult>(
|
||||
try {
|
||||
const data = deserialize({json: req.body.params, meta: req.body.meta?.params}) as TInput
|
||||
|
||||
log.info(chalk.dim("Starting with input:"), data)
|
||||
const startTime = new Date().getTime()
|
||||
log.info(chalk.dim("Starting with input:"), data ? data : JSON.stringify(data))
|
||||
const startTime = Date.now()
|
||||
|
||||
const result = await resolver(data, res.blitzCtx)
|
||||
|
||||
const duration = prettyMs(new Date().getTime() - startTime)
|
||||
log.debug(chalk.dim("Result:"), result)
|
||||
log.info(chalk.dim("Finished", "in", duration))
|
||||
const duration = Date.now() - startTime
|
||||
log.debug(chalk.dim("Result:"), result ? result : JSON.stringify(result))
|
||||
log.info(chalk.dim(`Finished in ${prettyMs(duration)}ms`))
|
||||
displayLog.newline()
|
||||
|
||||
res.blitzResult = result
|
||||
|
||||
@@ -3,6 +3,7 @@ import {createStageManifest} from "./manifest"
|
||||
import {createStagePages} from "./pages"
|
||||
import {createStageRelative} from "./relative"
|
||||
import {createStageRewriteImports} from "./rewrite-imports"
|
||||
import {createStageRoutes} from "./routes"
|
||||
import {createStageRpc} from "./rpc"
|
||||
|
||||
type StagesConfig = {writeManifestFile: boolean; isTypescript: boolean}
|
||||
@@ -18,3 +19,9 @@ export const configureStages = (config: StagesConfig) => [
|
||||
createStageConfig,
|
||||
createStageManifest(config.writeManifestFile),
|
||||
]
|
||||
|
||||
export const configureRouteStages = (config: StagesConfig) => [
|
||||
createStagePages,
|
||||
createStageRpc(config.isTypescript),
|
||||
createStageRoutes,
|
||||
]
|
||||
|
||||
@@ -102,6 +102,8 @@ export const createStagePages: Stage = ({config, bus, getInputCache}) => {
|
||||
)
|
||||
}
|
||||
|
||||
file.originalPath = file.path
|
||||
file.originalRelative = file.relative
|
||||
file.path = apiTransformer(pagesTransformer(file.path))
|
||||
|
||||
return file
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import {Stage, transform} from "@blitzjs/file-pipeline"
|
||||
import fastGlob from "fast-glob"
|
||||
import path from "path"
|
||||
|
||||
const isJavaScriptFile = (filepath: string) => filepath.match(/\.(ts|tsx|js|jsx)$/)
|
||||
@@ -19,7 +20,7 @@ export const createStageRewriteImports: Stage = ({config: {cwd}}) => {
|
||||
|
||||
const contents = filecontents.toString()
|
||||
|
||||
const newContents = replaceImports(contents)
|
||||
const newContents = replaceImports(contents, cwd)
|
||||
file.contents = Buffer.from(newContents)
|
||||
|
||||
return file
|
||||
@@ -30,32 +31,53 @@ export const createStageRewriteImports: Stage = ({config: {cwd}}) => {
|
||||
|
||||
export const patternImport = /(import.*?["'])(.+?)(["'])/gs
|
||||
|
||||
export function replaceImports(content: string) {
|
||||
export function replaceImports(content: string, cwd: string) {
|
||||
return content.replace(patternImport, (...args) => {
|
||||
const [, start, resource, end] = args as string[]
|
||||
const [original, start, resource, end] = args as string[]
|
||||
|
||||
return start + rewriteImportOrigin(resource) + end
|
||||
if (resource.startsWith("@")) {
|
||||
return original
|
||||
}
|
||||
|
||||
return start + rewriteImportOrigin(resource, cwd) + end
|
||||
})
|
||||
}
|
||||
|
||||
export function rewriteImportOrigin(origin: string): string {
|
||||
/**
|
||||
* Check wether `someDir/api` links to `someDir/api.js` or `someDir/api/index.js`.
|
||||
*/
|
||||
function getImportType(absoluteOrigin: string, cwd: string) {
|
||||
const foundFiles = fastGlob.sync(
|
||||
// if absoluteOrigin is a file import,
|
||||
// we'll find a matching file.
|
||||
//
|
||||
[absoluteOrigin + ".[jt]s", absoluteOrigin + ".[jt]sx"],
|
||||
{
|
||||
cwd,
|
||||
},
|
||||
)
|
||||
|
||||
return foundFiles.length > 0 ? "file" : "directory"
|
||||
}
|
||||
|
||||
export function rewriteImportOrigin(origin: string, cwd: string): string {
|
||||
const parts = origin.split("/")
|
||||
|
||||
if (parts.indexOf("pages") === parts.length - 1 || parts.indexOf("api") === parts.length - 1) {
|
||||
if (getImportType(origin, cwd) === "file") {
|
||||
return origin
|
||||
}
|
||||
}
|
||||
|
||||
// If it's an import from a page, say from app/pages/mypage,
|
||||
// we'll rewrite that import to pages/mypage.
|
||||
if (parts.includes("pages")) {
|
||||
if (parts[0] === "app") {
|
||||
parts.splice(0, 1)
|
||||
}
|
||||
parts.splice(0, parts.indexOf("pages"))
|
||||
}
|
||||
|
||||
// If it's an import from an API Route, say from app/users/api/myRoute,
|
||||
// we'll rewrite it to pages/api/myRoute.
|
||||
if (parts.includes("api")) {
|
||||
if (parts.indexOf("api") === parts.length - 1) {
|
||||
parts.push("index")
|
||||
}
|
||||
|
||||
parts.splice(0, parts.indexOf("api"), "pages")
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ describe("rewrite-imports", () => {
|
||||
{
|
||||
path: normalize("/projects/blitz/blitz/app/pages/index.tsx"),
|
||||
contents: `
|
||||
import styles from "app/pages/index.module.css"
|
||||
export function someFunction() { return "foo"; }
|
||||
export default function Index() { return <p>Hello World</p> }
|
||||
`,
|
||||
@@ -105,6 +106,7 @@ describe("rewrite-imports", () => {
|
||||
{
|
||||
path: normalize("/projects/blitz/blitz/app/pages/index.tsx"),
|
||||
contents: `
|
||||
import styles from "pages/index.module.css"
|
||||
export function someFunction() { return "foo"; }
|
||||
export default function Index() { return <p>Hello World</p> }
|
||||
`,
|
||||
@@ -123,6 +125,30 @@ describe("rewrite-imports", () => {
|
||||
)
|
||||
})
|
||||
|
||||
describe("an import from app/admin/pages/admin/index", () => {
|
||||
it(
|
||||
"is rewritten to pages/admin/index",
|
||||
makeTest({
|
||||
input: [
|
||||
{
|
||||
path: normalize("/projects/blitz/blitz/app/admin/pages/admin/index.tsx"),
|
||||
contents: `
|
||||
import styles from "app/admin/pages/admin/index.module.scss"
|
||||
`,
|
||||
},
|
||||
],
|
||||
expectedOutput: [
|
||||
{
|
||||
path: normalize("/projects/blitz/blitz/app/admin/pages/admin/index.tsx"),
|
||||
contents: `
|
||||
import styles from "pages/admin/index.module.scss"
|
||||
`,
|
||||
},
|
||||
],
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
describe("an import from app/users/api/getUser", () => {
|
||||
it(
|
||||
"is rewritten to pages/api/getUser",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user