mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-23 18:59:59 +00:00
Compare commits
55 Commits
@vercel/ru
...
@vercel/st
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3fc3c1ca7 | ||
|
|
44037c58be | ||
|
|
1a9419b690 | ||
|
|
93d0e5966c | ||
|
|
306f3a1312 | ||
|
|
9c67e8115e | ||
|
|
b890ac1e44 | ||
|
|
28e71ff109 | ||
|
|
2bf060c708 | ||
|
|
c8ef1d71d1 | ||
|
|
3d2efc7dcd | ||
|
|
cd7185a872 | ||
|
|
981a76fbe2 | ||
|
|
c35c05446b | ||
|
|
b88e65c4ad | ||
|
|
9e16ce750b | ||
|
|
2105d31730 | ||
|
|
3d7e01ebf0 | ||
|
|
dccacc4ca0 | ||
|
|
be5c0da521 | ||
|
|
f985d953ed | ||
|
|
b8f8289afe | ||
|
|
e01a1cebfd | ||
|
|
2515d522a3 | ||
|
|
32e935d632 | ||
|
|
e6818dd3f9 | ||
|
|
e510415a66 | ||
|
|
1be75712e0 | ||
|
|
f682aefc9d | ||
|
|
cd485c1866 | ||
|
|
f7de7227b4 | ||
|
|
abea217177 | ||
|
|
4e52f8532b | ||
|
|
702cb9e29c | ||
|
|
d3d5555d79 | ||
|
|
2fd3fc73e5 | ||
|
|
de0b13a46e | ||
|
|
d0fe85db92 | ||
|
|
bfbd927320 | ||
|
|
90bacf88b8 | ||
|
|
07c369c542 | ||
|
|
a2e4186ccb | ||
|
|
6e1d708e3f | ||
|
|
38503103c3 | ||
|
|
e8fec4b69c | ||
|
|
b3ffcdf80d | ||
|
|
43c1a93c1d | ||
|
|
5b118fd4e6 | ||
|
|
8916b674af | ||
|
|
1807f83c69 | ||
|
|
74e8ec7c64 | ||
|
|
2644e3127b | ||
|
|
d77ac04b0c | ||
|
|
0ef9c8df4d | ||
|
|
dfc4c98820 |
@@ -16,3 +16,4 @@ packages/node/src/bridge.ts
|
||||
packages/node/test/fixtures
|
||||
packages/node-bridge/bridge.js
|
||||
packages/node-bridge/launcher.js
|
||||
packages/static-config/test/fixtures
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,4 +1,4 @@
|
||||
blank_issues_enabled: false
|
||||
blank_issues_enabled: true
|
||||
contact_links:
|
||||
- name: Bug Report
|
||||
url: https://vercel.com/support/request
|
||||
|
||||
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@@ -29,6 +29,6 @@ jobs:
|
||||
- name: Publish
|
||||
run: yarn publish-from-github
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN_ELEVATED }}
|
||||
GA_TRACKING_ID: ${{ secrets.GA_TRACKING_ID }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "11.1.2",
|
||||
"next": "12.0.1",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2"
|
||||
},
|
||||
|
||||
@@ -43,7 +43,14 @@
|
||||
core-js-pure "^3.16.0"
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@7.15.3", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2":
|
||||
"@babel/runtime@7.15.4":
|
||||
version "7.15.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a"
|
||||
integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2":
|
||||
version "7.15.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.3.tgz#2e1c2880ca118e5b2f9988322bd8a7656a32502b"
|
||||
integrity sha512-OvwMLqNXkCXSz1kSm58sEsNuhqOx/fKpnUnKnFB5v8uDda5bLNEHNgKPvhDN6IU0LDcnHQ90LlJ0Q6jnyBSIBA==
|
||||
@@ -112,10 +119,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@napi-rs/triples/-/triples-1.0.3.tgz#76d6d0c3f4d16013c61e45dfca5ff1e6c31ae53c"
|
||||
integrity sha512-jDJTpta+P4p1NZTFVLHJ/TLFVYVcOqv6l8xwOeBKNPMgY/zDYH/YH7SJbvrr/h1RcS9GzbPcLKGzpuK9cV56UA==
|
||||
|
||||
"@next/env@11.1.2":
|
||||
version "11.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-11.1.2.tgz#27996efbbc54c5f949f5e8c0a156e3aa48369b99"
|
||||
integrity sha512-+fteyVdQ7C/OoulfcF6vd1Yk0FEli4453gr8kSFbU8sKseNSizYq6df5MKz/AjwLptsxrUeIkgBdAzbziyJ3mA==
|
||||
"@next/env@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-12.0.1.tgz#d57141ef1fe844f6f7c18cdaf29a712788c18ca4"
|
||||
integrity sha512-+eJ8mQbAcV/ZILRAgIx9xwDg6hrqm6m/7QLfEvsf2BPnsh+fwU4Xf1zgcbyqD2V4ja4OTWG6ow+Hiukgap3mZQ==
|
||||
|
||||
"@next/eslint-plugin-next@11.1.0":
|
||||
version "11.1.0"
|
||||
@@ -124,15 +131,15 @@
|
||||
dependencies:
|
||||
glob "7.1.7"
|
||||
|
||||
"@next/polyfill-module@11.1.2":
|
||||
version "11.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-11.1.2.tgz#1fe92c364fdc81add775a16c678f5057c6aace98"
|
||||
integrity sha512-xZmixqADM3xxtqBV0TpAwSFzWJP0MOQzRfzItHXf1LdQHWb0yofHHC+7eOrPFic8+ZGz5y7BdPkkgR1S25OymA==
|
||||
"@next/polyfill-module@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/polyfill-module/-/polyfill-module-12.0.1.tgz#d20abf06f686ee7a8bd0d9056accfd0662f19e87"
|
||||
integrity sha512-fTrndwGuvrQO+4myVGcPtsYI4/tmZBhHHJId7MSHWz+9gW4NFgsmDlr8OI9Th2ZXpqk5WHLsTYQ+dLiQp1zV4g==
|
||||
|
||||
"@next/react-dev-overlay@11.1.2":
|
||||
version "11.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-11.1.2.tgz#73795dc5454b7af168bac93df7099965ebb603be"
|
||||
integrity sha512-rDF/mGY2NC69mMg2vDqzVpCOlWqnwPUXB2zkARhvknUHyS6QJphPYv9ozoPJuoT/QBs49JJd9KWaAzVBvq920A==
|
||||
"@next/react-dev-overlay@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/react-dev-overlay/-/react-dev-overlay-12.0.1.tgz#134299ae44fad5a59448d5e671518074f37cba95"
|
||||
integrity sha512-dLv1to40bvadbr0VO8pBsbr9ddgktCLilfejOpEFQkOOrdQBUuIfegqqEDiCL9THkAO3QGYY4t/ZPfv9wrxLZQ==
|
||||
dependencies:
|
||||
"@babel/code-frame" "7.12.11"
|
||||
anser "1.4.9"
|
||||
@@ -144,32 +151,67 @@
|
||||
shell-quote "1.7.2"
|
||||
source-map "0.8.0-beta.0"
|
||||
stacktrace-parser "0.1.10"
|
||||
strip-ansi "6.0.0"
|
||||
strip-ansi "6.0.1"
|
||||
|
||||
"@next/react-refresh-utils@11.1.2":
|
||||
version "11.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-11.1.2.tgz#44ea40d8e773e4b77bad85e24f6ac041d5e4b4a5"
|
||||
integrity sha512-hsoJmPfhVqjZ8w4IFzoo8SyECVnN+8WMnImTbTKrRUHOVJcYMmKLL7xf7T0ft00tWwAl/3f3Q3poWIN2Ueql/Q==
|
||||
"@next/react-refresh-utils@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/react-refresh-utils/-/react-refresh-utils-12.0.1.tgz#219be7a81696a7bd1e2d4ee397ca100eb8262f23"
|
||||
integrity sha512-CjTBR9a6ai+2fUT8KFya9AiTaCnfDY34H6pDmtdJdkD+vY08AwtPpv10kzsgNEhsL06210yVzH59IsEQLBIllA==
|
||||
|
||||
"@next/swc-darwin-arm64@11.1.2":
|
||||
version "11.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-11.1.2.tgz#93226c38db488c4b62b30a53b530e87c969b8251"
|
||||
integrity sha512-hZuwOlGOwBZADA8EyDYyjx3+4JGIGjSHDHWrmpI7g5rFmQNltjlbaefAbiU5Kk7j3BUSDwt30quJRFv3nyJQ0w==
|
||||
"@next/swc-android-arm64@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-12.0.1.tgz#c776853e0911c12fcc69a69cd7ab111dff29f8d2"
|
||||
integrity sha512-zI/6zsZuO2igknzHzfaQep0PeD3d4/qdjXUcQLwLHJQtGdhPvZFMke1z3BBWZqePHVsR1JPjE4QTii7udF5qsQ==
|
||||
|
||||
"@next/swc-darwin-x64@11.1.2":
|
||||
version "11.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-11.1.2.tgz#792003989f560c00677b5daeff360b35b510db83"
|
||||
integrity sha512-PGOp0E1GisU+EJJlsmJVGE+aPYD0Uh7zqgsrpD3F/Y3766Ptfbe1lEPPWnRDl+OzSSrSrX1lkyM/Jlmh5OwNvA==
|
||||
"@next/swc-darwin-arm64@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-12.0.1.tgz#bee9c5932511c993ab384ef9aedb86c02532d41e"
|
||||
integrity sha512-vRfHz7rEt9+TTfwi3uY9ObUSLhzMmgVZ96b+yOSmZ6Kxs/V46IXHOLawCnoldXylpskZ/+HTWcrB1D3aimGeZA==
|
||||
|
||||
"@next/swc-linux-x64-gnu@11.1.2":
|
||||
version "11.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-11.1.2.tgz#8216b2ae1f21f0112958735c39dd861088108f37"
|
||||
integrity sha512-YcDHTJjn/8RqvyJVB6pvEKXihDcdrOwga3GfMv/QtVeLphTouY4BIcEUfrG5+26Nf37MP1ywN3RRl1TxpurAsQ==
|
||||
"@next/swc-darwin-x64@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-12.0.1.tgz#a0bdcbcf11b8b62190ec8e0406cecbbcc810b7fc"
|
||||
integrity sha512-mM7QLIqRUqR8I74gbZ4Uq+dY8k3Whrs98wK+vPurmDTBhXhaVnAYblEkEwe0DJGqlmjD4w6faYfCydmFI69jqw==
|
||||
|
||||
"@next/swc-win32-x64-msvc@11.1.2":
|
||||
version "11.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-11.1.2.tgz#e15824405df137129918205e43cb5e9339589745"
|
||||
integrity sha512-e/pIKVdB+tGQYa1cW3sAeHm8gzEri/HYLZHT4WZojrUxgWXqx8pk7S7Xs47uBcFTqBDRvK3EcQpPLf3XdVsDdg==
|
||||
"@next/swc-linux-arm-gnueabihf@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-12.0.1.tgz#d0132637288f452ad5c6a6161e42aebcd4355f82"
|
||||
integrity sha512-QF5LVyAWTah5i1p/yG4a8nTGRXerHoDkS3kWYCdjcwlALOiAJ9m0GUTks/O47izNokBAbZnL7URUdvtGFjP0Ng==
|
||||
|
||||
"@next/swc-linux-arm64-gnu@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-12.0.1.tgz#6b310344b9bac7700eaff8f4c536540b1226e378"
|
||||
integrity sha512-ETFUh373WsjUJJr32GHSDlVSgwFwS+EJUJuSH40Pr4xB6250YxuRk8ccF6QR5LHqTL4tbbVEEfCD8sZVnccP8w==
|
||||
|
||||
"@next/swc-linux-arm64-musl@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-12.0.1.tgz#8ab1fc81d18bbb70bb15bcc4250382257bba6298"
|
||||
integrity sha512-pfnXNjKywXyp2DJsjFhkfOlvcNu9xa8HgEhCUKXm1OZ4pGnpeb1+UD4t5Pn9b9ggiWPzauZK1abR/9nShvbSzw==
|
||||
|
||||
"@next/swc-linux-x64-gnu@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-12.0.1.tgz#a664268aedec402da5df34efac1b337d9b0e492e"
|
||||
integrity sha512-d9cXS27Ar7TTtA3BJ8gxosDDdVNSFy4MQiwsszKlEiqfGrnINeXKdVgeiOa+xxq+JxNvPzonp4sbX6k8InIocg==
|
||||
|
||||
"@next/swc-linux-x64-musl@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-12.0.1.tgz#4b7e5fee5a62adb6d9c9aad1a4aa00a6a09b53dc"
|
||||
integrity sha512-4SAmi7riavU6TFGX7wQFioFi/vx8uJ2/Cx7ZfrYiZzzKmmuu2eM8onW1kcKu+aQD777x/kvzW4+2pWkM2gyPOA==
|
||||
|
||||
"@next/swc-win32-arm64-msvc@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-12.0.1.tgz#9ff0c2a2f00f41d40bd44d6da195bdf649d807c6"
|
||||
integrity sha512-JRad3QyXvs5zDkeEmc6z5tEvm/ZZnjnsBY921zWw7OIcIZR5wAs+1AnRVjIxHTEHSExxOvBgPyEMpgVkB8OyxQ==
|
||||
|
||||
"@next/swc-win32-ia32-msvc@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-12.0.1.tgz#5a927ec832b184ce2e35f8ec668daa34175e47d0"
|
||||
integrity sha512-ierQmzVWPi6a7PqrdgfI6nrQ/SWJ9W5jllByyQeFIOKhOzZiz030Tw+U6V7NqE3gGNeRwpj56Iya8nUb3hlM1g==
|
||||
|
||||
"@next/swc-win32-x64-msvc@12.0.1":
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-12.0.1.tgz#fe145cf7baf79564159a87a545e430f96c835578"
|
||||
integrity sha512-li3CCXpdMX0+wJlQpy0xZmHCgHMebaBf5X2BIAJrv8cQXYc6dejeojttXLFNCF0dNAo3UzlbP6h7N+8p6Wbakw==
|
||||
|
||||
"@node-rs/helper@1.2.1":
|
||||
version "1.2.1"
|
||||
@@ -258,6 +300,16 @@ acorn-jsx@^5.3.1:
|
||||
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
|
||||
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
|
||||
|
||||
acorn@8.5.0:
|
||||
version "8.5.0"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2"
|
||||
integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==
|
||||
|
||||
acorn@^6.2.1:
|
||||
version "6.4.2"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
|
||||
integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
|
||||
|
||||
acorn@^7.4.0:
|
||||
version "7.4.1"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
|
||||
@@ -298,6 +350,11 @@ ansi-regex@^5.0.0:
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
|
||||
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
|
||||
|
||||
ansi-regex@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||
|
||||
ansi-styles@^3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
|
||||
@@ -390,24 +447,11 @@ assert@2.0.0:
|
||||
object-is "^1.0.1"
|
||||
util "^0.12.0"
|
||||
|
||||
assert@^1.1.1:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb"
|
||||
integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==
|
||||
dependencies:
|
||||
object-assign "^4.1.1"
|
||||
util "0.10.3"
|
||||
|
||||
ast-types-flow@^0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
|
||||
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
|
||||
|
||||
ast-types@0.13.2:
|
||||
version "0.13.2"
|
||||
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.2.tgz#df39b677a911a83f3a049644fb74fdded23cea48"
|
||||
integrity sha512-uWMHxJxtfj/1oZClOxDEV1sQ1HCDkA4MG8Gr69KKeBjEVH0R84WlejZ0y2DcwyBlpAEMltmVYkVgqfLFb2oyiA==
|
||||
|
||||
astral-regex@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
|
||||
@@ -532,7 +576,7 @@ browserify-sign@^4.0.0:
|
||||
readable-stream "^3.6.0"
|
||||
safe-buffer "^5.2.0"
|
||||
|
||||
browserify-zlib@0.2.0, browserify-zlib@^0.2.0:
|
||||
browserify-zlib@0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f"
|
||||
integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==
|
||||
@@ -563,15 +607,6 @@ buffer@5.6.0:
|
||||
base64-js "^1.0.2"
|
||||
ieee754 "^1.1.4"
|
||||
|
||||
buffer@^4.3.0:
|
||||
version "4.9.2"
|
||||
resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8"
|
||||
integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==
|
||||
dependencies:
|
||||
base64-js "^1.0.2"
|
||||
ieee754 "^1.1.4"
|
||||
isarray "^1.0.0"
|
||||
|
||||
builtin-status-codes@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8"
|
||||
@@ -692,12 +727,7 @@ concat-map@0.0.1:
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
console-browserify@^1.1.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336"
|
||||
integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==
|
||||
|
||||
constants-browserify@1.0.0, constants-browserify@^1.0.0:
|
||||
constants-browserify@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
|
||||
integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
|
||||
@@ -714,11 +744,6 @@ core-js-pure@^3.16.0:
|
||||
resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.16.1.tgz#b997df2669c957a5b29f06e95813a171f993592e"
|
||||
integrity sha512-TyofCdMzx0KMhi84mVRS8rL1XsRk2SPUNz2azmth53iRN0/08Uim9fdhQTaZTG1LqaXHYVci4RDHka6WrXfnvg==
|
||||
|
||||
core-util-is@~1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
|
||||
|
||||
create-ecdh@^4.0.0:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e"
|
||||
@@ -759,7 +784,7 @@ cross-spawn@^7.0.2:
|
||||
shebang-command "^2.0.0"
|
||||
which "^2.0.1"
|
||||
|
||||
crypto-browserify@3.12.0, crypto-browserify@^3.11.0:
|
||||
crypto-browserify@3.12.0:
|
||||
version "3.12.0"
|
||||
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
|
||||
integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==
|
||||
@@ -886,11 +911,6 @@ domain-browser@4.19.0:
|
||||
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-4.19.0.tgz#1093e17c0a17dbd521182fe90d49ac1370054af1"
|
||||
integrity sha512-fRA+BaAWOR/yr/t7T9E9GJztHPeFjj8U35ajyAjCDtAAnTn1Rc1f6W6VGPJrO1tkQv9zWu+JRof7z6oQtiYVFQ==
|
||||
|
||||
domain-browser@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
|
||||
integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==
|
||||
|
||||
electron-to-chromium@^1.3.723:
|
||||
version "1.3.802"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.802.tgz#0afa989321de3e904ac653ee79e0d642883731a1"
|
||||
@@ -1219,7 +1239,7 @@ etag@1.8.1:
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
|
||||
|
||||
events@^3.0.0:
|
||||
events@3.3.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
|
||||
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
|
||||
@@ -1486,7 +1506,7 @@ http-errors@1.7.3:
|
||||
statuses ">= 1.5.0 < 2"
|
||||
toidentifier "1.0.0"
|
||||
|
||||
https-browserify@1.0.0, https-browserify@^1.0.0:
|
||||
https-browserify@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
||||
integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=
|
||||
@@ -1548,21 +1568,11 @@ inflight@^1.0.4:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3, inherits@~2.0.4:
|
||||
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3, inherits@~2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
inherits@2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1"
|
||||
integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=
|
||||
|
||||
inherits@2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
||||
internal-slot@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c"
|
||||
@@ -1706,11 +1716,6 @@ is-typed-array@^1.1.3, is-typed-array@^1.1.6:
|
||||
foreach "^2.0.5"
|
||||
has-tostringtag "^1.0.0"
|
||||
|
||||
isarray@^1.0.0, isarray@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
|
||||
integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=
|
||||
|
||||
isexe@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||
@@ -1952,32 +1957,30 @@ nanoid@^3.1.23:
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
|
||||
integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
|
||||
|
||||
native-url@0.3.4:
|
||||
version "0.3.4"
|
||||
resolved "https://registry.yarnpkg.com/native-url/-/native-url-0.3.4.tgz#29c943172aed86c63cee62c8c04db7f5756661f8"
|
||||
integrity sha512-6iM8R99ze45ivyH8vybJ7X0yekIcPf5GgLV5K0ENCbmRcaRIDoj37BC8iLEmaaBfqqb8enuZ5p0uhY+lVAbAcA==
|
||||
dependencies:
|
||||
querystring "^0.2.0"
|
||||
|
||||
natural-compare@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
|
||||
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
|
||||
|
||||
next@11.1.2:
|
||||
version "11.1.2"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-11.1.2.tgz#527475787a9a362f1bc916962b0c0655cc05bc91"
|
||||
integrity sha512-azEYL0L+wFjv8lstLru3bgvrzPvK0P7/bz6B/4EJ9sYkXeW8r5Bjh78D/Ol7VOg0EIPz0CXoe72hzAlSAXo9hw==
|
||||
neo-async@^2.6.1:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
|
||||
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
|
||||
|
||||
next@12.0.1:
|
||||
version "12.0.1"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-12.0.1.tgz#7b82a73bc185bfda7372e7e8309f9b38e6be9cb0"
|
||||
integrity sha512-4MNXAbD9+Tmtejg0TOKbaP52Cgu4mIn2ejKMLHWV0acxWGkkcE7QvdZwvg5pkg3fQBMrgucOxxtmw4D7yWaZvg==
|
||||
dependencies:
|
||||
"@babel/runtime" "7.15.3"
|
||||
"@babel/runtime" "7.15.4"
|
||||
"@hapi/accept" "5.0.2"
|
||||
"@next/env" "11.1.2"
|
||||
"@next/polyfill-module" "11.1.2"
|
||||
"@next/react-dev-overlay" "11.1.2"
|
||||
"@next/react-refresh-utils" "11.1.2"
|
||||
"@next/env" "12.0.1"
|
||||
"@next/polyfill-module" "12.0.1"
|
||||
"@next/react-dev-overlay" "12.0.1"
|
||||
"@next/react-refresh-utils" "12.0.1"
|
||||
"@node-rs/helper" "1.2.1"
|
||||
acorn "8.5.0"
|
||||
assert "2.0.0"
|
||||
ast-types "0.13.2"
|
||||
browserify-zlib "0.2.0"
|
||||
browserslist "4.16.6"
|
||||
buffer "5.6.0"
|
||||
@@ -1990,40 +1993,48 @@ next@11.1.2:
|
||||
domain-browser "4.19.0"
|
||||
encoding "0.1.13"
|
||||
etag "1.8.1"
|
||||
events "3.3.0"
|
||||
find-cache-dir "3.3.1"
|
||||
get-orientation "1.1.2"
|
||||
https-browserify "1.0.0"
|
||||
image-size "1.0.0"
|
||||
jest-worker "27.0.0-next.5"
|
||||
native-url "0.3.4"
|
||||
node-fetch "2.6.1"
|
||||
node-html-parser "1.4.9"
|
||||
node-libs-browser "^2.2.1"
|
||||
os-browserify "0.3.0"
|
||||
p-limit "3.1.0"
|
||||
path-browserify "1.0.1"
|
||||
pnp-webpack-plugin "1.6.4"
|
||||
postcss "8.2.15"
|
||||
process "0.11.10"
|
||||
querystring-es3 "0.2.1"
|
||||
raw-body "2.4.1"
|
||||
react-is "17.0.2"
|
||||
react-refresh "0.8.3"
|
||||
react-server-dom-webpack "0.0.0-experimental-3c4c1c470-20211021"
|
||||
regenerator-runtime "0.13.4"
|
||||
stream-browserify "3.0.0"
|
||||
stream-http "3.1.1"
|
||||
string_decoder "1.3.0"
|
||||
styled-jsx "4.0.1"
|
||||
styled-jsx "5.0.0-beta.3"
|
||||
timers-browserify "2.0.12"
|
||||
tty-browserify "0.0.1"
|
||||
use-subscription "1.5.1"
|
||||
util "0.12.4"
|
||||
vm-browserify "1.1.2"
|
||||
watchpack "2.1.1"
|
||||
web-streams-polyfill "3.0.3"
|
||||
optionalDependencies:
|
||||
"@next/swc-darwin-arm64" "11.1.2"
|
||||
"@next/swc-darwin-x64" "11.1.2"
|
||||
"@next/swc-linux-x64-gnu" "11.1.2"
|
||||
"@next/swc-win32-x64-msvc" "11.1.2"
|
||||
"@next/swc-android-arm64" "12.0.1"
|
||||
"@next/swc-darwin-arm64" "12.0.1"
|
||||
"@next/swc-darwin-x64" "12.0.1"
|
||||
"@next/swc-linux-arm-gnueabihf" "12.0.1"
|
||||
"@next/swc-linux-arm64-gnu" "12.0.1"
|
||||
"@next/swc-linux-arm64-musl" "12.0.1"
|
||||
"@next/swc-linux-x64-gnu" "12.0.1"
|
||||
"@next/swc-linux-x64-musl" "12.0.1"
|
||||
"@next/swc-win32-arm64-msvc" "12.0.1"
|
||||
"@next/swc-win32-ia32-msvc" "12.0.1"
|
||||
"@next/swc-win32-x64-msvc" "12.0.1"
|
||||
|
||||
node-fetch@2.6.1:
|
||||
version "2.6.1"
|
||||
@@ -2037,35 +2048,6 @@ node-html-parser@1.4.9:
|
||||
dependencies:
|
||||
he "1.2.0"
|
||||
|
||||
node-libs-browser@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425"
|
||||
integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==
|
||||
dependencies:
|
||||
assert "^1.1.1"
|
||||
browserify-zlib "^0.2.0"
|
||||
buffer "^4.3.0"
|
||||
console-browserify "^1.1.0"
|
||||
constants-browserify "^1.0.0"
|
||||
crypto-browserify "^3.11.0"
|
||||
domain-browser "^1.1.1"
|
||||
events "^3.0.0"
|
||||
https-browserify "^1.0.0"
|
||||
os-browserify "^0.3.0"
|
||||
path-browserify "0.0.1"
|
||||
process "^0.11.10"
|
||||
punycode "^1.2.4"
|
||||
querystring-es3 "^0.2.0"
|
||||
readable-stream "^2.3.3"
|
||||
stream-browserify "^2.0.1"
|
||||
stream-http "^2.7.2"
|
||||
string_decoder "^1.0.0"
|
||||
timers-browserify "^2.0.4"
|
||||
tty-browserify "0.0.0"
|
||||
url "^0.11.0"
|
||||
util "^0.11.0"
|
||||
vm-browserify "^1.0.1"
|
||||
|
||||
node-releases@^1.1.71:
|
||||
version "1.1.74"
|
||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.74.tgz#e5866488080ebaa70a93b91144ccde06f3c3463e"
|
||||
@@ -2166,7 +2148,7 @@ optionator@^0.9.1:
|
||||
type-check "^0.4.0"
|
||||
word-wrap "^1.2.3"
|
||||
|
||||
os-browserify@0.3.0, os-browserify@^0.3.0:
|
||||
os-browserify@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
|
||||
integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=
|
||||
@@ -2247,11 +2229,6 @@ parse-json@^4.0.0:
|
||||
error-ex "^1.3.1"
|
||||
json-parse-better-errors "^1.0.1"
|
||||
|
||||
path-browserify@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
|
||||
integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==
|
||||
|
||||
path-browserify@1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
|
||||
@@ -2341,13 +2318,6 @@ platform@1.3.6:
|
||||
resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.6.tgz#48b4ce983164b209c2d45a107adb31f473a6e7a7"
|
||||
integrity sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==
|
||||
|
||||
pnp-webpack-plugin@1.6.4:
|
||||
version "1.6.4"
|
||||
resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149"
|
||||
integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==
|
||||
dependencies:
|
||||
ts-pnp "^1.1.6"
|
||||
|
||||
postcss@8.2.15:
|
||||
version "8.2.15"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.15.tgz#9e66ccf07292817d226fc315cbbf9bc148fbca65"
|
||||
@@ -2362,12 +2332,7 @@ prelude-ls@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
|
||||
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
|
||||
|
||||
process-nextick-args@~2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
|
||||
|
||||
process@0.11.10, process@^0.11.10:
|
||||
process@0.11.10:
|
||||
version "0.11.10"
|
||||
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
||||
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
|
||||
@@ -2398,36 +2363,16 @@ public-encrypt@^4.0.0:
|
||||
randombytes "^2.0.1"
|
||||
safe-buffer "^5.1.2"
|
||||
|
||||
punycode@1.3.2:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
|
||||
integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
|
||||
|
||||
punycode@^1.2.4:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
||||
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
|
||||
|
||||
punycode@^2.1.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||
|
||||
querystring-es3@0.2.1, querystring-es3@^0.2.0:
|
||||
querystring-es3@0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
|
||||
integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=
|
||||
|
||||
querystring@0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620"
|
||||
integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
|
||||
|
||||
querystring@^0.2.0:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd"
|
||||
integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==
|
||||
|
||||
queue-microtask@^1.2.2:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
|
||||
@@ -2489,6 +2434,16 @@ react-refresh@0.8.3:
|
||||
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
|
||||
integrity sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==
|
||||
|
||||
react-server-dom-webpack@0.0.0-experimental-3c4c1c470-20211021:
|
||||
version "0.0.0-experimental-3c4c1c470-20211021"
|
||||
resolved "https://registry.yarnpkg.com/react-server-dom-webpack/-/react-server-dom-webpack-0.0.0-experimental-3c4c1c470-20211021.tgz#cdcaa2f19c8d820c1f4d31252319fb05e2de0e88"
|
||||
integrity sha512-YyRlED5kR0C2aQ3IJ/8BR2TELt51RcDZhnUDKz+m/HU+Gb/qak0CZkG0A8Zxffom9VI6HFkUj1dRFZqm0Lh9Pg==
|
||||
dependencies:
|
||||
acorn "^6.2.1"
|
||||
loose-envify "^1.1.0"
|
||||
neo-async "^2.6.1"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
react@17.0.2:
|
||||
version "17.0.2"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
|
||||
@@ -2514,19 +2469,6 @@ read-pkg@^3.0.0:
|
||||
normalize-package-data "^2.3.2"
|
||||
path-type "^3.0.0"
|
||||
|
||||
readable-stream@^2.0.2, readable-stream@^2.3.3, readable-stream@^2.3.6:
|
||||
version "2.3.7"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
|
||||
integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==
|
||||
dependencies:
|
||||
core-util-is "~1.0.0"
|
||||
inherits "~2.0.3"
|
||||
isarray "~1.0.0"
|
||||
process-nextick-args "~2.0.0"
|
||||
safe-buffer "~5.1.1"
|
||||
string_decoder "~1.1.1"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
readable-stream@^3.5.0, readable-stream@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||
@@ -2543,6 +2485,11 @@ readdirp@~3.5.0:
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
regenerator-runtime@0.13.4:
|
||||
version "0.13.4"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.4.tgz#e96bf612a3362d12bb69f7e8f74ffeab25c7ac91"
|
||||
integrity sha512-plpwicqEzfEyTQohIKktWigcLzmNStMGwbOUbykx51/29Z3JOGYldaaNGK7ngNXV+UcoqvIMmloZ48Sr74sd+g==
|
||||
|
||||
regenerator-runtime@^0.13.4:
|
||||
version "0.13.9"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
||||
@@ -2619,7 +2566,7 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2,
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
safe-buffer@~5.1.1:
|
||||
version "5.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
@@ -2780,14 +2727,6 @@ stream-browserify@3.0.0:
|
||||
inherits "~2.0.4"
|
||||
readable-stream "^3.5.0"
|
||||
|
||||
stream-browserify@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b"
|
||||
integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==
|
||||
dependencies:
|
||||
inherits "~2.0.1"
|
||||
readable-stream "^2.0.2"
|
||||
|
||||
stream-http@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.1.1.tgz#0370a8017cf8d050b9a8554afe608f043eaff564"
|
||||
@@ -2798,17 +2737,6 @@ stream-http@3.1.1:
|
||||
readable-stream "^3.6.0"
|
||||
xtend "^4.0.2"
|
||||
|
||||
stream-http@^2.7.2:
|
||||
version "2.8.3"
|
||||
resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc"
|
||||
integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==
|
||||
dependencies:
|
||||
builtin-status-codes "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
readable-stream "^2.3.6"
|
||||
to-arraybuffer "^1.0.0"
|
||||
xtend "^4.0.0"
|
||||
|
||||
stream-parser@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773"
|
||||
@@ -2860,21 +2788,21 @@ string.prototype.trimstart@^1.0.4:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
|
||||
string_decoder@1.3.0, string_decoder@^1.0.0, string_decoder@^1.1.1:
|
||||
string_decoder@1.3.0, string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
|
||||
dependencies:
|
||||
safe-buffer "~5.2.0"
|
||||
|
||||
string_decoder@~1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
|
||||
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
|
||||
strip-ansi@6.0.1:
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||
dependencies:
|
||||
safe-buffer "~5.1.0"
|
||||
ansi-regex "^5.0.1"
|
||||
|
||||
strip-ansi@6.0.0, strip-ansi@^6.0.0:
|
||||
strip-ansi@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
|
||||
integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
|
||||
@@ -2891,10 +2819,10 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
|
||||
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
|
||||
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
|
||||
|
||||
styled-jsx@4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-4.0.1.tgz#ae3f716eacc0792f7050389de88add6d5245b9e9"
|
||||
integrity sha512-Gcb49/dRB1k8B4hdK8vhW27Rlb2zujCk1fISrizCcToIs+55B4vmUM0N9Gi4nnVfFZWe55jRdWpAqH1ldAKWvQ==
|
||||
styled-jsx@5.0.0-beta.3:
|
||||
version "5.0.0-beta.3"
|
||||
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.0.0-beta.3.tgz#400d16179b5dff10d5954ab8be27a9a1b7780dd2"
|
||||
integrity sha512-HtDDGSFPvmjHIqWf9n8Oo54tAoY/DTplvlyOH2+YOtD80Sp31Ap8ffSmxhgk5EkUoJ7xepdXMGT650mSffWuRA==
|
||||
dependencies:
|
||||
"@babel/plugin-syntax-jsx" "7.14.5"
|
||||
"@babel/types" "7.15.0"
|
||||
@@ -2953,18 +2881,13 @@ text-table@^0.2.0:
|
||||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
||||
|
||||
timers-browserify@2.0.12, timers-browserify@^2.0.4:
|
||||
timers-browserify@2.0.12:
|
||||
version "2.0.12"
|
||||
resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee"
|
||||
integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==
|
||||
dependencies:
|
||||
setimmediate "^1.0.4"
|
||||
|
||||
to-arraybuffer@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
|
||||
integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
|
||||
|
||||
to-fast-properties@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
|
||||
@@ -2989,11 +2912,6 @@ tr46@^1.0.1:
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
ts-pnp@^1.1.6:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92"
|
||||
integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==
|
||||
|
||||
tsconfig-paths@^3.9.0:
|
||||
version "3.10.1"
|
||||
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.10.1.tgz#79ae67a68c15289fdf5c51cb74f397522d795ed7"
|
||||
@@ -3015,11 +2933,6 @@ tsutils@^3.21.0:
|
||||
dependencies:
|
||||
tslib "^1.8.1"
|
||||
|
||||
tty-browserify@0.0.0:
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
|
||||
integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=
|
||||
|
||||
tty-browserify@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.1.tgz#3f05251ee17904dfd0677546670db9651682b811"
|
||||
@@ -3064,14 +2977,6 @@ uri-js@^4.2.2:
|
||||
dependencies:
|
||||
punycode "^2.1.0"
|
||||
|
||||
url@^0.11.0:
|
||||
version "0.11.0"
|
||||
resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1"
|
||||
integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=
|
||||
dependencies:
|
||||
punycode "1.3.2"
|
||||
querystring "0.2.0"
|
||||
|
||||
use-subscription@1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.5.1.tgz#73501107f02fad84c6dd57965beb0b75c68c42d1"
|
||||
@@ -3079,18 +2984,11 @@ use-subscription@1.5.1:
|
||||
dependencies:
|
||||
object-assign "^4.1.1"
|
||||
|
||||
util-deprecate@^1.0.1, util-deprecate@~1.0.1:
|
||||
util-deprecate@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
|
||||
util@0.10.3:
|
||||
version "0.10.3"
|
||||
resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9"
|
||||
integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk=
|
||||
dependencies:
|
||||
inherits "2.0.1"
|
||||
|
||||
util@0.12.4, util@^0.12.0:
|
||||
version "0.12.4"
|
||||
resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253"
|
||||
@@ -3103,13 +3001,6 @@ util@0.12.4, util@^0.12.0:
|
||||
safe-buffer "^5.1.2"
|
||||
which-typed-array "^1.1.2"
|
||||
|
||||
util@^0.11.0:
|
||||
version "0.11.1"
|
||||
resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61"
|
||||
integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==
|
||||
dependencies:
|
||||
inherits "2.0.3"
|
||||
|
||||
v8-compile-cache@^2.0.3:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
||||
@@ -3123,7 +3014,7 @@ validate-npm-package-license@^3.0.1:
|
||||
spdx-correct "^3.0.0"
|
||||
spdx-expression-parse "^3.0.0"
|
||||
|
||||
vm-browserify@1.1.2, vm-browserify@^1.0.1:
|
||||
vm-browserify@1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
|
||||
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
|
||||
@@ -3136,6 +3027,11 @@ watchpack@2.1.1:
|
||||
glob-to-regexp "^0.4.1"
|
||||
graceful-fs "^4.1.2"
|
||||
|
||||
web-streams-polyfill@3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.0.3.tgz#f49e487eedeca47a207c1aee41ee5578f884b42f"
|
||||
integrity sha512-d2H/t0eqRNM4w2WvmTdoeIvzAUSpK7JmATB8Nr2lb7nQ9BTIJVjbQ/TRFVEh2gUH1HwclPdoPtfMoFfetXaZnA==
|
||||
|
||||
webidl-conversions@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad"
|
||||
@@ -3190,7 +3086,7 @@ wrappy@1:
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
xtend@^4.0.0, xtend@^4.0.2:
|
||||
xtend@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
|
||||
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
|
||||
|
||||
7
examples/parcel/.gitignore
vendored
Normal file
7
examples/parcel/.gitignore
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
node_modules
|
||||
.parcel-cache
|
||||
dist
|
||||
/.pnp
|
||||
.pnp.js
|
||||
.DS_Store
|
||||
.vercel
|
||||
34
examples/parcel/README.md
Normal file
34
examples/parcel/README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
This is a vanilla web app built with [Parcel](https://parceljs.org).
|
||||
|
||||
## Getting Started
|
||||
|
||||
Run the dev server:
|
||||
|
||||
```bash
|
||||
yarn start
|
||||
# or
|
||||
npm start
|
||||
```
|
||||
|
||||
And open [localhost:1234](http://localhost:1234) in your browser!
|
||||
|
||||
As you make changes, you should see your app automatically update in the browser without even refreshing the page!
|
||||
|
||||
## Learn More
|
||||
|
||||
- [Getting started guide](https://parceljs.org/getting-started/webapp/)
|
||||
- [Documentation](https://parceljs.org/docs/)
|
||||
|
||||
## Deploy Your Own
|
||||
|
||||
[](https://vercel.com/new/clone?repository-url=https://github.com/vercel/vercel/tree/main/examples/parcel&template=parcel)
|
||||
|
||||
_Live Example: https://parcel.examples.vercel.com_
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Parcel project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
12
examples/parcel/package.json
Normal file
12
examples/parcel/package.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "parcel-app",
|
||||
"private": true,
|
||||
"source": "src/index.html",
|
||||
"scripts": {
|
||||
"start": "parcel",
|
||||
"build": "parcel build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"parcel": "^2.0.0"
|
||||
}
|
||||
}
|
||||
1
examples/parcel/src/app.js
Normal file
1
examples/parcel/src/app.js
Normal file
@@ -0,0 +1 @@
|
||||
console.log('Hello world!');
|
||||
13
examples/parcel/src/index.html
Normal file
13
examples/parcel/src/index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>My First Parcel App</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
<script type="module" src="app.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello, Parcel!</h1>
|
||||
<p>This is a vanilla web app built with Parcel 2!<br>Check out the <a href="https://parceljs.org/getting-started/webapp/" target="_blank">getting started guide</a> and the <a href="https://parceljs.org/docs/" target="_blank">documentation</a> to learn more!</p>
|
||||
</body>
|
||||
</html>
|
||||
18
examples/parcel/src/styles.css
Normal file
18
examples/parcel/src/styles.css
Normal file
@@ -0,0 +1,18 @@
|
||||
body {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h1 {
|
||||
color: hotpink;
|
||||
font-family: cursive;
|
||||
font-size: 55px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: dodgerblue;
|
||||
}
|
||||
4541
examples/parcel/yarn.lock
Normal file
4541
examples/parcel/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "2.12.3-canary.1",
|
||||
"version": "2.12.3-canary.14",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
@@ -30,8 +30,8 @@
|
||||
"@types/node-fetch": "^2.1.6",
|
||||
"@types/semver": "6.0.0",
|
||||
"@types/yazl": "^2.4.1",
|
||||
"@vercel/frameworks": "0.5.1-canary.2",
|
||||
"@vercel/ncc": "0.29.2",
|
||||
"@vercel/frameworks": "0.5.1-canary.10",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"aggregate-error": "3.0.1",
|
||||
"async-retry": "1.2.3",
|
||||
"async-sema": "2.1.4",
|
||||
|
||||
@@ -1030,7 +1030,7 @@ function getRouteResult(
|
||||
// https://nextjs.org/docs/advanced-features/custom-error-page
|
||||
errorRoutes.push({
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
src: '^(?!/api).*$',
|
||||
dest: options.cleanUrls ? '/404' : '/404.html',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ interface LambdaOptions {
|
||||
maxDuration?: number;
|
||||
environment: Environment;
|
||||
allowQuery?: string[];
|
||||
regions?: string[];
|
||||
}
|
||||
|
||||
interface CreateLambdaOptions {
|
||||
@@ -30,6 +31,7 @@ interface CreateLambdaOptions {
|
||||
maxDuration?: number;
|
||||
environment?: Environment;
|
||||
allowQuery?: string[];
|
||||
regions?: string[];
|
||||
}
|
||||
|
||||
interface GetLambdaOptionsFromFunctionOptions {
|
||||
@@ -46,6 +48,7 @@ export class Lambda {
|
||||
public maxDuration?: number;
|
||||
public environment: Environment;
|
||||
public allowQuery?: string[];
|
||||
public regions?: string[];
|
||||
|
||||
constructor({
|
||||
zipBuffer,
|
||||
@@ -55,6 +58,7 @@ export class Lambda {
|
||||
memory,
|
||||
environment,
|
||||
allowQuery,
|
||||
regions,
|
||||
}: LambdaOptions) {
|
||||
this.type = 'Lambda';
|
||||
this.zipBuffer = zipBuffer;
|
||||
@@ -64,6 +68,7 @@ export class Lambda {
|
||||
this.maxDuration = maxDuration;
|
||||
this.environment = environment;
|
||||
this.allowQuery = allowQuery;
|
||||
this.regions = regions;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +83,7 @@ export async function createLambda({
|
||||
maxDuration,
|
||||
environment = {},
|
||||
allowQuery,
|
||||
regions,
|
||||
}: CreateLambdaOptions): Promise<Lambda> {
|
||||
assert(typeof files === 'object', '"files" must be an object');
|
||||
assert(typeof handler === 'string', '"handler" is not a string');
|
||||
@@ -100,6 +106,14 @@ export async function createLambda({
|
||||
);
|
||||
}
|
||||
|
||||
if (regions !== undefined) {
|
||||
assert(Array.isArray(regions), '"regions" is not an Array');
|
||||
assert(
|
||||
regions.every(r => typeof r === 'string'),
|
||||
'"regions" is not a string Array'
|
||||
);
|
||||
}
|
||||
|
||||
await sema.acquire();
|
||||
|
||||
try {
|
||||
@@ -111,6 +125,7 @@ export async function createLambda({
|
||||
memory,
|
||||
maxDuration,
|
||||
environment,
|
||||
regions,
|
||||
});
|
||||
} finally {
|
||||
sema.release();
|
||||
|
||||
@@ -9,6 +9,7 @@ interface PrerenderOptions {
|
||||
fallback: FileBlob | FileFsRef | FileRef | null;
|
||||
group?: number;
|
||||
bypassToken?: string | null /* optional to be non-breaking change */;
|
||||
allowQuery?: string[];
|
||||
}
|
||||
|
||||
export class Prerender {
|
||||
@@ -18,6 +19,7 @@ export class Prerender {
|
||||
public fallback: FileBlob | FileFsRef | FileRef | null;
|
||||
public group?: number;
|
||||
public bypassToken: string | null;
|
||||
public allowQuery?: string[];
|
||||
|
||||
constructor({
|
||||
expiration,
|
||||
@@ -25,6 +27,7 @@ export class Prerender {
|
||||
fallback,
|
||||
group,
|
||||
bypassToken,
|
||||
allowQuery,
|
||||
}: PrerenderOptions) {
|
||||
this.type = 'Prerender';
|
||||
this.expiration = expiration;
|
||||
@@ -62,5 +65,19 @@ export class Prerender {
|
||||
);
|
||||
}
|
||||
this.fallback = fallback;
|
||||
|
||||
if (allowQuery !== undefined) {
|
||||
if (!Array.isArray(allowQuery)) {
|
||||
throw new Error(
|
||||
'The `allowQuery` argument for `Prerender` must be Array.'
|
||||
);
|
||||
}
|
||||
if (!allowQuery.every(q => typeof q === 'string')) {
|
||||
throw new Error(
|
||||
'The `allowQuery` argument for `Prerender` must be Array of strings.'
|
||||
);
|
||||
}
|
||||
this.allowQuery = allowQuery;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2013,15 +2013,11 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
framework: 'redwoodjs',
|
||||
};
|
||||
|
||||
const {
|
||||
builders,
|
||||
defaultRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, {
|
||||
projectSettings,
|
||||
featHandleMiss,
|
||||
});
|
||||
const { builders, defaultRoutes, rewriteRoutes, errorRoutes } =
|
||||
await detectBuilders(files, null, {
|
||||
projectSettings,
|
||||
featHandleMiss,
|
||||
});
|
||||
|
||||
expect(builders).toStrictEqual([
|
||||
{
|
||||
@@ -2038,7 +2034,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
src: '^(?!/api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
@@ -2050,15 +2046,11 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
framework: 'redwoodjs',
|
||||
};
|
||||
|
||||
const {
|
||||
builders,
|
||||
defaultRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, {
|
||||
projectSettings,
|
||||
featHandleMiss,
|
||||
});
|
||||
const { builders, defaultRoutes, rewriteRoutes, errorRoutes } =
|
||||
await detectBuilders(files, null, {
|
||||
projectSettings,
|
||||
featHandleMiss,
|
||||
});
|
||||
|
||||
expect(builders).toStrictEqual([
|
||||
{
|
||||
@@ -2096,7 +2088,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
src: '^(?!/api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
@@ -2417,7 +2409,7 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
src: '^(?!/api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
@@ -2435,6 +2427,11 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
'/another/sub/index.html',
|
||||
'/another/sub/page.html',
|
||||
'/another/sub/page',
|
||||
'/another/api',
|
||||
'/another/api/page.html',
|
||||
'/rapid',
|
||||
'/rapid/page.html',
|
||||
'/health-api.html',
|
||||
].forEach(file => {
|
||||
expect(file).toMatch(pattern);
|
||||
});
|
||||
@@ -2443,12 +2440,12 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
'/api',
|
||||
'/api/',
|
||||
'/api/index.html',
|
||||
'/api/page.html',
|
||||
'/api/page',
|
||||
'/api/users.js',
|
||||
'/api/users',
|
||||
'/api/sub',
|
||||
'/api/sub/index.html',
|
||||
'/api/sub/page.html',
|
||||
'/api/sub/page',
|
||||
'/api/sub/users.js',
|
||||
'/api/sub/users',
|
||||
].forEach(file => {
|
||||
expect(file).not.toMatch(pattern);
|
||||
});
|
||||
@@ -2819,12 +2816,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
{
|
||||
const files = ['api/user.go', 'api/team.js', 'api/package.json'];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes, errorRoutes } =
|
||||
await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -2836,7 +2829,7 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
src: '^(?!/api).*$',
|
||||
dest: '/404',
|
||||
},
|
||||
]);
|
||||
@@ -2904,11 +2897,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
{
|
||||
const files = ['api/[endpoint].js', 'api/[endpoint]/[id].js'];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -2936,11 +2926,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
'api/[endpoint]/[id].js',
|
||||
];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -2974,11 +2961,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
|
||||
const files = ['public/index.html', 'api/[endpoint].js'];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, pkg, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, pkg, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -3004,11 +2988,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
{
|
||||
const files = ['api/date/index.js', 'api/date.js'];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -3022,11 +3003,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
{
|
||||
const files = ['api/date.js', 'api/[date]/index.js'];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -3051,11 +3029,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
'api/food.ts',
|
||||
'api/ts/gold.ts',
|
||||
];
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -3071,11 +3046,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
const functions = { 'api/user.php': { runtime: 'vercel-php@0.1.0' } };
|
||||
const files = ['api/user.php'];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, { functions, ...options });
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, { functions, ...options });
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -3105,11 +3077,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
{
|
||||
const files = ['api/user.go', 'api/team.js', 'api/package.json'];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -3152,11 +3121,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
{
|
||||
const files = ['api/[endpoint].js', 'api/[endpoint]/[id].js'];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -3184,11 +3150,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
'api/[endpoint]/[id].js',
|
||||
];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -3222,11 +3185,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
|
||||
const files = ['public/index.html', 'api/[endpoint].js'];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, pkg, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, pkg, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -3245,11 +3205,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
{
|
||||
const files = ['api/date/index.js', 'api/date.js'];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -3263,11 +3220,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
{
|
||||
const files = ['api/date.js', 'api/[date]/index.js'];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -3292,11 +3246,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
'api/food.ts',
|
||||
'api/ts/gold.ts',
|
||||
];
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
@@ -3312,11 +3263,8 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
const functions = { 'api/user.php': { runtime: 'vercel-php@0.1.0' } };
|
||||
const files = ['api/user.php'];
|
||||
|
||||
const {
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
} = await detectBuilders(files, null, { functions, ...options });
|
||||
const { defaultRoutes, redirectRoutes, rewriteRoutes } =
|
||||
await detectBuilders(files, null, { functions, ...options });
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "23.1.3-canary.1",
|
||||
"version": "23.1.3-canary.17",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -43,14 +43,17 @@
|
||||
"node": ">= 12"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "2.12.3-canary.1",
|
||||
"@vercel/go": "1.2.4-canary.1",
|
||||
"@vercel/node": "1.12.2-canary.1",
|
||||
"@vercel/python": "2.0.6-canary.1",
|
||||
"@vercel/ruby": "1.2.8-canary.1",
|
||||
"update-notifier": "4.1.0"
|
||||
"@vercel/build-utils": "2.12.3-canary.14",
|
||||
"@vercel/go": "1.2.4-canary.3",
|
||||
"@vercel/node": "1.12.2-canary.4",
|
||||
"@vercel/python": "2.0.6-canary.4",
|
||||
"@vercel/ruby": "1.2.8-canary.3",
|
||||
"update-notifier": "4.1.0",
|
||||
"vercel-plugin-middleware": "0.0.0-canary.3",
|
||||
"vercel-plugin-node": "1.12.2-plugin.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@next/env": "11.1.2",
|
||||
"@sentry/node": "5.5.0",
|
||||
"@sindresorhus/slugify": "0.11.0",
|
||||
"@tootallnate/once": "1.1.2",
|
||||
@@ -63,7 +66,7 @@
|
||||
"@types/dotenv": "6.1.1",
|
||||
"@types/escape-html": "0.0.20",
|
||||
"@types/express": "4.17.13",
|
||||
"@types/fs-extra": "5.0.5",
|
||||
"@types/fs-extra": "9.0.13",
|
||||
"@types/glob": "7.1.1",
|
||||
"@types/http-proxy": "1.16.2",
|
||||
"@types/inquirer": "7.3.1",
|
||||
@@ -87,8 +90,9 @@
|
||||
"@types/update-notifier": "5.1.0",
|
||||
"@types/which": "1.3.2",
|
||||
"@types/write-json-file": "2.2.1",
|
||||
"@vercel/frameworks": "0.5.1-canary.2",
|
||||
"@vercel/ncc": "0.29.2",
|
||||
"@vercel/frameworks": "0.5.1-canary.10",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/nft": "0.17.0",
|
||||
"@zeit/fun": "0.11.2",
|
||||
"@zeit/source-map-support": "0.6.2",
|
||||
"ajv": "6.12.2",
|
||||
@@ -120,7 +124,7 @@
|
||||
"execa": "3.2.0",
|
||||
"express": "4.17.1",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"fs-extra": "7.0.1",
|
||||
"fs-extra": "10.0.0",
|
||||
"get-port": "5.1.1",
|
||||
"glob": "7.1.2",
|
||||
"http-proxy": "1.18.1",
|
||||
|
||||
@@ -49,19 +49,12 @@ async function main() {
|
||||
|
||||
// Do the initial `ncc` build
|
||||
console.log();
|
||||
const src = join(dirRoot, 'src/index.ts');
|
||||
const args = [
|
||||
'ncc',
|
||||
'build',
|
||||
'--no-asset-builds',
|
||||
'--external',
|
||||
'update-notifier',
|
||||
];
|
||||
const args = ['ncc', 'build', '--external', 'update-notifier'];
|
||||
if (isDev) {
|
||||
args.push('--source-map');
|
||||
}
|
||||
args.push(src);
|
||||
await execa('yarn', args, { stdio: 'inherit' });
|
||||
args.push('src/index.ts');
|
||||
await execa('yarn', args, { stdio: 'inherit', cwd: dirRoot });
|
||||
|
||||
// `ncc` has some issues with `@zeit/fun`'s runtime files:
|
||||
// - Executable bits on the `bootstrap` files appear to be lost:
|
||||
|
||||
@@ -51,8 +51,6 @@ const help = () => {
|
||||
};
|
||||
|
||||
let argv;
|
||||
let debug;
|
||||
let apiUrl;
|
||||
let subcommand;
|
||||
|
||||
export default async client => {
|
||||
@@ -65,8 +63,6 @@ export default async client => {
|
||||
|
||||
argv._ = argv._.slice(1);
|
||||
|
||||
debug = argv['--debug'];
|
||||
apiUrl = client.apiUrl;
|
||||
subcommand = argv._[0];
|
||||
|
||||
if (argv['--help'] || !subcommand) {
|
||||
@@ -76,17 +72,13 @@ export default async client => {
|
||||
|
||||
const {
|
||||
output,
|
||||
authConfig: { token },
|
||||
config: { currentTeam },
|
||||
} = client;
|
||||
|
||||
const start = new Date();
|
||||
const creditCards = new NowCreditCards({
|
||||
apiUrl,
|
||||
token,
|
||||
debug,
|
||||
client,
|
||||
currentTeam,
|
||||
output,
|
||||
});
|
||||
|
||||
let contextName = null;
|
||||
|
||||
765
packages/cli/src/commands/build.ts
Normal file
765
packages/cli/src/commands/build.ts
Normal file
@@ -0,0 +1,765 @@
|
||||
import { loadEnvConfig, processEnv } from '@next/env';
|
||||
import {
|
||||
execCommand,
|
||||
getScriptName,
|
||||
GlobOptions,
|
||||
scanParentDirs,
|
||||
spawnAsync,
|
||||
} from '@vercel/build-utils';
|
||||
import { nodeFileTrace } from '@vercel/nft';
|
||||
import Sema from 'async-sema';
|
||||
import chalk from 'chalk';
|
||||
import { SpawnOptions } from 'child_process';
|
||||
import { assert } from 'console';
|
||||
import { createHash } from 'crypto';
|
||||
import fs from 'fs-extra';
|
||||
import ogGlob from 'glob';
|
||||
import { isAbsolute, join, parse, relative, resolve } from 'path';
|
||||
import pluralize from 'pluralize';
|
||||
import Client from '../util/client';
|
||||
import { emoji, prependEmoji } from '../util/emoji';
|
||||
import getArgs from '../util/get-args';
|
||||
import handleError from '../util/handle-error';
|
||||
import confirm from '../util/input/confirm';
|
||||
import { isSettingValue } from '../util/is-setting-value';
|
||||
import cmd from '../util/output/cmd';
|
||||
import code from '../util/output/code';
|
||||
import { getColorForPkgName } from '../util/output/color-name-cache';
|
||||
import logo from '../util/output/logo';
|
||||
import param from '../util/output/param';
|
||||
import stamp from '../util/output/stamp';
|
||||
import cliPkgJson from '../util/pkg';
|
||||
import { getCommandName, getPkgName } from '../util/pkg-name';
|
||||
import { findFramework } from '../util/projects/find-framework';
|
||||
import { VERCEL_DIR } from '../util/projects/link';
|
||||
import {
|
||||
ProjectLinkAndSettings,
|
||||
readProjectSettings,
|
||||
} from '../util/projects/project-settings';
|
||||
import pull from './pull';
|
||||
|
||||
const sema = new Sema(16, {
|
||||
capacity: 100,
|
||||
});
|
||||
|
||||
const help = () => {
|
||||
return console.log(`
|
||||
${chalk.bold(`${logo} ${getPkgName()} build`)}
|
||||
|
||||
${chalk.dim('Options:')}
|
||||
|
||||
-h, --help Output usage information
|
||||
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
|
||||
'FILE'
|
||||
)} Path to the local ${'`vercel.json`'} file
|
||||
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
--cwd [path] The current working directory
|
||||
-d, --debug Debug mode [off]
|
||||
-y, --yes Skip the confirmation prompt
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Build the project
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} build`)}
|
||||
${chalk.cyan(`$ ${getPkgName()} build --cwd ./path-to-project`)}
|
||||
`);
|
||||
};
|
||||
|
||||
const OUTPUT_DIR = '.output';
|
||||
const VERCEL_PLUGIN_PREFIX = 'vercel-plugin-';
|
||||
|
||||
const fields: {
|
||||
name: string;
|
||||
value: keyof ProjectLinkAndSettings['settings'];
|
||||
}[] = [
|
||||
{ name: 'Build Command', value: 'buildCommand' },
|
||||
{ name: 'Output Directory', value: 'outputDirectory' },
|
||||
{ name: 'Root Directory', value: 'rootDirectory' },
|
||||
];
|
||||
|
||||
export default async function main(client: Client) {
|
||||
let argv;
|
||||
const buildStamp = stamp();
|
||||
try {
|
||||
argv = getArgs(client.argv.slice(2), {
|
||||
'--debug': Boolean,
|
||||
'--cwd': String,
|
||||
});
|
||||
} catch (err) {
|
||||
handleError(err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argv['--help']) {
|
||||
help();
|
||||
return 2;
|
||||
}
|
||||
|
||||
let cwd = argv['--cwd'] || process.cwd();
|
||||
|
||||
let project = await readProjectSettings(join(cwd, VERCEL_DIR));
|
||||
// If there are no project settings, only then do we pull them down
|
||||
while (!project?.settings) {
|
||||
const confirmed = await confirm(
|
||||
`No Project Settings found locally. Run ${getCommandName(
|
||||
'pull'
|
||||
)} for retrieving them?`,
|
||||
true
|
||||
);
|
||||
if (!confirmed) {
|
||||
client.output.print(`Aborted. No Project Settings retrieved.\n`);
|
||||
return 0;
|
||||
}
|
||||
const result = await pull(client);
|
||||
if (result !== 0) {
|
||||
return result;
|
||||
}
|
||||
project = await readProjectSettings(join(cwd, VERCEL_DIR));
|
||||
}
|
||||
|
||||
cwd = project.settings.rootDirectory
|
||||
? join(cwd, project.settings.rootDirectory)
|
||||
: cwd;
|
||||
|
||||
// Load the environment
|
||||
const { combinedEnv, loadedEnvFiles } = loadEnvConfig(cwd, false, {
|
||||
info: () => ({}), // we don't want to log this yet.
|
||||
error: (...args: any[]) => client.output.error(args.join(' ')),
|
||||
});
|
||||
|
||||
// Set process.env with loaded environment variables
|
||||
await processEnv(loadedEnvFiles);
|
||||
|
||||
const spawnOpts = {
|
||||
env: { ...combinedEnv, VERCEL: '1' },
|
||||
};
|
||||
|
||||
process.chdir(cwd);
|
||||
|
||||
const framework = findFramework(project.settings.framework);
|
||||
// If this is undefined, we bail. If it is null, then findFramework should return "Other",
|
||||
// so this should really never happen, but just in case....
|
||||
if (framework === undefined) {
|
||||
client.output.error(
|
||||
`Framework detection failed or is malformed. Please run ${getCommandName(
|
||||
'pull'
|
||||
)} again.`
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const buildState = { ...project.settings };
|
||||
|
||||
client.output.log(`Retrieved Project Settings:`);
|
||||
client.output.print(
|
||||
chalk.dim(` - ${chalk.bold(`Framework Preset:`)} ${framework.name}\n`)
|
||||
);
|
||||
|
||||
for (let field of fields) {
|
||||
const defaults = (framework.settings as any)[field.value];
|
||||
if (defaults) {
|
||||
client.output.print(
|
||||
chalk.dim(
|
||||
` - ${chalk.bold(`${field.name}:`)} ${`${
|
||||
project.settings[field.value]
|
||||
? project.settings[field.value] + ` (override)`
|
||||
: isSettingValue(defaults)
|
||||
? defaults.value
|
||||
: chalk.italic(`${defaults.placeholder}`)
|
||||
}`}\n`
|
||||
)
|
||||
);
|
||||
}
|
||||
if (field.value != 'buildCommand') {
|
||||
(buildState as any)[field.value] = project.settings[field.value]
|
||||
? project.settings[field.value]
|
||||
: defaults
|
||||
? isSettingValue(defaults)
|
||||
? defaults.value
|
||||
: null
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
if (loadedEnvFiles.length > 0) {
|
||||
client.output.log(
|
||||
`Loaded Environment Variables from ${loadedEnvFiles.length} ${pluralize(
|
||||
'file',
|
||||
loadedEnvFiles.length
|
||||
)}:`
|
||||
);
|
||||
for (let envFile of loadedEnvFiles) {
|
||||
client.output.print(chalk.dim(` - ${envFile.path}\n`));
|
||||
}
|
||||
}
|
||||
|
||||
// Load plugins
|
||||
const debug = argv['--debug'];
|
||||
let plugins;
|
||||
try {
|
||||
plugins = await loadCliPlugins(client, cwd);
|
||||
} catch (error) {
|
||||
client.output.error('Failed to load CLI Plugins');
|
||||
handleError(error, { debug });
|
||||
return 1;
|
||||
}
|
||||
|
||||
const origLog = console.log;
|
||||
const origErr = console.error;
|
||||
const prefixedLog = (
|
||||
prefix: string,
|
||||
args: any[],
|
||||
logger: (...args: any[]) => void
|
||||
) => {
|
||||
if (typeof args[0] === 'string') {
|
||||
args[0] = `${prefix} ${args[0]}`;
|
||||
} else {
|
||||
args.unshift(prefix);
|
||||
}
|
||||
return logger(...args);
|
||||
};
|
||||
|
||||
if (plugins?.pluginCount && plugins?.pluginCount > 0) {
|
||||
client.output.log(
|
||||
`Loaded ${plugins.pluginCount} CLI ${pluralize(
|
||||
'Plugin',
|
||||
plugins.pluginCount
|
||||
)}`
|
||||
);
|
||||
// preBuild Plugins
|
||||
if (plugins.preBuildPlugins.length > 0) {
|
||||
client.output.log(
|
||||
`Running ${plugins.pluginCount} CLI ${pluralize(
|
||||
'Plugin',
|
||||
plugins.pluginCount
|
||||
)} before Build Command:`
|
||||
);
|
||||
for (let item of plugins.preBuildPlugins) {
|
||||
const { name, plugin, color } = item;
|
||||
if (typeof plugin.preBuild === 'function') {
|
||||
const pluginStamp = stamp();
|
||||
const fullName = name + '.preBuild';
|
||||
const prefix = chalk.gray(' > ') + color(fullName + ':');
|
||||
client.output.debug(`Running ${fullName}:`);
|
||||
try {
|
||||
console.log = (...args: any[]) =>
|
||||
prefixedLog(prefix, args, origLog);
|
||||
console.error = (...args: any[]) =>
|
||||
prefixedLog(prefix, args, origErr);
|
||||
await plugin.preBuild();
|
||||
client.output.debug(
|
||||
`Completed ${fullName} ${chalk.dim(`${pluginStamp()}`)}`
|
||||
);
|
||||
} catch (error) {
|
||||
client.output.error(`${prefix} failed`);
|
||||
handleError(error, { debug });
|
||||
return 1;
|
||||
} finally {
|
||||
console.log = origLog;
|
||||
console.error = origErr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean the output directory
|
||||
fs.removeSync(join(cwd, OUTPUT_DIR));
|
||||
let result: boolean;
|
||||
if (typeof buildState.buildCommand === 'string') {
|
||||
client.output.log(`Running Build Command: ${cmd(buildState.buildCommand)}`);
|
||||
result = await execCommand(buildState.buildCommand, {
|
||||
...spawnOpts,
|
||||
// Yarn v2 PnP mode may be activated, so force
|
||||
// "node-modules" linker style
|
||||
env: {
|
||||
YARN_NODE_LINKER: 'node-modules',
|
||||
...spawnOpts.env,
|
||||
},
|
||||
cwd: cwd,
|
||||
});
|
||||
} else if (fs.existsSync(join(cwd, 'package.json'))) {
|
||||
result = await runPackageJsonScript(
|
||||
client,
|
||||
cwd,
|
||||
['vercel-build', 'now-build', 'build'],
|
||||
spawnOpts
|
||||
);
|
||||
} else {
|
||||
// no package.json exists and no build command present
|
||||
result = true;
|
||||
}
|
||||
|
||||
if (!result) {
|
||||
client.output.error(
|
||||
`Missing required "${cmd(
|
||||
buildState.buildCommand || 'vercel-build' || 'build'
|
||||
)}" script in ${param(cwd)}"\n`
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!fs.existsSync(join(cwd, OUTPUT_DIR))) {
|
||||
let outputDir = join(OUTPUT_DIR, 'static');
|
||||
let distDir = await framework.getFsOutputDir(cwd);
|
||||
if (framework.slug === 'nextjs') {
|
||||
outputDir = OUTPUT_DIR;
|
||||
}
|
||||
const copyStamp = stamp();
|
||||
await fs.ensureDir(join(cwd, outputDir));
|
||||
const relativeDistDir = relative(cwd, distDir);
|
||||
client.output.spinner(
|
||||
`Copying files from ${param(distDir)} to ${param(outputDir)}`
|
||||
);
|
||||
const files = await glob(join(relativeDistDir, '**'), {
|
||||
ignore: [
|
||||
'node_modules/**',
|
||||
'.vercel/**',
|
||||
'_middleware.ts',
|
||||
'_middleware.mts',
|
||||
'_middleware.cts',
|
||||
'_middleware.mjs',
|
||||
'_middleware.cjs',
|
||||
'_middleware.js',
|
||||
'api/**',
|
||||
'.git/**',
|
||||
],
|
||||
nodir: true,
|
||||
dot: true,
|
||||
cwd,
|
||||
absolute: true,
|
||||
});
|
||||
await Promise.all(
|
||||
files.map(f =>
|
||||
smartCopy(
|
||||
client,
|
||||
f,
|
||||
distDir === '.'
|
||||
? join(cwd, outputDir, relative(cwd, f))
|
||||
: f.replace(distDir, outputDir)
|
||||
)
|
||||
)
|
||||
);
|
||||
client.output.stopSpinner();
|
||||
client.output.log(
|
||||
`Copied ${files.length.toLocaleString()} files from ${param(
|
||||
distDir
|
||||
)} to ${param(outputDir)} ${copyStamp()}`
|
||||
);
|
||||
|
||||
const buildManifestPath = join(cwd, OUTPUT_DIR, 'build-manifest.json');
|
||||
const routesManifestPath = join(cwd, OUTPUT_DIR, 'routes-manifest.json');
|
||||
|
||||
if (!fs.existsSync(buildManifestPath)) {
|
||||
client.output.debug(
|
||||
`Generating build manifest: ${param(buildManifestPath)}`
|
||||
);
|
||||
const buildManifest = {
|
||||
cache: framework.cachePattern ? [framework.cachePattern] : [],
|
||||
};
|
||||
await fs.writeJSON(buildManifestPath, buildManifest, { spaces: 2 });
|
||||
}
|
||||
|
||||
if (!fs.existsSync(routesManifestPath)) {
|
||||
client.output.debug(
|
||||
`Generating routes manifest: ${param(routesManifestPath)}`
|
||||
);
|
||||
const routesManifest = {
|
||||
version: 3,
|
||||
pages404: true,
|
||||
basePath: '',
|
||||
redirects: framework.defaultRedirects ?? [],
|
||||
headers: framework.defaultHeaders ?? [],
|
||||
dynamicRoutes: [],
|
||||
dataRoutes: [],
|
||||
rewrites: framework.defaultRewrites ?? [],
|
||||
};
|
||||
await fs.writeJSON(
|
||||
join(cwd, OUTPUT_DIR, 'routes-manifest.json'),
|
||||
routesManifest,
|
||||
{ spaces: 2 }
|
||||
);
|
||||
}
|
||||
|
||||
// Special Next.js processing.
|
||||
if (framework.slug === 'nextjs') {
|
||||
// The contents of `.output/static` should be placed inside of `.output/static/_next/static`
|
||||
const tempStatic = '___static';
|
||||
await fs.rename(
|
||||
join(cwd, OUTPUT_DIR, 'static'),
|
||||
join(cwd, OUTPUT_DIR, tempStatic)
|
||||
);
|
||||
await fs.mkdirp(join(cwd, OUTPUT_DIR, 'static', '_next', 'static'));
|
||||
await fs.rename(
|
||||
join(cwd, OUTPUT_DIR, tempStatic),
|
||||
join(cwd, OUTPUT_DIR, 'static', '_next', 'static')
|
||||
);
|
||||
|
||||
// We want to pick up directories for user-provided static files into `.`output/static`.
|
||||
// More specifically, the static directory contents would then be mounted to `output/static/static`,
|
||||
// and the public directory contents would be mounted to `output/static`. Old Next.js versions
|
||||
// allow `static`, and newer ones allow both, but since there's nobody that actually uses both,
|
||||
// we can check for the existence of both and pick the first match that we find (first
|
||||
// `public`, then`static`). We can't read both at the same time because that would mean we'd
|
||||
// read public for old Next.js versions that don't support it, which might be breaking (and
|
||||
// we don't want to make vercel build specific framework versions).
|
||||
const publicFiles = await glob('public/**', {
|
||||
nodir: true,
|
||||
dot: true,
|
||||
cwd,
|
||||
absolute: true,
|
||||
});
|
||||
if (publicFiles.length > 0) {
|
||||
await Promise.all(
|
||||
publicFiles.map(f =>
|
||||
smartCopy(
|
||||
client,
|
||||
f,
|
||||
f.replace('public', join(OUTPUT_DIR, 'static'))
|
||||
)
|
||||
)
|
||||
);
|
||||
} else {
|
||||
const staticFiles = await glob('static/**', {
|
||||
nodir: true,
|
||||
dot: true,
|
||||
cwd,
|
||||
absolute: true,
|
||||
});
|
||||
await Promise.all(
|
||||
staticFiles.map(f =>
|
||||
smartCopy(
|
||||
client,
|
||||
f,
|
||||
f.replace('static', join(OUTPUT_DIR, 'static', 'static'))
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Regardless of the Next.js version, we make sure that it is compatible with
|
||||
// the Filesystem API. We get there by moving all the files needed
|
||||
// into the outputs directory `inputs` folder. Next.js is > 12, we can
|
||||
// read the .nft.json files directly. If there aren't .nft.json files
|
||||
// we trace and create them. We then resolve the files in each nft file list
|
||||
// and move them into the "inputs" directory. We rename them with hashes to
|
||||
// prevent collisions and then update the related .nft files accordingly
|
||||
// to point to the newly named input files. Again, all of this is so that Next.js
|
||||
// works with the Filesystem API (and so .output contains all inputs
|
||||
// needed to run Next.js) and `vc --prebuilt`.
|
||||
const nftFiles = await glob(join(OUTPUT_DIR, '**', '*.nft.json'), {
|
||||
nodir: true,
|
||||
dot: true,
|
||||
cwd,
|
||||
absolute: true,
|
||||
});
|
||||
|
||||
// If there are no .nft.json files, we know that Next.js < 12. We then
|
||||
// execute the tracing on our own.
|
||||
if (nftFiles.length === 0) {
|
||||
const serverFiles = await glob(
|
||||
join(OUTPUT_DIR, 'server', 'pages', '**', '*.js'),
|
||||
{
|
||||
nodir: true,
|
||||
dot: true,
|
||||
cwd,
|
||||
ignore: ['webpack-runtime.js'],
|
||||
absolute: true,
|
||||
}
|
||||
);
|
||||
for (let f of serverFiles) {
|
||||
const { ext, dir } = parse(f);
|
||||
const { fileList } = await nodeFileTrace([f], {
|
||||
ignore: [
|
||||
relative(cwd, f),
|
||||
'node_modules/next/dist/pages/**/*',
|
||||
'node_modules/next/dist/compiled/webpack/(bundle4|bundle5).js',
|
||||
'node_modules/react/**/*.development.js',
|
||||
'node_modules/react-dom/**/*.development.js',
|
||||
'node_modules/use-subscription/**/*.development.js',
|
||||
'node_modules/sharp/**/*',
|
||||
],
|
||||
});
|
||||
fileList.delete(relative(cwd, f));
|
||||
await resolveNftToOutput({
|
||||
client,
|
||||
cwd,
|
||||
outputDir: OUTPUT_DIR,
|
||||
nftFileName: f.replace(ext, '.js.nft.json'),
|
||||
nft: {
|
||||
version: 1,
|
||||
files: Array.from(fileList).map(fileListEntry =>
|
||||
relative(dir, fileListEntry)
|
||||
),
|
||||
},
|
||||
});
|
||||
}
|
||||
} else {
|
||||
for (let f of nftFiles) {
|
||||
const json = await fs.readJson(f);
|
||||
await resolveNftToOutput({
|
||||
client,
|
||||
cwd,
|
||||
outputDir: OUTPUT_DIR,
|
||||
nftFileName: f,
|
||||
nft: json,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const requiredServerFilesPath = join(
|
||||
OUTPUT_DIR,
|
||||
'required-server-files.json'
|
||||
);
|
||||
const requiredServerFilesJson = await fs.readJSON(
|
||||
requiredServerFilesPath
|
||||
);
|
||||
await fs.writeJSON(requiredServerFilesPath, {
|
||||
...requiredServerFilesJson,
|
||||
appDir: '.',
|
||||
files: requiredServerFilesJson.files.map((i: string) => ({
|
||||
input: i.replace('.next', '.output'),
|
||||
output: i,
|
||||
})),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Build Plugins
|
||||
if (plugins?.buildPlugins && plugins.buildPlugins.length > 0) {
|
||||
client.output.log(
|
||||
`Running ${plugins.pluginCount} CLI ${pluralize(
|
||||
'Plugin',
|
||||
plugins.pluginCount
|
||||
)} after Build Command:`
|
||||
);
|
||||
for (let item of plugins.buildPlugins) {
|
||||
const { name, plugin, color } = item;
|
||||
if (typeof plugin.build === 'function') {
|
||||
const pluginStamp = stamp();
|
||||
const fullName = name + '.build';
|
||||
const prefix = chalk.gray(' > ') + color(fullName + ':');
|
||||
client.output.debug(`Running ${fullName}:`);
|
||||
try {
|
||||
console.log = (...args: any[]) => prefixedLog(prefix, args, origLog);
|
||||
console.error = (...args: any[]) =>
|
||||
prefixedLog(prefix, args, origErr);
|
||||
await plugin.build();
|
||||
client.output.debug(
|
||||
`Completed ${fullName} ${chalk.dim(`${pluginStamp()}`)}`
|
||||
);
|
||||
} catch (error) {
|
||||
client.output.error(`${prefix} failed`);
|
||||
handleError(error, { debug });
|
||||
return 1;
|
||||
} finally {
|
||||
console.log = origLog;
|
||||
console.error = origLog;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client.output.print(
|
||||
`${prependEmoji(
|
||||
`Build Completed in ${chalk.bold(OUTPUT_DIR)} ${chalk.gray(
|
||||
buildStamp()
|
||||
)}`,
|
||||
emoji('success')
|
||||
)}\n`
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
export async function runPackageJsonScript(
|
||||
client: Client,
|
||||
destPath: string,
|
||||
scriptNames: string | Iterable<string>,
|
||||
spawnOpts?: SpawnOptions
|
||||
) {
|
||||
assert(isAbsolute(destPath));
|
||||
|
||||
const { packageJson, cliType, lockfileVersion } = await scanParentDirs(
|
||||
destPath,
|
||||
true
|
||||
);
|
||||
const scriptName = getScriptName(
|
||||
packageJson,
|
||||
typeof scriptNames === 'string' ? [scriptNames] : scriptNames
|
||||
);
|
||||
if (!scriptName) return false;
|
||||
|
||||
client.output.debug('Running user script...');
|
||||
const runScriptTime = Date.now();
|
||||
|
||||
const opts: any = { cwd: destPath, ...spawnOpts };
|
||||
const env = (opts.env = { ...process.env, ...opts.env });
|
||||
|
||||
if (cliType === 'npm') {
|
||||
opts.prettyCommand = `npm run ${scriptName}`;
|
||||
|
||||
if (typeof lockfileVersion === 'number' && lockfileVersion >= 2) {
|
||||
// Ensure that npm 7 is at the beginning of the `$PATH`
|
||||
env.PATH = `/node16/bin-npm7:${env.PATH}`;
|
||||
}
|
||||
} else {
|
||||
opts.prettyCommand = `yarn run ${scriptName}`;
|
||||
|
||||
// Yarn v2 PnP mode may be activated, so force "node-modules" linker style
|
||||
if (!env.YARN_NODE_LINKER) {
|
||||
env.YARN_NODE_LINKER = 'node-modules';
|
||||
}
|
||||
}
|
||||
|
||||
client.output.log(`Running Build Command: ${cmd(opts.prettyCommand)}\n`);
|
||||
await spawnAsync(cliType, ['run', scriptName], opts);
|
||||
client.output.print('\n'); // give it some room
|
||||
client.output.debug(`Script complete [${Date.now() - runScriptTime}ms]`);
|
||||
return true;
|
||||
}
|
||||
|
||||
async function loadCliPlugins(client: Client, cwd: string) {
|
||||
const { packageJson } = await scanParentDirs(cwd, true);
|
||||
|
||||
let pluginCount = 0;
|
||||
const preBuildPlugins = [];
|
||||
const buildPlugins = [];
|
||||
const deps = new Set(
|
||||
[
|
||||
...Object.keys(packageJson?.dependencies || {}),
|
||||
...Object.keys(packageJson?.devDependencies || {}),
|
||||
...Object.keys(cliPkgJson.dependencies),
|
||||
].filter(dep => dep.startsWith(VERCEL_PLUGIN_PREFIX))
|
||||
);
|
||||
|
||||
for (let dep of deps) {
|
||||
pluginCount++;
|
||||
const resolved = require.resolve(dep, {
|
||||
paths: [cwd, process.cwd(), __dirname],
|
||||
});
|
||||
let plugin;
|
||||
try {
|
||||
plugin = require(resolved);
|
||||
const color = getColorForPkgName(dep);
|
||||
if (typeof plugin.preBuild === 'function') {
|
||||
preBuildPlugins.push({
|
||||
plugin,
|
||||
name: dep,
|
||||
color,
|
||||
});
|
||||
}
|
||||
if (typeof plugin.build === 'function') {
|
||||
buildPlugins.push({
|
||||
plugin,
|
||||
name: dep,
|
||||
color,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
client.output.error(`Failed to import ${code(dep)}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
return { pluginCount, preBuildPlugins, buildPlugins };
|
||||
}
|
||||
|
||||
async function linkOrCopy(existingPath: string, newPath: string) {
|
||||
try {
|
||||
await fs.createLink(existingPath, newPath);
|
||||
} catch (err: any) {
|
||||
// eslint-disable-line
|
||||
// If a hard link to the same file already exists
|
||||
// then trying to copy it will make an empty file from it.
|
||||
if (err['code'] === 'EEXIST') return;
|
||||
// In some VERY rare cases (1 in a thousand), hard-link creation fails on Windows.
|
||||
// In that case, we just fall back to copying.
|
||||
// This issue is reproducible with "pnpm add @material-ui/icons@4.9.1"
|
||||
await fs.copyFile(existingPath, newPath);
|
||||
}
|
||||
}
|
||||
|
||||
async function smartCopy(client: Client, from: string, to: string) {
|
||||
sema.acquire();
|
||||
try {
|
||||
client.output.debug(`Copying from ${from} to ${to}`);
|
||||
await linkOrCopy(from, to);
|
||||
} finally {
|
||||
sema.release();
|
||||
}
|
||||
}
|
||||
|
||||
async function glob(pattern: string, options: GlobOptions): Promise<string[]> {
|
||||
return new Promise((resolve, reject) => {
|
||||
ogGlob(pattern, options, (err, files) => {
|
||||
err ? reject(err) : resolve(files);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes a hash for the given buf.
|
||||
*
|
||||
* @param {Buffer} file data
|
||||
* @return {String} hex digest
|
||||
*/
|
||||
function hash(buf: Buffer): string {
|
||||
return createHash('sha1').update(buf).digest('hex');
|
||||
}
|
||||
|
||||
interface NftFile {
|
||||
version: number;
|
||||
files: (string | { input: string; output: string })[];
|
||||
}
|
||||
|
||||
// resolveNftToOutput takes nft file and moves all of its trace files
|
||||
// into the specified directory + `inputs`, (renaming them to their hash + ext) and
|
||||
// subsequently updating the original nft file accordingly. This is done
|
||||
// to make the `.output` directory be self-contained, so that it works
|
||||
// properly with `vc --prebuilt`.
|
||||
async function resolveNftToOutput({
|
||||
client,
|
||||
cwd,
|
||||
outputDir,
|
||||
nftFileName,
|
||||
nft,
|
||||
}: {
|
||||
client: Client;
|
||||
cwd: string;
|
||||
outputDir: string;
|
||||
nftFileName: string;
|
||||
nft: NftFile;
|
||||
}) {
|
||||
client.output.debug(`Processing and resolving ${nftFileName}`);
|
||||
await fs.ensureDir(join(outputDir, 'inputs'));
|
||||
const newFilesList: NftFile['files'] = [];
|
||||
for (let fileEntity of nft.files) {
|
||||
const relativeInput: string =
|
||||
typeof fileEntity === 'string' ? fileEntity : fileEntity.input;
|
||||
const fullInput = resolve(join(parse(nftFileName).dir, relativeInput));
|
||||
|
||||
// if the resolved path is NOT in the .output directory we move in it there
|
||||
if (!fullInput.includes(outputDir)) {
|
||||
const { ext } = parse(fullInput);
|
||||
const raw = await fs.readFile(fullInput);
|
||||
const newFilePath = join(outputDir, 'inputs', hash(raw) + ext);
|
||||
smartCopy(client, fullInput, newFilePath);
|
||||
|
||||
newFilesList.push({
|
||||
input: relative(parse(nftFileName).dir, newFilePath),
|
||||
output: relative(cwd, fullInput).replace('.output', '.next'),
|
||||
});
|
||||
} else {
|
||||
newFilesList.push(relativeInput);
|
||||
}
|
||||
}
|
||||
// Update the .nft.json with new input and output mapping
|
||||
await fs.writeJSON(nftFileName, {
|
||||
...nft,
|
||||
files: newFilesList,
|
||||
});
|
||||
}
|
||||
@@ -18,9 +18,10 @@ export const help = () => `
|
||||
init [example] Initialize an example project
|
||||
ls | list [app] Lists deployments
|
||||
inspect [id] Displays information related to a deployment
|
||||
link Link local directory to a Vercel Project
|
||||
link [path] Link local directory to a Vercel Project
|
||||
login [email] Logs into your account or creates a new one
|
||||
logout Logs out of your account
|
||||
pull [path] Pull your Project Settings from the cloud
|
||||
switch [scope] Switches between teams and your personal account
|
||||
help [cmd] Displays complete help for [cmd]
|
||||
|
||||
|
||||
@@ -60,13 +60,10 @@ import { getCommandName } from '../../util/pkg-name';
|
||||
import { getPreferredPreviewURL } from '../../util/deploy/get-preferred-preview-url';
|
||||
import { Output } from '../../util/output';
|
||||
import { help } from './args';
|
||||
import { getDeploymentChecks } from '../../util/deploy/get-deployment-checks';
|
||||
|
||||
export default async (client: Client) => {
|
||||
const {
|
||||
apiUrl,
|
||||
output,
|
||||
authConfig: { token },
|
||||
} = client;
|
||||
const { output } = client;
|
||||
|
||||
let argv = null;
|
||||
|
||||
@@ -82,6 +79,7 @@ export default async (client: Client) => {
|
||||
// This is not an array in favor of matching
|
||||
// the config property name.
|
||||
'--regions': String,
|
||||
'--prebuilt': Boolean,
|
||||
'--prod': Boolean,
|
||||
'--confirm': Boolean,
|
||||
'-f': '--force',
|
||||
@@ -157,10 +155,8 @@ export default async (client: Client) => {
|
||||
}
|
||||
}
|
||||
|
||||
const { log, debug, error, warn } = output;
|
||||
const debugEnabled = argv['--debug'];
|
||||
const { log, debug, error, warn, isTTY } = output;
|
||||
|
||||
const { isTTY } = process.stdout;
|
||||
const quiet = !isTTY;
|
||||
|
||||
// check paths
|
||||
@@ -437,11 +433,8 @@ export default async (client: Client) => {
|
||||
|
||||
const currentTeam = org?.type === 'team' ? org.id : undefined;
|
||||
const now = new Now({
|
||||
apiUrl,
|
||||
token,
|
||||
debug: debugEnabled,
|
||||
client,
|
||||
currentTeam,
|
||||
output,
|
||||
});
|
||||
let deployStamp = stamp();
|
||||
let deployment = null;
|
||||
@@ -453,6 +446,7 @@ export default async (client: Client) => {
|
||||
build: { env: deploymentBuildEnv },
|
||||
forceNew: argv['--force'],
|
||||
withCache: argv['--with-cache'],
|
||||
prebuilt: argv['--prebuilt'],
|
||||
quiet,
|
||||
wantsPublic: argv['--public'] || localConfig.public,
|
||||
isFile,
|
||||
@@ -536,6 +530,20 @@ export default async (client: Client) => {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (deployment.checksConclusion === 'failed') {
|
||||
const { checks } = await getDeploymentChecks(client, deployment.id);
|
||||
const counters = new Map<string, number>();
|
||||
checks.forEach(c => {
|
||||
counters.set(c.conclusion, (counters.get(c.conclusion) ?? 0) + 1);
|
||||
});
|
||||
|
||||
const counterList = Array.from(counters)
|
||||
.map(([name, no]) => `${no} ${name}`)
|
||||
.join(', ');
|
||||
output.error(`Running Checks: ${counterList}`);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const deploymentResponse = await getDeploymentByIdOrHost(
|
||||
client,
|
||||
contextName,
|
||||
|
||||
@@ -121,7 +121,7 @@ export default async function main(client: Client) {
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOTFOUND') {
|
||||
// Error message will look like the following:
|
||||
// "request to https://api.vercel.com/www/user failed, reason: getaddrinfo ENOTFOUND api.vercel.com"
|
||||
// "request to https://api.vercel.com/v2/user failed, reason: getaddrinfo ENOTFOUND api.vercel.com"
|
||||
const matches = /getaddrinfo ENOTFOUND (.*)$/.exec(err.message || '');
|
||||
if (matches && matches[1]) {
|
||||
const hostname = matches[1];
|
||||
|
||||
@@ -194,8 +194,8 @@ async function findDestinationMatch(
|
||||
user: User,
|
||||
teams: Team[]
|
||||
) {
|
||||
if (user.uid === destination || user.username === destination) {
|
||||
return user.uid;
|
||||
if (user.id === destination || user.username === destination) {
|
||||
return user.id;
|
||||
}
|
||||
|
||||
for (const team of teams) {
|
||||
|
||||
21
packages/cli/src/commands/env/index.ts
vendored
21
packages/cli/src/commands/env/index.ts
vendored
@@ -1,18 +1,16 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import getArgs from '../../util/get-args';
|
||||
import getSubcommand from '../../util/get-subcommand';
|
||||
import getInvalidSubcommand from '../../util/get-invalid-subcommand';
|
||||
import { getEnvTargetPlaceholder } from '../../util/env/env-target';
|
||||
import { getLinkedProject } from '../../util/projects/link';
|
||||
import Client from '../../util/client';
|
||||
import { getEnvTargetPlaceholder } from '../../util/env/env-target';
|
||||
import getArgs from '../../util/get-args';
|
||||
import getInvalidSubcommand from '../../util/get-invalid-subcommand';
|
||||
import getSubcommand from '../../util/get-subcommand';
|
||||
import handleError from '../../util/handle-error';
|
||||
import logo from '../../util/output/logo';
|
||||
import { getCommandName, getPkgName } from '../../util/pkg-name';
|
||||
|
||||
import { getLinkedProject } from '../../util/projects/link';
|
||||
import add from './add';
|
||||
import pull from './pull';
|
||||
import ls from './ls';
|
||||
import pull from './pull';
|
||||
import rm from './rm';
|
||||
|
||||
const help = () => {
|
||||
@@ -139,6 +137,13 @@ export default async function main(client: Client) {
|
||||
case 'rm':
|
||||
return rm(client, project, argv, args, output);
|
||||
case 'pull':
|
||||
output.warn(
|
||||
`${getCommandName(
|
||||
'env pull'
|
||||
)} is deprecated and will be removed in future releases. Run ${getCommandName(
|
||||
'pull'
|
||||
)} instead.`
|
||||
);
|
||||
return pull(client, project, argv, args, output);
|
||||
default:
|
||||
output.error(getInvalidSubcommand(COMMAND_CONFIG));
|
||||
|
||||
21
packages/cli/src/commands/env/pull.ts
vendored
21
packages/cli/src/commands/env/pull.ts
vendored
@@ -1,18 +1,18 @@
|
||||
import chalk from 'chalk';
|
||||
import { closeSync, openSync, promises, readSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
import { Project } from '../../types';
|
||||
import { Output } from '../../util/output';
|
||||
import confirm from '../../util/input/confirm';
|
||||
import Client from '../../util/client';
|
||||
import stamp from '../../util/output/stamp';
|
||||
import getDecryptedEnvRecords from '../../util/get-decrypted-env-records';
|
||||
import param from '../../util/output/param';
|
||||
import { join } from 'path';
|
||||
import { promises, openSync, closeSync, readSync } from 'fs';
|
||||
import exposeSystemEnvs from '../../util/dev/expose-system-envs';
|
||||
import { emoji, prependEmoji } from '../../util/emoji';
|
||||
import getSystemEnvValues from '../../util/env/get-system-env-values';
|
||||
import getDecryptedEnvRecords from '../../util/get-decrypted-env-records';
|
||||
import confirm from '../../util/input/confirm';
|
||||
import { Output } from '../../util/output';
|
||||
import param from '../../util/output/param';
|
||||
import stamp from '../../util/output/stamp';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
const { writeFile } = promises;
|
||||
import exposeSystemEnvs from '../../util/dev/expose-system-envs';
|
||||
import getSystemEnvValues from '../../util/env/get-system-env-values';
|
||||
|
||||
const CONTENTS_PREFIX = '# Created by Vercel CLI\n';
|
||||
|
||||
@@ -56,8 +56,9 @@ export default async function pull(
|
||||
return 1;
|
||||
}
|
||||
|
||||
// handle relative or absolute filename
|
||||
const [filename = '.env'] = args;
|
||||
const fullPath = join(process.cwd(), filename);
|
||||
const fullPath = resolve(filename);
|
||||
const skipConfirmation = opts['--yes'];
|
||||
|
||||
const head = tryReadHeadSync(fullPath, Buffer.byteLength(CONTENTS_PREFIX));
|
||||
|
||||
@@ -2,6 +2,7 @@ export default new Map([
|
||||
['alias', 'alias'],
|
||||
['aliases', 'alias'],
|
||||
['billing', 'billing'],
|
||||
['build', 'build'],
|
||||
['cc', 'billing'],
|
||||
['cert', 'certs'],
|
||||
['certs', 'certs'],
|
||||
@@ -24,6 +25,7 @@ export default new Map([
|
||||
['ls', 'list'],
|
||||
['project', 'projects'],
|
||||
['projects', 'projects'],
|
||||
['pull', 'pull'],
|
||||
['remove', 'remove'],
|
||||
['rm', 'remove'],
|
||||
['secret', 'secrets'],
|
||||
|
||||
@@ -77,14 +77,8 @@ export default async function main(client: Client) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
apiUrl,
|
||||
config,
|
||||
} = client;
|
||||
const { output, config } = client;
|
||||
|
||||
const debugEnabled = argv['--debug'];
|
||||
const { print, log, error, note, debug, spinner } = output;
|
||||
|
||||
if (argv._.length > 2) {
|
||||
@@ -126,10 +120,7 @@ export default async function main(client: Client) {
|
||||
spinner(`Fetching deployments in ${chalk.bold(contextName)}`);
|
||||
|
||||
const now = new Now({
|
||||
apiUrl,
|
||||
token,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
client,
|
||||
currentTeam,
|
||||
});
|
||||
const start = Date.now();
|
||||
|
||||
114
packages/cli/src/commands/pull.ts
Normal file
114
packages/cli/src/commands/pull.ts
Normal file
@@ -0,0 +1,114 @@
|
||||
import chalk from 'chalk';
|
||||
import { join } from 'path';
|
||||
import Client from '../util/client';
|
||||
import { emoji, prependEmoji } from '../util/emoji';
|
||||
import getArgs from '../util/get-args';
|
||||
import handleError from '../util/handle-error';
|
||||
import setupAndLink from '../util/link/setup-and-link';
|
||||
import logo from '../util/output/logo';
|
||||
import stamp from '../util/output/stamp';
|
||||
import { getPkgName } from '../util/pkg-name';
|
||||
import {
|
||||
getLinkedProject,
|
||||
VERCEL_DIR,
|
||||
VERCEL_DIR_PROJECT,
|
||||
} from '../util/projects/link';
|
||||
import { writeProjectSettings } from '../util/projects/project-settings';
|
||||
import pull from './env/pull';
|
||||
|
||||
const help = () => {
|
||||
return console.log(`
|
||||
${chalk.bold(`${logo} ${getPkgName()} pull`)} [path]
|
||||
|
||||
${chalk.dim('Options:')}
|
||||
|
||||
-h, --help Output usage information
|
||||
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
|
||||
'FILE'
|
||||
)} Path to the local ${'`vercel.json`'} file
|
||||
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--env [filename] The file to write Development Environment Variables to [.env]
|
||||
-y, --yes Skip the confirmation prompt
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Pull the latest Project Settings from the cloud
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} pull`)}
|
||||
${chalk.cyan(`$ ${getPkgName()} pull ./path-to-project`)}
|
||||
${chalk.cyan(`$ ${getPkgName()} pull --env .env.local`)}
|
||||
${chalk.cyan(`$ ${getPkgName()} pull ./path-to-project --env .env.local`)}
|
||||
`);
|
||||
};
|
||||
export default async function main(client: Client) {
|
||||
let argv;
|
||||
try {
|
||||
argv = getArgs(client.argv.slice(2), {
|
||||
'--yes': Boolean,
|
||||
'--env': String,
|
||||
'--debug': Boolean,
|
||||
'-d': '--debug',
|
||||
'-y': '--yes',
|
||||
});
|
||||
} catch (err) {
|
||||
handleError(err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (argv['--help']) {
|
||||
help();
|
||||
return 2;
|
||||
}
|
||||
|
||||
const cwd = argv._[1] || process.cwd();
|
||||
const yes = argv['--yes'];
|
||||
const env = argv['--env'] ?? '.env';
|
||||
const settingsStamp = stamp();
|
||||
let link = await getLinkedProject(client, cwd);
|
||||
if (link.status === 'not_linked') {
|
||||
link = await setupAndLink(client, cwd, {
|
||||
autoConfirm: yes,
|
||||
successEmoji: 'link',
|
||||
setupMsg: 'Set up',
|
||||
});
|
||||
|
||||
if (link.status === 'not_linked') {
|
||||
// User aborted project linking questions
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (link.status === 'error') {
|
||||
return link.exitCode;
|
||||
}
|
||||
|
||||
const { project, org } = link;
|
||||
|
||||
const result = await pull(
|
||||
client,
|
||||
project,
|
||||
argv,
|
||||
[join(cwd, env)],
|
||||
client.output
|
||||
);
|
||||
if (result !== 0) {
|
||||
// an error happened
|
||||
return result;
|
||||
}
|
||||
|
||||
await writeProjectSettings(cwd, project, org);
|
||||
|
||||
client.output.print(
|
||||
`${prependEmoji(
|
||||
`Downloaded project settings to ${chalk.bold(
|
||||
join(VERCEL_DIR, VERCEL_DIR_PROJECT)
|
||||
)} ${chalk.gray(settingsStamp())}`,
|
||||
emoji('success')
|
||||
)}\n`
|
||||
);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -85,8 +85,6 @@ export default async function main(client: Client) {
|
||||
argv._ = argv._.slice(1);
|
||||
|
||||
const {
|
||||
apiUrl,
|
||||
authConfig: { token },
|
||||
output,
|
||||
config: { currentTeam },
|
||||
} = client;
|
||||
@@ -245,11 +243,8 @@ export default async function main(client: Client) {
|
||||
}
|
||||
|
||||
const now = new Now({
|
||||
apiUrl,
|
||||
token,
|
||||
debug: argv['--debug'],
|
||||
client,
|
||||
currentTeam,
|
||||
output,
|
||||
});
|
||||
const start = Date.now();
|
||||
|
||||
|
||||
@@ -72,8 +72,6 @@ const help = () => {
|
||||
|
||||
// Options
|
||||
let argv;
|
||||
let debug;
|
||||
let apiUrl;
|
||||
let subcommand;
|
||||
let nextTimestamp;
|
||||
|
||||
@@ -90,8 +88,6 @@ const main = async client => {
|
||||
|
||||
argv._ = argv._.slice(1);
|
||||
|
||||
debug = argv.debug;
|
||||
apiUrl = client.apiUrl;
|
||||
subcommand = argv._[0];
|
||||
nextTimestamp = argv.next;
|
||||
|
||||
@@ -101,7 +97,6 @@ const main = async client => {
|
||||
}
|
||||
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config: { currentTeam },
|
||||
} = client;
|
||||
@@ -118,7 +113,7 @@ const main = async client => {
|
||||
throw err;
|
||||
}
|
||||
|
||||
return run({ output, token, contextName, currentTeam, client });
|
||||
return run({ output, contextName, currentTeam, client });
|
||||
};
|
||||
|
||||
export default async client => {
|
||||
@@ -130,8 +125,8 @@ export default async client => {
|
||||
}
|
||||
};
|
||||
|
||||
async function run({ output, token, contextName, currentTeam, client }) {
|
||||
const secrets = new NowSecrets({ apiUrl, token, debug, currentTeam, output });
|
||||
async function run({ output, contextName, currentTeam, client }) {
|
||||
const secrets = new NowSecrets({ client, currentTeam });
|
||||
const args = argv._.slice(1);
|
||||
const start = Date.now();
|
||||
const { 'test-warning': testWarningFlag } = argv;
|
||||
|
||||
@@ -56,7 +56,7 @@ export default async function list(client: Client): Promise<number> {
|
||||
}
|
||||
|
||||
if (accountIsCurrent) {
|
||||
currentTeam = user.uid;
|
||||
currentTeam = user.id;
|
||||
}
|
||||
|
||||
const teamList = teams.map(({ id, slug, name }) => ({
|
||||
@@ -67,7 +67,7 @@ export default async function list(client: Client): Promise<number> {
|
||||
}));
|
||||
|
||||
teamList.unshift({
|
||||
id: user.uid,
|
||||
id: user.id,
|
||||
name: user.email,
|
||||
value: user.username || user.email,
|
||||
current: accountIsCurrent ? chars.tick : '',
|
||||
|
||||
@@ -164,9 +164,15 @@ const main = async () => {
|
||||
output.print(
|
||||
`${chalk.grey(
|
||||
`${getTitleName()} CLI ${pkg.version}${
|
||||
targetOrSubcommand === 'dev' ? ' dev (beta)' : ''
|
||||
targetOrSubcommand === 'dev'
|
||||
? ' dev (beta)'
|
||||
: targetOrSubcommand === 'build'
|
||||
? ' build (beta)'
|
||||
: ''
|
||||
}${
|
||||
isCanary || targetOrSubcommand === 'dev'
|
||||
isCanary ||
|
||||
targetOrSubcommand === 'dev' ||
|
||||
targetOrSubcommand === 'build'
|
||||
? ' — https://vercel.com/feedback'
|
||||
: ''
|
||||
}`
|
||||
@@ -286,7 +292,14 @@ const main = async () => {
|
||||
|
||||
let authConfig = null;
|
||||
|
||||
const subcommandsWithoutToken = ['login', 'logout', 'help', 'init', 'update'];
|
||||
const subcommandsWithoutToken = [
|
||||
'login',
|
||||
'logout',
|
||||
'help',
|
||||
'init',
|
||||
'update',
|
||||
'build',
|
||||
];
|
||||
|
||||
if (authConfigExists) {
|
||||
try {
|
||||
@@ -393,20 +406,33 @@ const main = async () => {
|
||||
} else if (commands.has(singular)) {
|
||||
alternative = singular;
|
||||
}
|
||||
console.error(
|
||||
error(
|
||||
`The supplied argument ${param(targetOrSubcommand)} is ambiguous.` +
|
||||
`\nIf you wish to deploy the ${fileType} ${param(
|
||||
targetOrSubcommand
|
||||
)}, first run "cd ${targetOrSubcommand}". ` +
|
||||
if (targetOrSubcommand === 'build') {
|
||||
output.note(
|
||||
`If you wish to deploy the ${fileType} ${param(
|
||||
targetOrSubcommand
|
||||
)}, run ${getCommandName('deploy build')}.` +
|
||||
(alternative
|
||||
? `\nIf you wish to use the subcommand ${param(
|
||||
targetOrSubcommand
|
||||
)}, use ${param(alternative)} instead.`
|
||||
: '')
|
||||
)
|
||||
);
|
||||
return 1;
|
||||
);
|
||||
} else {
|
||||
console.error(
|
||||
error(
|
||||
`The supplied argument ${param(targetOrSubcommand)} is ambiguous.` +
|
||||
`\nIf you wish to deploy the ${fileType} ${param(
|
||||
targetOrSubcommand
|
||||
)}, first run "cd ${targetOrSubcommand}". ` +
|
||||
(alternative
|
||||
? `\nIf you wish to use the subcommand ${param(
|
||||
targetOrSubcommand
|
||||
)}, use ${param(alternative)} instead.`
|
||||
: '')
|
||||
)
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (subcommandExists) {
|
||||
@@ -550,7 +576,7 @@ const main = async () => {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (user.uid === scope || user.email === scope || user.username === scope) {
|
||||
if (user.id === scope || user.email === scope || user.username === scope) {
|
||||
delete client.config.currentTeam;
|
||||
} else {
|
||||
let teams = [];
|
||||
@@ -587,20 +613,99 @@ const main = async () => {
|
||||
}
|
||||
}
|
||||
|
||||
if (!targetCommand) {
|
||||
const sub = param(subcommand);
|
||||
console.error(error(`The ${sub} subcommand does not exist`));
|
||||
return 1;
|
||||
}
|
||||
|
||||
const metric = metrics();
|
||||
let exitCode;
|
||||
const eventCategory = 'Exit Code';
|
||||
|
||||
try {
|
||||
const start = Date.now();
|
||||
const full = require(`./commands/${targetCommand}`).default;
|
||||
exitCode = await full(client);
|
||||
let func: any;
|
||||
switch (targetCommand) {
|
||||
case 'alias':
|
||||
func = await import('./commands/alias');
|
||||
break;
|
||||
case 'billing':
|
||||
func = await import('./commands/billing');
|
||||
break;
|
||||
case 'build':
|
||||
func = await import('./commands/build');
|
||||
break;
|
||||
case 'certs':
|
||||
func = await import('./commands/certs');
|
||||
break;
|
||||
case 'deploy':
|
||||
func = await import('./commands/deploy');
|
||||
break;
|
||||
case 'dev':
|
||||
func = await import('./commands/dev');
|
||||
break;
|
||||
case 'dns':
|
||||
func = await import('./commands/dns');
|
||||
break;
|
||||
case 'domains':
|
||||
func = await import('./commands/domains');
|
||||
break;
|
||||
case 'env':
|
||||
func = await import('./commands/env');
|
||||
break;
|
||||
case 'init':
|
||||
func = await import('./commands/init');
|
||||
break;
|
||||
case 'inspect':
|
||||
func = await import('./commands/inspect');
|
||||
break;
|
||||
case 'link':
|
||||
func = await import('./commands/link');
|
||||
break;
|
||||
case 'list':
|
||||
func = await import('./commands/list');
|
||||
break;
|
||||
case 'logs':
|
||||
func = await import('./commands/logs');
|
||||
break;
|
||||
case 'login':
|
||||
func = await import('./commands/login');
|
||||
break;
|
||||
case 'logout':
|
||||
func = await import('./commands/logout');
|
||||
break;
|
||||
case 'projects':
|
||||
func = await import('./commands/projects');
|
||||
break;
|
||||
case 'pull':
|
||||
func = await import('./commands/pull');
|
||||
break;
|
||||
case 'remove':
|
||||
func = await import('./commands/remove');
|
||||
break;
|
||||
case 'secrets':
|
||||
func = await import('./commands/secrets');
|
||||
break;
|
||||
case 'teams':
|
||||
func = await import('./commands/teams');
|
||||
break;
|
||||
case 'update':
|
||||
func = await import('./commands/update');
|
||||
break;
|
||||
case 'whoami':
|
||||
func = await import('./commands/whoami');
|
||||
break;
|
||||
default:
|
||||
func = null;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!func || !targetCommand) {
|
||||
const sub = param(subcommand);
|
||||
output.error(`The ${sub} subcommand does not exist`);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (func.default) {
|
||||
func = func.default;
|
||||
}
|
||||
|
||||
exitCode = await func(client);
|
||||
const end = Date.now() - start;
|
||||
|
||||
if (shouldCollectMetrics) {
|
||||
@@ -614,7 +719,7 @@ const main = async () => {
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOTFOUND') {
|
||||
// Error message will look like the following:
|
||||
// "request to https://api.vercel.com/www/user failed, reason: getaddrinfo ENOTFOUND api.vercel.com"
|
||||
// "request to https://api.vercel.com/v2/user failed, reason: getaddrinfo ENOTFOUND api.vercel.com"
|
||||
const matches = /getaddrinfo ENOTFOUND (.*)$/.exec(err.message || '');
|
||||
if (matches && matches[1]) {
|
||||
const hostname = matches[1];
|
||||
|
||||
@@ -45,25 +45,12 @@ type Billing = {
|
||||
};
|
||||
|
||||
export type User = {
|
||||
uid: string;
|
||||
id: string;
|
||||
avatar: string;
|
||||
bio?: string;
|
||||
date: number;
|
||||
createdAt: number;
|
||||
email: string;
|
||||
username: string;
|
||||
website?: string;
|
||||
billingChecked: boolean;
|
||||
billing: Billing;
|
||||
github?: {
|
||||
email: string;
|
||||
installation: {
|
||||
id: string;
|
||||
login: string;
|
||||
loginType: string;
|
||||
};
|
||||
login: string;
|
||||
updatedAt: number;
|
||||
};
|
||||
name?: string;
|
||||
limited?: boolean;
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ async function getAppLastDeployment(
|
||||
const deployments = await getDeploymentsByAppName(client, appName);
|
||||
const deploymentItem = deployments
|
||||
.sort((a, b) => b.created - a.created)
|
||||
.filter(dep => dep.state === 'READY' && dep.creator.uid === user.uid)[0];
|
||||
.filter(dep => dep.state === 'READY' && dep.creator.uid === user.id)[0];
|
||||
|
||||
// Try to fetch deployment details
|
||||
if (deploymentItem) {
|
||||
|
||||
@@ -100,7 +100,7 @@ export default class Client extends EventEmitter {
|
||||
let body;
|
||||
if (isJSONObject(opts.body)) {
|
||||
body = JSON.stringify(opts.body);
|
||||
headers.set('content-type', 'application/json; charset=utf8');
|
||||
headers.set('content-type', 'application/json; charset=utf-8');
|
||||
} else {
|
||||
body = opts.body;
|
||||
}
|
||||
|
||||
37
packages/cli/src/util/deploy/get-deployment-checks.ts
Normal file
37
packages/cli/src/util/deploy/get-deployment-checks.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import Client from '../client';
|
||||
|
||||
type CheckStatus = 'registered' | 'running' | 'completed';
|
||||
type CheckConclusion =
|
||||
| 'canceled'
|
||||
| 'failed'
|
||||
| 'neutral'
|
||||
| 'succeeded'
|
||||
| 'skipped'
|
||||
| 'stale';
|
||||
|
||||
export interface DeploymentCheck {
|
||||
id: string;
|
||||
status: CheckStatus;
|
||||
conclusion: CheckConclusion;
|
||||
name: string;
|
||||
startedAt: number;
|
||||
completedAt: number;
|
||||
createdAt: number;
|
||||
updatedAt: number;
|
||||
integrationId: string;
|
||||
rerequestable: boolean;
|
||||
}
|
||||
|
||||
export interface DeploymentChecksResponse {
|
||||
checks: DeploymentCheck[];
|
||||
}
|
||||
|
||||
export async function getDeploymentChecks(
|
||||
client: Client,
|
||||
deploymentId: string
|
||||
) {
|
||||
const checksResponse = await client.fetch<DeploymentChecksResponse>(
|
||||
`/v1/deployments/${encodeURIComponent(deploymentId)}/checks`
|
||||
);
|
||||
return checksResponse;
|
||||
}
|
||||
@@ -47,6 +47,7 @@ export default async function processDeployment({
|
||||
force?: boolean;
|
||||
withCache?: boolean;
|
||||
org: Org;
|
||||
prebuilt: boolean;
|
||||
projectName: string;
|
||||
isSettingUpProject: boolean;
|
||||
skipAutoDetectionConfirmation?: boolean;
|
||||
@@ -62,6 +63,7 @@ export default async function processDeployment({
|
||||
withCache,
|
||||
nowConfig,
|
||||
quiet,
|
||||
prebuilt,
|
||||
} = args;
|
||||
|
||||
const { debug } = output;
|
||||
@@ -83,6 +85,7 @@ export default async function processDeployment({
|
||||
path: paths[0],
|
||||
force,
|
||||
withCache,
|
||||
prebuilt,
|
||||
skipAutoDetectionConfirmation,
|
||||
};
|
||||
|
||||
@@ -179,10 +182,26 @@ export default async function processDeployment({
|
||||
return event.payload;
|
||||
}
|
||||
|
||||
if (event.type === 'ready') {
|
||||
// If `checksState` is present, we can only continue to "Completing" if the checks finished,
|
||||
// otherwise we might show "Completing" before "Running Checks".
|
||||
if (
|
||||
event.type === 'ready' &&
|
||||
(event.payload.checksState
|
||||
? event.payload.checksState === 'completed'
|
||||
: true)
|
||||
) {
|
||||
output.spinner('Completing', 0);
|
||||
}
|
||||
|
||||
if (event.type === 'checks-running') {
|
||||
output.spinner('Running Checks', 0);
|
||||
}
|
||||
|
||||
if (event.type === 'checks-conclusion-failed') {
|
||||
output.stopSpinner();
|
||||
return event.payload;
|
||||
}
|
||||
|
||||
// Handle error events
|
||||
if (event.type === 'error') {
|
||||
output.stopSpinner();
|
||||
|
||||
@@ -217,13 +217,13 @@ export async function executeBuild(
|
||||
|
||||
if (output.maxDuration) {
|
||||
throw new Error(
|
||||
'The result of "builder.build()" must not contain `memory`'
|
||||
'The result of "builder.build()" must not contain `maxDuration`'
|
||||
);
|
||||
}
|
||||
|
||||
if (output.memory) {
|
||||
throw new Error(
|
||||
'The result of "builder.build()" must not contain `maxDuration`'
|
||||
'The result of "builder.build()" must not contain `memory`'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { APIError, InvalidToken, MissingUser } from './errors-ts';
|
||||
|
||||
export default async function getUser(client: Client) {
|
||||
try {
|
||||
const res = await client.fetch<{ user: User }>('/www/user', {
|
||||
const res = await client.fetch<{ user: User }>('/v2/user', {
|
||||
useCurrentTeam: false,
|
||||
});
|
||||
|
||||
|
||||
@@ -10,25 +10,21 @@ import chalk from 'chalk';
|
||||
import ua from './ua';
|
||||
import processDeployment from './deploy/process-deployment';
|
||||
import highlight from './output/highlight';
|
||||
import createOutput, { Output } from './output';
|
||||
import { responseError } from './error';
|
||||
import stamp from './output/stamp';
|
||||
import { APIError, BuildError } from './errors-ts';
|
||||
import printIndications from './print-indications';
|
||||
import { Org } from '../types';
|
||||
import { VercelConfig } from './dev/types';
|
||||
import { FetchOptions, isJSONObject } from './client';
|
||||
import Client, { FetchOptions, isJSONObject } from './client';
|
||||
import { Dictionary } from '@vercel/client';
|
||||
|
||||
export interface NowOptions {
|
||||
apiUrl: string;
|
||||
token?: string;
|
||||
client: Client;
|
||||
url?: string | null;
|
||||
currentTeam?: string | null;
|
||||
output: Output;
|
||||
forceNew?: boolean;
|
||||
withCache?: boolean;
|
||||
debug?: boolean;
|
||||
}
|
||||
|
||||
export interface CreateOptions {
|
||||
@@ -40,6 +36,7 @@ export interface CreateOptions {
|
||||
name: string;
|
||||
project?: string;
|
||||
wantsPublic: boolean;
|
||||
prebuilt?: boolean;
|
||||
meta: Dictionary<string>;
|
||||
regions?: string[];
|
||||
quiet?: boolean;
|
||||
@@ -66,39 +63,46 @@ export interface ListOptions {
|
||||
export default class Now extends EventEmitter {
|
||||
url: string | null;
|
||||
currentTeam: string | null;
|
||||
_apiUrl: string;
|
||||
_token?: string;
|
||||
_debug: boolean;
|
||||
_client: Client;
|
||||
_forceNew: boolean;
|
||||
_withCache: boolean;
|
||||
_output: Output;
|
||||
_syncAmount?: number;
|
||||
_files?: any[];
|
||||
_missing?: string[];
|
||||
|
||||
constructor({
|
||||
apiUrl,
|
||||
token,
|
||||
client,
|
||||
url = null,
|
||||
currentTeam = null,
|
||||
forceNew = false,
|
||||
withCache = false,
|
||||
debug = false,
|
||||
output = createOutput({ debug }),
|
||||
}: NowOptions) {
|
||||
super();
|
||||
|
||||
this.url = url;
|
||||
this._token = token;
|
||||
this._debug = debug;
|
||||
this._client = client;
|
||||
this._forceNew = forceNew;
|
||||
this._withCache = withCache;
|
||||
this._output = output;
|
||||
this._apiUrl = apiUrl;
|
||||
this._onRetry = this._onRetry.bind(this);
|
||||
this.currentTeam = currentTeam;
|
||||
}
|
||||
|
||||
get _apiUrl() {
|
||||
return this._client.apiUrl;
|
||||
}
|
||||
|
||||
get _token() {
|
||||
return this._client.authConfig.token;
|
||||
}
|
||||
|
||||
get _output() {
|
||||
return this._client.output;
|
||||
}
|
||||
|
||||
get _debug() {
|
||||
return this._client.output.isDebugEnabled();
|
||||
}
|
||||
|
||||
async create(
|
||||
paths: string[],
|
||||
{
|
||||
@@ -108,6 +112,7 @@ export default class Now extends EventEmitter {
|
||||
// Latest
|
||||
name,
|
||||
project,
|
||||
prebuilt = false,
|
||||
wantsPublic,
|
||||
meta,
|
||||
regions,
|
||||
@@ -162,6 +167,7 @@ export default class Now extends EventEmitter {
|
||||
isSettingUpProject,
|
||||
skipAutoDetectionConfirmation,
|
||||
cwd,
|
||||
prebuilt,
|
||||
});
|
||||
|
||||
if (deployment && deployment.warnings) {
|
||||
|
||||
@@ -29,7 +29,7 @@ export default async function selectOrg(
|
||||
const choices: Choice[] = [
|
||||
{
|
||||
name: user.name || user.username,
|
||||
value: { type: 'user', id: user.uid, slug: user.username },
|
||||
value: { type: 'user', id: user.id, slug: user.username },
|
||||
},
|
||||
...teams.map<Choice>(team => ({
|
||||
name: team.name || team.slug,
|
||||
|
||||
@@ -43,13 +43,7 @@ export default async function setupAndLink(
|
||||
projectName,
|
||||
}: SetupAndLinkOptions
|
||||
): Promise<ProjectLinkResult> {
|
||||
const {
|
||||
authConfig: { token },
|
||||
localConfig,
|
||||
apiUrl,
|
||||
output,
|
||||
config,
|
||||
} = client;
|
||||
const { localConfig, output, config } = client;
|
||||
const debug = output.isDebugEnabled();
|
||||
|
||||
const isFile = !isDirectory(path);
|
||||
@@ -153,10 +147,7 @@ export default async function setupAndLink(
|
||||
|
||||
if (isZeroConfig) {
|
||||
const now = new Now({
|
||||
apiUrl,
|
||||
token,
|
||||
debug,
|
||||
output,
|
||||
client,
|
||||
currentTeam: config.currentTeam,
|
||||
});
|
||||
const createArgs: CreateOptions = {
|
||||
|
||||
@@ -31,5 +31,5 @@ export default function verify(
|
||||
url.searchParams.set('ssoUserId', ssoUserId);
|
||||
}
|
||||
|
||||
return client.fetch<LoginResultSuccess>(url.href);
|
||||
return client.fetch<LoginResultSuccess>(url.href, { useCurrentTeam: false });
|
||||
}
|
||||
|
||||
24
packages/cli/src/util/output/color-name-cache.ts
Normal file
24
packages/cli/src/util/output/color-name-cache.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
const colors = [
|
||||
chalk.cyan,
|
||||
chalk.magenta,
|
||||
chalk.green,
|
||||
chalk.yellow,
|
||||
chalk.blue,
|
||||
];
|
||||
|
||||
let childIndex = 0;
|
||||
const packageNameColorCache = new Map<string, chalk.Chalk>();
|
||||
|
||||
/** Return a consistent (gradient) color for a given package name */
|
||||
export function getColorForPkgName(pkgName: string) {
|
||||
let color = packageNameColorCache.get(pkgName);
|
||||
|
||||
if (!color) {
|
||||
color = colors[childIndex++ % colors.length];
|
||||
packageNameColorCache.set(pkgName, color);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
@@ -20,15 +20,13 @@ export class Output {
|
||||
private debugEnabled: boolean;
|
||||
private spinnerMessage: string;
|
||||
private _spinner: StopSpinner | null;
|
||||
isTTY: boolean;
|
||||
|
||||
constructor({ debug: debugEnabled = false }: OutputOptions = {}) {
|
||||
this.debugEnabled = debugEnabled;
|
||||
this.spinnerMessage = '';
|
||||
this._spinner = null;
|
||||
}
|
||||
|
||||
get isTTY() {
|
||||
return process.stdout.isTTY;
|
||||
this.isTTY = process.stdout.isTTY || false;
|
||||
}
|
||||
|
||||
isDebugEnabled = () => {
|
||||
|
||||
5
packages/cli/src/util/projects/find-framework.ts
Normal file
5
packages/cli/src/util/projects/find-framework.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { Framework, frameworks } from '@vercel/frameworks';
|
||||
|
||||
export function findFramework(slug?: string | null) {
|
||||
return (frameworks as any as Framework[]).find(f => f.slug === slug);
|
||||
}
|
||||
@@ -23,6 +23,7 @@ const readFile = promisify(fs.readFile);
|
||||
const writeFile = promisify(fs.writeFile);
|
||||
|
||||
export const VERCEL_DIR = '.vercel';
|
||||
export const VERCEL_OUTPUT_DIR = '.output';
|
||||
export const VERCEL_DIR_FALLBACK = '.now';
|
||||
export const VERCEL_DIR_README = 'README.txt';
|
||||
export const VERCEL_DIR_PROJECT = 'project.json';
|
||||
@@ -67,12 +68,14 @@ async function getLink(path?: string): Promise<ProjectLink | null> {
|
||||
return getLinkFromDir(dir);
|
||||
}
|
||||
|
||||
async function getLinkFromDir(dir: string): Promise<ProjectLink | null> {
|
||||
export async function getLinkFromDir<T = ProjectLink>(
|
||||
dir: string
|
||||
): Promise<T | null> {
|
||||
try {
|
||||
const json = await readFile(join(dir, VERCEL_DIR_PROJECT), 'utf8');
|
||||
|
||||
const ajv = new AJV();
|
||||
const link: ProjectLink = JSON.parse(json);
|
||||
const link: T = JSON.parse(json);
|
||||
|
||||
if (!ajv.validate(linkSchema, link)) {
|
||||
throw new Error(
|
||||
@@ -106,7 +109,7 @@ async function getOrgById(client: Client, orgId: string): Promise<Org | null> {
|
||||
}
|
||||
|
||||
const user = await getUser(client);
|
||||
if (user.uid !== orgId) return null;
|
||||
if (user.id !== orgId) return null;
|
||||
return { type: 'user', id: orgId, slug: user.username };
|
||||
}
|
||||
|
||||
@@ -244,12 +247,16 @@ export async function linkFolderToProject(
|
||||
const gitIgnore = await readFile(gitIgnorePath, 'utf8').catch(() => null);
|
||||
const EOL = gitIgnore && gitIgnore.includes('\r\n') ? '\r\n' : os.EOL;
|
||||
|
||||
if (!gitIgnore || !gitIgnore.split(EOL).includes(VERCEL_DIR)) {
|
||||
if (
|
||||
!gitIgnore ||
|
||||
!gitIgnore.split(EOL).includes(VERCEL_DIR) ||
|
||||
!gitIgnore.split(EOL).includes(VERCEL_OUTPUT_DIR)
|
||||
) {
|
||||
await writeFile(
|
||||
gitIgnorePath,
|
||||
gitIgnore
|
||||
? `${gitIgnore}${EOL}${VERCEL_DIR}${EOL}`
|
||||
: `${VERCEL_DIR}${EOL}`
|
||||
? `${gitIgnore}${EOL}${VERCEL_DIR}${EOL}${VERCEL_OUTPUT_DIR}${EOL}`
|
||||
: `${VERCEL_DIR}${EOL}${VERCEL_OUTPUT_DIR}${EOL}`
|
||||
);
|
||||
isGitIgnoreUpdated = true;
|
||||
}
|
||||
|
||||
42
packages/cli/src/util/projects/project-settings.ts
Normal file
42
packages/cli/src/util/projects/project-settings.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { writeFile } from 'fs-extra';
|
||||
import { Org, Project, ProjectLink } from '../../types';
|
||||
import { getLinkFromDir, VERCEL_DIR, VERCEL_DIR_PROJECT } from './link';
|
||||
import { join } from 'path';
|
||||
|
||||
export type ProjectLinkAndSettings = ProjectLink & {
|
||||
settings: {
|
||||
buildCommand: Project['buildCommand'];
|
||||
devCommand: Project['devCommand'];
|
||||
outputDirectory: Project['outputDirectory'];
|
||||
rootDirectory: Project['rootDirectory'];
|
||||
framework: Project['framework'];
|
||||
};
|
||||
};
|
||||
|
||||
// writeProjectSettings writes the project configuration to `vercel/project.json`
|
||||
// Write the project configuration to `.vercel/project.json`
|
||||
// that is needed for `vercel build` and `vercel dev` commands
|
||||
export async function writeProjectSettings(
|
||||
cwd: string,
|
||||
project: Project,
|
||||
org: Org
|
||||
) {
|
||||
return await writeFile(
|
||||
join(cwd, VERCEL_DIR, VERCEL_DIR_PROJECT),
|
||||
JSON.stringify({
|
||||
projectId: project.id,
|
||||
orgId: org.id,
|
||||
settings: {
|
||||
buildCommand: project.buildCommand,
|
||||
devCommand: project.devCommand,
|
||||
directoryListing: project.directoryListing,
|
||||
rootDirectory: project.rootDirectory,
|
||||
framework: project.framework,
|
||||
},
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export async function readProjectSettings(cwd: string) {
|
||||
return await getLinkFromDir<ProjectLinkAndSettings>(cwd);
|
||||
}
|
||||
@@ -27,7 +27,7 @@ export default async function reportError(
|
||||
if (user) {
|
||||
const spec = {
|
||||
email: user.email,
|
||||
id: user.uid,
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
name: (user as any).name,
|
||||
};
|
||||
|
||||
@@ -23,7 +23,7 @@ describe('inspect', () => {
|
||||
client.setArgv('inspect', 'bad.com');
|
||||
const exitCode = await inspect(client);
|
||||
expect(exitCode).toEqual(1);
|
||||
expect(client.mockOutput.mock.calls[0][0]).toEqual(
|
||||
expect(client.outputBuffer).toEqual(
|
||||
`Error! Failed to find deployment "bad.com" in ${user.username}\n`
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
import { client } from '../mocks/client';
|
||||
import login from '../../src/commands/login';
|
||||
import { client } from '../mocks/client';
|
||||
import { useUser } from '../mocks/user';
|
||||
|
||||
describe('login', () => {
|
||||
it('should not allow the `--token` flag', async () => {
|
||||
client.setArgv('login', '--token', 'foo');
|
||||
const exitCode = await login(client);
|
||||
expect(exitCode).toEqual(2);
|
||||
expect(client.mockOutput.mock.calls.length).toEqual(1);
|
||||
expect(client.outputBuffer).toEqual(
|
||||
'Error! `--token` may not be used with the "login" command\n'
|
||||
);
|
||||
});
|
||||
|
||||
it('should allow login via email as argument', async () => {
|
||||
const user = useUser();
|
||||
client.setArgv('login', user.email);
|
||||
const exitCode = await login(client);
|
||||
expect(exitCode).toEqual(0);
|
||||
expect(
|
||||
client.mockOutput.mock.calls[0][0].includes(
|
||||
'`--token` may not be used with the "login" command'
|
||||
client.outputBuffer.includes(
|
||||
`Success! Email authentication complete for ${user.email}`
|
||||
)
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
45
packages/cli/test/commands/pull.test.ts
Normal file
45
packages/cli/test/commands/pull.test.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import pull from '../../src/commands/pull';
|
||||
import { setupFixture } from '../helpers/setup-fixture';
|
||||
import { client } from '../mocks/client';
|
||||
import { defaultProject, useProject } from '../mocks/project';
|
||||
import { useTeams } from '../mocks/team';
|
||||
import { useUser } from '../mocks/user';
|
||||
|
||||
describe('pull', () => {
|
||||
it('should handle pulling', async () => {
|
||||
const cwd = setupFixture('vercel-pull-next');
|
||||
useUser();
|
||||
useTeams();
|
||||
useProject({
|
||||
...defaultProject,
|
||||
id: 'vercel-pull-next',
|
||||
name: 'vercel-pull-next',
|
||||
});
|
||||
client.setArgv('pull', '--yes', cwd);
|
||||
const exitCode = await pull(client);
|
||||
expect(exitCode).toEqual(0);
|
||||
});
|
||||
|
||||
it('should handle custom --env flag', async () => {
|
||||
const cwd = setupFixture('vercel-pull-next');
|
||||
useUser();
|
||||
useTeams();
|
||||
useProject({
|
||||
...defaultProject,
|
||||
id: 'vercel-pull-next',
|
||||
name: 'vercel-pull-next',
|
||||
});
|
||||
const expectedEnvFilename = '.env.vercel';
|
||||
client.setArgv('pull', '--yes', `--env=${expectedEnvFilename}`, cwd);
|
||||
|
||||
const exitCode = await pull(client);
|
||||
const actualEnv = await fs.pathExists(path.join(cwd, expectedEnvFilename));
|
||||
const raw = await fs.readFile(path.join(cwd, expectedEnvFilename));
|
||||
|
||||
expect(exitCode).toEqual(0);
|
||||
expect(actualEnv).toBeTruthy();
|
||||
expect(raw.includes('# Created by Vercel CLI')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -14,7 +14,14 @@ describe('whoami', () => {
|
||||
const user = useUser();
|
||||
const exitCode = await whoami(client);
|
||||
expect(exitCode).toEqual(0);
|
||||
expect(client.mockOutput.mock.calls.length).toEqual(1);
|
||||
expect(client.mockOutput.mock.calls[0][0]).toEqual(`${user.username}\n`);
|
||||
expect(client.outputBuffer).toEqual(`> ${user.username}\n`);
|
||||
});
|
||||
|
||||
it('should print only the Vercel username when output is not a TTY', async () => {
|
||||
const user = useUser();
|
||||
client.output.isTTY = false;
|
||||
const exitCode = await whoami(client);
|
||||
expect(exitCode).toEqual(0);
|
||||
expect(client.outputBuffer).toEqual(`${user.username}\n`);
|
||||
});
|
||||
});
|
||||
|
||||
69
packages/cli/test/fixtures/unit/vercel-build-gatsby/.gitignore
vendored
Normal file
69
packages/cli/test/fixtures/unit/vercel-build-gatsby/.gitignore
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# dotenv environment variable files
|
||||
.env*
|
||||
|
||||
# gatsby files
|
||||
.cache/
|
||||
public
|
||||
|
||||
# Mac files
|
||||
.DS_Store
|
||||
|
||||
# Yarn
|
||||
yarn-error.log
|
||||
.pnp/
|
||||
.pnp.js
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
4
packages/cli/test/fixtures/unit/vercel-build-gatsby/.prettierignore
vendored
Normal file
4
packages/cli/test/fixtures/unit/vercel-build-gatsby/.prettierignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.cache
|
||||
package.json
|
||||
package-lock.json
|
||||
public
|
||||
7
packages/cli/test/fixtures/unit/vercel-build-gatsby/.prettierrc
vendored
Normal file
7
packages/cli/test/fixtures/unit/vercel-build-gatsby/.prettierrc
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"endOfLine": "lf",
|
||||
"semi": false,
|
||||
"singleQuote": false,
|
||||
"tabWidth": 2,
|
||||
"trailingComma": "es5"
|
||||
}
|
||||
22
packages/cli/test/fixtures/unit/vercel-build-gatsby/LICENSE
vendored
Normal file
22
packages/cli/test/fixtures/unit/vercel-build-gatsby/LICENSE
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 gatsbyjs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
97
packages/cli/test/fixtures/unit/vercel-build-gatsby/README.md
vendored
Normal file
97
packages/cli/test/fixtures/unit/vercel-build-gatsby/README.md
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
<!-- AUTO-GENERATED-CONTENT:START (STARTER) -->
|
||||
<p align="center">
|
||||
<a href="https://www.gatsbyjs.org">
|
||||
<img alt="Gatsby" src="https://www.gatsbyjs.org/monogram.svg" width="60" />
|
||||
</a>
|
||||
</p>
|
||||
<h1 align="center">
|
||||
Gatsby's default starter
|
||||
</h1>
|
||||
|
||||
Kick off your project with this default boilerplate. This starter ships with the main Gatsby configuration files you might need to get up and running blazing fast with the blazing fast app generator for React.
|
||||
|
||||
_Have another more specific idea? You may want to check out our vibrant collection of [official and community-created starters](https://www.gatsbyjs.org/docs/gatsby-starters/)._
|
||||
|
||||
## 🚀 Quick start
|
||||
|
||||
1. **Create a Gatsby site.**
|
||||
|
||||
Use the Gatsby CLI to create a new site, specifying the default starter.
|
||||
|
||||
```shell
|
||||
# create a new Gatsby site using the default starter
|
||||
gatsby new my-default-starter https://github.com/gatsbyjs/gatsby-starter-default
|
||||
```
|
||||
|
||||
1. **Start developing.**
|
||||
|
||||
Navigate into your new site’s directory and start it up.
|
||||
|
||||
```shell
|
||||
cd my-default-starter/
|
||||
gatsby develop
|
||||
```
|
||||
|
||||
1. **Open the source code and start editing!**
|
||||
|
||||
Your site is now running at `http://localhost:8000`!
|
||||
|
||||
_Note: You'll also see a second link: _`http://localhost:8000/___graphql`_. This is a tool you can use to experiment with querying your data. Learn more about using this tool in the [Gatsby tutorial](https://www.gatsbyjs.org/tutorial/part-five/#introducing-graphiql)._
|
||||
|
||||
Open the `my-default-starter` directory in your code editor of choice and edit `src/pages/index.js`. Save your changes and the browser will update in real time!
|
||||
|
||||
## 🧐 What's inside?
|
||||
|
||||
A quick look at the top-level files and directories you'll see in a Gatsby project.
|
||||
|
||||
.
|
||||
├── node_modules
|
||||
├── src
|
||||
├── .gitignore
|
||||
├── .prettierrc
|
||||
├── gatsby-browser.js
|
||||
├── gatsby-config.js
|
||||
├── gatsby-node.js
|
||||
├── gatsby-ssr.js
|
||||
├── LICENSE
|
||||
├── package-lock.json
|
||||
├── package.json
|
||||
└── README.md
|
||||
|
||||
1. **`/node_modules`**: This directory contains all of the modules of code that your project depends on (npm packages) are automatically installed.
|
||||
|
||||
2. **`/src`**: This directory will contain all of the code related to what you will see on the front-end of your site (what you see in the browser) such as your site header or a page template. `src` is a convention for “source code”.
|
||||
|
||||
3. **`.gitignore`**: This file tells git which files it should not track / not maintain a version history for.
|
||||
|
||||
4. **`.prettierrc`**: This is a configuration file for [Prettier](https://prettier.io/). Prettier is a tool to help keep the formatting of your code consistent.
|
||||
|
||||
5. **`gatsby-browser.js`**: This file is where Gatsby expects to find any usage of the [Gatsby browser APIs](https://www.gatsbyjs.org/docs/browser-apis/) (if any). These allow customization/extension of default Gatsby settings affecting the browser.
|
||||
|
||||
6. **`gatsby-config.js`**: This is the main configuration file for a Gatsby site. This is where you can specify information about your site (metadata) like the site title and description, which Gatsby plugins you’d like to include, etc. (Check out the [config docs](https://www.gatsbyjs.org/docs/gatsby-config/) for more detail).
|
||||
|
||||
7. **`gatsby-node.js`**: This file is where Gatsby expects to find any usage of the [Gatsby Node APIs](https://www.gatsbyjs.org/docs/node-apis/) (if any). These allow customization/extension of default Gatsby settings affecting pieces of the site build process.
|
||||
|
||||
8. **`gatsby-ssr.js`**: This file is where Gatsby expects to find any usage of the [Gatsby server-side rendering APIs](https://www.gatsbyjs.org/docs/ssr-apis/) (if any). These allow customization of default Gatsby settings affecting server-side rendering.
|
||||
|
||||
9. **`LICENSE`**: Gatsby is licensed under the MIT license.
|
||||
|
||||
10. **`package-lock.json`** (See `package.json` below, first). This is an automatically generated file based on the exact versions of your npm dependencies that were installed for your project. **(You won’t change this file directly).**
|
||||
|
||||
11. **`package.json`**: A manifest file for Node.js projects, which includes things like metadata (the project’s name, author, etc). This manifest is how npm knows which packages to install for your project.
|
||||
|
||||
12. **`README.md`**: A text file containing useful reference information about your project.
|
||||
|
||||
## 🎓 Learning Gatsby
|
||||
|
||||
Looking for more guidance? Full documentation for Gatsby lives [on the website](https://www.gatsbyjs.org/). Here are some places to start:
|
||||
|
||||
- **For most developers, we recommend starting with our [in-depth tutorial for creating a site with Gatsby](https://www.gatsbyjs.org/tutorial/).** It starts with zero assumptions about your level of ability and walks through every step of the process.
|
||||
|
||||
- **To dive straight into code samples, head [to our documentation](https://www.gatsbyjs.org/docs/).** In particular, check out the _Guides_, _API Reference_, and _Advanced Tutorials_ sections in the sidebar.
|
||||
|
||||
## 💫 Deploy
|
||||
|
||||
[](https://app.netlify.com/start/deploy?repository=https://github.com/gatsbyjs/gatsby-starter-default)
|
||||
|
||||
<!-- AUTO-GENERATED-CONTENT:END -->
|
||||
7
packages/cli/test/fixtures/unit/vercel-build-gatsby/gatsby-browser.js
vendored
Normal file
7
packages/cli/test/fixtures/unit/vercel-build-gatsby/gatsby-browser.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Implement Gatsby's Browser APIs in this file.
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/browser-apis/
|
||||
*/
|
||||
|
||||
// You can delete this file if you're not using it
|
||||
34
packages/cli/test/fixtures/unit/vercel-build-gatsby/gatsby-config.js
vendored
Normal file
34
packages/cli/test/fixtures/unit/vercel-build-gatsby/gatsby-config.js
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
module.exports = {
|
||||
siteMetadata: {
|
||||
title: `Gatsby Default Starter`,
|
||||
description: `Kick off your next, great Gatsby project with this default starter. This barebones starter ships with the main Gatsby configuration files you might need.`,
|
||||
author: `@gatsbyjs`,
|
||||
},
|
||||
plugins: [
|
||||
`gatsby-plugin-react-helmet`,
|
||||
{
|
||||
resolve: `gatsby-source-filesystem`,
|
||||
options: {
|
||||
name: `images`,
|
||||
path: `${__dirname}/src/images`,
|
||||
},
|
||||
},
|
||||
`gatsby-transformer-sharp`,
|
||||
`gatsby-plugin-sharp`,
|
||||
{
|
||||
resolve: `gatsby-plugin-manifest`,
|
||||
options: {
|
||||
name: `05-zero-config-gatsby`,
|
||||
short_name: `starter`,
|
||||
start_url: `/`,
|
||||
background_color: `#663399`,
|
||||
theme_color: `#663399`,
|
||||
display: `minimal-ui`,
|
||||
icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
|
||||
},
|
||||
},
|
||||
// this (optional) plugin enables Progressive Web App + Offline functionality
|
||||
// To learn more, visit: https://gatsby.dev/offline
|
||||
// `gatsby-plugin-offline`,
|
||||
],
|
||||
}
|
||||
7
packages/cli/test/fixtures/unit/vercel-build-gatsby/gatsby-node.js
vendored
Normal file
7
packages/cli/test/fixtures/unit/vercel-build-gatsby/gatsby-node.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Implement Gatsby's Node APIs in this file.
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/node-apis/
|
||||
*/
|
||||
|
||||
// You can delete this file if you're not using it
|
||||
7
packages/cli/test/fixtures/unit/vercel-build-gatsby/gatsby-ssr.js
vendored
Normal file
7
packages/cli/test/fixtures/unit/vercel-build-gatsby/gatsby-ssr.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Implement Gatsby's SSR (Server Side Rendering) APIs in this file.
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/ssr-apis/
|
||||
*/
|
||||
|
||||
// You can delete this file if you're not using it
|
||||
43
packages/cli/test/fixtures/unit/vercel-build-gatsby/package.json
vendored
Normal file
43
packages/cli/test/fixtures/unit/vercel-build-gatsby/package.json
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"name": "vercel-build-gatsby",
|
||||
"private": true,
|
||||
"description": "A simple starter to get up and developing quickly with Gatsby",
|
||||
"version": "0.1.0",
|
||||
"author": "Kyle Mathews <mathews.kyle@gmail.com>",
|
||||
"dependencies": {
|
||||
"gatsby": "^2.17.6",
|
||||
"gatsby-image": "^2.2.30",
|
||||
"gatsby-plugin-manifest": "^2.2.25",
|
||||
"gatsby-plugin-offline": "^3.0.17",
|
||||
"gatsby-plugin-react-helmet": "^3.1.13",
|
||||
"gatsby-plugin-sharp": "^2.2.34",
|
||||
"gatsby-source-filesystem": "^2.1.35",
|
||||
"gatsby-transformer-sharp": "^2.3.1",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.11.0",
|
||||
"react-dom": "^16.11.0",
|
||||
"react-helmet": "^5.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"prettier": "^1.18.2"
|
||||
},
|
||||
"keywords": [
|
||||
"gatsby"
|
||||
],
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"build": "gatsby build",
|
||||
"develop": "gatsby develop",
|
||||
"format": "prettier --write \"**/*.{js,jsx,json,md}\"",
|
||||
"start": "npm run develop",
|
||||
"serve": "gatsby serve",
|
||||
"test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/gatsbyjs/gatsby-starter-default"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/gatsbyjs/gatsby/issues"
|
||||
}
|
||||
}
|
||||
42
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/components/header.js
vendored
Normal file
42
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/components/header.js
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
import { Link } from "gatsby"
|
||||
import PropTypes from "prop-types"
|
||||
import React from "react"
|
||||
|
||||
const Header = ({ siteTitle }) => (
|
||||
<header
|
||||
style={{
|
||||
background: `rebeccapurple`,
|
||||
marginBottom: `1.45rem`,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
margin: `0 auto`,
|
||||
maxWidth: 960,
|
||||
padding: `1.45rem 1.0875rem`,
|
||||
}}
|
||||
>
|
||||
<h1 style={{ margin: 0 }}>
|
||||
<Link
|
||||
to="/"
|
||||
style={{
|
||||
color: `white`,
|
||||
textDecoration: `none`,
|
||||
}}
|
||||
>
|
||||
{siteTitle}
|
||||
</Link>
|
||||
</h1>
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
|
||||
Header.propTypes = {
|
||||
siteTitle: PropTypes.string,
|
||||
}
|
||||
|
||||
Header.defaultProps = {
|
||||
siteTitle: ``,
|
||||
}
|
||||
|
||||
export default Header
|
||||
32
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/components/image.js
vendored
Normal file
32
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/components/image.js
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
import React from "react"
|
||||
import { useStaticQuery, graphql } from "gatsby"
|
||||
import Img from "gatsby-image"
|
||||
|
||||
/*
|
||||
* This component is built using `gatsby-image` to automatically serve optimized
|
||||
* images with lazy loading and reduced file sizes. The image is loaded using a
|
||||
* `useStaticQuery`, which allows us to load the image from directly within this
|
||||
* component, rather than having to pass the image data down from pages.
|
||||
*
|
||||
* For more information, see the docs:
|
||||
* - `gatsby-image`: https://gatsby.dev/gatsby-image
|
||||
* - `useStaticQuery`: https://www.gatsbyjs.org/docs/use-static-query/
|
||||
*/
|
||||
|
||||
const Image = () => {
|
||||
const data = useStaticQuery(graphql`
|
||||
query {
|
||||
placeholderImage: file(relativePath: { eq: "gatsby-astronaut.png" }) {
|
||||
childImageSharp {
|
||||
fluid(maxWidth: 300) {
|
||||
...GatsbyImageSharpFluid
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
return <Img fluid={data.placeholderImage.childImageSharp.fluid} />
|
||||
}
|
||||
|
||||
export default Image
|
||||
622
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/components/layout.css
vendored
Normal file
622
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/components/layout.css
vendored
Normal file
@@ -0,0 +1,622 @@
|
||||
html {
|
||||
font-family: sans-serif;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
article,
|
||||
aside,
|
||||
details,
|
||||
figcaption,
|
||||
figure,
|
||||
footer,
|
||||
header,
|
||||
main,
|
||||
menu,
|
||||
nav,
|
||||
section,
|
||||
summary {
|
||||
display: block;
|
||||
}
|
||||
audio,
|
||||
canvas,
|
||||
progress,
|
||||
video {
|
||||
display: inline-block;
|
||||
}
|
||||
audio:not([controls]) {
|
||||
display: none;
|
||||
height: 0;
|
||||
}
|
||||
progress {
|
||||
vertical-align: baseline;
|
||||
}
|
||||
[hidden],
|
||||
template {
|
||||
display: none;
|
||||
}
|
||||
a {
|
||||
background-color: transparent;
|
||||
-webkit-text-decoration-skip: objects;
|
||||
}
|
||||
a:active,
|
||||
a:hover {
|
||||
outline-width: 0;
|
||||
}
|
||||
abbr[title] {
|
||||
border-bottom: none;
|
||||
text-decoration: underline;
|
||||
text-decoration: underline dotted;
|
||||
}
|
||||
b,
|
||||
strong {
|
||||
font-weight: inherit;
|
||||
font-weight: bolder;
|
||||
}
|
||||
dfn {
|
||||
font-style: italic;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2em;
|
||||
margin: 0.67em 0;
|
||||
}
|
||||
mark {
|
||||
background-color: #ff0;
|
||||
color: #000;
|
||||
}
|
||||
small {
|
||||
font-size: 80%;
|
||||
}
|
||||
sub,
|
||||
sup {
|
||||
font-size: 75%;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
vertical-align: baseline;
|
||||
}
|
||||
sub {
|
||||
bottom: -0.25em;
|
||||
}
|
||||
sup {
|
||||
top: -0.5em;
|
||||
}
|
||||
img {
|
||||
border-style: none;
|
||||
}
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
}
|
||||
code,
|
||||
kbd,
|
||||
pre,
|
||||
samp {
|
||||
font-family: monospace, monospace;
|
||||
font-size: 1em;
|
||||
}
|
||||
figure {
|
||||
margin: 1em 40px;
|
||||
}
|
||||
hr {
|
||||
box-sizing: content-box;
|
||||
height: 0;
|
||||
overflow: visible;
|
||||
}
|
||||
button,
|
||||
input,
|
||||
optgroup,
|
||||
select,
|
||||
textarea {
|
||||
font: inherit;
|
||||
margin: 0;
|
||||
}
|
||||
optgroup {
|
||||
font-weight: 700;
|
||||
}
|
||||
button,
|
||||
input {
|
||||
overflow: visible;
|
||||
}
|
||||
button,
|
||||
select {
|
||||
text-transform: none;
|
||||
}
|
||||
[type="reset"],
|
||||
[type="submit"],
|
||||
button,
|
||||
html [type="button"] {
|
||||
-webkit-appearance: button;
|
||||
}
|
||||
[type="button"]::-moz-focus-inner,
|
||||
[type="reset"]::-moz-focus-inner,
|
||||
[type="submit"]::-moz-focus-inner,
|
||||
button::-moz-focus-inner {
|
||||
border-style: none;
|
||||
padding: 0;
|
||||
}
|
||||
[type="button"]:-moz-focusring,
|
||||
[type="reset"]:-moz-focusring,
|
||||
[type="submit"]:-moz-focusring,
|
||||
button:-moz-focusring {
|
||||
outline: 1px dotted ButtonText;
|
||||
}
|
||||
fieldset {
|
||||
border: 1px solid silver;
|
||||
margin: 0 2px;
|
||||
padding: 0.35em 0.625em 0.75em;
|
||||
}
|
||||
legend {
|
||||
box-sizing: border-box;
|
||||
color: inherit;
|
||||
display: table;
|
||||
max-width: 100%;
|
||||
padding: 0;
|
||||
white-space: normal;
|
||||
}
|
||||
textarea {
|
||||
overflow: auto;
|
||||
}
|
||||
[type="checkbox"],
|
||||
[type="radio"] {
|
||||
box-sizing: border-box;
|
||||
padding: 0;
|
||||
}
|
||||
[type="number"]::-webkit-inner-spin-button,
|
||||
[type="number"]::-webkit-outer-spin-button {
|
||||
height: auto;
|
||||
}
|
||||
[type="search"] {
|
||||
-webkit-appearance: textfield;
|
||||
outline-offset: -2px;
|
||||
}
|
||||
[type="search"]::-webkit-search-cancel-button,
|
||||
[type="search"]::-webkit-search-decoration {
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
::-webkit-input-placeholder {
|
||||
color: inherit;
|
||||
opacity: 0.54;
|
||||
}
|
||||
::-webkit-file-upload-button {
|
||||
-webkit-appearance: button;
|
||||
font: inherit;
|
||||
}
|
||||
html {
|
||||
font: 112.5%/1.45em georgia, serif;
|
||||
box-sizing: border-box;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
* {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
*:before {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
*:after {
|
||||
box-sizing: inherit;
|
||||
}
|
||||
body {
|
||||
color: hsla(0, 0%, 0%, 0.8);
|
||||
font-family: georgia, serif;
|
||||
font-weight: normal;
|
||||
word-wrap: break-word;
|
||||
font-kerning: normal;
|
||||
-moz-font-feature-settings: "kern", "liga", "clig", "calt";
|
||||
-ms-font-feature-settings: "kern", "liga", "clig", "calt";
|
||||
-webkit-font-feature-settings: "kern", "liga", "clig", "calt";
|
||||
font-feature-settings: "kern", "liga", "clig", "calt";
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
h1 {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
color: inherit;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-weight: bold;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 2.25rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
h2 {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
color: inherit;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-weight: bold;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 1.62671rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
h3 {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
color: inherit;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-weight: bold;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 1.38316rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
h4 {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
color: inherit;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-weight: bold;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 1rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
h5 {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
color: inherit;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-weight: bold;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 0.85028rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
h6 {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
color: inherit;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||
font-weight: bold;
|
||||
text-rendering: optimizeLegibility;
|
||||
font-size: 0.78405rem;
|
||||
line-height: 1.1;
|
||||
}
|
||||
hgroup {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
ul {
|
||||
margin-left: 1.45rem;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
list-style-position: outside;
|
||||
list-style-image: none;
|
||||
}
|
||||
ol {
|
||||
margin-left: 1.45rem;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
list-style-position: outside;
|
||||
list-style-image: none;
|
||||
}
|
||||
dl {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
dd {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
p {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
figure {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
pre {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.42;
|
||||
background: hsla(0, 0%, 0%, 0.04);
|
||||
border-radius: 3px;
|
||||
overflow: auto;
|
||||
word-wrap: normal;
|
||||
padding: 1.45rem;
|
||||
}
|
||||
table {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.45rem;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
fieldset {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
blockquote {
|
||||
margin-left: 1.45rem;
|
||||
margin-right: 1.45rem;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
form {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
noscript {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
iframe {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
hr {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: calc(1.45rem - 1px);
|
||||
background: hsla(0, 0%, 0%, 0.2);
|
||||
border: none;
|
||||
height: 1px;
|
||||
}
|
||||
address {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
margin-top: 0;
|
||||
padding-bottom: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 0;
|
||||
margin-bottom: 1.45rem;
|
||||
}
|
||||
b {
|
||||
font-weight: bold;
|
||||
}
|
||||
strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
dt {
|
||||
font-weight: bold;
|
||||
}
|
||||
th {
|
||||
font-weight: bold;
|
||||
}
|
||||
li {
|
||||
margin-bottom: calc(1.45rem / 2);
|
||||
}
|
||||
ol li {
|
||||
padding-left: 0;
|
||||
}
|
||||
ul li {
|
||||
padding-left: 0;
|
||||
}
|
||||
li > ol {
|
||||
margin-left: 1.45rem;
|
||||
margin-bottom: calc(1.45rem / 2);
|
||||
margin-top: calc(1.45rem / 2);
|
||||
}
|
||||
li > ul {
|
||||
margin-left: 1.45rem;
|
||||
margin-bottom: calc(1.45rem / 2);
|
||||
margin-top: calc(1.45rem / 2);
|
||||
}
|
||||
blockquote *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
li *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
p *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
li > p {
|
||||
margin-bottom: calc(1.45rem / 2);
|
||||
}
|
||||
code {
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.45rem;
|
||||
}
|
||||
kbd {
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.45rem;
|
||||
}
|
||||
samp {
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.45rem;
|
||||
}
|
||||
abbr {
|
||||
border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5);
|
||||
cursor: help;
|
||||
}
|
||||
acronym {
|
||||
border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5);
|
||||
cursor: help;
|
||||
}
|
||||
abbr[title] {
|
||||
border-bottom: 1px dotted hsla(0, 0%, 0%, 0.5);
|
||||
cursor: help;
|
||||
text-decoration: none;
|
||||
}
|
||||
thead {
|
||||
text-align: left;
|
||||
}
|
||||
td,
|
||||
th {
|
||||
text-align: left;
|
||||
border-bottom: 1px solid hsla(0, 0%, 0%, 0.12);
|
||||
font-feature-settings: "tnum";
|
||||
-moz-font-feature-settings: "tnum";
|
||||
-ms-font-feature-settings: "tnum";
|
||||
-webkit-font-feature-settings: "tnum";
|
||||
padding-left: 0.96667rem;
|
||||
padding-right: 0.96667rem;
|
||||
padding-top: 0.725rem;
|
||||
padding-bottom: calc(0.725rem - 1px);
|
||||
}
|
||||
th:first-child,
|
||||
td:first-child {
|
||||
padding-left: 0;
|
||||
}
|
||||
th:last-child,
|
||||
td:last-child {
|
||||
padding-right: 0;
|
||||
}
|
||||
tt,
|
||||
code {
|
||||
background-color: hsla(0, 0%, 0%, 0.04);
|
||||
border-radius: 3px;
|
||||
font-family: "SFMono-Regular", Consolas, "Roboto Mono", "Droid Sans Mono",
|
||||
"Liberation Mono", Menlo, Courier, monospace;
|
||||
padding: 0;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
pre code {
|
||||
background: none;
|
||||
line-height: 1.42;
|
||||
}
|
||||
code:before,
|
||||
code:after,
|
||||
tt:before,
|
||||
tt:after {
|
||||
letter-spacing: -0.2em;
|
||||
content: " ";
|
||||
}
|
||||
pre code:before,
|
||||
pre code:after,
|
||||
pre tt:before,
|
||||
pre tt:after {
|
||||
content: "";
|
||||
}
|
||||
@media only screen and (max-width: 480px) {
|
||||
html {
|
||||
font-size: 100%;
|
||||
}
|
||||
}
|
||||
52
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/components/layout.js
vendored
Normal file
52
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/components/layout.js
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* Layout component that queries for data
|
||||
* with Gatsby's useStaticQuery component
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/use-static-query/
|
||||
*/
|
||||
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { useStaticQuery, graphql } from "gatsby"
|
||||
|
||||
import Header from "./header"
|
||||
import "./layout.css"
|
||||
|
||||
const Layout = ({ children }) => {
|
||||
const data = useStaticQuery(graphql`
|
||||
query SiteTitleQuery {
|
||||
site {
|
||||
siteMetadata {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Header siteTitle={data.site.siteMetadata.title} />
|
||||
<div
|
||||
style={{
|
||||
margin: `0 auto`,
|
||||
maxWidth: 960,
|
||||
padding: `0px 1.0875rem 1.45rem`,
|
||||
paddingTop: 0,
|
||||
}}
|
||||
>
|
||||
<main>{children}</main>
|
||||
<footer>
|
||||
© {new Date().getFullYear()}, Built with
|
||||
{` `}
|
||||
<a href="https://www.gatsbyjs.org">Gatsby</a>
|
||||
</footer>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Layout.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
}
|
||||
|
||||
export default Layout
|
||||
88
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/components/seo.js
vendored
Normal file
88
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/components/seo.js
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* SEO component that queries for data with
|
||||
* Gatsby's useStaticQuery React hook
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/use-static-query/
|
||||
*/
|
||||
|
||||
import React from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import Helmet from "react-helmet"
|
||||
import { useStaticQuery, graphql } from "gatsby"
|
||||
|
||||
function SEO({ description, lang, meta, title }) {
|
||||
const { site } = useStaticQuery(
|
||||
graphql`
|
||||
query {
|
||||
site {
|
||||
siteMetadata {
|
||||
title
|
||||
description
|
||||
author
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
)
|
||||
|
||||
const metaDescription = description || site.siteMetadata.description
|
||||
|
||||
return (
|
||||
<Helmet
|
||||
htmlAttributes={{
|
||||
lang,
|
||||
}}
|
||||
title={title}
|
||||
titleTemplate={`%s | ${site.siteMetadata.title}`}
|
||||
meta={[
|
||||
{
|
||||
name: `description`,
|
||||
content: metaDescription,
|
||||
},
|
||||
{
|
||||
property: `og:title`,
|
||||
content: title,
|
||||
},
|
||||
{
|
||||
property: `og:description`,
|
||||
content: metaDescription,
|
||||
},
|
||||
{
|
||||
property: `og:type`,
|
||||
content: `website`,
|
||||
},
|
||||
{
|
||||
name: `twitter:card`,
|
||||
content: `summary`,
|
||||
},
|
||||
{
|
||||
name: `twitter:creator`,
|
||||
content: site.siteMetadata.author,
|
||||
},
|
||||
{
|
||||
name: `twitter:title`,
|
||||
content: title,
|
||||
},
|
||||
{
|
||||
name: `twitter:description`,
|
||||
content: metaDescription,
|
||||
},
|
||||
].concat(meta)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
SEO.defaultProps = {
|
||||
lang: `en`,
|
||||
meta: [],
|
||||
description: ``,
|
||||
}
|
||||
|
||||
SEO.propTypes = {
|
||||
description: PropTypes.string,
|
||||
lang: PropTypes.string,
|
||||
meta: PropTypes.arrayOf(PropTypes.object),
|
||||
title: PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
export default SEO
|
||||
BIN
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/images/gatsby-astronaut.png
vendored
Normal file
BIN
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/images/gatsby-astronaut.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 163 KiB |
BIN
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/images/gatsby-icon.png
vendored
Normal file
BIN
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/images/gatsby-icon.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
14
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/pages/404.js
vendored
Normal file
14
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/pages/404.js
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from "react"
|
||||
|
||||
import Layout from "../components/layout"
|
||||
import SEO from "../components/seo"
|
||||
|
||||
const NotFoundPage = () => (
|
||||
<Layout>
|
||||
<SEO title="404: Not found" />
|
||||
<h1>NOT FOUND</h1>
|
||||
<p>You just hit a route that doesn't exist... the sadness.</p>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
export default NotFoundPage
|
||||
21
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/pages/index.js
vendored
Normal file
21
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/pages/index.js
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from "react"
|
||||
import { Link } from "gatsby"
|
||||
|
||||
import Layout from "../components/layout"
|
||||
import Image from "../components/image"
|
||||
import SEO from "../components/seo"
|
||||
|
||||
const IndexPage = () => (
|
||||
<Layout>
|
||||
<SEO title="Home" />
|
||||
<h1>Hi people</h1>
|
||||
<p>Welcome to your new Gatsby site.</p>
|
||||
<p>Now go build something great.</p>
|
||||
<div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
|
||||
<Image />
|
||||
</div>
|
||||
<Link to="/page-2/">Go to page 2</Link>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
export default IndexPage
|
||||
16
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/pages/page-2.js
vendored
Normal file
16
packages/cli/test/fixtures/unit/vercel-build-gatsby/src/pages/page-2.js
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import React from "react"
|
||||
import { Link } from "gatsby"
|
||||
|
||||
import Layout from "../components/layout"
|
||||
import SEO from "../components/seo"
|
||||
|
||||
const SecondPage = () => (
|
||||
<Layout>
|
||||
<SEO title="Page two" />
|
||||
<h1>Hi from the second page</h1>
|
||||
<p>Welcome to page 2</p>
|
||||
<Link to="/">Go back to the homepage</Link>
|
||||
</Layout>
|
||||
)
|
||||
|
||||
export default SecondPage
|
||||
4
packages/cli/test/fixtures/unit/vercel-pull-next/.gitignore
vendored
Normal file
4
packages/cli/test/fixtures/unit/vercel-pull-next/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.next
|
||||
yarn.lock
|
||||
.vercel
|
||||
.output
|
||||
12
packages/cli/test/fixtures/unit/vercel-pull-next/package.json
vendored
Normal file
12
packages/cli/test/fixtures/unit/vercel-pull-next/package.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"scripts": {
|
||||
"build": "next build",
|
||||
"dev": "next",
|
||||
"now-build": "next build"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "^8.0.0",
|
||||
"react": "^16.7.0",
|
||||
"react-dom": "^16.7.0"
|
||||
}
|
||||
}
|
||||
11
packages/cli/test/fixtures/unit/vercel-pull-next/pages/index.js
vendored
Normal file
11
packages/cli/test/fixtures/unit/vercel-pull-next/pages/index.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import { withRouter } from 'next/router';
|
||||
|
||||
function Index({ router }) {
|
||||
const data = {
|
||||
pathname: router.pathname,
|
||||
query: router.query,
|
||||
};
|
||||
return <div>{JSON.stringify(data)}</div>;
|
||||
}
|
||||
|
||||
export default withRouter(Index);
|
||||
1
packages/cli/test/fixtures/unit/vercel-pull-next/static/robots.txt
vendored
Normal file
1
packages/cli/test/fixtures/unit/vercel-pull-next/static/robots.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
User-Agent: *
|
||||
11
packages/cli/test/fixtures/unit/vercel-pull-next/vercel.json
vendored
Normal file
11
packages/cli/test/fixtures/unit/vercel-pull-next/vercel.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"version": 2,
|
||||
"name": "vercel-pull-next",
|
||||
"builds": [{ "src": "package.json", "use": "@vercel/next@canary" }],
|
||||
"routes": [
|
||||
{
|
||||
"src": "/(.*)",
|
||||
"dest": "/index?route-param=b"
|
||||
}
|
||||
]
|
||||
}
|
||||
59
packages/cli/test/helpers/setup-fixture.ts
Normal file
59
packages/cli/test/helpers/setup-fixture.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import findUp from 'find-up';
|
||||
import fs from 'fs-extra';
|
||||
import path from 'path';
|
||||
import tmp from 'tmp-promise';
|
||||
|
||||
// tmp is supposed to be able to clean up automatically, but this doesn't always work within jest.
|
||||
// So we attempt to use its built-in cleanup mechanisms, but tests should ideally do their own cleanup too.
|
||||
tmp.setGracefulCleanup();
|
||||
|
||||
let fixturesRoot: string | undefined;
|
||||
let tempRoot: tmp.DirResult | undefined;
|
||||
let tempNumber = 0;
|
||||
|
||||
/**
|
||||
* Create a temp directory containing the given fixture name in a git repo.
|
||||
* Be sure to call `cleanupFixtures()` after all tests to clean up temp directories.
|
||||
*/
|
||||
export function setupFixture(fixtureName: string) {
|
||||
if (!fixturesRoot) {
|
||||
fixturesRoot = findUp.sync('fixtures', {
|
||||
cwd: __dirname,
|
||||
type: 'directory',
|
||||
});
|
||||
}
|
||||
|
||||
const fixturePath = path.join(fixturesRoot!, 'unit', fixtureName);
|
||||
if (!fs.existsSync(fixturePath)) {
|
||||
throw new Error(
|
||||
`Couldn't find fixture "${fixtureName}" under "${path.join(
|
||||
fixturesRoot!,
|
||||
'unit'
|
||||
)}"`
|
||||
);
|
||||
}
|
||||
|
||||
if (!tempRoot) {
|
||||
// Create a shared root temp directory for fixture files
|
||||
tempRoot = tmp.dirSync({ unsafeCleanup: true }); // clean up even if files are left
|
||||
}
|
||||
|
||||
const cwd = path.join(tempRoot.name, String(tempNumber++), fixtureName);
|
||||
|
||||
fs.mkdirpSync(cwd);
|
||||
fs.copySync(fixturePath, cwd);
|
||||
|
||||
return cwd;
|
||||
}
|
||||
|
||||
export function cleanupFixtures() {
|
||||
if (tempRoot) {
|
||||
tempRoot.removeCallback();
|
||||
tempRoot = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
// After all tests are run, we clean up our fixtures
|
||||
afterAll(() => {
|
||||
cleanupFixtures();
|
||||
});
|
||||
46
packages/cli/test/integration.js
vendored
46
packages/cli/test/integration.js
vendored
@@ -85,7 +85,7 @@ const waitForDeployment = async href => {
|
||||
};
|
||||
|
||||
function fetchTokenInformation(token, retries = 3) {
|
||||
const url = `https://api.vercel.com/www/user`;
|
||||
const url = `https://api.vercel.com/v2/user`;
|
||||
const headers = { Authorization: `Bearer ${token}` };
|
||||
|
||||
return retry(
|
||||
@@ -2673,15 +2673,15 @@ test('ensure `github` and `scope` are not sent to the API', async t => {
|
||||
});
|
||||
|
||||
test('should show prompts to set up project during first deploy', async t => {
|
||||
const directory = fixture('project-link-deploy');
|
||||
const dir = fixture('project-link-deploy');
|
||||
const projectName = `project-link-deploy-${
|
||||
Math.random().toString(36).split('.')[1]
|
||||
}`;
|
||||
|
||||
// remove previously linked project if it exists
|
||||
await remove(path.join(directory, '.vercel'));
|
||||
await remove(path.join(dir, '.vercel'));
|
||||
|
||||
const now = execa(binaryPath, [directory, ...defaultArgs]);
|
||||
const now = execa(binaryPath, [dir, ...defaultArgs]);
|
||||
|
||||
await waitForPrompt(now, chunk => /Set up and deploy [^?]+\?/.test(chunk));
|
||||
now.stdin.write('yes\n');
|
||||
@@ -2743,19 +2743,17 @@ test('should show prompts to set up project during first deploy', async t => {
|
||||
t.is(output.exitCode, 0, formatOutput(output));
|
||||
|
||||
// Ensure .gitignore is created
|
||||
t.is(
|
||||
(await readFile(path.join(directory, '.gitignore'))).toString(),
|
||||
'.vercel\n'
|
||||
);
|
||||
const gitignore = await readFile(path.join(dir, '.gitignore'), 'utf8');
|
||||
t.is(gitignore, '.vercel\n.output\n');
|
||||
|
||||
// Ensure .vercel/project.json and .vercel/README.txt are created
|
||||
t.is(
|
||||
await exists(path.join(directory, '.vercel', 'project.json')),
|
||||
await exists(path.join(dir, '.vercel', 'project.json')),
|
||||
true,
|
||||
'project.json should be created'
|
||||
);
|
||||
t.is(
|
||||
await exists(path.join(directory, '.vercel', 'README.txt')),
|
||||
await exists(path.join(dir, '.vercel', 'README.txt')),
|
||||
true,
|
||||
'README.txt should be created'
|
||||
);
|
||||
@@ -2769,13 +2767,7 @@ test('should show prompts to set up project during first deploy', async t => {
|
||||
// and output directory
|
||||
let stderr = '';
|
||||
const port = 58351;
|
||||
const dev = execa(binaryPath, [
|
||||
'dev',
|
||||
'--listen',
|
||||
port,
|
||||
directory,
|
||||
...defaultArgs,
|
||||
]);
|
||||
const dev = execa(binaryPath, ['dev', '--listen', port, dir, ...defaultArgs]);
|
||||
dev.stderr.setEncoding('utf8');
|
||||
|
||||
try {
|
||||
@@ -2980,7 +2972,7 @@ test('deploy with unknown `VERCEL_PROJECT_ID` should fail', async t => {
|
||||
|
||||
const output = await execute([directory], {
|
||||
env: {
|
||||
VERCEL_ORG_ID: user.uid,
|
||||
VERCEL_ORG_ID: user.id,
|
||||
VERCEL_PROJECT_ID: 'asdf',
|
||||
},
|
||||
});
|
||||
@@ -2994,7 +2986,7 @@ test('deploy with `VERCEL_ORG_ID` but without `VERCEL_PROJECT_ID` should fail',
|
||||
const user = await fetchTokenInformation(token);
|
||||
|
||||
const output = await execute([directory], {
|
||||
env: { VERCEL_ORG_ID: user.uid },
|
||||
env: { VERCEL_ORG_ID: user.id },
|
||||
});
|
||||
|
||||
t.is(output.exitCode, 1, formatOutput(output));
|
||||
@@ -3136,7 +3128,7 @@ test('whoami with `VERCEL_ORG_ID` should favor `--scope` and should error', asyn
|
||||
const user = await fetchTokenInformation(token);
|
||||
|
||||
const output = await execute(['whoami', '--scope', 'asdf'], {
|
||||
env: { VERCEL_ORG_ID: user.uid },
|
||||
env: { VERCEL_ORG_ID: user.id },
|
||||
});
|
||||
|
||||
t.is(output.exitCode, 1, formatOutput(output));
|
||||
@@ -3155,7 +3147,7 @@ test('whoami with local .vercel scope', async t => {
|
||||
await ensureDir(path.join(directory, '.vercel'));
|
||||
await fs.writeFile(
|
||||
path.join(directory, '.vercel', 'project.json'),
|
||||
JSON.stringify({ orgId: user.uid, projectId: 'xxx' })
|
||||
JSON.stringify({ orgId: user.id, projectId: 'xxx' })
|
||||
);
|
||||
|
||||
const output = await execute(['whoami'], {
|
||||
@@ -3365,7 +3357,8 @@ test('[vc link] should show prompts to set up project', async t => {
|
||||
t.is(output.exitCode, 0, formatOutput(output));
|
||||
|
||||
// Ensure .gitignore is created
|
||||
t.is((await readFile(path.join(dir, '.gitignore'))).toString(), '.vercel\n');
|
||||
const gitignore = await readFile(path.join(dir, '.gitignore'), 'utf8');
|
||||
t.is(gitignore, '.vercel\n.output\n');
|
||||
|
||||
// Ensure .vercel/project.json and .vercel/README.txt are created
|
||||
t.is(
|
||||
@@ -3399,7 +3392,8 @@ test('[vc link --confirm] should not show prompts and autolink', async t => {
|
||||
t.regex(stderr, /Linked to /m);
|
||||
|
||||
// Ensure .gitignore is created
|
||||
t.is((await readFile(path.join(dir, '.gitignore'))).toString(), '.vercel\n');
|
||||
const gitignore = await readFile(path.join(dir, '.gitignore'), 'utf8');
|
||||
t.is(gitignore, '.vercel\n.output\n');
|
||||
|
||||
// Ensure .vercel/project.json and .vercel/README.txt are created
|
||||
t.is(
|
||||
@@ -3483,7 +3477,8 @@ test('[vc dev] should show prompts to set up project', async t => {
|
||||
await waitForPrompt(dev, chunk => chunk.includes('Linked to'));
|
||||
|
||||
// Ensure .gitignore is created
|
||||
t.is((await readFile(path.join(dir, '.gitignore'))).toString(), '.vercel\n');
|
||||
const gitignore = await readFile(path.join(dir, '.gitignore'), 'utf8');
|
||||
t.is(gitignore, '.vercel\n.output\n');
|
||||
|
||||
// Ensure .vercel/project.json and .vercel/README.txt are created
|
||||
t.is(
|
||||
@@ -3549,7 +3544,8 @@ test('[vc link] should show project prompts but not framework when `builds` defi
|
||||
t.is(output.exitCode, 0, formatOutput(output));
|
||||
|
||||
// Ensure .gitignore is created
|
||||
t.is((await readFile(path.join(dir, '.gitignore'))).toString(), '.vercel\n');
|
||||
const gitignore = await readFile(path.join(dir, '.gitignore'), 'utf8');
|
||||
t.is(gitignore, '.vercel\n.output\n');
|
||||
|
||||
// Ensure .vercel/project.json and .vercel/README.txt are created
|
||||
t.is(
|
||||
|
||||
@@ -56,7 +56,6 @@ export class MockClient extends Client {
|
||||
this.output = new Output();
|
||||
this.mockOutput = jest.fn();
|
||||
this.output.print = s => {
|
||||
//process.stdout.write(s);
|
||||
return this.mockOutput(s);
|
||||
};
|
||||
|
||||
@@ -69,6 +68,12 @@ export class MockClient extends Client {
|
||||
this.output.spinner = () => {};
|
||||
|
||||
this.scenario = Router();
|
||||
|
||||
this.output.isTTY = true;
|
||||
}
|
||||
|
||||
get outputBuffer() {
|
||||
return this.mockOutput.mock.calls.map(c => c[0]).join('');
|
||||
}
|
||||
|
||||
async startMockServer() {
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Build, User } from '../../src/types';
|
||||
let deployments = new Map<string, Deployment>();
|
||||
let deploymentBuilds = new Map<Deployment, Build[]>();
|
||||
|
||||
export function useDeployment({ creator }: { creator: Pick<User, 'uid'> }) {
|
||||
export function useDeployment({ creator }: { creator: Pick<User, 'id'> }) {
|
||||
const createdAt = Date.now();
|
||||
const url = new URL(chance().url());
|
||||
const deployment: Deployment = {
|
||||
@@ -22,7 +22,7 @@ export function useDeployment({ creator }: { creator: Pick<User, 'uid'> }) {
|
||||
version: 2,
|
||||
createdAt,
|
||||
createdIn: 'sfo1',
|
||||
ownerId: creator.uid,
|
||||
ownerId: creator.id,
|
||||
readyState: 'READY',
|
||||
env: {},
|
||||
build: { env: {} },
|
||||
|
||||
91
packages/cli/test/mocks/project.ts
Normal file
91
packages/cli/test/mocks/project.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { client } from './client';
|
||||
|
||||
const envs = [
|
||||
{
|
||||
type: 'encrypted',
|
||||
id: '781dt89g8r2h789g',
|
||||
key: 'REDIS_CONNECTION_STRING',
|
||||
value: 'redis://abc123@redis.example.com:6379',
|
||||
target: ['production', 'preview'],
|
||||
gitBranch: null,
|
||||
configurationId: null,
|
||||
updatedAt: 1557241361455,
|
||||
createdAt: 1557241361455,
|
||||
},
|
||||
{
|
||||
type: 'encrypted',
|
||||
id: 'r124t6frtu25df16',
|
||||
key: 'SQL_CONNECTION_STRING',
|
||||
value: 'Server=sql.example.com;Database=app;Uid=root;Pwd=P455W0RD;',
|
||||
target: ['production'],
|
||||
gitBranch: null,
|
||||
configurationId: null,
|
||||
updatedAt: 1557241361445,
|
||||
createdAt: 1557241361445,
|
||||
},
|
||||
];
|
||||
|
||||
export const defaultProject = {
|
||||
id: 'foo',
|
||||
name: 'cli',
|
||||
accountId: 'K4amb7K9dAt5R2vBJWF32bmY',
|
||||
createdAt: 1555413045188,
|
||||
updatedAt: 1555413045188,
|
||||
env: envs,
|
||||
targets: {
|
||||
production: {
|
||||
alias: ['foobar.com'],
|
||||
aliasAssigned: 1571239348998,
|
||||
createdAt: 1571239348998,
|
||||
createdIn: 'sfo1',
|
||||
deploymentHostname: 'a-project-name-rjtr4pz3f',
|
||||
forced: false,
|
||||
id: 'dpl_89qyp1cskzkLrVicDaZoDbjyHuDJ',
|
||||
meta: {},
|
||||
plan: 'pro',
|
||||
private: true,
|
||||
readyState: 'READY',
|
||||
requestedAt: 1571239348998,
|
||||
target: 'production',
|
||||
teamId: null,
|
||||
type: 'LAMBDAS',
|
||||
url: 'a-project-name-rjtr4pz3f.vercel.app',
|
||||
userId: 'K4amb7K9dAt5R2vBJWF32bmY',
|
||||
},
|
||||
},
|
||||
latestDeployments: [
|
||||
{
|
||||
alias: ['foobar.com'],
|
||||
aliasAssigned: 1571239348998,
|
||||
createdAt: 1571239348998,
|
||||
createdIn: 'sfo1',
|
||||
deploymentHostname: 'a-project-name-rjtr4pz3f',
|
||||
forced: false,
|
||||
id: 'dpl_89qyp1cskzkLrVicDaZoDbjyHuDJ',
|
||||
meta: {},
|
||||
plan: 'pro',
|
||||
private: true,
|
||||
readyState: 'READY',
|
||||
requestedAt: 1571239348998,
|
||||
target: 'production',
|
||||
teamId: null,
|
||||
type: 'LAMBDAS',
|
||||
url: 'a-project-name-rjtr4pz3f.vercel.app',
|
||||
userId: 'K4amb7K9dAt5R2vBJWF32bmY',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export function useProject(project = defaultProject) {
|
||||
client.scenario.get(`/projects/${project.name}`, (_req, res) => {
|
||||
res.json(project);
|
||||
});
|
||||
client.scenario.get(`/projects/${project.id}`, (_req, res) => {
|
||||
res.json(project);
|
||||
});
|
||||
client.scenario.get(`/v7/projects/${project.id}/env`, (_req, res) => {
|
||||
res.json({ envs });
|
||||
});
|
||||
|
||||
return { project, envs };
|
||||
}
|
||||
29
packages/cli/test/mocks/team.ts
Normal file
29
packages/cli/test/mocks/team.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import chance from 'chance';
|
||||
import { client } from './client';
|
||||
|
||||
export function useTeams() {
|
||||
const teams = [
|
||||
{
|
||||
id: chance().guid(),
|
||||
slug: chance().string({ length: 5, casing: 'lower' }),
|
||||
name: chance().company(),
|
||||
creatorId: chance().guid(),
|
||||
created: '2017-04-29T17:21:54.514Z',
|
||||
avatar: null,
|
||||
},
|
||||
];
|
||||
|
||||
for (let team of teams) {
|
||||
client.scenario.get(`/v1/team/${team.id}`, (_req, res) => {
|
||||
res.json(team);
|
||||
});
|
||||
}
|
||||
|
||||
client.scenario.get('/v1/teams', (_req, res) => {
|
||||
res.json({
|
||||
teams,
|
||||
});
|
||||
});
|
||||
|
||||
return teams;
|
||||
}
|
||||
@@ -2,20 +2,31 @@ import chance from 'chance';
|
||||
import { client } from './client';
|
||||
|
||||
export function useUser() {
|
||||
const userLimited = {
|
||||
uid: chance().guid(),
|
||||
const user = {
|
||||
id: chance().guid(),
|
||||
email: chance().email(),
|
||||
name: chance().name(),
|
||||
username: chance().first().toLowerCase(),
|
||||
};
|
||||
|
||||
client.scenario.get('/www/user', (_req, res) => {
|
||||
client.scenario.get('/v2/user', (_req, res) => {
|
||||
res.json({
|
||||
user: userLimited,
|
||||
user,
|
||||
});
|
||||
});
|
||||
|
||||
return {
|
||||
...userLimited,
|
||||
};
|
||||
client.scenario.post('/registration', (_req, res) => {
|
||||
res.json({
|
||||
token: 'T1dmvPu36nmyYisXAs7IRzcR',
|
||||
securityCode: 'Practical Saola',
|
||||
});
|
||||
});
|
||||
|
||||
client.scenario.get('/registration/verify', (_req, res) => {
|
||||
res.json({
|
||||
token: 'hjkjn',
|
||||
email: user.email,
|
||||
});
|
||||
});
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"strict": true,
|
||||
"noEmitOnError": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/client",
|
||||
"version": "10.2.3-canary.1",
|
||||
"version": "10.2.3-canary.15",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"homepage": "https://vercel.com",
|
||||
@@ -40,7 +40,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "2.12.3-canary.1",
|
||||
"@vercel/build-utils": "2.12.3-canary.14",
|
||||
"@zeit/fetch": "5.2.0",
|
||||
"async-retry": "1.2.3",
|
||||
"async-sema": "3.0.0",
|
||||
|
||||
@@ -88,6 +88,50 @@ export async function* checkDeploymentStatus(
|
||||
yield { type: 'ready', payload: deploymentUpdate };
|
||||
}
|
||||
|
||||
if (deploymentUpdate.checksState !== undefined) {
|
||||
if (
|
||||
deploymentUpdate.checksState === 'completed' &&
|
||||
!finishedEvents.has('checks-completed')
|
||||
) {
|
||||
finishedEvents.add('checks-completed');
|
||||
|
||||
if (deploymentUpdate.checksConclusion === 'succeeded') {
|
||||
yield {
|
||||
type: 'checks-conclusion-succeeded',
|
||||
payload: deploymentUpdate,
|
||||
};
|
||||
} else if (deploymentUpdate.checksConclusion === 'failed') {
|
||||
yield { type: 'checks-conclusion-failed', payload: deploymentUpdate };
|
||||
} else if (deploymentUpdate.checksConclusion === 'skipped') {
|
||||
yield {
|
||||
type: 'checks-conclusion-skipped',
|
||||
payload: deploymentUpdate,
|
||||
};
|
||||
} else if (deploymentUpdate.checksConclusion === 'canceled') {
|
||||
yield {
|
||||
type: 'checks-conclusion-canceled',
|
||||
payload: deploymentUpdate,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
deploymentUpdate.checksState === 'registered' &&
|
||||
!finishedEvents.has('checks-registered')
|
||||
) {
|
||||
finishedEvents.add('checks-registered');
|
||||
yield { type: 'checks-registered', payload: deploymentUpdate };
|
||||
}
|
||||
|
||||
if (
|
||||
deploymentUpdate.checksState === 'running' &&
|
||||
!finishedEvents.has('checks-running')
|
||||
) {
|
||||
finishedEvents.add('checks-running');
|
||||
yield { type: 'checks-running', payload: deploymentUpdate };
|
||||
}
|
||||
}
|
||||
|
||||
if (isAliasAssigned(deploymentUpdate)) {
|
||||
debug('Deployment alias assigned');
|
||||
return yield { type: 'alias-assigned', payload: deploymentUpdate };
|
||||
|
||||
@@ -77,7 +77,8 @@ export default function buildCreateDeployment() {
|
||||
let { fileList } = await buildFileTree(
|
||||
path,
|
||||
clientOptions.isDirectory,
|
||||
debug
|
||||
debug,
|
||||
clientOptions.prebuilt
|
||||
);
|
||||
|
||||
let configPath: string | undefined;
|
||||
|
||||
@@ -14,6 +14,7 @@ export interface VercelClientOptions {
|
||||
teamId?: string;
|
||||
apiUrl?: string;
|
||||
force?: boolean;
|
||||
prebuilt?: boolean;
|
||||
withCache?: boolean;
|
||||
userAgent?: string;
|
||||
defaultName?: string;
|
||||
|
||||
@@ -31,6 +31,14 @@ const EVENTS_ARRAY = [
|
||||
'notice',
|
||||
'tip',
|
||||
'canceled',
|
||||
// Checks events
|
||||
'checks-registered',
|
||||
'checks-completed',
|
||||
'checks-running',
|
||||
'checks-conclusion-succeeded',
|
||||
'checks-conclusion-failed',
|
||||
'checks-conclusion-skipped',
|
||||
'checks-conclusion-canceled',
|
||||
] as const;
|
||||
|
||||
export type DeploymentEventType = typeof EVENTS_ARRAY[number];
|
||||
@@ -74,11 +82,12 @@ const maybeRead = async function <T>(path: string, default_: T) {
|
||||
export async function buildFileTree(
|
||||
path: string | string[],
|
||||
isDirectory: boolean,
|
||||
debug: Debug
|
||||
debug: Debug,
|
||||
prebuilt?: boolean
|
||||
): Promise<{ fileList: string[]; ignoreList: string[] }> {
|
||||
const ignoreList: string[] = [];
|
||||
let fileList: string[];
|
||||
let { ig, ignores } = await getVercelIgnore(path);
|
||||
let { ig, ignores } = await getVercelIgnore(path, prebuilt);
|
||||
|
||||
debug(`Found ${ignores.length} rules in .vercelignore`);
|
||||
debug('Building file tree...');
|
||||
@@ -109,36 +118,38 @@ export async function buildFileTree(
|
||||
}
|
||||
|
||||
export async function getVercelIgnore(
|
||||
cwd: string | string[]
|
||||
cwd: string | string[],
|
||||
prebuilt?: boolean
|
||||
): Promise<{ ig: Ignore; ignores: string[] }> {
|
||||
const ignores: string[] = [
|
||||
'.hg',
|
||||
'.git',
|
||||
'.gitmodules',
|
||||
'.svn',
|
||||
'.cache',
|
||||
'.next',
|
||||
'.now',
|
||||
'.vercel',
|
||||
'.npmignore',
|
||||
'.dockerignore',
|
||||
'.gitignore',
|
||||
'.*.swp',
|
||||
'.DS_Store',
|
||||
'.wafpicke-*',
|
||||
'.lock-wscript',
|
||||
'.env.local',
|
||||
'.env.*.local',
|
||||
'.venv',
|
||||
'npm-debug.log',
|
||||
'config.gypi',
|
||||
'node_modules',
|
||||
'__pycache__',
|
||||
'venv',
|
||||
'CVS',
|
||||
'.vercel_build_output',
|
||||
];
|
||||
|
||||
const ignores: string[] = prebuilt
|
||||
? ['*', '!.output', '!.output/**']
|
||||
: [
|
||||
'.hg',
|
||||
'.git',
|
||||
'.gitmodules',
|
||||
'.svn',
|
||||
'.cache',
|
||||
'.next',
|
||||
'.now',
|
||||
'.vercel',
|
||||
'.npmignore',
|
||||
'.dockerignore',
|
||||
'.gitignore',
|
||||
'.*.swp',
|
||||
'.DS_Store',
|
||||
'.wafpicke-*',
|
||||
'.lock-wscript',
|
||||
'.env.local',
|
||||
'.env.*.local',
|
||||
'.venv',
|
||||
'npm-debug.log',
|
||||
'config.gypi',
|
||||
'node_modules',
|
||||
'__pycache__',
|
||||
'venv',
|
||||
'CVS',
|
||||
'.output',
|
||||
];
|
||||
const cwds = Array.isArray(cwd) ? cwd : [cwd];
|
||||
|
||||
const files = await Promise.all(
|
||||
|
||||
BIN
packages/frameworks/logos/parcel.png
Normal file
BIN
packages/frameworks/logos/parcel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 170 KiB |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/frameworks",
|
||||
"version": "0.5.1-canary.2",
|
||||
"version": "0.5.1-canary.10",
|
||||
"main": "./dist/frameworks.js",
|
||||
"types": "./dist/frameworks.d.ts",
|
||||
"files": [
|
||||
@@ -20,7 +20,7 @@
|
||||
"@types/js-yaml": "3.12.1",
|
||||
"@types/node": "12.0.4",
|
||||
"@types/node-fetch": "2.5.8",
|
||||
"@vercel/routing-utils": "1.11.3",
|
||||
"@vercel/routing-utils": "1.11.4-canary.5",
|
||||
"ajv": "6.12.2",
|
||||
"typescript": "4.3.4"
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ export const frameworks = [
|
||||
},
|
||||
devCommand: 'blitz start',
|
||||
buildCommand: 'blitz build',
|
||||
getFsOutputDir: async () => '.next',
|
||||
getOutputDirName: async () => 'public',
|
||||
},
|
||||
{
|
||||
@@ -99,6 +100,7 @@ export const frameworks = [
|
||||
],
|
||||
devCommand: 'next dev --port $PORT',
|
||||
buildCommand: 'next build',
|
||||
getFsOutputDir: async () => '.next',
|
||||
getOutputDirName: async () => 'public',
|
||||
cachePattern: '.next/cache/**',
|
||||
},
|
||||
@@ -142,6 +144,7 @@ export const frameworks = [
|
||||
devCommand: 'gatsby develop --port $PORT',
|
||||
buildCommand: 'gatsby build',
|
||||
getOutputDirName: async () => 'public',
|
||||
getFsOutputDir: async () => 'public',
|
||||
defaultRoutes: async (dirPrefix: string) => {
|
||||
// This file could be generated by gatsby-plugin-now or gatsby-plugin-zeit-now
|
||||
try {
|
||||
@@ -228,6 +231,7 @@ export const frameworks = [
|
||||
dependency: 'hexo',
|
||||
devCommand: 'hexo server --port $PORT',
|
||||
buildCommand: 'hexo generate',
|
||||
getFsOutputDir: async () => 'public',
|
||||
getOutputDirName: async () => 'public',
|
||||
},
|
||||
{
|
||||
@@ -267,6 +271,7 @@ export const frameworks = [
|
||||
dependency: '@11ty/eleventy',
|
||||
devCommand: 'npx @11ty/eleventy --serve --watch --port $PORT',
|
||||
buildCommand: 'npx @11ty/eleventy',
|
||||
getFsOutputDir: async () => '_site',
|
||||
getOutputDirName: async () => '_site',
|
||||
cachePattern: '.cache/**',
|
||||
},
|
||||
@@ -307,6 +312,22 @@ export const frameworks = [
|
||||
dependency: '@docusaurus/core',
|
||||
devCommand: 'docusaurus start --port $PORT',
|
||||
buildCommand: 'docusaurus build',
|
||||
getFsOutputDir: async (dirPrefix: string) => {
|
||||
const base = 'build';
|
||||
try {
|
||||
const location = join(dirPrefix, base);
|
||||
const content = await readdir(location, { withFileTypes: true });
|
||||
|
||||
// If there is only one file in it that is a dir we'll use it as dist dir
|
||||
if (content.length === 1 && content[0].isDirectory()) {
|
||||
return join(base, content[0].name);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error detecting output directory: `, error);
|
||||
}
|
||||
|
||||
return base;
|
||||
},
|
||||
getOutputDirName: async (dirPrefix: string) => {
|
||||
const base = 'build';
|
||||
try {
|
||||
@@ -323,6 +344,57 @@ export const frameworks = [
|
||||
|
||||
return base;
|
||||
},
|
||||
defaultHeaders: [
|
||||
{
|
||||
source: '^/[^./]+\\.[0-9a-f]{8}\\.(css|js)$',
|
||||
regex: '^/[^./]+\\.[0-9a-f]{8}\\.(css|js)$',
|
||||
headers: [
|
||||
{ key: 'cache-control', value: 'max-age=31536000, immutable' },
|
||||
],
|
||||
},
|
||||
{
|
||||
source:
|
||||
'^/assets/images/[^/]+-[0-9a-f]{32}\\.(ico|svg|jpg|jpeg|png|gif|webp)$',
|
||||
regex:
|
||||
'^/assets/images/[^/]+-[0-9a-f]{32}\\.(ico|svg|jpg|jpeg|png|gif|webp)$',
|
||||
headers: [
|
||||
{ key: 'cache-control', value: 'max-age=31536000, immutable' },
|
||||
],
|
||||
},
|
||||
{
|
||||
source:
|
||||
'^/assets/medias/[^/]+-[0-9a-f]{32}\\.(ogv|wav|mp3|m4a|aac|oga|flac)$',
|
||||
regex:
|
||||
'^/assets/medias/[^/]+-[0-9a-f]{32}\\.(ogv|wav|mp3|m4a|aac|oga|flac)$',
|
||||
headers: [
|
||||
{ key: 'cache-control', value: 'max-age=31536000, immutable' },
|
||||
],
|
||||
},
|
||||
{
|
||||
source:
|
||||
'^/assets/files/[^/]+-[0-9a-f]{32}\\.(pdf|doc|docx|xls|xlsx|zip|rar)$',
|
||||
regex:
|
||||
'^/assets/files/[^/]+-[0-9a-f]{32}\\.(pdf|doc|docx|xls|xlsx|zip|rar)$',
|
||||
headers: [
|
||||
{ key: 'cache-control', value: 'max-age=31536000, immutable' },
|
||||
],
|
||||
},
|
||||
{
|
||||
source: '^/ideal-img/[^/]+\\.[0-9a-f]{7}\\.\\d+\\.(png|jpe?g|gif)$',
|
||||
regex: '^/ideal-img/[^/]+\\.[0-9a-f]{7}\\.\\d+\\.(png|jpe?g|gif)$',
|
||||
headers: [
|
||||
{ key: 'cache-control', value: 'max-age=31536000, immutable' },
|
||||
],
|
||||
},
|
||||
],
|
||||
defaultRedirects: [
|
||||
{
|
||||
source: '.*',
|
||||
regex: '.*',
|
||||
statusCode: 404,
|
||||
destination: '404.html',
|
||||
},
|
||||
],
|
||||
defaultRoutes: [
|
||||
{
|
||||
src: '^/[^./]+\\.[0-9a-f]{8}\\.(css|js)$',
|
||||
@@ -396,6 +468,21 @@ export const frameworks = [
|
||||
dependency: 'docusaurus',
|
||||
devCommand: 'docusaurus-start --port $PORT',
|
||||
buildCommand: 'docusaurus-build',
|
||||
getFsOutputDir: async (dirPrefix: string) => {
|
||||
const base = 'build';
|
||||
try {
|
||||
const location = join(dirPrefix, base);
|
||||
const content = await readdir(location, { withFileTypes: true });
|
||||
|
||||
// If there is only one file in it that is a dir we'll use it as dist dir
|
||||
if (content.length === 1 && content[0].isDirectory()) {
|
||||
return join(base, content[0].name);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`Error detecting output directory: `, error);
|
||||
}
|
||||
return base;
|
||||
},
|
||||
getOutputDirName: async (dirPrefix: string) => {
|
||||
const base = 'build';
|
||||
try {
|
||||
@@ -448,6 +535,7 @@ export const frameworks = [
|
||||
dependency: 'preact-cli',
|
||||
devCommand: 'preact watch --port $PORT',
|
||||
buildCommand: 'preact build',
|
||||
getFsOutputDir: async () => 'build',
|
||||
getOutputDirName: async () => 'build',
|
||||
defaultRoutes: [
|
||||
{
|
||||
@@ -458,6 +546,13 @@ export const frameworks = [
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
defaultRewrites: [
|
||||
{
|
||||
source: '/(.*)',
|
||||
regex: '/(.*)',
|
||||
destination: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Dojo',
|
||||
@@ -498,6 +593,7 @@ export const frameworks = [
|
||||
dependency: '@dojo/cli',
|
||||
devCommand: 'dojo build -m dev -w -s -p $PORT',
|
||||
buildCommand: 'dojo build',
|
||||
getFsOutputDir: async () => 'output/dist',
|
||||
getOutputDirName: async () => join('output', 'dist'),
|
||||
defaultRoutes: [
|
||||
{
|
||||
@@ -513,6 +609,21 @@ export const frameworks = [
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
defaulHeaders: [
|
||||
{
|
||||
source: '/service-worker.js',
|
||||
regex: '/service-worker.js',
|
||||
headers: { 'cache-control': 's-maxage=0' },
|
||||
continue: true,
|
||||
},
|
||||
],
|
||||
defaultRewrites: [
|
||||
{
|
||||
source: '/(.*)',
|
||||
regex: '/(.*)',
|
||||
destination: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Ember.js',
|
||||
@@ -550,6 +661,7 @@ export const frameworks = [
|
||||
dependency: 'ember-cli',
|
||||
devCommand: 'ember serve --port $PORT',
|
||||
buildCommand: 'ember build',
|
||||
getFsOutputDir: async () => 'dist',
|
||||
getOutputDirName: async () => 'dist',
|
||||
defaultRoutes: [
|
||||
{
|
||||
@@ -560,6 +672,13 @@ export const frameworks = [
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
defaultRewrites: [
|
||||
{
|
||||
source: '/(.*)',
|
||||
regex: '/(.*)',
|
||||
destination: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Vue.js',
|
||||
@@ -598,6 +717,7 @@ export const frameworks = [
|
||||
dependency: '@vue/cli-service',
|
||||
devCommand: 'vue-cli-service serve --port $PORT',
|
||||
buildCommand: 'vue-cli-service build',
|
||||
getFsOutputDir: async () => 'dist',
|
||||
getOutputDirName: async () => 'dist',
|
||||
defaultRoutes: [
|
||||
{
|
||||
@@ -618,6 +738,27 @@ export const frameworks = [
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
defaultHeaders: [
|
||||
{
|
||||
source: '^/[^/]*\\.(js|txt|ico|json)',
|
||||
regex: '^/[^/]*\\.(js|txt|ico|json)',
|
||||
headers: [{ key: 'cache-control', value: 'max-age=300' }],
|
||||
},
|
||||
{
|
||||
source: '^/(img|js|css|fonts|media)/[^/]+\\.[0-9a-f]{8}\\.*',
|
||||
regex: '^/(img|js|css|fonts|media)/[^/]+\\.[0-9a-f]{8}\\.*',
|
||||
headers: [
|
||||
{ key: 'cache-control', value: 'max-age=31536000, immutable' },
|
||||
],
|
||||
},
|
||||
],
|
||||
defaultRewrites: [
|
||||
{
|
||||
source: '^.*',
|
||||
regex: '^.*',
|
||||
destination: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Scully',
|
||||
@@ -654,6 +795,7 @@ export const frameworks = [
|
||||
dependency: '@scullyio/init',
|
||||
devCommand: 'ng serve --port $PORT',
|
||||
buildCommand: 'ng build && scully',
|
||||
getFsOutputDir: async () => 'dist',
|
||||
getOutputDirName: async () => 'dist/static',
|
||||
},
|
||||
{
|
||||
@@ -682,15 +824,16 @@ export const frameworks = [
|
||||
placeholder: '`npm run build` or `ng build`',
|
||||
},
|
||||
devCommand: {
|
||||
value: 'ng serve',
|
||||
value: 'ng serve --port $PORT',
|
||||
},
|
||||
outputDirectory: {
|
||||
value: 'www',
|
||||
},
|
||||
},
|
||||
dependency: '@ionic/angular',
|
||||
devCommand: 'ng serve',
|
||||
devCommand: 'ng serve --port $PORT',
|
||||
buildCommand: 'ng build',
|
||||
getFsOutputDir: async () => 'www',
|
||||
getOutputDirName: async () => 'www',
|
||||
defaultRoutes: [
|
||||
{
|
||||
@@ -701,6 +844,13 @@ export const frameworks = [
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
defaultRewrites: [
|
||||
{
|
||||
source: '/(.*)',
|
||||
regex: '/(.*)',
|
||||
destination: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Angular',
|
||||
@@ -738,6 +888,7 @@ export const frameworks = [
|
||||
dependency: '@angular/cli',
|
||||
devCommand: 'ng serve --port $PORT',
|
||||
buildCommand: 'ng build',
|
||||
getFsOutputDir: async () => 'dist',
|
||||
getOutputDirName: async (dirPrefix: string) => {
|
||||
const base = 'dist';
|
||||
try {
|
||||
@@ -762,6 +913,13 @@ export const frameworks = [
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
defaultRewrites: [
|
||||
{
|
||||
source: '/(.*)',
|
||||
regex: '/(.*)',
|
||||
destination: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Polymer',
|
||||
@@ -799,6 +957,7 @@ export const frameworks = [
|
||||
dependency: 'polymer-cli',
|
||||
devCommand: 'polymer serve --port $PORT',
|
||||
buildCommand: 'polymer build',
|
||||
getFsOutputDir: async () => 'build',
|
||||
getOutputDirName: async (dirPrefix: string) => {
|
||||
const base = 'build';
|
||||
try {
|
||||
@@ -820,6 +979,13 @@ export const frameworks = [
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
defaultRewrites: [
|
||||
{
|
||||
source: '/(.*)',
|
||||
regex: '/(.*)',
|
||||
destination: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Svelte',
|
||||
@@ -861,6 +1027,7 @@ export const frameworks = [
|
||||
dependency: 'sirv-cli',
|
||||
devCommand: 'rollup -c -w',
|
||||
buildCommand: 'rollup -c',
|
||||
getFsOutputDir: async () => 'public',
|
||||
getOutputDirName: async () => 'public',
|
||||
defaultRoutes: [
|
||||
{
|
||||
@@ -871,6 +1038,13 @@ export const frameworks = [
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
defaultRewrites: [
|
||||
{
|
||||
source: '/(.*)',
|
||||
regex: '/(.*)',
|
||||
destination: '/index.html',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'SvelteKit',
|
||||
@@ -907,6 +1081,7 @@ export const frameworks = [
|
||||
},
|
||||
devCommand: 'svelte-kit dev --port $PORT',
|
||||
buildCommand: 'svelte-kit build',
|
||||
getFsOutputDir: async () => '.output',
|
||||
getOutputDirName: async () => 'public',
|
||||
},
|
||||
{
|
||||
@@ -944,6 +1119,7 @@ export const frameworks = [
|
||||
dependency: '@ionic/react',
|
||||
devCommand: 'react-scripts start',
|
||||
buildCommand: 'react-scripts build',
|
||||
getFsOutputDir: async () => 'build',
|
||||
getOutputDirName: async () => 'build',
|
||||
defaultRoutes: [
|
||||
{
|
||||
@@ -970,6 +1146,45 @@ export const frameworks = [
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
defaultHeaders: [
|
||||
{
|
||||
source: '/static/(.*)',
|
||||
regex: '/static/(.*)',
|
||||
headers: [
|
||||
{ key: 'cache-control', value: 's-maxage=31536000, immutable' },
|
||||
],
|
||||
},
|
||||
{
|
||||
source: '/service-worker.js',
|
||||
regex: '/service-worker.js',
|
||||
headers: [{ key: 'cache-control', value: 's-maxage=0' }],
|
||||
},
|
||||
{
|
||||
source: '/(.*)',
|
||||
regex: '/(.*)',
|
||||
headers: [{ key: 'cache-control', value: 's-maxage=0' }],
|
||||
},
|
||||
],
|
||||
defaultRedirects: [
|
||||
{
|
||||
source: '/static/(.*)',
|
||||
destination: '/404.html',
|
||||
statusCode: 404,
|
||||
regex: '/static/(.*)',
|
||||
},
|
||||
],
|
||||
defaultRewrites: [
|
||||
{
|
||||
source: '/sockjs-node/(.*)',
|
||||
destination: '/sockjs-node/$1',
|
||||
regex: '/sockjs-node/(.*)',
|
||||
},
|
||||
{
|
||||
source: '/(.*)',
|
||||
destination: '/index.html',
|
||||
regex: '/(.*)',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Create React App',
|
||||
@@ -1012,6 +1227,7 @@ export const frameworks = [
|
||||
dependency: 'react-scripts',
|
||||
devCommand: 'react-scripts start',
|
||||
buildCommand: 'react-scripts build',
|
||||
getFsOutputDir: async () => 'build',
|
||||
getOutputDirName: async () => 'build',
|
||||
defaultRoutes: [
|
||||
{
|
||||
@@ -1038,6 +1254,45 @@ export const frameworks = [
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
defaultHeaders: [
|
||||
{
|
||||
source: '/static/(.*)',
|
||||
regex: '/static/(.*)',
|
||||
headers: [
|
||||
{ key: 'cache-control', value: 's-maxage=31536000, immutable' },
|
||||
],
|
||||
},
|
||||
{
|
||||
source: '/service-worker.js',
|
||||
regex: '/service-worker.js',
|
||||
headers: [{ key: 'cache-control', value: 's-maxage=0' }],
|
||||
},
|
||||
{
|
||||
source: '/(.*)',
|
||||
regex: '/(.*)',
|
||||
headers: [{ key: 'cache-control', value: 's-maxage=0' }],
|
||||
},
|
||||
],
|
||||
defaultRedirects: [
|
||||
{
|
||||
source: '/static/(.*)',
|
||||
destination: '/404.html',
|
||||
statusCode: 404,
|
||||
regex: '/static/(.*)',
|
||||
},
|
||||
],
|
||||
defaultRewrites: [
|
||||
{
|
||||
source: '/sockjs-node/(.*)',
|
||||
destination: '/sockjs-node/$1',
|
||||
regex: '/sockjs-node/(.*)',
|
||||
},
|
||||
{
|
||||
source: '/(.*)',
|
||||
destination: '/index.html',
|
||||
regex: '/(.*)',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Gridsome',
|
||||
@@ -1075,6 +1330,7 @@ export const frameworks = [
|
||||
dependency: 'gridsome',
|
||||
devCommand: 'gridsome develop -p $PORT',
|
||||
buildCommand: 'gridsome build',
|
||||
getFsOutputDir: async () => 'dist',
|
||||
getOutputDirName: async () => 'dist',
|
||||
},
|
||||
{
|
||||
@@ -1113,6 +1369,7 @@ export const frameworks = [
|
||||
dependency: 'umi',
|
||||
devCommand: 'umi dev --port $PORT',
|
||||
buildCommand: 'umi build',
|
||||
getFsOutputDir: async () => 'dist',
|
||||
getOutputDirName: async () => 'dist',
|
||||
defaultRoutes: [
|
||||
{
|
||||
@@ -1123,6 +1380,13 @@ export const frameworks = [
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
defaultRewrites: [
|
||||
{
|
||||
source: '/(.*)',
|
||||
destination: '/index.html',
|
||||
regex: '/(.*)',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Sapper',
|
||||
@@ -1160,6 +1424,7 @@ export const frameworks = [
|
||||
dependency: 'sapper',
|
||||
devCommand: 'sapper dev --port $PORT',
|
||||
buildCommand: 'sapper export',
|
||||
getFsOutputDir: async () => '__sapper__/export',
|
||||
getOutputDirName: async () => '__sapper__/export',
|
||||
},
|
||||
{
|
||||
@@ -1198,6 +1463,7 @@ export const frameworks = [
|
||||
dependency: 'saber',
|
||||
devCommand: 'saber --port $PORT',
|
||||
buildCommand: 'saber build',
|
||||
getFsOutputDir: async () => 'public',
|
||||
getOutputDirName: async () => 'public',
|
||||
defaultRoutes: [
|
||||
{
|
||||
@@ -1213,6 +1479,23 @@ export const frameworks = [
|
||||
dest: '404.html',
|
||||
},
|
||||
],
|
||||
defaultHeaders: [
|
||||
{
|
||||
source: '/_saber/.*',
|
||||
regex: '/_saber/.*',
|
||||
headers: [
|
||||
{ key: 'cache-control', value: 'max-age=31536000, immutable' },
|
||||
],
|
||||
},
|
||||
],
|
||||
defaultRedirects: [
|
||||
{
|
||||
source: '.*',
|
||||
statusCode: 404,
|
||||
destination: '404.html',
|
||||
regex: '.*',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Stencil',
|
||||
@@ -1250,6 +1533,7 @@ export const frameworks = [
|
||||
dependency: '@stencil/core',
|
||||
devCommand: 'stencil build --dev --watch --serve --port $PORT',
|
||||
buildCommand: 'stencil build',
|
||||
getFsOutputDir: async () => 'www',
|
||||
getOutputDirName: async () => 'www',
|
||||
defaultRoutes: [
|
||||
{
|
||||
@@ -1275,6 +1559,32 @@ export const frameworks = [
|
||||
dest: '/index.html',
|
||||
},
|
||||
],
|
||||
defaultHeaders: [
|
||||
{
|
||||
source: '/assets/(.*)',
|
||||
regex: '/assets/(.*)',
|
||||
headers: [{ key: 'cache-control', value: 'max-age=2592000' }],
|
||||
},
|
||||
{
|
||||
source: '/build/p-.*',
|
||||
regex: '/build/p-.*',
|
||||
headers: [
|
||||
{ key: 'cache-control', value: 'max-age=31536000, immutable' },
|
||||
],
|
||||
},
|
||||
{
|
||||
source: '/sw.js',
|
||||
regex: '/sw.js',
|
||||
headers: [{ key: 'cache-control', value: 'no-cache' }],
|
||||
},
|
||||
],
|
||||
defaultRewrites: [
|
||||
{
|
||||
source: '/(.*)',
|
||||
destination: '/index.html',
|
||||
regex: '/(.*)',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Nuxt.js',
|
||||
@@ -1291,7 +1601,7 @@ export const frameworks = [
|
||||
{
|
||||
path: 'package.json',
|
||||
matchContent:
|
||||
'"(dev)?(d|D)ependencies":\\s*{[^}]*"nuxt(-edge)?":\\s*".+?"[^}]*}',
|
||||
'"(dev)?(d|D)ependencies":\\s*{[^}]*"nuxt3?(-edge)?":\\s*".+?"[^}]*}',
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -1312,6 +1622,7 @@ export const frameworks = [
|
||||
dependency: 'nuxt',
|
||||
devCommand: 'nuxt',
|
||||
buildCommand: 'nuxt generate',
|
||||
getFsOutputDir: async () => '.output',
|
||||
getOutputDirName: async () => 'dist',
|
||||
cachePattern: '.nuxt/**',
|
||||
defaultRoutes: [
|
||||
@@ -1371,6 +1682,7 @@ export const frameworks = [
|
||||
},
|
||||
devCommand: 'yarn rw dev --fwd="--port=$PORT --open=false',
|
||||
buildCommand: 'yarn rw deploy vercel',
|
||||
getFsOutputDir: async () => 'public',
|
||||
getOutputDirName: async () => 'public',
|
||||
},
|
||||
{
|
||||
@@ -1416,6 +1728,16 @@ export const frameworks = [
|
||||
},
|
||||
devCommand: 'hugo server -D -w -p $PORT',
|
||||
buildCommand: 'hugo -D --gc',
|
||||
getFsOutputDir: async (dirPrefix: string): Promise<string> => {
|
||||
type HugoConfig = { publishDir?: string };
|
||||
const config = await readConfigFile<HugoConfig>(
|
||||
['config.json', 'config.yaml', 'config.toml'].map(fileName => {
|
||||
return join(dirPrefix, fileName);
|
||||
})
|
||||
);
|
||||
|
||||
return (config && config.publishDir) || 'public';
|
||||
},
|
||||
getOutputDirName: async (dirPrefix: string): Promise<string> => {
|
||||
type HugoConfig = { publishDir?: string };
|
||||
const config = await readConfigFile<HugoConfig>(
|
||||
@@ -1461,6 +1783,13 @@ export const frameworks = [
|
||||
},
|
||||
devCommand: 'bundle exec jekyll serve --watch --port $PORT',
|
||||
buildCommand: 'jekyll build',
|
||||
getFsOutputDir: async (dirPrefix: string): Promise<string> => {
|
||||
type JekyllConfig = { destination?: string };
|
||||
const config = await readConfigFile<JekyllConfig>(
|
||||
join(dirPrefix, '_config.yml')
|
||||
);
|
||||
return (config && config.destination) || '_site';
|
||||
},
|
||||
getOutputDirName: async (dirPrefix: string): Promise<string> => {
|
||||
type JekyllConfig = { destination?: string };
|
||||
const config = await readConfigFile<JekyllConfig>(
|
||||
@@ -1503,6 +1832,7 @@ export const frameworks = [
|
||||
},
|
||||
devCommand: 'brunch watch --server --port $PORT',
|
||||
buildCommand: 'brunch build --production',
|
||||
getFsOutputDir: async () => 'public',
|
||||
getOutputDirName: async () => 'public',
|
||||
},
|
||||
{
|
||||
@@ -1538,6 +1868,7 @@ export const frameworks = [
|
||||
},
|
||||
devCommand: 'bundle exec middleman server -p $PORT',
|
||||
buildCommand: 'bundle exec middleman build',
|
||||
getFsOutputDir: async () => 'build',
|
||||
getOutputDirName: async () => 'build',
|
||||
cachePattern: '{vendor/bin,vendor/cache,vendor/bundle}/**',
|
||||
},
|
||||
@@ -1574,6 +1905,7 @@ export const frameworks = [
|
||||
},
|
||||
devCommand: 'zola serve --port $PORT',
|
||||
buildCommand: 'zola build',
|
||||
getFsOutputDir: async () => 'public',
|
||||
getOutputDirName: async () => 'public',
|
||||
defaultVersion: '0.13.0',
|
||||
},
|
||||
@@ -1613,13 +1945,71 @@ export const frameworks = [
|
||||
dependency: 'vite',
|
||||
devCommand: 'vite',
|
||||
buildCommand: 'vite build',
|
||||
getFsOutputDir: async () => 'dist',
|
||||
getOutputDirName: async () => 'dist',
|
||||
},
|
||||
{
|
||||
name: 'Parcel',
|
||||
slug: 'parcel',
|
||||
demo: 'https://parcel.examples.vercel.com',
|
||||
logo: 'https://raw.githubusercontent.com/vercel/vercel/main/packages/frameworks/logos/parcel.png',
|
||||
tagline:
|
||||
'Parcel is a zero configuration build tool for the web that scales to projects of any size and complexity.',
|
||||
description: 'A vanilla web app built with Parcel.',
|
||||
website: 'https://parceljs.org',
|
||||
detectors: {
|
||||
every: [
|
||||
{
|
||||
path: 'package.json',
|
||||
matchContent:
|
||||
'"(dev)?(d|D)ependencies":\\s*{[^}]*"parcel":\\s*".+?"[^}]*}',
|
||||
},
|
||||
],
|
||||
},
|
||||
settings: {
|
||||
installCommand: {
|
||||
placeholder: '`yarn install` or `npm install`',
|
||||
},
|
||||
buildCommand: {
|
||||
placeholder: '`npm run build` or `parcel build`',
|
||||
},
|
||||
devCommand: {
|
||||
placeholder: 'parcel',
|
||||
},
|
||||
outputDirectory: {
|
||||
placeholder: 'dist',
|
||||
},
|
||||
},
|
||||
dependency: 'parcel',
|
||||
devCommand: 'parcel',
|
||||
buildCommand: 'parcel build',
|
||||
getFsOutputDir: async () => 'dist',
|
||||
getOutputDirName: async () => 'dist',
|
||||
defaultRoutes: [
|
||||
{
|
||||
src: '^/[^./]+\\.[0-9a-f]{8}\\.(css|js|png|jpg|webp|avif|svg)$',
|
||||
headers: { 'cache-control': 's-maxage=31536000, immutable' },
|
||||
continue: true,
|
||||
},
|
||||
{
|
||||
handle: 'filesystem',
|
||||
},
|
||||
],
|
||||
defaultHeaders: [
|
||||
{
|
||||
source: '^/[^./]+\\.[0-9a-f]{8}\\.(css|js|png|jpg|webp|avif|svg)$',
|
||||
regex: '^/[^./]+\\.[0-9a-f]{8}\\.(css|js|png|jpg|webp|avif|svg)$',
|
||||
headers: [
|
||||
{ key: 'cache-control', value: 's-maxage=31536000, immutable' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'Other',
|
||||
slug: null,
|
||||
logo: 'https://raw.githubusercontent.com/vercel/vercel/main/packages/frameworks/logos/other.svg',
|
||||
description: 'No framework or a unoptimized framework.',
|
||||
description: 'No framework or an unoptimized framework.',
|
||||
settings: {
|
||||
installCommand: {
|
||||
placeholder: '`yarn install` or `npm install`',
|
||||
@@ -1636,6 +2026,22 @@ export const frameworks = [
|
||||
},
|
||||
devCommand: null,
|
||||
buildCommand: null,
|
||||
getFsOutputDir: async (dirPrefix: string): Promise<string> => {
|
||||
// Public if it exists or `.`
|
||||
let base = 'public';
|
||||
try {
|
||||
const location = join(dirPrefix, base);
|
||||
const content = await readdir(location, { withFileTypes: true });
|
||||
|
||||
// If there is only one file in it that is a dir we'll use it as dist dir
|
||||
if (content.length === 1 && content[0].isDirectory()) {
|
||||
return join(base, content[0].name);
|
||||
}
|
||||
} catch (_error) {
|
||||
base = '.';
|
||||
}
|
||||
return base;
|
||||
},
|
||||
getOutputDirName: async () => 'public',
|
||||
},
|
||||
] as const;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Route } from '@vercel/routing-utils';
|
||||
import { Header, Rewrite, Route } from '@vercel/routing-utils';
|
||||
|
||||
export interface FrameworkDetectionItem {
|
||||
/**
|
||||
@@ -32,6 +32,15 @@ export interface SettingValue {
|
||||
|
||||
export type Setting = SettingValue | SettingPlaceholder;
|
||||
|
||||
export type Redirect = Rewrite & {
|
||||
statusCode?: number;
|
||||
permanent?: boolean;
|
||||
};
|
||||
|
||||
type RoutesManifestRegex = {
|
||||
regex: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* Framework detection information.
|
||||
*/
|
||||
@@ -154,6 +163,11 @@ export interface Framework {
|
||||
* Function that returns the name of the directory that the framework outputs
|
||||
* its build results to. In some cases this is read from a configuration file.
|
||||
*/
|
||||
getFsOutputDir: (dirPrefix: string) => Promise<string>;
|
||||
/**
|
||||
* Function that returns the name of the directory that the framework outputs
|
||||
* its STATIC build results to. In some cases this is read from a configuration file.
|
||||
*/
|
||||
getOutputDirName: (dirPrefix: string) => Promise<string>;
|
||||
/**
|
||||
* An array (or a function that returns an array) of default `Route` rules that
|
||||
@@ -161,6 +175,27 @@ export interface Framework {
|
||||
* @example [{ handle: 'filesystem' }, { src: '.*', status: 404, dest: '404.html' }]
|
||||
*/
|
||||
defaultRoutes?: Route[] | ((dirPrefix: string) => Promise<Route[]>);
|
||||
/**
|
||||
* An array (or a function that returns an array) of default `Header` rules that
|
||||
* the framework uses.
|
||||
*/
|
||||
defaultHeaders?:
|
||||
| (Header & RoutesManifestRegex)[]
|
||||
| ((dirPrefix: string) => Promise<(Header & RoutesManifestRegex)[]>);
|
||||
/**
|
||||
* An array (or a function that returns an array) of default `Redirect` rules that
|
||||
* the framework uses.
|
||||
*/
|
||||
defaultRedirects?:
|
||||
| (Redirect & RoutesManifestRegex)[]
|
||||
| ((dirPrefix: string) => Promise<(Redirect & RoutesManifestRegex)[]>);
|
||||
/**
|
||||
* An array (or a function that returns an array) of default `Rewrite` rules that
|
||||
* the framework uses.
|
||||
*/
|
||||
defaultRewrites?:
|
||||
| (Rewrite & RoutesManifestRegex)[]
|
||||
| ((dirPrefix: string) => Promise<(Rewrite & RoutesManifestRegex)[]>);
|
||||
/**
|
||||
* A glob string of files to cache for future deployments.
|
||||
* @example ".cache/**"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/go",
|
||||
"version": "1.2.4-canary.1",
|
||||
"version": "1.2.4-canary.3",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
||||
@@ -24,7 +24,7 @@
|
||||
"@types/fs-extra": "^5.0.5",
|
||||
"@types/node-fetch": "^2.3.0",
|
||||
"@types/tar": "^4.0.0",
|
||||
"@vercel/ncc": "0.29.2",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"async-retry": "1.3.1",
|
||||
"execa": "^1.0.0",
|
||||
"fs-extra": "^7.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node",
|
||||
"version": "1.12.2-canary.1",
|
||||
"version": "1.12.2-canary.4",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
||||
@@ -32,8 +32,8 @@
|
||||
"@types/cookie": "0.3.3",
|
||||
"@types/etag": "1.8.0",
|
||||
"@types/test-listen": "1.1.0",
|
||||
"@vercel/ncc": "0.29.2",
|
||||
"@vercel/nft": "0.13.1",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/nft": "0.14.0",
|
||||
"@vercel/node-bridge": "2.1.1-canary.1",
|
||||
"content-type": "1.0.4",
|
||||
"cookie": "0.4.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/python",
|
||||
"version": "2.0.6-canary.1",
|
||||
"version": "2.0.6-canary.4",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
||||
@@ -20,7 +20,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/execa": "^0.9.0",
|
||||
"@vercel/ncc": "0.29.2",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"execa": "^1.0.0",
|
||||
"typescript": "4.3.4"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user