Compare commits

..

2 Commits

Author SHA1 Message Date
Nathan Rajlich
7cb1307627 . 2021-10-22 11:29:43 -07:00
Nathan Rajlich
887e299b34 [go] WIP Refactor to Vercel CLI Plugin 2021-10-22 11:29:01 -07:00
369 changed files with 1334 additions and 16275 deletions

View File

@@ -1,10 +1,11 @@
node_modules
dist
examples
packages/*/test/fixtures
packages/build-utils/test/fixtures
packages/cli/@types
packages/cli/download
packages/cli/dist
packages/cli/test/fixtures
packages/cli/test/dev/fixtures
packages/cli/bin
packages/cli/link
@@ -12,6 +13,6 @@ packages/cli/src/util/dev/templates/*.ts
packages/client/tests/fixtures
packages/client/lib
packages/node/src/bridge.ts
packages/node/test/fixtures
packages/node-bridge/bridge.js
packages/node-bridge/launcher.js
packages/middleware/src/entries.js

View File

@@ -11,7 +11,7 @@ on:
jobs:
test:
name: Dev
timeout-minutes: 75
timeout-minutes: 60
strategy:
fail-fast: false
matrix:

1
.gitignore vendored
View File

@@ -27,4 +27,3 @@ test/lib/deployment/failed-page.txt
/public
__pycache__
.vercel
.output

View File

@@ -14,6 +14,8 @@ const frameworks = (_frameworks as Framework[])
sort: undefined,
dependency: undefined,
defaultRoutes: undefined,
devCommand: undefined,
buildCommand: undefined,
};
if (framework.logo) {

View File

@@ -9,7 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"next": "12.0.1",
"next": "11.1.2",
"react": "17.0.2",
"react-dom": "17.0.2"
},

View File

@@ -43,14 +43,7 @@
core-js-pure "^3.16.0"
regenerator-runtime "^0.13.4"
"@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":
"@babel/runtime@7.15.3", "@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==
@@ -119,10 +112,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@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/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/eslint-plugin-next@11.1.0":
version "11.1.0"
@@ -131,15 +124,15 @@
dependencies:
glob "7.1.7"
"@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/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/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==
"@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==
dependencies:
"@babel/code-frame" "7.12.11"
anser "1.4.9"
@@ -151,67 +144,32 @@
shell-quote "1.7.2"
source-map "0.8.0-beta.0"
stacktrace-parser "0.1.10"
strip-ansi "6.0.1"
strip-ansi "6.0.0"
"@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/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/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-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-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-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-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-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-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==
"@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==
"@node-rs/helper@1.2.1":
version "1.2.1"
@@ -300,16 +258,6 @@ 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"
@@ -350,11 +298,6 @@ 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"
@@ -447,11 +390,24 @@ 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"
@@ -576,7 +532,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==
@@ -607,6 +563,15 @@ 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"
@@ -727,7 +692,12 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
constants-browserify@1.0.0:
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:
version "1.0.0"
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=
@@ -744,6 +714,11 @@ 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"
@@ -784,7 +759,7 @@ cross-spawn@^7.0.2:
shebang-command "^2.0.0"
which "^2.0.1"
crypto-browserify@3.12.0:
crypto-browserify@3.12.0, crypto-browserify@^3.11.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==
@@ -911,6 +886,11 @@ 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"
@@ -1239,7 +1219,7 @@ etag@1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
events@3.3.0:
events@^3.0.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
@@ -1506,7 +1486,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=
@@ -1568,11 +1548,21 @@ 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.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.1, 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"
@@ -1716,6 +1706,11 @@ 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"
@@ -1957,30 +1952,32 @@ 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=
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==
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==
dependencies:
"@babel/runtime" "7.15.4"
"@babel/runtime" "7.15.3"
"@hapi/accept" "5.0.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"
"@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"
"@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"
@@ -1993,48 +1990,40 @@ next@12.0.1:
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 "5.0.0-beta.3"
styled-jsx "4.0.1"
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-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"
"@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"
node-fetch@2.6.1:
version "2.6.1"
@@ -2048,6 +2037,35 @@ 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"
@@ -2148,7 +2166,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=
@@ -2229,6 +2247,11 @@ 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"
@@ -2318,6 +2341,13 @@ 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"
@@ -2332,7 +2362,12 @@ 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@0.11.10:
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:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
@@ -2363,16 +2398,36 @@ 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.1, querystring-es3@^0.2.0:
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"
@@ -2434,16 +2489,6 @@ 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"
@@ -2469,6 +2514,19 @@ 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"
@@ -2485,11 +2543,6 @@ 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"
@@ -2566,7 +2619,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.1:
safe-buffer@~5.1.0, 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==
@@ -2727,6 +2780,14 @@ 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"
@@ -2737,6 +2798,17 @@ 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"
@@ -2788,21 +2860,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.1.1:
string_decoder@1.3.0, string_decoder@^1.0.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"
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==
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==
dependencies:
ansi-regex "^5.0.1"
safe-buffer "~5.1.0"
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==
@@ -2819,10 +2891,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@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==
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==
dependencies:
"@babel/plugin-syntax-jsx" "7.14.5"
"@babel/types" "7.15.0"
@@ -2881,13 +2953,18 @@ 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.12, timers-browserify@^2.0.4:
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"
@@ -2912,6 +2989,11 @@ 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"
@@ -2933,6 +3015,11 @@ 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"
@@ -2977,6 +3064,14 @@ 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"
@@ -2984,11 +3079,18 @@ 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"
@@ -3001,6 +3103,13 @@ 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"
@@ -3014,7 +3123,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.1.2, vm-browserify@^1.0.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
@@ -3027,11 +3136,6 @@ 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"
@@ -3086,7 +3190,7 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
xtend@^4.0.2:
xtend@^4.0.0, 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==

View File

@@ -24,7 +24,7 @@
"eslint-config-prettier": "8.3.0",
"eslint-plugin-jest": "24.3.6",
"husky": "6.0.0",
"jest": "27.3.1",
"jest": "27.0.6",
"json5": "2.1.1",
"lint-staged": "9.2.5",
"node-fetch": "2.6.1",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/build-utils",
"version": "2.12.3-canary.20",
"version": "2.12.3-canary.13",
"license": "MIT",
"main": "./dist/index.js",
"types": "./dist/index.d.js",
@@ -21,7 +21,7 @@
"@types/async-retry": "^1.2.1",
"@types/cross-spawn": "6.0.0",
"@types/end-of-stream": "^1.4.0",
"@types/fs-extra": "9.0.13",
"@types/fs-extra": "^5.0.5",
"@types/glob": "^7.1.1",
"@types/jest": "27.0.1",
"@types/js-yaml": "3.12.1",
@@ -30,7 +30,7 @@
"@types/node-fetch": "^2.1.6",
"@types/semver": "6.0.0",
"@types/yazl": "^2.4.1",
"@vercel/frameworks": "0.5.1-canary.12",
"@vercel/frameworks": "0.5.1-canary.9",
"@vercel/ncc": "0.24.0",
"aggregate-error": "3.0.1",
"async-retry": "1.2.3",
@@ -38,7 +38,7 @@
"boxen": "4.2.0",
"cross-spawn": "6.0.5",
"end-of-stream": "1.4.1",
"fs-extra": "10.0.0",
"fs-extra": "7.0.0",
"glob": "7.1.3",
"into-stream": "5.0.0",
"js-yaml": "3.13.1",

View File

@@ -1,202 +0,0 @@
import fs from 'fs-extra';
import { join, dirname, relative } from 'path';
import glob from './fs/glob';
import { normalizePath } from './fs/normalize-path';
import { FILES_SYMBOL, getLambdaOptionsFromFunction, Lambda } from './lambda';
import type FileBlob from './file-blob';
import type { BuilderFunctions, BuildOptions, Files } from './types';
import minimatch from 'minimatch';
/**
* Convert legacy Runtime to a Plugin.
* @param buildRuntime - a legacy build() function from a Runtime
* @param ext - the file extension, for example `.py`
*/
export function convertRuntimeToPlugin(
buildRuntime: (options: BuildOptions) => Promise<{ output: Lambda }>,
ext: string
) {
return async function build({ workPath }: { workPath: string }) {
const opts = { cwd: workPath };
const files = await glob('**', opts);
delete files['vercel.json']; // Builders/Runtimes didn't have vercel.json
const entrypoints = await glob(`api/**/*${ext}`, opts);
const pages: { [key: string]: any } = {};
const { functions = {} } = await readVercelConfig(workPath);
const traceDir = join(workPath, '.output', 'runtime-traced-files');
await fs.ensureDir(traceDir);
for (const entrypoint of Object.keys(entrypoints)) {
const key =
Object.keys(functions).find(
src => src === entrypoint || minimatch(entrypoint, src)
) || '';
const config = functions[key] || {};
const { output } = await buildRuntime({
files,
entrypoint,
workPath,
config: {
zeroConfig: true,
includeFiles: config.includeFiles,
excludeFiles: config.excludeFiles,
},
});
pages[entrypoint] = {
handler: output.handler,
runtime: output.runtime,
memory: output.memory,
maxDuration: output.maxDuration,
environment: output.environment,
allowQuery: output.allowQuery,
regions: output.regions,
};
// @ts-ignore This symbol is a private API
const lambdaFiles: Files = output[FILES_SYMBOL];
const entry = join(workPath, '.output', 'server', 'pages', entrypoint);
await fs.ensureDir(dirname(entry));
await linkOrCopy(files[entrypoint].fsPath, entry);
const tracedFiles: {
absolutePath: string;
relativePath: string;
}[] = [];
Object.entries(lambdaFiles).forEach(async ([relPath, file]) => {
const newPath = join(traceDir, relPath);
tracedFiles.push({ absolutePath: newPath, relativePath: relPath });
if (file.fsPath) {
await linkOrCopy(file.fsPath, newPath);
} else if (file.type === 'FileBlob') {
const { data, mode } = file as FileBlob;
await fs.writeFile(newPath, data, { mode });
} else {
throw new Error(`Unknown file type: ${file.type}`);
}
});
const nft = join(
workPath,
'.output',
'server',
'pages',
`${entrypoint}.nft.json`
);
const json = JSON.stringify({
version: 1,
files: tracedFiles.map(f => ({
input: normalizePath(relative(nft, f.absolutePath)),
output: normalizePath(f.relativePath),
})),
});
await fs.ensureDir(dirname(nft));
await fs.writeFile(nft, json);
}
await updateFunctionsManifest({ workPath, pages });
};
}
async function linkOrCopy(existingPath: string, newPath: string) {
try {
await fs.createLink(existingPath, newPath);
} catch (err: any) {
if (err.code !== 'EEXIST') {
await fs.copyFile(existingPath, newPath);
}
}
}
async function readJson(filePath: string): Promise<{ [key: string]: any }> {
try {
const str = await fs.readFile(filePath, 'utf8');
return JSON.parse(str);
} catch (err) {
if (err.code === 'ENOENT') {
return {};
}
throw err;
}
}
async function readVercelConfig(
workPath: string
): Promise<{ functions?: BuilderFunctions; regions?: string[] }> {
const vercelJsonPath = join(workPath, 'vercel.json');
return readJson(vercelJsonPath);
}
/**
* If `.output/functions-manifest.json` exists, append to the pages
* property. Otherwise write a new file. This will also read `vercel.json`
* and apply relevant `functions` property config.
*/
export async function updateFunctionsManifest({
workPath,
pages,
}: {
workPath: string;
pages: { [key: string]: any };
}) {
const functionsManifestPath = join(
workPath,
'.output',
'functions-manifest.json'
);
const vercelConfig = await readVercelConfig(workPath);
const functionsManifest = await readJson(functionsManifestPath);
if (!functionsManifest.version) functionsManifest.version = 1;
if (!functionsManifest.pages) functionsManifest.pages = {};
for (const [pageKey, pageConfig] of Object.entries(pages)) {
const fnConfig = await getLambdaOptionsFromFunction({
sourceFile: pageKey,
config: vercelConfig,
});
functionsManifest.pages[pageKey] = {
...pageConfig,
memory: fnConfig.memory || pageConfig.memory,
maxDuration: fnConfig.maxDuration || pageConfig.maxDuration,
regions: vercelConfig.regions || pageConfig.regions,
};
}
await fs.writeFile(functionsManifestPath, JSON.stringify(functionsManifest));
}
/**
* Will append routes to the `routes-manifest.json` file.
* If the file does not exist, it'll be created.
*/
export async function updateRoutesManifest({
workPath,
dynamicRoutes,
}: {
workPath: string;
dynamicRoutes?: {
page: string;
regex: string;
namedRegex?: string;
routeKeys?: { [named: string]: string };
}[];
}) {
const routesManifestPath = join(workPath, '.output', 'routes-manifest.json');
const routesManifest = await readJson(routesManifestPath);
if (!routesManifest.version) routesManifest.version = 1;
if (routesManifest.pages404 === undefined) routesManifest.pages404 = true;
if (dynamicRoutes) {
if (!routesManifest.dynamicRoutes) routesManifest.dynamicRoutes = [];
routesManifest.dynamicRoutes.push(...dynamicRoutes);
}
await fs.writeFile(routesManifestPath, JSON.stringify(routesManifest));
}

View File

