mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-24 19:00:03 +00:00
Compare commits
58 Commits
@vercel/no
...
@vercel/st
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cca9b6c5c | ||
|
|
4af242af86 | ||
|
|
0cbdae1411 | ||
|
|
85dd667781 | ||
|
|
7d3dda7341 | ||
|
|
2144d0b2a9 | ||
|
|
976e6aedf9 | ||
|
|
6328751e14 | ||
|
|
8cb49a5136 | ||
|
|
3fa4f344cc | ||
|
|
27610896ed | ||
|
|
b9dae36e37 | ||
|
|
1537ff9c38 | ||
|
|
7e0317775f | ||
|
|
2dd27976b3 | ||
|
|
25e2b7efba | ||
|
|
3d23d1270c | ||
|
|
fde40e731a | ||
|
|
f353527421 | ||
|
|
c1cdfb3e75 | ||
|
|
fc413707d0 | ||
|
|
e842a8870e | ||
|
|
d1b0dbe3a7 | ||
|
|
d614709308 | ||
|
|
d5b588bc06 | ||
|
|
4a8622a10d | ||
|
|
6469ef1b8c | ||
|
|
b8d42a521b | ||
|
|
b1e8c9cb6e | ||
|
|
7c30b13ccb | ||
|
|
e5e757de34 | ||
|
|
2661f56347 | ||
|
|
b1c14cde03 | ||
|
|
8dd6d021df | ||
|
|
88ec6e69d6 | ||
|
|
a6f2e7b136 | ||
|
|
e906365909 | ||
|
|
7b01a07394 | ||
|
|
ce4633fe4d | ||
|
|
fdf86fda03 | ||
|
|
56178e6a46 | ||
|
|
5439d7c0c9 | ||
|
|
c670e51712 | ||
|
|
b56639b624 | ||
|
|
12bbae098c | ||
|
|
9969f0ba18 | ||
|
|
24e1e3c3be | ||
|
|
b61674cb2d | ||
|
|
cae60155f3 | ||
|
|
a91bde5287 | ||
|
|
0750517af9 | ||
|
|
70f6782954 | ||
|
|
5f1e37ee16 | ||
|
|
680d666fdc | ||
|
|
06a5dccfed | ||
|
|
f85df894c0 | ||
|
|
e9ec779f1c | ||
|
|
4333d1e6b2 |
14
.github/CODEOWNERS
vendored
14
.github/CODEOWNERS
vendored
@@ -2,19 +2,19 @@
|
||||
# https://help.github.com/en/articles/about-code-owners
|
||||
|
||||
# Restricted Paths
|
||||
* @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood
|
||||
/.github/workflows @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||
/packages/fs-detectors @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @agadzik @chloetedder
|
||||
/packages/next @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||
/packages/routing-utils @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||
/packages/edge @vercel/edge-compute
|
||||
* @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek
|
||||
/.github/workflows @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek @ijjk
|
||||
/packages/fs-detectors @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek @agadzik @chloetedder
|
||||
/packages/next @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek @ijjk
|
||||
/packages/routing-utils @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek @ijjk
|
||||
/packages/edge @vercel/compute
|
||||
/examples @leerob
|
||||
/examples/create-react-app @Timer
|
||||
/examples/nextjs @timneutkens @ijjk @styfle
|
||||
/examples/hugo @styfle
|
||||
/examples/jekyll @styfle
|
||||
/examples/zola @styfle
|
||||
/packages/node @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @Kikobeats
|
||||
/packages/node @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek @Kikobeats
|
||||
|
||||
# Unrestricted Paths
|
||||
.changeset/
|
||||
|
||||
@@ -44,6 +44,5 @@
|
||||
"react-use": "^17.4.0",
|
||||
"title": "^3.4.4",
|
||||
"typographic-base": "^1.0.4"
|
||||
},
|
||||
"author": "nrajlich"
|
||||
}
|
||||
}
|
||||
|
||||
377
examples/nextjs/package-lock.json
generated
377
examples/nextjs/package-lock.json
generated
@@ -8,9 +8,9 @@
|
||||
"name": "nextjs",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"eslint": "8.44.0",
|
||||
"eslint-config-next": "13.4.8",
|
||||
"next": "13.4.8",
|
||||
"eslint": "8.45.0",
|
||||
"eslint-config-next": "13.4.12",
|
||||
"next": "13.4.12",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
}
|
||||
@@ -24,9 +24,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.22.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz",
|
||||
"integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==",
|
||||
"version": "7.22.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.6.tgz",
|
||||
"integrity": "sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ==",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.13.11"
|
||||
},
|
||||
@@ -117,22 +117,22 @@
|
||||
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
|
||||
},
|
||||
"node_modules/@next/env": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.8.tgz",
|
||||
"integrity": "sha512-twuSf1klb3k9wXI7IZhbZGtFCWvGD4wXTY2rmvzIgVhXhs7ISThrbNyutBx3jWIL8Y/Hk9+woytFz5QsgtcRKQ=="
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.12.tgz",
|
||||
"integrity": "sha512-RmHanbV21saP/6OEPBJ7yJMuys68cIf8OBBWd7+uj40LdpmswVAwe1uzeuFyUsd6SfeITWT3XnQfn6wULeKwDQ=="
|
||||
},
|
||||
"node_modules/@next/eslint-plugin-next": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.8.tgz",
|
||||
"integrity": "sha512-cmfVHpxWjjcETFt2WHnoFU6EmY69QcPJRlRNAooQlNe53Ke90vg1Ci/dkPffryJZaxxiRziP9bQrV8lDVCn3Fw==",
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.12.tgz",
|
||||
"integrity": "sha512-6rhK9CdxEgj/j1qvXIyLTWEaeFv7zOK8yJMulz3Owel0uek0U9MJCGzmKgYxM3aAUBo3gKeywCZKyQnJKto60A==",
|
||||
"dependencies": {
|
||||
"glob": "7.1.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-darwin-arm64": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.8.tgz",
|
||||
"integrity": "sha512-MSFplVM4dTWOuKAUv0XR9gY7AWtMSBu9os9f+kp+s5rWhM1I2CdR3obFttd6366nS/W/VZxbPM5oEIdlIa46zA==",
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.12.tgz",
|
||||
"integrity": "sha512-deUrbCXTMZ6ZhbOoloqecnUeNpUOupi8SE2tx4jPfNS9uyUR9zK4iXBvH65opVcA/9F5I/p8vDXSYbUlbmBjZg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -145,9 +145,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-darwin-x64": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.8.tgz",
|
||||
"integrity": "sha512-Reox+UXgonon9P0WNDE6w85DGtyBqGitl/ryznOvn6TvfxEaZIpTgeu3ZrJLU9dHSMhiK7YAM793mE/Zii2/Qw==",
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.12.tgz",
|
||||
"integrity": "sha512-WRvH7RxgRHlC1yb5oG0ZLx8F7uci9AivM5/HGGv9ZyG2Als8Ij64GC3d+mQ5sJhWjusyU6T6V1WKTUoTmOB0zQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -160,9 +160,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.8.tgz",
|
||||
"integrity": "sha512-kdyzYvAYtqQVgzIKNN7e1rLU8aZv86FDSRqPlOkKZlvqudvTO0iohuTPmnEEDlECeBM6qRPShNffotDcU/R2KA==",
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.12.tgz",
|
||||
"integrity": "sha512-YEKracAWuxp54tKiAvvq73PUs9lok57cc8meYRibTWe/VdPB2vLgkTVWFcw31YDuRXdEhdX0fWS6Q+ESBhnEig==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -175,9 +175,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-musl": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.8.tgz",
|
||||
"integrity": "sha512-oWxx4yRkUGcR81XwbI+T0zhZ3bDF6V1aVLpG+C7hSG50ULpV8gC39UxVO22/bv93ZlcfMY4zl8xkz9Klct6dpQ==",
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.12.tgz",
|
||||
"integrity": "sha512-LhJR7/RAjdHJ2Isl2pgc/JaoxNk0KtBgkVpiDJPVExVWA1c6gzY57+3zWuxuyWzTG+fhLZo2Y80pLXgIJv7g3g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -190,9 +190,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-gnu": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.8.tgz",
|
||||
"integrity": "sha512-anhtvuO6eE9YRhYnaEGTfbpH3L5gT/9qPFcNoi6xS432r/4DAtpJY8kNktqkTVevVIC/pVumqO8tV59PR3zbNg==",
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.12.tgz",
|
||||
"integrity": "sha512-1DWLL/B9nBNiQRng+1aqs3OaZcxC16Nf+mOnpcrZZSdyKHek3WQh6j/fkbukObgNGwmCoVevLUa/p3UFTTqgqg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -205,9 +205,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-musl": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.8.tgz",
|
||||
"integrity": "sha512-aR+J4wWfNgH1DwCCBNjan7Iumx0lLtn+2/rEYuhIrYLY4vnxqSVGz9u3fXcgUwo6Q9LT8NFkaqK1vPprdq+BXg==",
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.12.tgz",
|
||||
"integrity": "sha512-kEAJmgYFhp0VL+eRWmUkVxLVunn7oL9Mdue/FS8yzRBVj7Z0AnIrHpTIeIUl1bbdQq1VaoOztnKicAjfkLTRCQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -220,9 +220,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.8.tgz",
|
||||
"integrity": "sha512-OWBKIrJwQBTqrat0xhxEB/jcsjJR3+diD9nc/Y8F1mRdQzsn4bPsomgJyuqPVZs6Lz3K18qdIkvywmfSq75SsQ==",
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.12.tgz",
|
||||
"integrity": "sha512-GMLuL/loR6yIIRTnPRY6UGbLL9MBdw2anxkOnANxvLvsml4F0HNIgvnU3Ej4BjbqMTNjD4hcPFdlEow4XHPdZA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -235,9 +235,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-ia32-msvc": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.8.tgz",
|
||||
"integrity": "sha512-agiPWGjUndXGTOn4ChbKipQXRA6/UPkywAWIkx7BhgGv48TiJfHTK6MGfBoL9tS6B4mtW39++uy0wFPnfD0JWg==",
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.12.tgz",
|
||||
"integrity": "sha512-PhgNqN2Vnkm7XaMdRmmX0ZSwZXQAtamBVSa9A/V1dfKQCV1rjIZeiy/dbBnVYGdj63ANfsOR/30XpxP71W0eww==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -250,9 +250,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-x64-msvc": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.8.tgz",
|
||||
"integrity": "sha512-UIRKoByVKbuR6SnFG4JM8EMFlJrfEGuUQ1ihxzEleWcNwRMMiVaCj1KyqfTOW8VTQhJ0u8P1Ngg6q1RwnIBTtw==",
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.12.tgz",
|
||||
"integrity": "sha512-Z+56e/Ljt0bUs+T+jPjhFyxYBcdY2RIq9ELFU+qAMQMteHo7ymbV7CKmlcX59RI9C4YzN8PgMgLyAoi916b5HA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -297,16 +297,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgr/utils": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.1.tgz",
|
||||
"integrity": "sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w==",
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz",
|
||||
"integrity": "sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw==",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.3",
|
||||
"fast-glob": "^3.2.12",
|
||||
"fast-glob": "^3.3.0",
|
||||
"is-glob": "^4.0.3",
|
||||
"open": "^9.1.0",
|
||||
"picocolors": "^1.0.0",
|
||||
"tslib": "^2.5.0"
|
||||
"tslib": "^2.6.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
|
||||
@@ -334,13 +334,13 @@
|
||||
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "5.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz",
|
||||
"integrity": "sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==",
|
||||
"version": "5.62.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz",
|
||||
"integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "5.61.0",
|
||||
"@typescript-eslint/types": "5.61.0",
|
||||
"@typescript-eslint/typescript-estree": "5.61.0",
|
||||
"@typescript-eslint/scope-manager": "5.62.0",
|
||||
"@typescript-eslint/types": "5.62.0",
|
||||
"@typescript-eslint/typescript-estree": "5.62.0",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
@@ -360,12 +360,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "5.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.61.0.tgz",
|
||||
"integrity": "sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==",
|
||||
"version": "5.62.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz",
|
||||
"integrity": "sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.61.0",
|
||||
"@typescript-eslint/visitor-keys": "5.61.0"
|
||||
"@typescript-eslint/types": "5.62.0",
|
||||
"@typescript-eslint/visitor-keys": "5.62.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
@@ -376,9 +376,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "5.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz",
|
||||
"integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==",
|
||||
"version": "5.62.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz",
|
||||
"integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
@@ -388,12 +388,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "5.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz",
|
||||
"integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==",
|
||||
"version": "5.62.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz",
|
||||
"integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.61.0",
|
||||
"@typescript-eslint/visitor-keys": "5.61.0",
|
||||
"@typescript-eslint/types": "5.62.0",
|
||||
"@typescript-eslint/visitor-keys": "5.62.0",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
@@ -414,11 +414,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "5.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.61.0.tgz",
|
||||
"integrity": "sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==",
|
||||
"version": "5.62.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz",
|
||||
"integrity": "sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.61.0",
|
||||
"@typescript-eslint/types": "5.62.0",
|
||||
"eslint-visitor-keys": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -430,9 +430,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.9.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz",
|
||||
"integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==",
|
||||
"version": "8.10.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
|
||||
"integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -582,6 +582,25 @@
|
||||
"get-intrinsic": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/arraybuffer.prototype.slice": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz",
|
||||
"integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==",
|
||||
"dependencies": {
|
||||
"array-buffer-byte-length": "^1.0.0",
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.2.0",
|
||||
"get-intrinsic": "^1.2.1",
|
||||
"is-array-buffer": "^3.0.2",
|
||||
"is-shared-array-buffer": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/ast-types-flow": {
|
||||
"version": "0.0.7",
|
||||
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
|
||||
@@ -704,9 +723,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001511",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001511.tgz",
|
||||
"integrity": "sha512-NaWPJawcoedlghN4P7bDNeADD7K+rZaY6V8ZcME7PkEZo/nfOg+lnrUgRWiKbNxcQ4/toFKSxnS4WdbyPZnKkw==",
|
||||
"version": "1.0.30001517",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz",
|
||||
"integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -908,17 +927,18 @@
|
||||
}
|
||||
},
|
||||
"node_modules/es-abstract": {
|
||||
"version": "1.21.2",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.2.tgz",
|
||||
"integrity": "sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==",
|
||||
"version": "1.22.1",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz",
|
||||
"integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==",
|
||||
"dependencies": {
|
||||
"array-buffer-byte-length": "^1.0.0",
|
||||
"arraybuffer.prototype.slice": "^1.0.1",
|
||||
"available-typed-arrays": "^1.0.5",
|
||||
"call-bind": "^1.0.2",
|
||||
"es-set-tostringtag": "^2.0.1",
|
||||
"es-to-primitive": "^1.2.1",
|
||||
"function.prototype.name": "^1.1.5",
|
||||
"get-intrinsic": "^1.2.0",
|
||||
"get-intrinsic": "^1.2.1",
|
||||
"get-symbol-description": "^1.0.0",
|
||||
"globalthis": "^1.0.3",
|
||||
"gopd": "^1.0.1",
|
||||
@@ -938,14 +958,18 @@
|
||||
"object-inspect": "^1.12.3",
|
||||
"object-keys": "^1.1.1",
|
||||
"object.assign": "^4.1.4",
|
||||
"regexp.prototype.flags": "^1.4.3",
|
||||
"regexp.prototype.flags": "^1.5.0",
|
||||
"safe-array-concat": "^1.0.0",
|
||||
"safe-regex-test": "^1.0.0",
|
||||
"string.prototype.trim": "^1.2.7",
|
||||
"string.prototype.trimend": "^1.0.6",
|
||||
"string.prototype.trimstart": "^1.0.6",
|
||||
"typed-array-buffer": "^1.0.0",
|
||||
"typed-array-byte-length": "^1.0.0",
|
||||
"typed-array-byte-offset": "^1.0.0",
|
||||
"typed-array-length": "^1.0.4",
|
||||
"unbox-primitive": "^1.0.2",
|
||||
"which-typed-array": "^1.1.9"
|
||||
"which-typed-array": "^1.1.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -1003,9 +1027,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "8.44.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz",
|
||||
"integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==",
|
||||
"version": "8.45.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz",
|
||||
"integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.4.0",
|
||||
@@ -1032,7 +1056,6 @@
|
||||
"globals": "^13.19.0",
|
||||
"graphemer": "^1.4.0",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.0.0",
|
||||
"imurmurhash": "^0.1.4",
|
||||
"is-glob": "^4.0.0",
|
||||
"is-path-inside": "^3.0.3",
|
||||
@@ -1044,7 +1067,6 @@
|
||||
"natural-compare": "^1.4.0",
|
||||
"optionator": "^0.9.3",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"strip-json-comments": "^3.1.0",
|
||||
"text-table": "^0.2.0"
|
||||
},
|
||||
"bin": {
|
||||
@@ -1058,11 +1080,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-config-next": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.4.8.tgz",
|
||||
"integrity": "sha512-2hE0b6lHuhtHBX8VgEXi8v4G8PVrPUBMOSLCTq8qtcQ2qQOX7+uBOLK2kU4FD2qDZzyXNlhmuH+WLT5ptY4XLA==",
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.4.12.tgz",
|
||||
"integrity": "sha512-ZF0r5vxKaVazyZH/37Au/XItiG7qUOBw+HaH3PeyXltIMwXorsn6bdrl0Nn9N5v5v9spc+6GM2ryjugbjF6X2g==",
|
||||
"dependencies": {
|
||||
"@next/eslint-plugin-next": "13.4.8",
|
||||
"@next/eslint-plugin-next": "13.4.12",
|
||||
"@rushstack/eslint-patch": "^1.1.3",
|
||||
"@typescript-eslint/parser": "^5.42.0",
|
||||
"eslint-import-resolver-node": "^0.3.6",
|
||||
@@ -1070,7 +1092,7 @@
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||
"eslint-plugin-react": "^7.31.7",
|
||||
"eslint-plugin-react-hooks": "^4.5.0"
|
||||
"eslint-plugin-react-hooks": "5.0.0-canary-7118f5dd7-20230705"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^7.23.0 || ^8.0.0",
|
||||
@@ -1126,13 +1148,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-import-resolver-typescript/node_modules/globby": {
|
||||
"version": "13.2.1",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-13.2.1.tgz",
|
||||
"integrity": "sha512-DPCBxctI7dN4EeIqjW2KGqgdcUMbrhJ9AzON+PlxCtvppWhubTLD4+a0GFxiym14ZvacUydTPjLPc2DlKz7EIg==",
|
||||
"version": "13.2.2",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz",
|
||||
"integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==",
|
||||
"dependencies": {
|
||||
"dir-glob": "^3.0.1",
|
||||
"fast-glob": "^3.2.11",
|
||||
"ignore": "^5.2.0",
|
||||
"fast-glob": "^3.3.0",
|
||||
"ignore": "^5.2.4",
|
||||
"merge2": "^1.4.1",
|
||||
"slash": "^4.0.0"
|
||||
},
|
||||
@@ -1226,9 +1248,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-import/node_modules/semver": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
@@ -1263,17 +1285,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-jsx-a11y/node_modules/semver": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-react": {
|
||||
"version": "7.32.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz",
|
||||
"integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==",
|
||||
"version": "7.33.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.0.tgz",
|
||||
"integrity": "sha512-qewL/8P34WkY8jAqdQxsiL82pDUeT7nhs8IsuXgfgnsEloKCT4miAV9N9kGtx7/KM9NH/NCGUE7Edt9iGxLXFw==",
|
||||
"dependencies": {
|
||||
"array-includes": "^3.1.6",
|
||||
"array.prototype.flatmap": "^1.3.1",
|
||||
@@ -1288,7 +1310,7 @@
|
||||
"object.values": "^1.1.6",
|
||||
"prop-types": "^15.8.1",
|
||||
"resolve": "^2.0.0-next.4",
|
||||
"semver": "^6.3.0",
|
||||
"semver": "^6.3.1",
|
||||
"string.prototype.matchall": "^4.0.8"
|
||||
},
|
||||
"engines": {
|
||||
@@ -1299,9 +1321,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-react-hooks": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz",
|
||||
"integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==",
|
||||
"version": "5.0.0-canary-7118f5dd7-20230705",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz",
|
||||
"integrity": "sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw==",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -1337,17 +1359,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-react/node_modules/semver": {
|
||||
"version": "6.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
|
||||
"integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
|
||||
"version": "7.2.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.1.tgz",
|
||||
"integrity": "sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==",
|
||||
"dependencies": {
|
||||
"esrecurse": "^4.3.0",
|
||||
"estraverse": "^5.2.0"
|
||||
@@ -1371,9 +1393,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/espree": {
|
||||
"version": "9.6.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz",
|
||||
"integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==",
|
||||
"version": "9.6.1",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
|
||||
"integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
|
||||
"dependencies": {
|
||||
"acorn": "^8.9.0",
|
||||
"acorn-jsx": "^5.3.2",
|
||||
@@ -2118,15 +2140,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/is-typed-array": {
|
||||
"version": "1.1.10",
|
||||
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
|
||||
"integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
|
||||
"version": "1.1.12",
|
||||
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
|
||||
"integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
|
||||
"dependencies": {
|
||||
"available-typed-arrays": "^1.0.5",
|
||||
"call-bind": "^1.0.2",
|
||||
"for-each": "^0.3.3",
|
||||
"gopd": "^1.0.1",
|
||||
"has-tostringtag": "^1.0.0"
|
||||
"which-typed-array": "^1.1.11"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
@@ -2171,6 +2189,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/isarray": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
|
||||
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@@ -2376,11 +2399,11 @@
|
||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
|
||||
},
|
||||
"node_modules/next": {
|
||||
"version": "13.4.8",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-13.4.8.tgz",
|
||||
"integrity": "sha512-lxUjndYKjZHGK3CWeN2RI+/6ni6EUvjiqGWXAYPxUfGIdFGQ5XoisrqAJ/dF74aP27buAfs8MKIbIMMdxjqSBg==",
|
||||
"version": "13.4.12",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-13.4.12.tgz",
|
||||
"integrity": "sha512-eHfnru9x6NRmTMcjQp6Nz0J4XH9OubmzOa7CkWL+AUrUxpibub3vWwttjduu9No16dug1kq04hiUUpo7J3m3Xw==",
|
||||
"dependencies": {
|
||||
"@next/env": "13.4.8",
|
||||
"@next/env": "13.4.12",
|
||||
"@swc/helpers": "0.5.1",
|
||||
"busboy": "1.6.0",
|
||||
"caniuse-lite": "^1.0.30001406",
|
||||
@@ -2396,15 +2419,15 @@
|
||||
"node": ">=16.8.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@next/swc-darwin-arm64": "13.4.8",
|
||||
"@next/swc-darwin-x64": "13.4.8",
|
||||
"@next/swc-linux-arm64-gnu": "13.4.8",
|
||||
"@next/swc-linux-arm64-musl": "13.4.8",
|
||||
"@next/swc-linux-x64-gnu": "13.4.8",
|
||||
"@next/swc-linux-x64-musl": "13.4.8",
|
||||
"@next/swc-win32-arm64-msvc": "13.4.8",
|
||||
"@next/swc-win32-ia32-msvc": "13.4.8",
|
||||
"@next/swc-win32-x64-msvc": "13.4.8"
|
||||
"@next/swc-darwin-arm64": "13.4.12",
|
||||
"@next/swc-darwin-x64": "13.4.12",
|
||||
"@next/swc-linux-arm64-gnu": "13.4.12",
|
||||
"@next/swc-linux-arm64-musl": "13.4.12",
|
||||
"@next/swc-linux-x64-gnu": "13.4.12",
|
||||
"@next/swc-linux-x64-musl": "13.4.12",
|
||||
"@next/swc-win32-arm64-msvc": "13.4.12",
|
||||
"@next/swc-win32-ia32-msvc": "13.4.12",
|
||||
"@next/swc-win32-x64-msvc": "13.4.12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentelemetry/api": "^1.1.0",
|
||||
@@ -2985,6 +3008,23 @@
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-array-concat": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz",
|
||||
"integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"get-intrinsic": "^1.2.0",
|
||||
"has-symbols": "^1.0.3",
|
||||
"isarray": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-regex-test": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
|
||||
@@ -3007,9 +3047,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.5.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
|
||||
"integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
@@ -3333,6 +3373,54 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/typed-array-buffer": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
|
||||
"integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"get-intrinsic": "^1.2.1",
|
||||
"is-typed-array": "^1.1.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/typed-array-byte-length": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
|
||||
"integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"for-each": "^0.3.3",
|
||||
"has-proto": "^1.0.1",
|
||||
"is-typed-array": "^1.1.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/typed-array-byte-offset": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
|
||||
"integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
|
||||
"dependencies": {
|
||||
"available-typed-arrays": "^1.0.5",
|
||||
"call-bind": "^1.0.2",
|
||||
"for-each": "^0.3.3",
|
||||
"has-proto": "^1.0.1",
|
||||
"is-typed-array": "^1.1.10"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/typed-array-length": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
|
||||
@@ -3431,16 +3519,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/which-typed-array": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
|
||||
"integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
|
||||
"integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
|
||||
"dependencies": {
|
||||
"available-typed-arrays": "^1.0.5",
|
||||
"call-bind": "^1.0.2",
|
||||
"for-each": "^0.3.3",
|
||||
"gopd": "^1.0.1",
|
||||
"has-tostringtag": "^1.0.0",
|
||||
"is-typed-array": "^1.1.10"
|
||||
"has-tostringtag": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint": "8.44.0",
|
||||
"eslint-config-next": "13.4.8",
|
||||
"next": "13.4.8",
|
||||
"eslint": "8.45.0",
|
||||
"eslint-config-next": "13.4.12",
|
||||
"next": "13.4.12",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
}
|
||||
|
||||
@@ -45,4 +45,4 @@ Locally preview production build:
|
||||
npm run preview
|
||||
```
|
||||
|
||||
Checkout the [deployment documentation](https://v3.nuxtjs.org/guide/deploy/presets) for more information.
|
||||
Checkout the [deployment documentation](https://nuxt.com/docs/getting-started/deployment#presets) for more information.
|
||||
|
||||
2
examples/package.json
vendored
2
examples/package.json
vendored
@@ -9,6 +9,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "27.4.1",
|
||||
"@vercel/frameworks": "1.4.3"
|
||||
"@vercel/frameworks": "1.5.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
# @vercel-internals/types
|
||||
|
||||
## 1.0.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0750517af`](https://github.com/vercel/vercel/commit/0750517af99aea41410d4f1f772ce427699554e7)]:
|
||||
- @vercel/build-utils@6.8.2
|
||||
|
||||
## 1.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@vercel-internals/types",
|
||||
"version": "1.0.4",
|
||||
"version": "1.0.5",
|
||||
"types": "index.d.ts",
|
||||
"main": "index.d.ts",
|
||||
"dependencies": {
|
||||
"@types/node": "14.14.31",
|
||||
"@vercel-internals/constants": "1.0.4",
|
||||
"@vercel/build-utils": "6.8.1",
|
||||
"@vercel/build-utils": "6.8.2",
|
||||
"@vercel/routing-utils": "2.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"source-map-support": "0.5.12",
|
||||
"ts-eager": "2.0.2",
|
||||
"ts-jest": "29.1.0",
|
||||
"turbo": "1.10.7",
|
||||
"turbo": "1.10.12",
|
||||
"typescript": "4.9.5"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @vercel/build-utils
|
||||
|
||||
## 6.8.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Push back `nodejs16.x` discontinue date to `2024-02-06` ([#10209](https://github.com/vercel/vercel/pull/10209))
|
||||
|
||||
## 6.8.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "6.8.1",
|
||||
"version": "6.8.2",
|
||||
"license": "Apache-2.0",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -10,7 +10,7 @@ function getOptions() {
|
||||
major: 16,
|
||||
range: '16.x',
|
||||
runtime: 'nodejs16.x',
|
||||
discontinueDate: new Date('2023-08-15'),
|
||||
discontinueDate: new Date('2024-02-06'),
|
||||
},
|
||||
{
|
||||
major: 14,
|
||||
|
||||
6
packages/build-utils/test/unit.test.ts
vendored
6
packages/build-utils/test/unit.test.ts
vendored
@@ -238,7 +238,7 @@ it('should get latest node version', async () => {
|
||||
it('should throw for discontinued versions', async () => {
|
||||
// Mock a future date so that Node 8 and 10 become discontinued
|
||||
const realDateNow = Date.now.bind(global.Date);
|
||||
global.Date.now = () => new Date('2023-10-01').getTime();
|
||||
global.Date.now = () => new Date('2024-02-13').getTime();
|
||||
|
||||
expect(getSupportedNodeVersion('8.10.x', false)).rejects.toThrow();
|
||||
expect(getSupportedNodeVersion('8.10.x', true)).rejects.toThrow();
|
||||
@@ -306,8 +306,8 @@ it('should warn for deprecated versions, soon to be discontinued', async () => {
|
||||
'Error: Node.js version 12.x has reached End-of-Life. Deployments created on or after 2022-10-03 will fail to build. Please set Node.js Version to 18.x in your Project Settings to use Node.js 18.',
|
||||
'Error: Node.js version 14.x has reached End-of-Life. Deployments created on or after 2023-08-15 will fail to build. Please set "engines": { "node": "18.x" } in your `package.json` file to use Node.js 18.',
|
||||
'Error: Node.js version 14.x has reached End-of-Life. Deployments created on or after 2023-08-15 will fail to build. Please set Node.js Version to 18.x in your Project Settings to use Node.js 18.',
|
||||
'Error: Node.js version 16.x has reached End-of-Life. Deployments created on or after 2023-08-15 will fail to build. Please set "engines": { "node": "18.x" } in your `package.json` file to use Node.js 18.',
|
||||
'Error: Node.js version 16.x has reached End-of-Life. Deployments created on or after 2023-08-15 will fail to build. Please set Node.js Version to 18.x in your Project Settings to use Node.js 18.',
|
||||
'Error: Node.js version 16.x has reached End-of-Life. Deployments created on or after 2024-02-06 will fail to build. Please set "engines": { "node": "18.x" } in your `package.json` file to use Node.js 18.',
|
||||
'Error: Node.js version 16.x has reached End-of-Life. Deployments created on or after 2024-02-06 will fail to build. Please set Node.js Version to 18.x in your Project Settings to use Node.js 18.',
|
||||
]);
|
||||
|
||||
global.Date.now = realDateNow;
|
||||
|
||||
@@ -1,5 +1,111 @@
|
||||
# vercel
|
||||
|
||||
## 31.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Migrate list command to new structure ([#10284](https://github.com/vercel/vercel/pull/10284))
|
||||
|
||||
- Migrate whoami command to new structure ([#10266](https://github.com/vercel/vercel/pull/10266))
|
||||
|
||||
- Migrate logs command to new structure ([#10281](https://github.com/vercel/vercel/pull/10281))
|
||||
|
||||
- Migrate login command to new structure ([#10283](https://github.com/vercel/vercel/pull/10283))
|
||||
|
||||
- Migrate pull command to new structure ([#10280](https://github.com/vercel/vercel/pull/10280))
|
||||
|
||||
- Migrate logout command to new structure ([#10282](https://github.com/vercel/vercel/pull/10282))
|
||||
|
||||
- Migrate build command to new structure ([#10286](https://github.com/vercel/vercel/pull/10286))
|
||||
|
||||
- Migrate inspect command to new structure ([#10277](https://github.com/vercel/vercel/pull/10277))
|
||||
|
||||
- Migrate redeploy command to new structure ([#10279](https://github.com/vercel/vercel/pull/10279))
|
||||
|
||||
- Migrate link command to new structure ([#10285](https://github.com/vercel/vercel/pull/10285))
|
||||
|
||||
- Update spacing of --help output for CLI ([#10287](https://github.com/vercel/vercel/pull/10287))
|
||||
|
||||
- Updated dependencies [[`4af242af8`](https://github.com/vercel/vercel/commit/4af242af8633e58b6a9bf920564416da3ef22ad4), [`0cbdae141`](https://github.com/vercel/vercel/commit/0cbdae1411aa7936ff7dfe551919ca5e56cd6e98), [`85dd66778`](https://github.com/vercel/vercel/commit/85dd667781693539d753d587566e53964bbe189d)]:
|
||||
- @vercel/node@2.15.8
|
||||
- @vercel/remix-builder@1.9.1
|
||||
- @vercel/static-build@1.3.44
|
||||
|
||||
## 31.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Migrate bisect command to new structure ([#10276](https://github.com/vercel/vercel/pull/10276))
|
||||
|
||||
- Migrate remove command to new structure ([#10268](https://github.com/vercel/vercel/pull/10268))
|
||||
|
||||
- Updated dependencies [[`fc413707d`](https://github.com/vercel/vercel/commit/fc413707d017e234d5013b761d885f65f9b981bc)]:
|
||||
- @vercel/node@2.15.7
|
||||
- @vercel/static-build@1.3.43
|
||||
|
||||
## 31.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add a "Global Options" section to help output ([#10250](https://github.com/vercel/vercel/pull/10250))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`d1b0dbe3a`](https://github.com/vercel/vercel/commit/d1b0dbe3a7d8754286aa2b7ba0c8b55d3adafdea), [`4a8622a10`](https://github.com/vercel/vercel/commit/4a8622a10d52260cb629a1c4a6f797ade05ea154), [`6469ef1b8`](https://github.com/vercel/vercel/commit/6469ef1b8ce37e93f50ab4a108aa0953d7631fe8)]:
|
||||
- @vercel/remix-builder@1.9.0
|
||||
- @vercel/next@3.9.3
|
||||
|
||||
## 31.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`7c30b13cc`](https://github.com/vercel/vercel/commit/7c30b13ccb79bdf0ac240282bba4c084f1d0d122)]:
|
||||
- @vercel/next@3.9.2
|
||||
|
||||
## 31.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add 'Environment' column to 'vc list' with new '--environment' filter and pipe URLs to stdout ([#10239](https://github.com/vercel/vercel/pull/10239))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Update `proxy-agent` to v6.3.0 ([#10226](https://github.com/vercel/vercel/pull/10226))
|
||||
|
||||
- Use `getNodeBinPaths()` in `vc dev` ([#10225](https://github.com/vercel/vercel/pull/10225))
|
||||
|
||||
- Updated dependencies [[`b1c14cde0`](https://github.com/vercel/vercel/commit/b1c14cde03f94b2c15ba12c9be9d19c72df2fdbb), [`ce4633fe4`](https://github.com/vercel/vercel/commit/ce4633fe4d00cb5c251cdabbfab08f39ec3f3b5f)]:
|
||||
- @vercel/next@3.9.1
|
||||
- @vercel/static-build@1.3.42
|
||||
|
||||
## 31.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Detect multiple frameworks within the same root directory during `vc link --repo` ([#10203](https://github.com/vercel/vercel/pull/10203))
|
||||
|
||||
- Updated dependencies [[`b56639b62`](https://github.com/vercel/vercel/commit/b56639b624e9ad1df048a4c85083e26888696060), [`cae60155f`](https://github.com/vercel/vercel/commit/cae60155f34883f08a5e4f51b547e2a1a5fee694), [`c670e5171`](https://github.com/vercel/vercel/commit/c670e51712022193e078bd68b055f7e61013015d), [`5439d7c0c`](https://github.com/vercel/vercel/commit/5439d7c0c9b79e7161bf4fa84ffdb357365f9e7e)]:
|
||||
- @vercel/node@2.15.6
|
||||
- @vercel/next@3.9.0
|
||||
- @vercel/remix-builder@1.8.18
|
||||
- @vercel/static-build@1.3.41
|
||||
|
||||
## 31.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Fix redeploy target to be undefined when null ([#10201](https://github.com/vercel/vercel/pull/10201))
|
||||
|
||||
- Respect forbidden API responses ([#10178](https://github.com/vercel/vercel/pull/10178))
|
||||
|
||||
- Update `supports-hyperlinks` to v3 ([#10208](https://github.com/vercel/vercel/pull/10208))
|
||||
|
||||
- Updated dependencies [[`0750517af`](https://github.com/vercel/vercel/commit/0750517af99aea41410d4f1f772ce427699554e7)]:
|
||||
- @vercel/build-utils@6.8.2
|
||||
- @vercel/static-build@1.3.40
|
||||
- @vercel/node@2.15.5
|
||||
- @vercel/remix-builder@1.8.17
|
||||
|
||||
## 31.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "31.0.2",
|
||||
"version": "31.2.2",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -31,16 +31,16 @@
|
||||
"node": ">= 14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.8.1",
|
||||
"@vercel/build-utils": "6.8.2",
|
||||
"@vercel/go": "2.5.1",
|
||||
"@vercel/hydrogen": "0.0.64",
|
||||
"@vercel/next": "3.8.8",
|
||||
"@vercel/node": "2.15.4",
|
||||
"@vercel/next": "3.9.3",
|
||||
"@vercel/node": "2.15.8",
|
||||
"@vercel/python": "3.1.60",
|
||||
"@vercel/redwood": "1.1.15",
|
||||
"@vercel/remix-builder": "1.8.16",
|
||||
"@vercel/remix-builder": "1.9.1",
|
||||
"@vercel/ruby": "1.3.76",
|
||||
"@vercel/static-build": "1.3.39"
|
||||
"@vercel/static-build": "1.3.44"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@alex_neo/jest-expect-message": "1.0.5",
|
||||
@@ -86,11 +86,11 @@
|
||||
"@types/yauzl-promise": "2.1.0",
|
||||
"@vercel-internals/constants": "1.0.4",
|
||||
"@vercel-internals/get-package-json": "1.0.0",
|
||||
"@vercel-internals/types": "1.0.4",
|
||||
"@vercel/client": "12.6.4",
|
||||
"@vercel-internals/types": "1.0.5",
|
||||
"@vercel/client": "12.6.5",
|
||||
"@vercel/error-utils": "1.0.10",
|
||||
"@vercel/frameworks": "1.4.3",
|
||||
"@vercel/fs-detectors": "4.0.1",
|
||||
"@vercel/frameworks": "1.5.0",
|
||||
"@vercel/fs-detectors": "4.1.1",
|
||||
"@vercel/fun": "1.0.4",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/routing-utils": "2.2.1",
|
||||
@@ -149,7 +149,7 @@
|
||||
"pluralize": "7.0.0",
|
||||
"promisepipe": "3.0.0",
|
||||
"proxy": "2.0.0",
|
||||
"proxy-agent": "6.1.1",
|
||||
"proxy-agent": "6.3.0",
|
||||
"psl": "1.1.31",
|
||||
"qr-image": "3.2.0",
|
||||
"raw-body": "2.4.1",
|
||||
@@ -158,7 +158,7 @@
|
||||
"serve-handler": "6.1.1",
|
||||
"strip-ansi": "6.0.1",
|
||||
"stripe": "5.1.0",
|
||||
"supports-hyperlinks": "2.2.0",
|
||||
"supports-hyperlinks": "3.0.0",
|
||||
"tar-fs": "1.16.3",
|
||||
"test-listen": "1.1.0",
|
||||
"text-table": "0.2.0",
|
||||
|
||||
69
packages/cli/src/commands/bisect/command.ts
Normal file
69
packages/cli/src/commands/bisect/command.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { Command } from '../help';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
|
||||
export const bisectCommand: Command = {
|
||||
name: 'bisect',
|
||||
description: 'Bisect the current project interactively.',
|
||||
arguments: [],
|
||||
options: [
|
||||
{
|
||||
name: 'bad',
|
||||
description: 'Known bad URL',
|
||||
argument: 'URL',
|
||||
shorthand: 'b',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'good',
|
||||
description: 'Known good URL',
|
||||
argument: 'URL',
|
||||
shorthand: 'g',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'open',
|
||||
description: 'Automatically open each URL in the browser',
|
||||
argument: 'URL',
|
||||
shorthand: 'o',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'path',
|
||||
description: 'Subpath of the deployment URL to test',
|
||||
argument: 'URL',
|
||||
shorthand: 'p',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'run',
|
||||
description: 'Test script to run for each deployment',
|
||||
argument: 'URL',
|
||||
shorthand: 'r',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
{
|
||||
name: 'Bisect the current project interactively',
|
||||
value: `${getPkgName()} bisect`,
|
||||
},
|
||||
{
|
||||
name: 'Bisect with a known bad deployment',
|
||||
value: `${getPkgName()} bisect --bad example-310pce9i0.vercel.app`,
|
||||
},
|
||||
{
|
||||
name: 'Automated bisect with a run script',
|
||||
value: `${getPkgName()} bisect --run ./test.sh`,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -8,53 +8,19 @@ import { URLSearchParams, parse } from 'url';
|
||||
import box from '../../util/output/box';
|
||||
import formatDate from '../../util/format-date';
|
||||
import link from '../../util/output/link';
|
||||
import logo from '../../util/output/logo';
|
||||
import getArgs from '../../util/get-args';
|
||||
import Client from '../../util/client';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
import { Deployment } from '@vercel-internals/types';
|
||||
import { normalizeURL } from '../../util/bisect/normalize-url';
|
||||
import getScope from '../../util/get-scope';
|
||||
import getDeployment from '../../util/get-deployment';
|
||||
import { help } from '../help';
|
||||
import { bisectCommand } from './command';
|
||||
|
||||
interface Deployments {
|
||||
deployments: Deployment[];
|
||||
}
|
||||
|
||||
const pkgName = getPkgName();
|
||||
|
||||
const help = () => {
|
||||
console.log(`
|
||||
${chalk.bold(`${logo} ${pkgName} bisect`)} [options]
|
||||
|
||||
${chalk.dim('Options:')}
|
||||
|
||||
-h, --help Output usage information
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-b, --bad Known bad URL
|
||||
-g, --good Known good URL
|
||||
-o, --open Automatically open each URL in the browser
|
||||
-p, --path Subpath of the deployment URL to test
|
||||
-r, --run Test script to run for each deployment
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Bisect the current project interactively
|
||||
|
||||
${chalk.cyan(`$ ${pkgName} bisect`)}
|
||||
|
||||
${chalk.gray('–')} Bisect with a known bad deployment
|
||||
|
||||
${chalk.cyan(`$ ${pkgName} bisect --bad example-310pce9i0.vercel.app`)}
|
||||
|
||||
${chalk.gray('–')} Automated bisect with a run script
|
||||
|
||||
${chalk.cyan(`$ ${pkgName} bisect --run ./test.sh`)}
|
||||
`);
|
||||
};
|
||||
|
||||
export default async function main(client: Client): Promise<number> {
|
||||
export default async function bisect(client: Client): Promise<number> {
|
||||
const { output } = client;
|
||||
const scope = await getScope(client);
|
||||
const { contextName } = scope;
|
||||
@@ -73,7 +39,7 @@ export default async function main(client: Client): Promise<number> {
|
||||
});
|
||||
|
||||
if (argv['--help']) {
|
||||
help();
|
||||
output.print(help(bisectCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
46
packages/cli/src/commands/build/command.ts
Normal file
46
packages/cli/src/commands/build/command.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { Command } from '../help';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
|
||||
export const buildCommand: Command = {
|
||||
name: 'build',
|
||||
description: 'Build the project.',
|
||||
arguments: [],
|
||||
options: [
|
||||
{
|
||||
name: 'prod',
|
||||
description: 'Build a production deployment',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'output',
|
||||
description: 'Directory where built assets should be written to',
|
||||
shorthand: null,
|
||||
argument: 'PATH',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'yes',
|
||||
description:
|
||||
'Skip the confirmation prompt about pulling environment variables and project settings when not found locally',
|
||||
shorthand: 'y',
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
{
|
||||
name: 'Build the project',
|
||||
value: `${getPkgName()} build`,
|
||||
},
|
||||
{
|
||||
name: 'Build the project in a specific directory',
|
||||
value: `${getPkgName()} build --cwd ./path-to-project`,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -38,35 +38,37 @@ import {
|
||||
import { fileNameSymbol } from '@vercel/client';
|
||||
import type { VercelConfig } from '@vercel/client';
|
||||
|
||||
import pull from './pull';
|
||||
import { staticFiles as getFiles } from '../util/get-files';
|
||||
import Client from '../util/client';
|
||||
import getArgs from '../util/get-args';
|
||||
import cmd from '../util/output/cmd';
|
||||
import * as cli from '../util/pkg-name';
|
||||
import cliPkg from '../util/pkg';
|
||||
import readJSONFile from '../util/read-json-file';
|
||||
import { CantParseJSONFile } from '../util/errors-ts';
|
||||
import pull from '../pull';
|
||||
import { staticFiles as getFiles } from '../../util/get-files';
|
||||
import Client from '../../util/client';
|
||||
import getArgs from '../../util/get-args';
|
||||
import cmd from '../../util/output/cmd';
|
||||
import * as cli from '../../util/pkg-name';
|
||||
import cliPkg from '../../util/pkg';
|
||||
import readJSONFile from '../../util/read-json-file';
|
||||
import { CantParseJSONFile } from '../../util/errors-ts';
|
||||
import {
|
||||
pickOverrides,
|
||||
ProjectLinkAndSettings,
|
||||
readProjectSettings,
|
||||
} from '../util/projects/project-settings';
|
||||
import { getProjectLink, VERCEL_DIR } from '../util/projects/link';
|
||||
import confirm from '../util/input/confirm';
|
||||
import { emoji, prependEmoji } from '../util/emoji';
|
||||
import stamp from '../util/output/stamp';
|
||||
} from '../../util/projects/project-settings';
|
||||
import { getProjectLink, VERCEL_DIR } from '../../util/projects/link';
|
||||
import confirm from '../../util/input/confirm';
|
||||
import { emoji, prependEmoji } from '../../util/emoji';
|
||||
import stamp from '../../util/output/stamp';
|
||||
import {
|
||||
OUTPUT_DIR,
|
||||
PathOverride,
|
||||
writeBuildResult,
|
||||
} from '../util/build/write-build-result';
|
||||
import { importBuilders } from '../util/build/import-builders';
|
||||
import { initCorepack, cleanupCorepack } from '../util/build/corepack';
|
||||
import { sortBuilders } from '../util/build/sort-builders';
|
||||
import { toEnumerableError } from '../util/error';
|
||||
import { validateConfig } from '../util/validate-config';
|
||||
import { setMonorepoDefaultSettings } from '../util/build/monorepo';
|
||||
} from '../../util/build/write-build-result';
|
||||
import { importBuilders } from '../../util/build/import-builders';
|
||||
import { initCorepack, cleanupCorepack } from '../../util/build/corepack';
|
||||
import { sortBuilders } from '../../util/build/sort-builders';
|
||||
import { toEnumerableError } from '../../util/error';
|
||||
import { validateConfig } from '../../util/validate-config';
|
||||
import { setMonorepoDefaultSettings } from '../../util/build/monorepo';
|
||||
import { help } from '../help';
|
||||
import { buildCommand } from './command';
|
||||
|
||||
type BuildResult = BuildResultV2 | BuildResultV3;
|
||||
|
||||
@@ -103,35 +105,6 @@ export interface BuildsManifest {
|
||||
builds?: SerializedBuilder[];
|
||||
}
|
||||
|
||||
const help = () => {
|
||||
return console.log(`
|
||||
${chalk.bold(`${cli.logo} ${cli.name} 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
|
||||
--output [path] Directory where built assets should be written to
|
||||
--prod Build a production deployment
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-y, --yes Skip the confirmation prompt about pulling environment variables and project settings when not found locally
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('-')} Build the project
|
||||
|
||||
${chalk.cyan(`$ ${cli.name} build`)}
|
||||
${chalk.cyan(`$ ${cli.name} build --cwd ./path-to-project`)}
|
||||
`);
|
||||
};
|
||||
|
||||
export default async function main(client: Client): Promise<number> {
|
||||
let { cwd } = client;
|
||||
const { output } = client;
|
||||
@@ -162,7 +135,7 @@ export default async function main(client: Client): Promise<number> {
|
||||
});
|
||||
|
||||
if (argv['--help']) {
|
||||
help();
|
||||
output.print(help(buildCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -57,12 +57,13 @@ export default async function dev(
|
||||
|
||||
let projectSettings: ProjectSettings | undefined;
|
||||
let envValues: Record<string, string> = {};
|
||||
let repoRoot: string | undefined;
|
||||
if (link.status === 'linked') {
|
||||
const { project, org, repoRoot } = link;
|
||||
const { project, org } = link;
|
||||
|
||||
// If repo linked, update `cwd` to the repo root
|
||||
if (repoRoot) {
|
||||
cwd = repoRoot;
|
||||
if (link.repoRoot) {
|
||||
repoRoot = cwd = link.repoRoot;
|
||||
}
|
||||
|
||||
client.config.currentTeam = org.type === 'team' ? org.id : undefined;
|
||||
@@ -82,6 +83,7 @@ export default async function dev(
|
||||
output,
|
||||
projectSettings,
|
||||
envValues,
|
||||
repoRoot,
|
||||
});
|
||||
|
||||
// listen to SIGTERM for graceful shutdown
|
||||
|
||||
@@ -30,6 +30,86 @@ export interface Command {
|
||||
examples: CommandExample[];
|
||||
}
|
||||
|
||||
const globalCommandOptions: CommandOption[] = [
|
||||
{
|
||||
name: 'help',
|
||||
shorthand: 'h',
|
||||
type: 'string',
|
||||
description: 'Output usage information',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'version',
|
||||
shorthand: 'v',
|
||||
type: 'string',
|
||||
description: 'Output the version number',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'cwd',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
argument: 'DIR',
|
||||
description:
|
||||
'Sets the current working directory for a single run of a command',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'local-config',
|
||||
shorthand: 'A',
|
||||
type: 'string',
|
||||
argument: 'FILE',
|
||||
description: 'Path to the local `vercel.json` file',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'global-config',
|
||||
shorthand: 'Q',
|
||||
type: 'string',
|
||||
argument: 'DIR',
|
||||
description: 'Path to the global `.vercel` directory',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'debug',
|
||||
shorthand: 'd',
|
||||
type: 'string',
|
||||
description: 'Debug mode (default off)',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'no-color',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
description: 'No color mode (default off)',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'scope',
|
||||
shorthand: 'S',
|
||||
type: 'string',
|
||||
description: 'Set a custom scope',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'token',
|
||||
shorthand: 't',
|
||||
type: 'string',
|
||||
argument: 'TOKEN',
|
||||
description: 'Login token',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
];
|
||||
|
||||
export function calcLineLength(line: string[]) {
|
||||
return stripAnsi(lineToString(line)).length;
|
||||
}
|
||||
@@ -52,8 +132,8 @@ export function lineToString(line: string[]) {
|
||||
return string;
|
||||
}
|
||||
|
||||
export function outputArrayToString(outputArray: string[]) {
|
||||
return outputArray.join(NEWLINE);
|
||||
export function outputArrayToString(outputArray: (string | null)[]) {
|
||||
return outputArray.filter(line => line !== null).join(NEWLINE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -62,7 +142,12 @@ export function outputArrayToString(outputArray: string[]) {
|
||||
* @returns
|
||||
*/
|
||||
export function buildCommandSynopsisLine(command: Command) {
|
||||
const line: string[] = [LOGO, chalk.bold(NAME), chalk.bold(command.name)];
|
||||
const line: string[] = [
|
||||
INDENT,
|
||||
LOGO,
|
||||
chalk.bold(NAME),
|
||||
chalk.bold(command.name),
|
||||
];
|
||||
if (command.arguments.length > 0) {
|
||||
for (const argument of command.arguments) {
|
||||
line.push(argument.required ? argument.name : `[${argument.name}]`);
|
||||
@@ -71,32 +156,39 @@ export function buildCommandSynopsisLine(command: Command) {
|
||||
if (command.options.length > 0) {
|
||||
line.push('[options]');
|
||||
}
|
||||
|
||||
line.push(NEWLINE);
|
||||
return lineToString(line);
|
||||
}
|
||||
|
||||
export function buildCommandOptionLines(
|
||||
command: Command,
|
||||
options: BuildHelpOutputOptions
|
||||
commandOptions: CommandOption[],
|
||||
options: BuildHelpOutputOptions,
|
||||
sectionTitle: String
|
||||
) {
|
||||
// Filter out deprecated and intentionally undocumented options
|
||||
command.options = command.options.filter(
|
||||
commandOptions = commandOptions.filter(
|
||||
option => !option.deprecated && option.description !== undefined
|
||||
);
|
||||
|
||||
if (commandOptions.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Initialize output array with header and empty line
|
||||
const outputArray: string[] = [chalk.dim(`Options:`), ''];
|
||||
const outputArray: string[] = [`${INDENT}${chalk.dim(sectionTitle)}:`, ''];
|
||||
|
||||
// Start building option lines
|
||||
const optionLines: string[][] = [];
|
||||
// Sort command options alphabetically
|
||||
command.options.sort((a, b) =>
|
||||
commandOptions.sort((a, b) =>
|
||||
a.name < b.name ? -1 : a.name > b.name ? 1 : 0
|
||||
);
|
||||
// Keep track of longest "start" of an option line to determine description spacing
|
||||
let maxLineStartLength = 0;
|
||||
// Iterate over options and create the "start" of each option (e.g. ` -b, --build-env <key=value>`)
|
||||
for (const option of command.options) {
|
||||
const startLine: string[] = [INDENT];
|
||||
for (const option of commandOptions) {
|
||||
const startLine: string[] = [INDENT, INDENT, INDENT];
|
||||
if (option.shorthand) {
|
||||
startLine.push(`-${option.shorthand},`);
|
||||
}
|
||||
@@ -135,7 +227,7 @@ export function buildCommandOptionLines(
|
||||
*/
|
||||
for (let i = 0; i < optionLines.length; i++) {
|
||||
const optionLine = optionLines[i];
|
||||
const option = command.options[i];
|
||||
const option = commandOptions[i];
|
||||
// Add only 2 spaces to the longest line, and then make all shorter lines the same length.
|
||||
optionLine.push(
|
||||
' '.repeat(2 + (maxLineStartLength - calcLineLength(optionLine)))
|
||||
@@ -162,16 +254,13 @@ export function buildCommandOptionLines(
|
||||
for (const line of lines) {
|
||||
outputArray.push(lineToString(line));
|
||||
}
|
||||
// add an empty line in between in each option block for readability (skip the last block)
|
||||
if (i !== optionLines.length - 1) outputArray.push('');
|
||||
}
|
||||
|
||||
// return the entire list of options as a single string after delete the last '\n' added to the option list
|
||||
return outputArrayToString(outputArray);
|
||||
return `${outputArrayToString(outputArray)}${NEWLINE}`;
|
||||
}
|
||||
|
||||
export function buildCommandExampleLines(command: Command) {
|
||||
const outputArray: string[] = [chalk.dim(`Examples:`), ''];
|
||||
const outputArray: string[] = [`${INDENT}${chalk.dim('Examples:')}`, ''];
|
||||
for (const example of command.examples) {
|
||||
const nameLine: string[] = [INDENT];
|
||||
nameLine.push(chalk.gray('-'));
|
||||
@@ -190,12 +279,15 @@ export function buildCommandExampleLines(command: Command) {
|
||||
}
|
||||
outputArray.push('');
|
||||
}
|
||||
// delete the last newline added after examples iteration
|
||||
outputArray.splice(-1);
|
||||
|
||||
return outputArrayToString(outputArray);
|
||||
}
|
||||
|
||||
function buildDescriptionLine(command: Command) {
|
||||
const line: string[] = [INDENT, command.description, NEWLINE];
|
||||
return lineToString(line);
|
||||
}
|
||||
|
||||
interface BuildHelpOutputOptions {
|
||||
columns: number;
|
||||
}
|
||||
@@ -204,13 +296,12 @@ export function buildHelpOutput(
|
||||
command: Command,
|
||||
options: BuildHelpOutputOptions
|
||||
) {
|
||||
const outputArray: string[] = [
|
||||
const outputArray: (string | null)[] = [
|
||||
'',
|
||||
buildCommandSynopsisLine(command),
|
||||
'',
|
||||
command.description,
|
||||
'',
|
||||
buildCommandOptionLines(command, options),
|
||||
'',
|
||||
buildDescriptionLine(command),
|
||||
buildCommandOptionLines(command.options, options, 'Options'),
|
||||
buildCommandOptionLines(globalCommandOptions, options, 'Global Options'),
|
||||
buildCommandExampleLines(command),
|
||||
'',
|
||||
];
|
||||
|
||||
50
packages/cli/src/commands/inspect/command.ts
Normal file
50
packages/cli/src/commands/inspect/command.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import { Command } from '../help';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
|
||||
export const inspectCommand: Command = {
|
||||
name: 'inspect',
|
||||
description: 'Show information about a deployment.',
|
||||
arguments: [
|
||||
{
|
||||
name: 'url',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'timeout',
|
||||
description: 'Time to wait for deployment completion [3m]',
|
||||
argument: 'TIME',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'wait',
|
||||
description: 'Blocks until deployment completes',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
{
|
||||
name: 'Get information about a deployment by its unique URL',
|
||||
value: `${getPkgName()} inspect my-deployment-ji2fjij2.vercel.app`,
|
||||
},
|
||||
{
|
||||
name: 'Get information about the deployment an alias points to',
|
||||
value: `${getPkgName()} inspect my-deployment.vercel.app`,
|
||||
},
|
||||
{
|
||||
name: 'Get information about a deployment by piping in the URL',
|
||||
value: `echo my-deployment.vercel.app | ${getPkgName()} inspect`,
|
||||
},
|
||||
{
|
||||
name: 'Wait up to 90 seconds for deployment to complete',
|
||||
value: `${getPkgName()} inspect my-deployment.vercel.app --wait --timeout 90s`,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,71 +1,27 @@
|
||||
import chalk from 'chalk';
|
||||
import getArgs from '../util/get-args';
|
||||
import buildsList from '../util/output/builds';
|
||||
import routesList from '../util/output/routes';
|
||||
import indent from '../util/output/indent';
|
||||
import logo from '../util/output/logo';
|
||||
import elapsed from '../util/output/elapsed';
|
||||
import { handleError } from '../util/error';
|
||||
import getScope from '../util/get-scope';
|
||||
import { getPkgName, getCommandName } from '../util/pkg-name';
|
||||
import Client from '../util/client';
|
||||
import getDeployment from '../util/get-deployment';
|
||||
import getArgs from '../../util/get-args';
|
||||
import buildsList from '../../util/output/builds';
|
||||
import routesList from '../../util/output/routes';
|
||||
import indent from '../../util/output/indent';
|
||||
import elapsed from '../../util/output/elapsed';
|
||||
import { handleError } from '../../util/error';
|
||||
import getScope from '../../util/get-scope';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
import Client from '../../util/client';
|
||||
import getDeployment from '../../util/get-deployment';
|
||||
import type { Build, Deployment } from '@vercel-internals/types';
|
||||
import title from 'title';
|
||||
import { isErrnoException } from '@vercel/error-utils';
|
||||
import { URL } from 'url';
|
||||
import readStandardInput from '../util/input/read-standard-input';
|
||||
import sleep from '../util/sleep';
|
||||
import readStandardInput from '../../util/input/read-standard-input';
|
||||
import sleep from '../../util/sleep';
|
||||
import ms from 'ms';
|
||||
import { isDeploying } from '../util/deploy/is-deploying';
|
||||
import { isDeploying } from '../../util/deploy/is-deploying';
|
||||
import { help } from '../help';
|
||||
import { inspectCommand } from './command';
|
||||
|
||||
const help = () => {
|
||||
console.log(`
|
||||
${chalk.bold(`${logo} ${getPkgName()} inspect`)} <url>
|
||||
|
||||
${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
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-S, --scope Set a custom scope
|
||||
--timeout=${chalk.bold.underline(
|
||||
'TIME'
|
||||
)} Time to wait for deployment completion [3m]
|
||||
--wait Blocks until deployment completes
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Get information about a deployment by its unique URL
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} inspect my-deployment-ji2fjij2.vercel.app`)}
|
||||
|
||||
${chalk.gray('-')} Get information about the deployment an alias points to
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} inspect my-deployment.vercel.app`)}
|
||||
|
||||
${chalk.gray('-')} Get information about a deployment by piping in the URL
|
||||
|
||||
${chalk.cyan(`$ echo my-deployment.vercel.app | ${getPkgName()} inspect`)}
|
||||
|
||||
${chalk.gray('-')} Wait up to 90 seconds for deployment to complete
|
||||
|
||||
${chalk.cyan(
|
||||
`$ ${getPkgName()} inspect my-deployment.vercel.app --wait --timeout 90s`
|
||||
)}
|
||||
`);
|
||||
};
|
||||
|
||||
export default async function main(client: Client) {
|
||||
export default async function inspect(client: Client) {
|
||||
const { output } = client;
|
||||
let argv;
|
||||
|
||||
try {
|
||||
@@ -79,7 +35,7 @@ export default async function main(client: Client) {
|
||||
}
|
||||
|
||||
if (argv['--help']) {
|
||||
help();
|
||||
output.print(help(inspectCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -99,7 +55,7 @@ export default async function main(client: Client) {
|
||||
|
||||
if (!deploymentIdOrHost) {
|
||||
error(`${getCommandName('inspect <url>')} expects exactly one argument`);
|
||||
help();
|
||||
output.print(help(inspectCommand, { columns: client.stderr.columns }));
|
||||
return 1;
|
||||
}
|
||||
|
||||
54
packages/cli/src/commands/link/command.ts
Normal file
54
packages/cli/src/commands/link/command.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
import { Command } from '../help';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
|
||||
export const linkCommand: Command = {
|
||||
name: 'link',
|
||||
description: 'Link a local directory to a Vercel Project.',
|
||||
arguments: [],
|
||||
options: [
|
||||
{
|
||||
name: 'repo',
|
||||
description: 'Link multiple projects based on Git repository (alpha)',
|
||||
shorthand: 'r',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'project',
|
||||
description: 'Specify a project name',
|
||||
shorthand: 'p',
|
||||
argument: 'NAME',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'yes',
|
||||
description:
|
||||
'Skip questions when setting up new project using default scope and settings',
|
||||
shorthand: 'y',
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
{
|
||||
name: 'Link current directory to a Vercel Project',
|
||||
value: `${getPkgName()} link`,
|
||||
},
|
||||
{
|
||||
name: 'Link current directory with default options and skip questions',
|
||||
value: `${getPkgName()} link --yes`,
|
||||
},
|
||||
{
|
||||
name: 'Link a specific directory to a Vercel Project',
|
||||
value: `${getPkgName()} link --cwd /path/to/project`,
|
||||
},
|
||||
{
|
||||
name: 'Link to the current Git repository, allowing for multiple Vercel Projects to be linked simultaneously (useful for monorepos)',
|
||||
value: `${getPkgName()} link --repo`,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,62 +1,12 @@
|
||||
import chalk from 'chalk';
|
||||
import Client from '../../util/client';
|
||||
import getArgs from '../../util/get-args';
|
||||
import logo from '../../util/output/logo';
|
||||
import cmd from '../../util/output/cmd';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
import { ensureLink } from '../../util/link/ensure-link';
|
||||
import { ensureRepoLink } from '../../util/link/repo';
|
||||
import { help } from '../help';
|
||||
import { linkCommand } from './command';
|
||||
|
||||
const help = () => {
|
||||
console.log(`
|
||||
${chalk.bold(`${logo} ${getPkgName()} link`)} [options]
|
||||
|
||||
${chalk.dim('Options:')}
|
||||
|
||||
-h, --help Output usage information
|
||||
-r, --repo Link multiple projects based on Git repository (alpha)
|
||||
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
|
||||
'FILE'
|
||||
)} Path to the local ${'`vercel.json`'} file
|
||||
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
-p ${chalk.bold.underline('NAME')}, --project=${chalk.bold.underline(
|
||||
'NAME'
|
||||
)} Project name
|
||||
-y, --yes Skip questions when setting up new project using default scope and settings
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Link current directory to a Vercel Project
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} link`)}
|
||||
|
||||
${chalk.gray(
|
||||
'–'
|
||||
)} Link current directory with default options and skip questions
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} link --yes`)}
|
||||
|
||||
${chalk.gray('–')} Link a specific directory to a Vercel Project
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} link --cwd /path/to/project`)}
|
||||
|
||||
${chalk.gray('–')} ${chalk.yellow(
|
||||
'(alpha)'
|
||||
)} Link to the current Git repository, allowing for multiple
|
||||
Vercel Projects to be linked simultaneously (useful for monorepos)
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} link --repo`)}
|
||||
`);
|
||||
};
|
||||
|
||||
export default async function main(client: Client) {
|
||||
export default async function link(client: Client) {
|
||||
const argv = getArgs(client.argv.slice(2), {
|
||||
'--yes': Boolean,
|
||||
'-y': '--yes',
|
||||
@@ -71,7 +21,7 @@ export default async function main(client: Client) {
|
||||
});
|
||||
|
||||
if (argv['--help']) {
|
||||
help();
|
||||
client.output.print(help(linkCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
61
packages/cli/src/commands/list/command.ts
Normal file
61
packages/cli/src/commands/list/command.ts
Normal file
@@ -0,0 +1,61 @@
|
||||
import { Command } from '../help';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
|
||||
export const listCommand: Command = {
|
||||
name: 'list',
|
||||
description: 'List app deployments for an app.',
|
||||
arguments: [
|
||||
{
|
||||
name: 'app',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'meta',
|
||||
description:
|
||||
'Filter deployments by metadata (e.g.: `-m KEY=value`). Can appear many times.',
|
||||
argument: 'KEY=value',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: true,
|
||||
},
|
||||
{
|
||||
name: 'environment',
|
||||
description: '',
|
||||
argument: 'production|preview',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'next',
|
||||
description: 'Show next page of results',
|
||||
argument: 'MS',
|
||||
shorthand: 'n',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
{
|
||||
name: 'List all deployments for the currently linked project',
|
||||
value: `${getPkgName()} list`,
|
||||
},
|
||||
{
|
||||
name: 'List all deployments for the project `my-app` in the team of the currently linked project',
|
||||
value: `${getPkgName()} list my-app`,
|
||||
},
|
||||
{
|
||||
name: 'Filter deployments by metadata',
|
||||
value: `${getPkgName()} list -m key1=value1 -m key2=value2`,
|
||||
},
|
||||
{
|
||||
name: 'Paginate deployments for a project, where `1584722256178` is the time in milliseconds since the UNIX epoch',
|
||||
value: `${getPkgName()} list my-app --next 1584722256178`,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -2,85 +2,37 @@ import chalk from 'chalk';
|
||||
import ms from 'ms';
|
||||
import table from 'text-table';
|
||||
import title from 'title';
|
||||
import Now from '../util';
|
||||
import getArgs from '../util/get-args';
|
||||
import { handleError } from '../util/error';
|
||||
import logo from '../util/output/logo';
|
||||
import elapsed from '../util/output/elapsed';
|
||||
import strlen from '../util/strlen';
|
||||
import toHost from '../util/to-host';
|
||||
import parseMeta from '../util/parse-meta';
|
||||
import { isValidName } from '../util/is-valid-name';
|
||||
import getCommandFlags from '../util/get-command-flags';
|
||||
import { getPkgName, getCommandName } from '../util/pkg-name';
|
||||
import Client from '../util/client';
|
||||
import Now from '../../util';
|
||||
import getArgs from '../../util/get-args';
|
||||
import { handleError } from '../../util/error';
|
||||
import elapsed from '../../util/output/elapsed';
|
||||
import strlen from '../../util/strlen';
|
||||
import toHost from '../../util/to-host';
|
||||
import parseMeta from '../../util/parse-meta';
|
||||
import { isValidName } from '../../util/is-valid-name';
|
||||
import getCommandFlags from '../../util/get-command-flags';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
import Client from '../../util/client';
|
||||
import { Deployment } from '@vercel/client';
|
||||
import { getLinkedProject } from '../util/projects/link';
|
||||
import { ensureLink } from '../util/link/ensure-link';
|
||||
import getScope from '../util/get-scope';
|
||||
import { isAPIError } from '../util/errors-ts';
|
||||
import { getLinkedProject } from '../../util/projects/link';
|
||||
import { ensureLink } from '../../util/link/ensure-link';
|
||||
import getScope from '../../util/get-scope';
|
||||
import { isAPIError } from '../../util/errors-ts';
|
||||
import { isErrnoException } from '@vercel/error-utils';
|
||||
import { help } from '../help';
|
||||
import { listCommand } from './command';
|
||||
|
||||
const help = () => {
|
||||
console.log(`
|
||||
${chalk.bold(`${logo} ${getPkgName()} list`)} [app]
|
||||
|
||||
${chalk.dim('Options:')}
|
||||
|
||||
-h, --help Output usage information
|
||||
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
|
||||
'FILE'
|
||||
)} Path to the local ${'`vercel.json`'} file
|
||||
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-y, --yes Skip questions when setting up new project using default scope and settings
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
-S, --scope Set a custom scope
|
||||
-m, --meta Filter deployments by metadata (e.g.: ${chalk.dim(
|
||||
'`-m KEY=value`'
|
||||
)}). Can appear many times.
|
||||
--prod Filter for production URLs
|
||||
-N, --next Show next page of results
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} List all deployments for the currently linked project
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} ls`)}
|
||||
|
||||
${chalk.gray('–')} List all deployments for the project ${chalk.dim(
|
||||
'`my-app`'
|
||||
)} in the team of the currently linked project
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} ls my-app`)}
|
||||
|
||||
${chalk.gray('–')} Filter deployments by metadata
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} ls -m key1=value1 -m key2=value2`)}
|
||||
|
||||
${chalk.gray('–')} Paginate deployments for a project, where ${chalk.dim(
|
||||
'`1584722256178`'
|
||||
)} is the time in milliseconds since the UNIX epoch.
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} ls my-app --next 1584722256178`)}
|
||||
`);
|
||||
};
|
||||
|
||||
export default async function main(client: Client) {
|
||||
export default async function list(client: Client) {
|
||||
let argv;
|
||||
|
||||
try {
|
||||
argv = getArgs(client.argv.slice(2), {
|
||||
'--environment': String,
|
||||
'--meta': [String],
|
||||
'-m': '--meta',
|
||||
'--next': Number,
|
||||
'-N': '--next',
|
||||
'--prod': Boolean,
|
||||
'--prod': Boolean, // this can be deprecated someday
|
||||
'--yes': Boolean,
|
||||
'-y': '--yes',
|
||||
|
||||
@@ -108,14 +60,19 @@ export default async function main(client: Client) {
|
||||
}
|
||||
|
||||
if (argv['--help']) {
|
||||
help();
|
||||
output.print(help(listCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
const autoConfirm = !!argv['--yes'];
|
||||
const prod = argv['--prod'] || false;
|
||||
const meta = parseMeta(argv['--meta']);
|
||||
|
||||
const target = argv['--prod']
|
||||
? 'production'
|
||||
: typeof argv['--environment'] === 'string'
|
||||
? argv['--environment'].toLowerCase()
|
||||
: undefined;
|
||||
|
||||
// retrieve `project` and `org` from .vercel
|
||||
let link = await getLinkedProject(client, cwd);
|
||||
|
||||
@@ -219,15 +176,12 @@ export default async function main(client: Client) {
|
||||
|
||||
debug('Fetching deployments');
|
||||
|
||||
const response = await now.list(
|
||||
app,
|
||||
{
|
||||
version: 6,
|
||||
meta,
|
||||
nextTimestamp,
|
||||
},
|
||||
prod
|
||||
);
|
||||
const response = await now.list(app, {
|
||||
version: 6,
|
||||
meta,
|
||||
nextTimestamp,
|
||||
target,
|
||||
});
|
||||
|
||||
let {
|
||||
deployments,
|
||||
@@ -280,9 +234,11 @@ export default async function main(client: Client) {
|
||||
}
|
||||
|
||||
log(
|
||||
`${prod ? `Production deployments` : `Deployments`} for ${chalk.bold(
|
||||
app
|
||||
)} under ${chalk.bold(contextName)} ${elapsed(Date.now() - start)}`
|
||||
`${
|
||||
target === 'production' ? `Production deployments` : `Deployments`
|
||||
} for ${chalk.bold(app)} under ${chalk.bold(contextName)} ${elapsed(
|
||||
Date.now() - start
|
||||
)}`
|
||||
);
|
||||
|
||||
// information to help the user find other deployments or instances
|
||||
@@ -292,8 +248,9 @@ export default async function main(client: Client) {
|
||||
|
||||
print('\n');
|
||||
|
||||
const headers = ['Age', 'Deployment', 'Status', 'Duration'];
|
||||
const headers = ['Age', 'Deployment', 'Status', 'Environment', 'Duration'];
|
||||
if (showUsername) headers.push('Username');
|
||||
const urls: string[] = [];
|
||||
|
||||
client.output.print(
|
||||
`${table(
|
||||
@@ -301,18 +258,17 @@ export default async function main(client: Client) {
|
||||
headers.map(header => chalk.bold(chalk.cyan(header))),
|
||||
...deployments
|
||||
.sort(sortRecent())
|
||||
.map(dep => [
|
||||
[
|
||||
.map(dep => {
|
||||
urls.push(`https://${dep.url}`);
|
||||
return [
|
||||
chalk.gray(ms(Date.now() - dep.createdAt)),
|
||||
`https://${dep.url}`,
|
||||
stateString(dep.state || ''),
|
||||
dep.target === 'production' ? 'Production' : 'Preview',
|
||||
chalk.gray(getDeploymentDuration(dep)),
|
||||
showUsername ? chalk.gray(dep.creator?.username) : '',
|
||||
],
|
||||
])
|
||||
// flatten since the previous step returns a nested
|
||||
// array of the deployment and (optionally) its instances
|
||||
.flat()
|
||||
];
|
||||
})
|
||||
.filter(app =>
|
||||
// if an app wasn't supplied to filter by,
|
||||
// we only want to render one deployment per app
|
||||
@@ -327,6 +283,11 @@ export default async function main(client: Client) {
|
||||
).replace(/^/gm, ' ')}\n\n`
|
||||
);
|
||||
|
||||
if (!client.stdout.isTTY) {
|
||||
client.stdout.write(urls.join('\n'));
|
||||
client.stdout.write('\n');
|
||||
}
|
||||
|
||||
if (pagination && pagination.count === 20) {
|
||||
const flags = getCommandFlags(argv, ['_', '--next']);
|
||||
log(
|
||||
49
packages/cli/src/commands/login/command.ts
Normal file
49
packages/cli/src/commands/login/command.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import { Command } from '../help';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
|
||||
export const loginCommand: Command = {
|
||||
name: 'login',
|
||||
description: 'Authenticate using your email or team id.',
|
||||
arguments: [
|
||||
{
|
||||
name: 'email or team id',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'github',
|
||||
description: 'Log in with GitHub',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'oob',
|
||||
description: 'Log in with "out of band" authentication',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
{
|
||||
name: 'Log into the Vercel platform',
|
||||
value: `${getPkgName()} login`,
|
||||
},
|
||||
{
|
||||
name: 'Log in using a specific email address',
|
||||
value: `${getPkgName()} login username@example.com`,
|
||||
},
|
||||
{
|
||||
name: 'Log in using a specific team "slug" for SAML Single Sign-On',
|
||||
value: `${getPkgName()} login acme`,
|
||||
},
|
||||
{
|
||||
name: 'Log in using GitHub in "out-of-band" mode',
|
||||
value: `${getPkgName()} login --github --oob`,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,55 +1,24 @@
|
||||
import { validate as validateEmail } from 'email-validator';
|
||||
import chalk from 'chalk';
|
||||
import hp from '../util/humanize-path';
|
||||
import getArgs from '../util/get-args';
|
||||
import logo from '../util/output/logo';
|
||||
import prompt from '../util/login/prompt';
|
||||
import doSamlLogin from '../util/login/saml';
|
||||
import doEmailLogin from '../util/login/email';
|
||||
import doGithubLogin from '../util/login/github';
|
||||
import doGitlabLogin from '../util/login/gitlab';
|
||||
import doBitbucketLogin from '../util/login/bitbucket';
|
||||
import { prependEmoji, emoji } from '../util/emoji';
|
||||
import { getCommandName, getPkgName } from '../util/pkg-name';
|
||||
import getGlobalPathConfig from '../util/config/global-path';
|
||||
import { writeToAuthConfigFile, writeToConfigFile } from '../util/config/files';
|
||||
import Client from '../util/client';
|
||||
import { LoginResult } from '../util/login/types';
|
||||
|
||||
const help = () => {
|
||||
console.log(`
|
||||
${chalk.bold(`${logo} ${getPkgName()} login`)} <email or team>
|
||||
|
||||
${chalk.dim('Options:')}
|
||||
|
||||
-h, --help Output usage information
|
||||
--no-color No color mode [off]
|
||||
-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
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Log into the Vercel platform
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} login`)}
|
||||
|
||||
${chalk.gray('–')} Log in using a specific email address
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} login john@doe.com`)}
|
||||
|
||||
${chalk.gray('–')} Log in using a specific team "slug" for SAML Single Sign-On
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} login acme`)}
|
||||
|
||||
${chalk.gray('–')} Log in using GitHub in "out-of-band" mode
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} login --github --oob`)}
|
||||
`);
|
||||
};
|
||||
import hp from '../../util/humanize-path';
|
||||
import getArgs from '../../util/get-args';
|
||||
import prompt from '../../util/login/prompt';
|
||||
import doSamlLogin from '../../util/login/saml';
|
||||
import doEmailLogin from '../../util/login/email';
|
||||
import doGithubLogin from '../../util/login/github';
|
||||
import doGitlabLogin from '../../util/login/gitlab';
|
||||
import doBitbucketLogin from '../../util/login/bitbucket';
|
||||
import { prependEmoji, emoji } from '../../util/emoji';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
import getGlobalPathConfig from '../../util/config/global-path';
|
||||
import {
|
||||
writeToAuthConfigFile,
|
||||
writeToConfigFile,
|
||||
} from '../../util/config/files';
|
||||
import Client from '../../util/client';
|
||||
import { LoginResult } from '../../util/login/types';
|
||||
import { help } from '../help';
|
||||
import { loginCommand } from './command';
|
||||
|
||||
export default async function login(client: Client): Promise<number> {
|
||||
const { output } = client;
|
||||
@@ -62,7 +31,7 @@ export default async function login(client: Client): Promise<number> {
|
||||
});
|
||||
|
||||
if (argv['--help']) {
|
||||
help();
|
||||
output.print(help(loginCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
15
packages/cli/src/commands/logout/command.ts
Normal file
15
packages/cli/src/commands/logout/command.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Command } from '../help';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
|
||||
export const logoutCommand: Command = {
|
||||
name: 'logout',
|
||||
description: 'Logout the current authenticated user or team.',
|
||||
arguments: [],
|
||||
options: [],
|
||||
examples: [
|
||||
{
|
||||
name: 'Logout from the CLI',
|
||||
value: `${getPkgName()} logout`,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,37 +1,19 @@
|
||||
import chalk from 'chalk';
|
||||
import logo from '../util/output/logo';
|
||||
import { handleError } from '../util/error';
|
||||
import { writeToConfigFile, writeToAuthConfigFile } from '../util/config/files';
|
||||
import getArgs from '../util/get-args';
|
||||
import Client from '../util/client';
|
||||
import { getCommandName, getPkgName } from '../util/pkg-name';
|
||||
import { isAPIError } from '../util/errors-ts';
|
||||
import { handleError } from '../../util/error';
|
||||
import {
|
||||
writeToConfigFile,
|
||||
writeToAuthConfigFile,
|
||||
} from '../../util/config/files';
|
||||
import getArgs from '../../util/get-args';
|
||||
import Client from '../../util/client';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
import { isAPIError } from '../../util/errors-ts';
|
||||
import { errorToString } from '@vercel/error-utils';
|
||||
|
||||
const help = () => {
|
||||
console.log(`
|
||||
${chalk.bold(`${logo} ${getPkgName()} logout`)}
|
||||
|
||||
${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
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Logout from the CLI:
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} logout`)}
|
||||
`);
|
||||
};
|
||||
import { help } from '../help';
|
||||
import { logoutCommand } from './command';
|
||||
|
||||
export default async function main(client: Client): Promise<number> {
|
||||
let argv;
|
||||
const { authConfig, config, output } = client;
|
||||
|
||||
try {
|
||||
argv = getArgs(client.argv.slice(2), {
|
||||
@@ -44,12 +26,10 @@ export default async function main(client: Client): Promise<number> {
|
||||
}
|
||||
|
||||
if (argv['--help']) {
|
||||
help();
|
||||
output.print(help(logoutCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
const { authConfig, config, output } = client;
|
||||
|
||||
if (!authConfig.token) {
|
||||
output.note(
|
||||
`Not currently logged in, so ${getCommandName('logout')} did nothing`
|
||||
66
packages/cli/src/commands/logs/command.ts
Normal file
66
packages/cli/src/commands/logs/command.ts
Normal file
@@ -0,0 +1,66 @@
|
||||
import { Command } from '../help';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
|
||||
export const logsCommand: Command = {
|
||||
name: 'logs',
|
||||
description: 'Display logs for a specific deployment.',
|
||||
arguments: [
|
||||
{
|
||||
name: 'url|deploymentId',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'follow',
|
||||
shorthand: 'f',
|
||||
description: 'Wait for additional data [off]',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'limit',
|
||||
shorthand: 'n',
|
||||
description: 'Number of log entries [100]',
|
||||
argument: 'NUMBER',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'since',
|
||||
shorthand: null,
|
||||
description: 'Only return logs after date (ISO 8601)',
|
||||
argument: 'SINCE',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'until',
|
||||
shorthand: null,
|
||||
description:
|
||||
'Only return logs before date (ISO 8601), ignored when used with --follow',
|
||||
argument: 'UNTIL',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'output',
|
||||
shorthand: 'o',
|
||||
description: `Specify the output format (short|raw) [short]`,
|
||||
argument: 'MODE',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
{
|
||||
name: 'Print the logs for the deployment DEPLOYMENT_ID',
|
||||
value: `${getPkgName()} logs DEPLOYMENT_ID`,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,60 +1,15 @@
|
||||
import chalk from 'chalk';
|
||||
import logo from '../util/output/logo';
|
||||
import elapsed from '../util/output/elapsed';
|
||||
import { maybeURL, normalizeURL } from '../util/url';
|
||||
import printEvents, { DeploymentEvent } from '../util/events';
|
||||
import getScope from '../util/get-scope';
|
||||
import { getPkgName } from '../util/pkg-name';
|
||||
import getArgs from '../util/get-args';
|
||||
import Client from '../util/client';
|
||||
import getDeployment from '../util/get-deployment';
|
||||
import elapsed from '../../util/output/elapsed';
|
||||
import { maybeURL, normalizeURL } from '../../util/url';
|
||||
import printEvents, { DeploymentEvent } from '../../util/events';
|
||||
import getScope from '../../util/get-scope';
|
||||
import getArgs from '../../util/get-args';
|
||||
import Client from '../../util/client';
|
||||
import getDeployment from '../../util/get-deployment';
|
||||
import { help } from '../help';
|
||||
import { logsCommand } from './command';
|
||||
|
||||
const help = () => {
|
||||
console.log(`
|
||||
${chalk.bold(`${logo} ${getPkgName()} logs`)} <url|deploymentId>
|
||||
|
||||
${chalk.dim('Options:')}
|
||||
|
||||
-h, --help Output usage information
|
||||
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
|
||||
'FILE'
|
||||
)} Path to the local ${'`vercel.json`'} file
|
||||
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-f, --follow Wait for additional data [off]
|
||||
-n ${chalk.bold.underline(
|
||||
'NUMBER'
|
||||
)} Number of logs [100]
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
--since=${chalk.bold.underline(
|
||||
'SINCE'
|
||||
)} Only return logs after date (ISO 8601)
|
||||
--until=${chalk.bold.underline(
|
||||
'UNTIL'
|
||||
)} Only return logs before date (ISO 8601), ignored for ${'`-f`'}
|
||||
-S, --scope Set a custom scope
|
||||
-o ${chalk.bold.underline('MODE')}, --output=${chalk.bold.underline(
|
||||
'MODE'
|
||||
)} Specify the output format (${Object.keys(logPrinters).join(
|
||||
'|'
|
||||
)}) [short]
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Print the logs for the deployment ${chalk.dim(
|
||||
'`deploymentId`'
|
||||
)}
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} logs deploymentId`)}
|
||||
`);
|
||||
};
|
||||
|
||||
export default async function main(client: Client) {
|
||||
export default async function logs(client: Client) {
|
||||
let head;
|
||||
let limit;
|
||||
let follow;
|
||||
@@ -76,14 +31,13 @@ export default async function main(client: Client) {
|
||||
|
||||
argv._ = argv._.slice(1);
|
||||
deploymentIdOrURL = argv._[0];
|
||||
const { output } = client;
|
||||
|
||||
if (argv['--help'] || !deploymentIdOrURL || deploymentIdOrURL === 'help') {
|
||||
help();
|
||||
output.print(help(logsCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
const { output } = client;
|
||||
|
||||
try {
|
||||
since = argv['--since'] ? toTimestamp(argv['--since']) : 0;
|
||||
} catch (err) {
|
||||
@@ -38,6 +38,10 @@ export default async function rm(client: Client, args: string[]) {
|
||||
client.output.error('No such project exists');
|
||||
return 1;
|
||||
}
|
||||
if (isAPIError(err) && err.status === 403) {
|
||||
client.output.error(err.message);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
const elapsed = ms(Date.now() - start);
|
||||
client.output.log(
|
||||
|
||||
53
packages/cli/src/commands/pull/command.ts
Normal file
53
packages/cli/src/commands/pull/command.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Command } from '../help';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
import { getEnvTargetPlaceholder } from '../../util/env/env-target';
|
||||
|
||||
export const pullCommand: Command = {
|
||||
name: 'pull',
|
||||
description:
|
||||
'Pull latest environment variables and project settings from Vercel. ',
|
||||
arguments: [
|
||||
{
|
||||
name: 'project-path',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'environment',
|
||||
description: 'Deployment environment [development]',
|
||||
argument: 'environment',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'yes',
|
||||
description:
|
||||
'Skip questions when setting up new project using default scope and settings',
|
||||
shorthand: 'y',
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
{
|
||||
name: 'Pull the latest Environment Variables and Project Settings from the cloud',
|
||||
value: `${getPkgName()} pull`,
|
||||
},
|
||||
{
|
||||
name: 'Pull the latest Environment Variables and Project Settings from the cloud targeting a directory',
|
||||
value: `${getPkgName()} pull ./path-to-project`,
|
||||
},
|
||||
{
|
||||
name: 'Pull for a specific environment',
|
||||
value: `${getPkgName()} pull --environment=${getEnvTargetPlaceholder()}`,
|
||||
},
|
||||
{
|
||||
name: 'If you want to download environment variables to a specific file, use `vercel env pull` instead',
|
||||
value: `${getPkgName()} env pull`,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,65 +1,26 @@
|
||||
import chalk from 'chalk';
|
||||
import { join } from 'path';
|
||||
import Client from '../util/client';
|
||||
import Client from '../../util/client';
|
||||
import type {
|
||||
Project,
|
||||
ProjectEnvTarget,
|
||||
ProjectLinked,
|
||||
} from '@vercel-internals/types';
|
||||
import { emoji, prependEmoji } from '../util/emoji';
|
||||
import getArgs from '../util/get-args';
|
||||
import logo from '../util/output/logo';
|
||||
import stamp from '../util/output/stamp';
|
||||
import { getPkgName } from '../util/pkg-name';
|
||||
import { VERCEL_DIR, VERCEL_DIR_PROJECT } from '../util/projects/link';
|
||||
import { writeProjectSettings } from '../util/projects/project-settings';
|
||||
import envPull from './env/pull';
|
||||
import { emoji, prependEmoji } from '../../util/emoji';
|
||||
import getArgs from '../../util/get-args';
|
||||
import stamp from '../../util/output/stamp';
|
||||
import { VERCEL_DIR, VERCEL_DIR_PROJECT } from '../../util/projects/link';
|
||||
import { writeProjectSettings } from '../../util/projects/project-settings';
|
||||
import envPull from '../env/pull';
|
||||
import {
|
||||
isValidEnvTarget,
|
||||
getEnvTargetPlaceholder,
|
||||
} from '../util/env/env-target';
|
||||
import { ensureLink } from '../util/link/ensure-link';
|
||||
import humanizePath from '../util/humanize-path';
|
||||
} from '../../util/env/env-target';
|
||||
import { ensureLink } from '../../util/link/ensure-link';
|
||||
import humanizePath from '../../util/humanize-path';
|
||||
|
||||
const help = () => {
|
||||
return console.log(`
|
||||
${chalk.bold(`${logo} ${getPkgName()} pull`)} [project-path]
|
||||
|
||||
${chalk.dim('Options:')}
|
||||
|
||||
-h, --help Output usage information
|
||||
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
|
||||
'FILE'
|
||||
)} Path to the local ${'`vercel.json`'} file
|
||||
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
--environment [environment] Deployment environment [development]
|
||||
-y, --yes Skip questions when setting up new project using default scope and settings
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray(
|
||||
'–'
|
||||
)} Pull the latest Environment Variables and Project Settings from the cloud
|
||||
and stores them in \`.vercel/.env.\${target}.local\` and \`.vercel/project.json\` respectively.
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} pull`)}
|
||||
${chalk.cyan(`$ ${getPkgName()} pull ./path-to-project`)}
|
||||
|
||||
${chalk.gray('–')} Pull for a specific environment
|
||||
|
||||
${chalk.cyan(
|
||||
`$ ${getPkgName()} pull --environment=${getEnvTargetPlaceholder()}`
|
||||
)}
|
||||
|
||||
${chalk.gray(
|
||||
'If you want to download environment variables to a specific file, use `vercel env pull` instead.'
|
||||
)}
|
||||
`);
|
||||
};
|
||||
import { help } from '../help';
|
||||
import { pullCommand } from './command';
|
||||
|
||||
function processArgs(client: Client) {
|
||||
return getArgs(client.argv.slice(2), {
|
||||
@@ -76,7 +37,7 @@ function parseArgs(client: Client) {
|
||||
const argv = processArgs(client);
|
||||
|
||||
if (argv['--help']) {
|
||||
help();
|
||||
client.output.print(help(pullCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
33
packages/cli/src/commands/redeploy/command.ts
Normal file
33
packages/cli/src/commands/redeploy/command.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Command } from '../help';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
|
||||
export const redeployCommand: Command = {
|
||||
name: 'redeploy',
|
||||
description: 'Rebuild and deploy a previous deployment.',
|
||||
arguments: [
|
||||
{
|
||||
name: 'deploymentId|deploymentName',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'no-wait',
|
||||
shorthand: null,
|
||||
description: "Don't wait for the redeploy to finish",
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
{
|
||||
name: 'Rebuild and deploy an existing deployment using id or url',
|
||||
value: `${getPkgName()} redeploy my-deployment.vercel.app`,
|
||||
},
|
||||
{
|
||||
name: 'Write Deployment URL to a file',
|
||||
value: `${getPkgName()} redeploy my-deployment.vercel.app > deployment-url.txt`,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,66 +1,29 @@
|
||||
import chalk from 'chalk';
|
||||
import { checkDeploymentStatus } from '@vercel/client';
|
||||
import type Client from '../util/client';
|
||||
import { emoji, prependEmoji } from '../util/emoji';
|
||||
import getArgs from '../util/get-args';
|
||||
import { getCommandName, getPkgName } from '../util/pkg-name';
|
||||
import { getDeploymentByIdOrURL } from '../util/deploy/get-deployment-by-id-or-url';
|
||||
import getScope from '../util/get-scope';
|
||||
import handleError from '../util/handle-error';
|
||||
import type Client from '../../util/client';
|
||||
import { emoji, prependEmoji } from '../../util/emoji';
|
||||
import getArgs from '../../util/get-args';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
import { getDeploymentByIdOrURL } from '../../util/deploy/get-deployment-by-id-or-url';
|
||||
import getScope from '../../util/get-scope';
|
||||
import handleError from '../../util/handle-error';
|
||||
import { isErrnoException } from '@vercel/error-utils';
|
||||
import logo from '../util/output/logo';
|
||||
import Now from '../util';
|
||||
import { printDeploymentStatus } from '../util/deploy/print-deployment-status';
|
||||
import stamp from '../util/output/stamp';
|
||||
import ua from '../util/ua';
|
||||
import Now from '../../util';
|
||||
import { printDeploymentStatus } from '../../util/deploy/print-deployment-status';
|
||||
import stamp from '../../util/output/stamp';
|
||||
import ua from '../../util/ua';
|
||||
import type { VercelClientOptions } from '@vercel/client';
|
||||
|
||||
const help = () => {
|
||||
console.log(`
|
||||
${chalk.bold(
|
||||
`${logo} ${getPkgName()} redeploy`
|
||||
)} [deploymentId|deploymentName]
|
||||
|
||||
Rebuild and deploy a previous deployment.
|
||||
|
||||
${chalk.dim('Options:')}
|
||||
|
||||
-h, --help Output usage information
|
||||
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
|
||||
'FILE'
|
||||
)} Path to the local ${'`vercel.json`'} file
|
||||
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
--no-wait Don't wait for the redeploy to finish
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
-y, --yes Skip questions when setting up new project using default scope and settings
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Rebuild and deploy an existing deployment using id or url
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} redeploy my-deployment.vercel.app`)}
|
||||
|
||||
${chalk.gray('–')} Write Deployment URL to a file
|
||||
|
||||
${chalk.cyan(
|
||||
`$ ${getPkgName()} redeploy my-deployment.vercel.app > deployment-url.txt`
|
||||
)}
|
||||
`);
|
||||
};
|
||||
import { help } from '../help';
|
||||
import { redeployCommand } from './command';
|
||||
|
||||
/**
|
||||
* `vc redeploy` command
|
||||
* @param {Client} client
|
||||
* @returns {Promise<number>} Resolves an exit code; 0 on success
|
||||
*/
|
||||
export default async (client: Client): Promise<number> => {
|
||||
export default async function redeploy(client: Client): Promise<number> {
|
||||
let argv;
|
||||
const { output } = client;
|
||||
try {
|
||||
argv = getArgs(client.argv.slice(2), {
|
||||
'--no-wait': Boolean,
|
||||
@@ -73,11 +36,10 @@ export default async (client: Client): Promise<number> => {
|
||||
}
|
||||
|
||||
if (argv['--help'] || argv._[0] === 'help') {
|
||||
help();
|
||||
output.print(help(redeployCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
const { output } = client;
|
||||
const deployIdOrUrl = argv._[1];
|
||||
if (!deployIdOrUrl) {
|
||||
output.error(
|
||||
@@ -108,7 +70,7 @@ export default async (client: Client): Promise<number> => {
|
||||
action: 'redeploy',
|
||||
},
|
||||
name: fromDeployment.name,
|
||||
target: fromDeployment.target,
|
||||
target: fromDeployment.target ?? undefined,
|
||||
},
|
||||
method: 'POST',
|
||||
});
|
||||
@@ -201,4 +163,4 @@ export default async (client: Client): Promise<number> => {
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
45
packages/cli/src/commands/remove/command.ts
Normal file
45
packages/cli/src/commands/remove/command.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { Command } from '../help';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
|
||||
export const removeCommand: Command = {
|
||||
name: 'remove',
|
||||
description: 'Remove a deployment by name or id.',
|
||||
arguments: [
|
||||
{
|
||||
name: '...deploymentId|deploymentName',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'yes',
|
||||
shorthand: 'y',
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
description: 'Skip confirmation',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'safe',
|
||||
shorthand: 's',
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
description: 'Skip deployments with an active alias',
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
{
|
||||
name: 'Remove a deployment identified by `deploymentId`',
|
||||
value: `${getPkgName()} remove my-app`,
|
||||
},
|
||||
{
|
||||
name: 'Remove all deployments with name `my-app`',
|
||||
value: `${getPkgName()} remove deploymentId`,
|
||||
},
|
||||
{
|
||||
name: 'Remove two deployments with IDs `eyWt6zuSdeus` and `uWHoA9RQ1d1o`',
|
||||
value: `${getPkgName()} remove eyWt6zuSdeus uWHoA9RQ1d1o`,
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -2,74 +2,31 @@ import chalk from 'chalk';
|
||||
import ms from 'ms';
|
||||
import plural from 'pluralize';
|
||||
import table from 'text-table';
|
||||
import Now from '../util';
|
||||
import getAliases from '../util/alias/get-aliases';
|
||||
import logo from '../util/output/logo';
|
||||
import elapsed from '../util/output/elapsed';
|
||||
import { normalizeURL } from '../util/url';
|
||||
import getScope from '../util/get-scope';
|
||||
import { isValidName } from '../util/is-valid-name';
|
||||
import removeProject from '../util/projects/remove-project';
|
||||
import getProjectByIdOrName from '../util/projects/get-project-by-id-or-name';
|
||||
import getDeployment from '../util/get-deployment';
|
||||
import getDeploymentsByProjectId from '../util/deploy/get-deployments-by-project-id';
|
||||
import { getPkgName, getCommandName } from '../util/pkg-name';
|
||||
import getArgs from '../util/get-args';
|
||||
import handleError from '../util/handle-error';
|
||||
import type Client from '../util/client';
|
||||
import { Output } from '../util/output';
|
||||
import Now from '../../util';
|
||||
import getAliases from '../../util/alias/get-aliases';
|
||||
import elapsed from '../../util/output/elapsed';
|
||||
import { normalizeURL } from '../../util/url';
|
||||
import getScope from '../../util/get-scope';
|
||||
import { isValidName } from '../../util/is-valid-name';
|
||||
import removeProject from '../../util/projects/remove-project';
|
||||
import getProjectByIdOrName from '../../util/projects/get-project-by-id-or-name';
|
||||
import getDeployment from '../../util/get-deployment';
|
||||
import getDeploymentsByProjectId from '../../util/deploy/get-deployments-by-project-id';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
import getArgs from '../../util/get-args';
|
||||
import handleError from '../../util/handle-error';
|
||||
import type Client from '../../util/client';
|
||||
import { Output } from '../../util/output';
|
||||
import { Alias, Deployment, Project } from '@vercel-internals/types';
|
||||
import { NowError } from '../util/now-error';
|
||||
import { NowError } from '../../util/now-error';
|
||||
import { help } from '../help';
|
||||
import { removeCommand } from './command';
|
||||
|
||||
type DeploymentWithAliases = Deployment & {
|
||||
aliases: Alias[];
|
||||
};
|
||||
|
||||
const help = () => {
|
||||
console.log(`
|
||||
${chalk.bold(
|
||||
`${logo} ${getPkgName()} remove`
|
||||
)} [...deploymentId|deploymentName]
|
||||
|
||||
${chalk.dim('Options:')}
|
||||
|
||||
-h, --help Output usage information
|
||||
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
|
||||
'FILE'
|
||||
)} Path to the local ${'`vercel.json`'} file
|
||||
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
-y, --yes Skip confirmation
|
||||
-s, --safe Skip deployments with an active alias
|
||||
-S, --scope Set a custom scope
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Remove a deployment identified by ${chalk.dim(
|
||||
'`deploymentId`'
|
||||
)}
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} rm deploymentId`)}
|
||||
|
||||
${chalk.gray('–')} Remove all deployments with name ${chalk.dim('`my-app`')}
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} rm my-app`)}
|
||||
|
||||
${chalk.gray('–')} Remove two deployments with IDs ${chalk.dim(
|
||||
'`eyWt6zuSdeus`'
|
||||
)} and ${chalk.dim('`uWHoA9RQ1d1o`')}
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} rm eyWt6zuSdeus uWHoA9RQ1d1o`)}
|
||||
`);
|
||||
};
|
||||
|
||||
export default async function main(client: Client) {
|
||||
export default async function remove(client: Client) {
|
||||
let argv;
|
||||
|
||||
try {
|
||||
@@ -98,13 +55,13 @@ export default async function main(client: Client) {
|
||||
const { success, error, log } = output;
|
||||
|
||||
if (argv['--help'] || ids[0] === 'help') {
|
||||
help();
|
||||
output.print(help(removeCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (ids.length < 1) {
|
||||
error(`${getCommandName('rm')} expects at least one argument`);
|
||||
help();
|
||||
output.print(help(removeCommand, { columns: client.stderr.columns }));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
import chalk from 'chalk';
|
||||
import logo from '../util/output/logo';
|
||||
import getScope from '../util/get-scope';
|
||||
import { getPkgName } from '../util/pkg-name';
|
||||
import getArgs from '../util/get-args';
|
||||
import Client from '../util/client';
|
||||
|
||||
const help = () => {
|
||||
console.log(`
|
||||
${chalk.bold(`${logo} ${getPkgName()} whoami`)}
|
||||
|
||||
${chalk.dim('Options:')}
|
||||
|
||||
-h, --help Output usage information
|
||||
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
|
||||
'FILE'
|
||||
)} Path to the local ${'`vercel.json`'} file
|
||||
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Shows the username of the currently logged in user
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} whoami`)}
|
||||
`);
|
||||
};
|
||||
|
||||
export default async (client: Client): Promise<number> => {
|
||||
const { output } = client;
|
||||
const argv = getArgs(client.argv.slice(2), {});
|
||||
argv._ = argv._.slice(1);
|
||||
|
||||
if (argv['--help'] || argv._[0] === 'help') {
|
||||
help();
|
||||
return 2;
|
||||
}
|
||||
|
||||
const { contextName } = await getScope(client, { getTeam: false });
|
||||
|
||||
if (client.stdout.isTTY) {
|
||||
output.log(contextName);
|
||||
} else {
|
||||
// If stdout is not a TTY, then only print the username
|
||||
// to support piping the output to another file / exe
|
||||
client.stdout.write(`${contextName}\n`);
|
||||
}
|
||||
|
||||
return 0;
|
||||
};
|
||||
15
packages/cli/src/commands/whoami/command.ts
Normal file
15
packages/cli/src/commands/whoami/command.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { Command } from '../help';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
|
||||
export const whoamiCommand: Command = {
|
||||
name: 'whoami',
|
||||
description: 'Shows the username of the currently logged in user.',
|
||||
arguments: [],
|
||||
options: [],
|
||||
examples: [
|
||||
{
|
||||
name: 'Shows the username of the currently logged in user',
|
||||
value: `${getPkgName()} whoami`,
|
||||
},
|
||||
],
|
||||
};
|
||||
29
packages/cli/src/commands/whoami/index.ts
Normal file
29
packages/cli/src/commands/whoami/index.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { help } from '../help';
|
||||
import { whoamiCommand } from './command';
|
||||
|
||||
import getScope from '../../util/get-scope';
|
||||
import getArgs from '../../util/get-args';
|
||||
import Client from '../../util/client';
|
||||
|
||||
export default async function whoami(client: Client): Promise<number> {
|
||||
const { output } = client;
|
||||
const argv = getArgs(client.argv.slice(2), {});
|
||||
argv._ = argv._.slice(1);
|
||||
|
||||
if (argv['--help'] || argv._[0] === 'help') {
|
||||
output.print(help(whoamiCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
const { contextName } = await getScope(client, { getTeam: false });
|
||||
|
||||
if (client.stdout.isTTY) {
|
||||
output.log(contextName);
|
||||
} else {
|
||||
// If stdout is not a TTY, then only print the username
|
||||
// to support piping the output to another file / exe
|
||||
client.stdout.write(`${contextName}\n`);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -146,7 +146,8 @@ export default class Client extends EventEmitter implements Stdio {
|
||||
if (!res.ok) {
|
||||
const error = await responseError(res);
|
||||
|
||||
if (isSAMLError(error)) {
|
||||
// we should force reauth only if error has a teamId
|
||||
if (isSAMLError(error) && error.teamId) {
|
||||
try {
|
||||
// A SAML error means the token is expired, or is not
|
||||
// designated for the requested team, so the user needs
|
||||
|
||||
@@ -234,6 +234,10 @@ export default async function processDeployment({
|
||||
return error;
|
||||
}
|
||||
|
||||
if (error.code === 'forbidden') {
|
||||
return error;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
Builder,
|
||||
cloneEnv,
|
||||
Env,
|
||||
getNodeBinPath,
|
||||
getNodeBinPaths,
|
||||
StartDevServerResult,
|
||||
FileFsRef,
|
||||
PackageJson,
|
||||
@@ -124,6 +124,7 @@ function sortBuilders(buildA: Builder, buildB: Builder) {
|
||||
|
||||
export default class DevServer {
|
||||
public cwd: string;
|
||||
public repoRoot: string;
|
||||
public output: Output;
|
||||
public proxy: httpProxy;
|
||||
public envConfigs: EnvConfigs;
|
||||
@@ -169,6 +170,7 @@ export default class DevServer {
|
||||
|
||||
constructor(cwd: string, options: DevServerOptions) {
|
||||
this.cwd = cwd;
|
||||
this.repoRoot = options.repoRoot ?? cwd;
|
||||
this.output = options.output;
|
||||
this.envConfigs = { buildEnv: {}, runEnv: {}, allEnv: {} };
|
||||
this.envValues = options.envValues || {};
|
||||
@@ -1412,7 +1414,7 @@ export default class DevServer {
|
||||
files,
|
||||
entrypoint: middleware.entrypoint,
|
||||
workPath,
|
||||
repoRootPath: this.cwd,
|
||||
repoRootPath: this.repoRoot,
|
||||
config: middleware.config || {},
|
||||
meta: {
|
||||
isDev: true,
|
||||
@@ -1849,7 +1851,7 @@ export default class DevServer {
|
||||
entrypoint: match.entrypoint,
|
||||
workPath,
|
||||
config: match.config || {},
|
||||
repoRootPath: this.cwd,
|
||||
repoRootPath: this.repoRoot,
|
||||
meta: {
|
||||
isDev: true,
|
||||
requestPath,
|
||||
@@ -2237,7 +2239,8 @@ export default class DevServer {
|
||||
);
|
||||
|
||||
// add the node_modules/.bin directory to the PATH
|
||||
const nodeBinPath = await getNodeBinPath({ cwd });
|
||||
const nodeBinPaths = getNodeBinPaths({ base: this.repoRoot, start: cwd });
|
||||
const nodeBinPath = nodeBinPaths.join(path.delimiter);
|
||||
env.PATH = `${nodeBinPath}${path.delimiter}${env.PATH}`;
|
||||
|
||||
// This is necesary so that the dev command in the Project
|
||||
|
||||
@@ -25,6 +25,7 @@ export interface DevServerOptions {
|
||||
output: Output;
|
||||
projectSettings?: ProjectSettings;
|
||||
envValues?: Record<string, string>;
|
||||
repoRoot?: string;
|
||||
}
|
||||
|
||||
export interface EnvConfigs {
|
||||
|
||||
@@ -61,6 +61,7 @@ export interface ListOptions {
|
||||
version?: number;
|
||||
meta?: Dictionary<string>;
|
||||
nextTimestamp?: number;
|
||||
target?: string;
|
||||
}
|
||||
|
||||
export default class Now extends EventEmitter {
|
||||
@@ -339,7 +340,7 @@ export default class Now extends EventEmitter {
|
||||
|
||||
async list(
|
||||
app?: string,
|
||||
{ version = 4, meta = {}, nextTimestamp }: ListOptions = {},
|
||||
{ version = 4, meta = {}, nextTimestamp, target }: ListOptions = {},
|
||||
prod?: boolean
|
||||
) {
|
||||
const fetchRetry = async (url: string, options: FetchOptions = {}) => {
|
||||
@@ -405,6 +406,8 @@ export default class Now extends EventEmitter {
|
||||
}
|
||||
if (prod) {
|
||||
query.set('target', 'production');
|
||||
} else if (target) {
|
||||
query.set('target', target);
|
||||
}
|
||||
|
||||
const response = await fetchRetry(`/v${version}/now/deployments?${query}`);
|
||||
|
||||
@@ -15,6 +15,7 @@ import { emoji, prependEmoji } from '../emoji';
|
||||
import selectOrg from '../input/select-org';
|
||||
import { addToGitIgnore } from './add-to-gitignore';
|
||||
import type Client from '../client';
|
||||
import type { Framework } from '@vercel/frameworks';
|
||||
import type { Project } from '@vercel-internals/types';
|
||||
import createProject from '../projects/create-project';
|
||||
import { detectProjects } from '../projects/detect-projects';
|
||||
@@ -90,7 +91,7 @@ export async function ensureRepoLink(
|
||||
// they will be ready by the time the projects are listed
|
||||
const detectedProjectsPromise = detectProjects(rootPath).catch(err => {
|
||||
output.debug(`Failed to detect local projects: ${err}`);
|
||||
return new Map<string, string>();
|
||||
return new Map<string, Framework[]>();
|
||||
});
|
||||
|
||||
// Not yet linked, so prompt user to begin linking
|
||||
@@ -187,17 +188,21 @@ export async function ensureRepoLink(
|
||||
detectedProjects.delete(project.rootDirectory ?? '');
|
||||
}
|
||||
|
||||
if (detectedProjects.size > 0) {
|
||||
const detectedProjectsCount = Array.from(detectedProjects.values()).reduce(
|
||||
(o, f) => o + f.length,
|
||||
0
|
||||
);
|
||||
if (detectedProjectsCount > 0) {
|
||||
output.log(
|
||||
`Detected ${pluralize(
|
||||
'new Project',
|
||||
detectedProjects.size,
|
||||
detectedProjectsCount,
|
||||
true
|
||||
)} that may be created.`
|
||||
);
|
||||
}
|
||||
|
||||
const addSeparators = projects.length > 0 && detectedProjects.size > 0;
|
||||
const addSeparators = projects.length > 0 && detectedProjectsCount > 0;
|
||||
const { selected } = await client.prompt({
|
||||
type: 'checkbox',
|
||||
name: 'selected',
|
||||
@@ -218,23 +223,30 @@ export async function ensureRepoLink(
|
||||
...(addSeparators
|
||||
? [new inquirer.Separator('----- New Projects to be created -----')]
|
||||
: []),
|
||||
...Array.from(detectedProjects.entries()).map(
|
||||
([rootDirectory, framework]) => {
|
||||
const name = slugify(
|
||||
[basename(rootPath), basename(rootDirectory)]
|
||||
.filter(Boolean)
|
||||
.join('-')
|
||||
);
|
||||
return {
|
||||
name: `${org.slug}/${name} (${framework})`,
|
||||
value: {
|
||||
newProject: true,
|
||||
rootDirectory,
|
||||
name,
|
||||
framework,
|
||||
},
|
||||
};
|
||||
}
|
||||
...Array.from(detectedProjects.entries()).flatMap(
|
||||
([rootDirectory, frameworks]) =>
|
||||
frameworks.map((framework, i) => {
|
||||
const name = slugify(
|
||||
[
|
||||
basename(rootPath),
|
||||
basename(rootDirectory),
|
||||
i > 0 ? framework.slug : '',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join('-')
|
||||
);
|
||||
return {
|
||||
name: `${org.slug}/${name} (${framework.name})`,
|
||||
value: {
|
||||
newProject: true,
|
||||
rootDirectory,
|
||||
name,
|
||||
framework,
|
||||
},
|
||||
// Checked by default when there are no other existing Projects
|
||||
checked: projects.length === 0,
|
||||
};
|
||||
})
|
||||
),
|
||||
],
|
||||
});
|
||||
@@ -251,7 +263,10 @@ export async function ensureRepoLink(
|
||||
output.spinner(`Creating new Project: ${orgAndName}`);
|
||||
delete selection.newProject;
|
||||
if (!selection.rootDirectory) delete selection.rootDirectory;
|
||||
selected[i] = await createProject(client, selection);
|
||||
selected[i] = await createProject(client, {
|
||||
...selection,
|
||||
framework: selection.framework.slug,
|
||||
});
|
||||
await connectGitProvider(
|
||||
client,
|
||||
org,
|
||||
@@ -262,7 +277,8 @@ export async function ensureRepoLink(
|
||||
output.log(
|
||||
`Created new Project: ${output.link(
|
||||
orgAndName,
|
||||
`https://vercel.com/${orgAndName}`
|
||||
`https://vercel.com/${orgAndName}`,
|
||||
{ fallback: false }
|
||||
)}`
|
||||
);
|
||||
}
|
||||
@@ -287,9 +303,11 @@ export async function ensureRepoLink(
|
||||
|
||||
output.print(
|
||||
prependEmoji(
|
||||
`Linked to ${repoUrlLink} under ${chalk.bold(
|
||||
org.slug
|
||||
)} (created ${VERCEL_DIR}${
|
||||
`Linked to ${pluralize(
|
||||
'Project',
|
||||
selected.length,
|
||||
true
|
||||
)} under ${chalk.bold(org.slug)} (created ${VERCEL_DIR}${
|
||||
isGitIgnoreUpdated ? ' and added it to .gitignore' : ''
|
||||
})`,
|
||||
emoji('link')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { join } from 'path';
|
||||
import frameworks from '@vercel/frameworks';
|
||||
import frameworkList, { Framework } from '@vercel/frameworks';
|
||||
import {
|
||||
detectFramework,
|
||||
detectFrameworks,
|
||||
getWorkspacePackagePaths,
|
||||
getWorkspaces,
|
||||
LocalFileSystemDetector,
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
export async function detectProjects(cwd: string) {
|
||||
const fs = new LocalFileSystemDetector(cwd);
|
||||
const workspaces = await getWorkspaces({ fs });
|
||||
const detectedProjects = new Map<string, string>();
|
||||
const detectedProjects = new Map<string, Framework[]>();
|
||||
const packagePaths = (
|
||||
await Promise.all(
|
||||
workspaces.map(workspace =>
|
||||
@@ -26,12 +26,12 @@ export async function detectProjects(cwd: string) {
|
||||
}
|
||||
await Promise.all(
|
||||
packagePaths.map(async p => {
|
||||
const framework = await detectFramework({
|
||||
const frameworks = await detectFrameworks({
|
||||
fs: fs.chdir(join('.', p)),
|
||||
frameworkList: frameworks,
|
||||
frameworkList,
|
||||
});
|
||||
if (!framework) return;
|
||||
detectedProjects.set(p.slice(1), framework);
|
||||
if (frameworks.length === 0) return;
|
||||
detectedProjects.set(p.slice(1), frameworks);
|
||||
})
|
||||
);
|
||||
return detectedProjects;
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
const { createGzip } = require('zlib');
|
||||
|
||||
module.exports = (_req, resp) => {
|
||||
resp.setHeader('content-encoding', 'gzip');
|
||||
|
||||
const gzip = createGzip();
|
||||
gzip.pipe(resp);
|
||||
gzip.end('Hello World!');
|
||||
};
|
||||
@@ -143,6 +143,13 @@ test(
|
||||
})
|
||||
);
|
||||
|
||||
test(
|
||||
'[vercel dev] 43-compress-encoding',
|
||||
testFixtureStdio('43-compress-encoding', async (testPath: any) => {
|
||||
await testPath(200, '/api', 'Hello World!');
|
||||
})
|
||||
);
|
||||
|
||||
test(
|
||||
'[vercel dev] Middleware that returns a 200 response',
|
||||
testFixtureStdio('middleware-response', async (testPath: any) => {
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
"orgId": ".",
|
||||
"projectId": ".",
|
||||
"settings": {
|
||||
"framework": "storybook",
|
||||
"buildCommand": "npm run build-storybook",
|
||||
"outputDirectory": "storybook-static"
|
||||
"framework": "storybook"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,106 +1,164 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`help command help output snapshots column width 40 1`] = `
|
||||
"▲ [1mvercel[22m [1mdeploy[22m [project-path] [options]
|
||||
"
|
||||
▲ [1mvercel[22m [1mdeploy[22m [project-path] [options]
|
||||
|
||||
Deploy your project to Vercel. The \`deploy\` command is the default command for the Vercel CLI, and can be omitted (\`vc deploy my-app\` equals \`vc my-app\`).
|
||||
Deploy your project to Vercel. The \`deploy\` command is the default command for the Vercel CLI, and can be omitted (\`vc deploy my-app\` equals \`vc my-app\`).
|
||||
|
||||
[2mOptions:[22m
|
||||
[2mOptions[22m:
|
||||
|
||||
--archive Compress
|
||||
the
|
||||
deployment
|
||||
code into
|
||||
a file
|
||||
before
|
||||
uploading
|
||||
it
|
||||
--archive
|
||||
Compress
|
||||
the
|
||||
deployment
|
||||
code
|
||||
into
|
||||
a
|
||||
file
|
||||
before
|
||||
uploading
|
||||
it
|
||||
-b, --build-env <key=value>
|
||||
Specify
|
||||
environment
|
||||
variables
|
||||
during
|
||||
build-time
|
||||
(e.g.
|
||||
\`-b
|
||||
KEY1=value1
|
||||
-b
|
||||
KEY2=value2\`)
|
||||
-e, --env <key=value>
|
||||
Specify
|
||||
environment
|
||||
variables
|
||||
during
|
||||
run-time
|
||||
(e.g.
|
||||
\`-e
|
||||
KEY1=value1
|
||||
-e
|
||||
KEY2=value2\`)
|
||||
-f, --force
|
||||
Force
|
||||
a new
|
||||
deployment
|
||||
even
|
||||
if
|
||||
nothing
|
||||
has
|
||||
changed
|
||||
-m, --meta <key=value>
|
||||
Specify
|
||||
metadata
|
||||
for
|
||||
the
|
||||
deployment
|
||||
(e.g.
|
||||
\`-m
|
||||
KEY1=value1
|
||||
-m
|
||||
KEY2=value2\`)
|
||||
--no-wait
|
||||
Don't
|
||||
wait
|
||||
for
|
||||
the
|
||||
deployment
|
||||
to
|
||||
finish
|
||||
--prebuilt Use
|
||||
in
|
||||
combination
|
||||
with
|
||||
\`vc
|
||||
build\`.
|
||||
Deploy
|
||||
an
|
||||
existing
|
||||
build
|
||||
--prod
|
||||
Create
|
||||
a
|
||||
production
|
||||
deployment
|
||||
-p, --public
|
||||
Deployment
|
||||
is
|
||||
public
|
||||
(\`/_src\`)
|
||||
is
|
||||
exposed)
|
||||
--regions Set
|
||||
default
|
||||
regions
|
||||
to
|
||||
enable
|
||||
the
|
||||
deployment
|
||||
on
|
||||
--with-cache
|
||||
Retain
|
||||
build
|
||||
cache
|
||||
when
|
||||
using
|
||||
"--force"
|
||||
-y, --yes Use
|
||||
default
|
||||
options
|
||||
to
|
||||
skip
|
||||
all
|
||||
prompts
|
||||
|
||||
-b, --build-env <key=value> Specify
|
||||
environment
|
||||
variables
|
||||
during
|
||||
build-time
|
||||
(e.g. \`-b
|
||||
KEY1=value1
|
||||
-b
|
||||
KEY2=value2\`)
|
||||
[2mGlobal Options[22m:
|
||||
|
||||
-e, --env <key=value> Specify
|
||||
environment
|
||||
variables
|
||||
during
|
||||
run-time
|
||||
(e.g. \`-e
|
||||
KEY1=value1
|
||||
-e
|
||||
KEY2=value2\`)
|
||||
--cwd <DIR> Sets
|
||||
the
|
||||
current
|
||||
working
|
||||
directory
|
||||
for a
|
||||
single
|
||||
run of
|
||||
a
|
||||
command
|
||||
-d, --debug Debug
|
||||
mode
|
||||
(default
|
||||
off)
|
||||
-Q, --global-config <DIR> Path to
|
||||
the
|
||||
global
|
||||
\`.vercel\`
|
||||
directory
|
||||
-h, --help Output
|
||||
usage
|
||||
information
|
||||
-A, --local-config <FILE> Path to
|
||||
the
|
||||
local
|
||||
\`vercel.json\`
|
||||
file
|
||||
--no-color No
|
||||
color
|
||||
mode
|
||||
(default
|
||||
off)
|
||||
-S, --scope Set a
|
||||
custom
|
||||
scope
|
||||
-t, --token <TOKEN> Login
|
||||
token
|
||||
-v, --version Output
|
||||
the
|
||||
version
|
||||
number
|
||||
|
||||
-f, --force Force a
|
||||
new
|
||||
deployment
|
||||
even if
|
||||
nothing
|
||||
has
|
||||
changed
|
||||
|
||||
-m, --meta <key=value> Specify
|
||||
metadata
|
||||
for the
|
||||
deployment
|
||||
(e.g. \`-m
|
||||
KEY1=value1
|
||||
-m
|
||||
KEY2=value2\`)
|
||||
|
||||
--no-wait Don't
|
||||
wait for
|
||||
the
|
||||
deployment
|
||||
to finish
|
||||
|
||||
--prebuilt Use in
|
||||
combination
|
||||
with \`vc
|
||||
build\`.
|
||||
Deploy an
|
||||
existing
|
||||
build
|
||||
|
||||
--prod Create a
|
||||
production
|
||||
deployment
|
||||
|
||||
-p, --public
|
||||
Deployment
|
||||
is public
|
||||
(\`/_src\`)
|
||||
is
|
||||
exposed)
|
||||
|
||||
--regions Set
|
||||
default
|
||||
regions
|
||||
to enable
|
||||
the
|
||||
deployment
|
||||
on
|
||||
|
||||
--with-cache Retain
|
||||
build
|
||||
cache
|
||||
when
|
||||
using
|
||||
"--force"
|
||||
|
||||
-y, --yes Use
|
||||
default
|
||||
options
|
||||
to skip
|
||||
all
|
||||
prompts
|
||||
|
||||
[2mExamples:[22m
|
||||
[2mExamples:[22m
|
||||
|
||||
[90m-[39m Deploy the current directory
|
||||
|
||||
@@ -122,47 +180,53 @@ Deploy your project to Vercel. The \`deploy\` command is the default command for
|
||||
[90m-[39m Write Deployment URL to a file
|
||||
|
||||
[36m$ vercel > deployment-url.txt[39m
|
||||
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`help command help output snapshots column width 80 1`] = `
|
||||
"▲ [1mvercel[22m [1mdeploy[22m [project-path] [options]
|
||||
"
|
||||
▲ [1mvercel[22m [1mdeploy[22m [project-path] [options]
|
||||
|
||||
Deploy your project to Vercel. The \`deploy\` command is the default command for the Vercel CLI, and can be omitted (\`vc deploy my-app\` equals \`vc my-app\`).
|
||||
Deploy your project to Vercel. The \`deploy\` command is the default command for the Vercel CLI, and can be omitted (\`vc deploy my-app\` equals \`vc my-app\`).
|
||||
|
||||
[2mOptions:[22m
|
||||
[2mOptions[22m:
|
||||
|
||||
--archive Compress the deployment code into a file before
|
||||
uploading it
|
||||
--archive Compress the deployment code into a file
|
||||
before uploading it
|
||||
-b, --build-env <key=value> Specify environment variables during
|
||||
build-time (e.g. \`-b KEY1=value1 -b
|
||||
KEY2=value2\`)
|
||||
-e, --env <key=value> Specify environment variables during run-time
|
||||
(e.g. \`-e KEY1=value1 -e KEY2=value2\`)
|
||||
-f, --force Force a new deployment even if nothing has
|
||||
changed
|
||||
-m, --meta <key=value> Specify metadata for the deployment (e.g. \`-m
|
||||
KEY1=value1 -m KEY2=value2\`)
|
||||
--no-wait Don't wait for the deployment to finish
|
||||
--prebuilt Use in combination with \`vc build\`. Deploy an
|
||||
existing build
|
||||
--prod Create a production deployment
|
||||
-p, --public Deployment is public (\`/_src\`) is exposed)
|
||||
--regions Set default regions to enable the deployment
|
||||
on
|
||||
--with-cache Retain build cache when using "--force"
|
||||
-y, --yes Use default options to skip all prompts
|
||||
|
||||
-b, --build-env <key=value> Specify environment variables during build-time
|
||||
(e.g. \`-b KEY1=value1 -b KEY2=value2\`)
|
||||
[2mGlobal Options[22m:
|
||||
|
||||
-e, --env <key=value> Specify environment variables during run-time
|
||||
(e.g. \`-e KEY1=value1 -e KEY2=value2\`)
|
||||
--cwd <DIR> Sets the current working directory for a single
|
||||
run of a command
|
||||
-d, --debug Debug mode (default off)
|
||||
-Q, --global-config <DIR> Path to the global \`.vercel\` directory
|
||||
-h, --help Output usage information
|
||||
-A, --local-config <FILE> Path to the local \`vercel.json\` file
|
||||
--no-color No color mode (default off)
|
||||
-S, --scope Set a custom scope
|
||||
-t, --token <TOKEN> Login token
|
||||
-v, --version Output the version number
|
||||
|
||||
-f, --force Force a new deployment even if nothing has
|
||||
changed
|
||||
|
||||
-m, --meta <key=value> Specify metadata for the deployment (e.g. \`-m
|
||||
KEY1=value1 -m KEY2=value2\`)
|
||||
|
||||
--no-wait Don't wait for the deployment to finish
|
||||
|
||||
--prebuilt Use in combination with \`vc build\`. Deploy an
|
||||
existing build
|
||||
|
||||
--prod Create a production deployment
|
||||
|
||||
-p, --public Deployment is public (\`/_src\`) is exposed)
|
||||
|
||||
--regions Set default regions to enable the deployment on
|
||||
|
||||
--with-cache Retain build cache when using "--force"
|
||||
|
||||
-y, --yes Use default options to skip all prompts
|
||||
|
||||
[2mExamples:[22m
|
||||
[2mExamples:[22m
|
||||
|
||||
[90m-[39m Deploy the current directory
|
||||
|
||||
@@ -184,41 +248,45 @@ Deploy your project to Vercel. The \`deploy\` command is the default command for
|
||||
[90m-[39m Write Deployment URL to a file
|
||||
|
||||
[36m$ vercel > deployment-url.txt[39m
|
||||
|
||||
"
|
||||
`;
|
||||
|
||||
exports[`help command help output snapshots column width 120 1`] = `
|
||||
"▲ [1mvercel[22m [1mdeploy[22m [project-path] [options]
|
||||
"
|
||||
▲ [1mvercel[22m [1mdeploy[22m [project-path] [options]
|
||||
|
||||
Deploy your project to Vercel. The \`deploy\` command is the default command for the Vercel CLI, and can be omitted (\`vc deploy my-app\` equals \`vc my-app\`).
|
||||
Deploy your project to Vercel. The \`deploy\` command is the default command for the Vercel CLI, and can be omitted (\`vc deploy my-app\` equals \`vc my-app\`).
|
||||
|
||||
[2mOptions:[22m
|
||||
[2mOptions[22m:
|
||||
|
||||
--archive Compress the deployment code into a file before uploading it
|
||||
--archive Compress the deployment code into a file before uploading it
|
||||
-b, --build-env <key=value> Specify environment variables during build-time (e.g. \`-b KEY1=value1 -b
|
||||
KEY2=value2\`)
|
||||
-e, --env <key=value> Specify environment variables during run-time (e.g. \`-e KEY1=value1 -e KEY2=value2\`)
|
||||
-f, --force Force a new deployment even if nothing has changed
|
||||
-m, --meta <key=value> Specify metadata for the deployment (e.g. \`-m KEY1=value1 -m KEY2=value2\`)
|
||||
--no-wait Don't wait for the deployment to finish
|
||||
--prebuilt Use in combination with \`vc build\`. Deploy an existing build
|
||||
--prod Create a production deployment
|
||||
-p, --public Deployment is public (\`/_src\`) is exposed)
|
||||
--regions Set default regions to enable the deployment on
|
||||
--with-cache Retain build cache when using "--force"
|
||||
-y, --yes Use default options to skip all prompts
|
||||
|
||||
-b, --build-env <key=value> Specify environment variables during build-time (e.g. \`-b KEY1=value1 -b KEY2=value2\`)
|
||||
[2mGlobal Options[22m:
|
||||
|
||||
-e, --env <key=value> Specify environment variables during run-time (e.g. \`-e KEY1=value1 -e KEY2=value2\`)
|
||||
--cwd <DIR> Sets the current working directory for a single run of a command
|
||||
-d, --debug Debug mode (default off)
|
||||
-Q, --global-config <DIR> Path to the global \`.vercel\` directory
|
||||
-h, --help Output usage information
|
||||
-A, --local-config <FILE> Path to the local \`vercel.json\` file
|
||||
--no-color No color mode (default off)
|
||||
-S, --scope Set a custom scope
|
||||
-t, --token <TOKEN> Login token
|
||||
-v, --version Output the version number
|
||||
|
||||
-f, --force Force a new deployment even if nothing has changed
|
||||
|
||||
-m, --meta <key=value> Specify metadata for the deployment (e.g. \`-m KEY1=value1 -m KEY2=value2\`)
|
||||
|
||||
--no-wait Don't wait for the deployment to finish
|
||||
|
||||
--prebuilt Use in combination with \`vc build\`. Deploy an existing build
|
||||
|
||||
--prod Create a production deployment
|
||||
|
||||
-p, --public Deployment is public (\`/_src\`) is exposed)
|
||||
|
||||
--regions Set default regions to enable the deployment on
|
||||
|
||||
--with-cache Retain build cache when using "--force"
|
||||
|
||||
-y, --yes Use default options to skip all prompts
|
||||
|
||||
[2mExamples:[22m
|
||||
[2mExamples:[22m
|
||||
|
||||
[90m-[39m Deploy the current directory
|
||||
|
||||
@@ -240,5 +308,6 @@ Deploy your project to Vercel. The \`deploy\` command is the default command for
|
||||
[90m-[39m Write Deployment URL to a file
|
||||
|
||||
[36m$ vercel > deployment-url.txt[39m
|
||||
|
||||
"
|
||||
`;
|
||||
|
||||
@@ -58,6 +58,7 @@ describe('list', () => {
|
||||
'Age',
|
||||
'Deployment',
|
||||
'Status',
|
||||
'Environment',
|
||||
'Duration',
|
||||
'Username',
|
||||
]);
|
||||
@@ -68,6 +69,7 @@ describe('list', () => {
|
||||
expect(data).toEqual([
|
||||
`https://${deployment.url}`,
|
||||
stateString(deployment.state || ''),
|
||||
deployment.target === 'production' ? 'Production' : 'Preview',
|
||||
getDeploymentDuration(deployment),
|
||||
user.username,
|
||||
]);
|
||||
@@ -107,7 +109,13 @@ describe('list', () => {
|
||||
|
||||
line = await lines.next();
|
||||
const header = parseSpacedTableRow(line.value!);
|
||||
expect(header).toEqual(['Age', 'Deployment', 'Status', 'Duration']);
|
||||
expect(header).toEqual([
|
||||
'Age',
|
||||
'Deployment',
|
||||
'Status',
|
||||
'Environment',
|
||||
'Duration',
|
||||
]);
|
||||
|
||||
line = await lines.next();
|
||||
const data = parseSpacedTableRow(line.value!);
|
||||
@@ -116,6 +124,7 @@ describe('list', () => {
|
||||
expect(data).toEqual([
|
||||
'https://' + deployment.url,
|
||||
stateString(deployment.state || ''),
|
||||
deployment.target === 'production' ? 'Production' : 'Preview',
|
||||
getDeploymentDuration(deployment),
|
||||
]);
|
||||
});
|
||||
@@ -160,6 +169,7 @@ describe('list', () => {
|
||||
'Age',
|
||||
'Deployment',
|
||||
'Status',
|
||||
'Environment',
|
||||
'Duration',
|
||||
'Username',
|
||||
]);
|
||||
@@ -170,8 +180,50 @@ describe('list', () => {
|
||||
expect(data).toEqual([
|
||||
`https://${deployment.url}`,
|
||||
stateString(deployment.state || ''),
|
||||
deployment.target === 'production' ? 'Production' : 'Preview',
|
||||
getDeploymentDuration(deployment),
|
||||
user.username,
|
||||
]);
|
||||
});
|
||||
|
||||
it('should output deployment URLs to stdout', async () => {
|
||||
const user = useUser();
|
||||
useProject({
|
||||
...defaultProject,
|
||||
id: 'with-team',
|
||||
name: 'with-team',
|
||||
});
|
||||
const prodDeployment = useDeployment({
|
||||
creator: user,
|
||||
createdAt: Date.now() - 1000,
|
||||
target: 'production',
|
||||
});
|
||||
const previewDeployment = useDeployment({
|
||||
creator: user,
|
||||
createdAt: Date.now(),
|
||||
target: undefined,
|
||||
});
|
||||
|
||||
client.stdout.isTTY = false;
|
||||
client.cwd = fixture('with-team');
|
||||
|
||||
// run with all deployments
|
||||
let prom = list(client);
|
||||
await expect(client.stdout).toOutput(
|
||||
`https://${previewDeployment.url}\nhttps://${prodDeployment.url}`
|
||||
);
|
||||
await prom;
|
||||
|
||||
// run again with preview deployments only
|
||||
client.setArgv('--environment', 'preview');
|
||||
prom = list(client);
|
||||
await expect(client.stdout).toOutput(`https://${previewDeployment.url}`);
|
||||
await prom;
|
||||
|
||||
// run again with production deployments only
|
||||
client.setArgv('--environment', 'production');
|
||||
prom = list(client);
|
||||
await expect(client.stdout).toOutput(`https://${prodDeployment.url}`);
|
||||
await prom;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -104,6 +104,14 @@ function initRedeployTest({ target }: { target?: Deployment['target'] } = {}) {
|
||||
const toDeployment = useDeployment({ creator: user, target });
|
||||
|
||||
client.scenario.post(`/v13/deployments`, (req, res) => {
|
||||
const { target } = req.body;
|
||||
if (target !== undefined && typeof target !== 'string') {
|
||||
res.status(400).json({
|
||||
message: 'Invalid request: `target` should be string',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
res.json(toDeployment);
|
||||
});
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { join } from 'path';
|
||||
import type { Framework } from '@vercel/frameworks';
|
||||
import { detectProjects } from '../../../../src/util/projects/detect-projects';
|
||||
|
||||
const REPO_ROOT = join(__dirname, '../../../../../..');
|
||||
@@ -8,23 +9,35 @@ const FS_DETECTORS_FIXTURES = join(
|
||||
'packages/fs-detectors/test/fixtures'
|
||||
);
|
||||
|
||||
function mapDetected(
|
||||
detected: Map<string, Framework[]>
|
||||
): Array<[string, string[]]> {
|
||||
return [...detected.entries()]
|
||||
.sort((a, b) => a[0].localeCompare(b[0]))
|
||||
.map(([dir, frameworks]) => [dir, frameworks.map(f => f.slug as string)]);
|
||||
}
|
||||
|
||||
describe('detectProjects()', () => {
|
||||
it('should match "nextjs" example', async () => {
|
||||
it('should match 1 Project in "nextjs" example', async () => {
|
||||
const dir = join(EXAMPLES_DIR, 'nextjs');
|
||||
const detected = await detectProjects(dir);
|
||||
expect([...detected.entries()]).toEqual([['', 'nextjs']]);
|
||||
expect(mapDetected(detected)).toEqual([['', ['nextjs']]]);
|
||||
});
|
||||
|
||||
it('should match 2 Projects in "storybook" example', async () => {
|
||||
const dir = join(EXAMPLES_DIR, 'storybook');
|
||||
const detected = await detectProjects(dir);
|
||||
expect(mapDetected(detected)).toEqual([['', ['nextjs', 'storybook']]]);
|
||||
});
|
||||
|
||||
it('should match "30-double-nested-workspaces"', async () => {
|
||||
const dir = join(FS_DETECTORS_FIXTURES, '30-double-nested-workspaces');
|
||||
const detected = await detectProjects(dir);
|
||||
expect(
|
||||
[...detected.entries()].sort((a, b) => a[0].localeCompare(b[0]))
|
||||
).toEqual([
|
||||
['packages/backend/c', 'remix'],
|
||||
['packages/backend/d', 'nextjs'],
|
||||
['packages/frontend/a', 'hexo'],
|
||||
['packages/frontend/b', 'ember'],
|
||||
expect(mapDetected(detected)).toEqual([
|
||||
['packages/backend/c', ['remix']],
|
||||
['packages/backend/d', ['nextjs']],
|
||||
['packages/frontend/a', ['hexo']],
|
||||
['packages/frontend/b', ['ember']],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
declare module 'supports-hyperlinks' {
|
||||
import { Writable } from 'stream';
|
||||
export function supportsHyperlink(stream: Writable): boolean;
|
||||
}
|
||||
@@ -1,5 +1,12 @@
|
||||
# @vercel/client
|
||||
|
||||
## 12.6.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0750517af`](https://github.com/vercel/vercel/commit/0750517af99aea41410d4f1f772ce427699554e7)]:
|
||||
- @vercel/build-utils@6.8.2
|
||||
|
||||
## 12.6.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/client",
|
||||
"version": "12.6.4",
|
||||
"version": "12.6.5",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"homepage": "https://vercel.com",
|
||||
@@ -35,7 +35,7 @@
|
||||
"typescript": "4.9.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.8.1",
|
||||
"@vercel/build-utils": "6.8.2",
|
||||
"@vercel/routing-utils": "2.2.1",
|
||||
"@zeit/fetch": "5.2.0",
|
||||
"async-retry": "1.2.3",
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @vercel/frameworks
|
||||
|
||||
## 1.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add `ignorePackageJsonScript` configuration for Framework command settings to ignore the `package.json` script. ([#10228](https://github.com/vercel/vercel/pull/10228))
|
||||
|
||||
Enable this mode for Storybook's `buildCommand`, since it should not invoke the "build" script, which is most likely designated for the frontend app build.
|
||||
|
||||
## 1.4.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/frameworks",
|
||||
"version": "1.4.3",
|
||||
"version": "1.5.0",
|
||||
"main": "./dist/frameworks.js",
|
||||
"types": "./dist/frameworks.d.ts",
|
||||
"files": [
|
||||
|
||||
@@ -1955,6 +1955,7 @@ export const frameworks = [
|
||||
},
|
||||
buildCommand: {
|
||||
value: 'storybook build',
|
||||
ignorePackageJsonScript: true,
|
||||
},
|
||||
devCommand: {
|
||||
value: `storybook dev -p $PORT`,
|
||||
|
||||
@@ -32,11 +32,24 @@ export interface SettingPlaceholder {
|
||||
|
||||
export interface SettingValue {
|
||||
/**
|
||||
* A predefined setting for the detected framework
|
||||
* A predefined setting for the detected framework.
|
||||
* @example "next dev --port $PORT"
|
||||
*/
|
||||
value: string | null;
|
||||
/**
|
||||
* Placeholder text that may be shown in the UI when
|
||||
* the user is configuring this setting value.
|
||||
* @example "`npm run build` or `next build`"
|
||||
*/
|
||||
placeholder?: string;
|
||||
/**
|
||||
* When set to `true`, then the builder will not
|
||||
* invoke the equivalent script in `package.json`,
|
||||
* and instead will invoke the command specified in
|
||||
* configuration setting directly. When this
|
||||
* configuration is enabled, `value` must be a string.
|
||||
*/
|
||||
ignorePackageJsonScript?: boolean;
|
||||
}
|
||||
|
||||
export type Setting = SettingValue | SettingPlaceholder;
|
||||
|
||||
16
packages/frameworks/test/frameworks.unit.test.ts
vendored
16
packages/frameworks/test/frameworks.unit.test.ts
vendored
@@ -49,6 +49,22 @@ const SchemaSettings = {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
required: ['value', 'ignorePackageJsonScript'],
|
||||
additionalProperties: false,
|
||||
properties: {
|
||||
value: {
|
||||
type: 'string',
|
||||
},
|
||||
placeholder: {
|
||||
type: 'string',
|
||||
},
|
||||
ignorePackageJsonScript: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'object',
|
||||
required: ['placeholder'],
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @vercel/fs-detectors
|
||||
|
||||
## 4.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`ce4633fe4`](https://github.com/vercel/vercel/commit/ce4633fe4d00cb5c251cdabbfab08f39ec3f3b5f)]:
|
||||
- @vercel/frameworks@1.5.0
|
||||
|
||||
## 4.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add `detectFrameworks()` function ([#10195](https://github.com/vercel/vercel/pull/10195))
|
||||
|
||||
## 4.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/fs-detectors",
|
||||
"version": "4.0.1",
|
||||
"version": "4.1.1",
|
||||
"description": "Vercel filesystem detectors",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -21,7 +21,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/error-utils": "1.0.10",
|
||||
"@vercel/frameworks": "1.4.3",
|
||||
"@vercel/frameworks": "1.5.0",
|
||||
"@vercel/routing-utils": "2.2.1",
|
||||
"glob": "8.0.3",
|
||||
"js-yaml": "4.1.0",
|
||||
@@ -36,7 +36,7 @@
|
||||
"@types/minimatch": "3.0.5",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/semver": "7.3.10",
|
||||
"@vercel/build-utils": "6.8.1",
|
||||
"@vercel/build-utils": "6.8.2",
|
||||
"typescript": "4.9.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,6 +151,24 @@ export async function detectFramework({
|
||||
return result.find(res => res !== null) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects all matching Frameworks based on the given virtual filesystem.
|
||||
*/
|
||||
export async function detectFrameworks({
|
||||
fs,
|
||||
frameworkList,
|
||||
}: DetectFrameworkRecordOptions): Promise<Framework[]> {
|
||||
const result = await Promise.all(
|
||||
frameworkList.map(async frameworkMatch => {
|
||||
if (await matches(fs, frameworkMatch)) {
|
||||
return frameworkMatch;
|
||||
}
|
||||
return null;
|
||||
})
|
||||
);
|
||||
return result.filter(res => res !== null) as Framework[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Framework with a `detectedVersion` specifying the version
|
||||
* or version range of the relevant package
|
||||
|
||||
@@ -7,6 +7,7 @@ export {
|
||||
export { detectFileSystemAPI } from './detect-file-system-api';
|
||||
export {
|
||||
detectFramework,
|
||||
detectFrameworks,
|
||||
detectFrameworkRecord,
|
||||
detectFrameworkVersion,
|
||||
} from './detect-framework';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import frameworkList from '@vercel/frameworks';
|
||||
import workspaceManagers from '../src/workspaces/workspace-managers';
|
||||
import { detectFramework } from '../src';
|
||||
import { detectFramework, detectFrameworks } from '../src';
|
||||
import VirtualFilesystem from './virtual-file-system';
|
||||
|
||||
describe('DetectorFilesystem', () => {
|
||||
@@ -114,12 +114,12 @@ describe('DetectorFilesystem', () => {
|
||||
expect(await packagesFs.isFile('app2')).toBe(false);
|
||||
expect(await packagesFs.isFile('app1/package.json')).toBe(true);
|
||||
expect(await packagesFs.isFile('app2/package.json')).toBe(true);
|
||||
expect(
|
||||
await (await packagesFs.readFile('app1/package.json')).toString()
|
||||
).toEqual(nextPackageJson);
|
||||
expect(
|
||||
await (await packagesFs.readFile('app2/package.json')).toString()
|
||||
).toEqual(gatsbyPackageJson);
|
||||
expect((await packagesFs.readFile('app1/package.json')).toString()).toEqual(
|
||||
nextPackageJson
|
||||
);
|
||||
expect((await packagesFs.readFile('app2/package.json')).toString()).toEqual(
|
||||
gatsbyPackageJson
|
||||
);
|
||||
|
||||
expect(await detectFramework({ fs: packagesFs, frameworkList })).toBe(null);
|
||||
|
||||
@@ -143,266 +143,294 @@ describe('DetectorFilesystem', () => {
|
||||
{ name: 'package.json', path: 'package.json', type: 'file' },
|
||||
]);
|
||||
|
||||
expect(
|
||||
await (await gatsbyAppFs.readFile('package.json')).toString()
|
||||
).toEqual(gatsbyPackageJson);
|
||||
expect((await gatsbyAppFs.readFile('package.json')).toString()).toEqual(
|
||||
gatsbyPackageJson
|
||||
);
|
||||
|
||||
expect(await detectFramework({ fs: gatsbyAppFs, frameworkList })).toBe(
|
||||
'gatsby'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#detectFramework', () => {
|
||||
it('Do not detect anything', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'README.md': '# hi',
|
||||
'api/cheese.js': 'export default (req, res) => res.end("cheese");',
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe(null);
|
||||
describe('detectFramework()', () => {
|
||||
it('Do not detect anything', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'README.md': '# hi',
|
||||
'api/cheese.js': 'export default (req, res) => res.end("cheese");',
|
||||
});
|
||||
|
||||
it('Detect nx', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'workspace.json': JSON.stringify({
|
||||
projects: { 'app-one': 'apps/app-one' },
|
||||
}),
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe(null);
|
||||
});
|
||||
|
||||
expect(
|
||||
await detectFramework({ fs, frameworkList: workspaceManagers })
|
||||
).toBe('nx');
|
||||
it('Detect nx', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'workspace.json': JSON.stringify({
|
||||
projects: { 'app-one': 'apps/app-one' },
|
||||
}),
|
||||
});
|
||||
|
||||
it('Do not detect anything', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'workspace.json': JSON.stringify({ projects: {} }),
|
||||
});
|
||||
expect(
|
||||
await detectFramework({ fs, frameworkList: workspaceManagers })
|
||||
).toBe('nx');
|
||||
});
|
||||
|
||||
expect(
|
||||
await detectFramework({ fs, frameworkList: workspaceManagers })
|
||||
).toBe(null);
|
||||
it('Do not detect anything', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'workspace.json': JSON.stringify({ projects: {} }),
|
||||
});
|
||||
|
||||
it('Detect Next.js', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
next: '9.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(
|
||||
await detectFramework({ fs, frameworkList: workspaceManagers })
|
||||
).toBe(null);
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('nextjs');
|
||||
it('Detect Next.js', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
next: '9.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
it('Detect frameworks based on ascending order in framework list', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
next: '9.0.0',
|
||||
gatsby: '4.18.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('nextjs');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('nextjs');
|
||||
it('Detect frameworks based on ascending order in framework list', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
next: '9.0.0',
|
||||
gatsby: '4.18.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
it('Detect Nuxt.js', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
nuxt: '1.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('nextjs');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('nuxtjs');
|
||||
it('Detect Nuxt.js', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
nuxt: '1.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
it('Detect Nuxt.js Edge', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
'nuxt-edge': '1.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('nuxtjs');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('nuxtjs');
|
||||
it('Detect Nuxt.js Edge', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
'nuxt-edge': '1.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
it('Detect Nuxt.js 3', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
nuxt3: '1.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('nuxtjs');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('nuxtjs');
|
||||
it('Detect Nuxt.js 3', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
nuxt3: '1.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
it('Detect Gatsby', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
gatsby: '1.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('nuxtjs');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('gatsby');
|
||||
it('Detect Gatsby', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
gatsby: '1.0.0',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
it('Detect Hugo #1', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.yaml': 'baseURL: http://example.org/',
|
||||
'content/post.md': '# hello world',
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('gatsby');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hugo');
|
||||
it('Detect Hugo #1', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.yaml': 'baseURL: http://example.org/',
|
||||
'content/post.md': '# hello world',
|
||||
});
|
||||
|
||||
it('Detect Hugo #2', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.json': '{ "baseURL": "http://example.org/" }',
|
||||
'content/post.md': '# hello world',
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hugo');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hugo');
|
||||
it('Detect Hugo #2', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.json': '{ "baseURL": "http://example.org/" }',
|
||||
'content/post.md': '# hello world',
|
||||
});
|
||||
|
||||
it('Detect Hugo #3', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.toml': 'baseURL = "http://example.org/"',
|
||||
'content/post.md': '# hello world',
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hugo');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hugo');
|
||||
it('Detect Hugo #3', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.toml': 'baseURL = "http://example.org/"',
|
||||
'content/post.md': '# hello world',
|
||||
});
|
||||
|
||||
it('Detect Jekyll', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'_config.yml': 'config',
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hugo');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('jekyll');
|
||||
it('Detect Jekyll', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'_config.yml': 'config',
|
||||
});
|
||||
|
||||
it('Detect Middleman', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.rb': 'config',
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('jekyll');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('middleman');
|
||||
it('Detect Middleman', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.rb': 'config',
|
||||
});
|
||||
|
||||
it('Detect Scully', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
'@angular/cli': 'latest',
|
||||
'@scullyio/init': 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('middleman');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('scully');
|
||||
it('Detect Scully', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
'@angular/cli': 'latest',
|
||||
'@scullyio/init': 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
it('Detect Zola', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.toml': 'base_url = "/"',
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('scully');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('zola');
|
||||
it('Detect Zola', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'config.toml': 'base_url = "/"',
|
||||
});
|
||||
|
||||
it('Detect Blitz.js (Legacy)', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'blitz.config.js': '// some config',
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('zola');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('blitzjs');
|
||||
it('Detect Blitz.js (Legacy)', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'blitz.config.js': '// some config',
|
||||
});
|
||||
|
||||
it('Detect Ember via `ember-source`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
'ember-source': 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('blitzjs');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('ember');
|
||||
it('Detect Ember via `ember-source`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
'ember-source': 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
it('Detect Ember via `ember-cli`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
'ember-cli': 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('ember');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('ember');
|
||||
it('Detect Ember via `ember-cli`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
'ember-cli': 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
it('Detect Brunch via `brunch`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
brunch: 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('ember');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('brunch');
|
||||
it('Detect Brunch via `brunch`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
brunch: 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
it('Detect Brunch via `brunch-config.js`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'brunch-config.js': '// some config',
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('brunch');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('brunch');
|
||||
it('Detect Brunch via `brunch-config.js`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'brunch-config.js': '// some config',
|
||||
});
|
||||
|
||||
it('Detect Hydrogen via `hydrogen.config.js`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'hydrogen.config.js': '// some config',
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('brunch');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hydrogen');
|
||||
it('Detect Hydrogen via `hydrogen.config.js`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'hydrogen.config.js': '// some config',
|
||||
});
|
||||
|
||||
it('Detect Hydrogen via `@shopify/hydrogen`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
'@shopify/hydrogen': 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hydrogen');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hydrogen');
|
||||
it('Detect Hydrogen via `@shopify/hydrogen`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
'@shopify/hydrogen': 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
it('Detect Storybook via `storybook`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
storybook: 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('hydrogen');
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('storybook');
|
||||
it('Detect Storybook via `storybook`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
storybook: 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
expect(await detectFramework({ fs, frameworkList })).toBe('storybook');
|
||||
});
|
||||
});
|
||||
|
||||
describe('detectFrameworks()', () => {
|
||||
it('Return empty array when there are no matches', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {},
|
||||
}),
|
||||
});
|
||||
|
||||
expect(await detectFrameworks({ fs, frameworkList })).toEqual([]);
|
||||
});
|
||||
|
||||
it('Detect `nextjs` and `storybook`', async () => {
|
||||
const fs = new VirtualFilesystem({
|
||||
'package.json': JSON.stringify({
|
||||
dependencies: {
|
||||
next: 'latest',
|
||||
storybook: 'latest',
|
||||
},
|
||||
}),
|
||||
});
|
||||
|
||||
const slugs = (await detectFrameworks({ fs, frameworkList })).map(
|
||||
f => f.slug
|
||||
);
|
||||
expect(slugs).toEqual(['nextjs', 'storybook']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,34 @@
|
||||
# @vercel/gatsby-plugin-vercel-builder
|
||||
|
||||
## 1.3.16
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`4af242af8`](https://github.com/vercel/vercel/commit/4af242af8633e58b6a9bf920564416da3ef22ad4), [`85dd66778`](https://github.com/vercel/vercel/commit/85dd667781693539d753d587566e53964bbe189d)]:
|
||||
- @vercel/node@2.15.8
|
||||
|
||||
## 1.3.15
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`fc413707d`](https://github.com/vercel/vercel/commit/fc413707d017e234d5013b761d885f65f9b981bc)]:
|
||||
- @vercel/node@2.15.7
|
||||
|
||||
## 1.3.14
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`b56639b62`](https://github.com/vercel/vercel/commit/b56639b624e9ad1df048a4c85083e26888696060)]:
|
||||
- @vercel/node@2.15.6
|
||||
|
||||
## 1.3.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`0750517af`](https://github.com/vercel/vercel/commit/0750517af99aea41410d4f1f772ce427699554e7)]:
|
||||
- @vercel/build-utils@6.8.2
|
||||
- @vercel/node@2.15.5
|
||||
|
||||
## 1.3.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/gatsby-plugin-vercel-builder",
|
||||
"version": "1.3.12",
|
||||
"version": "1.3.16",
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
"dist",
|
||||
@@ -20,8 +20,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@sinclair/typebox": "0.25.24",
|
||||
"@vercel/build-utils": "6.8.1",
|
||||
"@vercel/node": "2.15.4",
|
||||
"@vercel/build-utils": "6.8.2",
|
||||
"@vercel/node": "2.15.8",
|
||||
"@vercel/routing-utils": "2.2.1",
|
||||
"esbuild": "0.14.47",
|
||||
"etag": "1.8.1",
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"@types/node-fetch": "^2.3.0",
|
||||
"@types/tar": "^4.0.0",
|
||||
"@types/yauzl-promise": "2.1.0",
|
||||
"@vercel/build-utils": "6.8.1",
|
||||
"@vercel/build-utils": "6.8.2",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"async-retry": "1.3.1",
|
||||
"execa": "^1.0.0",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "27.5.1",
|
||||
"@types/node": "14.18.33",
|
||||
"@vercel/build-utils": "6.8.1",
|
||||
"@vercel/build-utils": "6.8.2",
|
||||
"@vercel/static-config": "2.0.17",
|
||||
"execa": "3.2.0",
|
||||
"fs-extra": "11.1.0",
|
||||
|
||||
@@ -1,5 +1,33 @@
|
||||
# @vercel/next
|
||||
|
||||
## 3.9.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- fix dynamic not found pages ([#10262](https://github.com/vercel/vercel/pull/10262))
|
||||
|
||||
## 3.9.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Fix pages/404 gsp + i18n case ([#10258](https://github.com/vercel/vercel/pull/10258))
|
||||
|
||||
## 3.9.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Fix pages and app router i18n handling ([#10243](https://github.com/vercel/vercel/pull/10243))
|
||||
|
||||
## 3.9.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Support maxDuration in Next.js deployments ([#10069](https://github.com/vercel/vercel/pull/10069))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Fix 404 page in edge runtime ([#10223](https://github.com/vercel/vercel/pull/10223))
|
||||
|
||||
## 3.8.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/next",
|
||||
"version": "3.8.8",
|
||||
"version": "3.9.3",
|
||||
"license": "Apache-2.0",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
||||
@@ -35,7 +35,7 @@
|
||||
"@types/semver": "6.0.0",
|
||||
"@types/text-table": "0.2.1",
|
||||
"@types/webpack-sources": "3.2.0",
|
||||
"@vercel/build-utils": "6.8.1",
|
||||
"@vercel/build-utils": "6.8.2",
|
||||
"@vercel/nft": "0.22.5",
|
||||
"@vercel/routing-utils": "2.2.1",
|
||||
"async-sema": "3.0.1",
|
||||
|
||||
@@ -90,6 +90,7 @@ import {
|
||||
validateEntrypoint,
|
||||
getOperationType,
|
||||
isApiPage,
|
||||
getFunctionsConfigManifest,
|
||||
} from './utils';
|
||||
|
||||
export const version = 2;
|
||||
@@ -272,7 +273,7 @@ export const build: BuildV2 = async ({
|
||||
});
|
||||
|
||||
let hasLegacyRoutes = false;
|
||||
const hasFunctionsConfig = !!config.functions;
|
||||
const hasFunctionsConfig = Boolean(config.functions);
|
||||
|
||||
if (await pathExists(dotNextStatic)) {
|
||||
console.warn('WARNING: You should not upload the `.next` directory.');
|
||||
@@ -487,7 +488,12 @@ export const build: BuildV2 = async ({
|
||||
? await getRequiredServerFilesManifest(entryPath, outputDirectory)
|
||||
: false;
|
||||
|
||||
isServerMode = !!requiredServerFilesManifest;
|
||||
isServerMode = Boolean(requiredServerFilesManifest);
|
||||
|
||||
const functionsConfigManifest = await getFunctionsConfigManifest(
|
||||
entryPath,
|
||||
outputDirectory
|
||||
);
|
||||
|
||||
const routesManifest = await getRoutesManifest(
|
||||
entryPath,
|
||||
@@ -1133,8 +1139,9 @@ export const build: BuildV2 = async ({
|
||||
const canUsePreviewMode = Object.keys(pages).some(page =>
|
||||
isApiPage(pages[page].fsPath)
|
||||
);
|
||||
staticPages = await filterStaticPages(
|
||||
await glob('**/*.html', pagesDir),
|
||||
const originalStaticPages = await glob('**/*.html', pagesDir);
|
||||
staticPages = filterStaticPages(
|
||||
originalStaticPages,
|
||||
dynamicPages,
|
||||
entryDirectory,
|
||||
htmlContentType,
|
||||
@@ -1310,14 +1317,27 @@ export const build: BuildV2 = async ({
|
||||
);
|
||||
}
|
||||
|
||||
const localePrefixed404 = !!(
|
||||
routesManifest.i18n &&
|
||||
originalStaticPages[
|
||||
path.posix.join(
|
||||
entryDirectory,
|
||||
routesManifest.i18n.defaultLocale,
|
||||
'404.html'
|
||||
)
|
||||
]
|
||||
);
|
||||
|
||||
return serverBuild({
|
||||
config,
|
||||
functionsConfigManifest,
|
||||
nextVersion,
|
||||
trailingSlash,
|
||||
appPathRoutesManifest,
|
||||
dynamicPages,
|
||||
canUsePreviewMode,
|
||||
staticPages,
|
||||
localePrefixed404,
|
||||
lambdaPages: pages,
|
||||
lambdaAppPaths,
|
||||
omittedPrerenderRoutes,
|
||||
@@ -1570,6 +1590,7 @@ export const build: BuildV2 = async ({
|
||||
const initialPageLambdaGroups = await getPageLambdaGroups({
|
||||
entryPath,
|
||||
config,
|
||||
functionsConfigManifest,
|
||||
pages: nonApiPages,
|
||||
prerenderRoutes: new Set(),
|
||||
pageTraces,
|
||||
@@ -1586,6 +1607,7 @@ export const build: BuildV2 = async ({
|
||||
const initialApiLambdaGroups = await getPageLambdaGroups({
|
||||
entryPath,
|
||||
config,
|
||||
functionsConfigManifest,
|
||||
pages: apiPages,
|
||||
prerenderRoutes: new Set(),
|
||||
pageTraces,
|
||||
@@ -2670,6 +2692,7 @@ async function getServerlessPages(params: {
|
||||
? Promise.all([
|
||||
glob('**/page.js', path.join(params.pagesDir, '../app')),
|
||||
glob('**/route.js', path.join(params.pagesDir, '../app')),
|
||||
glob('**/_not-found.js', path.join(params.pagesDir, '../app')),
|
||||
]).then(items => Object.assign(...items))
|
||||
: Promise.resolve({}),
|
||||
getMiddlewareManifest(params.entryPath, params.outputDirectory),
|
||||
|
||||
@@ -44,6 +44,7 @@ import {
|
||||
getFilesMapFromReasons,
|
||||
UnwrapPromise,
|
||||
getOperationType,
|
||||
FunctionsConfigManifestV1,
|
||||
} from './utils';
|
||||
import {
|
||||
nodeFileTrace,
|
||||
@@ -66,6 +67,7 @@ export async function serverBuild({
|
||||
dynamicPages,
|
||||
pagesDir,
|
||||
config = {},
|
||||
functionsConfigManifest,
|
||||
privateOutputs,
|
||||
baseDir,
|
||||
workPath,
|
||||
@@ -89,6 +91,7 @@ export async function serverBuild({
|
||||
routesManifest,
|
||||
staticPages,
|
||||
lambdaPages,
|
||||
localePrefixed404,
|
||||
nextVersion,
|
||||
lambdaAppPaths,
|
||||
canUsePreviewMode,
|
||||
@@ -105,10 +108,12 @@ export async function serverBuild({
|
||||
dynamicPages: string[];
|
||||
trailingSlash: boolean;
|
||||
config: Config;
|
||||
functionsConfigManifest?: FunctionsConfigManifestV1;
|
||||
pagesDir: string;
|
||||
baseDir: string;
|
||||
canUsePreviewMode: boolean;
|
||||
omittedPrerenderRoutes: Set<string>;
|
||||
localePrefixed404: boolean;
|
||||
staticPages: { [key: string]: FileFsRef };
|
||||
lambdaAppPaths: { [key: string]: FileFsRef };
|
||||
lambdaPages: { [key: string]: FileFsRef };
|
||||
@@ -212,12 +217,12 @@ export async function serverBuild({
|
||||
? path.posix.join(entryDirectory, '_errors/404')
|
||||
: undefined;
|
||||
|
||||
if (!static404Page && i18n) {
|
||||
static404Page = staticPages[
|
||||
path.posix.join(entryDirectory, i18n.defaultLocale, '404')
|
||||
]
|
||||
? path.posix.join(entryDirectory, i18n.defaultLocale, '404')
|
||||
: undefined;
|
||||
if (
|
||||
!static404Page &&
|
||||
i18n &&
|
||||
staticPages[path.posix.join(entryDirectory, i18n.defaultLocale, '404')]
|
||||
) {
|
||||
static404Page = path.posix.join(entryDirectory, i18n.defaultLocale, '404');
|
||||
}
|
||||
|
||||
if (!hasStatic500 && i18n) {
|
||||
@@ -752,6 +757,7 @@ export async function serverBuild({
|
||||
const pageLambdaGroups = await getPageLambdaGroups({
|
||||
entryPath: projectDir,
|
||||
config,
|
||||
functionsConfigManifest,
|
||||
pages: nonApiPages,
|
||||
prerenderRoutes,
|
||||
pageTraces,
|
||||
@@ -767,6 +773,7 @@ export async function serverBuild({
|
||||
const appRouterLambdaGroups = await getPageLambdaGroups({
|
||||
entryPath: projectDir,
|
||||
config,
|
||||
functionsConfigManifest,
|
||||
pages: appRouterPages,
|
||||
prerenderRoutes,
|
||||
pageTraces,
|
||||
@@ -789,6 +796,7 @@ export async function serverBuild({
|
||||
const apiLambdaGroups = await getPageLambdaGroups({
|
||||
entryPath: projectDir,
|
||||
config,
|
||||
functionsConfigManifest,
|
||||
pages: apiPages,
|
||||
prerenderRoutes,
|
||||
pageTraces,
|
||||
@@ -961,6 +969,7 @@ export async function serverBuild({
|
||||
if (
|
||||
i18n &&
|
||||
!isPrerender &&
|
||||
!group.isAppRouter &&
|
||||
(!isCorrectLocaleAPIRoutes ||
|
||||
!(pageNoExt === 'api' || pageNoExt.startsWith('api/')))
|
||||
) {
|
||||
@@ -998,6 +1007,7 @@ export async function serverBuild({
|
||||
isSharedLambdas: false,
|
||||
canUsePreviewMode,
|
||||
static404Page,
|
||||
localePrefixed404,
|
||||
hasPages404: routesManifest.pages404,
|
||||
isCorrectNotFoundRoutes,
|
||||
isEmptyAllowQueryForPrendered,
|
||||
@@ -1064,7 +1074,8 @@ export async function serverBuild({
|
||||
prerenderManifest,
|
||||
routesManifest,
|
||||
true,
|
||||
isCorrectLocaleAPIRoutes
|
||||
isCorrectLocaleAPIRoutes,
|
||||
inversedAppPathManifest
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1217,6 +1228,7 @@ export async function serverBuild({
|
||||
const rscVaryHeader =
|
||||
routesManifest?.rsc?.varyHeader ||
|
||||
'RSC, Next-Router-State-Tree, Next-Router-Prefetch';
|
||||
const appNotFoundPath = path.posix.join('.', entryDirectory, '_not-found');
|
||||
|
||||
return {
|
||||
wildcard: wildcardConfig,
|
||||
@@ -1749,6 +1761,7 @@ export async function serverBuild({
|
||||
{ handle: 'error' } as RouteWithHandle,
|
||||
|
||||
// Custom Next.js 404 page
|
||||
|
||||
...(i18n && (static404Page || hasIsr404Page || lambdaPages['404.js'])
|
||||
? [
|
||||
{
|
||||
@@ -1783,6 +1796,10 @@ export async function serverBuild({
|
||||
hasIsr404Page ||
|
||||
lambdas[path.posix.join(entryDirectory, '404')]
|
||||
? '/404'
|
||||
: appPathRoutesManifest &&
|
||||
(middleware.edgeFunctions[appNotFoundPath] ||
|
||||
lambdas[appNotFoundPath])
|
||||
? '/_not-found'
|
||||
: '/_error'
|
||||
),
|
||||
status: 404,
|
||||
|
||||
@@ -479,7 +479,8 @@ export function localizeDynamicRoutes(
|
||||
prerenderManifest: NextPrerenderedRoutes,
|
||||
routesManifest?: RoutesManifest,
|
||||
isServerMode?: boolean,
|
||||
isCorrectLocaleAPIRoutes?: boolean
|
||||
isCorrectLocaleAPIRoutes?: boolean,
|
||||
inversedAppPathRoutesManifest?: Record<string, string>
|
||||
): RouteWithSrc[] {
|
||||
return dynamicRoutes.map((route: RouteWithSrc) => {
|
||||
// i18n is already handled for middleware
|
||||
@@ -498,6 +499,9 @@ export function localizeDynamicRoutes(
|
||||
const isAutoExport =
|
||||
staticPages[addLocaleOrDefault(pathname!, routesManifest).substring(1)];
|
||||
|
||||
const isAppRoute =
|
||||
inversedAppPathRoutesManifest?.[pathnameNoPrefix || ''];
|
||||
|
||||
const isLocalePrefixed =
|
||||
isFallback || isBlocking || isAutoExport || isServerMode;
|
||||
|
||||
@@ -508,7 +512,11 @@ export function localizeDynamicRoutes(
|
||||
}${i18n.locales.map(locale => escapeStringRegexp(locale)).join('|')})?`
|
||||
);
|
||||
|
||||
if (isLocalePrefixed && !(isCorrectLocaleAPIRoutes && isApiRoute)) {
|
||||
if (
|
||||
isLocalePrefixed &&
|
||||
!(isCorrectLocaleAPIRoutes && isApiRoute) &&
|
||||
!isAppRoute
|
||||
) {
|
||||
// ensure destination has locale prefix to match prerender output
|
||||
// path so that the prerender object is used
|
||||
route.dest = route.dest!.replace(
|
||||
@@ -1397,6 +1405,7 @@ const LAMBDA_RESERVED_COMPRESSED_SIZE = 250 * KIB;
|
||||
export async function getPageLambdaGroups({
|
||||
entryPath,
|
||||
config,
|
||||
functionsConfigManifest,
|
||||
pages,
|
||||
prerenderRoutes,
|
||||
pageTraces,
|
||||
@@ -1410,6 +1419,7 @@ export async function getPageLambdaGroups({
|
||||
}: {
|
||||
entryPath: string;
|
||||
config: Config;
|
||||
functionsConfigManifest?: FunctionsConfigManifestV1;
|
||||
pages: string[];
|
||||
prerenderRoutes: Set<string>;
|
||||
pageTraces: {
|
||||
@@ -1436,16 +1446,26 @@ export async function getPageLambdaGroups({
|
||||
|
||||
let opts: { memory?: number; maxDuration?: number } = {};
|
||||
|
||||
if (
|
||||
functionsConfigManifest &&
|
||||
functionsConfigManifest.functions[routeName]
|
||||
) {
|
||||
opts = functionsConfigManifest.functions[routeName];
|
||||
}
|
||||
|
||||
if (config && config.functions) {
|
||||
const sourceFile = await getSourceFilePathFromPage({
|
||||
workPath: entryPath,
|
||||
page,
|
||||
pageExtensions,
|
||||
});
|
||||
opts = await getLambdaOptionsFromFunction({
|
||||
|
||||
const vercelConfigOpts = await getLambdaOptionsFromFunction({
|
||||
sourceFile,
|
||||
config,
|
||||
});
|
||||
|
||||
opts = { ...vercelConfigOpts, ...opts };
|
||||
}
|
||||
|
||||
let matchingGroup = groups.find(group => {
|
||||
@@ -1779,6 +1799,7 @@ export const onPrerenderRouteInitial = (
|
||||
type OnPrerenderRouteArgs = {
|
||||
appDir: string | null;
|
||||
pagesDir: string;
|
||||
localePrefixed404?: boolean;
|
||||
static404Page?: string;
|
||||
hasPages404: boolean;
|
||||
entryDirectory: string;
|
||||
@@ -1816,6 +1837,7 @@ export const onPrerenderRoute =
|
||||
appDir,
|
||||
pagesDir,
|
||||
static404Page,
|
||||
localePrefixed404,
|
||||
entryDirectory,
|
||||
prerenderManifest,
|
||||
isSharedLambdas,
|
||||
@@ -1951,7 +1973,9 @@ export const onPrerenderRoute =
|
||||
// file.
|
||||
`${
|
||||
isOmittedOrNotFound
|
||||
? addLocaleOrDefault('/404', routesManifest, locale)
|
||||
? localePrefixed404
|
||||
? addLocaleOrDefault('/404', routesManifest, locale)
|
||||
: '/404'
|
||||
: routeFileNoExt
|
||||
}.html`
|
||||
),
|
||||
@@ -1968,7 +1992,9 @@ export const onPrerenderRoute =
|
||||
: pagesDir,
|
||||
`${
|
||||
isOmittedOrNotFound
|
||||
? addLocaleOrDefault('/404.html', routesManifest, locale)
|
||||
? localePrefixed404
|
||||
? addLocaleOrDefault('/404.html', routesManifest, locale)
|
||||
: '/404.html'
|
||||
: isAppPathRoute
|
||||
? dataRoute
|
||||
: routeFileNoExt + '.json'
|
||||
@@ -2388,6 +2414,16 @@ export {
|
||||
getSourceFilePathFromPage,
|
||||
};
|
||||
|
||||
export type FunctionsConfigManifestV1 = {
|
||||
version: 1;
|
||||
functions: Record<
|
||||
string,
|
||||
{
|
||||
maxDuration?: number;
|
||||
}
|
||||
>;
|
||||
};
|
||||
|
||||
type MiddlewareManifest = MiddlewareManifestV1 | MiddlewareManifestV2;
|
||||
|
||||
interface MiddlewareManifestV1 {
|
||||
@@ -2663,7 +2699,9 @@ export async function getMiddlewareBundle({
|
||||
shortPath = shortPath.replace(/^pages\//, '');
|
||||
} else if (
|
||||
shortPath.startsWith('app/') &&
|
||||
(shortPath.endsWith('/page') || shortPath.endsWith('/route'))
|
||||
(shortPath.endsWith('/page') ||
|
||||
shortPath.endsWith('/route') ||
|
||||
shortPath === 'app/_not-found')
|
||||
) {
|
||||
const ogRoute = shortPath.replace(/^app\//, '/');
|
||||
shortPath = (
|
||||
@@ -2731,6 +2769,37 @@ export async function getMiddlewareBundle({
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to read the functions config manifest from the pre-defined
|
||||
* location. If the manifest can't be found it will resolve to
|
||||
* undefined.
|
||||
*/
|
||||
export async function getFunctionsConfigManifest(
|
||||
entryPath: string,
|
||||
outputDirectory: string
|
||||
): Promise<FunctionsConfigManifestV1 | undefined> {
|
||||
const functionConfigManifestPath = path.join(
|
||||
entryPath,
|
||||
outputDirectory,
|
||||
'./server/functions-config-manifest.json'
|
||||
);
|
||||
|
||||
const hasManifest = await fs
|
||||
.access(functionConfigManifestPath)
|
||||
.then(() => true)
|
||||
.catch(() => false);
|
||||
|
||||
if (!hasManifest) {
|
||||
return;
|
||||
}
|
||||
|
||||
const manifest: FunctionsConfigManifestV1 = await fs.readJSON(
|
||||
functionConfigManifestPath
|
||||
);
|
||||
|
||||
return manifest.version === 1 ? manifest : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to read the middleware manifest from the pre-defined
|
||||
* location. If the manifest can't be found it will resolve to
|
||||
|
||||
@@ -42,14 +42,14 @@
|
||||
"status": 200,
|
||||
"mustContain": "hello from /ssg",
|
||||
"responseHeaders": {
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "/hello/world/ssg",
|
||||
"status": 200,
|
||||
"responseHeaders": {
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
|
||||
},
|
||||
"headers": {
|
||||
"RSC": "1"
|
||||
@@ -82,14 +82,14 @@
|
||||
"status": 200,
|
||||
"mustContain": "hello from app/dashboard/deployments/[id]/settings",
|
||||
"responseHeaders": {
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "/hello/world/dashboard/deployments/123/settings",
|
||||
"status": 200,
|
||||
"responseHeaders": {
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
|
||||
},
|
||||
"headers": {
|
||||
"RSC": "1"
|
||||
@@ -102,14 +102,14 @@
|
||||
"status": 200,
|
||||
"mustContain": "catchall",
|
||||
"responseHeaders": {
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "/hello/world/dashboard/deployments/catchall/something",
|
||||
"status": 200,
|
||||
"responseHeaders": {
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
|
||||
},
|
||||
"headers": {
|
||||
"RSC": "1"
|
||||
@@ -122,7 +122,7 @@
|
||||
"status": 200,
|
||||
"mustContain": "hello from app/dashboard",
|
||||
"responseHeaders": {
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -142,7 +142,7 @@
|
||||
},
|
||||
"responseHeaders": {
|
||||
"content-type": "text/x-component",
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
|
||||
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
10
packages/next/test/fixtures/00-app-dir-dynamic-404/app/layout.js
vendored
Normal file
10
packages/next/test/fixtures/00-app-dir-dynamic-404/app/layout.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<html>
|
||||
<head>
|
||||
<title>Hello World</title>
|
||||
</head>
|
||||
<body>{children}</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
13
packages/next/test/fixtures/00-app-dir-dynamic-404/app/not-found.js
vendored
Normal file
13
packages/next/test/fixtures/00-app-dir-dynamic-404/app/not-found.js
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
import { cookies } from 'next/headers';
|
||||
|
||||
export default function Page() {
|
||||
cookies(); // dynamic
|
||||
|
||||
return (
|
||||
<>
|
||||
<h1>This Is The Not Found Page</h1>
|
||||
|
||||
<div id="timestamp">{Date.now()}</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
3
packages/next/test/fixtures/00-app-dir-dynamic-404/app/page.js
vendored
Normal file
3
packages/next/test/fixtures/00-app-dir-dynamic-404/app/page.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function Page() {
|
||||
return <h1>My page TEST</h1>
|
||||
}
|
||||
12
packages/next/test/fixtures/00-app-dir-dynamic-404/index.test.js
vendored
Normal file
12
packages/next/test/fixtures/00-app-dir-dynamic-404/index.test.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/* eslint-env jest */
|
||||
const path = require('path');
|
||||
const { deployAndTest } = require('../../utils');
|
||||
|
||||
const ctx = {};
|
||||
|
||||
describe(`${__dirname.split(path.sep).pop()}`, () => {
|
||||
it('should deploy and pass probe checks', async () => {
|
||||
const info = await deployAndTest(__dirname);
|
||||
Object.assign(ctx, info);
|
||||
});
|
||||
});
|
||||
1
packages/next/test/fixtures/00-app-dir-dynamic-404/next.config.js
vendored
Normal file
1
packages/next/test/fixtures/00-app-dir-dynamic-404/next.config.js
vendored
Normal file
@@ -0,0 +1 @@
|
||||
module.exports = {};
|
||||
11
packages/next/test/fixtures/00-app-dir-dynamic-404/package.json
vendored
Normal file
11
packages/next/test/fixtures/00-app-dir-dynamic-404/package.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"next": "canary",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental"
|
||||
},
|
||||
"ignoreNextjsUpdates": true,
|
||||
"scripts": {
|
||||
"vercel-build": "next build"
|
||||
}
|
||||
}
|
||||
12
packages/next/test/fixtures/00-app-dir-dynamic-404/probes.json
vendored
Normal file
12
packages/next/test/fixtures/00-app-dir-dynamic-404/probes.json
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
{ "probes": [
|
||||
{
|
||||
"path": "/",
|
||||
"status": 200,
|
||||
"mustContain": "My page"
|
||||
},
|
||||
{
|
||||
"path": "/not-found-page",
|
||||
"status": 404,
|
||||
"mustContain": "This Is The Not Found Page"
|
||||
}
|
||||
]}
|
||||
8
packages/next/test/fixtures/00-app-dir-dynamic-404/vercel.json
vendored
Normal file
8
packages/next/test/fixtures/00-app-dir-dynamic-404/vercel.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"builds": [
|
||||
{
|
||||
"src": "package.json",
|
||||
"use": "@vercel/next"
|
||||
}
|
||||
]
|
||||
}
|
||||
12
packages/next/test/fixtures/00-app-dir-edge-404/app/layout.js
vendored
Normal file
12
packages/next/test/fixtures/00-app-dir-edge-404/app/layout.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
export const runtime = 'edge'
|
||||
|
||||
export default function Layout({ children }) {
|
||||
return (
|
||||
<html>
|
||||
<head>
|
||||
<title>Hello World</title>
|
||||
</head>
|
||||
<body>{children}</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
9
packages/next/test/fixtures/00-app-dir-edge-404/app/not-found.js
vendored
Normal file
9
packages/next/test/fixtures/00-app-dir-edge-404/app/not-found.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
export default function Page() {
|
||||
return (
|
||||
<>
|
||||
<h1>This Is The Not Found Page</h1>
|
||||
|
||||
<div id="timestamp">{Date.now()}</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
3
packages/next/test/fixtures/00-app-dir-edge-404/app/not-found/not-found.js
vendored
Normal file
3
packages/next/test/fixtures/00-app-dir-edge-404/app/not-found/not-found.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function notFound() {
|
||||
return <h1>custom not found</h1>
|
||||
}
|
||||
3
packages/next/test/fixtures/00-app-dir-edge-404/app/not-found/page.js
vendored
Normal file
3
packages/next/test/fixtures/00-app-dir-edge-404/app/not-found/page.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function Page() {
|
||||
return <h1>I'm still a valid page</h1>
|
||||
}
|
||||
3
packages/next/test/fixtures/00-app-dir-edge-404/app/page.js
vendored
Normal file
3
packages/next/test/fixtures/00-app-dir-edge-404/app/page.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function Page() {
|
||||
return <h1>My page</h1>
|
||||
}
|
||||
12
packages/next/test/fixtures/00-app-dir-edge-404/index.test.js
vendored
Normal file
12
packages/next/test/fixtures/00-app-dir-edge-404/index.test.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/* eslint-env jest */
|
||||
const path = require('path');
|
||||
const { deployAndTest } = require('../../utils');
|
||||
|
||||
const ctx = {};
|
||||
|
||||
describe(`${__dirname.split(path.sep).pop()}`, () => {
|
||||
it('should deploy and pass probe checks', async () => {
|
||||
const info = await deployAndTest(__dirname);
|
||||
Object.assign(ctx, info);
|
||||
});
|
||||
});
|
||||
5
packages/next/test/fixtures/00-app-dir-edge-404/next.config.js
vendored
Normal file
5
packages/next/test/fixtures/00-app-dir-edge-404/next.config.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
experimental: {
|
||||
appDir: true,
|
||||
},
|
||||
};
|
||||
8
packages/next/test/fixtures/00-app-dir-edge-404/package.json
vendored
Normal file
8
packages/next/test/fixtures/00-app-dir-edge-404/package.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"next": "canary",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental"
|
||||
},
|
||||
"ignoreNextjsUpdates": true
|
||||
}
|
||||
20
packages/next/test/fixtures/00-app-dir-edge-404/vercel.json
vendored
Normal file
20
packages/next/test/fixtures/00-app-dir-edge-404/vercel.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"builds": [
|
||||
{
|
||||
"src": "package.json",
|
||||
"use": "@vercel/next"
|
||||
}
|
||||
],
|
||||
"probes": [
|
||||
{
|
||||
"path": "/",
|
||||
"status": 200,
|
||||
"mustContain": "My page"
|
||||
},
|
||||
{
|
||||
"path": "/not-found-page",
|
||||
"status": 404,
|
||||
"mustContain": "This Is The Not Found Page"
|
||||
}
|
||||
]
|
||||
}
|
||||
3
packages/next/test/fixtures/00-app-dir-i18n/app/api/hello-app/route.js
vendored
Normal file
3
packages/next/test/fixtures/00-app-dir-i18n/app/api/hello-app/route.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export function GET(req) {
|
||||
return new Response('hello world')
|
||||
}
|
||||
16
packages/next/test/fixtures/00-app-dir-i18n/app/dynamic/[slug]/page.js
vendored
Normal file
16
packages/next/test/fixtures/00-app-dir-i18n/app/dynamic/[slug]/page.js
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
export default function Page({ params: { slug } }) {
|
||||
return (
|
||||
<p>dynamic page {slug}</p>
|
||||
)
|
||||
}
|
||||
|
||||
export function generateStaticParams() {
|
||||
return [
|
||||
{
|
||||
slug: 'first',
|
||||
},
|
||||
{
|
||||
slug: 'second'
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -3,7 +3,7 @@ module.exports = {
|
||||
appDir: true,
|
||||
},
|
||||
i18n: {
|
||||
locales: ['en'],
|
||||
locales: ['en', 'fr', 'de'],
|
||||
defaultLocale: 'en',
|
||||
},
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user