mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-11 04:22:13 +00:00
Compare commits
119 Commits
@vercel/re
...
vercel@28.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1c8b454cc | ||
|
|
e2105e47b5 | ||
|
|
76d58673fc | ||
|
|
a585969dd3 | ||
|
|
35eca33b44 | ||
|
|
d608153961 | ||
|
|
a4cfc5f943 | ||
|
|
2eef3e3ddb | ||
|
|
8120fd3d7a | ||
|
|
ba498f3a8e | ||
|
|
b5a9408272 | ||
|
|
946f7f0bfc | ||
|
|
804a3863e7 | ||
|
|
a4d16c681a | ||
|
|
61bbd4f98b | ||
|
|
fedf264862 | ||
|
|
6420e54b35 | ||
|
|
aa6b957b23 | ||
|
|
c6717a1492 | ||
|
|
0b33c1c3e7 | ||
|
|
dbea973546 | ||
|
|
8ac4814702 | ||
|
|
c84d6c4355 | ||
|
|
61b6e87987 | ||
|
|
ada9a48d57 | ||
|
|
31f3daa5b4 | ||
|
|
fdf7fd6784 | ||
|
|
db216f903f | ||
|
|
40a55b11d5 | ||
|
|
5da537124c | ||
|
|
54aaab83aa | ||
|
|
7110cb449b | ||
|
|
89a15681d5 | ||
|
|
9317543c48 | ||
|
|
e3f326f714 | ||
|
|
eed6a377f1 | ||
|
|
c16d9e6784 | ||
|
|
25f6595d36 | ||
|
|
e8385566fa | ||
|
|
52ca35252a | ||
|
|
2004e3d734 | ||
|
|
49b4394c44 | ||
|
|
08cdfa2a05 | ||
|
|
f18fa8546f | ||
|
|
025344c4a7 | ||
|
|
8b036e97ea | ||
|
|
a4240e89e1 | ||
|
|
0863ae0c6f | ||
|
|
e09d3d5928 | ||
|
|
f5f544ffd2 | ||
|
|
4eb1ff8730 | ||
|
|
d4b604f05c | ||
|
|
a3cf05af06 | ||
|
|
df2bcec830 | ||
|
|
f5e81273af | ||
|
|
e75d900eaf | ||
|
|
1a4f185045 | ||
|
|
35cc7db1a7 | ||
|
|
f535a20aad | ||
|
|
fcea36bf04 | ||
|
|
93f5a4438b | ||
|
|
72265aa9a1 | ||
|
|
6ee5eb137b | ||
|
|
c4f1c2f5ed | ||
|
|
f35a77c292 | ||
|
|
4bf3c237ee | ||
|
|
62c991f25e | ||
|
|
6ea2db4ae9 | ||
|
|
1943b1ecc0 | ||
|
|
92f5b6e0c9 | ||
|
|
ed6ce1149a | ||
|
|
fc3611fb80 | ||
|
|
ed33c2b27c | ||
|
|
a7a5bf1a12 | ||
|
|
cc687b3880 | ||
|
|
053ec92d5f | ||
|
|
4838dc336a | ||
|
|
eae45f4019 | ||
|
|
02feb564a7 | ||
|
|
e174a06673 | ||
|
|
de034943af | ||
|
|
b3862271a5 | ||
|
|
aaceeef604 | ||
|
|
ad107ecf79 | ||
|
|
79ef5c3724 | ||
|
|
02ff265074 | ||
|
|
ae89b8b8be | ||
|
|
4ccdcde463 | ||
|
|
22d3ee160b | ||
|
|
6d97e1673e | ||
|
|
522565f6e5 | ||
|
|
07bf81ab10 | ||
|
|
35024a4e3a | ||
|
|
c1df9bca19 | ||
|
|
4c1cdd1f0f | ||
|
|
b5cdc82a1c | ||
|
|
c7851404b3 | ||
|
|
e54da8a2e5 | ||
|
|
a066bedf95 | ||
|
|
09b23e53ba | ||
|
|
b793a67588 | ||
|
|
31dd354b3a | ||
|
|
529ff3b2d7 | ||
|
|
e71d5638ee | ||
|
|
8c16e765ee | ||
|
|
a008c9c7fe | ||
|
|
62b28ad0b4 | ||
|
|
7c50f2916e | ||
|
|
a521dadafb | ||
|
|
1efb5d6c0d | ||
|
|
72df5ce8f6 | ||
|
|
e20b74687f | ||
|
|
8f1358bd15 | ||
|
|
74c0b3e1bb | ||
|
|
eb0a031aeb | ||
|
|
f327be2d1f | ||
|
|
16a5867f6b | ||
|
|
90cbd675fa | ||
|
|
9c768b98b7 |
@@ -43,5 +43,8 @@ packages/static-build/test/cache-fixtures
|
||||
# redwood
|
||||
packages/redwood/test/fixtures
|
||||
|
||||
# remix
|
||||
packages/remix/test/fixtures
|
||||
|
||||
# gatsby-plugin-vercel-analytics
|
||||
packages/gatsby-plugin-vercel-analytics
|
||||
|
||||
3
.github/CODEOWNERS
vendored
3
.github/CODEOWNERS
vendored
@@ -3,9 +3,6 @@
|
||||
|
||||
* @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood
|
||||
/.github/workflows @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||
/packages/cli/src/commands/domains @mglagola @anatrajkovska
|
||||
/packages/cli/src/commands/certs @mglagola @anatrajkovska
|
||||
/packages/cli/src/commands/env @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood
|
||||
/packages/fs-detectors @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @agadzik @chloetedder
|
||||
/packages/node-bridge @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||
/packages/next @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||
|
||||
20
.github/CONTRIBUTING.md
vendored
20
.github/CONTRIBUTING.md
vendored
@@ -6,7 +6,7 @@ Please read our [Code of Conduct](CODE_OF_CONDUCT.md) and follow it in all your
|
||||
|
||||
## Local development
|
||||
|
||||
This project is configured in a monorepo, where one repository contains multiple npm packages. Dependencies are installed and managed with `yarn`, not `npm` CLI.
|
||||
This project is configured in a monorepo, where one repository contains multiple npm packages. Dependencies are installed and managed with `pnpm`, not `npm` CLI.
|
||||
|
||||
To get started, execute the following:
|
||||
|
||||
@@ -14,22 +14,22 @@ To get started, execute the following:
|
||||
git clone https://github.com/vercel/vercel
|
||||
cd vercel
|
||||
corepack enable
|
||||
yarn install
|
||||
yarn bootstrap
|
||||
yarn build
|
||||
yarn lint
|
||||
yarn test-unit
|
||||
pnpm install
|
||||
pnpm bootstrap
|
||||
pnpm build
|
||||
pnpm lint
|
||||
pnpm test-unit
|
||||
```
|
||||
|
||||
Make sure all the tests pass before making changes.
|
||||
|
||||
### Running Vercel CLI Changes
|
||||
|
||||
You can use `yarn dev` from the `cli` package to invoke Vercel CLI with local changes:
|
||||
You can use `pnpm dev` from the `cli` package to invoke Vercel CLI with local changes:
|
||||
|
||||
```
|
||||
cd ./packages/cli
|
||||
yarn dev <cli-commands...>
|
||||
pnpm dev <cli-commands...>
|
||||
```
|
||||
|
||||
See [CLI Local Development](../packages/cli#local-development) for more details.
|
||||
@@ -39,7 +39,7 @@ See [CLI Local Development](../packages/cli#local-development) for more details.
|
||||
Once you are done with your changes (we even suggest doing it along the way), make sure all the tests still pass by running:
|
||||
|
||||
```
|
||||
yarn test-unit
|
||||
pnpm test-unit
|
||||
```
|
||||
|
||||
from the root of the project.
|
||||
@@ -102,7 +102,7 @@ When you run this script, you'll see all the imported files. If anything file is
|
||||
Sometimes you want to test changes to a Builder against an existing project, maybe with `vercel dev` or actual deployment. You can avoid publishing every Builder change to npm by uploading the Builder as a tarball.
|
||||
|
||||
1. Change directory to the desired Builder `cd ./packages/node`
|
||||
2. Run `yarn build` to compile typescript and other build steps
|
||||
2. Run `pnpm build` to compile typescript and other build steps
|
||||
3. Run `npm pack` to create a tarball file
|
||||
4. Run `vercel *.tgz` to upload the tarball file and get a URL
|
||||
5. Edit any existing `vercel.json` project and replace `use` with the URL
|
||||
|
||||
27
.github/workflows/cron-update-turbo.yml
vendored
Normal file
27
.github/workflows/cron-update-turbo.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
name: Cron Update Turbo
|
||||
|
||||
on:
|
||||
# Run every week https://crontab.guru/every-week
|
||||
schedule:
|
||||
- cron: '0 0 * * 0'
|
||||
|
||||
jobs:
|
||||
create-pull-request:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
# 0 means fetch all commits so we can commit and push in the script below
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: install pnpm@7.26.0
|
||||
run: npm i -g pnpm@7.26.0
|
||||
- name: Create Pull Request
|
||||
uses: actions/github-script@v6
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
# See https://github.com/actions/github-script#run-a-separate-file-with-an-async-function
|
||||
with:
|
||||
script: |
|
||||
const script = require('./utils/update-turbo.js')
|
||||
await script({ github, context })
|
||||
16
.github/workflows/publish.yml
vendored
16
.github/workflows/publish.yml
vendored
@@ -39,28 +39,22 @@ jobs:
|
||||
- name: Setup Node
|
||||
if: ${{ steps.check-release.outputs.IS_RELEASE == 'true' }}
|
||||
uses: actions/setup-node@v3
|
||||
timeout-minutes: 5 # See https://github.com/actions/cache/issues/810
|
||||
with:
|
||||
node-version: 14
|
||||
- name: Cache
|
||||
if: ${{ steps.check-release.outputs.IS_RELEASE == 'true' }}
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: yarn-${{ matrix.os }}-${{ matrix.node }}-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: yarn-${{ matrix.os }}-${{ matrix.node }}
|
||||
- name: install pnpm@7.24.2
|
||||
run: npm i -g pnpm@7.24.2
|
||||
- name: Install
|
||||
if: ${{ steps.check-release.outputs.IS_RELEASE == 'true' }}
|
||||
run: yarn install --check-files --frozen-lockfile --network-timeout 1000000
|
||||
run: pnpm install
|
||||
- name: Build
|
||||
if: ${{ steps.check-release.outputs.IS_RELEASE == 'true' }}
|
||||
run: yarn build
|
||||
run: pnpm build
|
||||
env:
|
||||
GA_TRACKING_ID: ${{ secrets.GA_TRACKING_ID }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
- name: Publish
|
||||
if: ${{ steps.check-release.outputs.IS_RELEASE == 'true' }}
|
||||
run: yarn publish-from-github
|
||||
run: pnpm publish-from-github
|
||||
env:
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN_ELEVATED }}
|
||||
GA_TRACKING_ID: ${{ secrets.GA_TRACKING_ID }}
|
||||
|
||||
14
.github/workflows/test-integration-cli.yml
vendored
14
.github/workflows/test-integration-cli.yml
vendored
@@ -35,17 +35,13 @@ jobs:
|
||||
with:
|
||||
go-version: '1.18'
|
||||
- uses: actions/setup-node@v3
|
||||
timeout-minutes: 5 # See https://github.com/actions/cache/issues/810
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: yarn-${{ matrix.os }}-${{ matrix.node }}-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: yarn-${{ matrix.os }}-${{ matrix.node }}
|
||||
- run: yarn install --network-timeout 1000000 --frozen-lockfile
|
||||
- run: yarn run build
|
||||
- run: yarn test-integration-cli
|
||||
- name: install pnpm@7.24.2
|
||||
run: npm i -g pnpm@7.24.2
|
||||
- run: pnpm install
|
||||
- run: pnpm run build
|
||||
- run: pnpm test-integration-cli
|
||||
env:
|
||||
VERCEL_TEST_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }}
|
||||
VERCEL_TEST_REGISTRATION_URL: ${{ secrets.VERCEL_TEST_REGISTRATION_URL }}
|
||||
|
||||
18
.github/workflows/test-unit.yml
vendored
18
.github/workflows/test-unit.yml
vendored
@@ -35,20 +35,16 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 2
|
||||
- uses: actions/setup-node@v3
|
||||
timeout-minutes: 5 # See https://github.com/actions/cache/issues/810
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: yarn-${{ matrix.os }}-${{ matrix.node }}-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: yarn-${{ matrix.os }}-${{ matrix.node }}
|
||||
- run: yarn install --network-timeout 1000000 --frozen-lockfile
|
||||
- run: yarn run build
|
||||
- run: yarn run lint
|
||||
- name: install pnpm@7.24.2
|
||||
run: npm i -g pnpm@7.24.2
|
||||
- run: pnpm install
|
||||
- run: pnpm run build
|
||||
- run: pnpm run lint
|
||||
if: matrix.os == 'ubuntu-latest' && matrix.node == 14 # only run lint once
|
||||
- run: yarn run test-unit
|
||||
- run: yarn workspace vercel run coverage
|
||||
- run: pnpm run test-unit
|
||||
- run: pnpm -C packages/cli run coverage
|
||||
if: matrix.os == 'ubuntu-latest' && matrix.node == 14 # only run coverage once
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
|
||||
21
.github/workflows/test.yml
vendored
21
.github/workflows/test.yml
vendored
@@ -33,15 +33,11 @@ jobs:
|
||||
with:
|
||||
go-version: '1.13.15'
|
||||
- uses: actions/setup-node@v3
|
||||
timeout-minutes: 5 # See https://github.com/actions/cache/issues/810
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: yarn-${{ matrix.os }}-${{ matrix.node }}-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: yarn-${{ matrix.os }}-${{ matrix.node }}
|
||||
- run: yarn install --network-timeout 1000000 --frozen-lockfile
|
||||
- name: install pnpm@7.24.2
|
||||
run: npm i -g pnpm@7.24.2
|
||||
- run: pnpm install
|
||||
- id: set-tests
|
||||
run: |
|
||||
TESTS_ARRAY=$(node utils/chunk-tests.js $SCRIPT_NAME)
|
||||
@@ -74,20 +70,17 @@ jobs:
|
||||
with:
|
||||
go-version: '1.13.15'
|
||||
- uses: actions/setup-node@v3
|
||||
timeout-minutes: 5 # See https://github.com/actions/cache/issues/810
|
||||
with:
|
||||
node-version: ${{ env.NODE_VERSION }}
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: '**/node_modules'
|
||||
key: yarn-${{ matrix.os }}-${{ matrix.node }}-${{ hashFiles('yarn.lock') }}
|
||||
restore-keys: yarn-${{ matrix.os }}-${{ matrix.node }}
|
||||
|
||||
- name: Install Hugo
|
||||
if: matrix.runner == 'macos-latest'
|
||||
run: curl -L -O https://github.com/gohugoio/hugo/releases/download/v0.56.0/hugo_0.56.0_macOS-64bit.tar.gz && tar -xzf hugo_0.56.0_macOS-64bit.tar.gz && mv ./hugo packages/cli/test/dev/fixtures/08-hugo/
|
||||
|
||||
- run: yarn install --network-timeout 1000000
|
||||
- name: install pnpm@7.24.2
|
||||
run: npm i -g pnpm@7.24.2
|
||||
|
||||
- run: pnpm install
|
||||
|
||||
- name: Build ${{matrix.packageName}} and all its dependencies
|
||||
run: node utils/gen.js && node_modules/.bin/turbo run build --cache-dir=".turbo" --scope=${{matrix.packageName}} --include-dependencies --no-deps
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
. "$(dirname "$0")/_/husky.sh"
|
||||
|
||||
yarn pre-commit
|
||||
pnpm pre-commit
|
||||
|
||||
5
.npmrc
Normal file
5
.npmrc
Normal file
@@ -0,0 +1,5 @@
|
||||
save-exact=true
|
||||
hoist-pattern[]=!"**/@types/**"
|
||||
hoist-pattern[]=!"**/typedoc"
|
||||
hoist-pattern[]=!"**/typedoc-plugin-markdown"
|
||||
hoist-pattern[]=!"**/typedoc-plugin-mdn-links"
|
||||
@@ -33,9 +33,9 @@ For details on how to use Vercel, check out our [documentation](https://vercel.c
|
||||
|
||||
## Contributing
|
||||
|
||||
This project uses [yarn](https://yarnpkg.com/) to install dependencies and run scripts.
|
||||
This project uses [pnpm](https://pnpm.io/) to install dependencies and run scripts.
|
||||
|
||||
You can use the `dev` script to run local changes as if you were invoking Vercel CLI. For example, `vercel deploy --cwd=/path/to/project` could be run with local changes with `yarn dev deploy --cwd=/path/to/project`.
|
||||
You can use the `dev` script to run local changes as if you were invoking Vercel CLI. For example, `vercel deploy --cwd=/path/to/project` could be run with local changes with `pnpm dev deploy --cwd=/path/to/project`.
|
||||
|
||||
See the [Contributing Guidelines](./.github/CONTRIBUTING.md) for more details.
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ function initSentry() {
|
||||
sentryInitDone = true;
|
||||
|
||||
init({
|
||||
// Cannot figure out whats going wrong here. VSCode resolves this fine. But when we build it blows up.
|
||||
// @ts-ignore
|
||||
dsn: assertEnv('SENTRY_DSN'),
|
||||
environment: process.env.NODE_ENV || 'production',
|
||||
release: `${serviceName}`,
|
||||
|
||||
@@ -4,9 +4,7 @@
|
||||
"version": "0.0.0",
|
||||
"description": "API for the vercel/vercel repo",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"//TODO": "We should add this pkg to yarn workspaces"
|
||||
},
|
||||
"scripts": {},
|
||||
"dependencies": {
|
||||
"@sentry/node": "5.11.1",
|
||||
"got": "10.2.1",
|
||||
@@ -16,9 +14,9 @@
|
||||
"unzip-stream": "0.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "14.18.33",
|
||||
"@types/node": "16.18.11",
|
||||
"@types/node-fetch": "2.5.4",
|
||||
"@vercel/node": "1.9.0",
|
||||
"typescript": "3.9.6"
|
||||
"@vercel/node": "*",
|
||||
"typescript": "4.3.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,5 +12,5 @@
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true
|
||||
},
|
||||
"include": ["examples", "frameworks.ts"]
|
||||
"include": ["examples", "frameworks.ts", "_lib"]
|
||||
}
|
||||
|
||||
524
api/yarn.lock
524
api/yarn.lock
@@ -1,524 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@sentry/apm@5.11.1":
|
||||
version "5.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/apm/-/apm-5.11.1.tgz#cc89fa4150056fbf009f92eca94fccc3980db34e"
|
||||
integrity sha512-4iZH11p/7w9IMLT9hqNY1+EqLESltiIoF6/YsbpK93sXWGEs8VQ83IuvGuKWxajvHgDmj4ND0TxIliTsYqTqFw==
|
||||
dependencies:
|
||||
"@sentry/browser" "5.11.1"
|
||||
"@sentry/hub" "5.11.1"
|
||||
"@sentry/minimal" "5.11.1"
|
||||
"@sentry/types" "5.11.0"
|
||||
"@sentry/utils" "5.11.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/browser@5.11.1":
|
||||
version "5.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-5.11.1.tgz#337ffcb52711b23064c847a07629e966f54a5ebb"
|
||||
integrity sha512-oqOX/otmuP92DEGRyZeBuQokXdeT9HQRxH73oqIURXXNLMP3PWJALSb4HtT4AftEt/2ROGobZLuA4TaID6My/Q==
|
||||
dependencies:
|
||||
"@sentry/core" "5.11.1"
|
||||
"@sentry/types" "5.11.0"
|
||||
"@sentry/utils" "5.11.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/core@5.11.1":
|
||||
version "5.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.11.1.tgz#9e2da485e196ae32971545c1c49ee6fe719930e2"
|
||||
integrity sha512-BpvPosVNT20Xso4gAV54Lu3KqDmD20vO63HYwbNdST5LUi8oYV4JhvOkoBraPEM2cbBwQvwVcFdeEYKk4tin9A==
|
||||
dependencies:
|
||||
"@sentry/hub" "5.11.1"
|
||||
"@sentry/minimal" "5.11.1"
|
||||
"@sentry/types" "5.11.0"
|
||||
"@sentry/utils" "5.11.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/hub@5.11.1":
|
||||
version "5.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.11.1.tgz#ddcb865563fae53852d405885c46b4c6de68a91b"
|
||||
integrity sha512-ucKprYCbGGLLjVz4hWUqHN9KH0WKUkGf5ZYfD8LUhksuobRkYVyig0ZGbshECZxW5jcDTzip4Q9Qimq/PkkXBg==
|
||||
dependencies:
|
||||
"@sentry/types" "5.11.0"
|
||||
"@sentry/utils" "5.11.1"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/minimal@5.11.1":
|
||||
version "5.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.11.1.tgz#0e705d01a567282d8fbbda2aed848b4974cc3cec"
|
||||
integrity sha512-HK8zs7Pgdq7DsbZQTThrhQPrJsVWzz7MaluAbQA0rTIAJ3TvHKQpsVRu17xDpjZXypqWcKCRsthDrC4LxDM1Bg==
|
||||
dependencies:
|
||||
"@sentry/hub" "5.11.1"
|
||||
"@sentry/types" "5.11.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/node@5.11.1":
|
||||
version "5.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.11.1.tgz#2a9c18cd1209cfdf7a69b9d91303413149d2c910"
|
||||
integrity sha512-FbJs0blJ36gEzE0rc2yBfA/KE+kXOLl8MUfFTcyJCBdCGF8XMETDCmgINnJ4TyBUJviwKoPw2TCk9TL2pa/A1w==
|
||||
dependencies:
|
||||
"@sentry/apm" "5.11.1"
|
||||
"@sentry/core" "5.11.1"
|
||||
"@sentry/hub" "5.11.1"
|
||||
"@sentry/types" "5.11.0"
|
||||
"@sentry/utils" "5.11.1"
|
||||
cookie "^0.3.1"
|
||||
https-proxy-agent "^4.0.0"
|
||||
lru_map "^0.3.3"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sentry/types@5.11.0":
|
||||
version "5.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.11.0.tgz#40f0f3174362928e033ddd9725d55e7c5cb7c5b6"
|
||||
integrity sha512-1Uhycpmeo1ZK2GLvrtwZhTwIodJHcyIS6bn+t4IMkN9MFoo6ktbAfhvexBDW/IDtdLlCGJbfm8nIZerxy0QUpg==
|
||||
|
||||
"@sentry/utils@5.11.1":
|
||||
version "5.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.11.1.tgz#aa19fcc234cf632257b2281261651d2fac967607"
|
||||
integrity sha512-O0Zl4R2JJh8cTkQ8ZL2cDqGCmQdpA5VeXpuBbEl1v78LQPkBDISi35wH4mKmLwMsLBtTVpx2UeUHBj0KO5aLlA==
|
||||
dependencies:
|
||||
"@sentry/types" "5.11.0"
|
||||
tslib "^1.9.3"
|
||||
|
||||
"@sindresorhus/is@^1.0.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-1.2.0.tgz#63ce3638cb85231f3704164c90a18ef816da3fb7"
|
||||
integrity sha512-mwhXGkRV5dlvQc4EgPDxDxO6WuMBVymGFd1CA+2Y+z5dG9MNspoQ+AWjl/Ld1MnpCL8AKbosZlDVohqcIwuWsw==
|
||||
|
||||
"@szmarczak/http-timer@^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.0.tgz#309789ccb7842ff1e41848cf43da587f78068836"
|
||||
integrity sha512-3yoXv8OtGr/r3R5gaWWNQ3VUoQ5G3Gmo8DXX95V14ZVvE2b7Pj6Ide9uIDON8ym4D/ItyfL9ejohYUPqOyvRXw==
|
||||
dependencies:
|
||||
defer-to-connect "^1.1.1"
|
||||
|
||||
"@types/cacheable-request@^6.0.1":
|
||||
version "6.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976"
|
||||
integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==
|
||||
dependencies:
|
||||
"@types/http-cache-semantics" "*"
|
||||
"@types/keyv" "*"
|
||||
"@types/node" "*"
|
||||
"@types/responselike" "*"
|
||||
|
||||
"@types/http-cache-semantics@*":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a"
|
||||
integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==
|
||||
|
||||
"@types/keyv@*":
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7"
|
||||
integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node-fetch@2.5.4":
|
||||
version "2.5.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.4.tgz#5245b6d8841fc3a6208b82291119bc11c4e0ce44"
|
||||
integrity sha512-Oz6id++2qAOFuOlE1j0ouk1dzl3mmI1+qINPNBhi9nt/gVOz0G+13Ao6qjhdF0Ys+eOkhu6JnFmt38bR3H0POQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*", "@types/node@13.1.4":
|
||||
version "13.1.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.1.4.tgz#4cfd90175a200ee9b02bd6b1cd19bc349741607e"
|
||||
integrity sha512-Lue/mlp2egZJoHXZr4LndxDAd7i/7SQYhV0EjWfb/a4/OZ6tuVwMCVPiwkU5nsEipxEf7hmkSU7Em5VQ8P5NGA==
|
||||
|
||||
"@types/responselike@*":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
|
||||
integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@vercel/node@1.9.0":
|
||||
version "1.9.0"
|
||||
resolved "https://registry.yarnpkg.com/@vercel/node/-/node-1.9.0.tgz#6b64f3b9a962ddb1089276fad00f441a1f4b9cf0"
|
||||
integrity sha512-Vk/ZpuY4Cdc8oUwBi/kf8qETRaJb/KYdFddVkLuS10QwA0yJx+RQ11trhZ1KFUdc27aBr5S2k8/dDxK8sLr+IA==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
ts-node "8.9.1"
|
||||
typescript "3.9.3"
|
||||
|
||||
agent-base@5:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c"
|
||||
integrity sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==
|
||||
|
||||
arg@^4.1.0:
|
||||
version "4.1.3"
|
||||
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
|
||||
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
|
||||
|
||||
binary@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/binary/-/binary-0.3.0.tgz#9f60553bc5ce8c3386f3b553cff47462adecaa79"
|
||||
integrity sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=
|
||||
dependencies:
|
||||
buffers "~0.1.1"
|
||||
chainsaw "~0.1.0"
|
||||
|
||||
bl@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.0.tgz#3611ec00579fd18561754360b21e9f784500ff88"
|
||||
integrity sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==
|
||||
dependencies:
|
||||
readable-stream "^3.0.1"
|
||||
|
||||
buffer-from@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
|
||||
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
||||
|
||||
buffers@~0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/buffers/-/buffers-0.1.1.tgz#b24579c3bed4d6d396aeee6d9a8ae7f5482ab7bb"
|
||||
integrity sha1-skV5w77U1tOWru5tmorn9Ugqt7s=
|
||||
|
||||
cacheable-lookup@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-0.2.1.tgz#f474ae2c686667d7ea08c43409ad31b2b31b26c2"
|
||||
integrity sha512-BQ8MRjxJASEq2q+w0SusPU3B054gS278K8sj58QCLMZIso5qG05+MdCdmXxuyVlfvI8h4bPsNOavVUauVCGxrg==
|
||||
dependencies:
|
||||
keyv "^3.1.0"
|
||||
|
||||
cacheable-request@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.0.tgz#12421aa084e943ec81eac8c93e56af90c624788a"
|
||||
integrity sha512-UVG4gMn3WjnAeFBBx7RFoprgOANIAkMwN5Dta6ONmfSwrCxfm0Ip7g0mIBxIRJZX9aDsoID0Ry3dU5Pr0csKKA==
|
||||
dependencies:
|
||||
clone-response "^1.0.2"
|
||||
get-stream "^5.1.0"
|
||||
http-cache-semantics "^4.0.0"
|
||||
keyv "^3.0.0"
|
||||
lowercase-keys "^2.0.0"
|
||||
normalize-url "^4.1.0"
|
||||
responselike "^2.0.0"
|
||||
|
||||
chainsaw@~0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/chainsaw/-/chainsaw-0.1.0.tgz#5eab50b28afe58074d0d58291388828b5e5fbc98"
|
||||
integrity sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=
|
||||
dependencies:
|
||||
traverse ">=0.3.0 <0.4"
|
||||
|
||||
chownr@^1.1.1:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142"
|
||||
integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==
|
||||
|
||||
clone-response@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
|
||||
integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
|
||||
dependencies:
|
||||
mimic-response "^1.0.0"
|
||||
|
||||
cookie@^0.3.1:
|
||||
version "0.3.1"
|
||||
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
|
||||
integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=
|
||||
|
||||
debug@4:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
|
||||
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
decompress-response@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-5.0.0.tgz#7849396e80e3d1eba8cb2f75ef4930f76461cb0f"
|
||||
integrity sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==
|
||||
dependencies:
|
||||
mimic-response "^2.0.0"
|
||||
|
||||
defer-to-connect@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.1.tgz#88ae694b93f67b81815a2c8c769aef6574ac8f2f"
|
||||
integrity sha512-J7thop4u3mRTkYRQ+Vpfwy2G5Ehoy82I14+14W4YMDLKdWloI9gSzRbV30s/NckQGVJtPkWNcW4oMAUigTdqiQ==
|
||||
|
||||
diff@^4.0.1:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
|
||||
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
|
||||
|
||||
duplexer3@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
|
||||
integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
|
||||
|
||||
end-of-stream@^1.1.0, end-of-stream@^1.4.1:
|
||||
version "1.4.4"
|
||||
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
|
||||
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
|
||||
dependencies:
|
||||
once "^1.4.0"
|
||||
|
||||
fs-constants@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
|
||||
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
|
||||
|
||||
get-stream@^5.0.0, get-stream@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9"
|
||||
integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==
|
||||
dependencies:
|
||||
pump "^3.0.0"
|
||||
|
||||
got@10.2.1:
|
||||
version "10.2.1"
|
||||
resolved "https://registry.yarnpkg.com/got/-/got-10.2.1.tgz#7087485482fb31aa6e6399fd493dd04639da117b"
|
||||
integrity sha512-IQX//hGm5oLjUj743GJG30U2RzjS58ZlhQQjwQXjsyR50TTD+etVMHlMEbNxYJGWVFa0ASgDVhRkAvQPe6M9iQ==
|
||||
dependencies:
|
||||
"@sindresorhus/is" "^1.0.0"
|
||||
"@szmarczak/http-timer" "^4.0.0"
|
||||
"@types/cacheable-request" "^6.0.1"
|
||||
cacheable-lookup "^0.2.1"
|
||||
cacheable-request "^7.0.0"
|
||||
decompress-response "^5.0.0"
|
||||
duplexer3 "^0.1.4"
|
||||
get-stream "^5.0.0"
|
||||
lowercase-keys "^2.0.0"
|
||||
mimic-response "^2.0.0"
|
||||
p-cancelable "^2.0.0"
|
||||
responselike "^2.0.0"
|
||||
to-readable-stream "^2.0.0"
|
||||
type-fest "^0.8.0"
|
||||
|
||||
http-cache-semantics@^4.0.0:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz#495704773277eeef6e43f9ab2c2c7d259dda25c5"
|
||||
integrity sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew==
|
||||
|
||||
https-proxy-agent@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz#702b71fb5520a132a66de1f67541d9e62154d82b"
|
||||
integrity sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==
|
||||
dependencies:
|
||||
agent-base "5"
|
||||
debug "4"
|
||||
|
||||
inherits@^2.0.3:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
json-buffer@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898"
|
||||
integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=
|
||||
|
||||
keyv@^3.0.0, keyv@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9"
|
||||
integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==
|
||||
dependencies:
|
||||
json-buffer "3.0.0"
|
||||
|
||||
lowercase-keys@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
|
||||
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
|
||||
|
||||
lru_map@^0.3.3:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd"
|
||||
integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=
|
||||
|
||||
make-error@^1.1.1:
|
||||
version "1.3.6"
|
||||
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
|
||||
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
|
||||
|
||||
mimic-response@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
|
||||
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
|
||||
|
||||
mimic-response@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.0.0.tgz#996a51c60adf12cb8a87d7fb8ef24c2f3d5ebb46"
|
||||
integrity sha512-8ilDoEapqA4uQ3TwS0jakGONKXVJqpy+RpM+3b7pLdOjghCrEiGp9SRkFbUHAmZW9vdnrENWHjaweIoTIJExSQ==
|
||||
|
||||
minimist@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
||||
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
|
||||
|
||||
mkdirp@^0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
|
||||
dependencies:
|
||||
minimist "0.0.8"
|
||||
|
||||
ms@^2.1.1:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||
|
||||
node-fetch@2.6.1:
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
|
||||
normalize-url@^4.1.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
|
||||
integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
|
||||
|
||||
once@^1.3.1, once@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
p-cancelable@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e"
|
||||
integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==
|
||||
|
||||
parse-github-url@1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/parse-github-url/-/parse-github-url-1.0.2.tgz#242d3b65cbcdda14bb50439e3242acf6971db395"
|
||||
integrity sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==
|
||||
|
||||
pump@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
|
||||
integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
|
||||
dependencies:
|
||||
end-of-stream "^1.1.0"
|
||||
once "^1.3.1"
|
||||
|
||||
readable-stream@^3.0.1, readable-stream@^3.1.1:
|
||||
version "3.4.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc"
|
||||
integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
responselike@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723"
|
||||
integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==
|
||||
dependencies:
|
||||
lowercase-keys "^2.0.0"
|
||||
|
||||
safe-buffer@~5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
|
||||
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
|
||||
|
||||
source-map-support@^0.5.17:
|
||||
version "0.5.19"
|
||||
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
|
||||
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
|
||||
dependencies:
|
||||
buffer-from "^1.0.0"
|
||||
source-map "^0.6.0"
|
||||
|
||||
source-map@^0.6.0:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
|
||||
string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
|
||||
dependencies:
|
||||
safe-buffer "~5.2.0"
|
||||
|
||||
tar-fs@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.0.tgz#677700fc0c8b337a78bee3623fdc235f21d7afad"
|
||||
integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==
|
||||
dependencies:
|
||||
chownr "^1.1.1"
|
||||
mkdirp "^0.5.1"
|
||||
pump "^3.0.0"
|
||||
tar-stream "^2.0.0"
|
||||
|
||||
tar-stream@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.0.tgz#d1aaa3661f05b38b5acc9b7020efdca5179a2cc3"
|
||||
integrity sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==
|
||||
dependencies:
|
||||
bl "^3.0.0"
|
||||
end-of-stream "^1.4.1"
|
||||
fs-constants "^1.0.0"
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^3.1.1"
|
||||
|
||||
to-readable-stream@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-2.1.0.tgz#82880316121bea662cdc226adb30addb50cb06e8"
|
||||
integrity sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==
|
||||
|
||||
"traverse@>=0.3.0 <0.4":
|
||||
version "0.3.9"
|
||||
resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9"
|
||||
integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=
|
||||
|
||||
ts-node@8.9.1:
|
||||
version "8.9.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.9.1.tgz#2f857f46c47e91dcd28a14e052482eb14cfd65a5"
|
||||
integrity sha512-yrq6ODsxEFTLz0R3BX2myf0WBCSQh9A+py8PBo1dCzWIOcvisbyH6akNKqDHMgXePF2kir5mm5JXJTH3OUJYOQ==
|
||||
dependencies:
|
||||
arg "^4.1.0"
|
||||
diff "^4.0.1"
|
||||
make-error "^1.1.1"
|
||||
source-map-support "^0.5.17"
|
||||
yn "3.1.1"
|
||||
|
||||
tslib@^1.9.3:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a"
|
||||
integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==
|
||||
|
||||
type-fest@^0.8.0:
|
||||
version "0.8.1"
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||
|
||||
typescript@3.9.3:
|
||||
version "3.9.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.3.tgz#d3ac8883a97c26139e42df5e93eeece33d610b8a"
|
||||
integrity sha512-D/wqnB2xzNFIcoBG9FG8cXRDjiqSTbG2wd8DMZeQyJlP1vfTkIxH4GKveWaEBYySKIg+USu+E+EDIR47SqnaMQ==
|
||||
|
||||
typescript@3.9.6:
|
||||
version "3.9.6"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.6.tgz#8f3e0198a34c3ae17091b35571d3afd31999365a"
|
||||
integrity sha512-Pspx3oKAPJtjNwE92YS05HQoY7z2SFyOpHo9MqJor3BXAGNaPUs83CuVp9VISFkSjyRfiTpmKuAYGJB7S7hOxw==
|
||||
|
||||
unzip-stream@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/unzip-stream/-/unzip-stream-0.3.0.tgz#c30c054cd6b0d64b13a23cd3ece911eb0b2b52d8"
|
||||
integrity sha512-NG1h/MdGIX3HzyqMjyj1laBCmlPYhcO4xEy7gEqqzGiSLw7XqDQCnY4nYSn5XSaH8mQ6TFkaujrO8d/PIZN85A==
|
||||
dependencies:
|
||||
binary "^0.3.0"
|
||||
mkdirp "^0.5.1"
|
||||
|
||||
util-deprecate@^1.0.1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
|
||||
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
|
||||
yn@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
|
||||
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
|
||||
@@ -1,8 +1,8 @@
|
||||
# `@now/next` Legacy Mode
|
||||
# `@vercel/next` Legacy Mode
|
||||
|
||||
#### Why This Warning Occurred
|
||||
|
||||
`@now/next` has two modes: `legacy` and `serverless`. You will always want to use the `serverless` mode. `legacy` is to provide backwards compatibility with previous `@now/next` versions.
|
||||
`@vercel/next` has two modes: `legacy` and `serverless`. You will always want to use the `serverless` mode. `legacy` is to provide backwards compatibility with previous `@vercel/next` versions.
|
||||
|
||||
The differences:
|
||||
|
||||
@@ -63,7 +63,7 @@ module.exports = {
|
||||
```js
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [{ "src": "package.json", "use": "@now/next" }]
|
||||
"builds": [{ "src": "package.json", "use": "@vercel/next" }]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# `@now/next` No Serverless Pages Built
|
||||
# `@vercel/next` No Serverless Pages Built
|
||||
|
||||
#### Why This Error Occurred
|
||||
|
||||
@@ -24,7 +24,7 @@ npm install next --save
|
||||
}
|
||||
```
|
||||
|
||||
3. Add `target: 'serverless'` to `next.config.js`
|
||||
3. Add `target: 'serverless'` to `next.config.js` [deprecated]
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
@@ -33,13 +33,15 @@ module.exports = {
|
||||
};
|
||||
```
|
||||
|
||||
4. Remove `distDir` from `next.config.js` as `@now/next` can't parse this file and expects your build output at `/.next`
|
||||
4. Remove `distDir` from `next.config.js` as `@vercel/next` can't parse this file and expects your build output at `/.next`
|
||||
|
||||
5. Optionally make sure the `"src"` in `"builds"` points to your application `package.json`
|
||||
|
||||
```js
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [{ "src": "package.json", "use": "@now/next" }]
|
||||
"builds": [{ "src": "package.json", "use": "@vercel/next" }]
|
||||
}
|
||||
```
|
||||
|
||||
6. Make sure you have the correct Node.js version selected for your build step in your project settings (`https://vercel.com/[username]/[project]/settings`)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"astro": "astro"
|
||||
},
|
||||
"devDependencies": {
|
||||
"astro": "^1.6.10",
|
||||
"web-vitals": "^3.1.0"
|
||||
"astro": "^2.0.6",
|
||||
"web-vitals": "^3.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
1830
examples/astro/pnpm-lock.yaml
generated
1830
examples/astro/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -2,7 +2,7 @@
|
||||
|
||||
This directory is a brief example of a [Gatsby](https://www.gatsbyjs.org/) app that can be deployed to Vercel with zero configuration.
|
||||
|
||||
> **Note:** We do not currently support some Gatsby v5 features, including API Routes and DSG. We are actively working on adding support for these features.
|
||||
> **Note:** SSR, DSG, and API Routes [are now supported](https://vercel.com/changelog/improved-support-for-gatsby-sites). We do not currently support some Gatsby v5 features, including Partial Hydration and the Slice API.
|
||||
|
||||
## Deploy Your Own
|
||||
|
||||
|
||||
@@ -9,5 +9,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"gridsome": "0.7.23"
|
||||
},
|
||||
"engines": {
|
||||
"node": "<17"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ First, run the development server:
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
# or
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
8
examples/nextjs/jsconfig.json
Normal file
8
examples/nextjs/jsconfig.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
1299
examples/nextjs/package-lock.json
generated
1299
examples/nextjs/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,10 +9,10 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@next/font": "13.1.1",
|
||||
"eslint": "8.30.0",
|
||||
"eslint-config-next": "13.1.1",
|
||||
"next": "13.1.1",
|
||||
"@next/font": "13.1.6",
|
||||
"eslint": "8.32.0",
|
||||
"eslint-config-next": "13.1.6",
|
||||
"next": "13.1.6",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import '../styles/globals.css'
|
||||
import '@/styles/globals.css'
|
||||
|
||||
export default function App({ Component, pageProps }) {
|
||||
return <Component {...pageProps} />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Head from 'next/head'
|
||||
import Image from 'next/image'
|
||||
import { Inter } from '@next/font/google'
|
||||
import styles from '../styles/Home.module.css'
|
||||
import styles from '@/styles/Home.module.css'
|
||||
|
||||
const inter = Inter({ subsets: ['latin'] })
|
||||
|
||||
|
||||
@@ -7,6 +7,6 @@
|
||||
"build": "parcel build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"parcel": "^2.0.0"
|
||||
"parcel": "^2.8.3"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -10,7 +10,7 @@
|
||||
"@remix-run/react": "^1.7.6",
|
||||
"@remix-run/vercel": "^1.7.6",
|
||||
"@vercel/analytics": "^0.1.5",
|
||||
"@vercel/node": "^2.6.3",
|
||||
"@vercel/node": "^2.7.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
@@ -20,7 +20,7 @@
|
||||
"@remix-run/serve": "^1.7.6",
|
||||
"@types/react": "^18.0.25",
|
||||
"@types/react-dom": "^18.0.9",
|
||||
"eslint": "^8.27.0",
|
||||
"eslint": "^8.28.0",
|
||||
"typescript": "^4.9.3"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
1867
examples/remix/pnpm-lock.yaml
generated
1867
examples/remix/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -12,7 +12,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "next",
|
||||
"@sveltejs/kit": "next",
|
||||
"@sveltejs/kit": "1.0.0-next.589",
|
||||
"@types/cookie": "^0.5.1",
|
||||
"prettier": "^2.6.2",
|
||||
"prettier-plugin-svelte": "^2.7.0",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"npmClient": "yarn",
|
||||
"npmClient": "pnpm",
|
||||
"useWorkspaces": true,
|
||||
"packages": ["packages/*"],
|
||||
"command": {
|
||||
|
||||
31
package.json
31
package.json
@@ -3,30 +3,25 @@
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"license": "Apache-2.0",
|
||||
"packageManager": "yarn@1.22.19",
|
||||
"workspaces": {
|
||||
"packages": [
|
||||
"packages/*"
|
||||
],
|
||||
"nohoist": [
|
||||
"**/@types/**",
|
||||
"**/typedoc",
|
||||
"**/typedoc-plugin-markdown",
|
||||
"**/typedoc-plugin-mdn-links"
|
||||
]
|
||||
},
|
||||
"packageManager": "pnpm@7.24.2",
|
||||
"dependencies": {
|
||||
"lerna": "3.16.4"
|
||||
"lerna": "5.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "14.18.33",
|
||||
"@typescript-eslint/eslint-plugin": "5.21.0",
|
||||
"@typescript-eslint/parser": "5.21.0",
|
||||
"@vercel/build-utils": "*",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"async-retry": "1.2.3",
|
||||
"buffer-replace": "1.0.0",
|
||||
"create-svelte": "2.0.1",
|
||||
"dot": "1.1.3",
|
||||
"eslint": "8.14.0",
|
||||
"eslint-config-prettier": "8.5.0",
|
||||
"eslint-plugin-jest": "26.1.5",
|
||||
"execa": "3.2.0",
|
||||
"fs-extra": "11.1.0",
|
||||
"husky": "7.0.4",
|
||||
"jest": "28.0.2",
|
||||
"json5": "2.1.1",
|
||||
@@ -34,22 +29,24 @@
|
||||
"node-fetch": "2.6.7",
|
||||
"npm-package-arg": "6.1.0",
|
||||
"prettier": "2.6.2",
|
||||
"source-map-support": "0.5.12",
|
||||
"ts-eager": "2.0.2",
|
||||
"ts-jest": "28.0.5",
|
||||
"turbo": "1.7.0-canary.9"
|
||||
"turbo": "1.7.0"
|
||||
},
|
||||
"scripts": {
|
||||
"lerna": "lerna",
|
||||
"version": "pnpm install && git add pnpm-lock.yaml",
|
||||
"bootstrap": "lerna bootstrap",
|
||||
"publish-stable": "echo 'Run `yarn changelog` for instructions'",
|
||||
"publish-stable": "echo 'Run `pnpm changelog` for instructions'",
|
||||
"publish-canary": "git checkout main && git pull && lerna version prerelease --preid canary --message \"Publish Canary\" --exact",
|
||||
"publish-from-github": "./utils/publish.sh",
|
||||
"changelog": "node utils/changelog.js",
|
||||
"build": "node utils/gen.js && turbo run build",
|
||||
"vercel-build": "yarn build && yarn run pack && cd api && node -r ts-eager/register ./_lib/script/build.ts",
|
||||
"vercel-build": "pnpm build && pnpm run pack && cd api && node -r ts-eager/register ./_lib/script/build.ts",
|
||||
"pre-commit": "lint-staged",
|
||||
"test": "jest --rootDir=\"test\" --testPathPattern=\"\\.test.js\"",
|
||||
"test-unit": "yarn test && node utils/gen.js && turbo run test-unit",
|
||||
"test-unit": "pnpm test && node utils/gen.js && turbo run test-unit",
|
||||
"test-integration-cli": "node utils/gen.js && turbo run test-integration-cli",
|
||||
"test-integration-once": "node utils/gen.js && turbo run test-integration-once",
|
||||
"test-integration-dev": "node utils/gen.js && turbo run test-integration-dev",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "5.7.5",
|
||||
"version": "6.2.1",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
@@ -13,8 +13,8 @@
|
||||
"scripts": {
|
||||
"build": "node build",
|
||||
"test": "jest --env node --verbose --runInBand --bail",
|
||||
"test-unit": "yarn test test/unit.*test.*",
|
||||
"test-integration-once": "yarn test test/integration.test.ts"
|
||||
"test-unit": "pnpm test test/unit.*test.*",
|
||||
"test-integration-once": "pnpm test test/integration.test.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iarna/toml": "2.2.3",
|
||||
@@ -25,8 +25,10 @@
|
||||
"@types/glob": "7.2.0",
|
||||
"@types/jest": "27.4.1",
|
||||
"@types/js-yaml": "3.12.1",
|
||||
"@types/minimatch": "^5.1.2",
|
||||
"@types/ms": "0.7.31",
|
||||
"@types/multistream": "2.1.1",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/node-fetch": "^2.1.6",
|
||||
"@types/semver": "6.0.0",
|
||||
"@types/yazl": "2.4.2",
|
||||
@@ -36,8 +38,10 @@
|
||||
"async-sema": "2.1.4",
|
||||
"cross-spawn": "6.0.5",
|
||||
"end-of-stream": "1.4.1",
|
||||
"execa": "3.2.0",
|
||||
"fs-extra": "10.0.0",
|
||||
"glob": "8.0.3",
|
||||
"ignore": "4.0.6",
|
||||
"into-stream": "5.0.0",
|
||||
"js-yaml": "3.13.1",
|
||||
"minimatch": "3.0.4",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Files } from './types';
|
||||
import type { Cron, Files } from './types';
|
||||
|
||||
/**
|
||||
* An Edge Functions output
|
||||
@@ -41,6 +41,9 @@ export class EdgeFunction {
|
||||
/** The regions where the edge function will be executed on */
|
||||
regions?: string | string[];
|
||||
|
||||
/** Cronjob definition for the edge function */
|
||||
cron?: Cron;
|
||||
|
||||
constructor(params: Omit<EdgeFunction, 'type'>) {
|
||||
this.type = 'EdgeFunction';
|
||||
this.name = params.name;
|
||||
@@ -50,5 +53,6 @@ export class EdgeFunction {
|
||||
this.envVarsInUse = params.envVarsInUse;
|
||||
this.assets = params.assets;
|
||||
this.regions = params.regions;
|
||||
this.cron = params.cron;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import path from 'path';
|
||||
import debug from '../debug';
|
||||
import FileFsRef from '../file-fs-ref';
|
||||
import { File, Files, Meta } from '../types';
|
||||
import { remove, mkdirp, readlink, symlink } from 'fs-extra';
|
||||
import { remove, mkdirp, readlink, symlink, chmod } from 'fs-extra';
|
||||
import streamToBuffer from './stream-to-buffer';
|
||||
|
||||
export interface DownloadedFiles {
|
||||
@@ -51,6 +51,12 @@ export async function downloadFile(
|
||||
): Promise<FileFsRef> {
|
||||
const { mode } = file;
|
||||
|
||||
if (isDirectory(mode)) {
|
||||
await mkdirp(fsPath);
|
||||
await chmod(fsPath, mode);
|
||||
return FileFsRef.fromFsPath({ mode, fsPath });
|
||||
}
|
||||
|
||||
// If the source is a symlink, try to create it instead of copying the file.
|
||||
// Note: creating symlinks on Windows requires admin priviliges or symlinks
|
||||
// enabled in the group policy. We may want to improve the error message.
|
||||
|
||||
@@ -6,7 +6,9 @@ import { lstat, Stats } from 'fs-extra';
|
||||
import { normalizePath } from './normalize-path';
|
||||
import FileFsRef from '../file-fs-ref';
|
||||
|
||||
export type GlobOptions = vanillaGlob_.IOptions;
|
||||
export interface GlobOptions extends vanillaGlob_.IOptions {
|
||||
includeDirectories?: boolean;
|
||||
}
|
||||
|
||||
const vanillaGlob = promisify(vanillaGlob_);
|
||||
|
||||
@@ -15,12 +17,7 @@ export default async function glob(
|
||||
opts: GlobOptions | string,
|
||||
mountpoint?: string
|
||||
): Promise<Record<string, FileFsRef>> {
|
||||
let options: GlobOptions;
|
||||
if (typeof opts === 'string') {
|
||||
options = { cwd: opts };
|
||||
} else {
|
||||
options = opts;
|
||||
}
|
||||
const options = typeof opts === 'string' ? { cwd: opts } : opts;
|
||||
|
||||
if (!options.cwd) {
|
||||
throw new Error(
|
||||
@@ -34,13 +31,18 @@ export default async function glob(
|
||||
|
||||
const results: Record<string, FileFsRef> = {};
|
||||
const statCache: Record<string, Stats> = {};
|
||||
const symlinks: Record<string, boolean | undefined> = {};
|
||||
|
||||
options.symlinks = {};
|
||||
options.statCache = statCache;
|
||||
options.stat = true;
|
||||
options.dot = true;
|
||||
const files = await vanillaGlob(pattern, {
|
||||
...options,
|
||||
symlinks,
|
||||
statCache,
|
||||
stat: true,
|
||||
dot: true,
|
||||
});
|
||||
|
||||
const files = await vanillaGlob(pattern, options);
|
||||
const dirs = new Set<string>();
|
||||
const dirsWithEntries = new Set<string>();
|
||||
|
||||
for (const relativePath of files) {
|
||||
const fsPath = normalizePath(path.join(options.cwd, relativePath));
|
||||
@@ -49,12 +51,20 @@ export default async function glob(
|
||||
stat,
|
||||
`statCache does not contain value for ${relativePath} (resolved to ${fsPath})`
|
||||
);
|
||||
const isSymlink = options.symlinks![fsPath];
|
||||
if (isSymlink || stat.isFile()) {
|
||||
const isSymlink = symlinks[fsPath];
|
||||
if (isSymlink || stat.isFile() || stat.isDirectory()) {
|
||||
if (isSymlink) {
|
||||
stat = await lstat(fsPath);
|
||||
}
|
||||
|
||||
// Some bookkeeping to track which directories already have entries within
|
||||
const dirname = path.dirname(relativePath);
|
||||
dirsWithEntries.add(dirname);
|
||||
if (stat.isDirectory()) {
|
||||
dirs.add(relativePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
let finalPath = relativePath;
|
||||
if (mountpoint) {
|
||||
finalPath = path.join(mountpoint, finalPath);
|
||||
@@ -64,5 +74,22 @@ export default async function glob(
|
||||
}
|
||||
}
|
||||
|
||||
// Add empty directory entries
|
||||
if (options.includeDirectories) {
|
||||
for (const relativePath of dirs) {
|
||||
if (dirsWithEntries.has(relativePath)) continue;
|
||||
|
||||
let finalPath = relativePath;
|
||||
if (mountpoint) {
|
||||
finalPath = path.join(mountpoint, finalPath);
|
||||
}
|
||||
|
||||
const fsPath = normalizePath(path.join(options.cwd, relativePath));
|
||||
const stat = statCache[fsPath];
|
||||
|
||||
results[finalPath] = new FileFsRef({ mode: stat.mode, fsPath });
|
||||
}
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import { Files } from '../types';
|
||||
type Delegate = (name: string) => string;
|
||||
|
||||
/**
|
||||
* Renames the keys of a `Files` map.
|
||||
*
|
||||
* @param files A map of filenames to `File` instances
|
||||
* @param delegate A function that returns the new filename
|
||||
* @returns A new file map with the renamed filenames
|
||||
*/
|
||||
export default function rename(files: Files, delegate: Delegate): Files {
|
||||
return Object.keys(files).reduce(
|
||||
(newFiles, name) => ({
|
||||
...newFiles,
|
||||
[delegate(name)]: files[name],
|
||||
}),
|
||||
{}
|
||||
);
|
||||
const result: Files = {};
|
||||
for (const [name, file] of Object.entries(files)) {
|
||||
result[delegate(name)] = file;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -111,53 +111,6 @@ export function spawnAsync(
|
||||
});
|
||||
}
|
||||
|
||||
export function execAsync(
|
||||
command: string,
|
||||
args: string[],
|
||||
opts: SpawnOptionsExtended = {}
|
||||
) {
|
||||
return new Promise<{ stdout: string; stderr: string; code: number }>(
|
||||
(resolve, reject) => {
|
||||
opts.stdio = 'pipe';
|
||||
|
||||
const stdoutList: Buffer[] = [];
|
||||
const stderrList: Buffer[] = [];
|
||||
|
||||
const child = spawn(command, args, opts);
|
||||
|
||||
child.stderr!.on('data', data => {
|
||||
stderrList.push(data);
|
||||
});
|
||||
|
||||
child.stdout!.on('data', data => {
|
||||
stdoutList.push(data);
|
||||
});
|
||||
|
||||
child.on('error', reject);
|
||||
child.on('close', (code, signal) => {
|
||||
if (code === 0 || opts.ignoreNon0Exit) {
|
||||
return resolve({
|
||||
code,
|
||||
stdout: Buffer.concat(stdoutList).toString(),
|
||||
stderr: Buffer.concat(stderrList).toString(),
|
||||
});
|
||||
}
|
||||
|
||||
const cmd = opts.prettyCommand
|
||||
? `Command "${opts.prettyCommand}"`
|
||||
: 'Command';
|
||||
|
||||
return reject(
|
||||
new NowBuildError({
|
||||
code: `BUILD_UTILS_EXEC_${code || signal}`,
|
||||
message: `${cmd} exited with ${code || signal}`,
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function spawnCommand(command: string, options: SpawnOptions = {}) {
|
||||
const opts = { ...options, prettyCommand: command };
|
||||
if (process.platform === 'win32') {
|
||||
@@ -246,7 +199,7 @@ export function getSpawnOptions(
|
||||
|
||||
export async function getNodeVersion(
|
||||
destPath: string,
|
||||
_nodeVersion?: string,
|
||||
nodeVersionFallback = process.env.VERCEL_PROJECT_SETTINGS_NODE_VERSION,
|
||||
config: Config = {},
|
||||
meta: Meta = {}
|
||||
): Promise<NodeVersion> {
|
||||
@@ -256,7 +209,7 @@ export async function getNodeVersion(
|
||||
return { ...latest, runtime: 'nodejs' };
|
||||
}
|
||||
const { packageJson } = await scanParentDirs(destPath, true);
|
||||
let { nodeVersion } = config;
|
||||
let nodeVersion = config.nodeVersion || nodeVersionFallback;
|
||||
let isAuto = true;
|
||||
if (packageJson?.engines?.node) {
|
||||
const { node } = packageJson.engines;
|
||||
|
||||
@@ -8,12 +8,12 @@ import download, {
|
||||
downloadFile,
|
||||
DownloadedFiles,
|
||||
isSymbolicLink,
|
||||
isDirectory,
|
||||
} from './fs/download';
|
||||
import getWriteableDirectory from './fs/get-writable-directory';
|
||||
import glob, { GlobOptions } from './fs/glob';
|
||||
import rename from './fs/rename';
|
||||
import {
|
||||
execAsync,
|
||||
spawnAsync,
|
||||
execCommand,
|
||||
spawnCommand,
|
||||
@@ -58,7 +58,6 @@ export {
|
||||
glob,
|
||||
GlobOptions,
|
||||
rename,
|
||||
execAsync,
|
||||
spawnAsync,
|
||||
getScriptName,
|
||||
installDependencies,
|
||||
@@ -82,6 +81,7 @@ export {
|
||||
streamToBuffer,
|
||||
debug,
|
||||
isSymbolicLink,
|
||||
isDirectory,
|
||||
getLambdaOptionsFromFunction,
|
||||
scanParentDirs,
|
||||
getIgnoreFilter,
|
||||
|
||||
@@ -5,7 +5,7 @@ import minimatch from 'minimatch';
|
||||
import { readlink } from 'fs-extra';
|
||||
import { isSymbolicLink, isDirectory } from './fs/download';
|
||||
import streamToBuffer from './fs/stream-to-buffer';
|
||||
import type { Files, Config } from './types';
|
||||
import type { Files, Config, Cron } from './types';
|
||||
|
||||
interface Environment {
|
||||
[key: string]: string;
|
||||
@@ -25,6 +25,7 @@ export interface LambdaOptionsBase {
|
||||
supportsWrapper?: boolean;
|
||||
experimentalResponseStreaming?: boolean;
|
||||
operationType?: string;
|
||||
cron?: Cron;
|
||||
}
|
||||
|
||||
export interface LambdaOptionsWithFiles extends LambdaOptionsBase {
|
||||
@@ -62,6 +63,7 @@ export class Lambda {
|
||||
environment: Environment;
|
||||
allowQuery?: string[];
|
||||
regions?: string[];
|
||||
cron?: Cron;
|
||||
/**
|
||||
* @deprecated Use `await lambda.createZip()` instead.
|
||||
*/
|
||||
@@ -79,6 +81,7 @@ export class Lambda {
|
||||
environment = {},
|
||||
allowQuery,
|
||||
regions,
|
||||
cron,
|
||||
supportsMultiPayloads,
|
||||
supportsWrapper,
|
||||
experimentalResponseStreaming,
|
||||
@@ -132,6 +135,10 @@ export class Lambda {
|
||||
);
|
||||
}
|
||||
|
||||
if (cron !== undefined) {
|
||||
assert(typeof cron === 'string', '"cron" is not a string');
|
||||
}
|
||||
|
||||
this.type = 'Lambda';
|
||||
this.operationType = operationType;
|
||||
this.files = 'files' in opts ? opts.files : undefined;
|
||||
@@ -142,6 +149,7 @@ export class Lambda {
|
||||
this.environment = environment;
|
||||
this.allowQuery = allowQuery;
|
||||
this.regions = regions;
|
||||
this.cron = cron;
|
||||
this.zipBuffer = 'zipBuffer' in opts ? opts.zipBuffer : undefined;
|
||||
this.supportsMultiPayloads = supportsMultiPayloads;
|
||||
this.supportsWrapper = supportsWrapper;
|
||||
@@ -220,7 +228,7 @@ export async function getLambdaOptionsFromFunction({
|
||||
sourceFile,
|
||||
config,
|
||||
}: GetLambdaOptionsFromFunctionOptions): Promise<
|
||||
Pick<LambdaOptions, 'memory' | 'maxDuration'>
|
||||
Pick<LambdaOptions, 'memory' | 'maxDuration' | 'cron'>
|
||||
> {
|
||||
if (config?.functions) {
|
||||
for (const [pattern, fn] of Object.entries(config.functions)) {
|
||||
@@ -228,6 +236,7 @@ export async function getLambdaOptionsFromFunction({
|
||||
return {
|
||||
memory: fn.memory,
|
||||
maxDuration: fn.maxDuration,
|
||||
cron: fn.cron,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ interface PrerenderOptions {
|
||||
allowQuery?: string[];
|
||||
initialHeaders?: Record<string, string>;
|
||||
initialStatus?: number;
|
||||
passQuery?: boolean;
|
||||
}
|
||||
|
||||
export class Prerender {
|
||||
@@ -22,6 +23,7 @@ export class Prerender {
|
||||
public allowQuery?: string[];
|
||||
public initialHeaders?: Record<string, string>;
|
||||
public initialStatus?: number;
|
||||
public passQuery?: boolean;
|
||||
|
||||
constructor({
|
||||
expiration,
|
||||
@@ -32,6 +34,7 @@ export class Prerender {
|
||||
allowQuery,
|
||||
initialHeaders,
|
||||
initialStatus,
|
||||
passQuery,
|
||||
}: PrerenderOptions) {
|
||||
this.type = 'Prerender';
|
||||
this.expiration = expiration;
|
||||
@@ -52,6 +55,17 @@ export class Prerender {
|
||||
}
|
||||
this.group = group;
|
||||
|
||||
if (passQuery === true) {
|
||||
this.passQuery = true;
|
||||
} else if (
|
||||
typeof passQuery !== 'boolean' &&
|
||||
typeof passQuery !== 'undefined'
|
||||
) {
|
||||
throw new Error(
|
||||
`The \`passQuery\` argument for \`Prerender\` must be a boolean.`
|
||||
);
|
||||
}
|
||||
|
||||
if (bypassToken == null) {
|
||||
this.bypassToken = null;
|
||||
} else if (typeof bypassToken === 'string') {
|
||||
|
||||
@@ -31,6 +31,11 @@ export const functionsSchema = {
|
||||
type: 'string',
|
||||
maxLength: 256,
|
||||
},
|
||||
cron: {
|
||||
type: 'string',
|
||||
minLength: 9,
|
||||
maxLength: 256,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -319,6 +319,7 @@ export interface BuilderFunctions {
|
||||
runtime?: string;
|
||||
includeFiles?: string;
|
||||
excludeFiles?: string;
|
||||
cron?: Cron;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -410,6 +411,8 @@ export interface BuildResultBuildOutput {
|
||||
buildOutputPath: string;
|
||||
}
|
||||
|
||||
export type Cron = string;
|
||||
|
||||
/**
|
||||
* When a Builder implements `version: 2`, the `build()` function is expected
|
||||
* to return this type.
|
||||
|
||||
3
packages/build-utils/test/fixtures/15-npm-8-legacy-peer-deps/package-lock.json
generated
vendored
3
packages/build-utils/test/fixtures/15-npm-8-legacy-peer-deps/package-lock.json
generated
vendored
@@ -7,6 +7,9 @@
|
||||
"dependencies": {
|
||||
"react": "16.8.0",
|
||||
"swr": "1.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "16.x"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "a",
|
||||
"name": "a21",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "b",
|
||||
"name": "b21",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "21-npm-workspaces",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"workspaces": [
|
||||
"a",
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
{
|
||||
"name": "22-pnpm",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "mkdir -p public && (printf \"pnpm version: \" && pnpm -v) > public/index.txt"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "c",
|
||||
"name": "build-c23",
|
||||
"license": "MIT",
|
||||
"version": "0.1.0"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "d",
|
||||
"name": "build-d23",
|
||||
"license": "MIT",
|
||||
"version": "0.1.0",
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"private": "true",
|
||||
"name": "24-pnpm-hoisted",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "ls -Al node_modules && node index.js"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "a",
|
||||
"name": "build-a25",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "b",
|
||||
"name": "build-b25",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"private": "true",
|
||||
"name": "25-multiple-lock-files-yarn",
|
||||
"private": true,
|
||||
"workspaces": [
|
||||
"a",
|
||||
"b"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "a",
|
||||
"name": "build-a26",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "b",
|
||||
"name": "build-b26",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"private": "true",
|
||||
"name": "26-multiple-lock-files-pnpm",
|
||||
"private": true,
|
||||
"workspaces": [
|
||||
"a",
|
||||
"b"
|
||||
|
||||
195
packages/build-utils/test/unit.download.test.ts
vendored
Normal file
195
packages/build-utils/test/unit.download.test.ts
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
import path from 'path';
|
||||
import fs, { readlink } from 'fs-extra';
|
||||
import { strict as assert, strictEqual } from 'assert';
|
||||
import { download, glob, FileBlob } from '../src';
|
||||
|
||||
describe('download()', () => {
|
||||
let warningMessages: string[];
|
||||
const originalConsoleWarn = console.warn;
|
||||
beforeEach(() => {
|
||||
warningMessages = [];
|
||||
console.warn = m => {
|
||||
warningMessages.push(m);
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
console.warn = originalConsoleWarn;
|
||||
});
|
||||
|
||||
it('should re-create FileFsRef symlinks properly', async () => {
|
||||
if (process.platform === 'win32') {
|
||||
console.log('Skipping test on windows');
|
||||
return;
|
||||
}
|
||||
const files = await glob('**', path.join(__dirname, 'symlinks'));
|
||||
assert.equal(Object.keys(files).length, 4);
|
||||
|
||||
const outDir = path.join(__dirname, 'symlinks-out');
|
||||
await fs.remove(outDir);
|
||||
|
||||
const files2 = await download(files, outDir);
|
||||
assert.equal(Object.keys(files2).length, 4);
|
||||
|
||||
const [linkStat, linkDirStat, aStat] = await Promise.all([
|
||||
fs.lstat(path.join(outDir, 'link.txt')),
|
||||
fs.lstat(path.join(outDir, 'link-dir')),
|
||||
fs.lstat(path.join(outDir, 'a.txt')),
|
||||
]);
|
||||
assert(linkStat.isSymbolicLink());
|
||||
assert(linkDirStat.isSymbolicLink());
|
||||
assert(aStat.isFile());
|
||||
|
||||
const [linkDirContents, linkTextContents] = await Promise.all([
|
||||
readlink(path.join(outDir, 'link-dir')),
|
||||
readlink(path.join(outDir, 'link.txt')),
|
||||
]);
|
||||
|
||||
strictEqual(linkDirContents, 'dir');
|
||||
strictEqual(linkTextContents, './a.txt');
|
||||
});
|
||||
|
||||
it('should re-create FileBlob symlinks properly', async () => {
|
||||
if (process.platform === 'win32') {
|
||||
console.log('Skipping test on windows');
|
||||
return;
|
||||
}
|
||||
|
||||
const files = {
|
||||
'a.txt': new FileBlob({
|
||||
mode: 33188,
|
||||
contentType: undefined,
|
||||
data: 'a text',
|
||||
}),
|
||||
'dir/b.txt': new FileBlob({
|
||||
mode: 33188,
|
||||
contentType: undefined,
|
||||
data: 'b text',
|
||||
}),
|
||||
'link-dir': new FileBlob({
|
||||
mode: 41453,
|
||||
contentType: undefined,
|
||||
data: 'dir',
|
||||
}),
|
||||
'link.txt': new FileBlob({
|
||||
mode: 41453,
|
||||
contentType: undefined,
|
||||
data: 'a.txt',
|
||||
}),
|
||||
};
|
||||
|
||||
strictEqual(Object.keys(files).length, 4);
|
||||
|
||||
const outDir = path.join(__dirname, 'symlinks-out');
|
||||
await fs.remove(outDir);
|
||||
|
||||
const files2 = await download(files, outDir);
|
||||
strictEqual(Object.keys(files2).length, 4);
|
||||
|
||||
const [linkStat, linkDirStat, aStat, dirStat] = await Promise.all([
|
||||
fs.lstat(path.join(outDir, 'link.txt')),
|
||||
fs.lstat(path.join(outDir, 'link-dir')),
|
||||
fs.lstat(path.join(outDir, 'a.txt')),
|
||||
fs.lstat(path.join(outDir, 'dir')),
|
||||
]);
|
||||
|
||||
assert(linkStat.isSymbolicLink());
|
||||
assert(linkDirStat.isSymbolicLink());
|
||||
assert(aStat.isFile());
|
||||
assert(dirStat.isDirectory());
|
||||
|
||||
const [linkDirContents, linkTextContents] = await Promise.all([
|
||||
readlink(path.join(outDir, 'link-dir')),
|
||||
readlink(path.join(outDir, 'link.txt')),
|
||||
]);
|
||||
|
||||
strictEqual(linkDirContents, 'dir');
|
||||
strictEqual(linkTextContents, 'a.txt');
|
||||
});
|
||||
|
||||
it('should download symlinks even with incorrect file', async () => {
|
||||
if (process.platform === 'win32') {
|
||||
console.log('Skipping test on windows');
|
||||
return;
|
||||
}
|
||||
const files = {
|
||||
'dir/file.txt': new FileBlob({
|
||||
mode: 33188,
|
||||
contentType: undefined,
|
||||
data: 'file text',
|
||||
}),
|
||||
linkdir: new FileBlob({
|
||||
mode: 41453,
|
||||
contentType: undefined,
|
||||
data: 'dir',
|
||||
}),
|
||||
'linkdir/file.txt': new FileBlob({
|
||||
mode: 33188,
|
||||
contentType: undefined,
|
||||
data: 'this file should be discarded',
|
||||
}),
|
||||
};
|
||||
|
||||
const outDir = path.join(__dirname, 'symlinks-out');
|
||||
await fs.remove(outDir);
|
||||
await fs.mkdirp(outDir);
|
||||
|
||||
await download(files, outDir);
|
||||
|
||||
const [dir, file, linkdir] = await Promise.all([
|
||||
fs.lstat(path.join(outDir, 'dir')),
|
||||
fs.lstat(path.join(outDir, 'dir/file.txt')),
|
||||
fs.lstat(path.join(outDir, 'linkdir')),
|
||||
]);
|
||||
expect(dir.isFile()).toBe(false);
|
||||
expect(dir.isSymbolicLink()).toBe(false);
|
||||
|
||||
expect(file.isFile()).toBe(true);
|
||||
expect(file.isSymbolicLink()).toBe(false);
|
||||
|
||||
expect(linkdir.isSymbolicLink()).toBe(true);
|
||||
|
||||
expect(warningMessages).toEqual([
|
||||
'Warning: file "linkdir/file.txt" is within a symlinked directory "linkdir" and will be ignored',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should create empty directory entries', async () => {
|
||||
const outDir = path.join(__dirname, 'symlinks-out');
|
||||
await fs.remove(outDir);
|
||||
const files = {
|
||||
'empty-dir': new FileBlob({
|
||||
mode: 16877, // drwxr-xr-x
|
||||
contentType: undefined,
|
||||
data: '',
|
||||
}),
|
||||
dir: new FileBlob({
|
||||
mode: 16877,
|
||||
contentType: undefined,
|
||||
data: '',
|
||||
}),
|
||||
'dir/subdir': new FileBlob({
|
||||
mode: 16877,
|
||||
contentType: undefined,
|
||||
data: '',
|
||||
}),
|
||||
'another/subdir': new FileBlob({
|
||||
mode: 16895, // drwxrwxrwx
|
||||
contentType: undefined,
|
||||
data: '',
|
||||
}),
|
||||
};
|
||||
|
||||
await download(files, outDir);
|
||||
|
||||
for (const [p, f] of Object.entries(files)) {
|
||||
const stat = await fs.lstat(path.join(outDir, p));
|
||||
expect(stat.isDirectory()).toEqual(true);
|
||||
|
||||
if (process.platform !== 'win32') {
|
||||
// Don't test Windows since it doesn't support the same permissions
|
||||
expect(stat.mode).toEqual(f.mode);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,29 +0,0 @@
|
||||
import { execAsync, NowBuildError } from '../src';
|
||||
|
||||
it('should execute a command', async () => {
|
||||
const { code, stdout, stderr } = await execAsync('echo', ['hello']);
|
||||
|
||||
expect(code).toBe(0);
|
||||
expect(stdout).toContain('hello');
|
||||
expect(stderr).toBe('');
|
||||
});
|
||||
|
||||
it('should throw if the command exits with non-0 code', async () => {
|
||||
await expect(execAsync('find', ['unknown-file'])).rejects.toBeInstanceOf(
|
||||
NowBuildError
|
||||
);
|
||||
});
|
||||
|
||||
it('should return if the command exits with non-0 code and ignoreNon0Exit=true', async () => {
|
||||
const { code, stdout, stderr } = await execAsync('find', ['unknown-file'], {
|
||||
ignoreNon0Exit: true,
|
||||
});
|
||||
|
||||
expect(code).toBe(process.platform === 'win32' ? 2 : 1);
|
||||
expect(stdout).toBe('');
|
||||
expect(stderr).toContain(
|
||||
process.platform === 'win32'
|
||||
? 'Parameter format not correct'
|
||||
: 'No such file or directory'
|
||||
);
|
||||
});
|
||||
65
packages/build-utils/test/unit.glob.test.ts
vendored
Normal file
65
packages/build-utils/test/unit.glob.test.ts
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
import fs from 'fs-extra';
|
||||
import { join } from 'path';
|
||||
import { tmpdir } from 'os';
|
||||
import { glob, isDirectory } from '../src';
|
||||
|
||||
describe('glob()', () => {
|
||||
it('should not return entries for empty directories by default', async () => {
|
||||
const dir = await fs.mkdtemp(join(tmpdir(), 'build-utils-test'));
|
||||
try {
|
||||
await Promise.all([
|
||||
fs.writeFile(join(dir, 'root.txt'), 'file at the root'),
|
||||
fs.mkdirp(join(dir, 'empty-dir')),
|
||||
fs
|
||||
.mkdirp(join(dir, 'dir-with-file'))
|
||||
.then(() =>
|
||||
fs.writeFile(join(dir, 'dir-with-file/data.json'), '{"a":"b"}')
|
||||
),
|
||||
fs.mkdirp(join(dir, 'another/subdir')),
|
||||
]);
|
||||
const files = await glob('**', dir);
|
||||
const fileNames = Object.keys(files).sort();
|
||||
expect(fileNames).toHaveLength(2);
|
||||
expect(fileNames).toEqual(['dir-with-file/data.json', 'root.txt']);
|
||||
expect(isDirectory(files['dir-with-file/data.json'].mode)).toEqual(false);
|
||||
expect(isDirectory(files['root.txt'].mode)).toEqual(false);
|
||||
expect(files['dir-with-file']).toBeUndefined();
|
||||
expect(files['another/subdir']).toBeUndefined();
|
||||
expect(files['empty-dir']).toBeUndefined();
|
||||
} finally {
|
||||
await fs.remove(dir);
|
||||
}
|
||||
});
|
||||
|
||||
it('should return entries for empty directories with `includeDirectories: true`', async () => {
|
||||
const dir = await fs.mkdtemp(join(tmpdir(), 'build-utils-test'));
|
||||
try {
|
||||
await Promise.all([
|
||||
fs.writeFile(join(dir, 'root.txt'), 'file at the root'),
|
||||
fs.mkdirp(join(dir, 'empty-dir')),
|
||||
fs
|
||||
.mkdirp(join(dir, 'dir-with-file'))
|
||||
.then(() =>
|
||||
fs.writeFile(join(dir, 'dir-with-file/data.json'), '{"a":"b"}')
|
||||
),
|
||||
fs.mkdirp(join(dir, 'another/subdir')),
|
||||
]);
|
||||
const files = await glob('**', { cwd: dir, includeDirectories: true });
|
||||
const fileNames = Object.keys(files).sort();
|
||||
expect(fileNames).toHaveLength(4);
|
||||
expect(fileNames).toEqual([
|
||||
'another/subdir',
|
||||
'dir-with-file/data.json',
|
||||
'empty-dir',
|
||||
'root.txt',
|
||||
]);
|
||||
expect(isDirectory(files['another/subdir'].mode)).toEqual(true);
|
||||
expect(isDirectory(files['empty-dir'].mode)).toEqual(true);
|
||||
expect(isDirectory(files['dir-with-file/data.json'].mode)).toEqual(false);
|
||||
expect(isDirectory(files['root.txt'].mode)).toEqual(false);
|
||||
expect(files['dir-with-file']).toBeUndefined();
|
||||
} finally {
|
||||
await fs.remove(dir);
|
||||
}
|
||||
});
|
||||
});
|
||||
255
packages/build-utils/test/unit.test.ts
vendored
255
packages/build-utils/test/unit.test.ts
vendored
@@ -1,20 +1,20 @@
|
||||
import ms from 'ms';
|
||||
import path from 'path';
|
||||
import fs, { readlink } from 'fs-extra';
|
||||
import { strict as assert, strictEqual } from 'assert';
|
||||
import fs from 'fs-extra';
|
||||
import { strict as assert } from 'assert';
|
||||
import { getSupportedNodeVersion } from '../src/fs/node-version';
|
||||
import download from '../src/fs/download';
|
||||
import {
|
||||
glob,
|
||||
FileBlob,
|
||||
getNodeVersion,
|
||||
getLatestNodeVersion,
|
||||
getDiscontinuedNodeVersions,
|
||||
rename,
|
||||
runNpmInstall,
|
||||
runPackageJsonScript,
|
||||
scanParentDirs,
|
||||
FileBlob,
|
||||
Prerender,
|
||||
} from '../src';
|
||||
import type { Files } from '../src';
|
||||
|
||||
jest.setTimeout(10 * 1000);
|
||||
|
||||
@@ -49,143 +49,6 @@ afterEach(() => {
|
||||
console.warn = originalConsoleWarn;
|
||||
});
|
||||
|
||||
it('should re-create FileFsRef symlinks properly', async () => {
|
||||
if (process.platform === 'win32') {
|
||||
console.log('Skipping test on windows');
|
||||
return;
|
||||
}
|
||||
const files = await glob('**', path.join(__dirname, 'symlinks'));
|
||||
assert.equal(Object.keys(files).length, 4);
|
||||
|
||||
const outDir = path.join(__dirname, 'symlinks-out');
|
||||
await fs.remove(outDir);
|
||||
|
||||
const files2 = await download(files, outDir);
|
||||
assert.equal(Object.keys(files2).length, 4);
|
||||
|
||||
const [linkStat, linkDirStat, aStat] = await Promise.all([
|
||||
fs.lstat(path.join(outDir, 'link.txt')),
|
||||
fs.lstat(path.join(outDir, 'link-dir')),
|
||||
fs.lstat(path.join(outDir, 'a.txt')),
|
||||
]);
|
||||
assert(linkStat.isSymbolicLink());
|
||||
assert(linkDirStat.isSymbolicLink());
|
||||
assert(aStat.isFile());
|
||||
|
||||
const [linkDirContents, linkTextContents] = await Promise.all([
|
||||
readlink(path.join(outDir, 'link-dir')),
|
||||
readlink(path.join(outDir, 'link.txt')),
|
||||
]);
|
||||
|
||||
strictEqual(linkDirContents, 'dir');
|
||||
strictEqual(linkTextContents, './a.txt');
|
||||
});
|
||||
|
||||
it('should re-create FileBlob symlinks properly', async () => {
|
||||
if (process.platform === 'win32') {
|
||||
console.log('Skipping test on windows');
|
||||
return;
|
||||
}
|
||||
|
||||
const files = {
|
||||
'a.txt': new FileBlob({
|
||||
mode: 33188,
|
||||
contentType: undefined,
|
||||
data: 'a text',
|
||||
}),
|
||||
'dir/b.txt': new FileBlob({
|
||||
mode: 33188,
|
||||
contentType: undefined,
|
||||
data: 'b text',
|
||||
}),
|
||||
'link-dir': new FileBlob({
|
||||
mode: 41453,
|
||||
contentType: undefined,
|
||||
data: 'dir',
|
||||
}),
|
||||
'link.txt': new FileBlob({
|
||||
mode: 41453,
|
||||
contentType: undefined,
|
||||
data: 'a.txt',
|
||||
}),
|
||||
};
|
||||
|
||||
strictEqual(Object.keys(files).length, 4);
|
||||
|
||||
const outDir = path.join(__dirname, 'symlinks-out');
|
||||
await fs.remove(outDir);
|
||||
|
||||
const files2 = await download(files, outDir);
|
||||
strictEqual(Object.keys(files2).length, 4);
|
||||
|
||||
const [linkStat, linkDirStat, aStat, dirStat] = await Promise.all([
|
||||
fs.lstat(path.join(outDir, 'link.txt')),
|
||||
fs.lstat(path.join(outDir, 'link-dir')),
|
||||
fs.lstat(path.join(outDir, 'a.txt')),
|
||||
fs.lstat(path.join(outDir, 'dir')),
|
||||
]);
|
||||
|
||||
assert(linkStat.isSymbolicLink());
|
||||
assert(linkDirStat.isSymbolicLink());
|
||||
assert(aStat.isFile());
|
||||
assert(dirStat.isDirectory());
|
||||
|
||||
const [linkDirContents, linkTextContents] = await Promise.all([
|
||||
readlink(path.join(outDir, 'link-dir')),
|
||||
readlink(path.join(outDir, 'link.txt')),
|
||||
]);
|
||||
|
||||
strictEqual(linkDirContents, 'dir');
|
||||
strictEqual(linkTextContents, 'a.txt');
|
||||
});
|
||||
|
||||
it('should download symlinks even with incorrect file', async () => {
|
||||
if (process.platform === 'win32') {
|
||||
console.log('Skipping test on windows');
|
||||
return;
|
||||
}
|
||||
const files = {
|
||||
'dir/file.txt': new FileBlob({
|
||||
mode: 33188,
|
||||
contentType: undefined,
|
||||
data: 'file text',
|
||||
}),
|
||||
linkdir: new FileBlob({
|
||||
mode: 41453,
|
||||
contentType: undefined,
|
||||
data: 'dir',
|
||||
}),
|
||||
'linkdir/file.txt': new FileBlob({
|
||||
mode: 33188,
|
||||
contentType: undefined,
|
||||
data: 'this file should be discarded',
|
||||
}),
|
||||
};
|
||||
|
||||
const outDir = path.join(__dirname, 'symlinks-out');
|
||||
await fs.remove(outDir);
|
||||
await fs.mkdirp(outDir);
|
||||
|
||||
await download(files, outDir);
|
||||
|
||||
const [dir, file, linkdir] = await Promise.all([
|
||||
fs.lstat(path.join(outDir, 'dir')),
|
||||
fs.lstat(path.join(outDir, 'dir/file.txt')),
|
||||
fs.lstat(path.join(outDir, 'linkdir')),
|
||||
]);
|
||||
expect(dir.isFile()).toBe(false);
|
||||
expect(dir.isSymbolicLink()).toBe(false);
|
||||
|
||||
expect(file.isFile()).toBe(true);
|
||||
expect(file.isSymbolicLink()).toBe(false);
|
||||
|
||||
expect(linkdir.isSymbolicLink()).toBe(true);
|
||||
|
||||
expect(warningMessages).toEqual([
|
||||
'Warning: file "linkdir/file.txt" is within a symlinked directory "linkdir" and will be ignored',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should only match supported node versions, otherwise throw an error', async () => {
|
||||
expect(await getSupportedNodeVersion('14.x', false)).toHaveProperty(
|
||||
'major',
|
||||
@@ -275,13 +138,25 @@ it('should ignore node version in vercel dev getNodeVersion()', async () => {
|
||||
).toHaveProperty('runtime', 'nodejs');
|
||||
});
|
||||
|
||||
it('should select project setting from config when no package.json is found', async () => {
|
||||
it('should select project setting from config when no package.json is found and fallback undefined', async () => {
|
||||
expect(
|
||||
await getNodeVersion('/tmp', undefined, { nodeVersion: '16.x' }, {})
|
||||
).toHaveProperty('range', '16.x');
|
||||
expect(warningMessages).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('should select project setting from config when no package.json is found and fallback is null', async () => {
|
||||
expect(
|
||||
await getNodeVersion('/tmp', null as any, { nodeVersion: '16.x' }, {})
|
||||
).toHaveProperty('range', '16.x');
|
||||
expect(warningMessages).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('should select project setting from fallback when no package.json is found', async () => {
|
||||
expect(await getNodeVersion('/tmp', '16.x')).toHaveProperty('range', '16.x');
|
||||
expect(warningMessages).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('should prefer package.json engines over project setting from config and warn', async () => {
|
||||
expect(
|
||||
await getNodeVersion(
|
||||
@@ -443,22 +318,65 @@ it('should support initialHeaders and initialStatus correctly', async () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should support require by path for legacy builders', () => {
|
||||
const index = require('@vercel/build-utils');
|
||||
it('should support passQuery correctly', async () => {
|
||||
new Prerender({
|
||||
expiration: 1,
|
||||
fallback: null,
|
||||
group: 1,
|
||||
bypassToken: 'some-long-bypass-token-to-make-it-work',
|
||||
passQuery: true,
|
||||
});
|
||||
new Prerender({
|
||||
expiration: 1,
|
||||
fallback: null,
|
||||
group: 1,
|
||||
bypassToken: 'some-long-bypass-token-to-make-it-work',
|
||||
passQuery: false,
|
||||
});
|
||||
new Prerender({
|
||||
expiration: 1,
|
||||
fallback: null,
|
||||
group: 1,
|
||||
bypassToken: 'some-long-bypass-token-to-make-it-work',
|
||||
passQuery: undefined,
|
||||
});
|
||||
new Prerender({
|
||||
expiration: 1,
|
||||
fallback: null,
|
||||
group: 1,
|
||||
bypassToken: 'some-long-bypass-token-to-make-it-work',
|
||||
});
|
||||
|
||||
const download2 = require('@vercel/build-utils/fs/download.js');
|
||||
const getWriteableDirectory2 = require('@vercel/build-utils/fs/get-writable-directory.js');
|
||||
const glob2 = require('@vercel/build-utils/fs/glob.js');
|
||||
const rename2 = require('@vercel/build-utils/fs/rename.js');
|
||||
expect(() => {
|
||||
new Prerender({
|
||||
expiration: 1,
|
||||
fallback: null,
|
||||
group: 1,
|
||||
bypassToken: 'some-long-bypass-token-to-make-it-work',
|
||||
// @ts-expect-error testing invalid field
|
||||
passQuery: 'true',
|
||||
});
|
||||
}).toThrowError(
|
||||
`The \`passQuery\` argument for \`Prerender\` must be a boolean.`
|
||||
);
|
||||
});
|
||||
|
||||
it('should support require by path for legacy builders', () => {
|
||||
const index = require('../');
|
||||
|
||||
const download2 = require('../fs/download.js');
|
||||
const getWriteableDirectory2 = require('../fs/get-writable-directory.js');
|
||||
const glob2 = require('../fs/glob.js');
|
||||
const rename2 = require('../fs/rename.js');
|
||||
const {
|
||||
runNpmInstall: runNpmInstall2,
|
||||
} = require('@vercel/build-utils/fs/run-user-scripts.js');
|
||||
const streamToBuffer2 = require('@vercel/build-utils/fs/stream-to-buffer.js');
|
||||
} = require('../fs/run-user-scripts.js');
|
||||
const streamToBuffer2 = require('../fs/stream-to-buffer.js');
|
||||
|
||||
const FileBlob2 = require('@vercel/build-utils/file-blob.js');
|
||||
const FileFsRef2 = require('@vercel/build-utils/file-fs-ref.js');
|
||||
const FileRef2 = require('@vercel/build-utils/file-ref.js');
|
||||
const { Lambda: Lambda2 } = require('@vercel/build-utils/lambda.js');
|
||||
const FileBlob2 = require('../file-blob.js');
|
||||
const FileFsRef2 = require('../file-fs-ref.js');
|
||||
const FileRef2 = require('../file-ref.js');
|
||||
const { Lambda: Lambda2 } = require('../lambda.js');
|
||||
|
||||
expect(download2).toBe(index.download);
|
||||
expect(getWriteableDirectory2).toBe(index.getWriteableDirectory);
|
||||
@@ -560,9 +478,9 @@ it('should detect package.json in nested backend', async () => {
|
||||
'../../node/test/fixtures/18.1-nested-packagejson/backend'
|
||||
);
|
||||
const result = await scanParentDirs(fixture);
|
||||
expect(result.cliType).toEqual('yarn');
|
||||
expect(result.lockfileVersion).toEqual(undefined);
|
||||
// There is no lockfile but this test will pick up vercel/vercel/yarn.lock
|
||||
expect(result.cliType).toEqual('pnpm');
|
||||
// There is no lockfile but this test will pick up vercel/vercel/pnpm-lock.yaml
|
||||
expect(result.lockfileVersion).toEqual(5.4);
|
||||
expect(result.packageJsonPath).toEqual(path.join(fixture, 'package.json'));
|
||||
});
|
||||
|
||||
@@ -572,9 +490,9 @@ it('should detect package.json in nested frontend', async () => {
|
||||
'../../node/test/fixtures/18.1-nested-packagejson/frontend'
|
||||
);
|
||||
const result = await scanParentDirs(fixture);
|
||||
expect(result.cliType).toEqual('yarn');
|
||||
expect(result.lockfileVersion).toEqual(undefined);
|
||||
// There is no lockfile but this test will pick up vercel/vercel/yarn.lock
|
||||
expect(result.cliType).toEqual('pnpm');
|
||||
// There is no lockfile but this test will pick up vercel/vercel/pnpm-lock.yaml
|
||||
expect(result.lockfileVersion).toEqual(5.4);
|
||||
expect(result.packageJsonPath).toEqual(path.join(fixture, 'package.json'));
|
||||
});
|
||||
|
||||
@@ -591,3 +509,18 @@ it('should retry npm install when peer deps invalid and npm@8 on node@16', async
|
||||
'Warning: Retrying "Install Command" with `--legacy-peer-deps` which may accept a potentially broken dependency and slow install time.',
|
||||
]);
|
||||
});
|
||||
|
||||
describe('rename', () => {
|
||||
it('should rename keys of files map', () => {
|
||||
const before: Files = {};
|
||||
const toUpper = (s: string) => s.toUpperCase();
|
||||
|
||||
for (let i = 97; i <= 122; i++) {
|
||||
const key = String.fromCharCode(i);
|
||||
before[key] = new FileBlob({ contentType: 'text/plain', data: key });
|
||||
}
|
||||
|
||||
const after = rename(before, toUpper);
|
||||
expect(Object.keys(after)).toEqual('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''));
|
||||
});
|
||||
});
|
||||
|
||||
14
packages/build-utils/test/unit.walk.test.ts
vendored
14
packages/build-utils/test/unit.walk.test.ts
vendored
@@ -2,7 +2,7 @@ import { walkParentDirs } from '../src';
|
||||
import { strict } from 'assert';
|
||||
import { join } from 'path';
|
||||
import { promises } from 'fs';
|
||||
const { deepEqual, notDeepEqual, fail } = strict;
|
||||
const { notDeepEqual, fail } = strict;
|
||||
const { readFile } = promises;
|
||||
const fixture = (name: string) => join(__dirname, 'walk', name);
|
||||
const filename = 'file.txt';
|
||||
@@ -10,7 +10,7 @@ const filename = 'file.txt';
|
||||
async function assertContent(target: string | null, contents: string) {
|
||||
notDeepEqual(target, null);
|
||||
const actual = await readFile(target!, 'utf8');
|
||||
deepEqual(actual.trim(), contents.trim());
|
||||
strict.deepEqual(actual.trim(), contents.trim());
|
||||
}
|
||||
|
||||
describe('Test `walkParentDirs`', () => {
|
||||
@@ -21,7 +21,7 @@ describe('Test `walkParentDirs`', () => {
|
||||
await walkParentDirs({ base, start, filename });
|
||||
fail('Expected error');
|
||||
} catch (error) {
|
||||
deepEqual(
|
||||
strict.deepEqual(
|
||||
(error as Error).message,
|
||||
'Expected "base" to be absolute path'
|
||||
);
|
||||
@@ -35,7 +35,7 @@ describe('Test `walkParentDirs`', () => {
|
||||
await walkParentDirs({ base, start, filename });
|
||||
fail('Expected error');
|
||||
} catch (error) {
|
||||
deepEqual(
|
||||
strict.deepEqual(
|
||||
(error as Error).message,
|
||||
'Expected "start" to be absolute path'
|
||||
);
|
||||
@@ -67,21 +67,21 @@ describe('Test `walkParentDirs`', () => {
|
||||
const base = fixture('not-found');
|
||||
const start = base;
|
||||
const target = await walkParentDirs({ base, start, filename });
|
||||
deepEqual(target, null);
|
||||
strict.deepEqual(target, null);
|
||||
});
|
||||
|
||||
it('should not find nested two', async () => {
|
||||
const base = fixture('not-found');
|
||||
const start = join(base, 'two');
|
||||
const target = await walkParentDirs({ base, start, filename });
|
||||
deepEqual(target, null);
|
||||
strict.deepEqual(target, null);
|
||||
});
|
||||
|
||||
it('should not find nested three', async () => {
|
||||
const base = fixture('not-found');
|
||||
const start = join(base, 'two', 'three');
|
||||
const target = await walkParentDirs({ base, start, filename });
|
||||
deepEqual(target, null);
|
||||
strict.deepEqual(target, null);
|
||||
});
|
||||
|
||||
it('should find only one', async () => {
|
||||
|
||||
@@ -41,8 +41,8 @@ To develop Vercel CLI, first check out the source code, install dependencies, an
|
||||
```bash
|
||||
git clone https://github.com/vercel/vercel.git
|
||||
cd vercel
|
||||
yarn
|
||||
yarn build
|
||||
pnpm install
|
||||
pnpm build
|
||||
```
|
||||
|
||||
At this point you can make modifications to the CLI source code and test them out locally. The CLI source code is located in the `packages/cli` directory.
|
||||
@@ -51,15 +51,15 @@ At this point you can make modifications to the CLI source code and test them ou
|
||||
cd packages/cli
|
||||
```
|
||||
|
||||
### `yarn dev <cli-commands...>`
|
||||
### `pnpm dev <cli-commands...>`
|
||||
|
||||
From within the `packages/cli` directory, you can use the "dev" script to quickly execute Vercel CLI from its TypeScript source code directly (without having to manually compile first). For example:
|
||||
|
||||
```bash
|
||||
yarn dev deploy
|
||||
yarn dev whoami
|
||||
yarn dev login
|
||||
yarn dev switch --debug
|
||||
pnpm dev deploy
|
||||
pnpm dev whoami
|
||||
pnpm dev login
|
||||
pnpm dev switch --debug
|
||||
```
|
||||
|
||||
When you are satisfied with your changes, make a commit and create a pull request!
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "28.11.1",
|
||||
"version": "28.15.2",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -13,9 +13,9 @@
|
||||
"scripts": {
|
||||
"preinstall": "node ./scripts/preinstall.js",
|
||||
"test": "jest --env node --verbose --bail",
|
||||
"test-unit": "yarn test test/unit/",
|
||||
"test-unit": "pnpm test test/unit/",
|
||||
"test-integration-cli": "rimraf test/fixtures/integration && ava test/integration.js --serial --fail-fast --verbose",
|
||||
"test-integration-dev": "yarn test test/dev/",
|
||||
"test-integration-dev": "pnpm test test/dev/",
|
||||
"coverage": "codecov",
|
||||
"build": "ts-node ./scripts/build.ts",
|
||||
"dev": "ts-node ./src/index.ts"
|
||||
@@ -41,16 +41,16 @@
|
||||
"node": ">= 14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "5.7.5",
|
||||
"@vercel/go": "2.2.24",
|
||||
"@vercel/hydrogen": "0.0.38",
|
||||
"@vercel/next": "3.3.9",
|
||||
"@vercel/node": "2.8.6",
|
||||
"@vercel/python": "3.1.34",
|
||||
"@vercel/redwood": "1.0.45",
|
||||
"@vercel/remix": "1.1.7",
|
||||
"@vercel/ruby": "1.3.50",
|
||||
"@vercel/static-build": "1.1.1"
|
||||
"@vercel/build-utils": "6.2.1",
|
||||
"@vercel/go": "2.3.3",
|
||||
"@vercel/hydrogen": "0.0.49",
|
||||
"@vercel/next": "3.4.1",
|
||||
"@vercel/node": "2.9.2",
|
||||
"@vercel/python": "3.1.45",
|
||||
"@vercel/redwood": "1.1.1",
|
||||
"@vercel/remix": "1.2.12",
|
||||
"@vercel/ruby": "1.3.61",
|
||||
"@vercel/static-build": "1.3.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@alex_neo/jest-expect-message": "1.0.5",
|
||||
@@ -83,6 +83,7 @@
|
||||
"@types/npm-package-arg": "6.1.0",
|
||||
"@types/pluralize": "0.0.29",
|
||||
"@types/psl": "1.1.0",
|
||||
"@types/qs": "6.9.7",
|
||||
"@types/semver": "6.0.1",
|
||||
"@types/tar-fs": "1.16.1",
|
||||
"@types/text-table": "0.2.0",
|
||||
@@ -92,13 +93,13 @@
|
||||
"@types/which": "1.3.2",
|
||||
"@types/write-json-file": "2.2.1",
|
||||
"@types/yauzl-promise": "2.1.0",
|
||||
"@vercel/client": "12.2.26",
|
||||
"@vercel/error-utils": "1.0.3",
|
||||
"@vercel/frameworks": "1.1.18",
|
||||
"@vercel/fs-detectors": "3.6.2",
|
||||
"@vercel/client": "12.3.7",
|
||||
"@vercel/error-utils": "1.0.8",
|
||||
"@vercel/frameworks": "1.3.0",
|
||||
"@vercel/fs-detectors": "3.7.10",
|
||||
"@vercel/fun": "1.0.4",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/routing-utils": "2.1.3",
|
||||
"@vercel/routing-utils": "2.1.8",
|
||||
"@zeit/source-map-support": "0.6.2",
|
||||
"ajv": "6.12.2",
|
||||
"alpha-sort": "2.0.1",
|
||||
@@ -138,6 +139,7 @@
|
||||
"is-port-reachable": "3.1.0",
|
||||
"is-url": "1.2.2",
|
||||
"jaro-winkler": "0.2.8",
|
||||
"jest-matcher-utils": "29.3.1",
|
||||
"json5": "2.2.1",
|
||||
"jsonlines": "0.1.1",
|
||||
"line-async-iterator": "3.0.0",
|
||||
@@ -169,7 +171,7 @@
|
||||
"tmp-promise": "1.0.3",
|
||||
"tree-kill": "1.2.2",
|
||||
"ts-node": "10.9.1",
|
||||
"typescript": "4.7.4",
|
||||
"typescript": "4.9.4",
|
||||
"universal-analytics": "0.4.20",
|
||||
"utility-types": "2.1.0",
|
||||
"write-json-file": "2.2.0",
|
||||
|
||||
@@ -47,12 +47,12 @@ async function main() {
|
||||
const dependencies = Object.keys(pkg?.dependencies ?? {});
|
||||
// Do the initial `ncc` build
|
||||
console.log('Dependencies:', dependencies);
|
||||
const externs = [];
|
||||
const externs: Array<string> = [];
|
||||
for (const dep of dependencies) {
|
||||
externs.push('--external', dep);
|
||||
}
|
||||
const args = ['ncc', 'build', 'src/index.ts', ...externs];
|
||||
await execa('yarn', args, { stdio: 'inherit', cwd: dirRoot });
|
||||
await execa('pnpm', args, { stdio: 'inherit', cwd: dirRoot });
|
||||
|
||||
// `ncc` has some issues with `@vercel/fun`'s runtime files:
|
||||
// - Executable bits on the `bootstrap` files appear to be lost:
|
||||
@@ -66,10 +66,7 @@ async function main() {
|
||||
// get compiled into the final ncc bundle file, however, we want them to be
|
||||
// present in the npm package because the contents of those files are involved
|
||||
// with `fun`'s cache invalidation mechanism and they need to be shasum'd.
|
||||
const runtimes = join(
|
||||
dirRoot,
|
||||
'../../node_modules/@vercel/fun/dist/src/runtimes'
|
||||
);
|
||||
const runtimes = join(dirRoot, 'node_modules/@vercel/fun/dist/src/runtimes');
|
||||
await cpy('**/*', join(distRoot, 'runtimes'), {
|
||||
parents: true,
|
||||
cwd: runtimes,
|
||||
|
||||
@@ -32,6 +32,7 @@ const help = () => {
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
|
||||
@@ -51,7 +51,7 @@ export default async function ls(
|
||||
...paginationOptions
|
||||
);
|
||||
output.log(`aliases found under ${chalk.bold(contextName)} ${lsStamp()}`);
|
||||
output.log(printAliasTable(aliases));
|
||||
client.stdout.write(printAliasTable(aliases));
|
||||
|
||||
if (pagination && pagination.count === 20) {
|
||||
const flags = getCommandFlags(opts, ['_', '--next']);
|
||||
|
||||
@@ -33,6 +33,7 @@ const help = () => {
|
||||
|
||||
-h, --help Output usage information
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-b, --bad Known bad URL
|
||||
-g, --good Known good URL
|
||||
-o, --open Automatically open each URL in the browser
|
||||
|
||||
@@ -17,7 +17,11 @@ import {
|
||||
BuildResultV3,
|
||||
NowBuildError,
|
||||
} from '@vercel/build-utils';
|
||||
import { detectBuilders } from '@vercel/fs-detectors';
|
||||
import {
|
||||
detectBuilders,
|
||||
detectFrameworkRecord,
|
||||
LocalFileSystemDetector,
|
||||
} from '@vercel/fs-detectors';
|
||||
import minimatch from 'minimatch';
|
||||
import {
|
||||
appendRoutesToPhase,
|
||||
@@ -59,6 +63,9 @@ 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;
|
||||
|
||||
@@ -69,6 +76,20 @@ interface SerializedBuilder extends Builder {
|
||||
apiVersion: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build Output API `config.json` file interface.
|
||||
*/
|
||||
interface BuildOutputConfig {
|
||||
version?: 3;
|
||||
wildcard?: BuildResultV2Typical['wildcard'];
|
||||
images?: BuildResultV2Typical['images'];
|
||||
routes?: BuildResultV2Typical['routes'];
|
||||
overrides?: Record<string, PathOverride>;
|
||||
framework?: {
|
||||
version: string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Contents of the `builds.json` file.
|
||||
*/
|
||||
@@ -97,6 +118,7 @@ const help = () => {
|
||||
--output [path] Directory where built assets should be written to
|
||||
--prod Build a production deployment
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-y, --yes Skip the confirmation prompt about pulling environment variables and project settings when not found locally
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
@@ -191,10 +213,15 @@ export default async function main(client: Client): Promise<number> {
|
||||
}
|
||||
|
||||
// Delete output directory from potential previous build
|
||||
const defaultOutputDir = join(cwd, OUTPUT_DIR);
|
||||
const outputDir = argv['--output']
|
||||
? resolve(argv['--output'])
|
||||
: join(cwd, OUTPUT_DIR);
|
||||
await fs.remove(outputDir);
|
||||
: defaultOutputDir;
|
||||
await Promise.all([
|
||||
fs.remove(outputDir),
|
||||
// Also delete `.vercel/output`, in case the script is targeting Build Output API directly
|
||||
outputDir !== defaultOutputDir ? fs.remove(defaultOutputDir) : undefined,
|
||||
]);
|
||||
|
||||
const buildsJson: BuildsManifest = {
|
||||
'//': 'This file was generated by the `vercel build` command. It is not part of the Build Output API.',
|
||||
@@ -434,7 +461,7 @@ async function doBuild(
|
||||
// Execute Builders for detected entrypoints
|
||||
// TODO: parallelize builds (except for frontend)
|
||||
const sortedBuilders = sortBuilders(builds);
|
||||
const buildResults: Map<Builder, BuildResult> = new Map();
|
||||
const buildResults: Map<Builder, BuildResult | BuildOutputConfig> = new Map();
|
||||
const overrides: PathOverride[] = [];
|
||||
const repoRootPath = cwd;
|
||||
const corepackShimDir = await initCorepack({ repoRootPath });
|
||||
@@ -450,6 +477,22 @@ async function doBuild(
|
||||
try {
|
||||
const { builder, pkg: builderPkg } = builderWithPkg;
|
||||
|
||||
for (const key of [
|
||||
'buildCommand',
|
||||
'installCommand',
|
||||
'outputDirectory',
|
||||
'nodeVersion',
|
||||
] as const) {
|
||||
const value = projectSettings[key];
|
||||
if (typeof value === 'string') {
|
||||
const envKey =
|
||||
`VERCEL_PROJECT_SETTINGS_` +
|
||||
key.replace(/[A-Z]/g, letter => `_${letter}`).toUpperCase();
|
||||
process.env[envKey] = value;
|
||||
output.debug(`Setting env ${envKey} to "${value}"`);
|
||||
}
|
||||
}
|
||||
|
||||
const buildConfig: Config = isZeroConfig
|
||||
? {
|
||||
outputDirectory: projectSettings.outputDirectory ?? undefined,
|
||||
@@ -538,8 +581,7 @@ async function doBuild(
|
||||
|
||||
// Merge existing `config.json` file into the one that will be produced
|
||||
const configPath = join(outputDir, 'config.json');
|
||||
// TODO: properly type
|
||||
const existingConfig = await readJSONFile<any>(configPath);
|
||||
const existingConfig = await readJSONFile<BuildOutputConfig>(configPath);
|
||||
if (existingConfig instanceof CantParseJSONFile) {
|
||||
throw existingConfig;
|
||||
}
|
||||
@@ -585,15 +627,17 @@ async function doBuild(
|
||||
const mergedOverrides: Record<string, PathOverride> =
|
||||
overrides.length > 0 ? Object.assign({}, ...overrides) : undefined;
|
||||
|
||||
const framework = await getFramework(cwd, buildResults);
|
||||
|
||||
// Write out the final `config.json` file based on the
|
||||
// user configuration and Builder build results
|
||||
// TODO: properly type
|
||||
const config = {
|
||||
const config: BuildOutputConfig = {
|
||||
version: 3,
|
||||
routes: mergedRoutes,
|
||||
images: mergedImages,
|
||||
wildcard: mergedWildcard,
|
||||
overrides: mergedOverrides,
|
||||
framework,
|
||||
};
|
||||
await fs.writeJSON(join(outputDir, 'config.json'), config, { spaces: 2 });
|
||||
|
||||
@@ -608,6 +652,50 @@ async function doBuild(
|
||||
);
|
||||
}
|
||||
|
||||
async function getFramework(
|
||||
cwd: string,
|
||||
buildResults: Map<Builder, BuildResult | BuildOutputConfig>
|
||||
): Promise<{ version: string } | undefined> {
|
||||
const detectedFramework = await detectFrameworkRecord({
|
||||
fs: new LocalFileSystemDetector(cwd),
|
||||
frameworkList: frameworks,
|
||||
});
|
||||
|
||||
if (!detectedFramework) {
|
||||
return;
|
||||
}
|
||||
|
||||
// determine framework version from build result
|
||||
if (detectedFramework.useRuntime) {
|
||||
for (const [build, buildResult] of buildResults.entries()) {
|
||||
if (
|
||||
'framework' in buildResult &&
|
||||
build.use === detectedFramework.useRuntime.use
|
||||
) {
|
||||
return buildResult.framework;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// determine framework version from listed package.json version
|
||||
if (detectedFramework.detectedVersion) {
|
||||
// check for a valid, explicit version, not a range
|
||||
if (semver.valid(detectedFramework.detectedVersion)) {
|
||||
return {
|
||||
version: detectedFramework.detectedVersion,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// determine framework version with runtime lookup
|
||||
const frameworkVersion = detectFrameworkVersion(detectedFramework);
|
||||
if (frameworkVersion) {
|
||||
return {
|
||||
version: frameworkVersion,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function expandBuild(files: string[], build: Builder): Builder[] {
|
||||
if (!build.use) {
|
||||
throw new NowBuildError({
|
||||
@@ -648,7 +736,7 @@ function expandBuild(files: string[], build: Builder): Builder[] {
|
||||
|
||||
function mergeImages(
|
||||
images: BuildResultV2Typical['images'],
|
||||
buildResults: Iterable<BuildResult>
|
||||
buildResults: Iterable<BuildResult | BuildOutputConfig>
|
||||
): BuildResultV2Typical['images'] {
|
||||
for (const result of buildResults) {
|
||||
if ('images' in result && result.images) {
|
||||
@@ -659,7 +747,7 @@ function mergeImages(
|
||||
}
|
||||
|
||||
function mergeWildcard(
|
||||
buildResults: Iterable<BuildResult>
|
||||
buildResults: Iterable<BuildResult | BuildOutputConfig>
|
||||
): BuildResultV2Typical['wildcard'] {
|
||||
let wildcard: BuildResultV2Typical['wildcard'] = undefined;
|
||||
for (const result of buildResults) {
|
||||
|
||||
@@ -37,6 +37,7 @@ const help = () => {
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
|
||||
@@ -55,7 +55,7 @@ async function ls(
|
||||
);
|
||||
|
||||
if (certs.length > 0) {
|
||||
output.log(formatCertsTable(certs));
|
||||
client.stdout.write(formatCertsTable(certs));
|
||||
}
|
||||
|
||||
if (pagination && pagination.count === 20) {
|
||||
|
||||
@@ -53,6 +53,7 @@ export const help = () => `
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-f, --force Force a new deployment even if nothing has changed
|
||||
--with-cache Retain build cache when using "--force"
|
||||
-t ${chalk.underline('TOKEN')}, --token=${chalk.underline(
|
||||
|
||||
@@ -31,6 +31,7 @@ const help = () => {
|
||||
|
||||
-h, --help Output usage information
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-l, --listen [uri] Specify a URI endpoint on which to listen [0.0.0.0:3000]
|
||||
-t, --token [token] Specify an Authorization Token
|
||||
-y, --yes Skip questions when setting up new project using default scope and settings
|
||||
|
||||
@@ -33,6 +33,7 @@ const help = () => {
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
|
||||
@@ -70,7 +70,7 @@ export default async function ls(
|
||||
records.length > 0 ? 'Records' : 'No records'
|
||||
} found under ${chalk.bold(contextName)} ${chalk.gray(lsStamp())}`
|
||||
);
|
||||
output.log(getDNSRecordsTable([{ domainName, records }]));
|
||||
client.stdout.write(getDNSRecordsTable([{ domainName, records }]));
|
||||
|
||||
if (pagination && pagination.count === 20) {
|
||||
const flags = getCommandFlags(opts, ['_', '--next']);
|
||||
|
||||
@@ -33,6 +33,7 @@ const help = () => {
|
||||
|
||||
-h, --help Output usage information
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-f, --force Force a domain on a project and remove it from an existing one
|
||||
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
|
||||
'FILE'
|
||||
|
||||
1
packages/cli/src/commands/env/index.ts
vendored
1
packages/cli/src/commands/env/index.ts
vendored
@@ -40,6 +40,7 @@ const help = () => {
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
|
||||
@@ -34,7 +34,7 @@ const help = () => {
|
||||
)} Connect your Vercel Project to your Git repository defined in your local .git config
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} git connect`)}
|
||||
|
||||
|
||||
${chalk.gray(
|
||||
'–'
|
||||
)} Connect your Vercel Project to a Git repository using the remote URL
|
||||
@@ -96,6 +96,7 @@ export default async function main(client: Client) {
|
||||
}
|
||||
|
||||
const { org, project } = linkedProject;
|
||||
client.config.currentTeam = org.type === 'team' ? org.id : undefined;
|
||||
|
||||
switch (subcommand) {
|
||||
case 'connect':
|
||||
|
||||
@@ -21,6 +21,7 @@ const help = () => {
|
||||
|
||||
-h, --help Output usage information
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-f, --force Overwrite destination directory if exists [off]
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
@@ -32,6 +32,7 @@ const help = () => {
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-S, --scope Set a custom scope
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
@@ -19,6 +19,7 @@ const help = () => {
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
|
||||
@@ -36,6 +36,7 @@ const help = () => {
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-y, --yes Skip questions when setting up new project using default scope and settings
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
|
||||
@@ -23,6 +23,7 @@ const help = () => {
|
||||
${chalk.dim('Options:')}
|
||||
|
||||
-h, --help Output usage information
|
||||
--no-color No color mode [off]
|
||||
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
|
||||
'FILE'
|
||||
)} Path to the local ${'`vercel.json`'} file
|
||||
|
||||
@@ -23,6 +23,7 @@ const help = () => {
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-f, --follow Wait for additional data [off]
|
||||
-n ${chalk.bold.underline(
|
||||
'NUMBER'
|
||||
|
||||
@@ -31,6 +31,7 @@ const help = () => {
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
--environment [environment] Deployment environment [development]
|
||||
-y, --yes Skip questions when setting up new project using default scope and settings
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ const help = () => {
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
|
||||
@@ -28,6 +28,7 @@ const help = () => {
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
|
||||
@@ -30,6 +30,7 @@ const help = () => {
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-N, --next Show next page of results
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
@@ -19,6 +19,7 @@ const help = () => {
|
||||
'DIR'
|
||||
)} Path to the global ${'`.vercel`'} directory
|
||||
-d, --debug Debug mode [off]
|
||||
--no-color No color mode [off]
|
||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||
'TOKEN'
|
||||
)} Login token
|
||||
|
||||
@@ -103,7 +103,12 @@ const main = async () => {
|
||||
}
|
||||
|
||||
const isDebugging = argv['--debug'];
|
||||
const output = new Output(process.stderr, { debug: isDebugging });
|
||||
const isNoColor = argv['--no-color'];
|
||||
|
||||
const output = new Output(process.stderr, {
|
||||
debug: isDebugging,
|
||||
noColor: isNoColor,
|
||||
});
|
||||
|
||||
debug = output.debug;
|
||||
|
||||
|
||||
@@ -8,6 +8,8 @@ const ARG_COMMON = {
|
||||
'--debug': Boolean,
|
||||
'-d': '--debug',
|
||||
|
||||
'--no-color': Boolean,
|
||||
|
||||
'--token': String,
|
||||
'-t': '--token',
|
||||
|
||||
|
||||
@@ -5,18 +5,14 @@ import { satisfies } from 'semver';
|
||||
import { dirname, join } from 'path';
|
||||
import { mkdirp, outputJSON, readJSON, symlink } from 'fs-extra';
|
||||
import { isStaticRuntime } from '@vercel/fs-detectors';
|
||||
import {
|
||||
BuilderV2,
|
||||
BuilderV3,
|
||||
PackageJson,
|
||||
spawnAsync,
|
||||
} from '@vercel/build-utils';
|
||||
import { BuilderV2, BuilderV3, PackageJson } from '@vercel/build-utils';
|
||||
import execa from 'execa';
|
||||
import * as staticBuilder from './static-builder';
|
||||
import { VERCEL_DIR } from '../projects/link';
|
||||
import { Output } from '../output';
|
||||
import readJSONFile from '../read-json-file';
|
||||
import { CantParseJSONFile } from '../errors-ts';
|
||||
import { errorToString, isErrnoException, isError } from '@vercel/error-utils';
|
||||
import { isErrnoException, isError } from '@vercel/error-utils';
|
||||
import cmd from '../output/cmd';
|
||||
import code from '../output/code';
|
||||
|
||||
@@ -213,32 +209,44 @@ async function installBuilders(
|
||||
).join(', ')}`
|
||||
);
|
||||
try {
|
||||
await spawnAsync(
|
||||
const { stderr } = await execa(
|
||||
'npm',
|
||||
['install', '@vercel/build-utils', ...buildersToAdd],
|
||||
{
|
||||
cwd: buildersDir,
|
||||
stdio: 'pipe',
|
||||
reject: true,
|
||||
}
|
||||
);
|
||||
stderr
|
||||
.split('/\r?\n/')
|
||||
.filter(line => line.includes('npm WARN deprecated'))
|
||||
.forEach(line => {
|
||||
output.warn(line);
|
||||
});
|
||||
} catch (err: unknown) {
|
||||
if (isError(err)) {
|
||||
(err as any).link =
|
||||
'https://vercel.link/builder-dependencies-install-failed';
|
||||
if (isErrnoException(err) && err.code === 'ENOENT') {
|
||||
const execaMessage = err.message;
|
||||
let message =
|
||||
err && 'stderr' in err && typeof err.stderr === 'string'
|
||||
? err.stderr
|
||||
: execaMessage;
|
||||
if (execaMessage.startsWith('Command failed with ENOENT')) {
|
||||
// `npm` is not installed
|
||||
err.message = `Please install ${cmd('npm')} before continuing`;
|
||||
message = `Please install ${cmd('npm')} before continuing`;
|
||||
} else {
|
||||
const message = errorToString(err);
|
||||
const notFound = /GET (.*) - Not found/.exec(message);
|
||||
if (notFound) {
|
||||
const url = new URL(notFound[1]);
|
||||
const packageName = decodeURIComponent(url.pathname.slice(1));
|
||||
err.message = `The package ${code(
|
||||
message = `The package ${code(
|
||||
packageName
|
||||
)} is not published on the npm registry`;
|
||||
}
|
||||
}
|
||||
err.message = message;
|
||||
(err as any).link =
|
||||
'https://vercel.link/builder-dependencies-install-failed';
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
46
packages/cli/src/util/build/merge.ts
Normal file
46
packages/cli/src/util/build/merge.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { join } from 'path';
|
||||
import { isErrnoException } from '@vercel/error-utils';
|
||||
import { stat, move, remove, rmdir, readdir } from 'fs-extra';
|
||||
import type { Stats } from 'fs-extra';
|
||||
|
||||
/**
|
||||
* Merge a directory into another directory. A `move` file operation is preferred,
|
||||
* falling back to a recursive `move` of contents within the source directory.
|
||||
*/
|
||||
export async function merge(source: string, destination: string) {
|
||||
const destStat: Stats | NodeJS.ErrnoException = await stat(destination).catch(
|
||||
err => err
|
||||
);
|
||||
if (isErrnoException(destStat)) {
|
||||
if (destStat.code === 'ENOENT') {
|
||||
// Destination does not exist, so move directly
|
||||
await move(source, destination);
|
||||
return;
|
||||
}
|
||||
// Some other kind of error, bail
|
||||
throw destStat;
|
||||
} else if (destStat.isDirectory()) {
|
||||
// Destination is already a directory, so merge contents recursively
|
||||
const contents: string[] | NodeJS.ErrnoException = await readdir(
|
||||
source
|
||||
).catch(err => err);
|
||||
if (isErrnoException(contents)) {
|
||||
// If source is not a directory, then fall through to rm + move
|
||||
if (contents.code !== 'ENOTDIR') {
|
||||
// Any other error then bail
|
||||
throw contents;
|
||||
}
|
||||
} else {
|
||||
await Promise.all(
|
||||
contents.map(name => merge(join(source, name), join(destination, name)))
|
||||
);
|
||||
// Source should be empty at this point
|
||||
await rmdir(source);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Destination is not a directory, or dest is a dir + source is not, so overwrite
|
||||
await remove(destination);
|
||||
await move(source, destination);
|
||||
}
|
||||
@@ -54,8 +54,12 @@ export async function setMonorepoDefaultSettings(
|
||||
)} monorepo manager. Attempting to assign default settings.`
|
||||
);
|
||||
|
||||
setCommand('buildCommand', commands.buildCommand);
|
||||
setCommand('installCommand', commands.installCommand);
|
||||
if (commands.buildCommand) {
|
||||
setCommand('buildCommand', commands.buildCommand);
|
||||
}
|
||||
if (commands.installCommand) {
|
||||
setCommand('installCommand', commands.installCommand);
|
||||
}
|
||||
if (commands.commandForIgnoringBuildStep) {
|
||||
setCommand(
|
||||
'commandForIgnoringBuildStep',
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
Builder,
|
||||
BuildResultV2,
|
||||
BuildResultV3,
|
||||
Cron,
|
||||
File,
|
||||
FileFsRef,
|
||||
BuilderV2,
|
||||
@@ -28,9 +29,10 @@ import {
|
||||
normalizePath,
|
||||
} from '@vercel/build-utils';
|
||||
import pipe from 'promisepipe';
|
||||
import { merge } from './merge';
|
||||
import { unzip } from './unzip';
|
||||
import { VERCEL_DIR } from '../projects/link';
|
||||
import { VercelConfig } from '@vercel/client';
|
||||
import { fileNameSymbol, VercelConfig } from '@vercel/client';
|
||||
|
||||
const { normalize } = posix;
|
||||
export const OUTPUT_DIR = join(VERCEL_DIR, 'output');
|
||||
@@ -39,6 +41,7 @@ export const OUTPUT_DIR = join(VERCEL_DIR, 'output');
|
||||
* An entry in the "functions" object in `vercel.json`.
|
||||
*/
|
||||
interface FunctionConfiguration {
|
||||
cron?: Cron;
|
||||
memory?: number;
|
||||
maxDuration?: number;
|
||||
}
|
||||
@@ -56,6 +59,7 @@ export async function writeBuildResult(
|
||||
return writeBuildResultV2(
|
||||
outputDir,
|
||||
buildResult as BuildResultV2,
|
||||
build,
|
||||
vercelConfig
|
||||
);
|
||||
} else if (version === 3) {
|
||||
@@ -107,6 +111,7 @@ function stripDuplicateSlashes(path: string): string {
|
||||
async function writeBuildResultV2(
|
||||
outputDir: string,
|
||||
buildResult: BuildResultV2,
|
||||
build: Builder,
|
||||
vercelConfig: VercelConfig | null
|
||||
) {
|
||||
if ('buildOutputPath' in buildResult) {
|
||||
@@ -114,6 +119,18 @@ async function writeBuildResultV2(
|
||||
return;
|
||||
}
|
||||
|
||||
// Some very old `@now` scoped Builders return `output` at the top-level.
|
||||
// These Builders are no longer supported.
|
||||
if (!buildResult.output) {
|
||||
const configFile = vercelConfig?.[fileNameSymbol];
|
||||
const updateMessage = build.use.startsWith('@now/')
|
||||
? ` Please update from "@now" to "@vercel" in your \`${configFile}\` file.`
|
||||
: '';
|
||||
throw new Error(
|
||||
`The build result from "${build.use}" is missing the "output" property.${updateMessage}`
|
||||
);
|
||||
}
|
||||
|
||||
const lambdas = new Map<Lambda, string>();
|
||||
const overrides: Record<string, PathOverride> = {};
|
||||
for (const [path, output] of Object.entries(buildResult.output)) {
|
||||
@@ -355,12 +372,14 @@ async function writeLambda(
|
||||
throw new Error('Malformed `Lambda` - no "files" present');
|
||||
}
|
||||
|
||||
const cron = functionConfiguration?.cron ?? lambda.cron;
|
||||
const memory = functionConfiguration?.memory ?? lambda.memory;
|
||||
const maxDuration = functionConfiguration?.maxDuration ?? lambda.maxDuration;
|
||||
|
||||
const config = {
|
||||
...lambda,
|
||||
handler: normalizePath(lambda.handler),
|
||||
cron,
|
||||
memory,
|
||||
maxDuration,
|
||||
type: undefined,
|
||||
@@ -412,7 +431,7 @@ async function mergeBuilderOutput(
|
||||
// so no need to do anything
|
||||
return;
|
||||
}
|
||||
await fs.copy(buildResult.buildOutputPath, outputDir);
|
||||
await merge(buildResult.buildOutputPath, outputDir);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { lookup as lookupMimeType } from 'mime-types';
|
||||
import { contentType } from 'mime-types';
|
||||
|
||||
export default function getMimeType(fileName: string) {
|
||||
return lookupMimeType(fileName) || 'application/octet-stream';
|
||||
return contentType(fileName) || 'application/octet-stream';
|
||||
}
|
||||
|
||||
@@ -1129,10 +1129,10 @@ export default class DevServer {
|
||||
});
|
||||
body = `${json}\n`;
|
||||
} else if (accept.includes('html')) {
|
||||
res.setHeader('content-type', 'text/html');
|
||||
res.setHeader('content-type', 'text/html; charset=utf-8');
|
||||
body = redirectTemplate({ location, statusCode });
|
||||
} else {
|
||||
res.setHeader('content-type', 'text/plain');
|
||||
res.setHeader('content-type', 'text/plain; charset=utf-8');
|
||||
body = `Redirecting to ${location} (${statusCode})\n`;
|
||||
}
|
||||
res.end(body);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user