@@ -3,7 +3,6 @@ import assert from 'assert';
import vanillaGlob_ from 'glob';
import { promisify } from 'util';
import { lstat, Stats } from 'fs-extra';
import { normalizePath } from './normalize-path';
import FileFsRef from '../file-fs-ref';
export type GlobOptions = vanillaGlob_.IOptions;
@@ -46,7 +45,7 @@ export default async function glob(
const files = await vanillaGlob(pattern, options);
for (const relativePath of files) {
const fsPath = normalizePath(path.join(options.cwd!, relativePath));
const fsPath = path.join(options.cwd!, relativePath).replace(/\\/g, '/');
let stat: Stats = options.statCache![fsPath] as Stats;
assert(
stat,

View File

@@ -1,8 +0,0 @@
const isWin = process.platform === 'win32';
/**
* Convert Windows separators to Unix separators.
*/
export function normalizePath(p: string): string {
return isWin ? p.replace(/\\/g, '/') : p;
}

View File

@@ -81,12 +81,6 @@ export {
export { detectFramework } from './detect-framework';
export { DetectorFilesystem } from './detectors/filesystem';
export { readConfigFile } from './fs/read-config-file';
export { normalizePath } from './fs/normalize-path';
export {
convertRuntimeToPlugin,
updateFunctionsManifest,
updateRoutesManifest,
} from './convert-runtime-to-plugin';
export * from './schemas';
export * from './types';

View File

@@ -36,11 +36,9 @@ interface CreateLambdaOptions {
interface GetLambdaOptionsFromFunctionOptions {
sourceFile: string;
config?: Pick<Config, 'functions'>;
config?: Config;
}
export const FILES_SYMBOL = Symbol('files');
export class Lambda {
public type: 'Lambda';
public zipBuffer: Buffer;
@@ -120,7 +118,7 @@ export async function createLambda({
try {
const zipBuffer = await createZip(files);
const lambda = new Lambda({
return new Lambda({
zipBuffer,
handler,
runtime,
@@ -129,9 +127,6 @@ export async function createLambda({
environment,
regions,
});
// @ts-ignore This symbol is a private API
lambda[FILES_SYMBOL] = files;
return lambda;
} finally {
sema.release();
}

View File

@@ -10,7 +10,6 @@ export interface File {
mode: number;
contentType?: string;
toStream: () => NodeJS.ReadableStream;
toStreamAsync?: () => Promise<NodeJS.ReadableStream>;
/**
* The absolute path to the file in the filesystem
*/

View File

@@ -1,5 +1,5 @@
{
"version": 2,
"builds": [{ "src": "package.json", "use": "@vercel/static-build" }],
"probes": [{ "path": "/", "mustContain": "npm version: 8" }]
"probes": [{ "path": "/", "mustContain": "npm version: 7" }]
}

View File

@@ -1,182 +0,0 @@
import { join } from 'path';
import fs from 'fs-extra';
import { BuildOptions, createLambda } from '../src';
import { convertRuntimeToPlugin } from '../src/convert-runtime-to-plugin';
async function fsToJson(dir: string, output: Record<string, any> = {}) {
const files = await fs.readdir(dir);
for (const file of files) {
const fsPath = join(dir, file);
const stat = await fs.stat(fsPath);
if (stat.isDirectory()) {
output[file] = {};
await fsToJson(fsPath, output[file]);
} else {
output[file] = await fs.readFile(fsPath, 'utf8');
}
}
return output;
}
const workPath = join(__dirname, 'walk', 'python-api');
describe('convert-runtime-to-plugin', () => {
afterEach(async () => {
await fs.remove(join(workPath, '.output'));
});
it('should create correct fileystem for python', async () => {
const lambdaOptions = {
handler: 'index.handler',
runtime: 'python3.9',
memory: 512,
maxDuration: 5,
environment: {},
regions: ['sfo1'],
};
const buildRuntime = async (opts: BuildOptions) => {
const lambda = await createLambda({
files: opts.files,
...lambdaOptions,
});
return { output: lambda };
};
const lambdaFiles = await fsToJson(workPath);
delete lambdaFiles['vercel.json'];
const build = await convertRuntimeToPlugin(buildRuntime, '.py');
await build({ workPath });
const output = await fsToJson(join(workPath, '.output'));
expect(output).toMatchObject({
'functions-manifest.json': expect.stringContaining('{'),
'runtime-traced-files': lambdaFiles,
server: {
pages: {
api: {
'index.py': expect.stringContaining('index'),
'index.py.nft.json': expect.stringContaining('{'),
users: {
'get.py': expect.stringContaining('get'),
'get.py.nft.json': expect.stringContaining('{'),
'post.py': expect.stringContaining('post'),
'post.py.nft.json': expect.stringContaining('{'),
},
},
},
},
});
const funcManifest = JSON.parse(output['functions-manifest.json']);
expect(funcManifest).toMatchObject({
version: 1,
pages: {
'api/index.py': lambdaOptions,
'api/users/get.py': lambdaOptions,
'api/users/post.py': { ...lambdaOptions, memory: 3008 },
},
});
const indexJson = JSON.parse(output.server.pages.api['index.py.nft.json']);
expect(indexJson).toMatchObject({
version: 1,
files: [
{
input: '../../../../runtime-traced-files/api/index.py',
output: 'api/index.py',
},
{
input: '../../../../runtime-traced-files/api/users/get.py',
output: 'api/users/get.py',
},
{
input: '../../../../runtime-traced-files/api/users/post.py',
output: 'api/users/post.py',
},
{
input: '../../../../runtime-traced-files/file.txt',
output: 'file.txt',
},
{
input: '../../../../runtime-traced-files/util/date.py',
output: 'util/date.py',
},
{
input: '../../../../runtime-traced-files/util/math.py',
output: 'util/math.py',
},
],
});
const getJson = JSON.parse(
output.server.pages.api.users['get.py.nft.json']
);
expect(getJson).toMatchObject({
version: 1,
files: [
{
input: '../../../../../runtime-traced-files/api/index.py',
output: 'api/index.py',
},
{
input: '../../../../../runtime-traced-files/api/users/get.py',
output: 'api/users/get.py',
},
{
input: '../../../../../runtime-traced-files/api/users/post.py',
output: 'api/users/post.py',
},
{
input: '../../../../../runtime-traced-files/file.txt',
output: 'file.txt',
},
{
input: '../../../../../runtime-traced-files/util/date.py',
output: 'util/date.py',
},
{
input: '../../../../../runtime-traced-files/util/math.py',
output: 'util/math.py',
},
],
});
const postJson = JSON.parse(
output.server.pages.api.users['post.py.nft.json']
);
expect(postJson).toMatchObject({
version: 1,
files: [
{
input: '../../../../../runtime-traced-files/api/index.py',
output: 'api/index.py',
},
{
input: '../../../../../runtime-traced-files/api/users/get.py',
output: 'api/users/get.py',
},
{
input: '../../../../../runtime-traced-files/api/users/post.py',
output: 'api/users/post.py',
},
{
input: '../../../../../runtime-traced-files/file.txt',
output: 'file.txt',
},
{
input: '../../../../../runtime-traced-files/util/date.py',
output: 'util/date.py',
},
{
input: '../../../../../runtime-traced-files/util/math.py',
output: 'util/math.py',
},
],
});
expect(output.server.pages['file.txt']).toBeUndefined();
expect(output.server.pages.api['file.txt']).toBeUndefined();
});
});

View File

@@ -1 +0,0 @@
# index

View File

@@ -1 +0,0 @@
This file should also be included

View File

@@ -1 +0,0 @@
# date

View File

@@ -1 +0,0 @@
# math

View File

@@ -1,10 +0,0 @@
{
"functions": {
"api/users/post.py": {
"memory": 3008
},
"api/not-matching-anything.py": {
"memory": 768
}
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "23.1.3-canary.36",
"version": "23.1.3-canary.15",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -43,17 +43,14 @@
"node": ">= 12"
},
"dependencies": {
"@vercel/build-utils": "2.12.3-canary.20",
"@vercel/go": "1.2.4-canary.4",
"@vercel/node": "1.12.2-canary.7",
"@vercel/python": "2.0.6-canary.6",
"@vercel/ruby": "1.2.8-canary.4",
"update-notifier": "4.1.0",
"vercel-plugin-middleware": "0.0.0-canary.7",
"vercel-plugin-node": "1.12.2-canary.11"
"@vercel/build-utils": "2.12.3-canary.13",
"@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"
},
"devDependencies": {
"@next/env": "11.1.2",
"@sentry/node": "5.5.0",
"@sindresorhus/slugify": "0.11.0",
"@tootallnate/once": "1.1.2",
@@ -66,7 +63,7 @@
"@types/dotenv": "6.1.1",
"@types/escape-html": "0.0.20",
"@types/express": "4.17.13",
"@types/fs-extra": "9.0.13",
"@types/fs-extra": "5.0.5",
"@types/glob": "7.1.1",
"@types/http-proxy": "1.16.2",
"@types/inquirer": "7.3.1",
@@ -90,9 +87,8 @@
"@types/update-notifier": "5.1.0",
"@types/which": "1.3.2",
"@types/write-json-file": "2.2.1",
"@vercel/frameworks": "0.5.1-canary.12",
"@vercel/frameworks": "0.5.1-canary.9",
"@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",
@@ -124,7 +120,7 @@
"execa": "3.2.0",
"express": "4.17.1",
"fast-deep-equal": "3.1.3",
"fs-extra": "10.0.0",
"fs-extra": "7.0.1",
"get-port": "5.1.1",
"glob": "7.1.2",
"http-proxy": "1.18.1",

View File

@@ -1,791 +0,0 @@
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 logo from '../util/output/logo';
import param from '../util/output/param';
import stamp from '../util/output/stamp';
import { getCommandName, getPkgName } from '../util/pkg-name';
import { loadCliPlugins } from '../util/plugins';
import { findFramework } from '../util/projects/find-framework';
import { VERCEL_DIR } from '../util/projects/link';
import { 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';
export default async function main(client: Client) {
if (process.env.__VERCEL_BUILD_RUNNING) {
client.output.error(
`${cmd(
`${getPkgName()} build`
)} must not recursively invoke itself. Check the Build Command in the Project Settings or the ${cmd(
'build'
)} script in ${cmd('package.json')}`
);
client.output.error(
`Learn More: https://vercel.link/recursive-invocation-of-commands`
);
return 1;
} else {
process.env.__VERCEL_BUILD_RUNNING = '1';
}
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));
}
// If `rootDirectory` exists, then `baseDir` will be the repo's root directory.
const baseDir = cwd;
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 };
const formatSetting = (
name: string,
override: string | null | undefined,
defaults: typeof framework.settings.outputDirectory
) =>
` - ${chalk.bold(`${name}:`)} ${`${
override
? override + ` (override)`
: 'placeholder' in defaults
? chalk.italic(`${defaults.placeholder}`)
: defaults.value
}`}`;
console.log(`Retrieved Project Settings:`);
console.log(
chalk.dim(` - ${chalk.bold(`Framework Preset:`)} ${framework.name}`)
);
console.log(
chalk.dim(
formatSetting(
'Build Command',
project.settings.buildCommand,
framework.settings.buildCommand
)
)
);
console.log(
chalk.dim(
formatSetting(
'Output Directory',
project.settings.outputDirectory,
framework.settings.outputDirectory
)
)
);
buildState.outputDirectory =
project.settings.outputDirectory ||
(isSettingValue(framework.settings.outputDirectory)
? framework.settings.outputDirectory.value
: null);
buildState.rootDirectory = project.settings.rootDirectory;
if (loadedEnvFiles.length > 0) {
console.log(
`Loaded Environment Variables from ${loadedEnvFiles.length} ${pluralize(
'file',
loadedEnvFiles.length
)}:`
);
for (let envFile of loadedEnvFiles) {
console.log(chalk.dim(` - ${envFile.path}`));
}
}
// Load plugins
const debug = argv['--debug'];
let plugins;
try {
plugins = await loadCliPlugins(cwd, client.output);
} 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) {
console.log(
`Loaded ${plugins.pluginCount} CLI ${pluralize(
'Plugin',
plugins.pluginCount
)}`
);
// preBuild Plugins
if (plugins.preBuildPlugins.length > 0) {
console.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));
// Yarn v2 PnP mode may be activated, so force
// "node-modules" linker style
const env = {
YARN_NODE_LINKER: 'node-modules',
...spawnOpts.env,
};
if (typeof buildState.buildCommand === 'string') {
console.log(`Running Build Command: ${cmd(buildState.buildCommand)}`);
await execCommand(buildState.buildCommand, {
...spawnOpts,
env,
cwd,
});
} else if (fs.existsSync(join(cwd, 'package.json'))) {
await runPackageJsonScript(
client,
cwd,
['vercel-build', 'now-build', 'build'],
spawnOpts
);
} else if (typeof framework.settings.buildCommand.value === 'string') {
console.log(
`Running Build Command: ${cmd(framework.settings.buildCommand.value)}`
);
await execCommand(framework.settings.buildCommand.value, {
...spawnOpts,
env,
cwd,
});
}
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/**',
'.env',
'.env.*',
'.*ignore',
'_middleware.ts',
'_middleware.mts',
'_middleware.cts',
'_middleware.mjs',
'_middleware.cjs',
'_middleware.js',
'api/**',
'.git/**',
'.next/cache/**',
],
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();
console.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')
);
// Next.js might reference files from the `static` directory in `middleware-manifest.json`.
// Since we move all files from `static` to `static/_next/static`, we'll need to change
// those references as well and update the manifest file.
const middlewareManifest = join(
cwd,
OUTPUT_DIR,
'server',
'middleware-manifest.json'
);
if (fs.existsSync(middlewareManifest)) {
const manifest = await fs.readJSON(middlewareManifest);
Object.keys(manifest.middleware).forEach(key => {
const files = manifest.middleware[key].files.map((f: string) => {
if (f.startsWith('static/')) {
const next = f.replace(/^static\//gm, 'static/_next/static/');
client.output.debug(
`Replacing file in \`middleware-manifest.json\`: ${f} => ${next}`
);
return next;
}
return f;
});
manifest.middleware[key].files = files;
});
await fs.writeJSON(middlewareManifest, manifest);
}
// 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,
baseDir,
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,
baseDir,
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) => {
const absolutePath = join(cwd, i.replace('.next', '.output'));
const output = relative(baseDir, absolutePath);
return {
input: i.replace('.next', '.output'),
output,
};
}),
});
}
}
// Build Plugins
if (plugins?.buildPlugins && plugins.buildPlugins.length > 0) {
console.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({
workPath: cwd,
});
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;
}
}
}
}
console.log(
`${prependEmoji(
`Build Completed in ${chalk.bold(OUTPUT_DIR)} ${chalk.gray(
buildStamp()
)}`,
emoji('success')
)}`
);
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';
}
}
console.log(`Running Build Command: ${cmd(opts.prettyCommand)}\n`);
await spawnAsync(cliType, ['run', scriptName], opts);
console.log(); // give it some room
client.output.debug(`Script complete [${Date.now() - runScriptTime}ms]`);
return true;
}
async function linkOrCopy(existingPath: string, newPath: string) {
try {
if (
newPath.endsWith('.nft.json') ||
newPath.endsWith('middleware-manifest.json') ||
newPath.endsWith('required-server-files.json')
) {
await fs.copy(existingPath, newPath, {
overwrite: true,
});
} else {
await fs.createSymlink(existingPath, newPath, 'file');
}
} catch (err: any) {
// eslint-disable-line
// If a symlink 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), symlink 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.copy(existingPath, newPath, {
overwrite: true,
});
}
}
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,
baseDir,
outputDir,
nftFileName,
nft,
}: {
client: Client;
baseDir: 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);
// We have to use `baseDir` instead of `cwd`, because we want to
// mount everything from there (especially `node_modules`).
// This is important for NPM Workspaces where `node_modules` is not
// in the directory of the workspace.
const output = relative(baseDir, fullInput).replace('.output', '.next');
newFilesList.push({
input: relative(parse(nftFileName).dir, newFilePath),
output,
});
} else {
newFilesList.push(relativeInput);
}
}
// Update the .nft.json with new input and output mapping
await fs.writeJSON(nftFileName, {
...nft,
files: newFilesList,
});
}

View File

@@ -60,7 +60,6 @@ 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 { output } = client;
@@ -79,7 +78,6 @@ 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',
@@ -446,7 +444,6 @@ 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,
@@ -530,20 +527,6 @@ 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,

View File

@@ -6,6 +6,7 @@ import { ProjectEnvVariable } from '../../types';
import Client from '../../util/client';
import { getLinkedProject } from '../../util/projects/link';
import { getFrameworks } from '../../util/get-frameworks';
import { isSettingValue } from '../../util/is-setting-value';
import { ProjectSettings } from '../../types';
import getDecryptedEnvRecords from '../../util/get-decrypted-env-records';
import setupAndLink from '../../util/link/setup-and-link';
@@ -70,9 +71,9 @@ export default async function dev(
frameworkSlug = framework.slug;
}
const defaults = framework.settings.devCommand.value;
if (defaults) {
devCommand = defaults;
const defaults = framework.settings.devCommand;
if (isSettingValue(defaults)) {
devCommand = defaults.value;
}
}
}

View File

@@ -48,22 +48,6 @@ const help = () => {
};
export default async function main(client: Client) {
if (process.env.__VERCEL_DEV_RUNNING) {
client.output.error(
`${cmd(
`${getPkgName()} dev`
)} must not recursively invoke itself. Check the Development Command in the Project Settings or the ${cmd(
'dev'
)} script in ${cmd('package.json')}`
);
client.output.error(
`Learn More: https://vercel.link/recursive-invocation-of-commands`
);
return 1;
} else {
process.env.__VERCEL_DEV_RUNNING = '1';
}
let argv;
let args;
const { output } = client;
@@ -106,21 +90,22 @@ export default async function main(client: Client) {
if (pkg) {
const { scripts } = pkg as PackageJson;
if (
scripts &&
scripts.dev &&
/\b(now|vercel)\b\W+\bdev\b/.test(scripts.dev)
) {
client.output.error(
`${cmd(
`${getPkgName()} dev`
)} must not recursively invoke itself. Check the Development Command in the Project Settings or the ${cmd(
'dev'
)} script in ${cmd('package.json')}`
if (scripts && scripts.dev && /\bnow\b\W+\bdev\b/.test(scripts.dev)) {
output.error(
`The ${cmd('dev')} script in ${cmd(
'package.json'
)} must not contain ${cmd('now dev')}`
);
client.output.error(
`Learn More: https://vercel.link/recursive-invocation-of-commands`
output.error(`Learn More: http://err.sh/vercel/now-dev-as-dev-script`);
return 1;
}
if (scripts && scripts.dev && /\bvercel\b\W+\bdev\b/.test(scripts.dev)) {
output.error(
`The ${cmd('dev')} script in ${cmd(
'package.json'
)} must not contain ${cmd('vercel dev')}`
);
output.error(`Learn More: http://err.sh/vercel/now-dev-as-dev-script`);
return 1;
}
}

View File

@@ -2,7 +2,6 @@ export default new Map([
['alias', 'alias'],
['aliases', 'alias'],
['billing', 'billing'],
['build', 'build'],
['cc', 'billing'],
['cert', 'certs'],
['certs', 'certs'],

View File

@@ -13,7 +13,7 @@ import {
VERCEL_DIR,
VERCEL_DIR_PROJECT,
} from '../util/projects/link';
import { writeProjectSettings } from '../util/projects/project-settings';
import { writeProjectSettings } from '../util/projects/write-project-settings';
import pull from './env/pull';
const help = () => {
@@ -87,8 +87,6 @@ export default async function main(client: Client) {
const { project, org } = link;
client.config.currentTeam = org.type === 'team' ? org.id : undefined;
const result = await pull(
client,
project,

View File

@@ -160,26 +160,18 @@ const main = async () => {
// * a path to deploy (as in: `vercel path/`)
// * a subcommand (as in: `vercel ls`)
const targetOrSubcommand = argv._[2];
const isBuildOrDev =
targetOrSubcommand === 'build' || targetOrSubcommand === 'dev';
if (isBuildOrDev) {
console.log(
`${chalk.grey(
`${getTitleName()} CLI ${
pkg.version
} ${targetOrSubcommand} (beta) — https://vercel.com/feedback`
)}`
);
} else {
output.print(
`${chalk.grey(
`${getTitleName()} CLI ${pkg.version}${
isCanary ? ' — https://vercel.com/feedback' : ''
}`
)}\n`
);
}
output.print(
`${chalk.grey(
`${getTitleName()} CLI ${pkg.version}${
targetOrSubcommand === 'dev' ? ' dev (beta)' : ''
}${
isCanary || targetOrSubcommand === 'dev'
? ' — https://vercel.com/feedback'
: ''
}`
)}\n`
);
// Handle `--version` directly
if (!targetOrSubcommand && argv['--version']) {
@@ -294,14 +286,7 @@ const main = async () => {
let authConfig = null;
const subcommandsWithoutToken = [
'login',
'logout',
'help',
'init',
'update',
'build',
];
const subcommandsWithoutToken = ['login', 'logout', 'help', 'init', 'update'];
if (authConfigExists) {
try {
@@ -408,33 +393,20 @@ const main = async () => {
} else if (commands.has(singular)) {
alternative = singular;
}
if (targetOrSubcommand === 'build') {
output.note(
`If you wish to deploy the ${fileType} ${param(
targetOrSubcommand
)}, run ${getCommandName('deploy build')}.` +
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.`
: '')
);
} 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;
}
)
);
return 1;
}
if (subcommandExists) {
@@ -629,9 +601,6 @@ const main = async () => {
case 'billing':
func = await import('./commands/billing');
break;
case 'build':
func = await import('./commands/build');
break;
case 'certs':
func = await import('./commands/certs');
break;

View File

@@ -18,8 +18,12 @@ export const isDirectory = (path: string): boolean => {
const getGlobalPathConfig = (): string => {
let customPath: string | undefined;
const argv = getArgs(process.argv.slice(2), {}, { permissive: true });
customPath = argv['--global-config'];
try {
const argv = getArgs(process.argv.slice(2), {});
customPath = argv['--global-config'];
} catch (_error) {
// args are optional so consume error
}
const vercelDirectories = XDGAppPaths('com.vercel.cli').dataDirs();

View File

@@ -7,8 +7,12 @@ import getArgs from '../../util/get-args';
export default function getLocalPathConfig(prefix: string) {
let customPath: string | undefined;
const argv = getArgs(process.argv.slice(2), {}, { permissive: true });
customPath = argv['--local-config'];
try {
const argv = getArgs(process.argv.slice(2), {});
customPath = argv['--local-config'];
} catch (_error) {
// args are optional so consume error
}
// If `--local-config` flag was specified, then that takes priority
if (customPath) {

View File

@@ -1,37 +0,0 @@
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;
}

View File

@@ -47,7 +47,6 @@ export default async function processDeployment({
force?: boolean;
withCache?: boolean;
org: Org;
prebuilt: boolean;
projectName: string;
isSettingUpProject: boolean;
skipAutoDetectionConfirmation?: boolean;
@@ -63,7 +62,6 @@ export default async function processDeployment({
withCache,
nowConfig,
quiet,
prebuilt,
} = args;
const { debug } = output;
@@ -85,7 +83,6 @@ export default async function processDeployment({
path: paths[0],
force,
withCache,
prebuilt,
skipAutoDetectionConfirmation,
};
@@ -182,26 +179,10 @@ export default async function processDeployment({
return event.payload;
}
// 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)
) {
if (event.type === 'ready') {
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();

View File

@@ -89,7 +89,6 @@ import {
} from './types';
import { ProjectEnvVariable, ProjectSettings } from '../../types';
import exposeSystemEnvs from './expose-system-envs';
import { loadCliPlugins } from '../plugins';
const frontendRuntimeSet = new Set(
frameworkList.map(f => f.useRuntime?.use || '@vercel/static-build')
@@ -1350,30 +1349,6 @@ export default class DevServer {
return false;
};
runDevMiddleware = async (
req: http.IncomingMessage,
res: http.ServerResponse
) => {
const { devMiddlewarePlugins } = await loadCliPlugins(
this.cwd,
this.output
);
try {
for (let plugin of devMiddlewarePlugins) {
const result = await plugin.plugin.runDevMiddleware(req, res, this.cwd);
if (result.finished) {
return result;
}
}
return { finished: false };
} catch (e) {
return {
finished: true,
error: e,
};
}
};
/**
* Serve project directory as a v2 deployment.
*/
@@ -1441,36 +1416,6 @@ export default class DevServer {
let prevUrl = req.url;
let prevHeaders: HttpHeadersConfig = {};
const middlewareResult = await this.runDevMiddleware(req, res);
if (middlewareResult) {
if (middlewareResult.error) {
this.sendError(
req,
res,
requestId,
'EDGE_FUNCTION_INVOCATION_FAILED',
500
);
return;
}
if (middlewareResult.finished) {
return;
}
if (middlewareResult.pathname) {
const origUrl = url.parse(req.url || '/', true);
origUrl.pathname = middlewareResult.pathname;
prevUrl = url.format(origUrl);
}
if (middlewareResult.query && prevUrl) {
const origUrl = url.parse(req.url || '/', true);
delete origUrl.search;
Object.assign(origUrl.query, middlewareResult.query);
prevUrl = url.format(origUrl);
}
}
for (const phase of phases) {
statusCode = undefined;
@@ -2161,10 +2106,7 @@ export default class DevServer {
process.stdout.write(data.replace(proxyPort, devPort));
});
p.on('exit', (code: number) => {
if (code > 0) {
process.exit(code);
}
p.on('exit', () => {
this.devProcessPort = undefined;
});

View File

@@ -1,9 +1,11 @@
import { Stats } from 'fs';
import { sep, dirname, join, resolve } from 'path';
import { lstat, readlink, readFile, realpath } from 'fs-extra';
import { readJSON, lstat, readlink, readFile, realpath } from 'fs-extra';
import { isCanary } from './is-canary';
import { getPkgName } from './pkg-name';
// `npm` tacks a bunch of extra properties on the `package.json` file,
// so check for one of them to determine yarn vs. npm.
async function isYarn(): Promise<boolean> {
let s: Stats;
let binPath = process.argv[1];
@@ -18,12 +20,8 @@ async function isYarn(): Promise<boolean> {
}
}
const pkgPath = join(dirname(binPath), '..', 'package.json');
/*
* Generally, pkgPath looks like:
* "/Users/username/.config/yarn/global/node_modules/vercel/package.json"
* "/usr/local/share/.config/yarn/global/node_modules/vercel/package.json"
*/
return pkgPath.includes(join('yarn', 'global'));
const pkg = await readJSON(pkgPath).catch(() => ({}));
return !('_id' in pkg);
}
async function getConfigPrefix() {

View File

@@ -36,7 +36,6 @@ export interface CreateOptions {
name: string;
project?: string;
wantsPublic: boolean;
prebuilt?: boolean;
meta: Dictionary<string>;
regions?: string[];
quiet?: boolean;
@@ -112,7 +111,6 @@ export default class Now extends EventEmitter {
// Latest
name,
project,
prebuilt = false,
wantsPublic,
meta,
regions,
@@ -167,7 +165,6 @@ export default class Now extends EventEmitter {
isSettingUpProject,
skipAutoDetectionConfirmation,
cwd,
prebuilt,
});
if (deployment && deployment.warnings) {

View File

@@ -1,5 +1,6 @@
import crypto from 'crypto';
import ua from 'universal-analytics';
import { platform, release, userInfo } from 'os';
import { getPlatformEnv } from '@vercel/build-utils';
import userAgent from './ua-browser';
@@ -15,15 +16,10 @@ export const shouldCollectMetrics =
export const metrics = (): ua.Visitor => {
const token =
typeof config.token === 'string'
? config.token
: process.platform + process.arch;
const salt =
(process.env.USER || '') +
(process.env.LANG || '') +
(process.env.SHELL || '');
typeof config.token === 'string' ? config.token : platform() + release();
const salt = userInfo().username;
const hash = crypto
.pbkdf2Sync(token, salt, 100, 64, 'sha512')
.pbkdf2Sync(token, salt, 1000, 64, 'sha512')
.toString('hex')
.substring(0, 24);

View File

@@ -1,24 +0,0 @@
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;
}

View File

@@ -125,14 +125,10 @@ export class Output {
this.debug(`Spinner invoked (${message}) with a ${delay}ms delay`);
return;
}
if (this.isTTY) {
if (this._spinner) {
this._spinner.text = message;
} else {
this._spinner = wait(message, delay);
}
if (this._spinner) {
this._spinner.text = message;
} else {
this.print(`${message}\n`);
this._spinner = wait(message, delay);
}
};

View File

@@ -1,6 +1,11 @@
import { relative as nativeRelative } from 'path';
import { normalizePath } from '@vercel/build-utils';
const isWin = process.platform === 'win32';
export function relative(a: string, b: string): string {
return normalizePath(nativeRelative(a, b));
let p = nativeRelative(a, b);
if (isWin) {
p = p.replace(/\\/g, '/');
}
return p;
}

View File

@@ -1,76 +0,0 @@
import code from '../util/output/code';
import { getColorForPkgName } from '../util/output/color-name-cache';
import cliPkgJson from '../util/pkg';
import { scanParentDirs } from '@vercel/build-utils';
import { Output } from './output';
const VERCEL_PLUGIN_PREFIX = 'vercel-plugin-';
export async function loadCliPlugins(cwd: string, output: Output) {
const { packageJson } = await scanParentDirs(cwd, true);
let pluginCount = 0;
const preBuildPlugins = [];
const buildPlugins = [];
const devServerPlugins = [];
const devMiddlewarePlugins = [];
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,
});
}
if (typeof plugin.startDevServer === 'function') {
devServerPlugins.push({
plugin,
name: dep,
color,
});
}
if (typeof plugin.runDevMiddleware === 'function') {
devMiddlewarePlugins.push({
plugin,
name: dep,
color,
});
}
} catch (error) {
output.error(`Failed to import ${code(dep)}`);
throw error;
}
}
return {
pluginCount,
preBuildPlugins,
buildPlugins,
devServerPlugins,
devMiddlewarePlugins,
};
}

View File

@@ -1,5 +0,0 @@
import { Framework, frameworks } from '@vercel/frameworks';
export function findFramework(slug?: string | null) {
return (frameworks as any as Framework[]).find(f => f.slug === slug);
}

View File

@@ -23,7 +23,6 @@ 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';
@@ -68,14 +67,12 @@ async function getLink(path?: string): Promise<ProjectLink | null> {
return getLinkFromDir(dir);
}
export async function getLinkFromDir<T = ProjectLink>(
dir: string
): Promise<T | null> {
async function getLinkFromDir(dir: string): Promise<ProjectLink | null> {
try {
const json = await readFile(join(dir, VERCEL_DIR_PROJECT), 'utf8');
const ajv = new AJV();
const link: T = JSON.parse(json);
const link: ProjectLink = JSON.parse(json);
if (!ajv.validate(linkSchema, link)) {
throw new Error(
@@ -244,27 +241,16 @@ export async function linkFolderToProject(
try {
const gitIgnorePath = join(path, '.gitignore');
let gitIgnore =
(await readFile(gitIgnorePath, 'utf8').catch(() => null)) ?? '';
const EOL = gitIgnore.includes('\r\n') ? '\r\n' : os.EOL;
let contentModified = false;
const gitIgnore = await readFile(gitIgnorePath, 'utf8').catch(() => null);
const EOL = gitIgnore && gitIgnore.includes('\r\n') ? '\r\n' : os.EOL;
if (!gitIgnore.split(EOL).includes(VERCEL_DIR)) {
gitIgnore += `${
gitIgnore.endsWith(EOL) || gitIgnore.length === 0 ? '' : EOL
}${VERCEL_DIR}${EOL}`;
contentModified = true;
}
if (!gitIgnore.split(EOL).includes(VERCEL_OUTPUT_DIR)) {
gitIgnore += `${
gitIgnore.endsWith(EOL) || gitIgnore.length === 0 ? '' : EOL
}${VERCEL_OUTPUT_DIR}${EOL}`;
contentModified = true;
}
if (contentModified) {
await writeFile(gitIgnorePath, gitIgnore);
if (!gitIgnore || !gitIgnore.split(EOL).includes(VERCEL_DIR)) {
await writeFile(
gitIgnorePath,
gitIgnore
? `${gitIgnore}${EOL}${VERCEL_DIR}${EOL}`
: `${VERCEL_DIR}${EOL}`
);
isGitIgnoreUpdated = true;
}
} catch (error) {

View File

@@ -1,19 +1,8 @@
import { writeFile } from 'fs-extra';
import { Org, Project, ProjectLink } from '../../types';
import { getLinkFromDir, VERCEL_DIR, VERCEL_DIR_PROJECT } from './link';
import { Org, Project } from '../../types';
import { 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(
@@ -30,13 +19,10 @@ export async function writeProjectSettings(
buildCommand: project.buildCommand,
devCommand: project.devCommand,
directoryListing: project.directoryListing,
outputDirectory: project.outputDirectory,
rootDirectory: project.rootDirectory,
framework: project.framework,
},
})
);
}
export async function readProjectSettings(cwd: string) {
return await getLinkFromDir<ProjectLinkAndSettings>(cwd);
}

View File

@@ -1,3 +0,0 @@
export default () => {
throw new Error('asdf');
};

View File

@@ -1,3 +0,0 @@
export default function () {
return 'freecandy';
}

View File

@@ -1,5 +0,0 @@
import { response } from './response';
export default () => {
return new Response(response);
};

View File

@@ -1 +0,0 @@
export const response = 'response';

View File

@@ -1,10 +0,0 @@
import response from './response.json';
export default function () {
return new Response(JSON.stringify(response), {
status: 200,
headers: {
'Content-Type': 'application/json',
},
});
}

View File

@@ -1 +0,0 @@
not hello world

View File

@@ -1,3 +0,0 @@
{
"text": "hello world"
}

View File

@@ -1,69 +0,0 @@
# 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

View File

@@ -1,4 +0,0 @@
.cache
package.json
package-lock.json
public

View File

@@ -1,7 +0,0 @@
{
"endOfLine": "lf",
"semi": false,
"singleQuote": false,
"tabWidth": 2,
"trailingComma": "es5"
}

View File

@@ -1,22 +0,0 @@
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.

View File

@@ -1,97 +0,0 @@
<!-- 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 sites 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 youd 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 wont change this file directly).**
11. **`package.json`**: A manifest file for Node.js projects, which includes things like metadata (the projects 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
[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/gatsbyjs/gatsby-starter-default)
<!-- AUTO-GENERATED-CONTENT:END -->

View File

@@ -1,7 +0,0 @@
/**
* 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

View File

@@ -1,34 +0,0 @@
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`,
],
}

View File

@@ -1,7 +0,0 @@
/**
* 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

View File

@@ -1,7 +0,0 @@
/**
* 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

View File

@@ -1,43 +0,0 @@
{
"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"
}
}

View File

@@ -1,42 +0,0 @@
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

View File

@@ -1,32 +0,0 @@
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

View File

@@ -1,622 +0,0 @@
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%;
}
}

View File

@@ -1,52 +0,0 @@
/**
* 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

View File

@@ -1,88 +0,0 @@
/**
* 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

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,14 +0,0 @@
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&#39;t exist... the sadness.</p>
</Layout>
)
export default NotFoundPage

View File

@@ -1,21 +0,0 @@
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

View File

@@ -1,16 +0,0 @@
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

View File

@@ -1,4 +1,2 @@
.next
yarn.lock
.vercel
.output

View File

@@ -1 +0,0 @@
User-Agent: *

View File

@@ -19,7 +19,7 @@ const getRevertAliasConfigFile = () => {
],
});
};
module.exports = async function prepare(session, binaryPath) {
module.exports = async function prepare(session) {
const spec = {
'static-single-file': {
'first.png': getImageFile(session, { size: 30 }),
@@ -114,23 +114,6 @@ module.exports = async function prepare(session, binaryPath) {
2
),
},
'dev-fail-on-recursion-command': {
'package.json': '{}',
},
'build-fail-on-recursion-command': {
'package.json': '{}',
},
'build-fail-on-recursion-script': {
'package.json': JSON.stringify(
{
scripts: {
build: `${binaryPath} build`,
},
},
null,
2
),
},
'static-deployment': {
'index.txt': 'Hello World',
},
@@ -365,10 +348,6 @@ module.exports = async function prepare(session, binaryPath) {
'project-link-dev': {
'package.json': '{}',
},
'project-link-gitignore': {
'package.json': '{}',
'.gitignore': '.output',
},
'project-link-legacy': {
'index.html': 'Hello',
'vercel.json': '{"builds":[{"src":"*.html","use":"@vercel/static"}]}',

View File

@@ -252,69 +252,10 @@ const createUser = async () => {
const getConfigAuthPath = () => path.join(globalDir, 'auth.json');
async function setupProject(process, projectName, overrides) {
await waitForPrompt(process, chunk => /Set up [^?]+\?/.test(chunk));
process.stdin.write('yes\n');
await waitForPrompt(process, chunk => /Which scope [^?]+\?/.test(chunk));
process.stdin.write('\n');
await waitForPrompt(process, chunk =>
chunk.includes('Link to existing project?')
);
process.stdin.write('no\n');
await waitForPrompt(process, chunk =>
chunk.includes('Whats your projects name?')
);
process.stdin.write(`${projectName}\n`);
await waitForPrompt(process, chunk =>
chunk.includes('In which directory is your code located?')
);
process.stdin.write('\n');
await waitForPrompt(process, chunk =>
chunk.includes('Want to override the settings?')
);
if (overrides) {
process.stdin.write('yes\n');
const { buildCommand, outputDirectory, devCommand } = overrides;
await waitForPrompt(process, chunk =>
chunk.includes(
'Which settings would you like to overwrite (select multiple)?'
)
);
process.stdin.write('a\n'); // 'a' means select all
await waitForPrompt(process, chunk =>
chunk.includes(`What's your Build Command?`)
);
process.stdin.write(`${buildCommand ?? ''}\n`);
await waitForPrompt(process, chunk =>
chunk.includes(`What's your Output Directory?`)
);
process.stdin.write(`${outputDirectory ?? ''}\n`);
await waitForPrompt(process, chunk =>
chunk.includes(`What's your Development Command?`)
);
process.stdin.write(`${devCommand ?? ''}\n`);
} else {
process.stdin.write('no\n');
}
await waitForPrompt(process, chunk => chunk.includes('Linked to'));
}
test.before(async () => {
try {
await createUser();
await prepareFixtures(contextName, binaryPath);
await prepareFixtures(contextName);
} catch (err) {
console.log('Failed `test.before`');
console.log(err);
@@ -2286,93 +2227,13 @@ test('whoami', async t => {
t.is(stdout, contextName, formatOutput({ stdout, stderr }));
});
test('[vercel dev] fails when dev script calls vercel dev recursively', async t => {
test('fail `now dev` dev script without now.json', async t => {
const deploymentPath = fixture('now-dev-fail-dev-script');
const { exitCode, stderr } = await execute(['dev', deploymentPath]);
t.is(exitCode, 1);
t.true(
stderr.includes('must not recursively invoke itself'),
`Received instead: "${stderr}"`
);
});
test('[vercel dev] fails when development commad calls vercel dev recursively', async t => {
const dir = fixture('dev-fail-on-recursion-command');
const projectName = `dev-fail-on-recursion-command-${
Math.random().toString(36).split('.')[1]
}`;
const dev = execa(binaryPath, ['dev', ...defaultArgs], {
cwd: dir,
reject: false,
});
await setupProject(dev, projectName, {
devCommand: `${binaryPath} dev`,
});
const { exitCode, stderr } = await dev;
t.is(exitCode, 1);
t.true(
stderr.includes('must not recursively invoke itself'),
`Received instead: "${stderr}"`
);
});
test('[vercel build] fails when build commad calls vercel build recursively', async t => {
const dir = fixture('build-fail-on-recursion-command');
const projectName = `build-fail-on-recursion-command-${
Math.random().toString(36).split('.')[1]
}`;
const build = execa(binaryPath, ['build', ...defaultArgs], {
cwd: dir,
reject: false,
});
await waitForPrompt(build, chunk =>
chunk.includes('No Project Settings found locally')
);
build.stdin.write('yes\n');
await setupProject(build, projectName, {
buildCommand: `${binaryPath} build`,
});
const { exitCode, stderr } = await build;
t.is(exitCode, 1);
t.true(
stderr.includes('must not recursively invoke itself'),
`Received instead: "${stderr}"`
);
});
test('[vercel build] fails when build script calls vercel build recursively', async t => {
const dir = fixture('build-fail-on-recursion-script');
const projectName = `build-fail-on-recursion-script-${
Math.random().toString(36).split('.')[1]
}`;
const build = execa(binaryPath, ['build', ...defaultArgs], {
cwd: dir,
reject: false,
});
await waitForPrompt(build, chunk =>
chunk.includes('No Project Settings found locally')
);
build.stdin.write('yes\n');
await setupProject(build, projectName);
const { exitCode, stderr } = await build;
t.is(exitCode, 1);
t.true(
stderr.includes('must not recursively invoke itself'),
stderr.includes('must not contain `now dev`'),
`Received instead: "${stderr}"`
);
});
@@ -2683,7 +2544,7 @@ test('deploy a Lambda with 3 seconds of maxDuration', async t => {
const url = new URL(output.stdout);
// Should time out
url.pathname = '/api/wait-for/5';
url.pathname = '/api/wait-for/4';
const response1 = await fetch(url.href);
t.is(
response1.status,
@@ -2692,7 +2553,7 @@ test('deploy a Lambda with 3 seconds of maxDuration', async t => {
);
// Should not time out
url.pathname = '/api/wait-for/1';
url.pathname = '/api/wait-for/2';
const response2 = await fetch(url.href);
t.is(
response2.status,
@@ -2812,20 +2673,69 @@ 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 dir = fixture('project-link-deploy');
const directory = 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(dir, '.vercel'));
await remove(path.join(directory, '.vercel'));
const now = execa(binaryPath, [dir, ...defaultArgs]);
const now = execa(binaryPath, [directory, ...defaultArgs]);
await setupProject(now, projectName, {
buildCommand: `mkdir -p o && echo '<h1>custom hello</h1>' > o/index.html`,
outputDirectory: 'o',
});
await waitForPrompt(now, chunk => /Set up and deploy [^?]+\?/.test(chunk));
now.stdin.write('yes\n');
await waitForPrompt(now, chunk =>
chunk.includes('Which scope do you want to deploy to?')
);
now.stdin.write('\n');
await waitForPrompt(now, chunk =>
chunk.includes('Link to existing project?')
);
now.stdin.write('no\n');
await waitForPrompt(now, chunk =>
chunk.includes('Whats your projects name?')
);
now.stdin.write(`${projectName}\n`);
await waitForPrompt(now, chunk =>
chunk.includes('In which directory is your code located?')
);
now.stdin.write('\n');
await waitForPrompt(now, chunk =>
chunk.includes('Want to override the settings?')
);
now.stdin.write('yes\n');
await waitForPrompt(now, chunk =>
chunk.includes(
'Which settings would you like to overwrite (select multiple)?'
)
);
now.stdin.write('a\n'); // 'a' means select all
await waitForPrompt(now, chunk =>
chunk.includes(`What's your Build Command?`)
);
now.stdin.write(
`mkdir -p o && echo '<h1>custom hello</h1>' > o/index.html\n`
);
await waitForPrompt(now, chunk =>
chunk.includes(`What's your Output Directory?`)
);
now.stdin.write(`o\n`);
await waitForPrompt(now, chunk =>
chunk.includes(`What's your Development Command?`)
);
now.stdin.write(`\n`);
await waitForPrompt(now, chunk => chunk.includes('Linked to'));
const output = await now;
@@ -2833,17 +2743,19 @@ test('should show prompts to set up project during first deploy', async t => {
t.is(output.exitCode, 0, formatOutput(output));
// Ensure .gitignore is created
const gitignore = await readFile(path.join(dir, '.gitignore'), 'utf8');
t.is(gitignore, '.vercel\n.output\n');
t.is(
(await readFile(path.join(directory, '.gitignore'))).toString(),
'.vercel\n'
);
// Ensure .vercel/project.json and .vercel/README.txt are created
t.is(
await exists(path.join(dir, '.vercel', 'project.json')),
await exists(path.join(directory, '.vercel', 'project.json')),
true,
'project.json should be created'
);
t.is(
await exists(path.join(dir, '.vercel', 'README.txt')),
await exists(path.join(directory, '.vercel', 'README.txt')),
true,
'README.txt should be created'
);
@@ -2857,7 +2769,13 @@ 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, dir, ...defaultArgs]);
const dev = execa(binaryPath, [
'dev',
'--listen',
port,
directory,
...defaultArgs,
]);
dev.stderr.setEncoding('utf8');
try {
@@ -3391,10 +3309,55 @@ test('[vc link] should show prompts to set up project', async t => {
const vc = execa(binaryPath, ['link', ...defaultArgs], { cwd: dir });
await setupProject(vc, projectName, {
buildCommand: `mkdir -p o && echo '<h1>custom hello</h1>' > o/index.html`,
outputDirectory: 'o',
});
await waitForPrompt(vc, chunk => /Set up [^?]+\?/.test(chunk));
vc.stdin.write('yes\n');
await waitForPrompt(vc, chunk =>
chunk.includes('Which scope should contain your project?')
);
vc.stdin.write('\n');
await waitForPrompt(vc, chunk => chunk.includes('Link to existing project?'));
vc.stdin.write('no\n');
await waitForPrompt(vc, chunk =>
chunk.includes('Whats your projects name?')
);
vc.stdin.write(`${projectName}\n`);
await waitForPrompt(vc, chunk =>
chunk.includes('In which directory is your code located?')
);
vc.stdin.write('\n');
await waitForPrompt(vc, chunk =>
chunk.includes('Want to override the settings?')
);
vc.stdin.write('yes\n');
await waitForPrompt(vc, chunk =>
chunk.includes(
'Which settings would you like to overwrite (select multiple)?'
)
);
vc.stdin.write('a\n'); // 'a' means select all
await waitForPrompt(vc, chunk =>
chunk.includes(`What's your Build Command?`)
);
vc.stdin.write(`mkdir -p o && echo '<h1>custom hello</h1>' > o/index.html\n`);
await waitForPrompt(vc, chunk =>
chunk.includes(`What's your Output Directory?`)
);
vc.stdin.write(`o\n`);
await waitForPrompt(vc, chunk =>
chunk.includes(`What's your Development Command?`)
);
vc.stdin.write(`\n`);
await waitForPrompt(vc, chunk => chunk.includes('Linked to'));
const output = await vc;
@@ -3402,8 +3365,7 @@ test('[vc link] should show prompts to set up project', async t => {
t.is(output.exitCode, 0, formatOutput(output));
// Ensure .gitignore is created
const gitignore = await readFile(path.join(dir, '.gitignore'), 'utf8');
t.is(gitignore, '.vercel\n.output\n');
t.is((await readFile(path.join(dir, '.gitignore'))).toString(), '.vercel\n');
// Ensure .vercel/project.json and .vercel/README.txt are created
t.is(
@@ -3437,8 +3399,7 @@ test('[vc link --confirm] should not show prompts and autolink', async t => {
t.regex(stderr, /Linked to /m);
// Ensure .gitignore is created
const gitignore = await readFile(path.join(dir, '.gitignore'), 'utf8');
t.is(gitignore, '.vercel\n.output\n');
t.is((await readFile(path.join(dir, '.gitignore'))).toString(), '.vercel\n');
// Ensure .vercel/project.json and .vercel/README.txt are created
t.is(
@@ -3453,29 +3414,6 @@ test('[vc link --confirm] should not show prompts and autolink', async t => {
);
});
test('[vc link] should not duplicate paths in .gitignore', async t => {
const dir = fixture('project-link-gitignore');
// remove previously linked project if it exists
await remove(path.join(dir, '.vercel'));
const { exitCode, stderr, stdout } = await execa(
binaryPath,
['link', '--confirm', ...defaultArgs],
{ cwd: dir, reject: false }
);
// Ensure the exit code is right
t.is(exitCode, 0, formatOutput({ stderr, stdout }));
// Ensure the message is correct pattern
t.regex(stderr, /Linked to /m);
// Ensure .gitignore is created
const gitignore = await readFile(path.join(dir, '.gitignore'), 'utf8');
t.is(gitignore, '.output\n.vercel\n');
});
test('[vc dev] should show prompts to set up project', async t => {
const dir = fixture('project-link-dev');
const port = 58352;
@@ -3490,14 +3428,62 @@ test('[vc dev] should show prompts to set up project', async t => {
cwd: dir,
});
await setupProject(dev, projectName, {
buildCommand: `mkdir -p o && echo '<h1>custom hello</h1>' > o/index.html`,
outputDirectory: 'o',
});
await waitForPrompt(dev, chunk => /Set up and develop [^?]+\?/.test(chunk));
dev.stdin.write('yes\n');
await waitForPrompt(dev, chunk =>
chunk.includes('Which scope should contain your project?')
);
dev.stdin.write('\n');
await waitForPrompt(dev, chunk =>
chunk.includes('Link to existing project?')
);
dev.stdin.write('no\n');
await waitForPrompt(dev, chunk =>
chunk.includes('Whats your projects name?')
);
dev.stdin.write(`${projectName}\n`);
await waitForPrompt(dev, chunk =>
chunk.includes('In which directory is your code located?')
);
dev.stdin.write('\n');
await waitForPrompt(dev, chunk =>
chunk.includes('Want to override the settings?')
);
dev.stdin.write('yes\n');
await waitForPrompt(dev, chunk =>
chunk.includes(
'Which settings would you like to overwrite (select multiple)?'
)
);
dev.stdin.write('a\n'); // 'a' means select all
await waitForPrompt(dev, chunk =>
chunk.includes(`What's your Build Command?`)
);
dev.stdin.write(
`mkdir -p o && echo '<h1>custom hello</h1>' > o/index.html\n`
);
await waitForPrompt(dev, chunk =>
chunk.includes(`What's your Output Directory?`)
);
dev.stdin.write(`o\n`);
await waitForPrompt(dev, chunk =>
chunk.includes(`What's your Development Command?`)
);
dev.stdin.write(`\n`);
await waitForPrompt(dev, chunk => chunk.includes('Linked to'));
// Ensure .gitignore is created
const gitignore = await readFile(path.join(dir, '.gitignore'), 'utf8');
t.is(gitignore, '.vercel\n.output\n');
t.is((await readFile(path.join(dir, '.gitignore'))).toString(), '.vercel\n');
// Ensure .vercel/project.json and .vercel/README.txt are created
t.is(
@@ -3563,8 +3549,7 @@ test('[vc link] should show project prompts but not framework when `builds` defi
t.is(output.exitCode, 0, formatOutput(output));
// Ensure .gitignore is created
const gitignore = await readFile(path.join(dir, '.gitignore'), 'utf8');
t.is(gitignore, '.vercel\n.output\n');
t.is((await readFile(path.join(dir, '.gitignore'))).toString(), '.vercel\n');
// Ensure .vercel/project.json and .vercel/README.txt are created
t.is(
@@ -3593,12 +3578,59 @@ test('[vc dev] should send the platform proxy request headers to frontend dev se
cwd: dir,
});
await setupProject(dev, projectName, {
buildCommand: `mkdir -p o && echo '<h1>custom hello</h1>' > o/index.html`,
outputDirectory: 'o',
devCommand: 'node server.js',
});
await waitForPrompt(dev, chunk => /Set up and develop [^?]+\?/.test(chunk));
dev.stdin.write('yes\n');
await waitForPrompt(dev, chunk =>
chunk.includes('Which scope should contain your project?')
);
dev.stdin.write('\n');
await waitForPrompt(dev, chunk =>
chunk.includes('Link to existing project?')
);
dev.stdin.write('no\n');
await waitForPrompt(dev, chunk =>
chunk.includes('Whats your projects name?')
);
dev.stdin.write(`${projectName}\n`);
await waitForPrompt(dev, chunk =>
chunk.includes('In which directory is your code located?')
);
dev.stdin.write('\n');
await waitForPrompt(dev, chunk =>
chunk.includes('Want to override the settings?')
);
dev.stdin.write('yes\n');
await waitForPrompt(dev, chunk =>
chunk.includes(
'Which settings would you like to overwrite (select multiple)?'
)
);
dev.stdin.write('a\n'); // 'a' means select all
await waitForPrompt(dev, chunk =>
chunk.includes(`What's your Build Command?`)
);
dev.stdin.write(
`mkdir -p o && echo '<h1>custom hello</h1>' > o/index.html\n`
);
await waitForPrompt(dev, chunk =>
chunk.includes(`What's your Output Directory?`)
);
dev.stdin.write(`o\n`);
await waitForPrompt(dev, chunk =>
chunk.includes(`What's your Development Command?`)
);
dev.stdin.write(`node server.js\n`);
await waitForPrompt(dev, chunk => chunk.includes('Linked to'));
await waitForPrompt(dev, chunk => chunk.includes('Ready! Available at'));
// Ensure that `vc dev` also works

View File

@@ -335,54 +335,4 @@ describe('DevServer', () => {
expect(body).toEqual('The page could not be found.\n\nNOT_FOUND\n');
})
);
it(
'should support edge middleware',
testFixture('edge-middleware', async server => {
const response = await fetch(`${server.address}/index.html`);
const body = await response.json();
expect(body).toEqual(
JSON.parse(
fs.readFileSync(
path.join(
__dirname,
'../../fixtures/unit/edge-middleware/response.json'
),
'utf8'
)
)
);
})
);
it(
'should work with middleware written in typescript',
testFixture('edge-middleware-ts', async server => {
const response = await fetch(`${server.address}/index.html`);
const body = await response.text();
expect(body).toStrictEqual('response');
})
);
it(
'should render an error page when the middleware throws',
testFixture('edge-middleware-error', async server => {
const response = await fetch(`${server.address}/index.html`);
const body = await response.text();
expect(body).toStrictEqual(
'A server error has occurred\n\nEDGE_FUNCTION_INVOCATION_FAILED\n'
);
})
);
it(
'should render an error page when the middleware returns not a Response',
testFixture('edge-middleware-invalid-response', async server => {
const response = await fetch(`${server.address}/index.html`);
const body = await response.text();
expect(body).toStrictEqual(
'A server error has occurred\n\nEDGE_FUNCTION_INVOCATION_FAILED\n'
);
})
);
});

View File

@@ -5,7 +5,7 @@ describe('getUpdateCommand', () => {
it('should detect update command', async () => {
const updateCommand = await getUpdateCommand();
expect(updateCommand).toEqual(
`npm i vercel@${isCanary() ? 'canary' : 'latest'}`
`yarn add vercel@${isCanary() ? 'canary' : 'latest'}`
);
});
});

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/client",
"version": "10.2.3-canary.21",
"version": "10.2.3-canary.13",
"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.20",
"@vercel/build-utils": "2.12.3-canary.13",
"@zeit/fetch": "5.2.0",
"async-retry": "1.2.3",
"async-sema": "3.0.0",

View File

@@ -88,50 +88,6 @@ 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 };

View File

@@ -77,8 +77,7 @@ export default function buildCreateDeployment() {
let { fileList } = await buildFileTree(
path,
clientOptions.isDirectory,
debug,
clientOptions.prebuilt
debug
);
let configPath: string | undefined;

View File

@@ -14,7 +14,6 @@ export interface VercelClientOptions {
teamId?: string;
apiUrl?: string;
force?: boolean;
prebuilt?: boolean;
withCache?: boolean;
userAgent?: string;
defaultName?: string;

View File

@@ -31,14 +31,6 @@ 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];
@@ -82,12 +74,11 @@ const maybeRead = async function <T>(path: string, default_: T) {
export async function buildFileTree(
path: string | string[],
isDirectory: boolean,
debug: Debug,
prebuilt?: boolean
debug: Debug
): Promise<{ fileList: string[]; ignoreList: string[] }> {
const ignoreList: string[] = [];
let fileList: string[];
let { ig, ignores } = await getVercelIgnore(path, prebuilt);
let { ig, ignores } = await getVercelIgnore(path);
debug(`Found ${ignores.length} rules in .vercelignore`);
debug('Building file tree...');
@@ -118,38 +109,36 @@ export async function buildFileTree(
}
export async function getVercelIgnore(
cwd: string | string[],
prebuilt?: boolean
cwd: string | string[]
): Promise<{ ig: Ignore; ignores: string[] }> {
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 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 cwds = Array.isArray(cwd) ? cwd : [cwd];
const files = await Promise.all(

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/frameworks",
"version": "0.5.1-canary.12",
"version": "0.5.1-canary.9",
"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.4-canary.6",
"@vercel/routing-utils": "1.11.4-canary.5",
"ajv": "6.12.2",
"typescript": "4.3.4"
}

View File

@@ -43,7 +43,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `blitz build`',
value: 'blitz build',
},
devCommand: {
value: 'blitz start',
@@ -52,7 +51,8 @@ export const frameworks = [
placeholder: 'Next.js default',
},
},
getFsOutputDir: async () => '.next',
devCommand: 'blitz start',
buildCommand: 'blitz build',
getOutputDirName: async () => 'public',
},
{
@@ -82,7 +82,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `next build`',
value: 'next build',
},
devCommand: {
value: 'next dev --port $PORT',
@@ -98,7 +97,8 @@ export const frameworks = [
dependencies: ['next-plugin-sentry', 'next-sentry-source-maps'],
},
],
getFsOutputDir: async () => '.next',
devCommand: 'next dev --port $PORT',
buildCommand: 'next build',
getOutputDirName: async () => 'public',
cachePattern: '.next/cache/**',
},
@@ -129,7 +129,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `gatsby build`',
value: 'gatsby build',
},
devCommand: {
value: 'gatsby develop --port $PORT',
@@ -140,8 +139,9 @@ export const frameworks = [
},
},
dependency: 'gatsby',
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 {
@@ -216,7 +216,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `hexo generate`',
value: 'hexo generate',
},
devCommand: {
value: 'hexo server --port $PORT',
@@ -227,7 +226,8 @@ export const frameworks = [
},
},
dependency: 'hexo',
getFsOutputDir: async () => 'public',
devCommand: 'hexo server --port $PORT',
buildCommand: 'hexo generate',
getOutputDirName: async () => 'public',
},
{
@@ -255,7 +255,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `npx @11ty/eleventy`',
value: 'npx @11ty/eleventy',
},
devCommand: {
value: 'npx @11ty/eleventy --serve --watch --port $PORT',
@@ -266,7 +265,8 @@ export const frameworks = [
},
},
dependency: '@11ty/eleventy',
getFsOutputDir: async () => '_site',
devCommand: 'npx @11ty/eleventy --serve --watch --port $PORT',
buildCommand: 'npx @11ty/eleventy',
getOutputDirName: async () => '_site',
cachePattern: '.cache/**',
},
@@ -295,7 +295,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `docusaurus build`',
value: 'docusaurus build',
},
devCommand: {
value: 'docusaurus start --port $PORT',
@@ -306,22 +305,8 @@ export const frameworks = [
},
},
dependency: '@docusaurus/core',
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;
},
devCommand: 'docusaurus start --port $PORT',
buildCommand: 'docusaurus build',
getOutputDirName: async (dirPrefix: string) => {
const base = 'build';
try {
@@ -338,57 +323,6 @@ 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)$',
@@ -450,7 +384,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `docusaurus-build`',
value: 'docusaurus-build',
},
devCommand: {
value: 'docusaurus-start --port $PORT',
@@ -461,21 +394,8 @@ export const frameworks = [
},
},
dependency: 'docusaurus',
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;
},
devCommand: 'docusaurus-start --port $PORT',
buildCommand: 'docusaurus-build',
getOutputDirName: async (dirPrefix: string) => {
const base = 'build';
try {
@@ -516,7 +436,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `preact build`',
value: 'preact build',
},
devCommand: {
value: 'preact watch --port $PORT',
@@ -527,7 +446,8 @@ export const frameworks = [
},
},
dependency: 'preact-cli',
getFsOutputDir: async () => 'build',
devCommand: 'preact watch --port $PORT',
buildCommand: 'preact build',
getOutputDirName: async () => 'build',
defaultRoutes: [
{
@@ -538,13 +458,6 @@ export const frameworks = [
dest: '/index.html',
},
],
defaultRewrites: [
{
source: '/(.*)',
regex: '/(.*)',
destination: '/index.html',
},
],
},
{
name: 'Dojo',
@@ -573,7 +486,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `dojo build`',
value: 'dojo build',
},
devCommand: {
value: 'dojo build -m dev -w -s -p $PORT',
@@ -584,7 +496,8 @@ export const frameworks = [
},
},
dependency: '@dojo/cli',
getFsOutputDir: async () => 'output/dist',
devCommand: 'dojo build -m dev -w -s -p $PORT',
buildCommand: 'dojo build',
getOutputDirName: async () => join('output', 'dist'),
defaultRoutes: [
{
@@ -600,21 +513,6 @@ 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',
@@ -640,7 +538,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `ember build`',
value: 'ember build',
},
devCommand: {
value: 'ember serve --port $PORT',
@@ -651,7 +548,8 @@ export const frameworks = [
},
},
dependency: 'ember-cli',
getFsOutputDir: async () => 'dist',
devCommand: 'ember serve --port $PORT',
buildCommand: 'ember build',
getOutputDirName: async () => 'dist',
defaultRoutes: [
{
@@ -662,13 +560,6 @@ export const frameworks = [
dest: '/index.html',
},
],
defaultRewrites: [
{
source: '/(.*)',
regex: '/(.*)',
destination: '/index.html',
},
],
},
{
name: 'Vue.js',
@@ -695,7 +586,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `vue-cli-service build`',
value: 'vue-cli-service build',
},
devCommand: {
value: 'vue-cli-service serve --port $PORT',
@@ -706,7 +596,8 @@ export const frameworks = [
},
},
dependency: '@vue/cli-service',
getFsOutputDir: async () => 'dist',
devCommand: 'vue-cli-service serve --port $PORT',
buildCommand: 'vue-cli-service build',
getOutputDirName: async () => 'dist',
defaultRoutes: [
{
@@ -727,27 +618,6 @@ 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',
@@ -772,7 +642,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `ng build && scully`',
value: 'ng build && scully',
},
devCommand: {
value: 'ng serve --port $PORT',
@@ -783,7 +652,8 @@ export const frameworks = [
},
},
dependency: '@scullyio/init',
getFsOutputDir: async () => 'dist',
devCommand: 'ng serve --port $PORT',
buildCommand: 'ng build && scully',
getOutputDirName: async () => 'dist/static',
},
{
@@ -810,7 +680,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `ng build`',
value: 'ng build',
},
devCommand: {
value: 'ng serve --port $PORT',
@@ -820,7 +689,8 @@ export const frameworks = [
},
},
dependency: '@ionic/angular',
getFsOutputDir: async () => 'www',
devCommand: 'ng serve --port $PORT',
buildCommand: 'ng build',
getOutputDirName: async () => 'www',
defaultRoutes: [
{
@@ -831,13 +701,6 @@ export const frameworks = [
dest: '/index.html',
},
],
defaultRewrites: [
{
source: '/(.*)',
regex: '/(.*)',
destination: '/index.html',
},
],
},
{
name: 'Angular',
@@ -863,7 +726,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `ng build`',
value: 'ng build',
},
devCommand: {
value: 'ng serve --port $PORT',
@@ -874,7 +736,8 @@ export const frameworks = [
},
},
dependency: '@angular/cli',
getFsOutputDir: async () => 'dist',
devCommand: 'ng serve --port $PORT',
buildCommand: 'ng build',
getOutputDirName: async (dirPrefix: string) => {
const base = 'dist';
try {
@@ -899,13 +762,6 @@ export const frameworks = [
dest: '/index.html',
},
],
defaultRewrites: [
{
source: '/(.*)',
regex: '/(.*)',
destination: '/index.html',
},
],
},
{
name: 'Polymer',
@@ -931,7 +787,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `polymer build`',
value: 'polymer build',
},
devCommand: {
value: 'polymer serve --port $PORT',
@@ -942,7 +797,8 @@ export const frameworks = [
},
},
dependency: 'polymer-cli',
getFsOutputDir: async () => 'build',
devCommand: 'polymer serve --port $PORT',
buildCommand: 'polymer build',
getOutputDirName: async (dirPrefix: string) => {
const base = 'build';
try {
@@ -964,13 +820,6 @@ export const frameworks = [
dest: '/index.html',
},
],
defaultRewrites: [
{
source: '/(.*)',
regex: '/(.*)',
destination: '/index.html',
},
],
},
{
name: 'Svelte',
@@ -1001,7 +850,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `rollup -c`',
value: 'rollup -c',
},
devCommand: {
value: 'rollup -c -w',
@@ -1011,7 +859,8 @@ export const frameworks = [
},
},
dependency: 'sirv-cli',
getFsOutputDir: async () => 'public',
devCommand: 'rollup -c -w',
buildCommand: 'rollup -c',
getOutputDirName: async () => 'public',
defaultRoutes: [
{
@@ -1022,13 +871,6 @@ export const frameworks = [
dest: '/index.html',
},
],
defaultRewrites: [
{
source: '/(.*)',
regex: '/(.*)',
destination: '/index.html',
},
],
},
{
name: 'SvelteKit',
@@ -1054,7 +896,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `svelte-kit build`',
value: 'svelte-kit build',
},
devCommand: {
value: 'svelte-kit dev --port $PORT',
@@ -1064,7 +905,8 @@ export const frameworks = [
placeholder: 'public',
},
},
getFsOutputDir: async () => '.output',
devCommand: 'svelte-kit dev --port $PORT',
buildCommand: 'svelte-kit build',
getOutputDirName: async () => 'public',
},
{
@@ -1091,7 +933,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `react-scripts build`',
value: 'react-scripts build',
},
devCommand: {
value: 'react-scripts start',
@@ -1101,7 +942,8 @@ export const frameworks = [
},
},
dependency: '@ionic/react',
getFsOutputDir: async () => 'build',
devCommand: 'react-scripts start',
buildCommand: 'react-scripts build',
getOutputDirName: async () => 'build',
defaultRoutes: [
{
@@ -1128,45 +970,6 @@ 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',
@@ -1198,7 +1001,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `react-scripts build`',
value: 'react-scripts build',
},
devCommand: {
value: 'react-scripts start',
@@ -1208,7 +1010,8 @@ export const frameworks = [
},
},
dependency: 'react-scripts',
getFsOutputDir: async () => 'build',
devCommand: 'react-scripts start',
buildCommand: 'react-scripts build',
getOutputDirName: async () => 'build',
defaultRoutes: [
{
@@ -1235,45 +1038,6 @@ 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',
@@ -1299,7 +1063,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `gridsome build`',
value: 'gridsome build',
},
devCommand: {
value: 'gridsome develop -p $PORT',
@@ -1310,7 +1073,8 @@ export const frameworks = [
},
},
dependency: 'gridsome',
getFsOutputDir: async () => 'dist',
devCommand: 'gridsome develop -p $PORT',
buildCommand: 'gridsome build',
getOutputDirName: async () => 'dist',
},
{
@@ -1337,7 +1101,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `umi build`',
value: 'umi build',
},
devCommand: {
value: 'umi dev --port $PORT',
@@ -1348,7 +1111,8 @@ export const frameworks = [
},
},
dependency: 'umi',
getFsOutputDir: async () => 'dist',
devCommand: 'umi dev --port $PORT',
buildCommand: 'umi build',
getOutputDirName: async () => 'dist',
defaultRoutes: [
{
@@ -1359,13 +1123,6 @@ export const frameworks = [
dest: '/index.html',
},
],
defaultRewrites: [
{
source: '/(.*)',
destination: '/index.html',
regex: '/(.*)',
},
],
},
{
name: 'Sapper',
@@ -1391,7 +1148,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `sapper export`',
value: 'sapper export',
},
devCommand: {
value: 'sapper dev --port $PORT',
@@ -1402,7 +1158,8 @@ export const frameworks = [
},
},
dependency: 'sapper',
getFsOutputDir: async () => '__sapper__/export',
devCommand: 'sapper dev --port $PORT',
buildCommand: 'sapper export',
getOutputDirName: async () => '__sapper__/export',
},
{
@@ -1429,7 +1186,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `saber build`',
value: 'saber build',
},
devCommand: {
value: 'saber --port $PORT',
@@ -1440,7 +1196,8 @@ export const frameworks = [
},
},
dependency: 'saber',
getFsOutputDir: async () => 'public',
devCommand: 'saber --port $PORT',
buildCommand: 'saber build',
getOutputDirName: async () => 'public',
defaultRoutes: [
{
@@ -1456,23 +1213,6 @@ 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',
@@ -1498,7 +1238,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `stencil build`',
value: 'stencil build',
},
devCommand: {
value: 'stencil build --dev --watch --serve --port $PORT',
@@ -1509,7 +1248,8 @@ export const frameworks = [
},
},
dependency: '@stencil/core',
getFsOutputDir: async () => 'www',
devCommand: 'stencil build --dev --watch --serve --port $PORT',
buildCommand: 'stencil build',
getOutputDirName: async () => 'www',
defaultRoutes: [
{
@@ -1535,32 +1275,6 @@ 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',
@@ -1587,7 +1301,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `nuxt generate`',
value: 'nuxt generate',
},
devCommand: {
value: 'nuxt',
@@ -1597,7 +1310,8 @@ export const frameworks = [
},
},
dependency: 'nuxt',
getFsOutputDir: async () => '.output',
devCommand: 'nuxt',
buildCommand: 'nuxt generate',
getOutputDirName: async () => 'dist',
cachePattern: '.nuxt/**',
defaultRoutes: [
@@ -1655,7 +1369,8 @@ export const frameworks = [
placeholder: 'RedwoodJS default',
},
},
getFsOutputDir: async () => 'public',
devCommand: 'yarn rw dev --fwd="--port=$PORT --open=false',
buildCommand: 'yarn rw deploy vercel',
getOutputDirName: async () => 'public',
},
{
@@ -1690,7 +1405,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `hugo -D --gc`',
value: 'hugo -D --gc',
},
devCommand: {
value: 'hugo server -D -w -p $PORT',
@@ -1700,16 +1414,8 @@ export const frameworks = [
placeholder: '`public` or `publishDir` from the `config` file',
},
},
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';
},
devCommand: 'hugo server -D -w -p $PORT',
buildCommand: 'hugo -D --gc',
getOutputDirName: async (dirPrefix: string): Promise<string> => {
type HugoConfig = { publishDir?: string };
const config = await readConfigFile<HugoConfig>(
@@ -1744,7 +1450,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `jekyll build`',
value: 'jekyll build',
},
devCommand: {
value: 'bundle exec jekyll serve --watch --port $PORT',
@@ -1754,13 +1459,8 @@ export const frameworks = [
placeholder: '`_site` or `destination` from `_config.yml`',
},
},
getFsOutputDir: async (dirPrefix: string): Promise<string> => {
type JekyllConfig = { destination?: string };
const config = await readConfigFile<JekyllConfig>(
join(dirPrefix, '_config.yml')
);
return (config && config.destination) || '_site';
},
devCommand: 'bundle exec jekyll serve --watch --port $PORT',
buildCommand: 'jekyll build',
getOutputDirName: async (dirPrefix: string): Promise<string> => {
type JekyllConfig = { destination?: string };
const config = await readConfigFile<JekyllConfig>(
@@ -1792,7 +1492,6 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `brunch build --production`',
value: 'brunch build --production',
},
devCommand: {
value: 'brunch watch --server --port $PORT',
@@ -1802,7 +1501,8 @@ export const frameworks = [
value: 'public',
},
},
getFsOutputDir: async () => 'public',
devCommand: 'brunch watch --server --port $PORT',
buildCommand: 'brunch build --production',
getOutputDirName: async () => 'public',
},
{
@@ -1826,18 +1526,18 @@ export const frameworks = [
value: 'bundle install',
},
buildCommand: {
placeholder: '`npm run build` or `bundle exec middleman build`',
value: 'bundle exec middleman build',
value: '`npm run build` or `bundle exec middleman build`',
},
devCommand: {
placeholder: 'bundle exec middleman server',
value: 'bundle exec middleman server -p $PORT',
placeholder: 'bundle exec middleman server',
},
outputDirectory: {
value: 'build',
},
},
getFsOutputDir: async () => 'build',
devCommand: 'bundle exec middleman server -p $PORT',
buildCommand: 'bundle exec middleman build',
getOutputDirName: async () => 'build',
cachePattern: '{vendor/bin,vendor/cache,vendor/bundle}/**',
},
@@ -1865,14 +1565,15 @@ export const frameworks = [
value: 'zola build',
},
devCommand: {
placeholder: 'zola serve',
value: 'zola serve --port $PORT',
placeholder: 'zola serve',
},
outputDirectory: {
value: 'public',
},
},
getFsOutputDir: async () => 'public',
devCommand: 'zola serve --port $PORT',
buildCommand: 'zola build',
getOutputDirName: async () => 'public',
defaultVersion: '0.13.0',
},
@@ -1901,18 +1602,17 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `vite build`',
value: 'vite build',
},
devCommand: {
placeholder: 'vite',
value: 'vite',
},
outputDirectory: {
value: 'dist',
},
},
dependency: 'vite',
getFsOutputDir: async () => 'dist',
devCommand: 'vite',
buildCommand: 'vite build',
getOutputDirName: async () => 'dist',
},
{
@@ -1939,18 +1639,17 @@ export const frameworks = [
},
buildCommand: {
placeholder: '`npm run build` or `parcel build`',
value: 'parcel build',
},
devCommand: {
placeholder: 'parcel',
value: 'parcel',
},
outputDirectory: {
value: 'dist',
placeholder: 'dist',
},
},
dependency: 'parcel',
getFsOutputDir: async () => 'dist',
devCommand: 'parcel',
buildCommand: 'parcel build',
getOutputDirName: async () => 'dist',
defaultRoutes: [
{
@@ -1962,53 +1661,28 @@ export const frameworks = [
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 an unoptimized framework.',
description: 'No framework or a unoptimized framework.',
settings: {
installCommand: {
placeholder: '`yarn install` or `npm install`',
},
buildCommand: {
placeholder: '`npm run vercel-build` or `npm run build`',
value: null,
},
devCommand: {
placeholder: 'None',
value: null,
},
outputDirectory: {
placeholder: '`public` if it exists, or `.`',
},
},
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;
},
devCommand: null,
buildCommand: null,
getOutputDirName: async () => 'public',
},
] as const;

View File

@@ -1,4 +1,4 @@
import { Header, Rewrite, Route } from '@vercel/routing-utils';
import { Route } from '@vercel/routing-utils';
export interface FrameworkDetectionItem {
/**
@@ -26,21 +26,12 @@ export interface SettingValue {
* A predefined setting for the detected framework
* @example "next dev --port $PORT"
*/
value: string | null;
value: string;
placeholder?: string;
}
export type Setting = SettingValue | SettingPlaceholder;
export type Redirect = Rewrite & {
statusCode?: number;
permanent?: boolean;
};
type RoutesManifestRegex = {
regex: string;
};
/**
* Framework detection information.
*/
@@ -129,11 +120,11 @@ export interface Framework {
/**
* Default Build Command or a placeholder
*/
buildCommand: SettingValue;
buildCommand: Setting;
/**
* Default Development Command or a placeholder
*/
devCommand: SettingValue;
devCommand: Setting;
/**
* Default Output Directory
*/
@@ -157,18 +148,12 @@ export interface Framework {
/**
* Name of a dependency in `package.json` to detect this framework.
* @example "hexo"
* @deprecated use `detectors` instead (new frameworks should not use this prop)
*/
dependency?: string;
/**
* 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
@@ -176,32 +161,21 @@ 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/**"
*/
cachePattern?: string;
/**
* The default build command for the framework.
* @example "next build"
*/
buildCommand: string | null;
/**
* The default development command for the framework.
* @example "next dev"
*/
devCommand: string | null;
/**
* The default version of the framework command that is available within the
* build image. Usually an environment variable can be set to override this.

View File

@@ -34,7 +34,7 @@ const SchemaSettings = {
additionalProperties: false,
properties: {
value: {
type: ['string', 'null'],
type: 'string',
},
placeholder: {
type: 'string',
@@ -58,7 +58,15 @@ const Schema = {
type: 'array',
items: {
type: 'object',
required: ['name', 'slug', 'logo', 'description', 'settings'],
required: [
'name',
'slug',
'logo',
'description',
'settings',
'buildCommand',
'devCommand',
],
properties: {
name: { type: 'string' },
slug: { type: ['string', 'null'] },
@@ -130,6 +138,8 @@ const Schema = {
dependency: { type: 'string' },
cachePattern: { type: 'string' },
buildCommand: { type: ['string', 'null'] },
devCommand: { type: ['string', 'null'] },
defaultVersion: { type: 'string' },
},
},

View File

@@ -6,8 +6,7 @@ import { join } from 'path';
import stringArgv from 'string-argv';
import { debug } from '@vercel/build-utils';
const versionMap = new Map([
['1.17', '1.17.3'],
['1.16', '1.16.10'],
['1.16', '1.16'],
['1.15', '1.15.8'],
['1.14', '1.14.15'],
['1.13', '1.13.15'],

View File

@@ -1,10 +1,17 @@
import execa from 'execa';
//import execa from 'execa';
import retry from 'async-retry';
import { homedir, tmpdir } from 'os';
import { tmpdir } from 'os';
import { spawn } from 'child_process';
import { Readable } from 'stream';
import once from '@tootallnate/once';
import { join, dirname, basename, normalize, sep } from 'path';
import {
join,
dirname,
basename,
normalize,
sep,
parse as pathParse,
} from 'path';
import {
readFile,
writeFile,
@@ -14,28 +21,23 @@ import {
remove,
} from 'fs-extra';
import {
BuildOptions,
Meta,
Files,
PrepareCacheOptions,
StartDevServerOptions,
StartDevServerResult,
glob,
download,
createLambda,
getWriteableDirectory,
shouldServe,
debug,
} from '@vercel/build-utils';
const TMP = tmpdir();
import {
createGo,
getAnalyzedEntrypoint,
cacheDir,
OUT_EXTENSION,
} from './go-helpers';
const TMP = tmpdir();
const handlerFileName = `handler${OUT_EXTENSION}`;
export { shouldServe };
@@ -44,7 +46,6 @@ interface Analyzed {
found?: boolean;
packageName: string;
functionName: string;
watch: string[];
}
interface PortInfo {
@@ -52,58 +53,37 @@ interface PortInfo {
}
// Initialize private git repo for Go Modules
async function initPrivateGit(credentials: string) {
const gitCredentialsPath = join(homedir(), '.git-credentials');
await execa('git', [
'config',
'--global',
'credential.helper',
`store --file ${gitCredentialsPath}`,
]);
await writeFile(gitCredentialsPath, credentials);
}
//async function initPrivateGit(credentials: string) {
// const gitCredentialsPath = join(homedir(), '.git-credentials');
//
// await execa('git', [
// 'config',
// '--global',
// 'credential.helper',
// `store --file ${gitCredentialsPath}`,
// ]);
//
// await writeFile(gitCredentialsPath, credentials);
//}
/**
* Since `go build` does not support files that begin with a square bracket,
* we must rename to something temporary to support Path Segments.
* The output file is not renamed because v3 builders can't rename outputs
* which works great for this feature. We also need to add a suffix during `vercel dev`
* since the entrypoint is already stripped of its suffix before build() is called.
*/
async function getRenamedEntrypoint(
entrypoint: string,
files: Files,
meta: Meta
) {
const filename = basename(entrypoint);
if (filename.startsWith('[')) {
const suffix = meta.isDev && !entrypoint.endsWith('.go') ? '.go' : '';
const newEntrypoint = entrypoint.replace('/[', '/now-bracket[') + suffix;
const file = files[entrypoint];
delete files[entrypoint];
files[newEntrypoint] = file;
debug(`Renamed entrypoint from ${entrypoint} to ${newEntrypoint}`);
entrypoint = newEntrypoint;
function getRenamedEntrypoint(entrypoint: string) {
if (basename(entrypoint).startsWith('[')) {
return entrypoint.replace('/[', '/vercel-bracket[');
}
return entrypoint;
return null;
}
export const version = 3;
export async function build({
files,
entrypoint,
config,
workPath,
meta = {},
}: BuildOptions) {
if (process.env.GIT_CREDENTIALS && !meta.isDev) {
debug('Initialize Git credentials...');
await initPrivateGit(process.env.GIT_CREDENTIALS);
}
export async function build() {
// TODO NATE: probably only want to do this
// when inside the Vercel build container
//if (process.env.GIT_CREDENTIALS) {
// debug('Initialize Git credentials...');
// await initPrivateGit(process.env.GIT_CREDENTIALS);
//}
if (process.env.GO111MODULE) {
console.log(`\nManually assigning 'GO111MODULE' is not recommended.
@@ -116,19 +96,38 @@ We highly recommend you leverage Go Modules in your project.
Learn more: https://github.com/golang/go/wiki/Modules
`);
}
entrypoint = await getRenamedEntrypoint(entrypoint, files, meta);
const entrypoints = await glob('api/**/*.go', process.cwd());
for (const entrypoint of Object.keys(entrypoints)) {
await buildEntrypoint(entrypoint);
}
}
async function buildEntrypoint(entrypoint: string) {
const cwd = process.cwd();
const workPath = cwd;
const outputPath = join(cwd, '.output');
const { dir, name } = pathParse(entrypoint);
const entrypointWithoutExt = join(
dir,
name,
// "index" is enforced as a suffix so that nesting works properly
// i.e. "api/foo.go" -> "api/foo/index"
// "api/foo/bar.go" -> "api/foo/bar/index"
name === 'index' ? '' : 'index'
);
const outDir = join(outputPath, 'server/pages', entrypointWithoutExt);
console.log(`Compiling ${entrypoint} to ${outDir}`);
await mkdirp(outDir);
const renamedEntrypoint = getRenamedEntrypoint(entrypoint);
const entrypointArr = entrypoint.split(sep);
// eslint-disable-next-line prefer-const
let [goPath, outDir] = await Promise.all([
getWriteableDirectory(),
getWriteableDirectory(),
]);
const goPath = await getWriteableDirectory();
const forceMove = Boolean(meta.isDev);
const srcPath = join(goPath, 'src', 'lambda');
let downloadPath = meta.isDev || meta.skipDownload ? workPath : srcPath;
let downloadedFiles = await download(files, downloadPath, meta);
const forceMove = false;
const downloadPath = join(goPath, 'src', 'lambda');
//const downloadedFiles = await download(files, downloadPath, meta);
debug(`Parsing AST for "${entrypoint}"`);
let analyzed: string;
@@ -155,8 +154,7 @@ Learn more: https://github.com/golang/go/wiki/Modules
if (!analyzed) {
const err = new Error(
`Could not find an exported function in "${entrypoint}"
Learn more: https://vercel.com/docs/runtimes#official-runtimes/go
`
Learn more: https://vercel.com/docs/runtimes#official-runtimes/go`
);
console.log(err.message);
throw err;
@@ -164,81 +162,80 @@ Learn more: https://vercel.com/docs/runtimes#official-runtimes/go
const parsedAnalyzed = JSON.parse(analyzed) as Analyzed;
if (meta.isDev) {
// Create cache so Go rebuilds fast with `vercel dev`
// Old versions of the CLI don't assign this property
const { devCacheDir = join(workPath, '.now', 'cache') } = meta;
goPath = join(devCacheDir, 'go', basename(entrypoint, '.go'));
const destLambda = join(goPath, 'src', 'lambda');
await download(downloadedFiles, destLambda);
downloadedFiles = await glob('**', destLambda);
downloadPath = destLambda;
}
//if (meta.isDev) {
// // Create cache so Go rebuilds fast with `vercel dev`
// // Old versions of the CLI don't assign this property
// const { devCacheDir = join(workPath, '.now', 'cache') } = meta;
// goPath = join(devCacheDir, 'go', basename(entrypoint, '.go'));
// const destLambda = join(goPath, 'src', 'lambda');
// await download(downloadedFiles, destLambda);
// downloadedFiles = await glob('**', destLambda);
// downloadPath = destLambda;
//}
const isGoModExist = false;
// find `go.mod` in downloadedFiles
const entrypointDirname = dirname(downloadedFiles[entrypoint].fsPath);
let isGoModExist = false;
let goModPath = '';
let isGoModInRootDir = false;
for (const file of Object.keys(downloadedFiles)) {
const { fsPath } = downloadedFiles[file];
const fileDirname = dirname(fsPath);
if (file === 'go.mod') {
isGoModExist = true;
isGoModInRootDir = true;
goModPath = fileDirname;
} else if (file.endsWith('go.mod')) {
if (entrypointDirname === fileDirname) {
isGoModExist = true;
goModPath = fileDirname;
debug(`Found file dirname equals entrypoint dirname: ${fileDirname}`);
break;
}
//const entrypointDirname = dirname(downloadedFiles[entrypoint].fsPath);
//let isGoModExist = false;
//let goModPath = '';
//let isGoModInRootDir = false;
//for (const file of Object.keys(downloadedFiles)) {
// const { fsPath } = downloadedFiles[file];
// const fileDirname = dirname(fsPath);
// if (file === 'go.mod') {
// isGoModExist = true;
// isGoModInRootDir = true;
// goModPath = fileDirname;
// } else if (file.endsWith('go.mod')) {
// if (entrypointDirname === fileDirname) {
// isGoModExist = true;
// goModPath = fileDirname;
// debug(`Found file dirname equals entrypoint dirname: ${fileDirname}`);
// break;
// }
if (!isGoModInRootDir && config.zeroConfig && file === 'api/go.mod') {
// We didn't find `/go.mod` but we found `/api/go.mod` so move it to the root
isGoModExist = true;
isGoModInRootDir = true;
goModPath = join(fileDirname, '..');
const pathParts = fsPath.split(sep);
pathParts.pop(); // Remove go.mod
pathParts.pop(); // Remove api
pathParts.push('go.mod');
const newFsPath = pathParts.join(sep);
debug(`Moving api/go.mod to root: ${fsPath} to ${newFsPath}`);
await move(fsPath, newFsPath, { overwrite: forceMove });
const oldSumPath = join(dirname(fsPath), 'go.sum');
const newSumPath = join(dirname(newFsPath), 'go.sum');
if (await pathExists(oldSumPath)) {
debug(`Moving api/go.sum to root: ${oldSumPath} to ${newSumPath}`);
await move(oldSumPath, newSumPath, { overwrite: forceMove });
}
break;
}
}
}
// //if (!isGoModInRootDir && config.zeroConfig && file === 'api/go.mod') {
// // // We didn't find `/go.mod` but we found `/api/go.mod` so move it to the root
// // isGoModExist = true;
// // isGoModInRootDir = true;
// // goModPath = join(fileDirname, '..');
// // const pathParts = fsPath.split(sep);
// // pathParts.pop(); // Remove go.mod
// // pathParts.pop(); // Remove api
// // pathParts.push('go.mod');
// // const newFsPath = pathParts.join(sep);
// // debug(`Moving api/go.mod to root: ${fsPath} to ${newFsPath}`);
// // await move(fsPath, newFsPath, { overwrite: forceMove });
// // const oldSumPath = join(dirname(fsPath), 'go.sum');
// // const newSumPath = join(dirname(newFsPath), 'go.sum');
// // if (await pathExists(oldSumPath)) {
// // debug(`Moving api/go.sum to root: ${oldSumPath} to ${newSumPath}`);
// // await move(oldSumPath, newSumPath, { overwrite: forceMove });
// // }
// // break;
// //}
// }
//}
const input = entrypointDirname;
const includedFiles: Files = {};
if (config && config.includeFiles) {
const patterns = Array.isArray(config.includeFiles)
? config.includeFiles
: [config.includeFiles];
for (const pattern of patterns) {
const fsFiles = await glob(pattern, input);
for (const [assetName, asset] of Object.entries(fsFiles)) {
includedFiles[assetName] = asset;
}
}
}
//const includedFiles: Files = {};
//if (config && config.includeFiles) {
// const patterns = Array.isArray(config.includeFiles)
// ? config.includeFiles
// : [config.includeFiles];
// for (const pattern of patterns) {
// const fsFiles = await glob(pattern, input);
// for (const [assetName, asset] of Object.entries(fsFiles)) {
// includedFiles[assetName] = asset;
// }
// }
//}
const handlerFunctionName = parsedAnalyzed.functionName;
debug(`Found exported function "${handlerFunctionName}" in "${entrypoint}"`);
if (!isGoModExist && 'vendor' in downloadedFiles) {
throw new Error('`go.mod` is required to use a `vendor` directory.');
}
//if (!isGoModExist && 'vendor' in downloadedFiles) {
// throw new Error('`go.mod` is required to use a `vendor` directory.');
//}
// check if package name other than main
// using `go.mod` way building the handler
@@ -345,21 +342,21 @@ Learn more: https://vercel.com/docs/runtimes#official-runtimes/go
baseGoModPath = entrypointDirname;
}
if (meta.isDev) {
const isGoModBk = await pathExists(join(baseGoModPath, 'go.mod.bk'));
if (isGoModBk) {
await move(
join(baseGoModPath, 'go.mod.bk'),
join(baseGoModPath, 'go.mod'),
{ overwrite: forceMove }
);
await move(
join(baseGoModPath, 'go.sum.bk'),
join(baseGoModPath, 'go.sum'),
{ overwrite: forceMove }
);
}
}
//if (meta.isDev) {
// const isGoModBk = await pathExists(join(baseGoModPath, 'go.mod.bk'));
// if (isGoModBk) {
// await move(
// join(baseGoModPath, 'go.mod.bk'),
// join(baseGoModPath, 'go.mod'),
// { overwrite: forceMove }
// );
// await move(
// join(baseGoModPath, 'go.sum.bk'),
// join(baseGoModPath, 'go.sum'),
// { overwrite: forceMove }
// );
// }
//}
debug('Tidy `go.mod` file...');
try {
@@ -375,25 +372,25 @@ Learn more: https://vercel.com/docs/runtimes#official-runtimes/go
try {
const src = [join(baseGoModPath, mainModGoFileName)];
await go.build(src, destPath);
} catch (err) {
console.log('failed to `go build`');
throw err;
}
if (meta.isDev) {
// caching for `vercel dev`
await move(
join(baseGoModPath, 'go.mod'),
join(baseGoModPath, 'go.mod.bk'),
{ overwrite: forceMove }
);
await move(
join(baseGoModPath, 'go.sum'),
join(baseGoModPath, 'go.sum.bk'),
{ overwrite: forceMove }
);
}
//if (meta.isDev) {
// // caching for `vercel dev`
// await move(
// join(baseGoModPath, 'go.mod'),
// join(baseGoModPath, 'go.mod.bk'),
// { overwrite: forceMove }
// );
// await move(
// join(baseGoModPath, 'go.sum'),
// join(baseGoModPath, 'go.sum.bk'),
// { overwrite: forceMove }
// );
//}
} else {
// legacy mode
// we need `main.go` in the same dir as the entrypoint,
@@ -449,26 +446,14 @@ Learn more: https://vercel.com/docs/runtimes#official-runtimes/go
}
}
/*
const lambda = await createLambda({
files: { ...(await glob('**', outDir)), ...includedFiles },
handler: handlerFileName,
runtime: 'go1.x',
environment: {},
});
const watch = parsedAnalyzed.watch;
let watchSub: string[] = [];
// if `entrypoint` located in subdirectory
// we will need to concat it with return watch array
if (entrypointArr.length > 1) {
entrypointArr.pop();
watchSub = parsedAnalyzed.watch.map(file => join(...entrypointArr, file));
}
return {
output: lambda,
watch: watch.concat(watchSub),
};
*/
}
function isPortInfo(v: any): v is PortInfo {

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/go",
"version": "1.2.4-canary.4",
"name": "vercel-plugin-go",
"version": "1.2.4-canary.3",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",

View File

@@ -5,10 +5,10 @@
{ "src": "subdirectory/index.go", "use": "@vercel/go" }
],
"probes": [
{ "path": "/", "mustContain": "cow:go1.17.3:RANDOMNESS_PLACEHOLDER" },
{ "path": "/", "mustContain": "cow:go1.16:RANDOMNESS_PLACEHOLDER" },
{
"path": "/subdirectory",
"mustContain": "subcow:go1.17.3:RANDOMNESS_PLACEHOLDER"
"mustContain": "subcow:go1.16:RANDOMNESS_PLACEHOLDER"
}
]
}

View File

@@ -1,3 +1,3 @@
module with-nested
go 1.16
go 1.12

View File

@@ -1,2 +0,0 @@
entries.js
dist

View File

@@ -1,2 +0,0 @@
/dist
/test/fixtures/*/.output

View File

@@ -1,30 +0,0 @@
#!/usr/bin/env node
const fs = require('fs-extra');
const execa = require('execa');
const { join } = require('path');
async function main() {
const srcDir = join(__dirname, 'src');
const outDir = join(__dirname, 'dist');
// Start fresh
await fs.remove(outDir);
await execa(
'ncc',
['build', join(srcDir, 'index.ts'), '-o', outDir, '--external', 'esbuild'],
{
stdio: 'inherit',
}
);
await fs.copyFile(
join(__dirname, 'src/entries.js'),
join(outDir, 'entries.js')
);
}
main().catch(err => {
console.error(err);
process.exit(1);
});

View File

@@ -1,58 +0,0 @@
{
"name": "vercel-plugin-middleware",
"version": "0.0.0-canary.7",
"license": "MIT",
"main": "./dist/index",
"homepage": "",
"repository": {
"type": "git",
"url": "https://github.com/vercel/vercel.git",
"directory": "packages/middleware"
},
"scripts": {
"build": "node build",
"test-unit": "jest",
"prepublishOnly": "node build"
},
"files": [
"dist"
],
"dependencies": {
"esbuild": "0.13.12"
},
"devDependencies": {
"@peculiar/webcrypto": "1.2.0",
"@types/cookie": "0.4.1",
"@types/glob": "7.2.0",
"@types/http-proxy": "1.17.7",
"@types/jest": "27.0.2",
"@types/node": "16.11.6",
"@types/node-fetch": "^2",
"@types/ua-parser-js": "0.7.36",
"@types/uuid": "8.3.1",
"@vercel/ncc": "0.24.0",
"cookie": "0.4.1",
"formdata-node": "4.3.1",
"glob": "7.2.0",
"http-proxy": "1.18.1",
"node-fetch": "^2",
"ua-parser-js": "1.0.2",
"url": "0.11.0",
"uuid": "8.3.2",
"web-streams-polyfill": "3.1.1"
},
"jest": {
"preset": "ts-jest",
"globals": {
"ts-jest": {
"diagnostics": false,
"isolatedModules": true
}
},
"verbose": false,
"testEnvironment": "node",
"testMatch": [
"<rootDir>/test/**/*.test.ts"
]
}
}

View File

@@ -1,18 +0,0 @@
import * as middleware from './_middleware';
_ENTRIES = typeof _ENTRIES === 'undefined' ? {} : _ENTRIES;
_ENTRIES['middleware_pages/_middleware'] = {
default: async function (ev) {
const result = await middleware.default(ev.request, ev);
return {
promise: Promise.resolve(),
waitUntil: Promise.resolve(),
response:
result ||
new Response(null, {
headers: {
'x-middleware-next': 1,
},
}),
};
},
};

View File

@@ -1,323 +0,0 @@
import util from 'util';
import { extname, join, basename } from 'path';
import * as esbuild from 'esbuild';
import { promises as fsp } from 'fs';
import { IncomingMessage, ServerResponse } from 'http';
import libGlob from 'glob';
import Proxy from 'http-proxy';
import { run } from './websandbox';
import type { FetchEventResult } from './websandbox/types';
import { ParsedUrlQuery, stringify as stringifyQs } from 'querystring';
import {
format as formatUrl,
parse as parseUrl,
UrlWithParsedQuery,
} from 'url';
import { toNodeHeaders } from './websandbox/utils';
const glob = util.promisify(libGlob);
const SUPPORTED_EXTENSIONS = ['.js', '.ts'];
// File name of the `entries.js` file that gets copied into the
// project directory. Use a name that is unlikely to conflict.
const ENTRIES_NAME = '___vc_entries.js';
async function getMiddlewareFile(workingDirectory: string) {
// Only the root-level `_middleware.*` files are considered.
// For more granular routing, the Project's Framework (i.e. Next.js)
// middleware support should be used.
const middlewareFiles = await glob(join(workingDirectory, '_middleware.*'));
if (middlewareFiles.length === 0) {
// No middleware file at the root of the project, so bail...
return;
}
if (middlewareFiles.length > 1) {
throw new Error(
`Only one middleware file is allowed. Found: ${middlewareFiles.join(
', '
)}`
);
}
const ext = extname(middlewareFiles[0]);
if (!SUPPORTED_EXTENSIONS.includes(ext)) {
throw new Error(`Unsupported file type: ${ext}`);
}
return middlewareFiles[0];
}
export async function build({ workPath }: { workPath: string }) {
const entriesPath = join(workPath, ENTRIES_NAME);
const middlewareFile = await getMiddlewareFile(workPath);
if (!middlewareFile) return;
console.log('Compiling middleware file: %j', middlewareFile);
// Create `_ENTRIES` wrapper
await fsp.copyFile(join(__dirname, 'entries.js'), entriesPath);
// Build
try {
await esbuild.build({
entryPoints: [entriesPath],
bundle: true,
absWorkingDir: workPath,
outfile: join(workPath, '.output/server/pages/_middleware.js'),
});
} finally {
await fsp.unlink(entriesPath);
}
// Write middleware manifest
const middlewareManifest = {
version: 1,
sortedMiddleware: ['/'],
middleware: {
'/': {
env: [],
files: ['server/pages/_middleware.js'],
name: 'pages/_middleware',
page: '/',
regexp: '^/.*$',
},
},
};
const middlewareManifestData = JSON.stringify(middlewareManifest, null, 2);
const middlewareManifestPath = join(
workPath,
'.output/server/middleware-manifest.json'
);
await fsp.writeFile(middlewareManifestPath, middlewareManifestData);
}
const stringifyQuery = (req: IncomingMessage, query: ParsedUrlQuery) => {
const initialQueryValues = Object.values((req as any).__NEXT_INIT_QUERY);
return stringifyQs(query, undefined, undefined, {
encodeURIComponent(value: any) {
if (initialQueryValues.some(val => val === value)) {
return encodeURIComponent(value);
}
return value;
},
});
};
// eslint-disable-next-line
async function runMiddlewareCatchAll(
req: IncomingMessage,
res: ServerResponse,
requestId: string,
name: string,
path: string
) {
let result: FetchEventResult | null = null;
const parsedUrl = parseUrl(req.url!, true);
try {
result = await runMiddleware({
request: req,
response: res,
name: name,
path,
requestId: requestId,
parsedUrl,
parsed: parseUrl(req.url!, true),
});
} catch (err) {
console.error(err);
return { finished: true, error: err };
}
if (result === null) {
return { finished: true };
}
if (
!result.response.headers.has('x-middleware-rewrite') &&
!result.response.headers.has('x-middleware-next') &&
!result.response.headers.has('Location')
) {
result.response.headers.set('x-middleware-refresh', '1');
}
result.response.headers.delete('x-middleware-next');
for (const [key, value] of Object.entries(
toNodeHeaders(result.response.headers)
)) {
if (key !== 'content-encoding' && value !== undefined) {
res.setHeader(key, value);
}
}
const preflight =
req.method === 'HEAD' && req.headers['x-middleware-preflight'];
if (preflight) {
res.writeHead(200);
res.end();
return {
finished: true,
};
}
res.statusCode = result.response.status;
res.statusMessage = result.response.statusText;
const location = result.response.headers.get('Location');
if (location) {
res.statusCode = result.response.status;
if (res.statusCode === 308) {
res.setHeader('Refresh', `0;url=${location}`);
}
res.end();
return {
finished: true,
};
}
if (result.response.headers.has('x-middleware-rewrite')) {
const rewrite = result.response.headers.get('x-middleware-rewrite')!;
const rewriteParsed = parseUrl(rewrite, true);
if (rewriteParsed.protocol) {
return proxyRequest(req, res, rewriteParsed);
}
(req as any)._nextRewroteUrl = rewrite;
(req as any)._nextDidRewrite = (req as any)._nextRewroteUrl !== req.url;
return {
finished: false,
pathname: rewriteParsed.pathname,
query: {
...parsedUrl.query,
...rewriteParsed.query,
},
};
}
if (result.response.headers.has('x-middleware-refresh')) {
res.writeHead(result.response.status);
if (result.response.body instanceof Buffer) {
res.write(result.response.body);
} else {
//@ts-ignore
for await (const chunk of result.response.body || []) {
res.write(chunk);
}
}
res.end();
return {
finished: true,
};
}
return {
finished: false,
};
}
const proxyRequest = async (
req: IncomingMessage,
res: ServerResponse,
parsedUrl: UrlWithParsedQuery
) => {
const { query } = parsedUrl;
delete (parsedUrl as any).query;
parsedUrl.search = stringifyQuery(req, query);
const target = formatUrl(parsedUrl);
const proxy = new Proxy({
target,
changeOrigin: true,
ignorePath: true,
xfwd: true,
proxyTimeout: 30_000, // limit proxying to 30 seconds
});
await new Promise((proxyResolve, proxyReject) => {
let finished = false;
proxy.on('proxyReq', (proxyReq: any) => {
proxyReq.on('close', () => {
if (!finished) {
finished = true;
proxyResolve(true);
}
});
});
proxy.on('error', (err: any) => {
if (!finished) {
finished = true;
proxyReject(err);
}
});
proxy.web(req, res);
});
return {
finished: true,
};
};
async function runMiddleware(params: {
request: IncomingMessage;
response: ServerResponse;
parsedUrl: UrlWithParsedQuery;
parsed: UrlWithParsedQuery;
requestId: string;
name: string;
path: string;
}): Promise<FetchEventResult | null> {
const page: { name?: string; params?: { [key: string]: string } } = {};
let result: FetchEventResult | null = null;
result = await run({
name: params.name,
path: params.path,
request: {
headers: params.request.headers,
method: params.request.method || 'GET',
url: params.request.url!,
// url: (params.request as any).__NEXT_INIT_URL,
page,
},
});
result.waitUntil.catch((error: any) => {
console.error(`Uncaught: middleware waitUntil errored`, error);
});
return result;
}
// Should run the middleware in the `vm` sandbox and return the result
// back to `vercel dev`. If no middleware file exists then this function
// should return `finished: false` (very quickly, since this is being
// invoked for every HTTP request!).
export async function runDevMiddleware(
req: IncomingMessage,
res: ServerResponse,
workingDirectory: string
): ReturnType<typeof runMiddlewareCatchAll> {
const middlewareFile = await getMiddlewareFile(workingDirectory);
if (!middlewareFile) {
return {
finished: false,
};
}
return runMiddlewareCatchAll(
req,
res,
'',
basename(middlewareFile),
middlewareFile
);
}

View File

@@ -1,65 +0,0 @@
import type { RequestData, FetchEventResult } from './types';
import { DeprecationError } from './error';
import { fromNodeHeaders } from './utils';
import { NextFetchEvent } from './spec-extension/fetch-event';
import { NextRequest, RequestInit } from './spec-extension/request';
import { SpecResponse } from './spec-extension/response';
import { waitUntilSymbol } from './spec-compliant/fetch-event';
import { Response } from 'node-fetch';
export async function adapter(params: {
handler: (request: NextRequest, event: NextFetchEvent) => Promise<Response>;
page: string;
request: RequestData;
}): Promise<FetchEventResult> {
const url = params.request.url.startsWith('/')
? `https://${params.request.headers.host}${params.request.url}`
: params.request.url;
const request = new NextRequestHint({
page: params.page,
input: url,
init: {
geo: params.request.geo,
//@ts-ignore
headers: fromNodeHeaders(params.request.headers),
ip: params.request.ip,
method: params.request.method,
page: params.request.page,
},
});
const event = new NextFetchEvent({ request, page: params.page });
const original = await params.handler(request, event);
return {
response: original || SpecResponse.next(),
waitUntil: Promise.all(event[waitUntilSymbol]),
};
}
class NextRequestHint extends NextRequest {
sourcePage: string;
constructor(params: {
init: RequestInit;
input: Request | string;
page: string;
}) {
//@ts-ignore
super(params.input, params.init);
this.sourcePage = params.page;
}
get request() {
throw new DeprecationError({ page: this.sourcePage });
}
respondWith() {
throw new DeprecationError({ page: this.sourcePage });
}
waitUntil() {
throw new DeprecationError({ page: this.sourcePage });
}
}

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