Compare commits

..

45 Commits

Author SHA1 Message Date
Steven
1eeeaf23a1 Publish Stable
- @vercel/build-utils@2.5.3
 - vercel@20.1.1
 - @vercel/client@9.0.2
 - @vercel/next@2.6.26
 - @vercel/node@1.8.3
 - @vercel/static-build@0.17.9
2020-09-21 15:12:38 -04:00
Steven
f347164b6c Publish Canary
- vercel@20.1.1-canary.8
2020-09-18 17:51:03 -04:00
Steven
ea4be8a001 [tests] Delay deprecation message (#5210)
Follow up to #5158 to add longer delay.

There is an issue with npm consistency after publishing so we wait longer before deprecating the `now` package because its a little larger than the others.
2020-09-18 16:02:35 -04:00
JJ Kasper
19ac74d59e Publish Canary
- vercel@20.1.1-canary.7
 - @vercel/client@9.0.2-canary.5
 - @vercel/next@2.6.26-canary.3
 - @vercel/node@1.8.3-canary.2
 - @vercel/static-build@0.17.9-canary.1
2020-09-15 19:21:01 -05:00
JJ Kasper
9a87d4ea8e [next] Fix API page check (#5196)
This corrects the `isApiPage` check to not incorrectly detect `/api-docs` as an API route. 

Note: tests won't pass until a new canary with the below Next.js PR has been landed

x-ref: https://github.com/vercel/next.js/pull/17092
Closes: https://github.com/vercel/next.js/issues/17091
2020-09-15 15:28:19 +00:00
Albert Martin
35fd7b5f9c [static-build] Fix immutable cache header for Vue assets (#5070)
We have started migrating our projects to use Vue CLI with the Vercel zero-config builders. One particularly bug we ran into was due to the `Cache-Control` headers automatically applied on these resources that [differ from the documentation](https://vercel.com/docs/edge-network/caching#static-files):

> By default we return a `Cache-Control` header containing `public, max-age=0, must-revalidate` to prevent clients (e.g. browsers) from caching the file locally.

Instead of these headers, we were seeing `immutable` on all our resources. This is a good assumption for a vanilla Vue CLI setup because by default a content hash is used on every chunk, even the entry, which will change as soon as the file contents change. However, this may not always be the case, particularly on Vue CLI projects with any modifications to the build process, custom plugins, etc. that may exclude one or more files from the hash.

In our case this was breaking things in dramatic ways every time we deployed (and we deploy quite often!). Since the resources were being sent with the `immutable` header, the client browser was persisting these in cache and subsequent deployments with potentially breaking changes caused errors that were only resolved by clearing the client browser cache.

Example:

```
dist
├── css
│   ├── app.db598b39.css
│   └── common.css
├── js
│   ├── app.ac201ece.js
│   ├── chunk-587c608b.7d4361a1.js
│   ├── chunk-vendors.00676d62.js
│   └── common.js
└── index.html
```

In the above example, `common.css` and `common.js` are not hashed, but still have an `immutable` header preventing them from being re-validated by the client browser when a new deployment modifies their content.

To solve for this, I've updated the RegExp for Vue CLI to only apply the `immutable` caching header on files which have a content hash. This should solve for both vanilla Vue CLI setups and more advanced ones in which there may exist both files with and without a content hash.

Co-authored-by: Steven <steven@ceriously.com>
2020-09-14 09:08:15 -04:00
Steven
eb8db25845 [cli] Remove v1 messages and docs (#5183)
We removed v1 support in [20.0.0](https://github.com/vercel/vercel/releases/tag/vercel%4020.0.0) so this PR removes the unused documentation, warning messages, etc.
2020-09-11 22:46:32 +00:00
Steven
5c3cd17074 [tests] Cache token when possible (#5179)
This PR solves an issue where tests would sometimes be rate limited when generating a token. This can be solved by caching the token like we do for E2E tests.

Example failure: https://github.com/vercel/vercel/runs/1098030228#step:11:9376

I also update the `@vercel/node` tests to compare the error message, exactly like how we do it with `@vercel/static-build`.
2020-09-11 10:02:07 -04:00
Nathan Rajlich
72572ba6be Publish Canary
- @vercel/build-utils@2.5.3-canary.1
 - vercel@20.1.1-canary.6
 - @vercel/client@9.0.2-canary.4
 - @vercel/node@1.8.3-canary.1
 - @vercel/static-build@0.17.9-canary.0
2020-09-10 17:20:10 -07:00
Nathan Rajlich
b69a41a0aa [node] Use ts.readConfigFile() to parse user's tsconfig.json file (#5180)
TypeScript supports comments in the `tsconfig.json` file, which is not
compatible with `JSON.parse()` so we have to use the built-in function
to parse the config file.

Fixes #4835.
2020-09-10 17:18:30 -07:00
dependabot[bot]
7c35d7992b Bump node-fetch from 2.6.0 to 2.6.1 (#5176)
Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/bitinn/node-fetch/releases">node-fetch's releases</a>.</em></p>
<blockquote>
<h2>v2.6.1</h2>
<p><strong>This is an important security release. It is strongly recommended to update as soon as possible.</strong></p>
<p>See <a href="https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md#v261">CHANGELOG</a> for details.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md">node-fetch's changelog</a>.</em></p>
<blockquote>
<h2>v2.6.1</h2>
<p><strong>This is an important security release. It is strongly recommended to update as soon as possible.</strong></p>
<ul>
<li>Fix: honor the <code>size</code> option after following a redirect.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="b5e2e41b2b"><code>b5e2e41</code></a> update version number</li>
<li><a href="2358a6c256"><code>2358a6c</code></a> Honor the <code>size</code> option after following a redirect and revert data uri support</li>
<li><a href="8c197f8982"><code>8c197f8</code></a> docs: Fix typos and grammatical errors in README.md (<a href="https://github-redirect.dependabot.com/bitinn/node-fetch/issues/686">#686</a>)</li>
<li><a href="1e99050f94"><code>1e99050</code></a> fix: Change error message thrown with redirect mode set to error (<a href="https://github-redirect.dependabot.com/bitinn/node-fetch/issues/653">#653</a>)</li>
<li><a href="244e6f63d4"><code>244e6f6</code></a> docs: Show backers in README</li>
<li><a href="6a5d192034"><code>6a5d192</code></a> fix: Properly parse meta tag when parameters are reversed (<a href="https://github-redirect.dependabot.com/bitinn/node-fetch/issues/682">#682</a>)</li>
<li><a href="47a24a03eb"><code>47a24a0</code></a> chore: Add opencollective badge</li>
<li><a href="7b136627c5"><code>7b13662</code></a> chore: Add funding link</li>
<li><a href="5535c2ed47"><code>5535c2e</code></a> fix: Check for global.fetch before binding it (<a href="https://github-redirect.dependabot.com/bitinn/node-fetch/issues/674">#674</a>)</li>
<li><a href="1d5778ad0d"><code>1d5778a</code></a> docs: Add Discord badge</li>
<li>Additional commits viewable in <a href="https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1">compare view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by <a href="https://www.npmjs.com/~akepinski">akepinski</a>, a new releaser for node-fetch since your current version.</p>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=node-fetch&package-manager=npm_and_yarn&previous-version=2.6.0&new-version=2.6.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/configuring-github-dependabot-security-updates)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
- `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language
- `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language
- `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language
- `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language

You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/vercel/vercel/network/alerts).

</details>
2020-09-10 22:50:00 +00:00
JJ Kasper
290fdc0506 Publish Canary
- @vercel/next@2.6.26-canary.2
2020-09-10 13:15:27 -05:00
JJ Kasper
fc2d9f99e6 [next] Optimize page loading for shared lambdas (#5156)
This updates to prevent loading all pages at once for shared lambdas and waits to require the page when it's needed

Fixes https://github.com/vercel/next.js/issues/16990
2020-09-10 14:24:36 +00:00
Steven
1fd24fb4fc Publish Canary
- vercel@20.1.1-canary.5
 - @vercel/next@2.6.26-canary.1
2020-09-09 20:40:33 -04:00
Steven
17c72f1d35 [next] Fix config functions src file (#5168)
The [functions](https://vercel.com/docs/configuration#project/functions) property matches source files and it wasn't working for `index.js` or `.ts` files because `next build` converts the source file `pages/api/index.js` to the output `.next/server/pages/api.js`. So this PR fixes the logic to reverse the output page to source file.
2020-09-09 23:41:12 +00:00
Steven
9c1154c108 [tests] Fix test for functions in vercel.json (#5169) 2020-09-09 18:08:14 -04:00
dav-is
613c384ce8 Publish Canary
- @vercel/build-utils@2.5.3-canary.0
 - vercel@20.1.1-canary.4
 - @vercel/client@9.0.2-canary.3
 - @vercel/next@2.6.26-canary.0
 - @vercel/node@1.8.3-canary.0
2020-09-09 09:59:50 -04:00
Gianmarco
a9598d14e3 [docs] Fix typo in error message (#5141) 2020-09-08 16:48:52 -04:00
Connor Davis
48935e92d8 Remove extra newline in warning (#5165) 2020-09-08 11:23:28 -04:00
Steven
1b1e72ab88 Publish Stable
- @vercel/build-utils@2.5.2
 - @vercel/next@2.6.25
 - @vercel/node@1.8.2
2020-09-08 09:56:26 -04:00
Steven
0f574f67f6 [examples] Update Ember with missing robots.txt (#5164)
Fixes https://github.com/emberjs/ember.js/issues/19132

Source: https://github.com/ember-cli/ember-new-output/blob/master/public/robots.txt
2020-09-08 09:49:41 -04:00
Steven
0d4be3f5f2 Publish Canary
- @vercel/build-utils@2.5.2-canary.2
 - vercel@20.1.1-canary.3
 - @vercel/client@9.0.2-canary.2
 - @vercel/next@2.6.25-canary.2
 - @vercel/node@1.8.2-canary.2
2020-09-05 15:16:56 -04:00
Steven
a971c2aa3a [tests] Delay deprecation message (#5158)
This PR is a follow up to #5157 which was unable to deprecate a package immediately after publishing and failed with E405. So this PR adds a delay between publish and deprecate. It also uses the `-f` flag suggested in the error message. https://github.com/vercel/vercel/runs/1076007594#step:6:649
2020-09-05 15:13:48 -04:00
Steven
66414bd65a Publish Canary
- @vercel/build-utils@2.5.2-canary.1
 - vercel@20.1.1-canary.2
 - @vercel/client@9.0.2-canary.1
 - @vercel/next@2.6.25-canary.1
 - @vercel/node@1.8.2-canary.1
2020-09-05 13:54:34 -04:00
Steven
3b021993b5 [tests] Fix deprecation message (#5157)
This PR is a follow up to #5119 which had the names backwards.

I fixed the variable names to avoid the confusion since "new" and "old" were ambiguous.

I also removed the incorrect deprecation message from packages published during commit c9597dc199.
2020-09-05 13:49:20 -04:00
JJ Kasper
c9597dc199 Publish Canary
- @vercel/build-utils@2.5.2-canary.0
 - vercel@20.1.1-canary.1
 - @vercel/client@9.0.2-canary.0
 - @vercel/next@2.6.25-canary.0
 - @vercel/node@1.8.2-canary.0
2020-09-05 00:16:18 -05:00
Steven
1b5c94b392 [node][next] Fix nft tracing for monorepos (#5143)
Co-authored-by: Joe Haddad <joe.haddad@zeit.co>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2020-09-05 01:13:54 -04:00
dav-is
bd1393a9d6 Publish Canary
- vercel@20.1.1-canary.0
2020-09-04 18:40:25 -04:00
dependabot[bot]
47ddd36fec [cli] Update http-proxy to v1.18.1 (#5152)
Bumps [http-proxy](https://github.com/http-party/node-http-proxy) from 1.17.0 to 1.18.1.
- [Release notes](https://github.com/http-party/node-http-proxy/releases)
- [Changelog](https://github.com/http-party/node-http-proxy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/http-party/node-http-proxy/compare/1.17.0...1.18.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-09-04 14:33:56 -07:00
dependabot[bot]
bd047cdc6a Update tree-kill to v1.2.2 (#5151)
Bumps [tree-kill](https://github.com/pkrumins/node-tree-kill) from 1.2.1 to 1.2.2.
- [Release notes](https://github.com/pkrumins/node-tree-kill/releases)
- [Commits](https://github.com/pkrumins/node-tree-kill/compare/v1.2.1...v1.2.2)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-09-04 14:33:32 -07:00
Connor Davis
477f9e8753 [cli] Fix color and indention in learn more link (#5148)
CH-568

Before:
![image](https://user-images.githubusercontent.com/11590024/92258007-2883e080-eea4-11ea-8c14-af0f3c9e27a6.png)

After:
![Screenshot-2020-09-04-11:44](https://user-images.githubusercontent.com/11590024/92258023-3174b200-eea4-11ea-9170-0acd4d6f883b.png)
2020-09-04 21:25:52 +00:00
Mike Hartington
183ea42f94 [examples] chore(ionic-angular): remove Google Maps API key (#5130) 2020-08-31 11:58:52 -07:00
Steven
57a17eb416 [tests] Deprecate "now" npm package in favor of "vercel" (#5119)
We deprecated all the `now` scoped packages in favor of the `vercel` equivalents, however the deprecation message disappears after each publish, so we must to run `npm deprecate` after `npm publish` for legacy packages.
2020-08-28 15:39:06 -04:00
Steven
be24510f16 Publish Stable
- @vercel/frameworks@0.1.1
 - @vercel/build-utils@2.5.1
 - vercel@20.1.0
 - @vercel/client@9.0.1
 - @vercel/go@1.1.6
 - @vercel/next@2.6.24
 - @vercel/node@1.8.1
 - @vercel/python@1.2.3
 - @vercel/ruby@1.2.4
 - @vercel/static-build@0.17.8
 - @vercel/redwood@0.1.1
2020-08-27 20:01:15 -04:00
Steven
05c534d855 Publish Canary
- @vercel/frameworks@0.1.1-canary.0
 - @vercel/build-utils@2.5.1-canary.1
 - vercel@20.0.1-canary.2
 - @vercel/client@9.0.1-canary.1
 - @vercel/go@1.1.6-canary.0
 - @vercel/node@1.8.1-canary.0
 - @vercel/python@1.2.3-canary.0
 - @vercel/ruby@1.2.4-canary.0
 - @vercel/static-build@0.17.8-canary.0
 - @vercel/redwood@0.1.1-canary.0
2020-08-27 19:39:21 -04:00
Shu Ding
910169dba7 [cli] Add support for the sourceFilesOutsideRootDirectory option (#5113)
If the value is set to `true` in the project settings, we don't cd into `rootDirectory`. 
We default it to `true` for new projects.
2020-08-27 23:37:50 +00:00
Steven
0fc74feddc [all] Bump ncc to 0.24.0 (#5103)
- Bump ncc to [0.24.0](https://github.com/vercel/ncc/releases/tag/0.24.0)
- Install ncc in each package that depends on it
2020-08-26 11:03:34 -04:00
Naoyuki Kanezawa
a9ea294514 fix framework names (#5104) 2020-08-26 22:14:39 +09:00
Steven
42e0450d87 Publish Canary
- vercel@20.0.1-canary.1
 - @vercel/next@2.6.24-canary.0
2020-08-25 22:13:26 -04:00
Guy Bedford
08c0feb58a [cli] Improve startup perf - disable source maps and minification (#5100)
Currently on my machine, vercel --version takes 850ms to run. With this change, that execution time is reduced to ~550ms.

The reason is that source maps seem to significantly slow down Node.js execution, compounded by the size of the source map, even if it is not used.

I believe the benefits of this perf improvement outweigh the direct source maps and minification benefits.

If it is felt that direct per-file source maps are necessary for internal errors, then reducing the source map size should be investigated further to improve the runtime performance here.
2020-08-25 22:12:25 -04:00
Mark Glagola
60aaf76ed2 [cli] Fix vc domains ls pagination (#5099)
Fixes pagination for vercel cli `domains ls --next <timestamp>`
2020-08-25 19:39:34 -04:00
Matthew Sweeney
bd706beba5 [examples] Update README Files (#5092)
This PR updates the `README.md` files with the following changes:

- Removal of CLI deployment.
- Amends Blitz.js to be in line with other `README.md` formats.
2020-08-25 14:51:46 -04:00
JJ Kasper
b85a0a349a [next] Add test case for root optional revalidate params (#5072)
This adds test cases from https://github.com/vercel/next.js/pull/16451 which are currently failing and will pass after a new canary of Next.js has been published
2020-08-24 16:32:30 +00:00
Steven
a97bc2af6d Publish Canary
- @vercel/build-utils@2.5.1-canary.0
 - vercel@20.0.1-canary.0
 - @vercel/client@9.0.1-canary.0
2020-08-24 11:19:44 -04:00
Steven
a5dc90c8cd Revert "[build-utils] Use handle: error for api 404" (#5088)
* Revert "[build-utils] Use `handle: error` for api 404 (#5064)"

This reverts commit 02e1c921ac.

* Re-enable cli changes

* Re-enable redwood changes

* Minor cleanup
2020-08-24 11:16:32 -04:00
103 changed files with 797 additions and 1068 deletions

View File

@@ -68,12 +68,12 @@ In such cases you can visit the URL of the failed deployment and append `/_logs`
The logs of this deployment will contain the actual error which may help you to understand what went wrong.
### @zeit/node-file-trace
### @vercel/nft
Some of the Builders use `@zeit/node-file-trace` to tree-shake files before deployment. If you suspect an error with this tree-shaking mechanism, you can create the following script in your project:
Some of the Builders use `@vercel/nft` to tree-shake files before deployment. If you suspect an error with this tree-shaking mechanism, you can create the following script in your project:
```js
const trace = require('@zeit/node-file-trace');
const trace = require('@vercel/nft');
trace(['path/to/entrypoint.js'], {
ts: true,
mixedModules: true,
@@ -82,7 +82,7 @@ trace(['path/to/entrypoint.js'], {
.then(e => console.error(e));
```
When you run this script, you'll see all imported files. If anything file is missing, the bug is in [@zeit/node-file-trace](https://github.com/vercel/node-file-trace) and not the Builder.
When you run this script, you'll see all imported files. If anything file is missing, the bug is in [@vercel/nft](https://github.com/vercel/nft) and not the Builder.
## Deploy a Builder with existing project

View File

@@ -15,7 +15,7 @@ jobs:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 10
node-version: 12
- name: Install
run: yarn install --check-files --frozen-lockfile
- name: Build

View File

@@ -2,8 +2,8 @@
#### Why This Error Occurred
When supplying `regions` or `scale` settings, you
used an unknown or invalid dc identifier.
When supplying `regions` configuration, you
used an unknown or invalid DC identifier.
#### Possible Ways to Fix It
@@ -19,7 +19,7 @@ and DCs have to be in _lowercase_.
- `gru`
- `iad`
In `now-cli`, they currently are transformed to
In Vercel CLI, they currently are transformed to
DC identifiers before being sent to our APIs.
**Valid DC identifiers**:

View File

@@ -1,9 +0,0 @@
# Missing `--dotenv` Target
#### Why This Error Occurred
You specified a path as the value for the `--dotenv` flag, but the target of the path doesn't exist.
#### Possible Ways to Fix It
Make sure the target file you've specified exists and is readable by Vercel CLI. In addition, please ensure that the filename starts with a dot (example: `.env`) - then it should work.

View File

@@ -2,7 +2,7 @@
#### Why This Error Occurred
This error occurs when you have your application is not configured for Serverless Next.js build output.
This error occurs when your application is not configured for Serverless Next.js build output.
#### Possible Ways to Fix It

View File

@@ -1,32 +0,0 @@
# Can't Set `regions` and `scale` Options Simultaneously
#### Why This Error Occurred
Your deployment's configuration contains a `regions` and `scale`
configuration simultaneously.
#### Possible Ways to Fix It
The `regions` setting is intended to be used to scale the
deployment to the supplied regions or datacenters identifiers
with default scale settings.
```json
{
"regions": ["sfo", "bru", "gru", "iad"]
}
```
The `scale` object allows you to be more granular: you can decide a
`min` and `max` number of instances per region:
```json
{
"scale": {
"sfo": { "min": 0, "max": 10 }
}
}
```
To solve this problem, use only one of the two ways of deciding
where to scale your deployment to.

View File

@@ -1,36 +0,0 @@
# Invalid Region or DC Identifier
#### Why This Error Occurred
When supplying a region or DC identifier in `vercel scale`,
we weren't able to recognize the value as valid.
#### Possible Ways to Fix It
Check your `vercel scale` command make sure you are using a
valid string after the URL. Regions
and DCs have to be in _lowercase_.
**Valid region identifiers**:
- `all` (special, used to scale to all DCs, can only appear once)
- `sfo`
- `bru`
- `gru`
- `iad`
In Vercel CLI, they currently are transformed to
DC identifiers before being sent to our APIs.
**Valid DC identifiers**:
- `sfo1`
- `bru1`
- `gru1`
- `iad1`
To pass multiple ones, use a comma:
```
vercel scale my-url-123.now.sh sfo,bru,gru 1 5
```

View File

@@ -1,30 +0,0 @@
# `vercel scale ls` is deprecated
#### Why This Error Occurred
We have stopped supporting this command, in favor of
better alternatives.
`vercel scale ls` used to list all the scaling rules
for all your deployments. The output would be too long,
and it would often be hard to find the information
you needed in a long list of items.
#### Possible Ways to Fix It
Instead of using `vercel scale ls` to list all your deployments
and their scaling rules, first use `vercel ls` to find
your deployment:
```console
vercel ls
```
Then, select the URL of your deployment, which uniquely identifies it, and run:
```console
vercel inspect my-deployment-12345.now.sh
```
The `inspect` subcommand will give you your deployment's scale information, including what datacenters it's enabled on, the
current number of instances and minimums/maximums.

View File

@@ -1,12 +0,0 @@
# Scaling path alias
#### Why This Error Occurred
You tried to use `vercel scale` on a path alias (`vercel alias -r rules.json`).
#### Possible Ways to Fix It
Path aliases are routes to instances. Instances can be scaled independent from each other.
You can view path aliases by running `vercel alias ls <id>`.
Documentation for Path Aliases can be found [here](https://vercel.com/docs/features/path-aliases).

View File

@@ -1,16 +0,0 @@
# No minimum scale settings on Cloud v2 deployments
#### Why This Error Occurred
An attempt was made at scaling a Cloud v2 deployment with a `min` scale
setting. This isn't supported yet.
#### Possible Ways to Fix It
Ensure your scale settings (in `vercel.json`, the command you're running
or from a previous deployment who's alias you're trying to overwrite) has
the `min` scale setting set to `0`. You can do this by running
```
vercel scale <deployment> 0 10
```

View File

@@ -1,29 +0,0 @@
# Verification Timeout
#### Why This Error Occurred
After the deployment build completed and the deployment state was set to `READY`,
instances failed to initialize properly.
The CLI attempted to verify that the scale settings of your instances matched,
but it couldn't do so within the allotted time (defaults to 2 minutes).
#### Possible Ways to Fix It
Instance verification is the process of ensuring that after
your deployment is ready, we can actually run (instantiate) your code.
If you configured [regions or scale](https://vercel.com/docs/features/scaling),
we ensure the minimums and maximums are met for the regions you enabled.
If you think your code is taking too long to instantiate, this can be due
to slow boot up times. You can supply `--no-verify` to skip verification
if you are confident your code runs properly.
If your application is not listening on a HTTP port, we might be failing to
instantiate your deployment as well. It might not be showing any errors,
but the deployment instance is effectively not routable and cannot be
verified.
If your instances are crashing before an HTTP port is exposed, verification
will fail as well. Double check your logs (e.g.: by running `vercel logs <url>`)

View File

@@ -17,11 +17,3 @@ To get started deploying AMP with Vercel, you can use the [Vercel CLI](https://v
```shell
$ vercel init amp
```
### Deploying From Your Terminal
You can deploy your new AMP project with a single command from your terminal using Vercel CLI:
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ To get started with Angular, you can use the [Angular CLI](https://cli.angular.i
```shell
$ ng new
```
### Deploying From Your Terminal
You can deploy your new Angular project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -1,21 +1,19 @@
![Blitz Logo](https://github.com/vercel/vercel/blob/master/packages/frameworks/logos/blitz.svg)
This is a [Blitz.js](https://blitzjs.com/) project bootstrapped with `npx blitz new`.
# Blitz.js Example
## Getting Started
This directory is a brief example of a [Blitz.js](https://blitzjs.com/) project that can be deployed with Vercel and zero configuration.
First, run the development server:
## Deploy Your Own
```bash
npx blitz start
Deploy your own Blitz.js project with Vercel by viewing the [documentation on deploying to Vercel](https://blitzjs.com/docs/deploy-vercel)
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/vercel/vercel/tree/master/examples/blitzjs)
### How We Created This Example
To get started with Blitz.js, you can use [npx](https://www.npmjs.com/package/npx) to initialize the project:
```shell
$ npx blitz new
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
## Learn More
To learn more about Blitz.js, view [Blitzjs.com](https://blitzjs.com)
## Deploy on Vercel
View the [documentation on deploying to Vercel](https://blitzjs.com/docs/deploy-vercel)

View File

@@ -17,11 +17,3 @@ To get started deploying Brunch with Vercel, you can use the [Brunch CLI](https:
```shell
$ brunch new project-name -s es6
```
### Deploying From Your Terminal
You can deploy your new Brunch project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ To get started with React, along with [Serverless Functions](https://vercel.com/
```shell
$ npx create-react-app my-app
```
### Deploying From Your Terminal
You can deploy your new React project, along with [Serverless Functions](https://vercel.com/docs/v2/serverless-functions/introduction), with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -17,11 +17,3 @@ To get started deploying a Custom Built project with Vercel, you can use the [Ve
```shell
$ vercel init custom-build
```
### Deploying From Your Terminal
You can deploy your new Custom Built project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -15,11 +15,3 @@ To get started with Docusaurus on Vercel, you can use the [Docusaurus CLI](https
```shell
$ npx @docusaurus/init@next init my-website classic
```
### Deploying From Your Terminal
You can deploy your new Docusaurus project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ To get started with Docusaurus for deployment with Vercel, you can use the [Docu
```shell
$ docusaurus-init
```
### Deploying From Your Terminal
You can deploy your new Docusaurus project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -15,11 +15,3 @@ To get started with Dojo on Vercel, you can use the [Dojo CLI](https://github.co
```shell
$ vercel init dojo
```
### Deploying From Your Terminal
You can deploy your new Dojo project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ To get started with Eleventy for deployment with Vercel, you can use [npx](https
```shell
$ npx degit 11ty/eleventy-base-blog my-11ty-project
```
### Deploying From Your Terminal
You can deploy your new Eleventy project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -27,3 +27,6 @@
# Environment Variables
.env
.env.build
# Vercel
.vercel

View File

@@ -19,11 +19,3 @@ To get started with Ember for deployment with Vercel, you can use the [Ember CLI
```shell
$ npx ember-cli new ember-project
```
### Deploying From Your Terminal
You can deploy your new Ember project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -0,0 +1,3 @@
# http://www.robotstxt.org
User-agent: *
Disallow:

View File

@@ -19,11 +19,3 @@ To get started with Gatsby on Vercel, you can use the [Gatsby CLI](https://www.g
```shell
$ gatsby new gatsby-site
```
### Deploying From Your Terminal
You can deploy your new Gatsby project, along with [Serverless Functions](https://vercel.com/docs/v2/serverless-functions/introduction), with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ To get started with Gridsome for deployment with Vercel, you can use the [Gridso
```shell
$ gridsome create my-website
```
### Deploying From Your Terminal
You can deploy your new Gridsome project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ To get started with Hexo for deployment with Vercel, you can use the [Hexo CLI](
```shell
$ hexo init project-name
```
### Deploying From Your Terminal
You can deploy your new Hexo project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -17,11 +17,3 @@ To get started with Hugo for deployment with Vercel, you can use the [Hugo CLI](
```shell
$ hugo new site project-name
```
### Deploying From Your Terminal
You can deploy your new Hugo project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -17,11 +17,3 @@ To get started with Ionic Angular deployed with Vercel, you can use the [Ionic C
```shell
$ npx @ionic/cli start [project-name] conference --type angular && cd [project-name]
```
### Deploying From Your Terminal
You can deploy your new Ionic Angular project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -27,7 +27,7 @@ export class MapPage implements AfterViewInit {
}
const googleMaps = await getGoogleMaps(
'AIzaSyB8pf6ZdFQj5qw7rc_HSGrhUwQKfIe9ICw'
'YOUR_API_KEY_HERE'
);
let map;

View File

@@ -17,11 +17,3 @@ To get started with Ionic React deployed with Vercel, you can use the [Ionic CLI
```shell
$ npx ionic start [project-name] conference --type react && cd [project-name]
```
### Deploying From Your Terminal
You can deploy your new Ionic React project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -17,11 +17,3 @@ To get started with Jekyll for deployment with Vercel, you can use the [Jekyll C
```shell
$ jekyll new my-blog
```
### Deploying From Your Terminal
You can deploy your new Jekyll project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -17,11 +17,3 @@ To get started with Middleman for deployment with Vercel, you can use the [Middl
```shell
$ middleman init project-name
```
### Deploying From Your Terminal
You can deploy your new Middleman project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ $ npx create-nuxt-app my-app
```
> The only change made is to amend the output directory in `nuxt.config.js` to `"/public"`.
### Deploying From Your Terminal
You can deploy your new Nuxt.js project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ To get started with Polymer deployed with Vercel, you can use the [Polymer CLI](
```shell
$ polymer init
```
### Deploying From Your Terminal
You can deploy your new Polymer project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ To get started with Preact for deployment with Vercel, you can use the [Preact C
```shell
$ preact create default my-project
```
### Deploying From Your Terminal
You can deploy your new Preact project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ To get started with RedwoodJS on Vercel, you can [use Yarn to initialize](https:
```shell
$ yarn create redwood-app ./my-redwood-app
```
### Deploying From Your Terminal
You can deploy your new RedwoodJS project, along with [Serverless Functions](https://vercel.com/docs/v2/serverless-functions/introduction), with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ To get started with Saber on Vercel, you can use [`npm init`](https://docs.npmjs
```shell
$ npm init site my-saber-site
```
### Deploying From Your Terminal
You can deploy your new Saber project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ $ npx degit "sveltejs/sapper-template#webpack" my-sapper-app
```
> The only change made is to change the build script in `package.json` to be `"sapper export"`.
### Deploying From Your Terminal
You can deploy your new Sapper project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ To get started deploying Scully with Vercel, you can use the [Vercel CLI](https:
```shell
$ vercel init scully
```
### Deploying From Your Terminal
You can deploy your new Scully project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -17,11 +17,3 @@ To get started with Stencil deployed with Vercel, you can use the [Stencil proje
```shell
$ npm init stencil
```
### Deploying From Your Terminal
You can deploy your new Stencil project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -17,11 +17,3 @@ To get started with Svelte, along with [Serverless Functions](https://vercel.com
```shell
$ npx degit sveltejs/template my-svelte-project
```
### Deploying From Your Terminal
You can deploy your new Svelte project, along with [Serverless Functions](https://vercel.com/docs/v2/serverless-functions/introduction), with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -19,11 +19,3 @@ To get started with UmiJS deployed with Vercel, you can use the [Umi CLI](https:
```shell
$ yarn create umi app-name
```
### Deploying From Your Terminal
You can deploy your new UmiJS project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
```shell
$ vercel
```

View File

@@ -17,7 +17,7 @@
"devDependencies": {
"@typescript-eslint/eslint-plugin": "2.0.0",
"@typescript-eslint/parser": "2.0.0",
"@zeit/ncc": "0.20.4",
"@vercel/ncc": "0.24.0",
"async-retry": "1.2.3",
"buffer-replace": "1.0.0",
"cheerio": "1.0.0-rc.3",
@@ -27,7 +27,7 @@
"husky": "3.0.4",
"json5": "2.1.1",
"lint-staged": "9.2.5",
"node-fetch": "2.6.0",
"node-fetch": "2.6.1",
"npm-package-arg": "6.1.0",
"prettier": "2.0.5"
},

View File

@@ -59,7 +59,7 @@
}
},
{
"name": "Gatsby",
"name": "Gatsby.js",
"slug": "gatsby",
"demo": "https://gatsby.now-examples.now.sh",
"logo": "https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/gatsby.svg",
@@ -261,7 +261,7 @@
}
},
{
"name": "Ember",
"name": "Ember.js",
"slug": "ember",
"demo": "https://ember.now-examples.now.sh",
"logo": "https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/ember.svg",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/frameworks",
"version": "0.1.0",
"version": "0.1.1",
"main": "frameworks.json",
"license": "UNLICENSED",
"scripts": {

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/build-utils",
"version": "2.5.0",
"version": "2.5.3",
"license": "MIT",
"main": "./dist/index.js",
"types": "./dist/index.d.js",
@@ -29,7 +29,8 @@
"@types/node-fetch": "^2.1.6",
"@types/semver": "6.0.0",
"@types/yazl": "^2.4.1",
"@vercel/frameworks": "0.1.0",
"@vercel/frameworks": "0.1.1",
"@vercel/ncc": "0.24.0",
"aggregate-error": "3.0.1",
"async-retry": "1.2.3",
"async-sema": "2.1.4",
@@ -43,7 +44,7 @@
"js-yaml": "3.13.1",
"minimatch": "3.0.4",
"multistream": "2.1.1",
"node-fetch": "2.2.0",
"node-fetch": "2.6.1",
"semver": "6.1.1",
"ts-jest": "24.1.0",
"typescript": "3.9.3",

View File

@@ -978,9 +978,10 @@ function getRouteResult(
// to avoid enumerating serverless function names.
// But it causes issues in `vc dev` for frameworks that handle
// their own functions such as redwood, so we ignore.
errorRoutes.push({
status: 404,
rewriteRoutes.push({
src: '^/api(/.*)?$',
status: 404,
continue: true,
});
}
} else {

View File

@@ -107,6 +107,13 @@ export interface BuildOptions {
*/
workPath: string;
/**
* The "Root Directory" is assigned to the `workPath` so the `repoRootPath`
* is the Git Repository Root. This is only relevant for Monorepos.
* See https://vercel.com/blog/monorepos
*/
repoRootPath?: string;
/**
* An arbitrary object passed by the user in the build definition defined
* in `vercel.json`.

View File

@@ -947,18 +947,10 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
expect(redirectRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
},
]);
expect(rewriteRoutes!.length).toBe(1);
expect((rewriteRoutes![0] as Source).status).toBe(404);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('no package.json + no build + raw static + api', async () => {
@@ -982,18 +974,10 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
expect(redirectRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
},
]);
expect(rewriteRoutes!.length).toBe(1);
expect((rewriteRoutes![0] as Source).status).toBe(404);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('package.json + no build + root + api', async () => {
@@ -1031,19 +1015,11 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
expect(redirectRoutes).toStrictEqual([]);
expect(rewriteRoutes!.length).toBe(1);
expect(rewriteRoutes!.length).toBe(2);
expect((rewriteRoutes![0] as Source).src).toBe('^/api/([^/]+)/([^/]+)$');
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
},
]);
expect((rewriteRoutes![1] as Source).status).toBe(404);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('api + next + public', async () => {
@@ -1070,13 +1046,9 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
expect(redirectRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
]);
expect(rewriteRoutes!.length).toBe(1);
expect((rewriteRoutes![0] as Source).status).toBe(404);
expect(errorRoutes).toStrictEqual([]);
});
it('api + next + raw static', async () => {
@@ -1103,13 +1075,9 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
expect(redirectRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
]);
expect(rewriteRoutes!.length).toBe(1);
expect((rewriteRoutes![0] as Source).status).toBe(404);
expect(errorRoutes).toStrictEqual([]);
});
it('Using "Other" framework with Storybook should NOT autodetect Next.js for new projects', async () => {
@@ -1154,13 +1122,8 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
},
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
},
]);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('Using "Other" framework should autodetect Next.js for old projects', async () => {
@@ -1218,18 +1181,10 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
expect(redirectRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
},
]);
expect(rewriteRoutes!.length).toBe(1);
expect((rewriteRoutes![0] as Source).status).toBe(404);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('api + raw static + package.json no build script', async () => {
@@ -1256,18 +1211,10 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
expect(redirectRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
},
]);
expect(rewriteRoutes!.length).toBe(1);
expect((rewriteRoutes![0] as Source).status).toBe(404);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('api + public', async () => {
@@ -1286,17 +1233,8 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(builders![1].use).toBe('@vercel/static');
expect(builders![1].src).toBe('public/**/*');
expect(builders!.length).toBe(2);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
},
]);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('api go with test files', async () => {
@@ -1315,27 +1253,13 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
'api/src/controllers/user.module_test.go',
];
const { builders, rewriteRoutes, errorRoutes } = await detectBuilders(
files,
undefined,
{
featHandleMiss,
}
);
const { builders, errorRoutes } = await detectBuilders(files, undefined, {
featHandleMiss,
});
expect(builders!.length).toBe(7);
expect(builders!.some(b => b.src.endsWith('_test.go'))).toBe(false);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
},
]);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('just public', async () => {
@@ -1412,17 +1336,8 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/[endpoint].js');
expect(builders!.length).toBe(1);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
},
]);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('package.json with no build + public directory', async () => {
@@ -1541,31 +1456,17 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
it('many static files + one api file', async () => {
const files = Array.from({ length: 5000 }).map((_, i) => `file${i}.html`);
files.push('api/index.ts');
const { builders, rewriteRoutes, errorRoutes } = await detectBuilders(
files,
undefined,
{
featHandleMiss,
}
);
const { builders, errorRoutes } = await detectBuilders(files, undefined, {
featHandleMiss,
});
expect(builders!.length).toBe(2);
expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/index.ts');
expect(builders![1].use).toBe('@vercel/static');
expect(builders![1].src).toBe('!{api/**,package.json}');
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
},
]);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('functions with nextjs', async () => {
@@ -1957,18 +1858,10 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
expect(redirectRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
},
]);
expect(rewriteRoutes!.length).toBe(1);
expect((rewriteRoutes![0] as Source).status).toBe(404);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('Framework with non-package.json entrypoint', async () => {
@@ -2135,14 +2028,10 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
const files = ['config.rb', 'api/date.rb'];
const projectSettings = { framework: 'middleman' };
const { builders, rewriteRoutes, errorRoutes } = await detectBuilders(
files,
null,
{
projectSettings,
featHandleMiss,
}
);
const { builders, errorRoutes } = await detectBuilders(files, null, {
projectSettings,
featHandleMiss,
});
expect(builders).toEqual([
{
@@ -2161,18 +2050,8 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
},
},
]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
},
]);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('Error for non-api functions', async () => {
@@ -2426,12 +2305,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
check: true,
},
]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
continue: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/(?!.*api).*$',
@@ -2439,8 +2320,7 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
},
]);
const apiPattern = new RegExp(errorRoutes![0].src!);
const customPattern = new RegExp(errorRoutes![1].src!);
const pattern = new RegExp(errorRoutes![0].src!);
[
'/',
@@ -2454,8 +2334,7 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
'/another/sub/page.html',
'/another/sub/page',
].forEach(file => {
expect(file).not.toMatch(apiPattern);
expect(file).toMatch(customPattern);
expect(file).toMatch(pattern);
});
[
@@ -2469,8 +2348,7 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
'/api/sub/page.html',
'/api/sub/page',
].forEach(file => {
expect(file).toMatch(apiPattern);
expect(file).not.toMatch(customPattern);
expect(file).not.toMatch(pattern);
});
}
@@ -2508,13 +2386,9 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
{
const files = ['api/[endpoint].js', 'api/[endpoint]/[id].js'];
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
files,
null,
{
featHandleMiss,
}
);
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, null, {
featHandleMiss,
});
expect(defaultRoutes).toStrictEqual([
{ handle: 'miss' },
{
@@ -2534,16 +2408,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
dest: '/api/[endpoint]?endpoint=$1',
check: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
continue: true,
},
]);
}
@@ -2555,13 +2423,9 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
'api/[endpoint]/[id].js',
];
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
files,
null,
{
featHandleMiss,
}
);
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, null, {
featHandleMiss,
});
expect(defaultRoutes).toStrictEqual([
{ handle: 'miss' },
{
@@ -2582,16 +2446,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
dest: '/api/[endpoint]?endpoint=$1',
check: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
continue: true,
},
]);
}
@@ -2609,13 +2467,9 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
const files = ['public/index.html', 'api/[endpoint].js'];
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
files,
pkg,
{
featHandleMiss,
}
);
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, pkg, {
featHandleMiss,
});
expect(defaultRoutes).toStrictEqual([
{ handle: 'miss' },
{
@@ -2630,16 +2484,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
dest: '/api/[endpoint]?endpoint=$1',
check: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
continue: true,
},
]);
}
@@ -2656,13 +2504,9 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
{
const files = ['api/date/index.js', 'api/date.js'];
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
files,
null,
{
featHandleMiss,
}
);
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, null, {
featHandleMiss,
});
expect(defaultRoutes).toStrictEqual([
{ handle: 'miss' },
{
@@ -2671,16 +2515,12 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
check: true,
},
]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
continue: true,
},
]);
}
@@ -2688,13 +2528,9 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
{
const files = ['api/date.js', 'api/[date]/index.js'];
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
files,
null,
{
featHandleMiss,
}
);
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, null, {
featHandleMiss,
});
expect(defaultRoutes).toStrictEqual([
{ handle: 'miss' },
{
@@ -2709,16 +2545,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
dest: '/api/[date]/index?date=$1',
check: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
continue: true,
},
]);
}
@@ -2732,13 +2562,9 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
'api/food.ts',
'api/ts/gold.ts',
];
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
files,
null,
{
featHandleMiss,
}
);
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, null, {
featHandleMiss,
});
expect(defaultRoutes).toStrictEqual([
{ handle: 'miss' },
@@ -2748,16 +2574,12 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
check: true,
},
]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
continue: true,
},
]);
}
@@ -2767,14 +2589,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
const functions = { 'api/user.php': { runtime: 'vercel-php@0.1.0' } };
const files = ['api/user.php'];
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
files,
null,
{
functions,
featHandleMiss,
}
);
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, null, {
functions,
featHandleMiss,
});
expect(defaultRoutes).toStrictEqual([
{ handle: 'miss' },
{
@@ -2783,16 +2601,12 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
check: true,
},
]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404.html',
continue: true,
},
]);
}
@@ -2823,12 +2637,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
continue: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/(?!.*api).*$',
@@ -2903,7 +2719,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
@@ -2918,16 +2733,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
dest: '/api/[endpoint]?endpoint=$1',
check: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -2943,7 +2752,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
@@ -2958,16 +2766,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
dest: '/api/[endpoint]?endpoint=$1',
check: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -2989,7 +2791,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, pkg, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
@@ -2999,16 +2800,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
dest: '/api/[endpoint]?endpoint=$1',
check: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -3027,20 +2822,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -3052,7 +2841,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
@@ -3062,16 +2850,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
dest: '/api/[date]/index?date=$1',
check: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -3089,20 +2871,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -3116,20 +2892,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, { functions, ...options });
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -3157,20 +2927,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
@@ -3211,7 +2975,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
@@ -3226,16 +2989,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
dest: '/api/[endpoint]?endpoint=$1',
check: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -3251,7 +3008,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
@@ -3266,16 +3022,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
dest: '/api/[endpoint]?endpoint=$1',
check: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -3297,7 +3047,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, pkg, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
@@ -3307,16 +3056,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
dest: '/api/[endpoint]?endpoint=$1',
check: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -3328,20 +3071,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -3353,7 +3090,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
@@ -3363,16 +3099,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
dest: '/api/[date]/index?date=$1',
check: true,
},
]);
expect(errorRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -3390,20 +3120,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, options);
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}
@@ -3417,20 +3141,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
defaultRoutes,
redirectRoutes,
rewriteRoutes,
errorRoutes,
} = await detectBuilders(files, null, { functions, ...options });
testHeaders(redirectRoutes);
expect(defaultRoutes).toStrictEqual([]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
},
{
status: 404,
src: '^/(?!.*api).*$',
dest: '/404',
continue: true,
},
]);
}

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "20.0.0",
"version": "20.1.1",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -61,11 +61,11 @@
"node": ">= 10"
},
"dependencies": {
"@vercel/build-utils": "2.5.0",
"@vercel/go": "1.1.5",
"@vercel/node": "1.8.0",
"@vercel/python": "1.2.2",
"@vercel/ruby": "1.2.3",
"@vercel/build-utils": "2.5.3",
"@vercel/go": "1.1.6",
"@vercel/node": "1.8.3",
"@vercel/python": "1.2.3",
"@vercel/ruby": "1.2.4",
"update-notifier": "4.1.0"
},
"devDependencies": {
@@ -100,9 +100,9 @@
"@types/universal-analytics": "0.4.2",
"@types/which": "1.3.2",
"@types/write-json-file": "2.2.1",
"@vercel/frameworks": "0.1.0",
"@vercel/frameworks": "0.1.1",
"@vercel/ncc": "0.24.0",
"@zeit/fun": "0.11.2",
"@zeit/ncc": "0.18.5",
"@zeit/source-map-support": "0.6.2",
"ajv": "6.12.2",
"alpha-sort": "2.0.1",
@@ -134,7 +134,7 @@
"fs-extra": "7.0.1",
"get-port": "5.1.1",
"glob": "7.1.2",
"http-proxy": "1.17.0",
"http-proxy": "1.18.1",
"inquirer": "7.0.4",
"is-port-reachable": "3.0.0",
"is-url": "1.2.2",
@@ -147,7 +147,7 @@
"mri": "1.1.5",
"ms": "2.1.2",
"nanoid": "3.0.2",
"node-fetch": "2.6.0",
"node-fetch": "2.6.1",
"npm-package-arg": "6.1.0",
"nyc": "13.2.0",
"ora": "3.4.0",
@@ -168,7 +168,7 @@
"text-table": "0.2.0",
"title": "3.4.1",
"tmp-promise": "1.0.3",
"tree-kill": "1.2.1",
"tree-kill": "1.2.2",
"ts-node": "8.3.0",
"typescript": "3.9.3",
"universal-analytics": "0.4.20",

View File

@@ -49,18 +49,12 @@ async function main() {
// Do the initial `ncc` build
console.log();
const src = join(dirRoot, 'src');
const args = [
'@zeit/ncc',
'build',
'--source-map',
'--external',
'update-notifier',
];
if (!isDev) {
args.push('--minify');
const args = ['ncc', 'build', '--external', 'update-notifier'];
if (isDev) {
args.push('--source-map');
}
args.push(src);
await execa('npx', args, { stdio: 'inherit' });
await execa('yarn', args, { stdio: 'inherit' });
// `ncc` has some issues with `@zeit/fun`'s runtime files:
// - Executable bits on the `bootstrap` files appear to be lost:

View File

@@ -96,7 +96,7 @@ export default async function set(
return 1;
}
// For `now alias set <argument>`
// For `vercel alias set <argument>`
if (args.length === 1) {
const deployment = handleCertError(
output,
@@ -261,7 +261,7 @@ function handleSetupDomainError<T>(
{ extraSpace: ' ' }
)}\n\n`
);
output.print(' Read more: https://err.sh/now/domain-verification\n');
output.print(' Read more: https://err.sh/vercel/domain-verification\n');
return 1;
}

View File

@@ -75,7 +75,7 @@ export default async function issue(
}
if (crtPath || keyPath || caPath) {
if (args.length !== 0 || (!crtPath || !keyPath || !caPath)) {
if (args.length !== 0 || !crtPath || !keyPath || !caPath) {
output.error(
`Invalid number of arguments to create a custom certificate entry. Usage:`
);
@@ -230,6 +230,8 @@ async function runStartOrder(
output.print(
` ${chalk.cyan(getCommandName(`certs issue ${cns.join(' ')}`))}\n`
);
output.print(' Read more: https://err.sh/now/solve-challenges-manually\n');
output.print(
' Read more: https://err.sh/vercel/solve-challenges-manually\n'
);
return 0;
}

View File

@@ -1,7 +1,5 @@
import chalk from 'chalk';
import logo from '../../util/output/logo';
import code from '../../util/output/code';
import note from '../../util/output/note';
import { getPkgName } from '../../util/pkg-name.ts';
export const help = () => `
@@ -70,12 +68,6 @@ export const help = () => `
--prod Create a production deployment
-c, --confirm Confirm default options and skip questions
${note(
`To view the usage information for Now 1.0, run ${code(
`${getPkgName()} help deploy-v1`
)}`
)}
${chalk.dim('Examples:')}
${chalk.gray('')} Deploy the current directory

View File

@@ -104,7 +104,7 @@ const printDeploymentStatus = async (
if (readyState !== 'READY') {
output.error(
`Your deployment failed. Please retry later. More: https://err.sh/now/deployment-error`
`Your deployment failed. Please retry later. More: https://err.sh/vercel/deployment-error`
);
return 1;
}
@@ -157,17 +157,21 @@ const printDeploymentStatus = async (
}
if (indications) {
const indent = process.stdout.isTTY ? ' ' : ''; // if using emojis
const newline = '\n';
for (let indication of indications) {
output.print(
prependEmoji(
`${chalk.dim(indication.payload)}`,
emoji(indication.type)
) +
`\n` +
(indication.link
? `${indication.action || 'Learn More'}: ${indication.link}\n\n`
: '')
);
const message =
prependEmoji(chalk.dim(indication.payload), emoji(indication.type)) +
newline;
let link = '';
if (indication.link)
link =
indent +
chalk.dim(
`${indication.action || 'Learn More'}: ${indication.link}`
) +
newline;
output.print(message + link);
}
}
};
@@ -243,11 +247,6 @@ export default async function main(
const { isFile, path } = pathValidation;
const autoConfirm = argv['--confirm'] || isFile;
// --no-scale
if (argv['--no-scale']) {
warn(`The option --no-scale is only supported on Now 1.0 deployments`);
}
// deprecate --name
if (argv['--name']) {
output.print(
@@ -276,6 +275,7 @@ export default async function main(
let { org, project, status } = link;
let newProjectName = null;
let rootDirectory = project ? project.rootDirectory : null;
let sourceFilesOutsideRootDirectory = true;
if (status === 'not_linked') {
const shouldStartSetup =
@@ -333,6 +333,7 @@ export default async function main(
} else {
project = projectOrNewProjectName;
rootDirectory = project.rootDirectory;
sourceFilesOutsideRootDirectory = project.sourceFilesOutsideRootDirectory;
// we can already link the project
await linkFolderToProject(
@@ -349,7 +350,12 @@ export default async function main(
}
}
const sourcePath = rootDirectory ? join(path, rootDirectory) : path;
// if we have `sourceFilesOutsideRootDirectory` set to `true`, we use the current path
// and upload the entire directory.
const sourcePath =
rootDirectory && !sourceFilesOutsideRootDirectory
? join(path, rootDirectory)
: path;
if (
rootDirectory &&
@@ -368,7 +374,7 @@ export default async function main(
// If Root Directory is used we'll try to read the config
// from there instead and use it if it exists.
if (rootDirectory) {
const rootDirectoryConfig = readLocalConfig(sourcePath);
const rootDirectoryConfig = readLocalConfig(join(path, rootDirectory));
if (rootDirectoryConfig) {
debug(`Read local config from root directory (${rootDirectory})`);
@@ -525,6 +531,11 @@ export default async function main(
skipAutoDetectionConfirmation: autoConfirm,
};
if (!localConfig.builds || localConfig.builds.length === 0) {
// Only add projectSettings for zero config deployments
createArgs.projectSettings = { sourceFilesOutsideRootDirectory };
}
deployment = await createDeploy(
output,
now,
@@ -546,6 +557,10 @@ export default async function main(
projectSettings.rootDirectory = rootDirectory;
}
if (typeof sourceFilesOutsideRootDirectory !== 'undefined') {
projectSettings.sourceFilesOutsideRootDirectory = sourceFilesOutsideRootDirectory;
}
const settings = await editProjectSettings(
output,
projectSettings,

View File

@@ -99,7 +99,7 @@ export default async function main(ctx: NowContext) {
'package.json'
)} must not contain ${cmd('now dev')}`
);
output.error(`Learn More: http://err.sh/now/now-dev-as-dev-script`);
output.error(`Learn More: http://err.sh/vercel/now-dev-as-dev-script`);
return 1;
}
if (scripts && scripts.dev && /\bvercel\b\W+\bdev\b/.test(scripts.dev)) {
@@ -108,7 +108,7 @@ export default async function main(ctx: NowContext) {
'package.json'
)} must not contain ${cmd('vercel dev')}`
);
output.error(`Learn More: http://err.sh/now/now-dev-as-dev-script`);
output.error(`Learn More: http://err.sh/vercel/now-dev-as-dev-script`);
return 1;
}
}

View File

@@ -66,7 +66,10 @@ export default async function ls(
const cancelWait = wait(`Fetching Domains under ${chalk.bold(contextName)}`);
const { domains, pagination } = await getDomains(client).finally(() => {
const { domains, pagination } = await getDomains(
client,
nextTimestamp
).finally(() => {
cancelWait();
});

View File

@@ -67,13 +67,15 @@ export default function handleCertError<T>(
output.print(
` ${getCommandName(`certs issue --challenge-only <cns>`)}\n`
);
output.print(' Read more: https://err.sh/now/dns-configuration-error\n');
output.print(
' Read more: https://err.sh/vercel/dns-configuration-error\n'
);
} else {
output.print(
` We configured them for you, but the propagation may take a few minutes. Please try again later.\n`
);
output.print(
' Read more: https://err.sh/now/dns-configuration-error\n\n'
' Read more: https://err.sh/vercel/dns-configuration-error\n\n'
);
}
return 1;

View File

@@ -999,7 +999,7 @@ export class MissingDotenvVarsError extends NowError<
].join('\n');
}
message += '\nRead more: https://err.sh/now/missing-env-file';
message += '\nRead more: https://err.sh/vercel/missing-env-file';
super({
code: 'MISSING_DOTENV_VARS',

View File

@@ -186,7 +186,7 @@ export default class Now extends EventEmitter {
const { key } = error;
err.message =
`The env key ${key} has an invalid type: ${typeof env[key]}. ` +
'Please supply a String or a Number (https://err.sh/now-cli/env-value-invalid-type)';
'Please supply a String or a Number (https://err.sh/vercel-cli/env-value-invalid-type)';
} else if (code === 'unreferenced_build_specifications') {
const count = unreferencedBuildSpecs.length;
const prefix = count === 1 ? 'build' : 'builds';

View File

@@ -59,6 +59,7 @@ export default async function setupAndLink(
const isTTY = process.stdout.isTTY;
const quiet = !isTTY;
let rootDirectory: string | null = null;
let sourceFilesOutsideRootDirectory = true;
let newProjectName: string;
let org;
@@ -129,7 +130,13 @@ export default async function setupAndLink(
);
return { status: 'linked', org, project };
}
const sourcePath = rootDirectory ? join(path, rootDirectory) : path;
// if we have `sourceFilesOutsideRootDirectory` set to `true`, we use the current path
// and upload the entire directory.
const sourcePath =
rootDirectory && !sourceFilesOutsideRootDirectory
? join(path, rootDirectory)
: path;
if (
rootDirectory &&
@@ -174,6 +181,11 @@ export default async function setupAndLink(
skipAutoDetectionConfirmation: false,
};
if (!localConfig.builds || localConfig.builds.length === 0) {
// Only add projectSettings for zero config deployments
createArgs.projectSettings = { sourceFilesOutsideRootDirectory };
}
const deployment = await createDeploy(
output,
now,

View File

@@ -33,7 +33,7 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
boxen?: boxen.Options;
}
) {
const details = slug ? `https://err.sh/now/${slug}` : link;
const details = slug ? `https://err.sh/vercel/${slug}` : link;
print(
boxen(
@@ -66,7 +66,7 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
action = 'Learn More'
) {
print(`${chalk.red(`Error!`)} ${str}\n`);
const details = slug ? `https://err.sh/now/${slug}` : link;
const details = slug ? `https://err.sh/vercel/${slug}` : link;
if (details) {
print(`${chalk.bold(action)}: ${renderLink(details)}\n`);
}

View File

@@ -10,7 +10,7 @@ export default function error(...input: string[] | [APIError]) {
if (typeof input[0] === 'object') {
const { slug, message, link, action = 'Learn More' } = input[0];
messages = [message];
const details = slug ? `https://err.sh/now/${slug}` : link;
const details = slug ? `https://err.sh/vercel/${slug}` : link;
if (details) {
messages.push(`${chalk.bold(action)}: ${renderLink(details)}`);
}

View File

@@ -1,5 +1,68 @@
{
"compilerOptions": {
"module": "CommonJS"
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Basic Options */
// "incremental": true, /* Enable incremental compilation */
"module": "CommonJS",
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */,
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
/* Advanced Options */
"skipLibCheck": true /* Skip type checking of declaration files. */,
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
}
}

View File

@@ -10,7 +10,7 @@ import retry from 'async-retry';
import { satisfies } from 'semver';
import { getDistTag } from '../../src/util/get-dist-tag';
import { version as cliVersion } from '../../package.json';
import { fetchTokenWithRetry } from '../../../../test/lib/deployment/now-deploy';
import { fetchCachedToken } from '../../../../test/lib/deployment/now-deploy';
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const isCanary = () => getDistTag(cliVersion) === 'canary';
@@ -245,7 +245,7 @@ function testFixtureStdio(
const cwd = isExample
? exampleAbsolute(directory)
: fixtureAbsolute(directory);
const token = await fetchTokenWithRetry();
const token = await fetchCachedToken();
let deploymentUrl;
// Deploy fixture and link project

View File

@@ -90,7 +90,7 @@ module.exports = async function prepare(session) {
}),
'now-build.js': `
const fs = require('fs');
fs.writeFileSync(
fs.writeFileSync(
'index.js',
fs.readFileSync('index.js', 'utf8')
.replace('BUILD_ENV_DEBUG', process.env.NOW_BUILDER_DEBUG ? 'on' : 'off'),

View File

@@ -2365,7 +2365,6 @@ test('invalid `--token`', async t => {
);
});
// We need to skip this test until `now-php` supports Runtime version 3
test('deploy a Lambda with a specific runtime', async t => {
const directory = fixture('lambda-with-php-runtime');
const output = await execute([directory, '--public', '--confirm']);
@@ -2374,7 +2373,8 @@ test('deploy a Lambda with a specific runtime', async t => {
const { host: url } = new URL(output.stdout);
const [build] = await getDeploymentBuildsByUrl(url);
const builds = await getDeploymentBuildsByUrl(url);
const build = builds.find(b => b.use && b.use.includes('php')) || builds[0];
t.is(build.use, 'vercel-php@0.1.0', JSON.stringify(build, null, 2));
});

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/client",
"version": "9.0.0",
"version": "9.0.2",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"homepage": "https://vercel.com",
@@ -26,7 +26,6 @@
"@types/node": "12.0.4",
"@types/node-fetch": "2.5.4",
"@types/recursive-readdir": "2.2.0",
"@zeit/ncc": "0.18.5",
"typescript": "3.9.3"
},
"jest": {
@@ -38,14 +37,14 @@
]
},
"dependencies": {
"@vercel/build-utils": "2.5.0",
"@vercel/build-utils": "2.5.3",
"@zeit/fetch": "5.2.0",
"async-retry": "1.2.3",
"async-sema": "3.0.0",
"fs-extra": "8.0.1",
"ignore": "4.0.6",
"ms": "2.1.2",
"node-fetch": "2.6.0",
"node-fetch": "2.6.1",
"querystring": "^0.2.0",
"recursive-readdir": "2.2.2",
"sleep-promise": "8.0.1"

View File

@@ -1,10 +1,10 @@
const {
fetchTokenWithRetry,
fetchCachedToken,
// eslint-disable-next-line @typescript-eslint/no-var-requires
} = require('../../../test/lib/deployment/now-deploy.js');
export async function generateNewToken(): Promise<string> {
const token = await fetchTokenWithRetry();
const token = await fetchCachedToken();
return token;
}

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/go",
"version": "1.1.5",
"version": "1.1.6",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
@@ -25,6 +25,7 @@
"@types/fs-extra": "^5.0.5",
"@types/node-fetch": "^2.3.0",
"@types/tar": "^4.0.0",
"@vercel/ncc": "0.24.0",
"async-retry": "1.3.1",
"execa": "^1.0.0",
"fs-extra": "^7.0.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/next",
"version": "2.6.23",
"version": "2.6.26",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
@@ -26,7 +26,7 @@
"@types/resolve-from": "5.0.1",
"@types/semver": "6.0.0",
"@types/yazl": "2.4.1",
"@zeit/node-file-trace": "0.8.2",
"@vercel/nft": "0.9.2",
"async-sema": "3.0.1",
"buffer-crc32": "0.2.13",
"escape-string-regexp": "3.0.0",

View File

@@ -16,7 +16,7 @@ import {
convertRedirects,
convertRewrites,
} from '@vercel/routing-utils/dist/superstatic';
import { nodeFileTrace, NodeFileTraceReasons } from '@zeit/node-file-trace';
import { nodeFileTrace, NodeFileTraceReasons } from '@vercel/nft';
import { Sema } from 'async-sema';
import { ChildProcess, fork } from 'child_process';
import escapeStringRegexp from 'escape-string-regexp';
@@ -213,6 +213,7 @@ function startDevServer(entryPath: string, runtimeEnv: EnvConfig) {
export const build = async ({
files,
workPath,
repoRootPath,
entrypoint,
config = {} as Config,
meta = {} as BuildParamsMeta,
@@ -231,6 +232,7 @@ export const build = async ({
const entryPath = path.join(workPath, entryDirectory);
const outputDirectory = config.outputDirectory || '.next';
const dotNextStatic = path.join(entryPath, outputDirectory, 'static');
const baseDir = repoRootPath || workPath;
await download(files, workPath, meta);
@@ -240,7 +242,7 @@ export const build = async ({
const spawnOpts = getSpawnOptions(meta, nodeVersion);
const nowJsonPath = await findUp(['now.json', 'vercel.json'], {
cwd: path.join(workPath, path.dirname(entrypoint)),
cwd: entryPath,
});
let hasLegacyRoutes = false;
@@ -755,10 +757,16 @@ export const build = async ({
],
};
const lambdaOptions = await getLambdaOptionsFromFunction({
sourceFile: await getSourceFilePathFromPage({ workPath, page }),
config,
});
let lambdaOptions = {};
if (config && config.functions) {
lambdaOptions = await getLambdaOptionsFromFunction({
sourceFile: await getSourceFilePathFromPage({
workPath: entryPath,
page,
}),
config,
});
}
debug(`Creating serverless function for page: "${page}"...`);
lambdas[path.join(entryDirectory, pathname)] = await createLambda({
@@ -864,7 +872,7 @@ export const build = async ({
};
const isApiPage = (page: string) =>
page.replace(/\\/g, '/').match(/serverless\/pages\/api/);
page.replace(/\\/g, '/').match(/serverless\/pages\/api(\/|\.js$)/);
const canUsePreviewMode = Object.keys(pages).some(page =>
isApiPage(pages[page].fsPath)
@@ -939,12 +947,18 @@ export const build = async ({
const {
fileList: apiFileList,
reasons: apiReasons,
} = await nodeFileTrace(apiPages, { base: workPath });
} = await nodeFileTrace(apiPages, {
base: baseDir,
processCwd: entryPath,
});
const {
fileList,
reasons: nonApiReasons,
} = await nodeFileTrace(nonApiPages, { base: workPath });
const { fileList, reasons: nonApiReasons } = await nodeFileTrace(
nonApiPages,
{
base: baseDir,
processCwd: entryPath,
}
);
debug(`node-file-trace result for pages: ${fileList}`);
@@ -962,7 +976,7 @@ export const build = async ({
// Initial files are manually added to the lambda later
return;
}
const filePath = path.join(workPath, file);
const filePath = path.join(baseDir, file);
if (!lstatResults[filePath]) {
lstatResults[filePath] = lstatSema
@@ -973,7 +987,7 @@ export const build = async ({
const { mode } = await lstatResults[filePath];
files[file] = new FileFsRef({
fsPath: path.join(workPath, file),
fsPath: path.join(baseDir, file),
mode,
});
};
@@ -1158,7 +1172,11 @@ export const build = async ({
const {
pseudoLayer: pageLayer,
pseudoLayerBytes: pageLayerBytes,
} = await createPseudoLayer({ [pageFileName]: pages[page] });
} = await createPseudoLayer({
[path.join(path.relative(baseDir, entryPath), pageFileName)]: pages[
page
],
});
currentLambdaGroup.pages[outputName] = {
pageLayer,
@@ -1194,21 +1212,31 @@ export const build = async ({
}
const pageFileName = path.normalize(
path.relative(workPath, pages[page].fsPath)
path.relative(entryPath, pages[page].fsPath)
);
const launcher = launcherData.replace(
/__LAUNCHER_PAGE_PATH__/g,
JSON.stringify(requiresTracing ? `./${pageFileName}` : './page')
);
const launcherFiles: { [name: string]: FileFsRef | FileBlob } = {
'now__bridge.js': new FileFsRef({
[path.join(
path.relative(baseDir, entryPath),
'now__bridge.js'
)]: new FileFsRef({
fsPath: path.join(__dirname, 'now__bridge.js'),
}),
'now__launcher.js': new FileBlob({ data: launcher }),
[path.join(
path.relative(baseDir, entryPath),
'now__launcher.js'
)]: new FileBlob({ data: launcher }),
};
const lambdaOptions = await getLambdaOptionsFromFunction({
sourceFile: await getSourceFilePathFromPage({ workPath, page }),
sourceFile: await getSourceFilePathFromPage({
workPath: entryPath,
page,
}),
config,
});
@@ -1218,10 +1246,16 @@ export const build = async ({
lambdas[outputName] = await createLambdaFromPseudoLayers({
files: {
...launcherFiles,
[requiresTracing ? pageFileName : 'page.js']: pages[page],
[path.join(
path.relative(baseDir, entryPath),
pageFileName
)]: pages[page],
},
layers: isApiPage(pageFileName) ? apiPseudoLayers : pseudoLayers,
handler: 'now__launcher.launcher',
handler: path.join(
path.relative(baseDir, entryPath),
'now__launcher.launcher'
),
runtime: nodeVersion.runtime,
...lambdaOptions,
});
@@ -1231,7 +1265,7 @@ export const build = async ({
...launcherFiles,
...assets,
...tracedFiles,
[requiresTracing ? pageFileName : 'page.js']: pages[page],
['page.js']: pages[page],
},
handler: 'now__launcher.launcher',
runtime: nodeVersion.runtime,
@@ -1293,7 +1327,7 @@ export const build = async ({
${groupPageKeys
.map(
page =>
`'${page}': require('./${path.join(
`'${page}': () => require('./${path.join(
'./',
group.pages[page].pageFileName
)}')`
@@ -1302,7 +1336,7 @@ export const build = async ({
${
'' /*
creates a mapping of the page and the page's module e.g.
'/about': require('./.next/serverless/pages/about.js')
'/about': () => require('./.next/serverless/pages/about.js')
*/
}
}
@@ -1362,7 +1396,10 @@ export const build = async ({
res.statusCode = 500
return res.end('internal server error')
}
const method = currentPage.render || currentPage.default || currentPage
const mod = currentPage()
const method = mod.render || mod.default || mod
return method(req, res)
} catch (err) {
console.error('Unhandled error during request:', err)
@@ -1372,10 +1409,16 @@ export const build = async ({
`
);
const launcherFiles: { [name: string]: FileFsRef | FileBlob } = {
'now__bridge.js': new FileFsRef({
[path.join(
path.relative(baseDir, entryPath),
'now__bridge.js'
)]: new FileFsRef({
fsPath: path.join(__dirname, 'now__bridge.js'),
}),
'now__launcher.js': new FileBlob({ data: launcher }),
[path.join(
path.relative(baseDir, entryPath),
'now__launcher.js'
)]: new FileBlob({ data: launcher }),
};
const pageLayers: PseudoLayer[] = [];
@@ -1397,7 +1440,10 @@ export const build = async ({
...(group.isApiLambda ? apiPseudoLayers : pseudoLayers),
...pageLayers,
],
handler: 'now__launcher.launcher',
handler: path.join(
path.relative(baseDir, entryPath),
'now__launcher.launcher'
),
runtime: nodeVersion.runtime,
});
} else {
@@ -1409,7 +1455,10 @@ export const build = async ({
...assets,
},
layers: pageLayers,
handler: 'now__launcher.launcher',
handler: path.join(
path.relative(baseDir, entryPath),
'now__launcher.launcher'
),
runtime: nodeVersion.runtime,
});
}

View File

@@ -1,3 +1,9 @@
// The Next.js builder can emit the project in a subdirectory depending on how
// many folder levels of `node_modules` are traced. To ensure `process.cwd()`
// returns the proper path, we change the directory to the folder with the
// launcher. This mimics `yarn workspace run` behavior.
process.chdir(__dirname);
if (!process.env.NODE_ENV) {
const region = process.env.VERCEL_REGION || process.env.NOW_REGION;
process.env.NODE_ENV = region === 'dev1' ? 'development' : 'production';

View File

@@ -1,3 +1,9 @@
// The Next.js builder can emit the project in a subdirectory depending on how
// many folder levels of `node_modules` are traced. To ensure `process.cwd()`
// returns the proper path, we change the directory to the folder with the
// launcher. This mimics `yarn workspace run` behavior.
process.chdir(__dirname);
if (!process.env.NODE_ENV) {
const region = process.env.VERCEL_REGION || process.env.NOW_REGION;
process.env.NODE_ENV = region === 'dev1' ? 'development' : 'production';

View File

@@ -1000,11 +1000,38 @@ async function getSourceFilePathFromPage({
workPath: string;
page: string;
}) {
let fsPath = path.join(workPath, 'pages', page);
if (await usesSrcDirectory(workPath)) {
return path.join('src', 'pages', page);
fsPath = path.join(workPath, 'src', 'pages', page);
}
return path.join('pages', page);
if (fs.existsSync(fsPath)) {
return path.relative(workPath, fsPath);
}
const extensionless = fsPath.slice(0, -3); // remove ".js"
fsPath = extensionless + '.ts';
if (fs.existsSync(fsPath)) {
return path.relative(workPath, fsPath);
}
if (isDirectory(extensionless)) {
fsPath = path.join(extensionless, 'index.js');
if (fs.existsSync(fsPath)) {
return path.relative(workPath, fsPath);
}
fsPath = path.join(extensionless, 'index.ts');
if (fs.existsSync(fsPath)) {
return path.relative(workPath, fsPath);
}
}
console.log(`WARNING: Unable to find source file for page ${page}`);
return '';
}
function isDirectory(path: string) {
return fs.existsSync(path) && fs.lstatSync(path).isDirectory();
}
export {

View File

@@ -0,0 +1,52 @@
/* eslint-env jest */
const fetch = require('node-fetch');
const cheerio = require('cheerio');
const waitFor = ms => new Promise(resolve => setTimeout(resolve, ms));
module.exports = function (ctx) {
const getProps = async path => {
const html = await fetch(`${ctx.deploymentUrl}/${path}`).then(res =>
res.text()
);
const $ = cheerio.load(html);
return JSON.parse($('#props').text());
};
it('should render / correctly', async () => {
const props = await getProps('/', { params: {} });
expect(props.params).toEqual({});
await waitFor(2000);
await getProps('/');
const newProps = await getProps('/', { params: {} });
expect(newProps.params).toEqual({});
expect(props.random).not.toBe(newProps.random);
});
it('should render /a correctly', async () => {
const props = await getProps('/a');
expect(props.params).toEqual({ slug: ['a'] });
await waitFor(2000);
await getProps('/a');
const newProps = await getProps('/a');
expect(newProps.params).toEqual({ slug: ['a'] });
expect(props.random).not.toBe(newProps.random);
});
it('should render /hello/world correctly', async () => {
const props = await getProps('/hello/world');
expect(props.params).toEqual({ slug: ['hello', 'world'] });
await waitFor(2000);
await getProps('/hello/world');
const newProps = await getProps('/hello/world');
expect(newProps.params).toEqual({ slug: ['hello', 'world'] });
expect(props.random).not.toBe(newProps.random);
});
};

View File

@@ -0,0 +1,15 @@
{
"version": 2,
"builds": [
{
"src": "package.json",
"use": "@vercel/next"
}
],
"probes": [
{
"path": "/non-existent",
"status": 404
}
]
}

View File

@@ -0,0 +1,7 @@
{
"dependencies": {
"next": "canary",
"react": "^16.8.6",
"react-dom": "^16.8.6"
}
}

View File

@@ -0,0 +1,24 @@
export default function Home(props) {
return <pre id="props">{JSON.stringify(props)}</pre>;
}
export async function getStaticPaths() {
return {
paths: [
{ params: { slug: false } },
{ params: { slug: ['a'] } },
{ params: { slug: ['hello', 'world'] } },
],
fallback: false,
};
}
export async function getStaticProps({ params }) {
return {
props: {
params,
random: Math.random(),
},
revalidate: 1,
};
}

View File

@@ -7,6 +7,15 @@
"functions": {
"src/pages/api/memory.js": {
"memory": 128
},
"src/pages/api/index.js": {
"memory": 192
},
"src/pages/api/sub/index.ts": {
"memory": 128
},
"src/pages/api/sub/another.ts": {
"memory": 192
}
}
}
@@ -18,6 +27,21 @@
"status": 200,
"mustContain": "128"
},
{
"path": "/api",
"status": 200,
"mustContain": "192"
},
{
"path": "/api/sub",
"status": 200,
"mustContain": "128"
},
{
"path": "/api/sub/another",
"status": 200,
"mustContain": "192"
},
{
"logMustContain": "WARNING: Your application is being opted out of \"@vercel/next\" optimized lambdas mode due to `functions` config"
}

View File

@@ -1,7 +1,11 @@
{
"private": true,
"dependencies": {
"@types/node": "^12.12.56",
"@types/react": "^16.9.49",
"next": "canary",
"react": "^16.8.6",
"react-dom": "^16.8.6"
"react": "^16.13.1",
"react-dom": "^16.13.1",
"typescript": "^4.0.2"
}
}

View File

@@ -0,0 +1,3 @@
export default function (req, res) {
res.end(`${process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE}`);
}

View File

@@ -0,0 +1,3 @@
export default function (req: any, res: any) {
res.end(`${process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE}`);
}

View File

@@ -0,0 +1,3 @@
export default function (req: any, res: any) {
res.end(`${process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE}`);
}

View File

@@ -135,6 +135,27 @@
"path": "/_next/data/testing-build-id/nofallback/nope.json",
"status": 404
},
{
"path": "/api-docs/first",
"status": 200,
"mustContain": "API Docs"
},
{
"path": "/api-docs/second",
"status": 200,
"mustContain": "Loading..."
},
{
"path": "/_next/data/testing-build-id/api-docs/first.json",
"status": 200,
"responseHeaders": {
"x-vercel-cache": "/HIT|STALE|PRERENDER/"
}
},
{
"path": "/_next/data/testing-build-id/api-docs/second.json",
"status": 200
},
{
"logMustNotContain": "WARNING: your application is being opted out of @vercel/next's optimized lambdas mode due to legacy routes"
},

View File

@@ -0,0 +1,27 @@
import { useRouter } from 'next/router';
export const getStaticProps = () => {
return {
props: {
hello: 'world',
},
};
};
export const getStaticPaths = () => {
return {
paths: ['/api-docs/first'],
fallback: true,
};
};
export default function Slug(props) {
if (useRouter().isFallback) return 'Loading...';
return (
<>
<p id="api-docs">API Docs</p>
<p id="props">{JSON.stringify(props)}</p>
</>
);
}

View File

@@ -40,6 +40,6 @@ declare namespace ncc {
}
}
declare module '@zeit/ncc' {
declare module '@vercel/ncc' {
export = ncc;
}

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/node",
"version": "1.8.0",
"version": "1.8.3",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -32,13 +32,13 @@
"@types/cookie": "0.3.3",
"@types/etag": "1.8.0",
"@types/test-listen": "1.1.0",
"@zeit/ncc": "0.20.4",
"@zeit/node-file-trace": "0.8.2",
"@vercel/ncc": "0.24.0",
"@vercel/nft": "0.9.2",
"content-type": "1.0.4",
"cookie": "0.4.0",
"etag": "1.8.1",
"mkdirp-promise": "5.0.1",
"node-fetch": "2.6.0",
"node-fetch": "2.6.1",
"source-map-support": "0.5.12",
"test-listen": "1.1.0"
}

View File

@@ -8,11 +8,10 @@ if (!entrypoint) {
throw new Error('`VERCEL_DEV_ENTRYPOINT` must be defined');
}
import fs from 'fs';
import { register } from 'ts-node';
// Use the project's version of TypeScript if available,
// otherwise fall back to using the copy that `@now/node` uses.
// otherwise fall back to using the copy that `@vercel/node` uses.
let compiler: string;
try {
compiler = require.resolve('typescript', {
@@ -34,12 +33,11 @@ if (nodeMajor >= 14) {
if (tsconfig) {
try {
const tsconfigParsed = JSON.parse(fs.readFileSync(tsconfig, 'utf8'));
if (
tsconfigParsed.compilerOptions &&
tsconfigParsed.compilerOptions.target
) {
target = tsconfigParsed.compilerOptions.target;
// eslint-disable-next-line @typescript-eslint/no-var-requires
const ts: typeof import('typescript') = require(compiler);
const { config } = ts.readConfigFile(tsconfig, ts.sys.readFile);
if (config?.compilerOptions?.target) {
target = config.compilerOptions.target;
}
} catch (err) {
if (err.code !== 'ENOENT') {

View File

@@ -19,7 +19,7 @@ import {
// @ts-ignore - `@types/mkdirp-promise` is broken
import mkdirp from 'mkdirp-promise';
import once from '@tootallnate/once';
import { nodeFileTrace } from '@zeit/node-file-trace';
import { nodeFileTrace } from '@vercel/nft';
import buildUtils from './build-utils';
import {
File,
@@ -52,12 +52,6 @@ import { Register, register } from './typescript';
export { shouldServe };
export { NowRequest, NowResponse } from './types';
interface CompilerConfig {
debug?: boolean;
includeFiles?: string | string[];
excludeFiles?: string | string[];
}
interface DownloadOptions {
files: Files;
entrypoint: string;
@@ -125,9 +119,10 @@ async function downloadInstallAndBundle({
async function compile(
workPath: string,
baseDir: string,
entrypointPath: string,
entrypoint: string,
config: CompilerConfig
config: Config
): Promise<{
preparedFiles: Files;
shouldAddSourcemapSupport: boolean;
@@ -150,20 +145,21 @@ async function compile(
for (const pattern of includeFiles) {
const files = await glob(pattern, workPath);
await Promise.all(
Object.keys(files).map(async file => {
const entry = files[file];
fsCache.set(file, entry);
Object.values(files).map(async entry => {
const { fsPath } = entry;
const relPath = relative(baseDir, fsPath);
fsCache.set(relPath, entry);
const stream = entry.toStream();
const { data } = await FileBlob.fromStream({ stream });
if (file.endsWith('.ts') || file.endsWith('.tsx')) {
if (relPath.endsWith('.ts') || relPath.endsWith('.tsx')) {
sourceCache.set(
file,
compileTypeScript(resolve(workPath, file), data.toString())
relPath,
compileTypeScript(fsPath, data.toString())
);
} else {
sourceCache.set(file, data);
sourceCache.set(relPath, data);
}
inputFiles.add(resolve(workPath, file));
inputFiles.add(fsPath);
})
);
}
@@ -178,7 +174,7 @@ async function compile(
let tsCompile: Register;
function compileTypeScript(path: string, source: string): string {
const relPath = relative(workPath, path);
const relPath = relative(baseDir, path);
if (!tsCompile) {
tsCompile = register({
basePath: workPath, // The base is the same as root now.json dir
@@ -201,12 +197,13 @@ async function compile(
const { fileList, esmFileList, warnings } = await nodeFileTrace(
[...inputFiles],
{
base: workPath,
base: baseDir,
processCwd: workPath,
ts: true,
mixedModules: true,
ignore: config.excludeFiles,
readFile(fsPath: string): Buffer | string | null {
const relPath = relative(workPath, fsPath);
const relPath = relative(baseDir, fsPath);
const cached = sourceCache.get(relPath);
if (cached) return cached.toString();
// null represents a not found
@@ -246,7 +243,7 @@ async function compile(
for (const path of fileList) {
let entry = fsCache.get(path);
if (!entry) {
const fsPath = resolve(workPath, path);
const fsPath = resolve(baseDir, path);
const { mode } = lstatSync(fsPath);
if (isSymbolicLink(mode)) {
entry = new FileFsRef({ fsPath, mode });
@@ -258,14 +255,14 @@ async function compile(
if (isSymbolicLink(entry.mode) && entry.fsPath) {
// ensure the symlink target is added to the file list
const symlinkTarget = relative(
workPath,
baseDir,
resolve(dirname(entry.fsPath), readlinkSync(entry.fsPath))
);
if (
!symlinkTarget.startsWith('..' + sep) &&
fileList.indexOf(symlinkTarget) === -1
) {
const stats = statSync(resolve(workPath, symlinkTarget));
const stats = statSync(resolve(baseDir, symlinkTarget));
if (stats.isFile()) {
fileList.push(symlinkTarget);
}
@@ -275,7 +272,7 @@ async function compile(
// There is a bug on Windows where entrypoint uses forward slashes
// and workPath uses backslashes so we use resolve before comparing.
if (
resolve(workPath, path) !== resolve(workPath, entrypoint) &&
resolve(baseDir, path) !== resolve(workPath, entrypoint) &&
tsCompiled.has(path)
) {
preparedFiles[
@@ -339,6 +336,7 @@ export async function build({
files,
entrypoint,
workPath,
repoRootPath,
config = {},
meta = {},
}: BuildOptions) {
@@ -346,6 +344,7 @@ export async function build({
config.helpers === false || process.env.NODEJS_HELPERS === '0'
);
const baseDir = repoRootPath || workPath;
const awsLambdaHandler = getAWSLambdaHandler(entrypoint, config);
const {
@@ -372,6 +371,7 @@ export async function build({
const traceTime = Date.now();
const { preparedFiles, shouldAddSourcemapSupport, watch } = await compile(
workPath,
baseDir,
entrypointPath,
entrypoint,
config
@@ -383,7 +383,7 @@ export async function build({
const launcherFiles: Files = {
[`${LAUNCHER_FILENAME}.js`]: new FileBlob({
data: makeLauncher({
entrypointPath: `./${entrypoint}`,
entrypointPath: `./${relative(baseDir, entrypointPath)}`,
bridgePath: `./${BRIDGE_FILENAME}`,
helpersPath: `./${HELPERS_FILENAME}`,
sourcemapSupportPath: `./${SOURCEMAP_SUPPORT_FILENAME}`,

View File

@@ -3,6 +3,7 @@
"strict": true,
"esModuleInterop": true,
"sourceMap": true,
"jsx": "react",
"lib": ["esnext"],
"target": "esnext",
"module": "commonjs"

View File

@@ -28,26 +28,32 @@ beforeAll(async () => {
const fixturesPath = path.resolve(__dirname, 'fixtures');
const testsThatFailToBuild = new Set(['45-noEmitOnError-true']);
const testsThatFailToBuild = new Map([
[
'45-noEmitOnError-true',
`index.ts(3,19): error TS2339: Property 'thisDoesNotExist' does not exist on type 'IncomingMessage'.\n`,
],
]);
// eslint-disable-next-line no-restricted-syntax
for (const fixture of fs.readdirSync(fixturesPath)) {
if (testsThatFailToBuild.has(fixture)) {
const errMsg = testsThatFailToBuild.get(fixture);
if (errMsg) {
// eslint-disable-next-line no-loop-func
it(`should not build ${fixture}`, async () => {
it(`should fail to build ${fixture}`, async () => {
try {
await testDeployment(
{ builderUrl, buildUtilsUrl },
path.join(fixturesPath, fixture)
);
} catch (err) {
expect(err.message).toMatch(/is ERROR/);
expect(err).toBeTruthy();
expect(err.deployment).toBeTruthy();
expect(err.deployment.errorMessage).toBe(errMsg);
}
});
continue; //eslint-disable-line
}
// eslint-disable-next-line no-loop-func
it(`should build ${fixture}`, async () => {
await expect(
testDeployment(

View File

@@ -3,7 +3,7 @@
"strict": true,
"esModuleInterop": true,
"lib": ["esnext"],
"target": "esnext",
"target": "es2018",
"module": "commonjs",
"outDir": "dist",
"sourceMap": false,

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/python",
"version": "1.2.2",
"version": "1.2.3",
"main": "./dist/index.js",
"license": "MIT",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
@@ -20,6 +20,7 @@
},
"devDependencies": {
"@types/execa": "^0.9.0",
"@vercel/ncc": "0.24.0",
"execa": "^1.0.0",
"typescript": "3.9.3"
}

View File

@@ -1,7 +1,7 @@
{
"name": "@vercel/ruby",
"author": "Nathan Cahill <nathan@nathancahill.com>",
"version": "1.2.3",
"version": "1.2.4",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby",
@@ -22,6 +22,7 @@
"devDependencies": {
"@types/fs-extra": "8.0.0",
"@types/semver": "6.0.0",
"@vercel/ncc": "0.24.0",
"execa": "2.0.4",
"fs-extra": "^7.0.1",
"semver": "6.1.1",

View File

@@ -1,9 +1,9 @@
{
"name": "@vercel/static-build",
"version": "0.17.7",
"version": "0.17.9",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/static-builds",
"homepage": "https://vercel.com/docs/build-step",
"files": [
"dist"
],
@@ -23,10 +23,11 @@
"@types/ms": "0.7.31",
"@types/node-fetch": "2.5.4",
"@types/promise-timeout": "1.3.0",
"@vercel/ncc": "0.24.0",
"get-port": "5.0.0",
"is-port-reachable": "2.0.1",
"ms": "2.1.2",
"node-fetch": "2.6.0",
"node-fetch": "2.6.1",
"typescript": "3.9.3"
}
}

View File

@@ -225,7 +225,7 @@ const frameworkList: Framework[] = [
continue: true,
},
{
src: '^/(img|js|css|fonts|media)/.*',
src: '^/(img|js|css|fonts|media)/[^/]+\\.[0-9a-f]{8}\\.*',
headers: { 'cache-control': 'max-age=31536000, immutable' },
continue: true,
},

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/redwood",
"version": "0.1.0",
"version": "0.1.1",
"main": "./dist/index.js",
"license": "MIT",
"homepage": "https://vercel.com/docs",
@@ -19,7 +19,7 @@
},
"dependencies": {
"@netlify/zip-it-and-ship-it": "1.2.0",
"@vercel/frameworks": "0.1.0"
"@vercel/frameworks": "0.1.1"
},
"devDependencies": {
"@types/aws-lambda": "8.10.19",

View File

@@ -154,23 +154,21 @@ async function fetchWithAuth(url, opts = {}) {
if (!opts.headers) opts.headers = {};
if (!opts.headers.Authorization) {
currentCount += 1;
if (!token || currentCount === MAX_COUNT) {
currentCount = 0;
// used for health checks
token = process.env.VERCEL_TOKEN || process.env.NOW_TOKEN;
if (!token) {
// used by GH Actions
token = await fetchTokenWithRetry();
}
}
opts.headers.Authorization = `Bearer ${token}`;
opts.headers.Authorization = `Bearer ${await fetchCachedToken()}`;
}
return await fetchApi(url, opts);
}
async function fetchCachedToken() {
currentCount += 1;
if (!token || currentCount === MAX_COUNT) {
currentCount = 0;
token = await fetchTokenWithRetry();
}
return token;
}
async function fetchTokenWithRetry(retries = 5) {
const {
NOW_TOKEN,
@@ -248,5 +246,6 @@ module.exports = {
fetchWithAuth,
nowDeploy,
fetchTokenWithRetry,
fetchCachedToken,
fileModeSymbol,
};

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