mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-11 12:57:46 +00:00
Compare commits
86 Commits
api@0.0.0
...
@vercel-in
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a91bde5287 | ||
|
|
0750517af9 | ||
|
|
70f6782954 | ||
|
|
5f1e37ee16 | ||
|
|
680d666fdc | ||
|
|
06a5dccfed | ||
|
|
f85df894c0 | ||
|
|
e9ec779f1c | ||
|
|
4333d1e6b2 | ||
|
|
493a31091d | ||
|
|
8d7206f5b6 | ||
|
|
4bf2ca55ff | ||
|
|
5e5332fbc9 | ||
|
|
281ec776a5 | ||
|
|
ee8f9292b4 | ||
|
|
027bce00b3 | ||
|
|
ca1f41200a | ||
|
|
834b3e652b | ||
|
|
5c6941d18c | ||
|
|
761ede2482 | ||
|
|
1d01703dc3 | ||
|
|
7021279b28 | ||
|
|
28acf50bdf | ||
|
|
718bbd365a | ||
|
|
7e791ee080 | ||
|
|
13769106cb | ||
|
|
aa734efc6c | ||
|
|
acc10e47c7 | ||
|
|
6a0e1e0b66 | ||
|
|
3468922108 | ||
|
|
e4895d979b | ||
|
|
733ff5ed85 | ||
|
|
0867f11a6a | ||
|
|
a6de052ed2 | ||
|
|
f5d48ec3bc | ||
|
|
6ec1180798 | ||
|
|
36db62a491 | ||
|
|
f9266e069f | ||
|
|
8163a153df | ||
|
|
c5e6bd1a7a | ||
|
|
c2f1bebd1f | ||
|
|
3138415533 | ||
|
|
8f6813bb63 | ||
|
|
734499fc03 | ||
|
|
f06988d914 | ||
|
|
71ac16220b | ||
|
|
8b3a4146af | ||
|
|
cfea31e6cf | ||
|
|
7090fec110 | ||
|
|
bc7c80fb9b | ||
|
|
91406abdb0 | ||
|
|
a5af8381ce | ||
|
|
2230ea6cc1 | ||
|
|
f057f0421b | ||
|
|
42c0b32a8d | ||
|
|
d61a1a7988 | ||
|
|
c438bbb362 | ||
|
|
cb5eef0eb5 | ||
|
|
79dee367cf | ||
|
|
dea58dea7e | ||
|
|
fecebfa7fa | ||
|
|
94d5612dce | ||
|
|
3eaf58bb74 | ||
|
|
e63cf40153 | ||
|
|
709c9509f4 | ||
|
|
6107c1ed22 | ||
|
|
7a0f377afe | ||
|
|
a04bf557fc | ||
|
|
b6736e82cf | ||
|
|
7923056bc0 | ||
|
|
71ff193ea3 | ||
|
|
c21d93de44 | ||
|
|
0039c8b5ce | ||
|
|
49c7178567 | ||
|
|
b038b29614 | ||
|
|
7a249a2284 | ||
|
|
a5e32ec31d | ||
|
|
bc5afe24c4 | ||
|
|
5070e3bbbd | ||
|
|
4ad1cbbd7d | ||
|
|
4f4e09477d | ||
|
|
cd35071f60 | ||
|
|
f373c94508 | ||
|
|
553c001eb0 | ||
|
|
f6c3a95783 | ||
|
|
c0bcef0ca4 |
4
.github/CODEOWNERS
vendored
4
.github/CODEOWNERS
vendored
@@ -1,6 +1,7 @@
|
||||
# Documentation
|
||||
# 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
|
||||
@@ -14,3 +15,6 @@
|
||||
/examples/jekyll @styfle
|
||||
/examples/zola @styfle
|
||||
/packages/node @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @Kikobeats
|
||||
|
||||
# Unrestricted Paths
|
||||
.changeset/
|
||||
|
||||
16
.github/workflows/test-lint.yml
vendored
16
.github/workflows/test-lint.yml
vendored
@@ -19,6 +19,22 @@ concurrency:
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
||||
|
||||
jobs:
|
||||
enforce-changeset:
|
||||
name: Enforce Changeset
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.title != 'Version Packages'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: main
|
||||
- run: git checkout ${{ github.event.pull_request.head.ref }}
|
||||
- name: install pnpm@8.3.1
|
||||
run: npm i -g pnpm@8.3.1
|
||||
- run: pnpm install
|
||||
# Enforce a changeset file to be present
|
||||
- run: pnpm exec changeset status --since=main
|
||||
|
||||
test:
|
||||
name: Lint
|
||||
timeout-minutes: 10
|
||||
|
||||
520
examples/nextjs/package-lock.json
generated
520
examples/nextjs/package-lock.json
generated
@@ -8,17 +8,25 @@
|
||||
"name": "nextjs",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"eslint": "8.41.0",
|
||||
"eslint-config-next": "13.4.4",
|
||||
"next": "13.4.4",
|
||||
"eslint": "8.44.0",
|
||||
"eslint-config-next": "13.4.9",
|
||||
"next": "13.4.9",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@aashutoshrathi/word-wrap": {
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
|
||||
"integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.21.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz",
|
||||
"integrity": "sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==",
|
||||
"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"
|
||||
},
|
||||
@@ -49,13 +57,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz",
|
||||
"integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==",
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz",
|
||||
"integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==",
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.5.2",
|
||||
"espree": "^9.6.0",
|
||||
"globals": "^13.19.0",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
@@ -71,17 +79,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "8.41.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.41.0.tgz",
|
||||
"integrity": "sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==",
|
||||
"version": "8.44.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz",
|
||||
"integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/config-array": {
|
||||
"version": "0.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz",
|
||||
"integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==",
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
|
||||
"integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==",
|
||||
"dependencies": {
|
||||
"@humanwhocodes/object-schema": "^1.2.1",
|
||||
"debug": "^4.1.1",
|
||||
@@ -109,22 +117,22 @@
|
||||
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
|
||||
},
|
||||
"node_modules/@next/env": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.4.tgz",
|
||||
"integrity": "sha512-q/y7VZj/9YpgzDe64Zi6rY1xPizx80JjlU2BTevlajtaE3w1LqweH1gGgxou2N7hdFosXHjGrI4OUvtFXXhGLg=="
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.9.tgz",
|
||||
"integrity": "sha512-vuDRK05BOKfmoBYLNi2cujG2jrYbEod/ubSSyqgmEx9n/W3eZaJQdRNhTfumO+qmq/QTzLurW487n/PM/fHOkw=="
|
||||
},
|
||||
"node_modules/@next/eslint-plugin-next": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.4.tgz",
|
||||
"integrity": "sha512-5jnh7q6I15efnjR/rR+/TGTc9hn53g3JTbEjAMjmeQiExKqEUgIXqrHI5zlTNlNyzCPkBB860/ctxXheZaF2Vw==",
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.9.tgz",
|
||||
"integrity": "sha512-nDtGpa992tNyAkT/KmSMy7QkHfNZmGCBYhHtafU97DubqxzNdvLsqRtliQ4FU04CysRCtvP2hg8rRC1sAKUTUA==",
|
||||
"dependencies": {
|
||||
"glob": "7.1.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-darwin-arm64": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.4.tgz",
|
||||
"integrity": "sha512-xfjgXvp4KalNUKZMHmsFxr1Ug+aGmmO6NWP0uoh4G3WFqP/mJ1xxfww0gMOeMeSq/Jyr5k7DvoZ2Pv+XOITTtw==",
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.9.tgz",
|
||||
"integrity": "sha512-TVzGHpZoVBk3iDsTOQA/R6MGmFp0+17SWXMEWd6zG30AfuELmSSMe2SdPqxwXU0gbpWkJL1KgfLzy5ReN0crqQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -137,9 +145,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-darwin-x64": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.4.tgz",
|
||||
"integrity": "sha512-ZY9Ti1hkIwJsxGus3nlubIkvYyB0gNOYxKrfsOrLEqD0I2iCX8D7w8v6QQZ2H+dDl6UT29oeEUdDUNGk4UEpfg==",
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.9.tgz",
|
||||
"integrity": "sha512-aSfF1fhv28N2e7vrDZ6zOQ+IIthocfaxuMWGReB5GDriF0caTqtHttAvzOMgJgXQtQx6XhyaJMozLTSEXeNN+A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -152,9 +160,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-gnu": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.4.tgz",
|
||||
"integrity": "sha512-+KZnDeMShYkpkqAvGCEDeqYTRADJXc6SY1jWXz+Uo6qWQO/Jd9CoyhTJwRSxvQA16MoYzvILkGaDqirkRNctyA==",
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.9.tgz",
|
||||
"integrity": "sha512-JhKoX5ECzYoTVyIy/7KykeO4Z2lVKq7HGQqvAH+Ip9UFn1MOJkOnkPRB7v4nmzqAoY+Je05Aj5wNABR1N18DMg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -167,9 +175,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-arm64-musl": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.4.tgz",
|
||||
"integrity": "sha512-evC1twrny2XDT4uOftoubZvW3EG0zs0ZxMwEtu/dDGVRO5n5pT48S8qqEIBGBUZYu/Xx4zzpOkIxx1vpWdE+9A==",
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.9.tgz",
|
||||
"integrity": "sha512-OOn6zZBIVkm/4j5gkPdGn4yqQt+gmXaLaSjRSO434WplV8vo2YaBNbSHaTM9wJpZTHVDYyjzuIYVEzy9/5RVZw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -182,9 +190,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-gnu": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.4.tgz",
|
||||
"integrity": "sha512-PX706XcCHr2FfkyhP2lpf+pX/tUvq6/ke7JYnnr0ykNdEMo+sb7cC/o91gnURh4sPYSiZJhsF2gbIqg9rciOHQ==",
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.9.tgz",
|
||||
"integrity": "sha512-iA+fJXFPpW0SwGmx/pivVU+2t4zQHNOOAr5T378PfxPHY6JtjV6/0s1vlAJUdIHeVpX98CLp9k5VuKgxiRHUpg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -197,9 +205,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-linux-x64-musl": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.4.tgz",
|
||||
"integrity": "sha512-TKUUx3Ftd95JlHV6XagEnqpT204Y+IsEa3awaYIjayn0MOGjgKZMZibqarK3B1FsMSPaieJf2FEAcu9z0yT5aA==",
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.9.tgz",
|
||||
"integrity": "sha512-rlNf2WUtMM+GAQrZ9gMNdSapkVi3koSW3a+dmBVp42lfugWVvnyzca/xJlN48/7AGx8qu62WyO0ya1ikgOxh6A==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -212,9 +220,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-arm64-msvc": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.4.tgz",
|
||||
"integrity": "sha512-FP8AadgSq4+HPtim7WBkCMGbhr5vh9FePXiWx9+YOdjwdQocwoCK5ZVC3OW8oh3TWth6iJ0AXJ/yQ1q1cwSZ3A==",
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.9.tgz",
|
||||
"integrity": "sha512-5T9ybSugXP77nw03vlgKZxD99AFTHaX8eT1ayKYYnGO9nmYhJjRPxcjU5FyYI+TdkQgEpIcH7p/guPLPR0EbKA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -227,9 +235,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-ia32-msvc": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.4.tgz",
|
||||
"integrity": "sha512-3WekVmtuA2MCdcAOrgrI+PuFiFURtSyyrN1I3UPtS0ckR2HtLqyqmS334Eulf15g1/bdwMteePdK363X/Y9JMg==",
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.9.tgz",
|
||||
"integrity": "sha512-ojZTCt1lP2ucgpoiFgrFj07uq4CZsq4crVXpLGgQfoFq00jPKRPgesuGPaz8lg1yLfvafkU3Jd1i8snKwYR3LA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -242,9 +250,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@next/swc-win32-x64-msvc": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.4.tgz",
|
||||
"integrity": "sha512-AHRITu/CrlQ+qzoqQtEMfaTu7GHaQ6bziQln/pVWpOYC1wU+Mq6VQQFlsDtMCnDztPZtppAXdvvbNS7pcfRzlw==",
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.9.tgz",
|
||||
"integrity": "sha512-QbT03FXRNdpuL+e9pLnu+XajZdm/TtIXVYY4lA9t+9l0fLZbHXDYEKitAqxrOj37o3Vx5ufxiRAniaIebYDCgw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -289,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"
|
||||
@@ -308,9 +316,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rushstack/eslint-patch": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.0.tgz",
|
||||
"integrity": "sha512-IthPJsJR85GhOkp3Hvp8zFOPK5ynKn6STyHa/WZpioK7E1aYDiBzpqQPrngc14DszIUkIrdd3k9Iu0XSzlP/1w=="
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.2.tgz",
|
||||
"integrity": "sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw=="
|
||||
},
|
||||
"node_modules/@swc/helpers": {
|
||||
"version": "0.5.1",
|
||||
@@ -326,13 +334,13 @@
|
||||
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "5.59.7",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.7.tgz",
|
||||
"integrity": "sha512-VhpsIEuq/8i5SF+mPg9jSdIwgMBBp0z9XqjiEay+81PYLJuroN+ET1hM5IhkiYMJd9MkTz8iJLt7aaGAgzWUbQ==",
|
||||
"version": "5.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.61.0.tgz",
|
||||
"integrity": "sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "5.59.7",
|
||||
"@typescript-eslint/types": "5.59.7",
|
||||
"@typescript-eslint/typescript-estree": "5.59.7",
|
||||
"@typescript-eslint/scope-manager": "5.61.0",
|
||||
"@typescript-eslint/types": "5.61.0",
|
||||
"@typescript-eslint/typescript-estree": "5.61.0",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
@@ -352,12 +360,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "5.59.7",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.7.tgz",
|
||||
"integrity": "sha512-FL6hkYWK9zBGdxT2wWEd2W8ocXMu3K94i3gvMrjXpx+koFYdYV7KprKfirpgY34vTGzEPPuKoERpP8kD5h7vZQ==",
|
||||
"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==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.59.7",
|
||||
"@typescript-eslint/visitor-keys": "5.59.7"
|
||||
"@typescript-eslint/types": "5.61.0",
|
||||
"@typescript-eslint/visitor-keys": "5.61.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
@@ -368,9 +376,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "5.59.7",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.7.tgz",
|
||||
"integrity": "sha512-UnVS2MRRg6p7xOSATscWkKjlf/NDKuqo5TdbWck6rIRZbmKpVNTLALzNvcjIfHBE7736kZOFc/4Z3VcZwuOM/A==",
|
||||
"version": "5.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.61.0.tgz",
|
||||
"integrity": "sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
@@ -380,12 +388,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "5.59.7",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.7.tgz",
|
||||
"integrity": "sha512-4A1NtZ1I3wMN2UGDkU9HMBL+TIQfbrh4uS0WDMMpf3xMRursDbqEf1ahh6vAAe3mObt8k3ZATnezwG4pdtWuUQ==",
|
||||
"version": "5.61.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.61.0.tgz",
|
||||
"integrity": "sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.59.7",
|
||||
"@typescript-eslint/visitor-keys": "5.59.7",
|
||||
"@typescript-eslint/types": "5.61.0",
|
||||
"@typescript-eslint/visitor-keys": "5.61.0",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
@@ -406,11 +414,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "5.59.7",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.7.tgz",
|
||||
"integrity": "sha512-tyN+X2jvMslUszIiYbF0ZleP+RqQsFVpGrKI6e0Eet1w8WmhsAtmzaqm8oM8WJQ1ysLwhnsK/4hYHJjOgJVfQQ==",
|
||||
"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==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.59.7",
|
||||
"@typescript-eslint/types": "5.61.0",
|
||||
"eslint-visitor-keys": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -422,9 +430,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.8.2",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
|
||||
"integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
|
||||
"version": "8.10.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
|
||||
"integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
@@ -483,11 +491,11 @@
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/aria-query": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz",
|
||||
"integrity": "sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==",
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz",
|
||||
"integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==",
|
||||
"dependencies": {
|
||||
"deep-equal": "^2.0.5"
|
||||
"dequal": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/array-buffer-byte-length": {
|
||||
@@ -599,11 +607,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/axobject-query": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz",
|
||||
"integrity": "sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg==",
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz",
|
||||
"integrity": "sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg==",
|
||||
"dependencies": {
|
||||
"deep-equal": "^2.0.5"
|
||||
"dequal": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
@@ -696,9 +704,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001489",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001489.tgz",
|
||||
"integrity": "sha512-x1mgZEXK8jHIfAxm+xgdpHpk50IN3z3q3zP261/WS+uvePxW8izXuCu6AHz0lkuYTlATDehiZ/tNyYBdSQsOUQ==",
|
||||
"version": "1.0.30001512",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001512.tgz",
|
||||
"integrity": "sha512-2S9nK0G/mE+jasCUsMPlARhRCts1ebcp2Ji8Y8PWi4NDE1iRdLCnEPHkEfeBrGC45L4isBx5ur3IQ6yTE2mRZw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -789,34 +797,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/deep-equal": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz",
|
||||
"integrity": "sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ==",
|
||||
"dependencies": {
|
||||
"array-buffer-byte-length": "^1.0.0",
|
||||
"call-bind": "^1.0.2",
|
||||
"es-get-iterator": "^1.1.3",
|
||||
"get-intrinsic": "^1.2.0",
|
||||
"is-arguments": "^1.1.1",
|
||||
"is-array-buffer": "^3.0.2",
|
||||
"is-date-object": "^1.0.5",
|
||||
"is-regex": "^1.1.4",
|
||||
"is-shared-array-buffer": "^1.0.2",
|
||||
"isarray": "^2.0.5",
|
||||
"object-is": "^1.1.5",
|
||||
"object-keys": "^1.1.1",
|
||||
"object.assign": "^4.1.4",
|
||||
"regexp.prototype.flags": "^1.5.0",
|
||||
"side-channel": "^1.0.4",
|
||||
"which-boxed-primitive": "^1.0.2",
|
||||
"which-collection": "^1.0.1",
|
||||
"which-typed-array": "^1.1.9"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/deep-is": {
|
||||
"version": "0.1.4",
|
||||
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
|
||||
@@ -880,6 +860,14 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/dequal": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/dir-glob": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
@@ -908,9 +896,9 @@
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
|
||||
},
|
||||
"node_modules/enhanced-resolve": {
|
||||
"version": "5.14.1",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz",
|
||||
"integrity": "sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==",
|
||||
"version": "5.15.0",
|
||||
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz",
|
||||
"integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.4",
|
||||
"tapable": "^2.2.0"
|
||||
@@ -966,25 +954,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/es-get-iterator": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz",
|
||||
"integrity": "sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"get-intrinsic": "^1.1.3",
|
||||
"has-symbols": "^1.0.3",
|
||||
"is-arguments": "^1.1.1",
|
||||
"is-map": "^2.0.2",
|
||||
"is-set": "^2.0.2",
|
||||
"is-string": "^1.0.7",
|
||||
"isarray": "^2.0.5",
|
||||
"stop-iteration-iterator": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/es-set-tostringtag": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
|
||||
@@ -1034,15 +1003,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "8.41.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.41.0.tgz",
|
||||
"integrity": "sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==",
|
||||
"version": "8.44.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz",
|
||||
"integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.2.0",
|
||||
"@eslint-community/regexpp": "^4.4.0",
|
||||
"@eslint/eslintrc": "^2.0.3",
|
||||
"@eslint/js": "8.41.0",
|
||||
"@humanwhocodes/config-array": "^0.11.8",
|
||||
"@eslint/eslintrc": "^2.1.0",
|
||||
"@eslint/js": "8.44.0",
|
||||
"@humanwhocodes/config-array": "^0.11.10",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@nodelib/fs.walk": "^1.2.8",
|
||||
"ajv": "^6.10.0",
|
||||
@@ -1053,7 +1022,7 @@
|
||||
"escape-string-regexp": "^4.0.0",
|
||||
"eslint-scope": "^7.2.0",
|
||||
"eslint-visitor-keys": "^3.4.1",
|
||||
"espree": "^9.5.2",
|
||||
"espree": "^9.6.0",
|
||||
"esquery": "^1.4.2",
|
||||
"esutils": "^2.0.2",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
@@ -1073,7 +1042,7 @@
|
||||
"lodash.merge": "^4.6.2",
|
||||
"minimatch": "^3.1.2",
|
||||
"natural-compare": "^1.4.0",
|
||||
"optionator": "^0.9.1",
|
||||
"optionator": "^0.9.3",
|
||||
"strip-ansi": "^6.0.1",
|
||||
"strip-json-comments": "^3.1.0",
|
||||
"text-table": "^0.2.0"
|
||||
@@ -1089,11 +1058,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-config-next": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.4.4.tgz",
|
||||
"integrity": "sha512-z/PMbm6L0iC/fwISULxe8IVy4DtNqZk2wQY711o35klenq70O6ns82A8yuMVCFjHC0DIyB2lyugesRtuk9u8dQ==",
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.4.9.tgz",
|
||||
"integrity": "sha512-0fLtKRR268NArpqeXXwnLgMXPvF64YESQvptVg+RMLCaijKm3FICN9Y7Jc1p2o+yrWwE4DufJXDM/Vo53D1L7g==",
|
||||
"dependencies": {
|
||||
"@next/eslint-plugin-next": "13.4.4",
|
||||
"@next/eslint-plugin-next": "13.4.9",
|
||||
"@rushstack/eslint-patch": "^1.1.3",
|
||||
"@typescript-eslint/parser": "^5.42.0",
|
||||
"eslint-import-resolver-node": "^0.3.6",
|
||||
@@ -1101,7 +1070,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",
|
||||
@@ -1157,13 +1126,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-import-resolver-typescript/node_modules/globby": {
|
||||
"version": "13.1.4",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-13.1.4.tgz",
|
||||
"integrity": "sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g==",
|
||||
"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"
|
||||
},
|
||||
@@ -1330,9 +1299,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"
|
||||
},
|
||||
@@ -1402,11 +1371,11 @@
|
||||
}
|
||||
},
|
||||
"node_modules/espree": {
|
||||
"version": "9.5.2",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
|
||||
"integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
|
||||
"version": "9.6.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz",
|
||||
"integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==",
|
||||
"dependencies": {
|
||||
"acorn": "^8.8.0",
|
||||
"acorn": "^8.9.0",
|
||||
"acorn-jsx": "^5.3.2",
|
||||
"eslint-visitor-keys": "^3.4.1"
|
||||
},
|
||||
@@ -1483,9 +1452,9 @@
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
},
|
||||
"node_modules/fast-glob": {
|
||||
"version": "3.2.12",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz",
|
||||
"integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==",
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz",
|
||||
"integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==",
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
"@nodelib/fs.walk": "^1.2.3",
|
||||
@@ -1664,9 +1633,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/get-tsconfig": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.5.0.tgz",
|
||||
"integrity": "sha512-MjhiaIWCJ1sAU4pIQ5i5OfOuHHxVo1oYeNsWTON7jxYkod8pHocXeh+SSbmu5OZZZK73B6cbJ2XADzXehLyovQ==",
|
||||
"version": "4.6.2",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.6.2.tgz",
|
||||
"integrity": "sha512-E5XrT4CbbXcXWy+1jChlZmrmCwd5KGx502kDCXJJ7y898TtWW9FwoG5HfOLVRKmlmDGkWN2HM9Ho+/Y8F0sJDg==",
|
||||
"dependencies": {
|
||||
"resolve-pkg-maps": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
||||
}
|
||||
@@ -1701,6 +1673,11 @@
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/glob-to-regexp": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
|
||||
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
|
||||
},
|
||||
"node_modules/globals": {
|
||||
"version": "13.20.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
|
||||
@@ -1909,21 +1886,6 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-arguments": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
|
||||
"integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"has-tostringtag": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-array-buffer": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
|
||||
@@ -2049,14 +2011,6 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/is-map": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
|
||||
"integrity": "sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-negative-zero": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz",
|
||||
@@ -2113,14 +2067,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-set": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz",
|
||||
"integrity": "sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-shared-array-buffer": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz",
|
||||
@@ -2189,14 +2135,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-weakmap": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz",
|
||||
"integrity": "sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-weakref": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
|
||||
@@ -2208,18 +2146,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-weakset": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz",
|
||||
"integrity": "sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"get-intrinsic": "^1.1.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-wsl": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",
|
||||
@@ -2245,11 +2171,6 @@
|
||||
"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",
|
||||
@@ -2293,12 +2214,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/jsx-ast-utils": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz",
|
||||
"integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==",
|
||||
"version": "3.3.4",
|
||||
"resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.4.tgz",
|
||||
"integrity": "sha512-fX2TVdCViod6HwKEtSWGHs57oFhVfCMwieb9PuRDgjDPh5XeqJiHFFFJCHxU5cnTc3Bu/GRL+kPiFmw8XWOfKw==",
|
||||
"dependencies": {
|
||||
"array-includes": "^3.1.5",
|
||||
"object.assign": "^4.1.3"
|
||||
"array-includes": "^3.1.6",
|
||||
"array.prototype.flat": "^1.3.1",
|
||||
"object.assign": "^4.1.4",
|
||||
"object.values": "^1.1.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
@@ -2453,16 +2376,17 @@
|
||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
|
||||
},
|
||||
"node_modules/next": {
|
||||
"version": "13.4.4",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-13.4.4.tgz",
|
||||
"integrity": "sha512-C5S0ysM0Ily9McL4Jb48nOQHT1BukOWI59uC3X/xCMlYIh9rJZCv7nzG92J6e1cOBqQbKovlpgvHWFmz4eKKEA==",
|
||||
"version": "13.4.9",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-13.4.9.tgz",
|
||||
"integrity": "sha512-vtefFm/BWIi/eWOqf1GsmKG3cjKw1k3LjuefKRcL3iiLl3zWzFdPG3as6xtxrGO6gwTzzaO1ktL4oiHt/uvTjA==",
|
||||
"dependencies": {
|
||||
"@next/env": "13.4.4",
|
||||
"@next/env": "13.4.9",
|
||||
"@swc/helpers": "0.5.1",
|
||||
"busboy": "1.6.0",
|
||||
"caniuse-lite": "^1.0.30001406",
|
||||
"postcss": "8.4.14",
|
||||
"styled-jsx": "5.1.1",
|
||||
"watchpack": "2.4.0",
|
||||
"zod": "3.21.4"
|
||||
},
|
||||
"bin": {
|
||||
@@ -2472,15 +2396,15 @@
|
||||
"node": ">=16.8.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@next/swc-darwin-arm64": "13.4.4",
|
||||
"@next/swc-darwin-x64": "13.4.4",
|
||||
"@next/swc-linux-arm64-gnu": "13.4.4",
|
||||
"@next/swc-linux-arm64-musl": "13.4.4",
|
||||
"@next/swc-linux-x64-gnu": "13.4.4",
|
||||
"@next/swc-linux-x64-musl": "13.4.4",
|
||||
"@next/swc-win32-arm64-msvc": "13.4.4",
|
||||
"@next/swc-win32-ia32-msvc": "13.4.4",
|
||||
"@next/swc-win32-x64-msvc": "13.4.4"
|
||||
"@next/swc-darwin-arm64": "13.4.9",
|
||||
"@next/swc-darwin-x64": "13.4.9",
|
||||
"@next/swc-linux-arm64-gnu": "13.4.9",
|
||||
"@next/swc-linux-arm64-musl": "13.4.9",
|
||||
"@next/swc-linux-x64-gnu": "13.4.9",
|
||||
"@next/swc-linux-x64-musl": "13.4.9",
|
||||
"@next/swc-win32-arm64-msvc": "13.4.9",
|
||||
"@next/swc-win32-ia32-msvc": "13.4.9",
|
||||
"@next/swc-win32-x64-msvc": "13.4.9"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentelemetry/api": "^1.1.0",
|
||||
@@ -2542,21 +2466,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/object-is": {
|
||||
"version": "1.1.5",
|
||||
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz",
|
||||
"integrity": "sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.2",
|
||||
"define-properties": "^1.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/object-keys": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
|
||||
@@ -2679,16 +2588,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/optionator": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
|
||||
"integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==",
|
||||
"version": "0.9.3",
|
||||
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
|
||||
"integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
|
||||
"dependencies": {
|
||||
"@aashutoshrathi/word-wrap": "^1.2.3",
|
||||
"deep-is": "^0.1.3",
|
||||
"fast-levenshtein": "^2.0.6",
|
||||
"levn": "^0.4.1",
|
||||
"prelude-ls": "^1.2.1",
|
||||
"type-check": "^0.4.0",
|
||||
"word-wrap": "^1.2.3"
|
||||
"type-check": "^0.4.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
@@ -2927,6 +2836,14 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/resolve-pkg-maps": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
|
||||
"integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
|
||||
"funding": {
|
||||
"url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
@@ -3090,9 +3007,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.5.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
|
||||
"integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
|
||||
"version": "7.5.3",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
|
||||
"integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
@@ -3156,17 +3073,6 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/stop-iteration-iterator": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz",
|
||||
"integrity": "sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==",
|
||||
"dependencies": {
|
||||
"internal-slot": "^1.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/streamsearch": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz",
|
||||
@@ -3382,9 +3288,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.5.2",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz",
|
||||
"integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA=="
|
||||
"version": "2.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.0.tgz",
|
||||
"integrity": "sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA=="
|
||||
},
|
||||
"node_modules/tsutils": {
|
||||
"version": "3.21.0",
|
||||
@@ -3441,16 +3347,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
|
||||
"integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.6.tgz",
|
||||
"integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.20"
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/unbox-primitive": {
|
||||
@@ -3483,6 +3389,18 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/watchpack": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz",
|
||||
"integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==",
|
||||
"dependencies": {
|
||||
"glob-to-regexp": "^0.4.1",
|
||||
"graceful-fs": "^4.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.13.0"
|
||||
}
|
||||
},
|
||||
"node_modules/which": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
@@ -3512,20 +3430,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/which-collection": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz",
|
||||
"integrity": "sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==",
|
||||
"dependencies": {
|
||||
"is-map": "^2.0.1",
|
||||
"is-set": "^2.0.1",
|
||||
"is-weakmap": "^2.0.1",
|
||||
"is-weakset": "^2.0.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/which-typed-array": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
|
||||
@@ -3545,14 +3449,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/word-wrap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint": "8.41.0",
|
||||
"eslint-config-next": "13.4.4",
|
||||
"next": "13.4.4",
|
||||
"eslint": "8.44.0",
|
||||
"eslint-config-next": "13.4.9",
|
||||
"next": "13.4.9",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
}
|
||||
|
||||
2
examples/package.json
vendored
2
examples/package.json
vendored
@@ -9,6 +9,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "27.4.1",
|
||||
"@vercel/frameworks": "1.4.2"
|
||||
"@vercel/frameworks": "1.4.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node"],
|
||||
};
|
||||
|
||||
7
examples/remix/.gitignore
vendored
7
examples/remix/.gitignore
vendored
@@ -1,11 +1,12 @@
|
||||
node_modules
|
||||
|
||||
.cache
|
||||
/.cache
|
||||
/build
|
||||
/public/build
|
||||
.env
|
||||
|
||||
.vercel
|
||||
.output
|
||||
|
||||
/build/
|
||||
/public/build
|
||||
/api/index.js
|
||||
/api/index.js.map
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MetaFunction } from "@vercel/remix";
|
||||
import { cssBundleHref } from "@remix-run/css-bundle";
|
||||
import {
|
||||
Links,
|
||||
LiveReload,
|
||||
@@ -8,17 +8,18 @@ import {
|
||||
ScrollRestoration,
|
||||
} from "@remix-run/react";
|
||||
import { Analytics } from "@vercel/analytics/react";
|
||||
import type { LinksFunction } from "@vercel/remix";
|
||||
|
||||
export const meta: MetaFunction = () => ({
|
||||
charset: "utf-8",
|
||||
title: "New Remix App",
|
||||
viewport: "width=device-width,initial-scale=1",
|
||||
});
|
||||
export const links: LinksFunction = () => [
|
||||
...(cssBundleHref ? [{ rel: "stylesheet", href: cssBundleHref }] : []),
|
||||
];
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charSet="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<Meta />
|
||||
<Links />
|
||||
</head>
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
import type { V2_MetaFunction } from "@vercel/remix";
|
||||
|
||||
export const meta: V2_MetaFunction = () => [{ title: "New Remix App" }];
|
||||
|
||||
export default function Index() {
|
||||
return (
|
||||
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
|
||||
@@ -1,5 +1,9 @@
|
||||
import type { V2_MetaFunction } from "@vercel/remix";
|
||||
|
||||
export const config = { runtime: "edge" };
|
||||
|
||||
export const meta: V2_MetaFunction = () => [{ title: "Remix@Edge | New Remix App" }];
|
||||
|
||||
export default function Edge() {
|
||||
return (
|
||||
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
|
||||
|
||||
@@ -3,24 +3,28 @@
|
||||
"sideEffects": false,
|
||||
"scripts": {
|
||||
"build": "remix build",
|
||||
"dev": "remix dev"
|
||||
"dev": "remix dev",
|
||||
"start": "remix-serve build",
|
||||
"typecheck": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@remix-run/node": "^1.15.0",
|
||||
"@remix-run/react": "^1.15.0",
|
||||
"@remix-run/serve": "^1.15.0",
|
||||
"@remix-run/css-bundle": "^1.18.0",
|
||||
"@remix-run/node": "^1.18.0",
|
||||
"@remix-run/react": "^1.18.0",
|
||||
"@remix-run/serve": "^1.18.0",
|
||||
"@vercel/analytics": "^0.1.11",
|
||||
"@vercel/remix": "^1.15.0",
|
||||
"@vercel/remix": "^1.18.0",
|
||||
"isbot": "^3.6.8",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@remix-run/dev": "^1.15.0",
|
||||
"@remix-run/eslint-config": "^1.15.0",
|
||||
"@remix-run/dev": "^1.18.0",
|
||||
"@remix-run/eslint-config": "^1.18.0",
|
||||
"@types/react": "^18.0.25",
|
||||
"@types/react-dom": "^18.0.11",
|
||||
"eslint": "^8.28.0",
|
||||
"typescript": "^4.9.3"
|
||||
"typescript": "^5.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
|
||||
7492
examples/remix/pnpm-lock.yaml
generated
7492
examples/remix/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,8 +1,15 @@
|
||||
/**
|
||||
* @type {import('@remix-run/dev').AppConfig}
|
||||
*/
|
||||
/** @type {import('@remix-run/dev').AppConfig} */
|
||||
module.exports = {
|
||||
ignoredRouteFiles: ['**/.*'],
|
||||
future: {
|
||||
v2_dev: true,
|
||||
v2_errorBoundary: true,
|
||||
v2_headers: true,
|
||||
v2_meta: true,
|
||||
v2_normalizeFormMethod: true,
|
||||
v2_routeConvention: true,
|
||||
},
|
||||
ignoredRouteFiles: ["**/.*"],
|
||||
serverModuleFormat: "cjs",
|
||||
// appDirectory: "app",
|
||||
// assetsBuildDirectory: "public/build",
|
||||
// serverBuildPath: "build/index.js",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Saber Example
|
||||
|
||||
This directory is a brief example of a [Saber](https://saber.land) site that can be deployed to Vercel with zero configuration.
|
||||
This directory is a brief example of a [Saber](https://saber.egoist.dev) site that can be deployed to Vercel with zero configuration.
|
||||
|
||||
## Deploy Your Own
|
||||
|
||||
|
||||
@@ -5,4 +5,4 @@ layout: page
|
||||
|
||||
This is the Saber port of the base Jekyll theme. Check out the [GitHub project](https://github.com/egoist/saber-theme-minima) for detailed usages.
|
||||
|
||||
You can find out more info about customizing your theme, as well as basic Saber usage documentation at https://saber.land
|
||||
You can find out more info about customizing your theme, as well as basic Saber usage documentation at https://saber.egoist.dev
|
||||
|
||||
4
examples/storybook/vercel.json
Normal file
4
examples/storybook/vercel.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"framework": "storybook",
|
||||
"buildCommand": "storybook build"
|
||||
}
|
||||
@@ -1,5 +1,25 @@
|
||||
# @vercel-internals/constants
|
||||
|
||||
## 1.0.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Create new help output and arg parsing for deploy command ([#10090](https://github.com/vercel/vercel/pull/10090))
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`346892210`](https://github.com/vercel/vercel/commit/3468922108f411482a72acd0331f0f2ee52a6d4c)]:
|
||||
- @vercel/build-utils@6.8.0
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
|
||||
- @vercel/build-utils@6.7.5
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@vercel-internals/constants",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.4",
|
||||
"types": "dist/index.d.ts",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/routing-utils": "2.2.1"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@vercel-internals/tsconfig": "1.0.0",
|
||||
"@vercel/style-guide": "4.0.2",
|
||||
|
||||
@@ -3,3 +3,7 @@ export const PROJECT_ENV_TARGET = [
|
||||
'preview',
|
||||
'development',
|
||||
] as const;
|
||||
|
||||
export const LOGO = '▲' as const;
|
||||
export const NAME = 'vercel' as const;
|
||||
export const TITLE = 'Vercel' as const;
|
||||
|
||||
@@ -1,5 +1,36 @@
|
||||
# @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
|
||||
|
||||
- Updated dependencies [[`7021279b2`](https://github.com/vercel/vercel/commit/7021279b284f314a4d1bdbb4306b4c22291efa08), [`718bbd365`](https://github.com/vercel/vercel/commit/718bbd365a50271a980bdca231ca801a0eead32b)]:
|
||||
- @vercel/build-utils@6.8.1
|
||||
- @vercel-internals/constants@1.0.4
|
||||
|
||||
## 1.0.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`346892210`](https://github.com/vercel/vercel/commit/3468922108f411482a72acd0331f0f2ee52a6d4c)]:
|
||||
- @vercel/build-utils@6.8.0
|
||||
- @vercel-internals/constants@1.0.3
|
||||
|
||||
## 1.0.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
|
||||
- @vercel/build-utils@6.7.5
|
||||
- @vercel-internals/constants@1.0.2
|
||||
|
||||
## 1.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
67
internals/types/index.d.ts
vendored
67
internals/types/index.d.ts
vendored
@@ -1,5 +1,6 @@
|
||||
import type { BuilderFunctions } from '@vercel/build-utils';
|
||||
import type { Readable, Writable } from 'stream';
|
||||
import type * as tty from 'tty';
|
||||
import type { Route } from '@vercel/routing-utils';
|
||||
import { PROJECT_ENV_TARGET } from '@vercel-internals/constants';
|
||||
|
||||
@@ -378,28 +379,60 @@ export interface ProjectLink {
|
||||
* to the root directory of the repository.
|
||||
*/
|
||||
repoRoot?: string;
|
||||
/**
|
||||
* When linked as a repository, contains the relative path
|
||||
* to the selected project root directory.
|
||||
*/
|
||||
projectRootDirectory?: string;
|
||||
}
|
||||
|
||||
export interface PaginationOptions {
|
||||
prev: number;
|
||||
/**
|
||||
* Amount of items in the current page.
|
||||
* @example 20
|
||||
*/
|
||||
count: number;
|
||||
next?: number;
|
||||
/**
|
||||
* Timestamp that must be used to request the next page.
|
||||
* @example 1540095775951
|
||||
*/
|
||||
next: number | null;
|
||||
/**
|
||||
* Timestamp that must be used to request the previous page.
|
||||
* @example 1540095775951
|
||||
*/
|
||||
prev: number | null;
|
||||
}
|
||||
|
||||
export type ProjectLinked = {
|
||||
status: 'linked';
|
||||
org: Org;
|
||||
project: Project;
|
||||
repoRoot?: string;
|
||||
};
|
||||
|
||||
export type ProjectNotLinked = {
|
||||
status: 'not_linked';
|
||||
org: null;
|
||||
project: null;
|
||||
};
|
||||
|
||||
export type ProjectLinkedError = {
|
||||
status: 'error';
|
||||
exitCode: number;
|
||||
reason?:
|
||||
| 'HEADLESS'
|
||||
| 'NOT_AUTHORIZED'
|
||||
| 'TEAM_DELETED'
|
||||
| 'PATH_IS_FILE'
|
||||
| 'INVALID_ROOT_DIRECTORY'
|
||||
| 'MISSING_PROJECT_SETTINGS';
|
||||
};
|
||||
|
||||
export type ProjectLinkResult =
|
||||
| { status: 'linked'; org: Org; project: Project; repoRoot?: string }
|
||||
| { status: 'not_linked'; org: null; project: null }
|
||||
| {
|
||||
status: 'error';
|
||||
exitCode: number;
|
||||
reason?:
|
||||
| 'HEADLESS'
|
||||
| 'NOT_AUTHORIZED'
|
||||
| 'TEAM_DELETED'
|
||||
| 'PATH_IS_FILE'
|
||||
| 'INVALID_ROOT_DIRECTORY'
|
||||
| 'MISSING_PROJECT_SETTINGS';
|
||||
};
|
||||
| ProjectLinked
|
||||
| ProjectNotLinked
|
||||
| ProjectLinkedError;
|
||||
|
||||
/**
|
||||
* @deprecated - `RollbackJobStatus` has been replace by `LastAliasRequest['jobStatus']`.
|
||||
@@ -599,6 +632,6 @@ export interface WritableTTY extends Writable {
|
||||
|
||||
export interface Stdio {
|
||||
stdin: ReadableTTY;
|
||||
stdout: WritableTTY;
|
||||
stderr: WritableTTY;
|
||||
stdout: tty.WriteStream;
|
||||
stderr: tty.WriteStream;
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@vercel-internals/types",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.5",
|
||||
"types": "index.d.ts",
|
||||
"main": "index.d.ts",
|
||||
"dependencies": {
|
||||
"@types/node": "14.14.31",
|
||||
"@vercel-internals/constants": "1.0.1",
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel-internals/constants": "1.0.4",
|
||||
"@vercel/build-utils": "6.8.2",
|
||||
"@vercel/routing-utils": "2.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
13
lerna.json
13
lerna.json
@@ -1,13 +0,0 @@
|
||||
{
|
||||
"npmClient": "pnpm",
|
||||
"useWorkspaces": true,
|
||||
"packages": ["packages/*"],
|
||||
"command": {
|
||||
"publish": {
|
||||
"npmClient": "npm",
|
||||
"allowBranch": ["main"],
|
||||
"registry": "https://registry.npmjs.org/"
|
||||
}
|
||||
},
|
||||
"version": "independent"
|
||||
}
|
||||
@@ -32,7 +32,7 @@
|
||||
"source-map-support": "0.5.12",
|
||||
"ts-eager": "2.0.2",
|
||||
"ts-jest": "29.1.0",
|
||||
"turbo": "1.9.9",
|
||||
"turbo": "1.10.7",
|
||||
"typescript": "4.9.5"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
# @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
|
||||
|
||||
- Revert "[build-utils] Allow file-ref sema to be controlled through env flag" ([#10167](https://github.com/vercel/vercel/pull/10167))
|
||||
|
||||
## 6.8.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add `getNodeBinPaths()` and `traverseUpDirectories()` functions ([#10150](https://github.com/vercel/vercel/pull/10150))
|
||||
|
||||
## 6.7.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Publish missing build-utils ([`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb))
|
||||
|
||||
## 6.7.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "6.7.4",
|
||||
"version": "6.8.2",
|
||||
"license": "Apache-2.0",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -5,13 +5,7 @@ import path from 'path';
|
||||
import Sema from 'async-sema';
|
||||
import { FileBase } from './types';
|
||||
|
||||
const DEFAULT_SEMA = 20;
|
||||
const semaToPreventEMFILE = new Sema(
|
||||
parseInt(
|
||||
process.env.VERCEL_INTERNAL_FILE_FS_REF_SEMA || String(DEFAULT_SEMA),
|
||||
10
|
||||
) || DEFAULT_SEMA
|
||||
);
|
||||
const semaToPreventEMFILE = new Sema(20);
|
||||
|
||||
interface FileFsRefOptions {
|
||||
mode?: number;
|
||||
|
||||
@@ -12,13 +12,7 @@ interface FileRefOptions {
|
||||
mutable?: boolean;
|
||||
}
|
||||
|
||||
const DEFAULT_SEMA = 5;
|
||||
const semaToDownloadFromS3 = new Sema(
|
||||
parseInt(
|
||||
process.env.VERCEL_INTERNAL_FILE_REF_SEMA || String(DEFAULT_SEMA),
|
||||
10
|
||||
) || DEFAULT_SEMA
|
||||
);
|
||||
const semaToDownloadFromS3 = new Sema(5);
|
||||
|
||||
class BailableError extends Error {
|
||||
public bail: boolean;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -44,23 +44,33 @@ export interface ScanParentDirsResult {
|
||||
lockfileVersion?: number;
|
||||
}
|
||||
|
||||
export interface WalkParentDirsProps {
|
||||
export interface TraverseUpDirectoriesProps {
|
||||
/**
|
||||
* The highest directory, typically the workPath root of the project.
|
||||
* If this directory is reached and it doesn't contain the file, null is returned.
|
||||
*/
|
||||
base: string;
|
||||
/**
|
||||
* The directory to start searching, typically the same directory of the entrypoint.
|
||||
* If this directory doesn't contain the file, the parent is checked, etc.
|
||||
* The directory to start iterating from, typically the same directory of the entrypoint.
|
||||
*/
|
||||
start: string;
|
||||
/**
|
||||
* The highest directory, typically the workPath root of the project.
|
||||
*/
|
||||
base?: string;
|
||||
}
|
||||
|
||||
export interface WalkParentDirsProps
|
||||
extends Required<TraverseUpDirectoriesProps> {
|
||||
/**
|
||||
* The name of the file to search for, typically `package.json` or `Gemfile`.
|
||||
*/
|
||||
filename: string;
|
||||
}
|
||||
|
||||
export interface WalkParentDirsMultiProps
|
||||
extends Required<TraverseUpDirectoriesProps> {
|
||||
/**
|
||||
* The name of the file to search for, typically `package.json` or `Gemfile`.
|
||||
*/
|
||||
filenames: string[];
|
||||
}
|
||||
|
||||
export interface SpawnOptionsExtended extends SpawnOptions {
|
||||
/**
|
||||
* Pretty formatted command that is being spawned for logging purposes.
|
||||
@@ -131,6 +141,24 @@ export async function execCommand(command: string, options: SpawnOptions = {}) {
|
||||
return true;
|
||||
}
|
||||
|
||||
export function* traverseUpDirectories({
|
||||
start,
|
||||
base,
|
||||
}: TraverseUpDirectoriesProps) {
|
||||
let current: string | undefined = path.normalize(start);
|
||||
const normalizedRoot = base ? path.normalize(base) : undefined;
|
||||
while (current) {
|
||||
yield current;
|
||||
if (current === normalizedRoot) break;
|
||||
// Go up one directory
|
||||
const next = path.join(current, '..');
|
||||
current = next === current ? undefined : next;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use `getNodeBinPaths()` instead.
|
||||
*/
|
||||
export async function getNodeBinPath({
|
||||
cwd,
|
||||
}: {
|
||||
@@ -141,6 +169,15 @@ export async function getNodeBinPath({
|
||||
return path.join(dir, 'node_modules', '.bin');
|
||||
}
|
||||
|
||||
export function getNodeBinPaths({
|
||||
start,
|
||||
base,
|
||||
}: TraverseUpDirectoriesProps): string[] {
|
||||
return Array.from(traverseUpDirectories({ start, base })).map(dir =>
|
||||
path.join(dir, 'node_modules/.bin')
|
||||
);
|
||||
}
|
||||
|
||||
async function chmodPlusX(fsPath: string) {
|
||||
const s = await fs.stat(fsPath);
|
||||
const newMode = s.mode | 64 | 8 | 1; // eslint-disable-line no-bitwise
|
||||
@@ -297,22 +334,14 @@ export async function walkParentDirs({
|
||||
}: WalkParentDirsProps): Promise<string | null> {
|
||||
assert(path.isAbsolute(base), 'Expected "base" to be absolute path');
|
||||
assert(path.isAbsolute(start), 'Expected "start" to be absolute path');
|
||||
let parent = '';
|
||||
|
||||
for (let current = start; base.length <= current.length; current = parent) {
|
||||
const fullPath = path.join(current, filename);
|
||||
for (const dir of traverseUpDirectories({ start, base })) {
|
||||
const fullPath = path.join(dir, filename);
|
||||
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
if (await fs.pathExists(fullPath)) {
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
parent = path.dirname(current);
|
||||
|
||||
if (parent === current) {
|
||||
// Reached root directory of the filesystem
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -322,14 +351,9 @@ async function walkParentDirsMulti({
|
||||
base,
|
||||
start,
|
||||
filenames,
|
||||
}: {
|
||||
base: string;
|
||||
start: string;
|
||||
filenames: string[];
|
||||
}): Promise<(string | undefined)[]> {
|
||||
let parent = '';
|
||||
for (let current = start; base.length <= current.length; current = parent) {
|
||||
const fullPaths = filenames.map(f => path.join(current, f));
|
||||
}: WalkParentDirsMultiProps): Promise<(string | undefined)[]> {
|
||||
for (const dir of traverseUpDirectories({ start, base })) {
|
||||
const fullPaths = filenames.map(f => path.join(dir, f));
|
||||
const existResults = await Promise.all(
|
||||
fullPaths.map(f => fs.pathExists(f))
|
||||
);
|
||||
@@ -338,13 +362,6 @@ async function walkParentDirsMulti({
|
||||
if (foundOneOrMore) {
|
||||
return fullPaths.map((f, i) => (existResults[i] ? f : undefined));
|
||||
}
|
||||
|
||||
parent = path.dirname(current);
|
||||
|
||||
if (parent === current) {
|
||||
// Reached root directory of the filesystem
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
|
||||
@@ -30,7 +30,9 @@ import {
|
||||
getNodeVersion,
|
||||
getSpawnOptions,
|
||||
getNodeBinPath,
|
||||
getNodeBinPaths,
|
||||
scanParentDirs,
|
||||
traverseUpDirectories,
|
||||
} from './fs/run-user-scripts';
|
||||
import {
|
||||
getLatestNodeVersion,
|
||||
@@ -43,6 +45,7 @@ import { getPlatformEnv } from './get-platform-env';
|
||||
import { getPrefixedEnvVars } from './get-prefixed-env-vars';
|
||||
import { cloneEnv } from './clone-env';
|
||||
import { hardLinkDir } from './hard-link-dir';
|
||||
import { validateNpmrc } from './validate-npmrc';
|
||||
|
||||
export {
|
||||
FileBlob,
|
||||
@@ -67,6 +70,7 @@ export {
|
||||
spawnCommand,
|
||||
walkParentDirs,
|
||||
getNodeBinPath,
|
||||
getNodeBinPaths,
|
||||
runNpmInstall,
|
||||
runBundleInstall,
|
||||
runPipInstall,
|
||||
@@ -88,6 +92,8 @@ export {
|
||||
getIgnoreFilter,
|
||||
cloneEnv,
|
||||
hardLinkDir,
|
||||
traverseUpDirectories,
|
||||
validateNpmrc,
|
||||
};
|
||||
|
||||
export { EdgeFunction } from './edge-function';
|
||||
|
||||
26
packages/build-utils/src/validate-npmrc.ts
Normal file
26
packages/build-utils/src/validate-npmrc.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { join } from 'path';
|
||||
import { readFile } from 'fs/promises';
|
||||
|
||||
/**
|
||||
* Checks if there is a `.npmrc` in the cwd (project root) and makes sure it
|
||||
* doesn't contain a `use-node-version`. This config setting is not supported
|
||||
* since it causes the package manager to install the Node.js version which in
|
||||
* the case of newer Node.js versions is not compatible with AWS due to
|
||||
* outdated GLIBC binaries.
|
||||
*
|
||||
* @see https://pnpm.io/npmrc#use-node-version
|
||||
*
|
||||
* @param cwd The current working directory (e.g. project root);
|
||||
*/
|
||||
export async function validateNpmrc(cwd: string): Promise<void> {
|
||||
const npmrc = await readFile(join(cwd, '.npmrc'), 'utf-8').catch(err => {
|
||||
if (err.code !== 'ENOENT') throw err;
|
||||
});
|
||||
|
||||
const nodeRegExp = /(?<!#.*)use-node-version/;
|
||||
if (npmrc?.match(nodeRegExp)) {
|
||||
throw new Error(
|
||||
'Detected unsupported "use-node-version" in your ".npmrc". Please use "engines" in your "package.json" instead.'
|
||||
);
|
||||
}
|
||||
}
|
||||
2
packages/build-utils/test/fixtures/29-npmrc/comment-use-node-version/.npmrc
vendored
Normal file
2
packages/build-utils/test/fixtures/29-npmrc/comment-use-node-version/.npmrc
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
foo=bar
|
||||
# use-node-version=16.16.0
|
||||
1
packages/build-utils/test/fixtures/29-npmrc/good/.npmrc
vendored
Normal file
1
packages/build-utils/test/fixtures/29-npmrc/good/.npmrc
vendored
Normal file
@@ -0,0 +1 @@
|
||||
foo=bar
|
||||
3
packages/build-utils/test/fixtures/29-npmrc/has-use-node-version/.npmrc
vendored
Normal file
3
packages/build-utils/test/fixtures/29-npmrc/has-use-node-version/.npmrc
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
foo=bar
|
||||
# the next line is not supported
|
||||
use-node-version=16.16.0
|
||||
17
packages/build-utils/test/unit.get-node-bin-paths.test.ts
vendored
Normal file
17
packages/build-utils/test/unit.get-node-bin-paths.test.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import { join } from 'path';
|
||||
import { getNodeBinPaths } from '../src/fs/run-user-scripts';
|
||||
|
||||
describe('getNodeBinPaths()', () => {
|
||||
const cwd = process.cwd();
|
||||
|
||||
it('should return array of `node_modules/.bin` paths', () => {
|
||||
const start = join(cwd, 'foo/bar/baz');
|
||||
const paths = getNodeBinPaths({ start, base: cwd });
|
||||
expect(paths).toEqual([
|
||||
join(cwd, 'foo/bar/baz/node_modules/.bin'),
|
||||
join(cwd, 'foo/bar/node_modules/.bin'),
|
||||
join(cwd, 'foo/node_modules/.bin'),
|
||||
join(cwd, 'node_modules/.bin'),
|
||||
]);
|
||||
});
|
||||
});
|
||||
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;
|
||||
|
||||
50
packages/build-utils/test/unit.traverse-up-directories.test.ts
vendored
Normal file
50
packages/build-utils/test/unit.traverse-up-directories.test.ts
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
import { traverseUpDirectories } from '../src/fs/run-user-scripts';
|
||||
|
||||
const isWindows = process.platform === 'win32';
|
||||
|
||||
describe('traverseUpDirectories()', () => {
|
||||
test.each(
|
||||
isWindows
|
||||
? [
|
||||
{
|
||||
start: 'C:\\foo\\bar\\baz',
|
||||
expected: ['C:\\foo\\bar\\baz', 'C:\\foo\\bar', 'C:\\foo', 'C:\\'],
|
||||
},
|
||||
{
|
||||
start: 'C:\\foo\\..\\bar\\.\\baz',
|
||||
expected: ['C:\\bar\\baz', 'C:\\bar', 'C:\\'],
|
||||
},
|
||||
{
|
||||
start: 'C:\\foo\\bar\\baz\\another',
|
||||
base: 'C:\\foo\\bar',
|
||||
expected: [
|
||||
'C:\\foo\\bar\\baz\\another',
|
||||
'C:\\foo\\bar\\baz',
|
||||
'C:\\foo\\bar',
|
||||
],
|
||||
},
|
||||
]
|
||||
: [
|
||||
{
|
||||
start: '/foo/bar/baz',
|
||||
expected: ['/foo/bar/baz', '/foo/bar', '/foo', '/'],
|
||||
},
|
||||
{
|
||||
start: '/foo/../bar/./baz',
|
||||
expected: ['/bar/baz', '/bar', '/'],
|
||||
},
|
||||
{
|
||||
start: '/foo/bar/baz/another',
|
||||
base: '/foo/bar',
|
||||
expected: ['/foo/bar/baz/another', '/foo/bar/baz', '/foo/bar'],
|
||||
},
|
||||
]
|
||||
)(
|
||||
'should traverse start="$start", base="$base"',
|
||||
({ start, base, expected }) => {
|
||||
expect(Array.from(traverseUpDirectories({ start, base }))).toEqual(
|
||||
expected
|
||||
);
|
||||
}
|
||||
);
|
||||
});
|
||||
22
packages/build-utils/test/unit.validate-npmrc.test.ts
vendored
Normal file
22
packages/build-utils/test/unit.validate-npmrc.test.ts
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
import { join } from 'path';
|
||||
import { validateNpmrc } from '../src/validate-npmrc';
|
||||
|
||||
const fixture = (name: string) => join(__dirname, 'fixtures', '29-npmrc', name);
|
||||
|
||||
describe('validateNpmrc', () => {
|
||||
it('should not error with no use-node-version', async () => {
|
||||
await expect(validateNpmrc(fixture('good'))).resolves.toBe(undefined);
|
||||
});
|
||||
|
||||
it('should throw when use-node-version is found', async () => {
|
||||
await expect(
|
||||
validateNpmrc(fixture('has-use-node-version'))
|
||||
).rejects.toThrow('Detected unsupported');
|
||||
});
|
||||
|
||||
it('should not error when use-node-version is commented out', async () => {
|
||||
await expect(
|
||||
validateNpmrc(fixture('comment-use-node-version'))
|
||||
).resolves.toBe(undefined);
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,146 @@
|
||||
# vercel
|
||||
|
||||
## 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
|
||||
|
||||
- Allow additional project settings in `createProject()` ([#10172](https://github.com/vercel/vercel/pull/10172))
|
||||
|
||||
- Run local Project detection during `vc link --repo`. ([#10094](https://github.com/vercel/vercel/pull/10094))
|
||||
This allows for creation of new Projects that do not yet exist under the selected scope.
|
||||
|
||||
- Redeploy command no longer redeploys preview deployments to production ([#10186](https://github.com/vercel/vercel/pull/10186))
|
||||
|
||||
- Added trailing new line at end of help output ([#10170](https://github.com/vercel/vercel/pull/10170))
|
||||
|
||||
- Create new help output and arg parsing for deploy command ([#10090](https://github.com/vercel/vercel/pull/10090))
|
||||
|
||||
- [cli] Remove `preinstall` script ([#10157](https://github.com/vercel/vercel/pull/10157))
|
||||
|
||||
- Updated dependencies [[`7021279b2`](https://github.com/vercel/vercel/commit/7021279b284f314a4d1bdbb4306b4c22291efa08), [`5e5332fbc`](https://github.com/vercel/vercel/commit/5e5332fbc9317a8f3cc4ed0b72ec1a2c76020891), [`027bce00b`](https://github.com/vercel/vercel/commit/027bce00b3821d9b4a8f7ec320cd1c43ab9f4215)]:
|
||||
- @vercel/build-utils@6.8.1
|
||||
- @vercel/node@2.15.4
|
||||
- @vercel/remix-builder@1.8.16
|
||||
- @vercel/static-build@1.3.39
|
||||
|
||||
## 31.0.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`aa734efc6`](https://github.com/vercel/vercel/commit/aa734efc6c42badd4aa9bf64487904aa64e9bd49)]:
|
||||
- @vercel/next@3.8.8
|
||||
|
||||
## 31.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- Update `vc dev` redirect response to match production behavior ([#10143](https://github.com/vercel/vercel/pull/10143))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- require `--yes` to promote preview deployment ([#10135](https://github.com/vercel/vercel/pull/10135))
|
||||
|
||||
- [cli] Optimize write build result for vc build ([#10154](https://github.com/vercel/vercel/pull/10154))
|
||||
|
||||
- Only show relevant Project matches in Project selector ([#10114](https://github.com/vercel/vercel/pull/10114))
|
||||
|
||||
- [cli] Fix error message when token is invalid ([#10131](https://github.com/vercel/vercel/pull/10131))
|
||||
|
||||
- Updated dependencies [[`e4895d979`](https://github.com/vercel/vercel/commit/e4895d979b57e369e0618481c5974243887d72cc), [`346892210`](https://github.com/vercel/vercel/commit/3468922108f411482a72acd0331f0f2ee52a6d4c), [`346892210`](https://github.com/vercel/vercel/commit/3468922108f411482a72acd0331f0f2ee52a6d4c), [`a6de052ed`](https://github.com/vercel/vercel/commit/a6de052ed2f09cc80bf4c2d0f06bedd267a63cdc)]:
|
||||
- @vercel/next@3.8.7
|
||||
- @vercel/static-build@1.3.38
|
||||
- @vercel/build-utils@6.8.0
|
||||
- @vercel/remix-builder@1.8.15
|
||||
- @vercel/node@2.15.3
|
||||
|
||||
## 30.2.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [cli] do not force auto-assign value on deployments ([#10110](https://github.com/vercel/vercel/pull/10110))
|
||||
|
||||
- Updated dependencies [[`91406abdb`](https://github.com/vercel/vercel/commit/91406abdb0c332152fc6c7c1e4bd3a872b084434), [`2230ea6cc`](https://github.com/vercel/vercel/commit/2230ea6cc1b84c1f03227a4e197b7684635b5955), [`8b3a4146a`](https://github.com/vercel/vercel/commit/8b3a4146af68d2b7288c80a5b919d832dba929b5)]:
|
||||
- @vercel/node@2.15.2
|
||||
- @vercel/remix-builder@1.8.14
|
||||
- @vercel/static-build@1.3.37
|
||||
|
||||
## 30.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [cli] vc env pull should add `.env*.local` to `.gitignore` ([#10085](https://github.com/vercel/vercel/pull/10085))
|
||||
|
||||
- [cli] Fix team validation bug where you are apart of a team ([#10092](https://github.com/vercel/vercel/pull/10092))
|
||||
|
||||
- Add support for `vc dev` command with repo link ([#10082](https://github.com/vercel/vercel/pull/10082))
|
||||
|
||||
- Add support for `vc deploy --prebuilt` command with repo link ([#10083](https://github.com/vercel/vercel/pull/10083))
|
||||
|
||||
- Move readme copy logic to a helper function for `vc link` ([#10084](https://github.com/vercel/vercel/pull/10084))
|
||||
|
||||
- Add support for `vc pull` command with repo link ([#10078](https://github.com/vercel/vercel/pull/10078))
|
||||
|
||||
- Add support for `vc build` command with repo link ([#10075](https://github.com/vercel/vercel/pull/10075))
|
||||
|
||||
## 30.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a04bf557f`](https://github.com/vercel/vercel/commit/a04bf557fc6e1080a117428977d0993dec78b004)]:
|
||||
- @vercel/node@2.15.1
|
||||
- @vercel/static-build@1.3.36
|
||||
|
||||
## 30.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- [node] Add isomorphic functions ([#9947](https://github.com/vercel/vercel/pull/9947))
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Add `client.fetchPaginated()` helper function ([#10054](https://github.com/vercel/vercel/pull/10054))
|
||||
|
||||
- Updated dependencies [[`bc5afe24c`](https://github.com/vercel/vercel/commit/bc5afe24c4547dbf798b939199e8212c4b34038e), [`49c717856`](https://github.com/vercel/vercel/commit/49c7178567ec5bcebe633b598c8c9c0e1aa40fbb), [`0039c8b5c`](https://github.com/vercel/vercel/commit/0039c8b5cea975316a62c4f6aaca5d66d731cc0d)]:
|
||||
- @vercel/node@2.15.0
|
||||
- @vercel/remix-builder@1.8.13
|
||||
- @vercel/static-build@1.3.35
|
||||
|
||||
## 30.1.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Publish missing build-utils ([`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb))
|
||||
|
||||
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
|
||||
- @vercel/build-utils@6.7.5
|
||||
- @vercel/node@2.14.5
|
||||
- @vercel/remix-builder@1.8.12
|
||||
- @vercel/static-build@1.3.34
|
||||
|
||||
## 30.1.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- [cli] vc build ignore '.env\*' & ignore files for '@vercel/static' ([#10056](https://github.com/vercel/vercel/pull/10056))
|
||||
|
||||
- [cli] Ensure .npmrc does not contain use-node-version ([#10049](https://github.com/vercel/vercel/pull/10049))
|
||||
|
||||
## 30.1.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "30.1.0",
|
||||
"version": "31.0.3",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -11,7 +11,6 @@
|
||||
"directory": "packages/cli"
|
||||
},
|
||||
"scripts": {
|
||||
"preinstall": "node ./scripts/preinstall.js",
|
||||
"test": "jest --env node --verbose --bail",
|
||||
"test-unit": "pnpm test test/unit/",
|
||||
"test-e2e": "rimraf test/fixtures/integration && pnpm test test/integration-1.test.ts test/integration-2.test.ts test/integration-3.test.ts",
|
||||
@@ -32,20 +31,20 @@
|
||||
"node": ">= 14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.8.2",
|
||||
"@vercel/go": "2.5.1",
|
||||
"@vercel/hydrogen": "0.0.64",
|
||||
"@vercel/next": "3.8.6",
|
||||
"@vercel/node": "2.14.4",
|
||||
"@vercel/next": "3.8.8",
|
||||
"@vercel/node": "2.15.5",
|
||||
"@vercel/python": "3.1.60",
|
||||
"@vercel/redwood": "1.1.15",
|
||||
"@vercel/remix-builder": "1.8.11",
|
||||
"@vercel/remix-builder": "1.8.17",
|
||||
"@vercel/ruby": "1.3.76",
|
||||
"@vercel/static-build": "1.3.33"
|
||||
"@vercel/static-build": "1.3.40"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@alex_neo/jest-expect-message": "1.0.5",
|
||||
"@edge-runtime/node-utils": "2.0.3",
|
||||
"@edge-runtime/node-utils": "2.1.0",
|
||||
"@next/env": "11.1.2",
|
||||
"@sentry/node": "5.5.0",
|
||||
"@sindresorhus/slugify": "0.11.0",
|
||||
@@ -85,13 +84,13 @@
|
||||
"@types/which": "3.0.0",
|
||||
"@types/write-json-file": "2.2.1",
|
||||
"@types/yauzl-promise": "2.1.0",
|
||||
"@vercel-internals/constants": "1.0.1",
|
||||
"@vercel-internals/constants": "1.0.4",
|
||||
"@vercel-internals/get-package-json": "1.0.0",
|
||||
"@vercel-internals/types": "1.0.1",
|
||||
"@vercel/client": "12.6.1",
|
||||
"@vercel-internals/types": "1.0.5",
|
||||
"@vercel/client": "12.6.5",
|
||||
"@vercel/error-utils": "1.0.10",
|
||||
"@vercel/frameworks": "1.4.2",
|
||||
"@vercel/fs-detectors": "3.9.3",
|
||||
"@vercel/frameworks": "1.4.3",
|
||||
"@vercel/fs-detectors": "4.1.0",
|
||||
"@vercel/fun": "1.0.4",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/routing-utils": "2.2.1",
|
||||
@@ -159,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",
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
const { join } = require('path');
|
||||
const { statSync } = require('fs');
|
||||
const pkg = require('../package');
|
||||
|
||||
function error(command) {
|
||||
console.error('> Error:', command);
|
||||
}
|
||||
|
||||
function debug(str) {
|
||||
if (
|
||||
process.argv.find(str => str === '--debug') ||
|
||||
process.env.PREINSTALL_DEBUG
|
||||
) {
|
||||
console.log(`[debug] [${new Date().toISOString()}]`, str);
|
||||
}
|
||||
}
|
||||
|
||||
function isYarn() {
|
||||
return process.env.npm_config_heading !== 'npm';
|
||||
}
|
||||
|
||||
function isGlobal() {
|
||||
const cmd = JSON.parse(process.env.npm_config_argv || '{ "original": [] }');
|
||||
|
||||
return isYarn()
|
||||
? cmd.original.includes('global')
|
||||
: Boolean(process.env.npm_config_global);
|
||||
}
|
||||
|
||||
function isVercel() {
|
||||
return pkg.name === 'vercel';
|
||||
}
|
||||
|
||||
function validateNodeVersion() {
|
||||
let semver = '>= 0';
|
||||
let major = '1';
|
||||
|
||||
try {
|
||||
major = process.versions.node.split('.')[0];
|
||||
const pkg = require('../package.json');
|
||||
semver = pkg.engines.node;
|
||||
} catch (e) {
|
||||
debug('Failed to read package.json engines');
|
||||
}
|
||||
|
||||
const isValid = eval(`${major} ${semver}`);
|
||||
return { isValid, expected: semver, actual: process.versions.node };
|
||||
}
|
||||
|
||||
function isInNodeModules(name) {
|
||||
try {
|
||||
const nodeModules = join(__dirname, '..', '..');
|
||||
const stat = statSync(join(nodeModules, name));
|
||||
return stat.isDirectory();
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
if (!isGlobal()) {
|
||||
debug('Skipping preinstall since Vercel CLI is being installed locally');
|
||||
return;
|
||||
}
|
||||
|
||||
const ver = validateNodeVersion();
|
||||
|
||||
if (!ver.isValid) {
|
||||
error(
|
||||
`Detected unsupported Node.js version.\n` +
|
||||
`Expected "${ver.expected}" but found "${ver.actual}".\n` +
|
||||
`Please update to the latest Node.js LTS version to install Vercel CLI.`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (isVercel() && isInNodeModules('now')) {
|
||||
const uninstall = isYarn()
|
||||
? 'yarn global remove now'
|
||||
: 'npm uninstall -g now';
|
||||
console.error(`NOTE: Run \`${uninstall}\` to uninstall \`now\`\n`);
|
||||
}
|
||||
}
|
||||
|
||||
process.on('unhandledRejection', err => {
|
||||
console.error('Unhandled Rejection:');
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
process.on('uncaughtException', err => {
|
||||
console.error('Uncaught Exception:');
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -6,21 +6,19 @@ import chalk, { Chalk } from 'chalk';
|
||||
import { URLSearchParams, parse } from 'url';
|
||||
|
||||
import box from '../../util/output/box';
|
||||
import sleep from '../../util/sleep';
|
||||
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, PaginationOptions } from '@vercel-internals/types';
|
||||
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';
|
||||
|
||||
interface Deployments {
|
||||
deployments: Deployment[];
|
||||
pagination: PaginationOptions;
|
||||
}
|
||||
|
||||
const pkgName = getPkgName();
|
||||
@@ -206,44 +204,34 @@ export default async function main(client: Client): Promise<number> {
|
||||
|
||||
// Fetch all the project's "READY" deployments with the pagination API
|
||||
let deployments: Deployment[] = [];
|
||||
let next: number | undefined = badDeployment.createdAt + 1;
|
||||
do {
|
||||
const query = new URLSearchParams();
|
||||
query.set('projectId', projectId);
|
||||
if (badDeployment.target) {
|
||||
query.set('target', badDeployment.target);
|
||||
}
|
||||
query.set('limit', '100');
|
||||
query.set('state', 'READY');
|
||||
if (next) {
|
||||
query.set('until', String(next));
|
||||
}
|
||||
|
||||
const res = await client.fetch<Deployments>(`/v6/deployments?${query}`, {
|
||||
const query = new URLSearchParams();
|
||||
query.set('projectId', projectId);
|
||||
if (badDeployment.target) {
|
||||
query.set('target', badDeployment.target);
|
||||
}
|
||||
query.set('state', 'READY');
|
||||
query.set('until', String(badDeployment.createdAt + 1));
|
||||
|
||||
for await (const chunk of client.fetchPaginated<Deployments>(
|
||||
`/v6/deployments?${query}`,
|
||||
{
|
||||
accountId: badDeployment.ownerId,
|
||||
});
|
||||
|
||||
next = res.pagination.next;
|
||||
|
||||
let newDeployments = res.deployments;
|
||||
}
|
||||
)) {
|
||||
let newDeployments = chunk.deployments;
|
||||
|
||||
// If we have the "good" deployment in this chunk, then we're done
|
||||
for (let i = 0; i < newDeployments.length; i++) {
|
||||
if (newDeployments[i].url === good) {
|
||||
// grab all deployments up until the good one
|
||||
newDeployments = newDeployments.slice(0, i);
|
||||
next = undefined;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
deployments = deployments.concat(newDeployments);
|
||||
|
||||
if (next) {
|
||||
// Small sleep to avoid rate limiting
|
||||
await sleep(100);
|
||||
}
|
||||
} while (next);
|
||||
}
|
||||
|
||||
if (!deployments.length) {
|
||||
output.error(
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import fs from 'fs-extra';
|
||||
import chalk from 'chalk';
|
||||
import dotenv from 'dotenv';
|
||||
import semver from 'semver';
|
||||
import minimatch from 'minimatch';
|
||||
import { join, normalize, relative, resolve, sep } from 'path';
|
||||
import frameworks from '@vercel/frameworks';
|
||||
import {
|
||||
getDiscontinuedNodeVersions,
|
||||
normalizePath,
|
||||
@@ -17,13 +20,14 @@ import {
|
||||
BuildResultV3,
|
||||
NowBuildError,
|
||||
Cron,
|
||||
validateNpmrc,
|
||||
} from '@vercel/build-utils';
|
||||
import {
|
||||
detectBuilders,
|
||||
detectFrameworkRecord,
|
||||
detectFrameworkVersion,
|
||||
LocalFileSystemDetector,
|
||||
} from '@vercel/fs-detectors';
|
||||
import minimatch from 'minimatch';
|
||||
import {
|
||||
appendRoutesToPhase,
|
||||
getTransformedRoutes,
|
||||
@@ -48,7 +52,7 @@ import {
|
||||
ProjectLinkAndSettings,
|
||||
readProjectSettings,
|
||||
} from '../util/projects/project-settings';
|
||||
import { VERCEL_DIR } from '../util/projects/link';
|
||||
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';
|
||||
@@ -62,11 +66,7 @@ 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 frameworks from '@vercel/frameworks';
|
||||
import { detectFrameworkVersion } from '@vercel/fs-detectors';
|
||||
import semver from 'semver';
|
||||
|
||||
type BuildResult = BuildResultV2 | BuildResultV3;
|
||||
|
||||
@@ -133,7 +133,8 @@ const help = () => {
|
||||
};
|
||||
|
||||
export default async function main(client: Client): Promise<number> {
|
||||
const { cwd, output } = client;
|
||||
let { cwd } = client;
|
||||
const { output } = client;
|
||||
|
||||
// Ensure that `vc build` is not being invoked recursively
|
||||
if (process.env.__VERCEL_BUILD_RUNNING) {
|
||||
@@ -169,10 +170,25 @@ export default async function main(client: Client): Promise<number> {
|
||||
const target = argv['--prod'] ? 'production' : 'preview';
|
||||
const yes = Boolean(argv['--yes']);
|
||||
|
||||
try {
|
||||
await validateNpmrc(cwd);
|
||||
} catch (err) {
|
||||
output.prettyError(err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// If repo linked, update `cwd` to the repo root
|
||||
const link = await getProjectLink(client, cwd);
|
||||
const projectRootDirectory = link?.projectRootDirectory ?? '';
|
||||
if (link?.repoRoot) {
|
||||
cwd = client.cwd = link.repoRoot;
|
||||
}
|
||||
|
||||
// TODO: read project settings from the API, fall back to local `project.json` if that fails
|
||||
|
||||
// Read project settings, and pull them from Vercel if necessary
|
||||
let project = await readProjectSettings(join(cwd, VERCEL_DIR));
|
||||
const vercelDir = join(cwd, projectRootDirectory, VERCEL_DIR);
|
||||
let project = await readProjectSettings(vercelDir);
|
||||
const isTTY = process.stdin.isTTY;
|
||||
while (!project?.settings) {
|
||||
let confirmed = yes;
|
||||
@@ -199,6 +215,7 @@ export default async function main(client: Client): Promise<number> {
|
||||
return 0;
|
||||
}
|
||||
const { argv: originalArgv } = client;
|
||||
client.cwd = join(cwd, projectRootDirectory);
|
||||
client.argv = [
|
||||
...originalArgv.slice(0, 2),
|
||||
'pull',
|
||||
@@ -209,12 +226,13 @@ export default async function main(client: Client): Promise<number> {
|
||||
if (result !== 0) {
|
||||
return result;
|
||||
}
|
||||
client.cwd = cwd;
|
||||
client.argv = originalArgv;
|
||||
project = await readProjectSettings(join(cwd, VERCEL_DIR));
|
||||
project = await readProjectSettings(vercelDir);
|
||||
}
|
||||
|
||||
// Delete output directory from potential previous build
|
||||
const defaultOutputDir = join(cwd, OUTPUT_DIR);
|
||||
const defaultOutputDir = join(cwd, projectRootDirectory, OUTPUT_DIR);
|
||||
const outputDir = argv['--output']
|
||||
? resolve(argv['--output'])
|
||||
: defaultOutputDir;
|
||||
@@ -233,7 +251,12 @@ export default async function main(client: Client): Promise<number> {
|
||||
const envToUnset = new Set<string>(['VERCEL', 'NOW_BUILDER']);
|
||||
|
||||
try {
|
||||
const envPath = join(cwd, VERCEL_DIR, `.env.${target}.local`);
|
||||
const envPath = join(
|
||||
cwd,
|
||||
projectRootDirectory,
|
||||
VERCEL_DIR,
|
||||
`.env.${target}.local`
|
||||
);
|
||||
// TODO (maybe?): load env vars from the API, fall back to the local file if that fails
|
||||
const dotenvResult = dotenv.config({
|
||||
path: envPath,
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
import chalk from 'chalk';
|
||||
import logo from '../../util/output/logo';
|
||||
import { getPkgName } from '../../util/pkg-name';
|
||||
|
||||
export const help = () => {
|
||||
return `
|
||||
${chalk.bold(`${logo} ${getPkgName()} [deploy]`)} [path-to-project] [options]
|
||||
|
||||
--prod Create a production deployment
|
||||
-p, --public Deployment is public (${chalk.dim(
|
||||
'`/_src`'
|
||||
)} is exposed)
|
||||
-e, --env Include an env var during run time (e.g.: ${chalk.dim(
|
||||
'`-e KEY=value`'
|
||||
)}). Can appear many times.
|
||||
-b, --build-env Similar to ${chalk.dim(
|
||||
'`--env`'
|
||||
)} but for build time only.
|
||||
-m, --meta Add metadata for the deployment (e.g.: ${chalk.dim(
|
||||
'`-m KEY=value`'
|
||||
)}). Can appear many times.
|
||||
--no-wait Don't wait for the deployment to finish
|
||||
-f, --force Force a new deployment even if nothing has changed
|
||||
--with-cache Retain build cache when using "--force"
|
||||
--regions Set default regions to enable the deployment on
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Deploy the current directory
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()}`)}
|
||||
|
||||
${chalk.gray('–')} Deploy a custom path
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} /usr/src/project`)}
|
||||
|
||||
${chalk.gray('–')} Deploy with Environment Variables
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} -e NODE_ENV=production`)}
|
||||
|
||||
${chalk.gray('–')} Deploy with prebuilt outputs
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} build`)}
|
||||
${chalk.cyan(`$ ${getPkgName()} deploy --prebuilt`)}
|
||||
|
||||
${chalk.gray('–')} Write Deployment URL to a file
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} > deployment-url.txt`)}
|
||||
`;
|
||||
};
|
||||
181
packages/cli/src/commands/deploy/command.ts
Normal file
181
packages/cli/src/commands/deploy/command.ts
Normal file
@@ -0,0 +1,181 @@
|
||||
import { Command } from '../help';
|
||||
|
||||
export const deployCommand: Command = {
|
||||
name: 'deploy',
|
||||
description:
|
||||
'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`).',
|
||||
arguments: [
|
||||
{
|
||||
name: 'project-path',
|
||||
required: false,
|
||||
},
|
||||
],
|
||||
options: [
|
||||
{
|
||||
name: 'force',
|
||||
shorthand: 'f',
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
description: 'Force a new deployment even if nothing has changed',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'with-cache',
|
||||
shorthand: null,
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
description: 'Retain build cache when using "--force"',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'public',
|
||||
shorthand: 'p',
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
description: 'Deployment is public (`/_src`) is exposed)',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'env',
|
||||
shorthand: 'e',
|
||||
type: 'string',
|
||||
argument: 'key=value',
|
||||
deprecated: false,
|
||||
multi: true,
|
||||
description:
|
||||
'Specify environment variables during run-time (e.g. `-e KEY1=value1 -e KEY2=value2`)',
|
||||
},
|
||||
{
|
||||
name: 'build-env',
|
||||
shorthand: 'b',
|
||||
type: 'string',
|
||||
argument: 'key=value',
|
||||
deprecated: false,
|
||||
multi: true,
|
||||
description:
|
||||
'Specify environment variables during build-time (e.g. `-b KEY1=value1 -b KEY2=value2`)',
|
||||
},
|
||||
{
|
||||
name: 'meta',
|
||||
shorthand: 'm',
|
||||
type: 'string',
|
||||
argument: 'key=value',
|
||||
deprecated: false,
|
||||
multi: true,
|
||||
description:
|
||||
'Specify metadata for the deployment (e.g. `-m KEY1=value1 -m KEY2=value2`)',
|
||||
},
|
||||
{
|
||||
name: 'regions',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
description: 'Set default regions to enable the deployment on',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'prebuilt',
|
||||
shorthand: null,
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
description:
|
||||
'Use in combination with `vc build`. Deploy an existing build',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'prod',
|
||||
shorthand: null,
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
description: 'Create a production deployment',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'archive',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
deprecated: false,
|
||||
description:
|
||||
'Compress the deployment code into a file before uploading it',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'no-wait',
|
||||
shorthand: null,
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
description: "Don't wait for the deployment to finish",
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'skip-domain',
|
||||
shorthand: null,
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
description: undefined,
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'yes',
|
||||
shorthand: 'y',
|
||||
type: 'boolean',
|
||||
deprecated: false,
|
||||
description: 'Use default options to skip all prompts',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'name',
|
||||
shorthand: 'n',
|
||||
type: 'string',
|
||||
deprecated: true,
|
||||
description: 'Provide a Vercel Project name',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'no-clipboard',
|
||||
shorthand: null,
|
||||
type: 'boolean',
|
||||
deprecated: true,
|
||||
description: 'Do not copy deployment URL to clipboard',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'target',
|
||||
shorthand: null,
|
||||
type: 'string',
|
||||
deprecated: true,
|
||||
description: 'Specify the target deployment environment',
|
||||
multi: false,
|
||||
},
|
||||
{
|
||||
name: 'confirm',
|
||||
shorthand: 'c',
|
||||
type: 'boolean',
|
||||
deprecated: true,
|
||||
description: 'Use default options to skip all prompts',
|
||||
multi: false,
|
||||
},
|
||||
],
|
||||
examples: [
|
||||
{
|
||||
name: 'Deploy the current directory',
|
||||
value: 'vercel',
|
||||
},
|
||||
{
|
||||
name: 'Deploy a custom path',
|
||||
value: 'vercel /usr/src/project',
|
||||
},
|
||||
{
|
||||
name: 'Deploy with run-time Environment Variables',
|
||||
value: 'vercel -e NODE_ENV=production',
|
||||
},
|
||||
{
|
||||
name: 'Deploy with prebuilt outputs',
|
||||
value: ['vercel build', 'vercel deploy --prebuilt'],
|
||||
},
|
||||
{
|
||||
name: 'Write Deployment URL to a file',
|
||||
value: 'vercel > deployment-url.txt',
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -59,7 +59,6 @@ import validatePaths, {
|
||||
} from '../../util/validate-paths';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
import { Output } from '../../util/output';
|
||||
import { help } from './args';
|
||||
import { getDeploymentChecks } from '../../util/deploy/get-deployment-checks';
|
||||
import parseTarget from '../../util/deploy/parse-target';
|
||||
import getPrebuiltJson from '../../util/deploy/get-prebuilt-json';
|
||||
@@ -69,44 +68,38 @@ import { parseEnv } from '../../util/parse-env';
|
||||
import { errorToString, isErrnoException, isError } from '@vercel/error-utils';
|
||||
import { pickOverrides } from '../../util/projects/project-settings';
|
||||
import { printDeploymentStatus } from '../../util/deploy/print-deployment-status';
|
||||
import { help } from '../help';
|
||||
import { deployCommand } from './command';
|
||||
|
||||
export default async (client: Client): Promise<number> => {
|
||||
const { output } = client;
|
||||
|
||||
let argv = null;
|
||||
|
||||
try {
|
||||
argv = getArgs(client.argv.slice(2), {
|
||||
'--force': Boolean,
|
||||
'--with-cache': Boolean,
|
||||
'--public': Boolean,
|
||||
'--env': [String],
|
||||
'--build-env': [String],
|
||||
'--meta': [String],
|
||||
// This is not an array in favor of matching
|
||||
// the config property name.
|
||||
'--regions': String,
|
||||
'--prebuilt': Boolean,
|
||||
'--prod': Boolean,
|
||||
'--archive': String,
|
||||
'--no-wait': Boolean,
|
||||
'--skip-domain': Boolean,
|
||||
'--yes': Boolean,
|
||||
'-f': '--force',
|
||||
'-p': '--public',
|
||||
'-e': '--env',
|
||||
'-b': '--build-env',
|
||||
'-m': '--meta',
|
||||
'-y': '--yes',
|
||||
const argOptions: {
|
||||
[k: string]:
|
||||
| BooleanConstructor
|
||||
| StringConstructor
|
||||
| string
|
||||
| [StringConstructor];
|
||||
} = {};
|
||||
for (const option of deployCommand.options) {
|
||||
argOptions[`--${option.name}`] =
|
||||
option.type === 'boolean' ? Boolean : String;
|
||||
if (option.shorthand) {
|
||||
argOptions[`-${option.shorthand}`] = `--${option.name}`;
|
||||
}
|
||||
if (
|
||||
option.name === 'env' ||
|
||||
option.name === 'build-env' ||
|
||||
option.name === 'meta'
|
||||
) {
|
||||
argOptions[`--${option.name}`] = [String];
|
||||
}
|
||||
}
|
||||
|
||||
// deprecated
|
||||
'--name': String,
|
||||
'-n': '--name',
|
||||
'--no-clipboard': Boolean,
|
||||
'--target': String,
|
||||
'--confirm': Boolean,
|
||||
'-c': '--confirm',
|
||||
});
|
||||
try {
|
||||
argv = getArgs(client.argv.slice(2), argOptions);
|
||||
|
||||
if ('--confirm' in argv) {
|
||||
output.warn('`--confirm` is deprecated, please use `--yes` instead');
|
||||
@@ -118,7 +111,7 @@ export default async (client: Client): Promise<number> => {
|
||||
}
|
||||
|
||||
if (argv['--help']) {
|
||||
output.print(help());
|
||||
output.print(help(deployCommand, { columns: client.stderr.columns }));
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -203,56 +196,6 @@ export default async (client: Client): Promise<number> => {
|
||||
return target;
|
||||
}
|
||||
|
||||
// build `--prebuilt`
|
||||
if (argv['--prebuilt']) {
|
||||
const prebuiltExists = await fs.pathExists(join(cwd, '.vercel/output'));
|
||||
if (!prebuiltExists) {
|
||||
error(
|
||||
`The ${param(
|
||||
'--prebuilt'
|
||||
)} option was used, but no prebuilt output found in ".vercel/output". Run ${getCommandName(
|
||||
'build'
|
||||
)} to generate a local build.`
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const prebuiltBuild = await getPrebuiltJson(cwd);
|
||||
|
||||
// Ensure that there was not a build error
|
||||
const prebuiltError =
|
||||
prebuiltBuild?.error ||
|
||||
prebuiltBuild?.builds?.find(build => 'error' in build)?.error;
|
||||
if (prebuiltError) {
|
||||
output.log(
|
||||
`Prebuilt deployment cannot be created because ${getCommandName(
|
||||
'build'
|
||||
)} failed with error:\n`
|
||||
);
|
||||
prettyError(prebuiltError);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Ensure that the deploy target matches the build target
|
||||
const assumedTarget = target || 'preview';
|
||||
if (prebuiltBuild?.target && prebuiltBuild.target !== assumedTarget) {
|
||||
let specifyTarget = '';
|
||||
if (prebuiltBuild.target === 'production') {
|
||||
specifyTarget = ` --prod`;
|
||||
}
|
||||
|
||||
prettyError({
|
||||
message: `The ${param(
|
||||
'--prebuilt'
|
||||
)} option was used with the target environment "${assumedTarget}", but the prebuilt output found in ".vercel/output" was built with target environment "${
|
||||
prebuiltBuild.target
|
||||
}". Please run ${getCommandName(`--prebuilt${specifyTarget}`)}.`,
|
||||
link: 'https://vercel.link/prebuilt-environment-mismatch',
|
||||
});
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
const archive = argv['--archive'];
|
||||
if (typeof archive === 'string' && !isValidArchive(archive)) {
|
||||
output.error(`Format must be one of: ${VALID_ARCHIVE_FORMATS.join(', ')}`);
|
||||
@@ -355,6 +298,66 @@ export default async (client: Client): Promise<number> => {
|
||||
throw new Error(`"org" is not defined`);
|
||||
}
|
||||
|
||||
// build `--prebuilt`
|
||||
if (argv['--prebuilt']) {
|
||||
// For repo-style linking, update `cwd` to be the Project
|
||||
// subdirectory when `rootDirectory` setting is defined
|
||||
if (
|
||||
link.status === 'linked' &&
|
||||
link.repoRoot &&
|
||||
link.project.rootDirectory
|
||||
) {
|
||||
cwd = join(cwd, link.project.rootDirectory);
|
||||
}
|
||||
|
||||
const prebuiltExists = await fs.pathExists(join(cwd, '.vercel/output'));
|
||||
if (!prebuiltExists) {
|
||||
error(
|
||||
`The ${param(
|
||||
'--prebuilt'
|
||||
)} option was used, but no prebuilt output found in ".vercel/output". Run ${getCommandName(
|
||||
'build'
|
||||
)} to generate a local build.`
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const prebuiltBuild = await getPrebuiltJson(cwd);
|
||||
|
||||
// Ensure that there was not a build error
|
||||
const prebuiltError =
|
||||
prebuiltBuild?.error ||
|
||||
prebuiltBuild?.builds?.find(build => 'error' in build)?.error;
|
||||
if (prebuiltError) {
|
||||
output.log(
|
||||
`Prebuilt deployment cannot be created because ${getCommandName(
|
||||
'build'
|
||||
)} failed with error:\n`
|
||||
);
|
||||
prettyError(prebuiltError);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Ensure that the deploy target matches the build target
|
||||
const assumedTarget = target || 'preview';
|
||||
if (prebuiltBuild?.target && prebuiltBuild.target !== assumedTarget) {
|
||||
let specifyTarget = '';
|
||||
if (prebuiltBuild.target === 'production') {
|
||||
specifyTarget = ` --prod`;
|
||||
}
|
||||
|
||||
prettyError({
|
||||
message: `The ${param(
|
||||
'--prebuilt'
|
||||
)} option was used with the target environment "${assumedTarget}", but the prebuilt output found in ".vercel/output" was built with target environment "${
|
||||
prebuiltBuild.target
|
||||
}". Please run ${getCommandName(`--prebuilt${specifyTarget}`)}.`,
|
||||
link: 'https://vercel.link/prebuilt-environment-mismatch',
|
||||
});
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the `contextName` and `currentTeam` as specified by the
|
||||
// Project Settings, so that API calls happen with the proper scope
|
||||
const contextName = org.slug;
|
||||
@@ -511,7 +514,8 @@ export default async (client: Client): Promise<number> => {
|
||||
}
|
||||
|
||||
try {
|
||||
const autoAssignCustomDomains = !argv['--skip-domain'];
|
||||
// if this flag is not set, use `undefined` to allow the project setting to be used
|
||||
const autoAssignCustomDomains = argv['--skip-domain'] ? false : undefined;
|
||||
|
||||
const createArgs: CreateOptions = {
|
||||
name,
|
||||
|
||||
@@ -58,7 +58,13 @@ export default async function dev(
|
||||
let projectSettings: ProjectSettings | undefined;
|
||||
let envValues: Record<string, string> = {};
|
||||
if (link.status === 'linked') {
|
||||
const { project, org } = link;
|
||||
const { project, org, repoRoot } = link;
|
||||
|
||||
// If repo linked, update `cwd` to the repo root
|
||||
if (repoRoot) {
|
||||
cwd = repoRoot;
|
||||
}
|
||||
|
||||
client.config.currentTeam = org.type === 'team' ? org.id : undefined;
|
||||
|
||||
projectSettings = project;
|
||||
|
||||
1
packages/cli/src/commands/env/index.ts
vendored
1
packages/cli/src/commands/env/index.ts
vendored
@@ -167,6 +167,7 @@ export default async function main(client: Client) {
|
||||
case 'pull':
|
||||
return pull(
|
||||
client,
|
||||
link,
|
||||
project,
|
||||
target,
|
||||
argv,
|
||||
|
||||
25
packages/cli/src/commands/env/pull.ts
vendored
25
packages/cli/src/commands/env/pull.ts
vendored
@@ -2,7 +2,11 @@ import chalk from 'chalk';
|
||||
import { outputFile } from 'fs-extra';
|
||||
import { closeSync, openSync, readSync } from 'fs';
|
||||
import { resolve } from 'path';
|
||||
import type { Project, ProjectEnvTarget } from '@vercel-internals/types';
|
||||
import type {
|
||||
Project,
|
||||
ProjectEnvTarget,
|
||||
ProjectLinked,
|
||||
} from '@vercel-internals/types';
|
||||
import Client from '../../util/client';
|
||||
import { emoji, prependEmoji } from '../../util/emoji';
|
||||
import confirm from '../../util/input/confirm';
|
||||
@@ -19,6 +23,7 @@ import {
|
||||
createEnvObject,
|
||||
} from '../../util/env/diff-env-files';
|
||||
import { isErrnoException } from '@vercel/error-utils';
|
||||
import { addToGitIgnore } from '../../util/link/add-to-gitignore';
|
||||
|
||||
const CONTENTS_PREFIX = '# Created by Vercel CLI\n';
|
||||
|
||||
@@ -51,6 +56,7 @@ function tryReadHeadSync(path: string, length: number) {
|
||||
|
||||
export default async function pull(
|
||||
client: Client,
|
||||
link: ProjectLinked,
|
||||
project: Project,
|
||||
environment: ProjectEnvTarget,
|
||||
opts: Partial<Options>,
|
||||
@@ -136,11 +142,22 @@ export default async function pull(
|
||||
output.log('No changes found.');
|
||||
}
|
||||
|
||||
let isGitIgnoreUpdated = false;
|
||||
if (filename === '.env.local') {
|
||||
// When the file is `.env.local`, we also add it to `.gitignore`
|
||||
// to avoid accidentally committing it to git.
|
||||
// We use '.env*.local' to match the default .gitignore from
|
||||
// create-next-app template. See:
|
||||
// https://github.com/vercel/next.js/blob/06abd634899095b6cc28e6e8315b1e8b9c8df939/packages/create-next-app/templates/app/js/gitignore#L28
|
||||
const rootPath = link.repoRoot ?? cwd;
|
||||
isGitIgnoreUpdated = await addToGitIgnore(rootPath, '.env*.local');
|
||||
}
|
||||
|
||||
output.print(
|
||||
`${prependEmoji(
|
||||
`${exists ? 'Updated' : 'Created'} ${chalk.bold(
|
||||
filename
|
||||
)} file ${chalk.gray(pullStamp())}`,
|
||||
`${exists ? 'Updated' : 'Created'} ${chalk.bold(filename)} file ${
|
||||
isGitIgnoreUpdated ? 'and added it to .gitignore' : ''
|
||||
} ${chalk.gray(pullStamp())}`,
|
||||
emoji('success')
|
||||
)}\n`
|
||||
);
|
||||
|
||||
229
packages/cli/src/commands/help.ts
Normal file
229
packages/cli/src/commands/help.ts
Normal file
@@ -0,0 +1,229 @@
|
||||
import chalk from 'chalk';
|
||||
import stripAnsi from 'strip-ansi';
|
||||
import { LOGO, NAME } from '@vercel-internals/constants';
|
||||
|
||||
const INDENT = ' '.repeat(2);
|
||||
const NEWLINE = '\n';
|
||||
|
||||
export interface CommandOption {
|
||||
name: string;
|
||||
shorthand: string | null;
|
||||
type: 'boolean' | 'string';
|
||||
argument?: string;
|
||||
deprecated: boolean;
|
||||
description?: string;
|
||||
multi: boolean;
|
||||
}
|
||||
export interface CommandArgument {
|
||||
name: string;
|
||||
required: boolean;
|
||||
}
|
||||
export interface CommandExample {
|
||||
name: string;
|
||||
value: string | string[];
|
||||
}
|
||||
export interface Command {
|
||||
name: string;
|
||||
description: string;
|
||||
arguments: CommandArgument[];
|
||||
options: CommandOption[];
|
||||
examples: CommandExample[];
|
||||
}
|
||||
|
||||
export function calcLineLength(line: string[]) {
|
||||
return stripAnsi(lineToString(line)).length;
|
||||
}
|
||||
|
||||
// Insert spaces in between non-whitespace items only
|
||||
export function lineToString(line: string[]) {
|
||||
let string = '';
|
||||
for (let i = 0; i < line.length; i++) {
|
||||
if (i === line.length - 1) {
|
||||
string += line[i];
|
||||
} else {
|
||||
const curr = line[i];
|
||||
const next = line[i + 1];
|
||||
string += curr;
|
||||
if (curr.trim() !== '' && next.trim() !== '') {
|
||||
string += ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
return string;
|
||||
}
|
||||
|
||||
export function outputArrayToString(outputArray: string[]) {
|
||||
return outputArray.join(NEWLINE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Example: `▲ vercel deploy [path] [options]`
|
||||
* @param command
|
||||
* @returns
|
||||
*/
|
||||
export function buildCommandSynopsisLine(command: Command) {
|
||||
const line: string[] = [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}]`);
|
||||
}
|
||||
}
|
||||
if (command.options.length > 0) {
|
||||
line.push('[options]');
|
||||
}
|
||||
return lineToString(line);
|
||||
}
|
||||
|
||||
export function buildCommandOptionLines(
|
||||
command: Command,
|
||||
options: BuildHelpOutputOptions
|
||||
) {
|
||||
// Filter out deprecated and intentionally undocumented options
|
||||
command.options = command.options.filter(
|
||||
option => !option.deprecated && option.description !== undefined
|
||||
);
|
||||
|
||||
// Initialize output array with header and empty line
|
||||
const outputArray: string[] = [chalk.dim(`Options:`), ''];
|
||||
|
||||
// Start building option lines
|
||||
const optionLines: string[][] = [];
|
||||
// Sort command options alphabetically
|
||||
command.options.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];
|
||||
if (option.shorthand) {
|
||||
startLine.push(`-${option.shorthand},`);
|
||||
}
|
||||
startLine.push(`--${option.name}`);
|
||||
if (option.argument) {
|
||||
startLine.push(`<${option.argument}>`);
|
||||
}
|
||||
// the length includes the INDENT
|
||||
const lineLength = calcLineLength(startLine);
|
||||
maxLineStartLength = Math.max(lineLength, maxLineStartLength);
|
||||
optionLines.push(startLine);
|
||||
}
|
||||
/*
|
||||
* Iterate over in-progress option lines to add space-filler and description
|
||||
* For Example:
|
||||
* | --archive My description starts here.
|
||||
* |
|
||||
* | -b, --build-env <key=value> Start of description here then
|
||||
* | it wraps here.
|
||||
* |
|
||||
* | -e, --env <key=value> My description is short.
|
||||
*
|
||||
* Breaking down option lines:
|
||||
* | -b, --build-env <key=value> Start of description here then
|
||||
* |[][ ][][ ]
|
||||
* |↑ ↑ ↑ ↑
|
||||
* |1 2 3 4
|
||||
* | it wraps here.
|
||||
* |[][ ][ ]
|
||||
* |↑ ↑ ↑
|
||||
* |5 6 7
|
||||
* | 1, 5 = indent
|
||||
* | 2 = start
|
||||
* | 3, 6 = space-filler
|
||||
* | 4, 7 = description
|
||||
*/
|
||||
for (let i = 0; i < optionLines.length; i++) {
|
||||
const optionLine = optionLines[i];
|
||||
const option = command.options[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)))
|
||||
);
|
||||
|
||||
// Descriptions may be longer than max line length. Wrap them to the same column as the first description line
|
||||
const lines: string[][] = [optionLine];
|
||||
if (option.description) {
|
||||
for (const descriptionWord of option.description.split(' ')) {
|
||||
// insert a new line when the next word would match or exceed the maximum line length
|
||||
if (
|
||||
calcLineLength(lines[lines.length - 1]) +
|
||||
stripAnsi(descriptionWord).length >=
|
||||
options.columns
|
||||
) {
|
||||
// initialize the new line with the necessary whitespace. The INDENT is apart of `maxLineStartLength`
|
||||
lines.push([' '.repeat(maxLineStartLength + 2)]);
|
||||
}
|
||||
// insert the word to the current last line
|
||||
lines[lines.length - 1].push(descriptionWord);
|
||||
}
|
||||
}
|
||||
// for every line, transform into a string and push it to the output
|
||||
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);
|
||||
}
|
||||
|
||||
export function buildCommandExampleLines(command: Command) {
|
||||
const outputArray: string[] = [chalk.dim(`Examples:`), ''];
|
||||
for (const example of command.examples) {
|
||||
const nameLine: string[] = [INDENT];
|
||||
nameLine.push(chalk.gray('-'));
|
||||
nameLine.push(example.name);
|
||||
outputArray.push(lineToString(nameLine));
|
||||
outputArray.push('');
|
||||
const buildValueLine = (value: string) => {
|
||||
return lineToString([INDENT, INDENT, chalk.cyan(`$ ${value}`)]);
|
||||
};
|
||||
if (Array.isArray(example.value)) {
|
||||
for (const line of example.value) {
|
||||
outputArray.push(buildValueLine(line));
|
||||
}
|
||||
} else {
|
||||
outputArray.push(buildValueLine(example.value));
|
||||
}
|
||||
outputArray.push('');
|
||||
}
|
||||
// delete the last newline added after examples iteration
|
||||
outputArray.splice(-1);
|
||||
|
||||
return outputArrayToString(outputArray);
|
||||
}
|
||||
|
||||
interface BuildHelpOutputOptions {
|
||||
columns: number;
|
||||
}
|
||||
|
||||
export function buildHelpOutput(
|
||||
command: Command,
|
||||
options: BuildHelpOutputOptions
|
||||
) {
|
||||
const outputArray: string[] = [
|
||||
buildCommandSynopsisLine(command),
|
||||
'',
|
||||
command.description,
|
||||
'',
|
||||
buildCommandOptionLines(command, options),
|
||||
'',
|
||||
buildCommandExampleLines(command),
|
||||
'',
|
||||
];
|
||||
|
||||
return outputArrayToString(outputArray);
|
||||
}
|
||||
|
||||
export interface HelpOptions {
|
||||
columns?: number;
|
||||
}
|
||||
|
||||
export function help(command: Command, options: HelpOptions) {
|
||||
return buildHelpOutput(command, {
|
||||
columns: options.columns ?? 80,
|
||||
});
|
||||
}
|
||||
@@ -97,7 +97,7 @@ export default async function main(client: Client) {
|
||||
client.output.warn(
|
||||
`The ${cmd('--repo')} flag is in alpha, please report issues`
|
||||
);
|
||||
await ensureRepoLink(client, cwd, yes);
|
||||
await ensureRepoLink(client, cwd, { yes, overwrite: true });
|
||||
} else {
|
||||
const link = await ensureLink('link', client, cwd, {
|
||||
autoConfirm: yes,
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -73,6 +73,8 @@ export default async (client: Client): Promise<number> => {
|
||||
return 2;
|
||||
}
|
||||
|
||||
const yes = argv['--yes'] ?? false;
|
||||
|
||||
// validate the timeout
|
||||
let timeout = argv['--timeout'];
|
||||
if (timeout && ms(timeout) === undefined) {
|
||||
@@ -103,6 +105,7 @@ export default async (client: Client): Promise<number> => {
|
||||
client,
|
||||
deployId: actionOrDeployId,
|
||||
timeout,
|
||||
yes,
|
||||
});
|
||||
} catch (err) {
|
||||
if (isErrnoException(err)) {
|
||||
|
||||
@@ -4,6 +4,7 @@ import { getCommandName } from '../../util/pkg-name';
|
||||
import getProjectByDeployment from '../../util/projects/get-project-by-deployment';
|
||||
import ms from 'ms';
|
||||
import promoteStatus from './status';
|
||||
import confirm from '../../util/input/confirm';
|
||||
|
||||
/**
|
||||
* Requests a promotion and waits for it complete.
|
||||
@@ -16,10 +17,12 @@ export default async function requestPromote({
|
||||
client,
|
||||
deployId,
|
||||
timeout,
|
||||
yes,
|
||||
}: {
|
||||
client: Client;
|
||||
deployId: string;
|
||||
timeout?: string;
|
||||
yes: boolean;
|
||||
}): Promise<number> {
|
||||
const { output } = client;
|
||||
|
||||
@@ -29,6 +32,16 @@ export default async function requestPromote({
|
||||
output: client.output,
|
||||
});
|
||||
|
||||
if (deployment.target !== 'production' && !yes) {
|
||||
const question =
|
||||
'This deployment does not target production, therefore promotion will not apply production environment variables. Are you sure you want to continue?';
|
||||
const answer = await confirm(client, question, false);
|
||||
if (!answer) {
|
||||
output.error('Canceled');
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// request the promotion
|
||||
await client.fetch(`/v9/projects/${project.id}/promote/${deployment.id}`, {
|
||||
body: {}, // required
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import chalk from 'chalk';
|
||||
import { join } from 'path';
|
||||
import Client from '../util/client';
|
||||
import type { Project, ProjectEnvTarget } from '@vercel-internals/types';
|
||||
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';
|
||||
@@ -15,6 +19,7 @@ import {
|
||||
getEnvTargetPlaceholder,
|
||||
} from '../util/env/env-target';
|
||||
import { ensureLink } from '../util/link/ensure-link';
|
||||
import humanizePath from '../util/humanize-path';
|
||||
|
||||
const help = () => {
|
||||
return console.log(`
|
||||
@@ -81,6 +86,7 @@ function parseArgs(client: Client) {
|
||||
async function pullAllEnvFiles(
|
||||
environment: ProjectEnvTarget,
|
||||
client: Client,
|
||||
link: ProjectLinked,
|
||||
project: Project,
|
||||
argv: ReturnType<typeof processArgs>,
|
||||
cwd: string
|
||||
@@ -88,6 +94,7 @@ async function pullAllEnvFiles(
|
||||
const environmentFile = `.env.${environment}.local`;
|
||||
return envPull(
|
||||
client,
|
||||
link,
|
||||
project,
|
||||
environment,
|
||||
argv,
|
||||
@@ -115,7 +122,7 @@ export default async function main(client: Client) {
|
||||
return argv;
|
||||
}
|
||||
|
||||
const cwd = argv._[1] || process.cwd();
|
||||
let cwd = argv._[1] || client.cwd;
|
||||
const autoConfirm = Boolean(argv['--yes']);
|
||||
const environment = parseEnvironment(argv['--environment'] || undefined);
|
||||
|
||||
@@ -124,13 +131,18 @@ export default async function main(client: Client) {
|
||||
return link;
|
||||
}
|
||||
|
||||
const { project, org } = link;
|
||||
const { project, org, repoRoot } = link;
|
||||
|
||||
if (repoRoot) {
|
||||
cwd = join(repoRoot, project.rootDirectory || '');
|
||||
}
|
||||
|
||||
client.config.currentTeam = org.type === 'team' ? org.id : undefined;
|
||||
|
||||
const pullResultCode = await pullAllEnvFiles(
|
||||
environment,
|
||||
client,
|
||||
link,
|
||||
project,
|
||||
argv,
|
||||
cwd
|
||||
@@ -141,13 +153,14 @@ export default async function main(client: Client) {
|
||||
|
||||
client.output.print('\n');
|
||||
client.output.log('Downloading project settings');
|
||||
await writeProjectSettings(cwd, project, org);
|
||||
const isRepoLinked = typeof repoRoot === 'string';
|
||||
await writeProjectSettings(cwd, project, org, isRepoLinked);
|
||||
|
||||
const settingsStamp = stamp();
|
||||
client.output.print(
|
||||
`${prependEmoji(
|
||||
`Downloaded project settings to ${chalk.bold(
|
||||
join(VERCEL_DIR, VERCEL_DIR_PROJECT)
|
||||
humanizePath(join(cwd, VERCEL_DIR, VERCEL_DIR_PROJECT))
|
||||
)} ${chalk.gray(settingsStamp())}`,
|
||||
emoji('success')
|
||||
)}\n`
|
||||
|
||||
@@ -108,7 +108,7 @@ export default async (client: Client): Promise<number> => {
|
||||
action: 'redeploy',
|
||||
},
|
||||
name: fromDeployment.name,
|
||||
target: fromDeployment.target || 'production',
|
||||
target: fromDeployment.target ?? undefined,
|
||||
},
|
||||
method: 'POST',
|
||||
});
|
||||
|
||||
@@ -12,7 +12,10 @@ export const build: BuildV2 = async ({ entrypoint, files, config }) => {
|
||||
if (
|
||||
filename.startsWith('.git/') ||
|
||||
filename === 'vercel.json' ||
|
||||
filename === 'now.json'
|
||||
filename === '.vercelignore' ||
|
||||
filename === 'now.json' ||
|
||||
filename === '.nowignore' ||
|
||||
filename.startsWith('.env')
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@ async function writeBuildResultV2(
|
||||
|
||||
const lambdas = new Map<Lambda, string>();
|
||||
const overrides: Record<string, PathOverride> = {};
|
||||
|
||||
for (const [path, output] of Object.entries(buildResult.output)) {
|
||||
const normalizedPath = stripDuplicateSlashes(path);
|
||||
if (isLambda(output)) {
|
||||
@@ -156,11 +157,26 @@ async function writeBuildResultV2(
|
||||
const ext = getFileExtension(fallback);
|
||||
const fallbackName = `${normalizedPath}.prerender-fallback${ext}`;
|
||||
const fallbackPath = join(outputDir, 'functions', fallbackName);
|
||||
const stream = fallback.toStream();
|
||||
await pipe(
|
||||
stream,
|
||||
fs.createWriteStream(fallbackPath, { mode: fallback.mode })
|
||||
);
|
||||
|
||||
// if file is already on the disk we can hard link
|
||||
// instead of creating a new copy
|
||||
let usedHardLink = false;
|
||||
if ('fsPath' in fallback) {
|
||||
try {
|
||||
await fs.link(fallback.fsPath, fallbackPath);
|
||||
usedHardLink = true;
|
||||
} catch (_) {
|
||||
// if link fails we continue attempting to copy
|
||||
}
|
||||
}
|
||||
|
||||
if (!usedHardLink) {
|
||||
const stream = fallback.toStream();
|
||||
await pipe(
|
||||
stream,
|
||||
fs.createWriteStream(fallbackPath, { mode: fallback.mode })
|
||||
);
|
||||
}
|
||||
fallback = new FileFsRef({
|
||||
...output.fallback,
|
||||
fsPath: basename(fallbackName),
|
||||
@@ -288,6 +304,14 @@ async function writeStaticFile(
|
||||
const dest = join(outputDir, 'static', fsPath);
|
||||
await fs.mkdirp(dirname(dest));
|
||||
|
||||
// if already on disk hard link instead of copying
|
||||
if ('fsPath' in file) {
|
||||
try {
|
||||
return await fs.link(file.fsPath, dest);
|
||||
} catch (_) {
|
||||
// if link fails we continue attempting to copy
|
||||
}
|
||||
}
|
||||
await downloadFile(file, dest);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,12 +18,14 @@ import type {
|
||||
JSONObject,
|
||||
Stdio,
|
||||
ReadableTTY,
|
||||
WritableTTY,
|
||||
PaginationOptions,
|
||||
} from '@vercel-internals/types';
|
||||
import { sharedPromise } from './promise';
|
||||
import { APIError } from './errors-ts';
|
||||
import { normalizeError } from '@vercel/error-utils';
|
||||
import type { Agent } from 'http';
|
||||
import sleep from './sleep';
|
||||
import type * as tty from 'tty';
|
||||
|
||||
const isSAMLError = (v: any): v is SAMLError => {
|
||||
return v && v.saml;
|
||||
@@ -57,8 +59,8 @@ export default class Client extends EventEmitter implements Stdio {
|
||||
apiUrl: string;
|
||||
authConfig: AuthConfig;
|
||||
stdin: ReadableTTY;
|
||||
stdout: WritableTTY;
|
||||
stderr: WritableTTY;
|
||||
stdout: tty.WriteStream;
|
||||
stderr: tty.WriteStream;
|
||||
output: Output;
|
||||
config: GlobalConfig;
|
||||
agent?: Agent;
|
||||
@@ -144,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
|
||||
@@ -176,6 +179,31 @@ export default class Client extends EventEmitter implements Stdio {
|
||||
}, opts.retry);
|
||||
}
|
||||
|
||||
async *fetchPaginated<T>(
|
||||
url: string | URL,
|
||||
opts?: FetchOptions
|
||||
): AsyncGenerator<T & { pagination: PaginationOptions }> {
|
||||
const endpoint =
|
||||
typeof url === 'string' ? new URL(url, this.apiUrl) : new URL(url.href);
|
||||
if (!endpoint.searchParams.has('limit')) {
|
||||
endpoint.searchParams.set('limit', '100');
|
||||
}
|
||||
let next: number | null | undefined;
|
||||
do {
|
||||
if (next) {
|
||||
// Small sleep to avoid rate limiting
|
||||
await sleep(100);
|
||||
endpoint.searchParams.set('until', String(next));
|
||||
}
|
||||
const res = await this.fetch<T & { pagination: PaginationOptions }>(
|
||||
endpoint.href,
|
||||
opts
|
||||
);
|
||||
yield res;
|
||||
next = res.pagination?.next;
|
||||
} while (next);
|
||||
}
|
||||
|
||||
reauthenticate = sharedPromise(async function (
|
||||
this: Client,
|
||||
error: SAMLError
|
||||
|
||||
@@ -234,6 +234,10 @@ export default async function processDeployment({
|
||||
return error;
|
||||
}
|
||||
|
||||
if (error.code === 'forbidden') {
|
||||
return error;
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
|
||||
|
||||
@@ -1131,7 +1131,7 @@ export default class DevServer {
|
||||
body = redirectTemplate({ location, statusCode });
|
||||
} else {
|
||||
res.setHeader('content-type', 'text/plain; charset=utf-8');
|
||||
body = `Redirecting to ${location} (${statusCode})\n`;
|
||||
body = `Redirecting...\n`;
|
||||
}
|
||||
res.end(body);
|
||||
}
|
||||
|
||||
@@ -8,10 +8,7 @@ import {
|
||||
import type { Server } from 'http';
|
||||
import type Client from '../client';
|
||||
|
||||
const toHeaders = buildToHeaders({
|
||||
// @ts-expect-error - `node-fetch` Headers is missing `getAll()`
|
||||
Headers,
|
||||
});
|
||||
const toHeaders = buildToHeaders({ Headers });
|
||||
|
||||
export function createProxy(client: Client): Server {
|
||||
return createServer(async (req, res) => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { basename } from 'path';
|
||||
import { VercelConfig } from '@vercel/client';
|
||||
|
||||
export interface GetProjectNameOptions {
|
||||
argv: { '--name'?: string };
|
||||
argv: { [k: string]: string | undefined };
|
||||
nowConfig?: VercelConfig;
|
||||
paths?: string[];
|
||||
}
|
||||
|
||||
5
packages/cli/src/util/git/repo-info-to-url.ts
Normal file
5
packages/cli/src/util/git/repo-info-to-url.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import type { RepoInfo } from './connect-git-provider';
|
||||
|
||||
export function repoInfoToUrl(info: RepoInfo): string {
|
||||
return `https://${info.provider}.com/${info.org}/${info.repo}`;
|
||||
}
|
||||
@@ -50,7 +50,7 @@ export interface CreateOptions {
|
||||
projectSettings?: any;
|
||||
skipAutoDetectionConfirmation?: boolean;
|
||||
noWait?: boolean;
|
||||
autoAssignCustomDomains: boolean;
|
||||
autoAssignCustomDomains?: boolean;
|
||||
}
|
||||
|
||||
export interface RemoveOptions {
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import { Org, Project } from '@vercel-internals/types';
|
||||
import Client from '../client';
|
||||
import setupAndLink from '../link/setup-and-link';
|
||||
import param from '../output/param';
|
||||
import { getCommandName } from '../pkg-name';
|
||||
import { getLinkedProject } from '../projects/link';
|
||||
import type { SetupAndLinkOptions } from '../link/setup-and-link';
|
||||
|
||||
type LinkResult = {
|
||||
org: Org;
|
||||
project: Project;
|
||||
};
|
||||
import type { ProjectLinked } from '@vercel-internals/types';
|
||||
|
||||
/**
|
||||
* Checks if a project is already linked and if not, links the project and
|
||||
@@ -23,15 +18,15 @@ type LinkResult = {
|
||||
* directory
|
||||
* @param opts.projectName - The project name to use when linking, otherwise
|
||||
* the current directory
|
||||
* @returns {Promise<LinkResult|number>} Returns a numeric exit code when aborted or
|
||||
* @returns {Promise<ProjectLinked|number>} Returns a numeric exit code when aborted or
|
||||
* error, otherwise an object containing the org an project
|
||||
*/
|
||||
export async function ensureLink(
|
||||
commandName: string,
|
||||
client: Client,
|
||||
cwd: string,
|
||||
opts: SetupAndLinkOptions
|
||||
): Promise<LinkResult | number> {
|
||||
opts: SetupAndLinkOptions = {}
|
||||
): Promise<ProjectLinked | number> {
|
||||
let { link } = opts;
|
||||
if (!link) {
|
||||
link = await getLinkedProject(client, cwd);
|
||||
@@ -61,5 +56,5 @@ export async function ensureLink(
|
||||
return link.exitCode;
|
||||
}
|
||||
|
||||
return { org: link.org, project: link.project };
|
||||
return link;
|
||||
}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import chalk from 'chalk';
|
||||
import inquirer from 'inquirer';
|
||||
import pluralize from 'pluralize';
|
||||
import { homedir } from 'os';
|
||||
import { join, normalize } from 'path';
|
||||
import { normalizePath } from '@vercel/build-utils';
|
||||
import { lstat, readJSON, outputJSON, writeFile, readFile } from 'fs-extra';
|
||||
import slugify from '@sindresorhus/slugify';
|
||||
import { basename, join, normalize } from 'path';
|
||||
import { normalizePath, traverseUpDirectories } from '@vercel/build-utils';
|
||||
import { lstat, readJSON, outputJSON } from 'fs-extra';
|
||||
import confirm from '../input/confirm';
|
||||
import toHumanPath from '../humanize-path';
|
||||
import {
|
||||
VERCEL_DIR,
|
||||
VERCEL_DIR_README,
|
||||
VERCEL_DIR_REPO,
|
||||
} from '../projects/link';
|
||||
import { VERCEL_DIR, VERCEL_DIR_REPO, writeReadme } from '../projects/link';
|
||||
import { getRemoteUrls } from '../create-git-meta';
|
||||
import link from '../output/link';
|
||||
import { emoji, prependEmoji } from '../emoji';
|
||||
@@ -18,6 +16,10 @@ import selectOrg from '../input/select-org';
|
||||
import { addToGitIgnore } from './add-to-gitignore';
|
||||
import type Client from '../client';
|
||||
import type { Project } from '@vercel-internals/types';
|
||||
import createProject from '../projects/create-project';
|
||||
import { detectProjects } from '../projects/detect-projects';
|
||||
import { repoInfoToUrl } from '../git/repo-info-to-url';
|
||||
import { connectGitProvider, parseRepoUrl } from '../git/connect-git-provider';
|
||||
|
||||
const home = homedir();
|
||||
|
||||
@@ -39,14 +41,22 @@ export interface RepoLink {
|
||||
repoConfig?: RepoProjectsConfig;
|
||||
}
|
||||
|
||||
export interface EnsureRepoLinkOptions {
|
||||
yes: boolean;
|
||||
overwrite: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a directory path `cwd`, finds the root of the Git repository
|
||||
* and returns the parsed `.vercel/repo.json` file if the repository
|
||||
* has already been linked.
|
||||
*/
|
||||
export async function getRepoLink(cwd: string): Promise<RepoLink | undefined> {
|
||||
export async function getRepoLink(
|
||||
client: Client,
|
||||
cwd: string
|
||||
): Promise<RepoLink | undefined> {
|
||||
// Determine where the root of the repo is
|
||||
const rootPath = await findRepoRoot(cwd);
|
||||
const rootPath = await findRepoRoot(client, cwd);
|
||||
if (!rootPath) return undefined;
|
||||
|
||||
// Read the `repo.json`, if this repo has already been linked
|
||||
@@ -63,11 +73,11 @@ export async function getRepoLink(cwd: string): Promise<RepoLink | undefined> {
|
||||
export async function ensureRepoLink(
|
||||
client: Client,
|
||||
cwd: string,
|
||||
yes = false
|
||||
{ yes, overwrite }: EnsureRepoLinkOptions
|
||||
): Promise<RepoLink | undefined> {
|
||||
const { output } = client;
|
||||
|
||||
const repoLink = await getRepoLink(cwd);
|
||||
const repoLink = await getRepoLink(client, cwd);
|
||||
if (repoLink) {
|
||||
output.debug(`Found Git repository root directory: ${repoLink.rootPath}`);
|
||||
} else {
|
||||
@@ -75,7 +85,14 @@ export async function ensureRepoLink(
|
||||
}
|
||||
let { rootPath, repoConfig, repoConfigPath } = repoLink;
|
||||
|
||||
if (!repoConfig) {
|
||||
if (overwrite || !repoConfig) {
|
||||
// Detect the projects on the filesystem out of band, so that
|
||||
// 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>();
|
||||
});
|
||||
|
||||
// Not yet linked, so prompt user to begin linking
|
||||
let shouldLink =
|
||||
yes ||
|
||||
@@ -112,64 +129,148 @@ export async function ensureRepoLink(
|
||||
remoteName = remoteNames[0];
|
||||
} else {
|
||||
// Prompt user to select which remote to use
|
||||
const originIndex = remoteNames.indexOf('origin');
|
||||
const answer = await client.prompt({
|
||||
type: 'list',
|
||||
name: 'value',
|
||||
message: 'Which Git remote should be used?',
|
||||
choices: remoteNames.map(name => {
|
||||
choices: remoteNames.sort().map(name => {
|
||||
return { name: name, value: name };
|
||||
}),
|
||||
default: originIndex === -1 ? 0 : originIndex,
|
||||
default: remoteNames.includes('origin') ? 'origin' : undefined,
|
||||
});
|
||||
remoteName = answer.value;
|
||||
}
|
||||
const repoUrl = remoteUrls[remoteName];
|
||||
const parsedRepoUrl = parseRepoUrl(repoUrl);
|
||||
if (!parsedRepoUrl) {
|
||||
throw new Error(`Failed to parse Git URL: ${repoUrl}`);
|
||||
}
|
||||
const repoUrlLink = output.link(repoUrl, repoInfoToUrl(parsedRepoUrl), {
|
||||
fallback: () => link(repoUrl),
|
||||
});
|
||||
output.spinner(
|
||||
`Fetching Projects for ${link(repoUrl)} under ${chalk.bold(org.slug)}…`
|
||||
`Fetching Projects for ${repoUrlLink} under ${chalk.bold(org.slug)}…`
|
||||
);
|
||||
// TODO: Add pagination to fetch all Projects
|
||||
const query = new URLSearchParams({ repoUrl, limit: '100' });
|
||||
const projects: Project[] = await client.fetch(`/v2/projects?${query}`);
|
||||
let projects: Project[] = [];
|
||||
const query = new URLSearchParams({ repoUrl });
|
||||
const projectsIterator = client.fetchPaginated<{
|
||||
projects: Project[];
|
||||
}>(`/v9/projects?${query}`);
|
||||
const detectedProjects = await detectedProjectsPromise;
|
||||
for await (const chunk of projectsIterator) {
|
||||
projects = projects.concat(chunk.projects);
|
||||
if (chunk.pagination.next) {
|
||||
output.spinner(`Found ${chalk.bold(projects.length)} Projects…`, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (projects.length === 0) {
|
||||
output.log(
|
||||
`No Projects are linked to ${link(repoUrl)} under ${chalk.bold(
|
||||
`No Projects are linked to ${repoUrlLink} under ${chalk.bold(
|
||||
org.slug
|
||||
)}.`
|
||||
);
|
||||
// TODO: run detection logic to find potential projects.
|
||||
// then prompt user to select valid projects.
|
||||
// then create new Projects
|
||||
} else {
|
||||
output.log(
|
||||
`Found ${chalk.bold(projects.length)} ${pluralize(
|
||||
`Found ${pluralize(
|
||||
'Project',
|
||||
projects.length
|
||||
)} linked to ${link(repoUrl)} under ${chalk.bold(org.slug)}:`
|
||||
projects.length,
|
||||
true
|
||||
)} linked to ${repoUrlLink} under ${chalk.bold(org.slug)}`
|
||||
);
|
||||
}
|
||||
|
||||
// For any projects that already exists on Vercel, remove them from the
|
||||
// locally detected directories. Any remaining ones will be prompted to
|
||||
// create new Projects for.
|
||||
for (const project of projects) {
|
||||
output.print(` * ${chalk.cyan(`${org.slug}/${project.name}\n`)}`);
|
||||
detectedProjects.delete(project.rootDirectory ?? '');
|
||||
}
|
||||
|
||||
shouldLink =
|
||||
yes ||
|
||||
(await confirm(
|
||||
client,
|
||||
`Link to ${projects.length === 1 ? 'it' : 'them'}?`,
|
||||
true
|
||||
));
|
||||
if (detectedProjects.size > 0) {
|
||||
output.log(
|
||||
`Detected ${pluralize(
|
||||
'new Project',
|
||||
detectedProjects.size,
|
||||
true
|
||||
)} that may be created.`
|
||||
);
|
||||
}
|
||||
|
||||
if (!shouldLink) {
|
||||
output.print(`Canceled. Repository not linked.\n`);
|
||||
const addSeparators = projects.length > 0 && detectedProjects.size > 0;
|
||||
const { selected } = await client.prompt({
|
||||
type: 'checkbox',
|
||||
name: 'selected',
|
||||
message: `Which Projects should be ${
|
||||
projects.length ? 'linked to' : 'created'
|
||||
}?`,
|
||||
choices: [
|
||||
...(addSeparators
|
||||
? [new inquirer.Separator('----- Existing Projects -----')]
|
||||
: []),
|
||||
...projects.map(project => {
|
||||
return {
|
||||
name: `${org.slug}/${project.name}`,
|
||||
value: project,
|
||||
checked: true,
|
||||
};
|
||||
}),
|
||||
...(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,
|
||||
},
|
||||
};
|
||||
}
|
||||
),
|
||||
],
|
||||
});
|
||||
|
||||
if (selected.length === 0) {
|
||||
output.print(`No Projects were selected. Repository not linked.\n`);
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < selected.length; i++) {
|
||||
const selection = selected[i];
|
||||
if (!selection.newProject) continue;
|
||||
const orgAndName = `${org.slug}/${selection.name}`;
|
||||
output.spinner(`Creating new Project: ${orgAndName}`);
|
||||
delete selection.newProject;
|
||||
if (!selection.rootDirectory) delete selection.rootDirectory;
|
||||
selected[i] = await createProject(client, selection);
|
||||
await connectGitProvider(
|
||||
client,
|
||||
org,
|
||||
selected[i].id,
|
||||
parsedRepoUrl.provider,
|
||||
`${parsedRepoUrl.org}/${parsedRepoUrl.repo}`
|
||||
);
|
||||
output.log(
|
||||
`Created new Project: ${output.link(
|
||||
orgAndName,
|
||||
`https://vercel.com/${orgAndName}`
|
||||
)}`
|
||||
);
|
||||
}
|
||||
|
||||
repoConfig = {
|
||||
orgId: org.id,
|
||||
remoteName,
|
||||
projects: projects.map(project => {
|
||||
projects: selected.map((project: Project) => {
|
||||
return {
|
||||
id: project.id,
|
||||
name: project.name,
|
||||
@@ -179,17 +280,14 @@ export async function ensureRepoLink(
|
||||
};
|
||||
await outputJSON(repoConfigPath, repoConfig, { spaces: 2 });
|
||||
|
||||
await writeFile(
|
||||
join(rootPath, VERCEL_DIR, VERCEL_DIR_README),
|
||||
await readFile(join(__dirname, 'VERCEL_DIR_README.txt'), 'utf8')
|
||||
);
|
||||
await writeReadme(rootPath);
|
||||
|
||||
// update .gitignore
|
||||
const isGitIgnoreUpdated = await addToGitIgnore(rootPath);
|
||||
|
||||
output.print(
|
||||
prependEmoji(
|
||||
`Linked to ${link(repoUrl)} under ${chalk.bold(
|
||||
`Linked to ${repoUrlLink} under ${chalk.bold(
|
||||
org.slug
|
||||
)} (created ${VERCEL_DIR}${
|
||||
isGitIgnoreUpdated ? ' and added it to .gitignore' : ''
|
||||
@@ -211,45 +309,47 @@ export async function ensureRepoLink(
|
||||
* the nearest `.git/config` file is found. Returns the directory where
|
||||
* the Git config was found, or `undefined` when no Git repo was found.
|
||||
*/
|
||||
export async function findRepoRoot(start: string): Promise<string | undefined> {
|
||||
for (const current of traverseUpDirectories(start)) {
|
||||
export async function findRepoRoot(
|
||||
client: Client,
|
||||
start: string
|
||||
): Promise<string | undefined> {
|
||||
const { debug } = client.output;
|
||||
const REPO_JSON_PATH = join(VERCEL_DIR, VERCEL_DIR_REPO);
|
||||
const GIT_CONFIG_PATH = normalize('.git/config');
|
||||
|
||||
for (const current of traverseUpDirectories({ start })) {
|
||||
if (current === home) {
|
||||
// Sometimes the $HOME directory is set up as a Git repo
|
||||
// (for dotfiles, etc.). In this case it's safe to say that
|
||||
// this isn't the repo we're looking for. Bail.
|
||||
debug('Arrived at home directory');
|
||||
break;
|
||||
}
|
||||
|
||||
// if `.vercel/repo.json` exists (already linked),
|
||||
// then consider this the repo root
|
||||
const repoConfigPath = join(current, VERCEL_DIR, VERCEL_DIR_REPO);
|
||||
const repoConfigPath = join(current, REPO_JSON_PATH);
|
||||
let stat = await lstat(repoConfigPath).catch(err => {
|
||||
if (err.code !== 'ENOENT') throw err;
|
||||
});
|
||||
if (stat) {
|
||||
debug(`Found "${REPO_JSON_PATH}" - detected "${current}" as repo root`);
|
||||
return current;
|
||||
}
|
||||
|
||||
// if `.git/config` exists (unlinked),
|
||||
// then consider this the repo root
|
||||
const gitConfigPath = join(current, '.git/config');
|
||||
const gitConfigPath = join(current, GIT_CONFIG_PATH);
|
||||
stat = await lstat(gitConfigPath).catch(err => {
|
||||
if (err.code !== 'ENOENT') throw err;
|
||||
});
|
||||
if (stat) {
|
||||
debug(`Found "${GIT_CONFIG_PATH}" - detected "${current}" as repo root`);
|
||||
return current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function* traverseUpDirectories(start: string) {
|
||||
let current: string | undefined = normalize(start);
|
||||
while (current) {
|
||||
yield current;
|
||||
// Go up one directory
|
||||
const next = join(current, '..');
|
||||
current = next === current ? undefined : next;
|
||||
}
|
||||
debug('Aborting search for repo root');
|
||||
}
|
||||
|
||||
function sortByDirectory(a: RepoProjectConfig, b: RepoProjectConfig): number {
|
||||
@@ -268,7 +368,7 @@ export function findProjectsFromPath(
|
||||
path: string
|
||||
): RepoProjectConfig[] {
|
||||
const normalizedPath = normalizePath(path);
|
||||
return projects
|
||||
const matches = projects
|
||||
.slice()
|
||||
.sort(sortByDirectory)
|
||||
.filter(project => {
|
||||
@@ -281,14 +381,9 @@ export function findProjectsFromPath(
|
||||
normalizedPath.startsWith(`${project.directory}/`)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: remove
|
||||
*/
|
||||
export function findProjectFromPath(
|
||||
projects: RepoProjectConfig[],
|
||||
path: string
|
||||
): RepoProjectConfig | undefined {
|
||||
return findProjectsFromPath(projects, path)[0];
|
||||
// If there are multiple matches, we only want the most relevant
|
||||
// selections (with the deepest directory depth), so pick the first
|
||||
// one and filter on those matches.
|
||||
const firstMatch = matches[0];
|
||||
return matches.filter(match => match.directory === firstMatch.directory);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
VERCEL_DIR_PROJECT,
|
||||
} from '../projects/link';
|
||||
import createProject from '../projects/create-project';
|
||||
import updateProject from '../projects/update-project';
|
||||
import Client from '../client';
|
||||
import handleError from '../handle-error';
|
||||
import confirm from '../input/confirm';
|
||||
@@ -245,10 +244,10 @@ export default async function setupAndLink(
|
||||
settings.rootDirectory = rootDirectory;
|
||||
}
|
||||
|
||||
const project = await createProject(client, newProjectName);
|
||||
|
||||
await updateProject(client, project.id, settings);
|
||||
Object.assign(project, settings);
|
||||
const project = await createProject(client, {
|
||||
...settings,
|
||||
name: newProjectName,
|
||||
});
|
||||
|
||||
await linkFolderToProject(
|
||||
client,
|
||||
|
||||
@@ -3,9 +3,9 @@ import * as ansiEscapes from 'ansi-escapes';
|
||||
import { supportsHyperlink as detectSupportsHyperlink } from 'supports-hyperlinks';
|
||||
import renderLink from './link';
|
||||
import wait, { StopSpinner } from './wait';
|
||||
import type { WritableTTY } from '@vercel-internals/types';
|
||||
import { errorToString } from '@vercel/error-utils';
|
||||
import { removeEmoji } from '../emoji';
|
||||
import type * as tty from 'tty';
|
||||
|
||||
const IS_TEST = process.env.NODE_ENV === 'test';
|
||||
|
||||
@@ -24,7 +24,7 @@ interface LinkOptions {
|
||||
}
|
||||
|
||||
export class Output {
|
||||
stream: WritableTTY;
|
||||
stream: tty.WriteStream;
|
||||
debugEnabled: boolean;
|
||||
supportsHyperlink: boolean;
|
||||
colorDisabled: boolean;
|
||||
@@ -32,7 +32,7 @@ export class Output {
|
||||
private _spinner: StopSpinner | null;
|
||||
|
||||
constructor(
|
||||
stream: WritableTTY,
|
||||
stream: tty.WriteStream,
|
||||
{
|
||||
debug: debugEnabled = false,
|
||||
supportsHyperlink = detectSupportsHyperlink(stream),
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import Client from '../client';
|
||||
import type { Project } from '@vercel-internals/types';
|
||||
import type { Project, ProjectSettings } from '@vercel-internals/types';
|
||||
|
||||
export default async function createProject(
|
||||
client: Client,
|
||||
projectName: string
|
||||
settings: ProjectSettings & { name: string }
|
||||
) {
|
||||
const project = await client.fetch<Project>('/v1/projects', {
|
||||
method: 'POST',
|
||||
body: { name: projectName },
|
||||
body: { ...settings },
|
||||
});
|
||||
return project;
|
||||
}
|
||||
|
||||
38
packages/cli/src/util/projects/detect-projects.ts
Normal file
38
packages/cli/src/util/projects/detect-projects.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { join } from 'path';
|
||||
import frameworks from '@vercel/frameworks';
|
||||
import {
|
||||
detectFramework,
|
||||
getWorkspacePackagePaths,
|
||||
getWorkspaces,
|
||||
LocalFileSystemDetector,
|
||||
} from '@vercel/fs-detectors';
|
||||
|
||||
export async function detectProjects(cwd: string) {
|
||||
const fs = new LocalFileSystemDetector(cwd);
|
||||
const workspaces = await getWorkspaces({ fs });
|
||||
const detectedProjects = new Map<string, string>();
|
||||
const packagePaths = (
|
||||
await Promise.all(
|
||||
workspaces.map(workspace =>
|
||||
getWorkspacePackagePaths({
|
||||
fs,
|
||||
workspace,
|
||||
})
|
||||
)
|
||||
)
|
||||
).flat();
|
||||
if (packagePaths.length === 0) {
|
||||
packagePaths.push('/');
|
||||
}
|
||||
await Promise.all(
|
||||
packagePaths.map(async p => {
|
||||
const framework = await detectFramework({
|
||||
fs: fs.chdir(join('.', p)),
|
||||
frameworkList: frameworks,
|
||||
});
|
||||
if (!framework) return;
|
||||
detectedProjects.set(p.slice(1), framework);
|
||||
})
|
||||
);
|
||||
return detectedProjects;
|
||||
}
|
||||
@@ -74,9 +74,7 @@ export default async function getProjectByDeployment({
|
||||
err.code = 'ERR_INVALID_TEAM';
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
if (team) {
|
||||
} else if (team) {
|
||||
const err: NodeJS.ErrnoException = new Error(
|
||||
`Deployment doesn't belong to current team ${chalk.bold(contextName)}`
|
||||
);
|
||||
|
||||
@@ -69,7 +69,7 @@ export function getVercelDirectory(cwd: string): string {
|
||||
return existingDirs[0] || possibleDirs[0];
|
||||
}
|
||||
|
||||
async function getProjectLink(
|
||||
export async function getProjectLink(
|
||||
client: Client,
|
||||
path: string
|
||||
): Promise<ProjectLink | null> {
|
||||
@@ -83,7 +83,7 @@ async function getProjectLinkFromRepoLink(
|
||||
client: Client,
|
||||
path: string
|
||||
): Promise<ProjectLink | null> {
|
||||
const repoLink = await getRepoLink(path);
|
||||
const repoLink = await getRepoLink(client, path);
|
||||
if (!repoLink?.repoConfig) {
|
||||
return null;
|
||||
}
|
||||
@@ -95,11 +95,13 @@ async function getProjectLinkFromRepoLink(
|
||||
if (projects.length === 1) {
|
||||
project = projects[0];
|
||||
} else {
|
||||
const selectableProjects =
|
||||
projects.length > 0 ? projects : repoLink.repoConfig.projects;
|
||||
const { p } = await client.prompt({
|
||||
name: 'p',
|
||||
type: 'list',
|
||||
message: `Please select a Project:`,
|
||||
choices: repoLink.repoConfig.projects.map(p => ({
|
||||
choices: selectableProjects.map(p => ({
|
||||
value: p,
|
||||
name: p.name,
|
||||
})),
|
||||
@@ -108,9 +110,10 @@ async function getProjectLinkFromRepoLink(
|
||||
}
|
||||
if (project) {
|
||||
return {
|
||||
repoRoot: repoLink.rootPath,
|
||||
orgId: repoLink.repoConfig.orgId,
|
||||
projectId: project.id,
|
||||
repoRoot: repoLink.rootPath,
|
||||
projectRootDirectory: project.directory,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
@@ -166,6 +169,7 @@ async function getOrgById(client: Client, orgId: string): Promise<Org | null> {
|
||||
}
|
||||
|
||||
async function hasProjectLink(
|
||||
client: Client,
|
||||
projectLink: ProjectLink,
|
||||
path: string
|
||||
): Promise<boolean> {
|
||||
@@ -180,7 +184,7 @@ async function hasProjectLink(
|
||||
}
|
||||
|
||||
// linked via `repo.json`?
|
||||
const repoLink = await getRepoLink(path);
|
||||
const repoLink = await getRepoLink(client, path);
|
||||
if (
|
||||
repoLink?.repoConfig?.orgId === projectLink.orgId &&
|
||||
repoLink.repoConfig.projects.find(p => p.id === projectLink.projectId)
|
||||
@@ -242,7 +246,7 @@ export async function getLinkedProject(
|
||||
if (isAPIError(err) && err.status === 403) {
|
||||
output.stopSpinner();
|
||||
|
||||
if (err.missingToken) {
|
||||
if (err.missingToken || err.invalidToken) {
|
||||
throw new InvalidToken();
|
||||
} else {
|
||||
throw new NowBuildError({
|
||||
@@ -284,6 +288,13 @@ export async function getLinkedProject(
|
||||
return { status: 'linked', org, project, repoRoot: link.repoRoot };
|
||||
}
|
||||
|
||||
export async function writeReadme(path: string) {
|
||||
await writeFile(
|
||||
join(path, VERCEL_DIR, VERCEL_DIR_README),
|
||||
await readFile(join(__dirname, 'VERCEL_DIR_README.txt'), 'utf8')
|
||||
);
|
||||
}
|
||||
|
||||
export async function linkFolderToProject(
|
||||
client: Client,
|
||||
path: string,
|
||||
@@ -293,7 +304,7 @@ export async function linkFolderToProject(
|
||||
successEmoji: EmojiLabel = 'link'
|
||||
) {
|
||||
// if the project is already linked, we skip linking
|
||||
if (await hasProjectLink(projectLink, path)) {
|
||||
if (await hasProjectLink(client, projectLink, path)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -313,10 +324,7 @@ export async function linkFolderToProject(
|
||||
JSON.stringify(projectLink)
|
||||
);
|
||||
|
||||
await writeFile(
|
||||
join(path, VERCEL_DIR, VERCEL_DIR_README),
|
||||
await readFile(join(__dirname, 'VERCEL_DIR_README.txt'), 'utf8')
|
||||
);
|
||||
await writeReadme(path);
|
||||
|
||||
// update .gitignore
|
||||
const isGitIgnoreUpdated = await addToGitIgnore(path);
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { outputJSON } from 'fs-extra';
|
||||
import { Org, Project, ProjectLink } from '@vercel-internals/types';
|
||||
import { getLinkFromDir, VERCEL_DIR, VERCEL_DIR_PROJECT } from './link';
|
||||
import { join } from 'path';
|
||||
import { outputJSON, readFile } from 'fs-extra';
|
||||
import { VercelConfig } from '@vercel/client';
|
||||
import { VERCEL_DIR, VERCEL_DIR_PROJECT } from './link';
|
||||
import { PartialProjectSettings } from '../input/edit-project-settings';
|
||||
import type { Org, Project, ProjectLink } from '@vercel-internals/types';
|
||||
import { isErrnoException, isError } from '@vercel/error-utils';
|
||||
|
||||
export type ProjectLinkAndSettings = ProjectLink & {
|
||||
export type ProjectLinkAndSettings = Partial<ProjectLink> & {
|
||||
settings: {
|
||||
createdAt: Project['createdAt'];
|
||||
installCommand: Project['installCommand'];
|
||||
@@ -26,7 +27,8 @@ export type ProjectLinkAndSettings = ProjectLink & {
|
||||
export async function writeProjectSettings(
|
||||
cwd: string,
|
||||
project: Project,
|
||||
org: Org
|
||||
org: Org,
|
||||
isRepoLinked: boolean
|
||||
) {
|
||||
let analyticsId: string | undefined;
|
||||
if (
|
||||
@@ -39,8 +41,8 @@ export async function writeProjectSettings(
|
||||
}
|
||||
|
||||
const projectLinkAndSettings: ProjectLinkAndSettings = {
|
||||
projectId: project.id,
|
||||
orgId: org.id,
|
||||
projectId: isRepoLinked ? undefined : project.id,
|
||||
orgId: isRepoLinked ? undefined : org.id,
|
||||
settings: {
|
||||
createdAt: project.createdAt,
|
||||
framework: project.framework,
|
||||
@@ -60,8 +62,28 @@ export async function writeProjectSettings(
|
||||
});
|
||||
}
|
||||
|
||||
export async function readProjectSettings(cwd: string) {
|
||||
return await getLinkFromDir<ProjectLinkAndSettings>(cwd);
|
||||
export async function readProjectSettings(vercelDir: string) {
|
||||
try {
|
||||
return JSON.parse(
|
||||
await readFile(join(vercelDir, VERCEL_DIR_PROJECT), 'utf8')
|
||||
);
|
||||
} catch (err: unknown) {
|
||||
// `project.json` file does not exists, so project settings have not been pulled
|
||||
if (
|
||||
isErrnoException(err) &&
|
||||
err.code &&
|
||||
['ENOENT', 'ENOTDIR'].includes(err.code)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// failed to parse JSON, treat the same as if project settings have not been pulled
|
||||
if (isError(err) && err.name === 'SyntaxError') {
|
||||
return null;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
export function pickOverrides(
|
||||
|
||||
@@ -1,26 +1,16 @@
|
||||
import Client from '../client';
|
||||
import type { JSONObject, ProjectSettings } from '@vercel-internals/types';
|
||||
|
||||
interface ProjectSettingsResponse extends ProjectSettings {
|
||||
id: string;
|
||||
name: string;
|
||||
updatedAt: number;
|
||||
createdAt: number;
|
||||
}
|
||||
import type { Project, ProjectSettings } from '@vercel-internals/types';
|
||||
|
||||
export default async function updateProject(
|
||||
client: Client,
|
||||
prjNameOrId: string,
|
||||
settings: ProjectSettings
|
||||
) {
|
||||
// `ProjectSettings` is technically compatible with JSONObject
|
||||
const body = settings as JSONObject;
|
||||
|
||||
const res = await client.fetch<ProjectSettingsResponse>(
|
||||
const res = await client.fetch<Project>(
|
||||
`/v2/projects/${encodeURIComponent(prjNameOrId)}`,
|
||||
{
|
||||
method: 'PATCH',
|
||||
body,
|
||||
body: { ...settings },
|
||||
}
|
||||
);
|
||||
return res;
|
||||
|
||||
@@ -322,14 +322,17 @@ test('[vercel dev] should handle missing handler errors thrown in edge functions
|
||||
);
|
||||
validateResponseHeaders(res);
|
||||
|
||||
const { stderr } = await dev.kill();
|
||||
const { stdout } = await dev.kill();
|
||||
|
||||
expect(await res.text()).toMatch(
|
||||
/<strong>500<\/strong>: INTERNAL_SERVER_ERROR/g
|
||||
);
|
||||
expect(stderr).toMatch(
|
||||
/No default export was found. Add a default export to handle requests./g
|
||||
);
|
||||
const url = `http://localhost:${port}/api/edge-error-no-handler`;
|
||||
expect(stdout).toMatchInlineSnapshot(`
|
||||
"Error from API Route /api/edge-error-no-handler: No default or HTTP-named export was found at ${url}. Add one to handle requests. Learn more: https://vercel.link/creating-edge-middleware
|
||||
at (api/edge-error-no-handler.js)
|
||||
"
|
||||
`);
|
||||
} finally {
|
||||
await dev.kill();
|
||||
}
|
||||
|
||||
@@ -88,10 +88,10 @@ test(
|
||||
async (testPath: any) => {
|
||||
const vcRobots = `https://vercel.com/robots.txt`;
|
||||
await testPath(200, '/rewrite', /User-Agent: \*/m);
|
||||
await testPath(308, '/redirect', `Redirecting to ${vcRobots} (308)`, {
|
||||
await testPath(308, '/redirect', `Redirecting...`, {
|
||||
Location: vcRobots,
|
||||
});
|
||||
await testPath(307, '/tempRedirect', `Redirecting to ${vcRobots} (307)`, {
|
||||
await testPath(307, '/tempRedirect', `Redirecting...`, {
|
||||
Location: vcRobots,
|
||||
});
|
||||
}
|
||||
@@ -103,10 +103,10 @@ test(
|
||||
testFixtureStdio('test-routing-case-sensitive', async (testPath: any) => {
|
||||
await testPath(200, '/Path', 'UPPERCASE');
|
||||
await testPath(200, '/path', 'lowercase');
|
||||
await testPath(308, '/GoTo', 'Redirecting to /upper.html (308)', {
|
||||
await testPath(308, '/GoTo', 'Redirecting...', {
|
||||
Location: '/upper.html',
|
||||
});
|
||||
await testPath(308, '/goto', 'Redirecting to /lower.html (308)', {
|
||||
await testPath(308, '/goto', 'Redirecting...', {
|
||||
Location: '/lower.html',
|
||||
});
|
||||
})
|
||||
|
||||
@@ -233,7 +233,7 @@ test(
|
||||
expect(res.headers.get('location')).toBe(
|
||||
`http://localhost:${port}/?foo=bar`
|
||||
);
|
||||
expect(body).toBe('Redirecting to /?foo=bar (301)\n');
|
||||
expect(body).toBe('Redirecting...\n');
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -197,21 +197,18 @@ test(
|
||||
await testPath(200, '/sub', 'Sub Index Page');
|
||||
await testPath(200, '/sub/another', 'Sub Another Page');
|
||||
await testPath(200, '/style.css', 'body { color: green }');
|
||||
await testPath(308, '/index.html', 'Redirecting to / (308)', {
|
||||
await testPath(308, '/index.html', 'Redirecting...', {
|
||||
Location: '/',
|
||||
});
|
||||
await testPath(308, '/about.html', 'Redirecting to /about (308)', {
|
||||
await testPath(308, '/about.html', 'Redirecting...', {
|
||||
Location: '/about',
|
||||
});
|
||||
await testPath(308, '/sub/index.html', 'Redirecting to /sub (308)', {
|
||||
await testPath(308, '/sub/index.html', 'Redirecting...', {
|
||||
Location: '/sub',
|
||||
});
|
||||
await testPath(
|
||||
308,
|
||||
'/sub/another.html',
|
||||
'Redirecting to /sub/another (308)',
|
||||
{ Location: '/sub/another' }
|
||||
);
|
||||
await testPath(308, '/sub/another.html', 'Redirecting...', {
|
||||
Location: '/sub/another',
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -225,21 +222,18 @@ test(
|
||||
await testPath(200, '/sub', 'Sub Index Page');
|
||||
await testPath(200, '/sub/another', 'Sub Another Page');
|
||||
await testPath(200, '/style.css', 'body { color: green }');
|
||||
await testPath(308, '/index.html', 'Redirecting to / (308)', {
|
||||
await testPath(308, '/index.html', 'Redirecting...', {
|
||||
Location: '/',
|
||||
});
|
||||
await testPath(308, '/about.html', 'Redirecting to /about (308)', {
|
||||
await testPath(308, '/about.html', 'Redirecting...', {
|
||||
Location: '/about',
|
||||
});
|
||||
await testPath(308, '/sub/index.html', 'Redirecting to /sub (308)', {
|
||||
await testPath(308, '/sub/index.html', 'Redirecting...', {
|
||||
Location: '/sub',
|
||||
});
|
||||
await testPath(
|
||||
308,
|
||||
'/sub/another.html',
|
||||
'Redirecting to /sub/another (308)',
|
||||
{ Location: '/sub/another' }
|
||||
);
|
||||
await testPath(308, '/sub/another.html', 'Redirecting...', {
|
||||
Location: '/sub/another',
|
||||
});
|
||||
}
|
||||
)
|
||||
);
|
||||
@@ -264,21 +258,16 @@ test(
|
||||
await testPath(200, '/sub/another/', 'Sub Another Page');
|
||||
await testPath(200, '/style.css', 'body { color: green }');
|
||||
//TODO: fix this test so that location is `/` instead of `//`
|
||||
//await testPath(308, '/index.html', 'Redirecting to / (308)', { Location: '/' });
|
||||
await testPath(308, '/about.html', 'Redirecting to /about/ (308)', {
|
||||
//await testPath(308, '/index.html', 'Redirecting...', { Location: '/' });
|
||||
await testPath(308, '/about.html', 'Redirecting...', {
|
||||
Location: '/about/',
|
||||
});
|
||||
await testPath(308, '/sub/index.html', 'Redirecting to /sub/ (308)', {
|
||||
await testPath(308, '/sub/index.html', 'Redirecting...', {
|
||||
Location: '/sub/',
|
||||
});
|
||||
await testPath(
|
||||
308,
|
||||
'/sub/another.html',
|
||||
'Redirecting to /sub/another/ (308)',
|
||||
{
|
||||
Location: '/sub/another/',
|
||||
}
|
||||
);
|
||||
await testPath(308, '/sub/another.html', 'Redirecting...', {
|
||||
Location: '/sub/another/',
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
@@ -315,13 +304,13 @@ test(
|
||||
await testPath(200, '/sub/index.html', 'Sub Index Page');
|
||||
await testPath(200, '/sub/another.html', 'Sub Another Page');
|
||||
await testPath(200, '/style.css', 'body { color: green }');
|
||||
await testPath(308, '/about.html/', 'Redirecting to /about.html (308)', {
|
||||
await testPath(308, '/about.html/', 'Redirecting...', {
|
||||
Location: '/about.html',
|
||||
});
|
||||
await testPath(308, '/style.css/', 'Redirecting to /style.css (308)', {
|
||||
await testPath(308, '/style.css/', 'Redirecting...', {
|
||||
Location: '/style.css',
|
||||
});
|
||||
await testPath(308, '/sub', 'Redirecting to /sub/ (308)', {
|
||||
await testPath(308, '/sub', 'Redirecting...', {
|
||||
Location: '/sub/',
|
||||
});
|
||||
})
|
||||
@@ -347,20 +336,15 @@ test(
|
||||
await testPath(200, '/sub/index.html', 'Sub Index Page');
|
||||
await testPath(200, '/sub/another.html', 'Sub Another Page');
|
||||
await testPath(200, '/style.css', 'body { color: green }');
|
||||
await testPath(308, '/about.html/', 'Redirecting to /about.html (308)', {
|
||||
await testPath(308, '/about.html/', 'Redirecting...', {
|
||||
Location: '/about.html',
|
||||
});
|
||||
await testPath(308, '/sub/', 'Redirecting to /sub (308)', {
|
||||
await testPath(308, '/sub/', 'Redirecting...', {
|
||||
Location: '/sub',
|
||||
});
|
||||
await testPath(
|
||||
308,
|
||||
'/sub/another.html/',
|
||||
'Redirecting to /sub/another.html (308)',
|
||||
{
|
||||
Location: '/sub/another.html',
|
||||
}
|
||||
);
|
||||
await testPath(308, '/sub/another.html/', 'Redirecting...', {
|
||||
Location: '/sub/another.html',
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -44,7 +44,9 @@ function fetchWithRetry(url, opts = {}) {
|
||||
if (res.status !== opts.status) {
|
||||
const text = await res.text();
|
||||
throw new Error(
|
||||
`Failed to fetch ${url} with status ${res.status} (expected ${opts.status}):\n\n${text}\n\n`
|
||||
`Failed to fetch "${url}", received ${res.status}, expected ${
|
||||
opts.status
|
||||
}, id: ${res.headers.get('x-vercel-id')}:\n\n${text}\n\n`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
4
packages/cli/test/fixtures/unit/build-output-api-failed-before-builds/.vercel/project.json
vendored
Normal file
4
packages/cli/test/fixtures/unit/build-output-api-failed-before-builds/.vercel/project.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"orgId": "team_dummy",
|
||||
"projectId": "build-output-api-failed-before-builds"
|
||||
}
|
||||
4
packages/cli/test/fixtures/unit/build-output-api-failed-within-build/.vercel/project.json
vendored
Normal file
4
packages/cli/test/fixtures/unit/build-output-api-failed-within-build/.vercel/project.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"orgId": "team_dummy",
|
||||
"projectId": "build-output-api-failed-within-build"
|
||||
}
|
||||
4
packages/cli/test/fixtures/unit/build-output-api-preview/.vercel/project.json
vendored
Normal file
4
packages/cli/test/fixtures/unit/build-output-api-preview/.vercel/project.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"orgId": "team_dummy",
|
||||
"projectId": "build-output-api-preview"
|
||||
}
|
||||
4
packages/cli/test/fixtures/unit/build-output-api-production/.vercel/project.json
vendored
Normal file
4
packages/cli/test/fixtures/unit/build-output-api-production/.vercel/project.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"orgId": "team_dummy",
|
||||
"projectId": "build-output-api-production"
|
||||
}
|
||||
3
packages/cli/test/fixtures/unit/commands/build/npmrc-use-node-version/.npmrc
vendored
Normal file
3
packages/cli/test/fixtures/unit/commands/build/npmrc-use-node-version/.npmrc
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
foo=bar
|
||||
# the next line is not supported
|
||||
use-node-version=16.16.0
|
||||
1
packages/cli/test/fixtures/unit/commands/build/static-env/.env
vendored
Normal file
1
packages/cli/test/fixtures/unit/commands/build/static-env/.env
vendored
Normal file
@@ -0,0 +1 @@
|
||||
FOO=bar
|
||||
7
packages/cli/test/fixtures/unit/commands/build/static-env/.vercel/project.json
vendored
Normal file
7
packages/cli/test/fixtures/unit/commands/build/static-env/.vercel/project.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"orgId": ".",
|
||||
"projectId": ".",
|
||||
"settings": {
|
||||
"framework": null
|
||||
}
|
||||
}
|
||||
5
packages/cli/test/fixtures/unit/commands/build/static-env/index.html
vendored
Normal file
5
packages/cli/test/fixtures/unit/commands/build/static-env/index.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
Hello world!
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +1,3 @@
|
||||
!.vercel
|
||||
dist
|
||||
!/.vercel
|
||||
.vercel/output
|
||||
|
||||
6
packages/cli/test/fixtures/unit/monorepo-link/blog/package.json
vendored
Normal file
6
packages/cli/test/fixtures/unit/monorepo-link/blog/package.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "blog",
|
||||
"scripts": {
|
||||
"build": "mkdir -p dist && echo blog > dist/index.txt"
|
||||
}
|
||||
}
|
||||
6
packages/cli/test/fixtures/unit/monorepo-link/dashboard/package.json
vendored
Normal file
6
packages/cli/test/fixtures/unit/monorepo-link/dashboard/package.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "dashboard",
|
||||
"scripts": {
|
||||
"build": "mkdir -p dist && echo dashboard > dist/index.txt"
|
||||
}
|
||||
}
|
||||
6
packages/cli/test/fixtures/unit/monorepo-link/marketing/package.json
vendored
Normal file
6
packages/cli/test/fixtures/unit/monorepo-link/marketing/package.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "marketing",
|
||||
"scripts": {
|
||||
"build": "mkdir -p dist && echo marketing > dist/index.txt"
|
||||
}
|
||||
}
|
||||
4
packages/cli/test/fixtures/unit/vercel-env-pull-with-gitignore/.gitignore
vendored
Normal file
4
packages/cli/test/fixtures/unit/vercel-env-pull-with-gitignore/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.next
|
||||
yarn.lock
|
||||
!.vercel
|
||||
.env*.local
|
||||
4
packages/cli/test/fixtures/unit/vercel-env-pull-with-gitignore/.vercel/project.json
vendored
Normal file
4
packages/cli/test/fixtures/unit/vercel-env-pull-with-gitignore/.vercel/project.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"orgId": "team_dummy",
|
||||
"projectId": "vercel-env-pull-with-gitignore"
|
||||
}
|
||||
@@ -47,7 +47,7 @@ export function setupTmpDir(fixtureName?: string) {
|
||||
|
||||
const cwd = path.join(tempRoot.name, String(tempNumber++), fixtureName ?? '');
|
||||
fs.mkdirpSync(cwd);
|
||||
return cwd;
|
||||
return fs.realpathSync(cwd);
|
||||
}
|
||||
|
||||
export function cleanupFixtures() {
|
||||
|
||||
4
packages/cli/test/integration-1.test.ts
vendored
4
packages/cli/test/integration-1.test.ts
vendored
@@ -32,7 +32,9 @@ function fetchTokenInformation(token: string, retries = 3) {
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch ${url}, received status ${res.status}`
|
||||
`Failed to fetch "${url}", status: ${
|
||||
res.status
|
||||
}, id: ${res.headers.get('x-vercel-id')}`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
4
packages/cli/test/integration-2.test.ts
vendored
4
packages/cli/test/integration-2.test.ts
vendored
@@ -43,7 +43,9 @@ function fetchTokenInformation(token: string, retries = 3) {
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch ${url}, received status ${res.status}`
|
||||
`Failed to fetch "${url}", status: ${
|
||||
res.status
|
||||
}, id: ${res.headers.get('x-vercel-id')}`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
4
packages/cli/test/integration-3.test.ts
vendored
4
packages/cli/test/integration-3.test.ts
vendored
@@ -47,7 +47,9 @@ function fetchTokenInformation(token: string, retries = 3) {
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch ${url}, received status ${res.status}`
|
||||
`Failed to fetch "${url}", status: ${
|
||||
res.status
|
||||
}, id: ${res.headers.get('x-vercel-id')}`
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user