mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-11 12:57:46 +00:00
Compare commits
33 Commits
api@0.0.0
...
@vercel/fs
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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
|
||||
|
||||
241
examples/nextjs/package-lock.json
generated
241
examples/nextjs/package-lock.json
generated
@@ -8,17 +8,17 @@
|
||||
"name": "nextjs",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"eslint": "8.41.0",
|
||||
"eslint-config-next": "13.4.4",
|
||||
"next": "13.4.4",
|
||||
"eslint": "8.42.0",
|
||||
"eslint-config-next": "13.4.5",
|
||||
"next": "13.4.5",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.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.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.5.tgz",
|
||||
"integrity": "sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==",
|
||||
"dependencies": {
|
||||
"regenerator-runtime": "^0.13.11"
|
||||
},
|
||||
@@ -71,17 +71,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.42.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.42.0.tgz",
|
||||
"integrity": "sha512-6SWlXpWU5AvId8Ac7zjzmIOqMOba/JWY8XZ4A7q7Gn1Vlfg/SFFIlrtHXt9nPn4op9ZPAkl91Jao+QQv3r/ukw==",
|
||||
"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 +109,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.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.5.tgz",
|
||||
"integrity": "sha512-SG/gKH6eij4vwQy87b/3mbpQ1X3x2vUdnpwq6/qL2IQWjtq58EY/UuNAp9CoEZoC9sI4L9AD1r+73Z9r4d3uug=="
|
||||
},
|
||||
"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.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.5.tgz",
|
||||
"integrity": "sha512-/xD/kyJhXmBZq+0xGKOdjL22c9/4i3mBAXaU9aOGEHTXqqFeOz8scJbScWF13aMqigeoFCsDqngIB2MIatcn4g==",
|
||||
"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.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.5.tgz",
|
||||
"integrity": "sha512-XvTzi2ASUN5bECFIAAcBiSoDb0xsq+KLj4F0bof4d4rdc+FgOqLvseGQaOXwVi1TIh5bHa7o4b6droSJMO5+2g==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -137,9 +137,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.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.5.tgz",
|
||||
"integrity": "sha512-NQdqal/VKAqlJTuzhjZmNtdo8QSqwmfO7b2xJSAengTEVxQvsH76oGEzQeIv8Ci4NP6DysAFtFrJq++TmIxcUA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -152,9 +152,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.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.5.tgz",
|
||||
"integrity": "sha512-nB8TjtpJCXtzIFjYOMbnQu68ajkA8QK58TreHjTGojSQjsF0StDqo5zFHglVVVHrd8d3N/+EjC18yFNSWnd/ZA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -167,9 +167,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.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.5.tgz",
|
||||
"integrity": "sha512-W126XUW599OV3giSH9Co40VpT8VAOT47xONVHXZaYEpeca0qEevjj6WUr5IJu/8u+XGWm5xI1S0DYWjR6W+olw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -182,9 +182,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.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.5.tgz",
|
||||
"integrity": "sha512-ZbPLO/oztQdtjGmWvGhRmtkZ6j9kQqg65kiO7F7Ijj7ojTtu3hh/vY+XRsHa/4Cse6HgyJ8XGZJMGoLb8ecQfQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -197,9 +197,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.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.5.tgz",
|
||||
"integrity": "sha512-f+/h8KMNixVUoRB+2vza8I+jsthJ4KcvopGUsDIUHe7Q4t+m8nKwGFBeyNu9qNIenYK5g5QYEsSwYFEqZylrTQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -212,9 +212,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.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.5.tgz",
|
||||
"integrity": "sha512-dvtPQZ5+J+zUE1uq7gP853Oj63e+n0T1ydZ/yRdVh7d8zW9ZFuC9fFrg3MqP1cv1NPPur8rrTqDKN2mRBkSSBw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@@ -227,9 +227,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.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.5.tgz",
|
||||
"integrity": "sha512-gK9zwGe25x31S4AjPy3Bf2niQvHIAbmwgkzmqWG3OmD4K2Z/Dh2ju4vuyzPzIt0pwQe4B520meP9NizTBmVWSg==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@@ -242,9 +242,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.5",
|
||||
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.5.tgz",
|
||||
"integrity": "sha512-iyNQVc7eGehrik9RJt9xGcnO6b/pi8C7GCfg8RGenx1IlalEKbYRgBJloF7DQzwlrV47E9bQl8swT+JawaNcKA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@@ -308,9 +308,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.1",
|
||||
"resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.3.1.tgz",
|
||||
"integrity": "sha512-RkmuBcqiNioeeBKbgzMlOdreUkJfYaSjwgx9XDgGGpjvWgyaxWvDmZVSN9CS6LjEASadhgPv2BcFp+SeouWXXA=="
|
||||
},
|
||||
"node_modules/@swc/helpers": {
|
||||
"version": "0.5.1",
|
||||
@@ -326,13 +326,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.59.9",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.9.tgz",
|
||||
"integrity": "sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ==",
|
||||
"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.59.9",
|
||||
"@typescript-eslint/types": "5.59.9",
|
||||
"@typescript-eslint/typescript-estree": "5.59.9",
|
||||
"debug": "^4.3.4"
|
||||
},
|
||||
"engines": {
|
||||
@@ -352,12 +352,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.59.9",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz",
|
||||
"integrity": "sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.59.7",
|
||||
"@typescript-eslint/visitor-keys": "5.59.7"
|
||||
"@typescript-eslint/types": "5.59.9",
|
||||
"@typescript-eslint/visitor-keys": "5.59.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
@@ -368,9 +368,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.59.9",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz",
|
||||
"integrity": "sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw==",
|
||||
"engines": {
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
},
|
||||
@@ -380,12 +380,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.59.9",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz",
|
||||
"integrity": "sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.59.7",
|
||||
"@typescript-eslint/visitor-keys": "5.59.7",
|
||||
"@typescript-eslint/types": "5.59.9",
|
||||
"@typescript-eslint/visitor-keys": "5.59.9",
|
||||
"debug": "^4.3.4",
|
||||
"globby": "^11.1.0",
|
||||
"is-glob": "^4.0.3",
|
||||
@@ -406,11 +406,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.59.9",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz",
|
||||
"integrity": "sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q==",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "5.59.7",
|
||||
"@typescript-eslint/types": "5.59.9",
|
||||
"eslint-visitor-keys": "^3.3.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -696,9 +696,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.30001498",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001498.tgz",
|
||||
"integrity": "sha512-LFInN2zAwx3ANrGCDZ5AKKJroHqNKyjXitdV5zRIVIaQlXKj3GmxUKagoKsjqUfckpAObPCEWnk5EeMlyMWcgw==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -1034,15 +1034,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.42.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.42.0.tgz",
|
||||
"integrity": "sha512-ulg9Ms6E1WPf67PHaEY4/6E2tEn5/f7FXGzr3t9cBMugOmf1INYvuUwwh1aXQN4MfJ6a5K2iNwP3w4AColvI9A==",
|
||||
"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/js": "8.42.0",
|
||||
"@humanwhocodes/config-array": "^0.11.10",
|
||||
"@humanwhocodes/module-importer": "^1.0.1",
|
||||
"@nodelib/fs.walk": "^1.2.8",
|
||||
"ajv": "^6.10.0",
|
||||
@@ -1089,11 +1089,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.5",
|
||||
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.4.5.tgz",
|
||||
"integrity": "sha512-7qgJmRp9ClRzPgkzEz7ahK+Rasiv4k2aU3eqkkORzseNUGdtImZVYomcXUhUheHwkxzdN2p//nbIA7zJrCxsCg==",
|
||||
"dependencies": {
|
||||
"@next/eslint-plugin-next": "13.4.4",
|
||||
"@next/eslint-plugin-next": "13.4.5",
|
||||
"@rushstack/eslint-patch": "^1.1.3",
|
||||
"@typescript-eslint/parser": "^5.42.0",
|
||||
"eslint-import-resolver-node": "^0.3.6",
|
||||
@@ -1664,9 +1664,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.0",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.6.0.tgz",
|
||||
"integrity": "sha512-lgbo68hHTQnFddybKbbs/RDRJnJT5YyGy2kQzVwbq+g67X73i+5MVTval34QxGkOe9X5Ujf1UYpCaphLyltjEg==",
|
||||
"dependencies": {
|
||||
"resolve-pkg-maps": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
|
||||
}
|
||||
@@ -1701,6 +1704,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",
|
||||
@@ -2453,16 +2461,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.5",
|
||||
"resolved": "https://registry.npmjs.org/next/-/next-13.4.5.tgz",
|
||||
"integrity": "sha512-pfNsRLVM9e5Y1/z02VakJRfD6hMQkr24FaN2xc9GbcZDBxoOgiNAViSg5cXwlWCoMhtm4U315D7XYhgOr96Q3Q==",
|
||||
"dependencies": {
|
||||
"@next/env": "13.4.4",
|
||||
"@next/env": "13.4.5",
|
||||
"@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 +2481,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.5",
|
||||
"@next/swc-darwin-x64": "13.4.5",
|
||||
"@next/swc-linux-arm64-gnu": "13.4.5",
|
||||
"@next/swc-linux-arm64-musl": "13.4.5",
|
||||
"@next/swc-linux-x64-gnu": "13.4.5",
|
||||
"@next/swc-linux-x64-musl": "13.4.5",
|
||||
"@next/swc-win32-arm64-msvc": "13.4.5",
|
||||
"@next/swc-win32-ia32-msvc": "13.4.5",
|
||||
"@next/swc-win32-x64-msvc": "13.4.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentelemetry/api": "^1.1.0",
|
||||
@@ -2927,6 +2936,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",
|
||||
@@ -3382,9 +3399,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.5.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz",
|
||||
"integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w=="
|
||||
},
|
||||
"node_modules/tsutils": {
|
||||
"version": "3.21.0",
|
||||
@@ -3441,16 +3458,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.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz",
|
||||
"integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.20"
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/unbox-primitive": {
|
||||
@@ -3483,6 +3500,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",
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"eslint": "8.41.0",
|
||||
"eslint-config-next": "13.4.4",
|
||||
"next": "13.4.4",
|
||||
"eslint": "8.42.0",
|
||||
"eslint-config-next": "13.4.5",
|
||||
"next": "13.4.5",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
}
|
||||
|
||||
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,12 @@
|
||||
# @vercel-internals/constants
|
||||
|
||||
## 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,14 +1,14 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@vercel-internals/constants",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"types": "dist/index.d.ts",
|
||||
"main": "dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/routing-utils": "2.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# @vercel-internals/types
|
||||
|
||||
## 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
|
||||
|
||||
62
internals/types/index.d.ts
vendored
62
internals/types/index.d.ts
vendored
@@ -378,28 +378,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']`.
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@vercel-internals/types",
|
||||
"version": "1.0.1",
|
||||
"version": "1.0.2",
|
||||
"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.2",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/routing-utils": "2.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"source-map-support": "0.5.12",
|
||||
"ts-eager": "2.0.2",
|
||||
"ts-jest": "29.1.0",
|
||||
"turbo": "1.9.9",
|
||||
"turbo": "1.10.3",
|
||||
"typescript": "4.9.5"
|
||||
},
|
||||
"scripts": {
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @vercel/build-utils
|
||||
|
||||
## 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.7.5",
|
||||
"license": "Apache-2.0",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -43,6 +43,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,
|
||||
@@ -88,6 +89,7 @@ export {
|
||||
getIgnoreFilter,
|
||||
cloneEnv,
|
||||
hardLinkDir,
|
||||
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
|
||||
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,66 @@
|
||||
# vercel
|
||||
|
||||
## 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": "30.2.2",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -32,16 +32,16 @@
|
||||
"node": ">= 14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/go": "2.5.1",
|
||||
"@vercel/hydrogen": "0.0.64",
|
||||
"@vercel/next": "3.8.6",
|
||||
"@vercel/node": "2.14.4",
|
||||
"@vercel/node": "2.15.1",
|
||||
"@vercel/python": "3.1.60",
|
||||
"@vercel/redwood": "1.1.15",
|
||||
"@vercel/remix-builder": "1.8.11",
|
||||
"@vercel/remix-builder": "1.8.13",
|
||||
"@vercel/ruby": "1.3.76",
|
||||
"@vercel/static-build": "1.3.33"
|
||||
"@vercel/static-build": "1.3.36"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@alex_neo/jest-expect-message": "1.0.5",
|
||||
@@ -85,13 +85,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.2",
|
||||
"@vercel-internals/get-package-json": "1.0.0",
|
||||
"@vercel-internals/types": "1.0.1",
|
||||
"@vercel/client": "12.6.1",
|
||||
"@vercel-internals/types": "1.0.2",
|
||||
"@vercel/client": "12.6.2",
|
||||
"@vercel/error-utils": "1.0.10",
|
||||
"@vercel/frameworks": "1.4.2",
|
||||
"@vercel/fs-detectors": "3.9.3",
|
||||
"@vercel/fs-detectors": "4.0.0",
|
||||
"@vercel/fun": "1.0.4",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/routing-utils": "2.2.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,
|
||||
|
||||
@@ -203,56 +203,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 +305,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;
|
||||
|
||||
@@ -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`
|
||||
);
|
||||
|
||||
@@ -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`
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -19,11 +19,13 @@ import type {
|
||||
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';
|
||||
|
||||
const isSAMLError = (v: any): v is SAMLError => {
|
||||
return v && v.saml;
|
||||
@@ -176,6 +178,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
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -3,14 +3,10 @@ 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 { 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';
|
||||
@@ -128,9 +124,30 @@ export async function ensureRepoLink(
|
||||
output.spinner(
|
||||
`Fetching Projects for ${link(repoUrl)} 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}`);
|
||||
let printedFound = false;
|
||||
for await (const chunk of projectsIterator) {
|
||||
projects = projects.concat(chunk.projects);
|
||||
if (!printedFound && projects.length > 0) {
|
||||
output.log(
|
||||
`${pluralize('Project', chunk.projects.length)} linked to ${link(
|
||||
repoUrl
|
||||
)} under ${chalk.bold(org.slug)}:`
|
||||
);
|
||||
printedFound = true;
|
||||
}
|
||||
for (const project of chunk.projects) {
|
||||
output.print(` * ${chalk.cyan(`${org.slug}/${project.name}\n`)}`);
|
||||
}
|
||||
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(
|
||||
@@ -140,24 +157,17 @@ export async function ensureRepoLink(
|
||||
// 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(
|
||||
'Project',
|
||||
projects.length
|
||||
)} linked to ${link(repoUrl)} under ${chalk.bold(org.slug)}:`
|
||||
);
|
||||
}
|
||||
|
||||
for (const project of projects) {
|
||||
output.print(` * ${chalk.cyan(`${org.slug}/${project.name}\n`)}`);
|
||||
}
|
||||
|
||||
shouldLink =
|
||||
yes ||
|
||||
(await confirm(
|
||||
client,
|
||||
`Link to ${projects.length === 1 ? 'it' : 'them'}?`,
|
||||
`Link to ${
|
||||
projects.length === 1
|
||||
? 'this Project'
|
||||
: `these ${chalk.bold(projects.length)} Projects`
|
||||
}?`,
|
||||
true
|
||||
));
|
||||
|
||||
@@ -179,10 +189,7 @@ 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);
|
||||
@@ -268,7 +275,7 @@ export function findProjectsFromPath(
|
||||
path: string
|
||||
): RepoProjectConfig[] {
|
||||
const normalizedPath = normalizePath(path);
|
||||
return projects
|
||||
const matches = projects
|
||||
.slice()
|
||||
.sort(sortByDirectory)
|
||||
.filter(project => {
|
||||
@@ -281,14 +288,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);
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
@@ -108,9 +108,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;
|
||||
@@ -284,6 +285,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,
|
||||
@@ -313,10 +321,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(
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
@@ -1154,4 +1154,97 @@ describe('build', () => {
|
||||
delete process.env.STORYBOOK_DISABLE_TELEMETRY;
|
||||
}
|
||||
});
|
||||
|
||||
it('should error if .npmrc exists containing use-node-version', async () => {
|
||||
const cwd = fixture('npmrc-use-node-version');
|
||||
client.cwd = cwd;
|
||||
client.setArgv('build');
|
||||
const exitCodePromise = build(client);
|
||||
await expect(client.stderr).toOutput('Error: Detected unsupported');
|
||||
await expect(exitCodePromise).resolves.toEqual(1);
|
||||
});
|
||||
|
||||
it('should ignore `.env` for static site', async () => {
|
||||
const cwd = fixture('static-env');
|
||||
const output = join(cwd, '.vercel/output');
|
||||
client.cwd = cwd;
|
||||
const exitCode = await build(client);
|
||||
expect(exitCode).toEqual(0);
|
||||
|
||||
expect(fs.existsSync(join(output, 'static', 'index.html'))).toBe(true);
|
||||
expect(fs.existsSync(join(output, 'static', '.env'))).toBe(false);
|
||||
});
|
||||
|
||||
it('should build with `repo.json` link', async () => {
|
||||
const cwd = fixture('../../monorepo-link');
|
||||
|
||||
useUser();
|
||||
useTeams('team_dummy');
|
||||
|
||||
// "blog" app
|
||||
useProject({
|
||||
...defaultProject,
|
||||
id: 'QmScb7GPQt6gsS',
|
||||
name: 'monorepo-blog',
|
||||
rootDirectory: 'blog',
|
||||
outputDirectory: 'dist',
|
||||
framework: null,
|
||||
});
|
||||
let output = join(cwd, 'blog/.vercel/output');
|
||||
client.cwd = join(cwd, 'blog');
|
||||
client.setArgv('build', '--yes');
|
||||
let exitCode = await build(client);
|
||||
expect(exitCode).toEqual(0);
|
||||
delete process.env.__VERCEL_BUILD_RUNNING;
|
||||
|
||||
let files = await fs.readdir(join(output, 'static'));
|
||||
expect(files.sort()).toEqual(['index.txt']);
|
||||
expect(
|
||||
(await fs.readFile(join(output, 'static/index.txt'), 'utf8')).trim()
|
||||
).toEqual('blog');
|
||||
|
||||
// "dashboard" app
|
||||
useProject({
|
||||
...defaultProject,
|
||||
id: 'QmbKpqpiUqbcke',
|
||||
name: 'monorepo-dashboard',
|
||||
rootDirectory: 'dashboard',
|
||||
outputDirectory: 'dist',
|
||||
framework: null,
|
||||
});
|
||||
output = join(cwd, 'dashboard/.vercel/output');
|
||||
client.cwd = join(cwd, 'dashboard');
|
||||
client.setArgv('build', '--yes');
|
||||
exitCode = await build(client);
|
||||
expect(exitCode).toEqual(0);
|
||||
delete process.env.__VERCEL_BUILD_RUNNING;
|
||||
|
||||
files = await fs.readdir(join(output, 'static'));
|
||||
expect(files.sort()).toEqual(['index.txt']);
|
||||
expect(
|
||||
(await fs.readFile(join(output, 'static/index.txt'), 'utf8')).trim()
|
||||
).toEqual('dashboard');
|
||||
|
||||
// "marketing" app
|
||||
useProject({
|
||||
...defaultProject,
|
||||
id: 'QmX6P93ChNDoZP',
|
||||
name: 'monorepo-marketing',
|
||||
rootDirectory: 'marketing',
|
||||
outputDirectory: 'dist',
|
||||
framework: null,
|
||||
});
|
||||
output = join(cwd, 'marketing/.vercel/output');
|
||||
client.cwd = join(cwd, 'marketing');
|
||||
client.setArgv('build', '--yes');
|
||||
exitCode = await build(client);
|
||||
expect(exitCode).toEqual(0);
|
||||
delete process.env.__VERCEL_BUILD_RUNNING;
|
||||
|
||||
files = await fs.readdir(join(output, 'static'));
|
||||
expect(files.sort()).toEqual(['index.txt']);
|
||||
expect(
|
||||
(await fs.readFile(join(output, 'static/index.txt'), 'utf8')).trim()
|
||||
).toEqual('marketing');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -45,6 +45,14 @@ describe('deploy', () => {
|
||||
it('should reject deploying when `--prebuilt` is used and `vc build` failed before Builders', async () => {
|
||||
const cwd = setupUnitFixture('build-output-api-failed-before-builds');
|
||||
|
||||
useUser();
|
||||
useTeams('team_dummy');
|
||||
useProject({
|
||||
...defaultProject,
|
||||
id: 'build-output-api-failed-before-builds',
|
||||
name: 'build-output-api-failed-before-builds',
|
||||
});
|
||||
|
||||
client.setArgv('deploy', cwd, '--prebuilt');
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
@@ -56,6 +64,14 @@ describe('deploy', () => {
|
||||
it('should reject deploying when `--prebuilt` is used and `vc build` failed within a Builder', async () => {
|
||||
const cwd = setupUnitFixture('build-output-api-failed-within-build');
|
||||
|
||||
useUser();
|
||||
useTeams('team_dummy');
|
||||
useProject({
|
||||
...defaultProject,
|
||||
id: 'build-output-api-failed-within-build',
|
||||
name: 'build-output-api-failed-within-build',
|
||||
});
|
||||
|
||||
client.setArgv('deploy', cwd, '--prebuilt');
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
@@ -65,7 +81,16 @@ describe('deploy', () => {
|
||||
});
|
||||
|
||||
it('should reject deploying a directory that does not contain ".vercel/output" when `--prebuilt` is used', async () => {
|
||||
client.setArgv('deploy', __dirname, '--prebuilt');
|
||||
useUser();
|
||||
useTeams('team_dummy');
|
||||
useProject({
|
||||
...defaultProject,
|
||||
name: 'static',
|
||||
id: 'static',
|
||||
});
|
||||
|
||||
client.cwd = setupUnitFixture('commands/deploy/static');
|
||||
client.setArgv('deploy', '--prebuilt');
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
'Error: The "--prebuilt" option was used, but no prebuilt output found in ".vercel/output". Run `vercel build` to generate a local build.\n'
|
||||
@@ -102,8 +127,8 @@ describe('deploy', () => {
|
||||
useTeams('team_dummy');
|
||||
useProject({
|
||||
...defaultProject,
|
||||
id: 'build-output-api-preview',
|
||||
name: 'build-output-api-preview',
|
||||
id: 'build-output-api-production',
|
||||
name: 'build-output-api-production',
|
||||
});
|
||||
|
||||
client.setArgv('deploy', cwd, '--prebuilt');
|
||||
|
||||
@@ -25,7 +25,9 @@ describe('env', () => {
|
||||
await expect(client.stderr).toOutput(
|
||||
'Downloading `development` Environment Variables for Project vercel-env-pull'
|
||||
);
|
||||
await expect(client.stderr).toOutput('Created .env.local file');
|
||||
await expect(client.stderr).toOutput(
|
||||
'Created .env.local file and added it to .gitignore'
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
|
||||
const rawDevEnv = await fs.readFile(path.join(cwd, '.env.local'));
|
||||
@@ -50,7 +52,9 @@ describe('env', () => {
|
||||
await expect(client.stderr).toOutput(
|
||||
'Downloading `preview` Environment Variables for Project vercel-env-pull'
|
||||
);
|
||||
await expect(client.stderr).toOutput('Created .env.local file');
|
||||
await expect(client.stderr).toOutput(
|
||||
'Created .env.local file and added it to .gitignore'
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
|
||||
// check for Preview env vars
|
||||
@@ -86,7 +90,9 @@ describe('env', () => {
|
||||
await expect(client.stderr).toOutput(
|
||||
'Downloading `preview` Environment Variables for Project vercel-env-pull'
|
||||
);
|
||||
await expect(client.stderr).toOutput('Created .env.local file');
|
||||
await expect(client.stderr).toOutput(
|
||||
'Created .env.local file and added it to .gitignore'
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
|
||||
// check for Preview env vars
|
||||
@@ -122,6 +128,7 @@ describe('env', () => {
|
||||
'Downloading `development` Environment Variables for Project vercel-env-pull'
|
||||
);
|
||||
await expect(client.stderr).toOutput('Created other.env file');
|
||||
await expect(client.stderr).not.toOutput('and added it to .gitignore');
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
|
||||
const rawDevEnv = await fs.readFile(path.join(cwd, 'other.env'));
|
||||
@@ -146,7 +153,9 @@ describe('env', () => {
|
||||
await expect(client.stderr).toOutput(
|
||||
`Downloading \`production\` Environment Variables for Project vercel-env-pull`
|
||||
);
|
||||
await expect(client.stderr).toOutput('Created .env.local file');
|
||||
await expect(client.stderr).toOutput(
|
||||
'Created .env.local file and added it to .gitignore'
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
|
||||
const rawProdEnv = await fs.readFile(path.join(cwd, '.env.local'));
|
||||
@@ -201,6 +210,7 @@ describe('env', () => {
|
||||
'Downloading `development` Environment Variables for Project vercel-env-pull'
|
||||
);
|
||||
await expect(client.stderr).toOutput('Created other.env file');
|
||||
await expect(client.stderr).not.toOutput('and added it to .gitignore');
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
|
||||
const rawDevEnv = await fs.readFile(path.join(cwd, 'other.env'));
|
||||
@@ -247,7 +257,9 @@ describe('env', () => {
|
||||
await expect(client.stderr).toOutput(
|
||||
'+ SPECIAL_FLAG (Updated)\n+ NEW_VAR\n- TEST\n'
|
||||
);
|
||||
await expect(client.stderr).toOutput('Updated .env.local file');
|
||||
await expect(client.stderr).toOutput(
|
||||
'Updated .env.local file and added it to .gitignore'
|
||||
);
|
||||
|
||||
await expect(pullPromise).resolves.toEqual(0);
|
||||
} finally {
|
||||
@@ -268,7 +280,9 @@ describe('env', () => {
|
||||
client.cwd = cwd;
|
||||
client.setArgv('env', 'pull', '--yes');
|
||||
const pullPromise = env(client);
|
||||
await expect(client.stderr).toOutput('Updated .env.local file');
|
||||
await expect(client.stderr).toOutput(
|
||||
'Updated .env.local file and added it to .gitignore'
|
||||
);
|
||||
await expect(pullPromise).resolves.toEqual(0);
|
||||
});
|
||||
|
||||
@@ -284,7 +298,9 @@ describe('env', () => {
|
||||
client.setArgv('env', 'pull', '--yes');
|
||||
const pullPromise = env(client);
|
||||
await expect(client.stderr).toOutput('> No changes found.');
|
||||
await expect(client.stderr).toOutput('Updated .env.local file');
|
||||
await expect(client.stderr).toOutput(
|
||||
'Updated .env.local file and added it to .gitignore'
|
||||
);
|
||||
await expect(pullPromise).resolves.toEqual(0);
|
||||
});
|
||||
|
||||
@@ -321,7 +337,9 @@ describe('env', () => {
|
||||
'Downloading `development` Environment Variables for Project env-pull-delta'
|
||||
);
|
||||
await expect(client.stderr).toOutput('No changes found.\n');
|
||||
await expect(client.stderr).toOutput('Updated .env.local file');
|
||||
await expect(client.stderr).toOutput(
|
||||
'Updated .env.local file and added it to .gitignore'
|
||||
);
|
||||
|
||||
await expect(pullPromise).resolves.toEqual(0);
|
||||
} finally {
|
||||
@@ -371,5 +389,42 @@ describe('env', () => {
|
||||
await env(client);
|
||||
}
|
||||
});
|
||||
|
||||
it('should not update .gitignore if it contains a match', async () => {
|
||||
const prj = 'vercel-env-pull-with-gitignore';
|
||||
useUser();
|
||||
useTeams('team_dummy');
|
||||
useProject({
|
||||
...defaultProject,
|
||||
id: prj,
|
||||
name: prj,
|
||||
});
|
||||
const cwd = setupUnitFixture(prj);
|
||||
const gitignoreBefore = await fs.readFile(
|
||||
path.join(cwd, '.gitignore'),
|
||||
'utf8'
|
||||
);
|
||||
client.cwd = cwd;
|
||||
client.setArgv('env', 'pull', '--yes');
|
||||
const exitCodePromise = env(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
'Downloading `development` Environment Variables for Project ' + prj
|
||||
);
|
||||
await expect(client.stderr).toOutput('Created .env.local file');
|
||||
await expect(client.stderr).not.toOutput('and added it to .gitignore');
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
|
||||
const rawDevEnv = await fs.readFile(path.join(cwd, '.env.local'));
|
||||
|
||||
// check for development env value
|
||||
const devFileHasDevEnv = rawDevEnv.toString().includes('SPECIAL_FLAG');
|
||||
expect(devFileHasDevEnv).toBeTruthy();
|
||||
|
||||
const gitignoreAfter = await fs.readFile(
|
||||
path.join(cwd, '.gitignore'),
|
||||
'utf8'
|
||||
);
|
||||
expect(gitignoreAfter).toBe(gitignoreBefore);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -26,7 +26,7 @@ describe('pull', () => {
|
||||
`Created .vercel${path.sep}.env.development.local file`
|
||||
);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Downloaded project settings to .vercel${path.sep}project.json`
|
||||
`Downloaded project settings to ${cwd}${path.sep}.vercel${path.sep}project.json`
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
|
||||
@@ -92,7 +92,7 @@ describe('pull', () => {
|
||||
`Created .vercel${path.sep}.env.development.local file`
|
||||
);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Downloaded project settings to .vercel${path.sep}project.json`
|
||||
`Downloaded project settings to ${cwd}${path.sep}.vercel${path.sep}project.json`
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
|
||||
@@ -130,7 +130,7 @@ describe('pull', () => {
|
||||
`Created .vercel${path.sep}.env.preview.local file`
|
||||
);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Downloaded project settings to .vercel${path.sep}project.json`
|
||||
`Downloaded project settings to ${cwd}${path.sep}.vercel${path.sep}project.json`
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
|
||||
@@ -161,7 +161,7 @@ describe('pull', () => {
|
||||
`Created .vercel${path.sep}.env.production.local file`
|
||||
);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Downloaded project settings to .vercel${path.sep}project.json`
|
||||
`Downloaded project settings to ${cwd}${path.sep}.vercel${path.sep}project.json`
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
|
||||
@@ -177,4 +177,29 @@ describe('pull', () => {
|
||||
.includes('SQL_CONNECTION_STRING');
|
||||
expect(previewFileHasPreviewEnv2).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should work with repo link', async () => {
|
||||
const cwd = setupUnitFixture('monorepo-link');
|
||||
useUser();
|
||||
useTeams('team_dummy');
|
||||
useProject({
|
||||
...defaultProject,
|
||||
id: 'QmbKpqpiUqbcke',
|
||||
name: 'dashboard',
|
||||
rootDirectory: 'dashboard',
|
||||
});
|
||||
client.cwd = path.join(cwd, 'dashboard');
|
||||
client.setArgv('pull');
|
||||
const exitCodePromise = pull(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
'Downloading `development` Environment Variables for Project dashboard'
|
||||
);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Created .vercel${path.sep}.env.development.local file`
|
||||
);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Downloaded project settings to ${cwd}${path.sep}dashboard${path.sep}.vercel${path.sep}project.json`
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join, sep } from 'node:path';
|
||||
import {
|
||||
findProjectFromPath,
|
||||
findProjectsFromPath,
|
||||
findRepoRoot,
|
||||
RepoProjectConfig,
|
||||
traverseUpDirectories,
|
||||
@@ -57,35 +57,36 @@ describe('traverseUpDirectories()', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('findProjectFromPath()', () => {
|
||||
describe('findProjectsFromPath()', () => {
|
||||
const projects: RepoProjectConfig[] = [
|
||||
{ id: 'root', name: 'r', directory: '.' },
|
||||
{ id: 'site', name: 'a', directory: 'apps/site' },
|
||||
{ id: 'site2', name: 'a', directory: 'apps/site2' },
|
||||
{ id: 'other', name: 'b', directory: 'apps/other' },
|
||||
{ id: 'duplicate', name: 'd', directory: 'apps/other' },
|
||||
{ id: 'nested', name: 'n', directory: 'apps/other/nested' },
|
||||
];
|
||||
|
||||
it.each([
|
||||
{ id: 'root', path: '.' },
|
||||
{ id: 'root', path: 'lib' },
|
||||
{ id: 'root', path: 'lib' },
|
||||
{ id: 'site', path: `apps${sep}site` },
|
||||
{ id: 'site', path: `apps${sep}site` },
|
||||
{ id: 'site', path: `apps${sep}site${sep}components` },
|
||||
{ id: 'site2', path: `apps${sep}site2` },
|
||||
{ id: 'site2', path: `apps${sep}site2${sep}inner` },
|
||||
{ id: 'other', path: `apps${sep}other` },
|
||||
{ id: 'other', path: `apps${sep}other${sep}lib` },
|
||||
{ id: 'nested', path: `apps${sep}other${sep}nested` },
|
||||
{ id: 'nested', path: `apps${sep}other${sep}nested${sep}foo` },
|
||||
])('should find Project "$id" for path "$path"', ({ path, id }) => {
|
||||
const actual = findProjectFromPath(projects, path);
|
||||
expect(actual?.id).toEqual(id);
|
||||
{ ids: ['root'], path: '.' },
|
||||
{ ids: ['root'], path: 'lib' },
|
||||
{ ids: ['root'], path: 'lib' },
|
||||
{ ids: ['site'], path: `apps${sep}site` },
|
||||
{ ids: ['site'], path: `apps${sep}site` },
|
||||
{ ids: ['site'], path: `apps${sep}site${sep}components` },
|
||||
{ ids: ['site2'], path: `apps${sep}site2` },
|
||||
{ ids: ['site2'], path: `apps${sep}site2${sep}inner` },
|
||||
{ ids: ['other', 'duplicate'], path: `apps${sep}other` },
|
||||
{ ids: ['other', 'duplicate'], path: `apps${sep}other${sep}lib` },
|
||||
{ ids: ['nested'], path: `apps${sep}other${sep}nested` },
|
||||
{ ids: ['nested'], path: `apps${sep}other${sep}nested${sep}foo` },
|
||||
])('should find Project "$id" for path "$path"', ({ path, ids }) => {
|
||||
const actual = findProjectsFromPath(projects, path);
|
||||
expect(actual.map(a => a.id)).toEqual(ids);
|
||||
});
|
||||
|
||||
it('should return `undefined` when there are no matching Projects', () => {
|
||||
const actual = findProjectFromPath([projects[1]], '.');
|
||||
expect(actual).toBeUndefined();
|
||||
it('should return empty array when there are no matching Projects', () => {
|
||||
const actual = findProjectsFromPath([projects[1]], '.');
|
||||
expect(actual).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
import { client } from '../../../mocks/client';
|
||||
import getProjectByDeployment from '../../../../src/util/projects/get-project-by-deployment';
|
||||
import { useTeams } from '../../../mocks/team';
|
||||
import { useUser } from '../../../mocks/user';
|
||||
import { useDeployment } from '../../../mocks/deployment';
|
||||
import { defaultProject, useProject } from '../../../mocks/project';
|
||||
|
||||
describe('getProjectByDeployment', () => {
|
||||
it('should get project and deployment', async () => {
|
||||
const user = useUser();
|
||||
const { project: p } = useProject({
|
||||
...defaultProject,
|
||||
id: 'foo',
|
||||
name: 'foo',
|
||||
});
|
||||
const d = useDeployment({
|
||||
creator: user,
|
||||
createdAt: Date.now(),
|
||||
project: p,
|
||||
});
|
||||
|
||||
const { deployment, project } = await getProjectByDeployment({
|
||||
client,
|
||||
deployId: d.id,
|
||||
output: client.output,
|
||||
});
|
||||
|
||||
expect(project.id).toBe(p.id);
|
||||
expect(deployment.id).toBe(d.id);
|
||||
});
|
||||
|
||||
it('should get project and deployment associated to a team', async () => {
|
||||
const [team] = useTeams('team_dummy');
|
||||
const user = useUser();
|
||||
const { project: p } = useProject({
|
||||
...defaultProject,
|
||||
id: 'foo',
|
||||
name: 'foo',
|
||||
});
|
||||
const d = useDeployment({
|
||||
creator: {
|
||||
id: team.id,
|
||||
name: team.name,
|
||||
email: user.email,
|
||||
username: team.slug,
|
||||
},
|
||||
createdAt: Date.now(),
|
||||
project: p,
|
||||
});
|
||||
|
||||
client.config.currentTeam = team.id;
|
||||
d.team = team;
|
||||
|
||||
const { deployment, project } = await getProjectByDeployment({
|
||||
client,
|
||||
deployId: d.id,
|
||||
output: client.output,
|
||||
});
|
||||
|
||||
expect(project.id).toBe(p.id);
|
||||
expect(deployment.id).toBe(d.id);
|
||||
});
|
||||
|
||||
it("should error if deployment team doesn't match current user's team", async () => {
|
||||
const [team] = useTeams('team_dummy');
|
||||
const user = useUser();
|
||||
const { project: p } = useProject({
|
||||
...defaultProject,
|
||||
id: 'foo',
|
||||
name: 'foo',
|
||||
});
|
||||
const d = useDeployment({
|
||||
creator: {
|
||||
id: team.id,
|
||||
name: team.name,
|
||||
email: user.email,
|
||||
username: team.slug,
|
||||
},
|
||||
createdAt: Date.now(),
|
||||
project: p,
|
||||
});
|
||||
|
||||
client.config.currentTeam = team.id;
|
||||
|
||||
await expect(
|
||||
getProjectByDeployment({
|
||||
client,
|
||||
deployId: d.id,
|
||||
output: client.output,
|
||||
})
|
||||
).rejects.toThrowError("Deployment doesn't belong to current team");
|
||||
|
||||
client.config.currentTeam = undefined;
|
||||
d.team = team;
|
||||
|
||||
await expect(
|
||||
getProjectByDeployment({
|
||||
client,
|
||||
deployId: d.id,
|
||||
output: client.output,
|
||||
})
|
||||
).rejects.toThrowError('Deployment belongs to a different team');
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,12 @@
|
||||
# @vercel/client
|
||||
|
||||
## 12.6.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
|
||||
- @vercel/build-utils@6.7.5
|
||||
|
||||
## 12.6.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/client",
|
||||
"version": "12.6.1",
|
||||
"version": "12.6.2",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"homepage": "https://vercel.com",
|
||||
@@ -35,7 +35,7 @@
|
||||
"typescript": "4.9.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/routing-utils": "2.2.1",
|
||||
"@zeit/fetch": "5.2.0",
|
||||
"async-retry": "1.2.3",
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @vercel/fs-detectors
|
||||
|
||||
## 4.0.0
|
||||
|
||||
### Major Changes
|
||||
|
||||
- `LocalFileSystemDetector#readdir()` now returns paths relative to the root dir, instead of absolute paths. This is to align with the usage of the detectors that are using the `DetectorFilesystem` interface. ([#10100](https://github.com/vercel/vercel/pull/10100))
|
||||
|
||||
## 3.9.3
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/fs-detectors",
|
||||
"version": "3.9.3",
|
||||
"version": "4.0.0",
|
||||
"description": "Vercel filesystem detectors",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -15,8 +15,8 @@
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"test": "jest --env node --verbose --runInBand --bail test/unit.*test.*",
|
||||
"test-unit": "pnpm test"
|
||||
"test": "jest --env node --verbose --runInBand --bail",
|
||||
"test-unit": "pnpm test test/unit.*test.*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/error-utils": "1.0.10",
|
||||
@@ -35,7 +35,7 @@
|
||||
"@types/minimatch": "3.0.5",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/semver": "7.3.10",
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"typescript": "4.9.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,12 @@ import { isErrnoException } from '@vercel/error-utils';
|
||||
|
||||
export class LocalFileSystemDetector extends DetectorFilesystem {
|
||||
private rootPath: string;
|
||||
|
||||
constructor(rootPath: string) {
|
||||
super();
|
||||
this.rootPath = rootPath;
|
||||
}
|
||||
|
||||
async _hasPath(name: string): Promise<boolean> {
|
||||
try {
|
||||
await fs.stat(this.getFilePath(name));
|
||||
@@ -21,13 +23,16 @@ export class LocalFileSystemDetector extends DetectorFilesystem {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
_readFile(name: string): Promise<Buffer> {
|
||||
return fs.readFile(this.getFilePath(name));
|
||||
}
|
||||
|
||||
async _isFile(name: string): Promise<boolean> {
|
||||
const stat = await fs.stat(this.getFilePath(name));
|
||||
return stat.isFile();
|
||||
}
|
||||
|
||||
async _readdir(name: string): Promise<DetectorFilesystemStat[]> {
|
||||
const dirPath = this.getFilePath(name);
|
||||
const dir = await fs.readdir(dirPath, {
|
||||
@@ -44,14 +49,22 @@ export class LocalFileSystemDetector extends DetectorFilesystem {
|
||||
};
|
||||
return dir.map(dirent => ({
|
||||
name: dirent.name,
|
||||
path: path.join(dirPath, dirent.name),
|
||||
path: path.join(this.getRelativeFilePath(name), dirent.name),
|
||||
type: getType(dirent),
|
||||
}));
|
||||
}
|
||||
|
||||
_chdir(name: string): DetectorFilesystem {
|
||||
return new LocalFileSystemDetector(this.getFilePath(name));
|
||||
}
|
||||
|
||||
private getRelativeFilePath(name: string) {
|
||||
return name.startsWith(this.rootPath)
|
||||
? path.relative(this.rootPath, name)
|
||||
: name;
|
||||
}
|
||||
|
||||
private getFilePath(name: string) {
|
||||
return path.join(this.rootPath, name);
|
||||
return path.join(this.rootPath, this.getRelativeFilePath(name));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from 'path';
|
||||
import { LocalFileSystemDetector } from '../src';
|
||||
import { detectFramework } from '../src/detect-framework';
|
||||
import monorepoManagers from '../src/monorepos/monorepo-managers';
|
||||
import { FixtureFilesystem } from './utils/fixture-filesystem';
|
||||
|
||||
describe('monorepo-managers', () => {
|
||||
describe.each([
|
||||
@@ -17,7 +17,7 @@ describe('monorepo-managers', () => {
|
||||
|
||||
it(testName, async () => {
|
||||
const fixture = path.join(__dirname, 'fixtures', fixturePath);
|
||||
const fs = new FixtureFilesystem(fixture);
|
||||
const fs = new LocalFileSystemDetector(fixture);
|
||||
|
||||
const result = await detectFramework({
|
||||
fs,
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import path from 'path';
|
||||
import { packageManagers, detectFramework } from '../src';
|
||||
import { FixtureFilesystem } from './utils/fixture-filesystem';
|
||||
import {
|
||||
packageManagers,
|
||||
detectFramework,
|
||||
LocalFileSystemDetector,
|
||||
} from '../src';
|
||||
|
||||
describe('package-managers', () => {
|
||||
describe.each([
|
||||
@@ -16,7 +19,7 @@ describe('package-managers', () => {
|
||||
|
||||
it(testName, async () => {
|
||||
const fixture = path.join(__dirname, 'fixtures', fixturePath);
|
||||
const fs = new FixtureFilesystem(fixture);
|
||||
const fs = new LocalFileSystemDetector(fixture);
|
||||
|
||||
const result = await detectFramework({
|
||||
fs,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from 'path';
|
||||
import { LocalFileSystemDetector } from '../src';
|
||||
import { detectFramework } from '../src/detect-framework';
|
||||
import workspaceManagers from '../src/workspaces/workspace-managers';
|
||||
import { FixtureFilesystem } from './utils/fixture-filesystem';
|
||||
|
||||
describe('workspace-managers', () => {
|
||||
describe.each([
|
||||
@@ -19,7 +19,7 @@ describe('workspace-managers', () => {
|
||||
|
||||
it(testName, async () => {
|
||||
const fixture = path.join(__dirname, 'fixtures', fixturePath);
|
||||
const fs = new FixtureFilesystem(fixture);
|
||||
const fs = new LocalFileSystemDetector(fixture);
|
||||
|
||||
const result = await detectFramework({
|
||||
fs,
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import frameworkList from '@vercel/frameworks';
|
||||
import { detectFramework } from '../src';
|
||||
import { FixtureFilesystem } from './utils/fixture-filesystem';
|
||||
import { detectFramework, LocalFileSystemDetector } from '../src';
|
||||
import { getExamples } from '../../../examples/__tests__/test-utils';
|
||||
|
||||
describe('examples should be detected', () => {
|
||||
it.each(getExamples())(
|
||||
'should detect $exampleName',
|
||||
async ({ exampleName, examplePath }) => {
|
||||
const fs = new FixtureFilesystem(examplePath);
|
||||
const fs = new LocalFileSystemDetector(examplePath);
|
||||
const framework = await detectFramework({ fs, frameworkList });
|
||||
if (!framework) {
|
||||
throw new Error(`Framework not detected for example "${exampleName}".`);
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import { mkdtempSync } from 'fs';
|
||||
import {
|
||||
getMonorepoDefaultSettings,
|
||||
LocalFileSystemDetector,
|
||||
MissingBuildPipeline,
|
||||
MissingBuildTarget,
|
||||
} from '../src';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import os from 'os';
|
||||
import { FixtureFilesystem } from './utils/fixture-filesystem';
|
||||
|
||||
describe('getMonorepoDefaultSettings', () => {
|
||||
test('MissingBuildTarget is an error', () => {
|
||||
@@ -69,7 +68,7 @@ describe('getMonorepoDefaultSettings', () => {
|
||||
},
|
||||
};
|
||||
|
||||
const ffs = new FixtureFilesystem(
|
||||
const fs = new LocalFileSystemDetector(
|
||||
path.join(
|
||||
__dirname,
|
||||
'fixtures',
|
||||
@@ -81,16 +80,16 @@ describe('getMonorepoDefaultSettings', () => {
|
||||
packageName,
|
||||
isRoot ? '/' : 'packages/app-1',
|
||||
isRoot ? '/' : '../..',
|
||||
ffs
|
||||
fs
|
||||
);
|
||||
expect(result).toStrictEqual(expectedResultMap[expectedResultKey]);
|
||||
}
|
||||
);
|
||||
|
||||
test('returns null when neither nx nor turbo is detected', async () => {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'monorepo-test-'));
|
||||
const lfs = new LocalFileSystemDetector(dir);
|
||||
const result = await getMonorepoDefaultSettings('', '', '', lfs);
|
||||
const dir = mkdtempSync(path.join(os.tmpdir(), 'monorepo-test-'));
|
||||
const fs = new LocalFileSystemDetector(dir);
|
||||
const result = await getMonorepoDefaultSettings('', '', '', fs);
|
||||
expect(result).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from 'path';
|
||||
import { normalizePath } from '@vercel/build-utils';
|
||||
import { getProjectPaths, ProjectPath } from '../src/get-project-paths';
|
||||
import { FixtureFilesystem } from './utils/fixture-filesystem';
|
||||
import { LocalFileSystemDetector } from '../src';
|
||||
|
||||
describe.each<{
|
||||
fixturePath: string;
|
||||
@@ -52,7 +52,7 @@ describe.each<{
|
||||
|
||||
it(testName, async () => {
|
||||
const fixture = path.join(__dirname, 'fixtures', fixturePath);
|
||||
const fs = new FixtureFilesystem(fixture);
|
||||
const fs = new LocalFileSystemDetector(fixture);
|
||||
const mockReaddir = jest.fn().mockImplementation(fs.readdir);
|
||||
const mockHasPath = jest.fn().mockImplementation(fs.hasPath);
|
||||
fs.readdir = mockReaddir;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import path from 'path';
|
||||
import { getWorkspaces } from '../src/workspaces/get-workspaces';
|
||||
import { getWorkspacePackagePaths } from '../src/workspaces/get-workspace-package-paths';
|
||||
import { FixtureFilesystem } from './utils/fixture-filesystem';
|
||||
import { LocalFileSystemDetector } from '../src';
|
||||
|
||||
describe.each<[string, string[]]>([
|
||||
['21-npm-workspaces', ['/a', '/b']],
|
||||
@@ -32,7 +32,7 @@ describe.each<[string, string[]]>([
|
||||
|
||||
it(testName, async () => {
|
||||
const fixture = path.join(__dirname, 'fixtures', fixturePath);
|
||||
const fs = new FixtureFilesystem(fixture);
|
||||
const fs = new LocalFileSystemDetector(fixture);
|
||||
|
||||
const workspaces = await getWorkspaces({ fs });
|
||||
const actualPackagePaths = (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import path from 'path';
|
||||
import { LocalFileSystemDetector } from '../src';
|
||||
import { getWorkspaces, Workspace } from '../src/workspaces/get-workspaces';
|
||||
import { FixtureFilesystem } from './utils/fixture-filesystem';
|
||||
|
||||
describe.each<[string, Workspace[]]>([
|
||||
['21-npm-workspaces', [{ type: 'npm', rootPath: '/' }]],
|
||||
@@ -34,7 +34,7 @@ describe.each<[string, Workspace[]]>([
|
||||
|
||||
it(testName, async () => {
|
||||
const fixture = path.join(__dirname, 'fixtures', fixturePath);
|
||||
const fs = new FixtureFilesystem(fixture);
|
||||
const fs = new LocalFileSystemDetector(fixture);
|
||||
|
||||
const actualWorkspaces = await getWorkspaces({ fs });
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { LocalFileSystemDetector, DetectorFilesystem } from '../src';
|
||||
|
||||
const tmpdir = path.join(os.tmpdir(), 'local-file-system-test');
|
||||
|
||||
const dirs = ['', 'a', 'a/b']; // root, single-nested, double-nested
|
||||
const dirs = ['', 'a', `a${path.sep}b`]; // root, single-nested, double-nested
|
||||
const files = ['foo', 'bar'];
|
||||
const filePaths = dirs.flatMap(dir => files.map(file => path.join(dir, file)));
|
||||
|
||||
@@ -63,12 +63,7 @@ describe('LocalFileSystemDetector', () => {
|
||||
const readdirResults = await Promise.all(
|
||||
dirs.map(dir => localFileSystem.readdir(dir))
|
||||
);
|
||||
const expectedPaths = [
|
||||
...dirs.map(dir => path.join(tmpdir, dir)),
|
||||
...filePaths.map(filePath => path.join(tmpdir, filePath)),
|
||||
]
|
||||
.sort()
|
||||
.slice(1); // drop the first path since its the root
|
||||
const expectedPaths = [...dirs, ...filePaths].sort().slice(1); // drop the first path since its the root
|
||||
const actualPaths = readdirResults
|
||||
.flatMap(result => result.map(stat => stat.path))
|
||||
.sort();
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
import { promises } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
import { DetectorFilesystem } from '../../src';
|
||||
import { DetectorFilesystemStat } from '../../src/detectors/filesystem';
|
||||
|
||||
const { stat, readFile, readdir } = promises;
|
||||
|
||||
export class FixtureFilesystem extends DetectorFilesystem {
|
||||
private rootPath: string;
|
||||
|
||||
constructor(fixturePath: string) {
|
||||
super();
|
||||
|
||||
this.rootPath = fixturePath;
|
||||
}
|
||||
|
||||
async _hasPath(name: string): Promise<boolean> {
|
||||
try {
|
||||
const filePath = path.join(this.rootPath, name);
|
||||
await stat(filePath);
|
||||
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async _readFile(name: string): Promise<Buffer> {
|
||||
const filePath = path.join(this.rootPath, name);
|
||||
return readFile(filePath);
|
||||
}
|
||||
async _isFile(name: string): Promise<boolean> {
|
||||
const filePath = path.join(this.rootPath, name);
|
||||
return (await stat(filePath)).isFile();
|
||||
}
|
||||
|
||||
async _readdir(name: string): Promise<DetectorFilesystemStat[]> {
|
||||
const dirPath = path.join(this.rootPath, name);
|
||||
const files = await readdir(dirPath, { withFileTypes: true });
|
||||
|
||||
return files.map(file => ({
|
||||
name: file.name,
|
||||
type: file.isFile() ? 'file' : 'dir',
|
||||
path: path.join(name, file.name),
|
||||
}));
|
||||
}
|
||||
|
||||
_chdir(name: string): DetectorFilesystem {
|
||||
return new FixtureFilesystem(path.join(this.rootPath, name));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,27 @@
|
||||
# @vercel/gatsby-plugin-vercel-builder
|
||||
|
||||
## 1.3.9
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`a04bf557f`](https://github.com/vercel/vercel/commit/a04bf557fc6e1080a117428977d0993dec78b004)]:
|
||||
- @vercel/node@2.15.1
|
||||
|
||||
## 1.3.8
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`bc5afe24c`](https://github.com/vercel/vercel/commit/bc5afe24c4547dbf798b939199e8212c4b34038e), [`0039c8b5c`](https://github.com/vercel/vercel/commit/0039c8b5cea975316a62c4f6aaca5d66d731cc0d)]:
|
||||
- @vercel/node@2.15.0
|
||||
|
||||
## 1.3.7
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
|
||||
- @vercel/build-utils@6.7.5
|
||||
- @vercel/node@2.14.5
|
||||
|
||||
## 1.3.6
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/gatsby-plugin-vercel-builder",
|
||||
"version": "1.3.6",
|
||||
"version": "1.3.9",
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
"dist",
|
||||
@@ -20,8 +20,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@sinclair/typebox": "0.25.24",
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/node": "2.14.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/node": "2.15.1",
|
||||
"@vercel/routing-utils": "2.2.1",
|
||||
"esbuild": "0.14.47",
|
||||
"etag": "1.8.1",
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"@types/node-fetch": "^2.3.0",
|
||||
"@types/tar": "^4.0.0",
|
||||
"@types/yauzl-promise": "2.1.0",
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"async-retry": "1.3.1",
|
||||
"execa": "^1.0.0",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "27.5.1",
|
||||
"@types/node": "14.18.33",
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/static-config": "2.0.17",
|
||||
"execa": "3.2.0",
|
||||
"fs-extra": "11.1.0",
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
"@types/semver": "6.0.0",
|
||||
"@types/text-table": "0.2.1",
|
||||
"@types/webpack-sources": "3.2.0",
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/nft": "0.22.5",
|
||||
"@vercel/routing-utils": "2.2.1",
|
||||
"async-sema": "3.0.1",
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
# @vercel/node
|
||||
|
||||
## 2.15.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- handle undefined content type in `vc dev` ([#10077](https://github.com/vercel/vercel/pull/10077))
|
||||
|
||||
## 2.15.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- Add maxDuration config support for vc node deployments ([#10028](https://github.com/vercel/vercel/pull/10028))
|
||||
|
||||
- [node] Add isomorphic functions ([#9947](https://github.com/vercel/vercel/pull/9947))
|
||||
|
||||
## 2.14.5
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
|
||||
- @vercel/build-utils@6.7.5
|
||||
|
||||
## 2.14.4
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node",
|
||||
"version": "2.14.4",
|
||||
"version": "2.15.1",
|
||||
"license": "Apache-2.0",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
||||
@@ -19,10 +19,12 @@
|
||||
"dist"
|
||||
],
|
||||
"dependencies": {
|
||||
"@edge-runtime/node-utils": "2.0.3",
|
||||
"@edge-runtime/primitives": "2.1.2",
|
||||
"@edge-runtime/vm": "2.0.0",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/node-fetch": "2.6.3",
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/error-utils": "1.0.10",
|
||||
"@vercel/static-config": "2.0.17",
|
||||
"async-listen": "3.0.0",
|
||||
|
||||
@@ -10,14 +10,14 @@ function getUrl(url, headers) {
|
||||
return urlObj.toString();
|
||||
}
|
||||
|
||||
async function respond(userEdgeHandler, event, options, dependencies) {
|
||||
async function respond(handler, event, options, dependencies) {
|
||||
const { Request, Response } = dependencies;
|
||||
const { isMiddleware } = options;
|
||||
event.request.headers.set(
|
||||
'host',
|
||||
event.request.headers.get('x-forwarded-host')
|
||||
);
|
||||
let response = await userEdgeHandler(
|
||||
let response = await handler(
|
||||
new Request(
|
||||
getUrl(event.request.url, event.request.headers),
|
||||
event.request
|
||||
@@ -62,16 +62,34 @@ async function parseRequestEvent(event) {
|
||||
|
||||
// This will be invoked by logic using this template
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
function registerFetchListener(userEdgeHandler, options, dependencies) {
|
||||
function registerFetchListener(module, options, dependencies) {
|
||||
let handler;
|
||||
|
||||
addEventListener('fetch', async event => {
|
||||
try {
|
||||
const response = await respond(
|
||||
userEdgeHandler,
|
||||
event,
|
||||
options,
|
||||
dependencies
|
||||
);
|
||||
return event.respondWith(response);
|
||||
if (typeof module.default === 'function') {
|
||||
handler = module.default;
|
||||
} else {
|
||||
if (
|
||||
['GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'DELETE', 'PATCH'].some(
|
||||
method => typeof module[method] === 'function'
|
||||
)
|
||||
) {
|
||||
const method = event.request.method ?? 'GET';
|
||||
handler =
|
||||
typeof module[method] === 'function'
|
||||
? module[method]
|
||||
: () => new dependencies.Response(null, { status: 405 });
|
||||
}
|
||||
}
|
||||
if (!handler) {
|
||||
const url = getUrl(event.request.url, event.request.headers);
|
||||
throw new Error(
|
||||
`No default or HTTP-named export was found at ${url}. Add one to handle requests. Learn more: https://vercel.link/creating-edge-middleware`
|
||||
);
|
||||
}
|
||||
const response = await respond(handler, event, options, dependencies);
|
||||
event.respondWith(response);
|
||||
} catch (error) {
|
||||
event.respondWith(toResponseError(error, dependencies.Response));
|
||||
}
|
||||
|
||||
@@ -89,12 +89,7 @@ async function compileUserCode(
|
||||
|
||||
// user code
|
||||
${compiledFile.text};
|
||||
const userEdgeHandler = module.exports.default;
|
||||
if (!userEdgeHandler) {
|
||||
throw new Error(
|
||||
'No default export was found. Add a default export to handle requests. Learn more: https://vercel.link/creating-edge-middleware'
|
||||
);
|
||||
}
|
||||
const userModule = module.exports;
|
||||
|
||||
// request metadata
|
||||
const isMiddleware = ${isMiddleware};
|
||||
@@ -104,7 +99,7 @@ async function compileUserCode(
|
||||
${edgeHandlerTemplate};
|
||||
const dependencies = { Request, Response };
|
||||
const options = { isMiddleware, entrypointLabel };
|
||||
registerFetchListener(userEdgeHandler, options, dependencies);
|
||||
registerFetchListener(userModule, options, dependencies);
|
||||
`;
|
||||
|
||||
return {
|
||||
|
||||
@@ -506,6 +506,7 @@ export const build: BuildV3 = async ({
|
||||
shouldAddSourcemapSupport,
|
||||
awsLambdaHandler,
|
||||
supportsResponseStreaming,
|
||||
maxDuration: staticConfig?.maxDuration,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
76
packages/node/src/serverless-functions/helpers-web.ts
Normal file
76
packages/node/src/serverless-functions/helpers-web.ts
Normal file
@@ -0,0 +1,76 @@
|
||||
import type { ServerResponse, IncomingMessage } from 'http';
|
||||
import type { NodeHandler } from '@edge-runtime/node-utils';
|
||||
import { buildToNodeHandler } from '@edge-runtime/node-utils';
|
||||
|
||||
class FetchEvent {
|
||||
public request: Request;
|
||||
public awaiting: Set<Promise<void>>;
|
||||
public response: Response | null;
|
||||
|
||||
constructor(request: Request) {
|
||||
this.request = request;
|
||||
this.response = null;
|
||||
this.awaiting = new Set();
|
||||
}
|
||||
|
||||
respondWith(response: Response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
waitUntil() {
|
||||
throw new Error('waitUntil is not implemented yet for Node.js');
|
||||
}
|
||||
}
|
||||
|
||||
const webHandlerToNodeHandler = buildToNodeHandler(
|
||||
{
|
||||
Headers,
|
||||
ReadableStream,
|
||||
Request: class extends Request {
|
||||
constructor(input: RequestInfo | URL, init?: RequestInit | undefined) {
|
||||
super(input, addDuplexToInit(init));
|
||||
}
|
||||
},
|
||||
Uint8Array: Uint8Array,
|
||||
FetchEvent: FetchEvent,
|
||||
},
|
||||
{ defaultOrigin: 'https://vercel.com' }
|
||||
);
|
||||
|
||||
/**
|
||||
* When users export at least one HTTP handler, we will generate
|
||||
* a generic handler routing to the right method. If there is no
|
||||
* handler function exported returns null.
|
||||
*/
|
||||
export function getWebExportsHandler(listener: any, methods: string[]) {
|
||||
const handlerByMethod: { [key: string]: NodeHandler } = {};
|
||||
|
||||
for (const key of methods) {
|
||||
handlerByMethod[key] =
|
||||
typeof listener[key] !== 'undefined'
|
||||
? webHandlerToNodeHandler(listener[key])
|
||||
: defaultHttpHandler;
|
||||
}
|
||||
|
||||
return (req: IncomingMessage, res: ServerResponse) => {
|
||||
const method = req.method ?? 'GET';
|
||||
handlerByMethod[method](req, res);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Add `duplex: 'half'` by default to all requests
|
||||
* https://github.com/vercel/edge-runtime/blob/bf167c418247a79d3941bfce4a5d43c37f512502/packages/primitives/src/primitives/fetch.js#L22-L26
|
||||
* https://developer.chrome.com/articles/fetch-streaming-requests/#streaming-request-bodies
|
||||
*/
|
||||
function addDuplexToInit(init: RequestInit | undefined) {
|
||||
if (typeof init === 'undefined' || typeof init === 'object') {
|
||||
return { duplex: 'half', ...init };
|
||||
}
|
||||
return init;
|
||||
}
|
||||
|
||||
function defaultHttpHandler(_: IncomingMessage, res: ServerResponse) {
|
||||
res.statusCode = 405;
|
||||
res.end();
|
||||
}
|
||||
@@ -27,10 +27,19 @@ class ApiError extends Error {
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeContentType(contentType: string | undefined) {
|
||||
if (!contentType) {
|
||||
return 'text/plain';
|
||||
}
|
||||
|
||||
const { parse: parseContentType } = require('content-type');
|
||||
const { type } = parseContentType(contentType);
|
||||
return type;
|
||||
}
|
||||
|
||||
function getBodyParser(body: Buffer, contentType: string | undefined) {
|
||||
return function parseBody(): VercelRequestBody {
|
||||
const { parse: parseContentType } = require('content-type');
|
||||
const { type } = parseContentType(contentType);
|
||||
const type = normalizeContentType(contentType);
|
||||
|
||||
if (type === 'application/json') {
|
||||
try {
|
||||
|
||||
@@ -21,40 +21,63 @@ type ServerlessFunctionSignature = (
|
||||
res: ServerResponse | VercelResponse
|
||||
) => void;
|
||||
|
||||
async function createServerlessServer(
|
||||
userCode: ServerlessFunctionSignature,
|
||||
options: ServerlessServerOptions
|
||||
) {
|
||||
const server = createServer(async (req, res) => {
|
||||
if (options.shouldAddHelpers) await addHelpers(req, res);
|
||||
return userCode(req, res);
|
||||
});
|
||||
const [NODE_MAJOR] = process.versions.node.split('.').map(v => Number(v));
|
||||
|
||||
/* https://nextjs.org/docs/app/building-your-application/routing/router-handlers#supported-http-methods */
|
||||
const HTTP_METHODS = [
|
||||
'GET',
|
||||
'HEAD',
|
||||
'OPTIONS',
|
||||
'POST',
|
||||
'PUT',
|
||||
'DELETE',
|
||||
'PATCH',
|
||||
];
|
||||
|
||||
async function createServerlessServer(userCode: ServerlessFunctionSignature) {
|
||||
const server = createServer(userCode);
|
||||
exitHook(() => server.close());
|
||||
return { url: await listen(server) };
|
||||
}
|
||||
|
||||
async function compileUserCode(entrypointPath: string) {
|
||||
async function compileUserCode(
|
||||
entrypointPath: string,
|
||||
options: ServerlessServerOptions
|
||||
) {
|
||||
const id = isAbsolute(entrypointPath)
|
||||
? pathToFileURL(entrypointPath).href
|
||||
: entrypointPath;
|
||||
let fn = await import(id);
|
||||
let listener = await import(id);
|
||||
|
||||
/**
|
||||
* In some cases we might have nested default props due to TS => JS
|
||||
*/
|
||||
for (let i = 0; i < 5; i++) {
|
||||
if (fn.default) fn = fn.default;
|
||||
if (listener.default) listener = listener.default;
|
||||
}
|
||||
|
||||
return fn;
|
||||
if (HTTP_METHODS.some(method => typeof listener[method] === 'function')) {
|
||||
if (NODE_MAJOR < 18) {
|
||||
throw new Error(
|
||||
'Node.js v18 or above is required to use HTTP method exports in your functions.'
|
||||
);
|
||||
}
|
||||
const { getWebExportsHandler } = await import('./helpers-web.js');
|
||||
return getWebExportsHandler(listener, HTTP_METHODS);
|
||||
}
|
||||
|
||||
return async (req: IncomingMessage, res: ServerResponse) => {
|
||||
if (options.shouldAddHelpers) await addHelpers(req, res);
|
||||
return listener(req, res);
|
||||
};
|
||||
}
|
||||
|
||||
export async function createServerlessEventHandler(
|
||||
entrypointPath: string,
|
||||
options: ServerlessServerOptions
|
||||
): Promise<(request: IncomingMessage) => Promise<VercelProxyResponse>> {
|
||||
const userCode = await compileUserCode(entrypointPath);
|
||||
const server = await createServerlessServer(userCode, options);
|
||||
const userCode = await compileUserCode(entrypointPath, options);
|
||||
const server = await createServerlessServer(userCode);
|
||||
|
||||
return async function (request: IncomingMessage) {
|
||||
const url = new URL(request.url ?? '/', server.url);
|
||||
|
||||
@@ -59,7 +59,12 @@ export function entrypointToOutputPath(
|
||||
}
|
||||
|
||||
export function logError(error: Error) {
|
||||
console.error(error.message);
|
||||
let message = error.message;
|
||||
if (!message.startsWith('Error:')) {
|
||||
message = `Error: ${message}`;
|
||||
}
|
||||
console.error(message);
|
||||
|
||||
if (error.stack) {
|
||||
// only show the stack trace if debug is enabled
|
||||
// because it points to internals, not user code
|
||||
|
||||
10
packages/node/test/dev-fixtures/serverless-web.js
Normal file
10
packages/node/test/dev-fixtures/serverless-web.js
Normal file
@@ -0,0 +1,10 @@
|
||||
/* global Response */
|
||||
|
||||
const baseUrl = ({ headers }) =>
|
||||
`${headers.get('x-forwarded-proto')}://${headers.get('x-forwarded-host')}`;
|
||||
|
||||
export function GET(request) {
|
||||
const { searchParams } = new URL(request.url, baseUrl(request));
|
||||
const name = searchParams.get('name');
|
||||
return new Response(`Greetings, ${name}`);
|
||||
}
|
||||
@@ -4,6 +4,8 @@ import fetch from 'node-fetch';
|
||||
|
||||
jest.setTimeout(20 * 1000);
|
||||
|
||||
const [NODE_MAJOR] = process.versions.node.split('.').map(v => Number(v));
|
||||
|
||||
function testForkDevServer(entrypoint: string) {
|
||||
const ext = extname(entrypoint);
|
||||
const isTypeScript = ext === '.ts';
|
||||
@@ -24,6 +26,41 @@ function testForkDevServer(entrypoint: string) {
|
||||
});
|
||||
}
|
||||
|
||||
(NODE_MAJOR < 18 ? test.skip : test)(
|
||||
'runs an serverless function that exports GET',
|
||||
async () => {
|
||||
const child = testForkDevServer('./serverless-web.js');
|
||||
try {
|
||||
const result = await readMessage(child);
|
||||
if (result.state !== 'message') {
|
||||
throw new Error('Exited. error: ' + JSON.stringify(result.value));
|
||||
}
|
||||
|
||||
const { address, port } = result.value;
|
||||
|
||||
{
|
||||
const response = await fetch(
|
||||
`http://${address}:${port}/api/serverless-web?name=Vercel`
|
||||
);
|
||||
expect({
|
||||
status: response.status,
|
||||
body: await response.text(),
|
||||
}).toEqual({ status: 200, body: 'Greetings, Vercel' });
|
||||
}
|
||||
|
||||
{
|
||||
const response = await fetch(
|
||||
`http://${address}:${port}/api/serverless-web?name=Vercel`,
|
||||
{ method: 'HEAD' }
|
||||
);
|
||||
expect({ status: response.status }).toEqual({ status: 405 });
|
||||
}
|
||||
} finally {
|
||||
child.kill(9);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
test('runs an edge function that uses `WebSocket`', async () => {
|
||||
const child = testForkDevServer('./edge-websocket.js');
|
||||
try {
|
||||
@@ -57,9 +94,8 @@ test('runs an edge function that uses `buffer`', async () => {
|
||||
throw new Error('Exited. error: ' + JSON.stringify(result.value));
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`http://localhost:${result.value.port}/api/edge-buffer`
|
||||
);
|
||||
const { address, port } = result.value;
|
||||
const response = await fetch(`http://${address}:${port}/api/edge-buffer`);
|
||||
expect({
|
||||
status: response.status,
|
||||
json: await response.json(),
|
||||
@@ -84,9 +120,8 @@ test('runs a mjs endpoint', async () => {
|
||||
throw new Error('Exited. error: ' + JSON.stringify(result.value));
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`http://localhost:${result.value.port}/api/hello`
|
||||
);
|
||||
const { address, port } = result.value;
|
||||
const response = await fetch(`http://${address}:${port}/api/hello`);
|
||||
expect({
|
||||
status: response.status,
|
||||
headers: Object.fromEntries(response.headers),
|
||||
@@ -117,9 +152,8 @@ test('runs a esm typescript endpoint', async () => {
|
||||
throw new Error('Exited. error: ' + JSON.stringify(result.value));
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`http://localhost:${result.value.port}/api/hello`
|
||||
);
|
||||
const { address, port } = result.value;
|
||||
const response = await fetch(`http://${address}:${port}/api/hello`);
|
||||
expect({
|
||||
status: response.status,
|
||||
headers: Object.fromEntries(response.headers),
|
||||
@@ -150,9 +184,8 @@ test('allow setting multiple cookies with same name', async () => {
|
||||
throw new Error(`Exited. error: ${JSON.stringify(result.value)}`);
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`http://localhost:${result.value.port}/api/hello`
|
||||
);
|
||||
const { address, port } = result.value;
|
||||
const response = await fetch(`http://${address}:${port}/api/hello`);
|
||||
expect({
|
||||
status: response.status,
|
||||
text: await response.text(),
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
"@types/execa": "^0.9.0",
|
||||
"@types/jest": "27.4.1",
|
||||
"@types/node": "14.18.33",
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"execa": "^1.0.0"
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
"@types/aws-lambda": "8.10.19",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/semver": "6.0.0",
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"execa": "3.2.0",
|
||||
"fs-extra": "11.1.0"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,18 @@
|
||||
# @vercel/remix-builder
|
||||
|
||||
## 1.8.13
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Update `@remix-run/dev` fork to v1.17.0 ([#10072](https://github.com/vercel/vercel/pull/10072))
|
||||
|
||||
## 1.8.12
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
|
||||
- @vercel/build-utils@6.7.5
|
||||
|
||||
## 1.8.11
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/remix-builder",
|
||||
"version": "1.8.11",
|
||||
"version": "1.8.13",
|
||||
"license": "Apache-2.0",
|
||||
"main": "./dist/index.js",
|
||||
"homepage": "https://vercel.com/docs",
|
||||
@@ -20,8 +20,8 @@
|
||||
"defaults"
|
||||
],
|
||||
"dependencies": {
|
||||
"@remix-run/dev": "npm:@vercel/remix-run-dev@1.16.1",
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@remix-run/dev": "npm:@vercel/remix-run-dev@1.17.0",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/nft": "0.22.5",
|
||||
"@vercel/static-config": "2.0.17",
|
||||
"path-to-regexp": "6.2.1",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "8.0.0",
|
||||
"@types/semver": "6.0.0",
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"execa": "2.0.4",
|
||||
"fs-extra": "^7.0.1",
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
# @vercel/static-build
|
||||
|
||||
## 1.3.36
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @vercel/gatsby-plugin-vercel-builder@1.3.9
|
||||
|
||||
## 1.3.35
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @vercel/gatsby-plugin-vercel-builder@1.3.8
|
||||
|
||||
## 1.3.34
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies []:
|
||||
- @vercel/gatsby-plugin-vercel-builder@1.3.7
|
||||
|
||||
## 1.3.33
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/static-build",
|
||||
"version": "1.3.33",
|
||||
"version": "1.3.36",
|
||||
"license": "Apache-2.0",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/build-step",
|
||||
@@ -20,7 +20,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/gatsby-plugin-vercel-analytics": "1.0.10",
|
||||
"@vercel/gatsby-plugin-vercel-builder": "1.3.6"
|
||||
"@vercel/gatsby-plugin-vercel-builder": "1.3.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/aws-lambda": "8.10.64",
|
||||
@@ -32,10 +32,10 @@
|
||||
"@types/node-fetch": "2.5.4",
|
||||
"@types/promise-timeout": "1.3.0",
|
||||
"@types/semver": "7.3.13",
|
||||
"@vercel/build-utils": "6.7.4",
|
||||
"@vercel/build-utils": "6.7.5",
|
||||
"@vercel/error-utils": "1.0.10",
|
||||
"@vercel/frameworks": "1.4.2",
|
||||
"@vercel/fs-detectors": "3.9.3",
|
||||
"@vercel/fs-detectors": "4.0.0",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/routing-utils": "2.2.1",
|
||||
"@vercel/static-config": "2.0.17",
|
||||
|
||||
1
packages/static-config/test/fixtures/deno.ts
vendored
1
packages/static-config/test/fixtures/deno.ts
vendored
@@ -4,6 +4,7 @@ import { readerFromStreamReader } from 'https://deno.land/std@0.107.0/io/streams
|
||||
export const config = {
|
||||
runtime: 'deno',
|
||||
location: 'https://example.com/page',
|
||||
maxDuration: 60
|
||||
};
|
||||
|
||||
export default async ({ request }: Deno.RequestEvent) => {
|
||||
|
||||
1
packages/static-config/test/fixtures/node.js
vendored
1
packages/static-config/test/fixtures/node.js
vendored
@@ -3,6 +3,7 @@ import fs from 'fs';
|
||||
export const config = {
|
||||
runtime: 'nodejs',
|
||||
memory: 1024,
|
||||
maxDuration: 60,
|
||||
};
|
||||
|
||||
export default function (req, res) {
|
||||
|
||||
2
packages/static-config/test/index.test.ts
vendored
2
packages/static-config/test/index.test.ts
vendored
@@ -9,6 +9,7 @@ describe('getConfig()', () => {
|
||||
const config = getConfig(project, sourcePath);
|
||||
expect(config).toMatchInlineSnapshot(`
|
||||
{
|
||||
"maxDuration": 60,
|
||||
"memory": 1024,
|
||||
"runtime": "nodejs",
|
||||
}
|
||||
@@ -27,6 +28,7 @@ describe('getConfig()', () => {
|
||||
expect(config).toMatchInlineSnapshot(`
|
||||
{
|
||||
"location": "https://example.com/page",
|
||||
"maxDuration": 60,
|
||||
"runtime": "deno",
|
||||
}
|
||||
`);
|
||||
|
||||
2
packages/static-config/test/swc.test.ts
vendored
2
packages/static-config/test/swc.test.ts
vendored
@@ -56,6 +56,7 @@ describe('getConfig for swc', () => {
|
||||
const config = getConfig(ast, BaseFunctionConfigSchema);
|
||||
expect(config).toMatchInlineSnapshot(`
|
||||
{
|
||||
"maxDuration": 60,
|
||||
"memory": 1024,
|
||||
"runtime": "nodejs",
|
||||
}
|
||||
@@ -73,6 +74,7 @@ describe('getConfig for swc', () => {
|
||||
expect(config).toMatchInlineSnapshot(`
|
||||
{
|
||||
"location": "https://example.com/page",
|
||||
"maxDuration": 60,
|
||||
"runtime": "deno",
|
||||
}
|
||||
`);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user