Compare commits

..

150 Commits

Author SHA1 Message Date
JJ Kasper
b190f2e118 Publish Stable
- @vercel/next@2.6.38
2020-11-07 12:11:05 -06:00
JJ Kasper
2389d3e936 Publish Canary
- @vercel/next@2.6.38-canary.0
2020-11-07 11:55:08 -06:00
JJ Kasper
0f4ed1965a [next] Correct data routes with basePath (#5381) 2020-11-06 23:40:32 -05:00
luc
e1e38ee536 Publish Canary
- vercel@20.1.3-canary.5
2020-11-06 16:50:13 +01:00
Luc Leray
dc1ff00610 [cli] Show error when removing env variable from no target environment (#5378)
* error if no env target is selected

* improve prompt ui

* add test
2020-11-06 16:49:34 +01:00
luc
5f31736603 Publish Canary
- vercel@20.1.3-canary.4
2020-11-05 23:17:08 +01:00
Luc Leray
9a57cc72dd [cli] (major) Update vercel env (#5372)
* prompt to select env type

* improve copy

* create env variable with type

* remove nanoid dependency

* use encodeURIComponent

* refactor envType -> type

* refactor envName -> key

* do not hide value input

* adjust value prompt depending on type

* handle std input for plaintext env variables

* show custom error when secret is not found

* handle secret name input starting with `@`

* fix system env value question

* improve ui of prompts

* expand env list in vc rm

* adjust tests

* environment -> environments

* list multiple targets in vc env ls

* show value for system env vars

* adjust tests

* capitalize targets

* add <type> to arguments

* always use stdInput for envValue

* fix number of arguments error

* adjust tests

* refactor ProjectEnvType

* refactor SYSTEM_ENV_VALUES

* fix typo for typePlaceholder

* use getCommandName

* use title

* remove @ts-ignore

* improve types

* show key controls for checkbox prompt
2020-11-05 22:58:58 +01:00
JJ Kasper
9d9c5f3753 Publish Stable
- @vercel/next@2.6.37
2020-11-05 12:44:43 -06:00
JJ Kasper
deeefc0c93 Publish Canary
- @vercel/next@2.6.37-canary.0
2020-11-05 11:50:05 -06:00
JJ Kasper
5c23b08bc1 Ensure auto-export dynamic routes are routed properly (#5377) 2020-11-05 11:48:29 -06:00
dependabot[bot]
7c4e25ccce Bump bl from 1.2.2 to 1.2.3 (#5363)
Bumps [bl](https://github.com/rvagg/bl) from 1.2.2 to 1.2.3.
- [Release notes](https://github.com/rvagg/bl/releases)
- [Commits](https://github.com/rvagg/bl/compare/v1.2.2...v1.2.3)

Signed-off-by: dependabot[bot] <support@github.com>
2020-11-05 10:24:17 -05:00
Joe Haddad
1bfa310945 Publish Stable
- @vercel/static-build@0.17.11
2020-11-04 23:29:30 -05:00
Joe Haddad
c96062266b Publish Canary
- @vercel/frameworks@0.1.2-canary.1
 - @vercel/build-utils@2.5.5-canary.1
 - vercel@20.1.3-canary.3
 - @vercel/client@9.0.4-canary.1
 - @vercel/static-build@0.17.11-canary.0
 - @vercel/redwood@0.1.2-canary.1
2020-11-04 23:12:46 -05:00
Joe Haddad
5bea99c1d9 [static-build] zero-config gatsby should support export default (#5375) 2020-11-04 23:11:40 -05:00
Luc Leray
358be773a2 [tests] Cleanup fixture folder before running CLI test (#5374) 2020-11-05 02:09:36 +01:00
Nathan Rajlich
9ebf4e531d [frameworks] Add installCommand placeholders (#5373) 2020-11-04 16:24:06 -08:00
Joe Haddad
71e79258b7 Publish Stable
- @vercel/next@2.6.36
 - @vercel/static-build@0.17.10
2020-11-03 10:49:41 -05:00
Joe Haddad
1dfafe7040 Publish Canary
- @vercel/next@2.6.36-canary.0
2020-11-03 10:40:07 -05:00
JJ Kasper
78ed452a99 [next] Ensure localeDetection: false is honored (#5365)
This disables adding the locale redirects when `localeDetection` is set to `false` 

x-ref: https://github.com/vercel/next.js/issues/18482
2020-11-03 01:58:40 +00:00
Joe Haddad
d408e2ef1a Publish Canary
- @vercel/static-build@0.17.10-canary.0
2020-11-02 15:04:48 -05:00
Joe Haddad
8ebb1fd9ce [static-build] add Vercel Analytics Support for Gatsby (#5366) 2020-11-02 15:03:45 -05:00
JJ Kasper
4eb5ad625c Publish Stable
- @vercel/next@2.6.35
2020-11-02 10:26:52 -06:00
luc
7164f6e58e Publish Canary
- vercel@20.1.3-canary.2
2020-11-02 15:43:54 +01:00
Naoyuki Kanezawa
a36d084b3e [cli] Add support for plaintext env variables (#5345)
* fix plain envs can not be retrieved

* add test

* add test for `vc dev`

* use v6 to retrieve env variables

* fix v6 return type

* use v6 to display env vars

* add test for vc env ls

* expand env vars with multiple targets

* minor type fixes

* always use v6 for getEnvVariables

Co-authored-by: luc <luc.leray@gmail.com>
2020-11-02 15:42:28 +01:00
JJ Kasper
8a16447fed Publish Canary
- vercel@20.1.3-canary.1
 - @vercel/next@2.6.35-canary.1
2020-11-01 12:24:51 -06:00
Leo Lamprecht
efda4ab6b9 Updated Next.js Template to use latest version of Next.js and React (#5358) 2020-11-01 17:13:16 +01:00
JJ Kasper
16060a71a9 [next] Add additional tests for i18n revalidate params (#5356) 2020-11-01 15:15:20 +01:00
Luc Leray
b18e0a7415 [cli] Replace util/prompt-bool by util/input/confirm (#5359) 2020-10-31 22:07:35 +01:00
JJ Kasper
1251f11a97 Publish Canary
- @vercel/next@2.6.35-canary.0
2020-10-31 00:34:03 -05:00
JJ Kasper
07235e22f6 [next] Fix root-most optional-catchall with i18n (#5354)
* Fix root-most optional-catchall with i18n

* Ensure dynamic prerenders revalidation

* Add test delay
2020-10-30 17:40:39 -05:00
JJ Kasper
81011df816 Publish Stable
- @vercel/next@2.6.34
2020-10-30 10:50:03 -05:00
JJ Kasper
c8d31bdcf7 Publish Canary
- @vercel/next@2.6.34-canary.0
2020-10-30 10:16:20 -05:00
JJ Kasper
5e7f1158ad [next] Ensure revalidation works with i18n (#5350)
This corrects some i18n pages being considered staticPages instead of prerender items which was breaking revalidate behavior. This also adds more verbose tests for i18n ensuring revalidation is working correctly

x-ref: https://github.com/vercel/next.js/discussions/18443
Fixes: https://github.com/vercel/next.js/issues/18503
2020-10-30 14:59:47 +00:00
JJ Kasper
df5aa1f10d Publish Stable
- @vercel/next@2.6.33
2020-10-27 13:41:00 -05:00
JJ Kasper
eb1ba97309 Publish Canary
- @vercel/next@2.6.33-canary.0
2020-10-27 13:33:33 -05:00
JJ Kasper
8047d6de49 [next] Fix index data path for non-locale path (#5339)
* Fix index data path for non-locale path

* Add index SSG test

* Update tests for canary

* Correct logic check to handle default locale
2020-10-27 13:33:02 -05:00
JJ Kasper
7470ff3724 Publish Stable
- @vercel/next@2.6.32
2020-10-27 09:30:43 -05:00
JJ Kasper
8340d9327c Publish Canary
- @vercel/next@2.6.32-canary.1
2020-10-27 09:11:04 -05:00
JJ Kasper
d278425810 Update tests for stabilized field (#5337) 2020-10-27 09:05:39 -05:00
JJ Kasper
8b26bbe643 [next] Add redirecting domain specific locales (#5333)
Co-authored-by: Joe Haddad <joe.haddad@zeit.co>
2020-10-27 11:32:08 +01:00
JJ Kasper
fa8e1e73c8 Ensure index GSP data is available at correct path (#5336) 2020-10-27 01:51:58 -05:00
JJ Kasper
f8abcbcd9f Remove unstable_ prefix from unstable_blocking (#5334) 2020-10-27 00:42:11 -05:00
Andy Bitz
e18ff683b2 Publish Canary
- @vercel/frameworks@0.1.2-canary.0
 - @vercel/build-utils@2.5.5-canary.0
 - vercel@20.1.3-canary.0
 - @vercel/client@9.0.4-canary.0
 - @vercel/redwood@0.1.2-canary.0
2020-10-26 16:22:53 +01:00
Andy
f28293a5a8 [frameworks] Add recommended integrations and related dependencies (#5330)
Adds the `recommendedIntegrations` property to the frameworks list with related dependencies.

Story https://app.clubhouse.io/vercel/story/13391
2020-10-26 15:10:40 +00:00
Steven
a4963a89c7 Publish Canary
- @vercel/next@2.6.32-canary.0
2020-10-25 16:58:01 -04:00
Steven
21df39fe8c [next] Image Optimization for default loader (#5321)
We currently pass through `images` whenever its defined, but this is enabling Image Optimization in the Proxy for every Next.js project.

Instead, we should check to see if the default loader is used (the same use for `next dev`) as a signal to enable this feature in the deployment.

Related to https://github.com/vercel/next.js/issues/18122
2020-10-24 12:55:53 +00:00
JJ Kasper
5ad9d61451 Publish Stable
- @vercel/next@2.6.31
2020-10-23 15:48:21 -05:00
JJ Kasper
8b5a2aa44f Publish Canary
- @vercel/next@2.6.31-canary.0
2020-10-23 15:17:30 -05:00
JJ Kasper
d0da1ce195 [next] Add handling for not found routes with i18n (#5313)
* Add handling for not found routes with i18n

* Update prerender lambda check
2020-10-23 14:34:17 -05:00
JJ Kasper
fd5d3b2921 Publish Stable
- @vercel/next@2.6.30
2020-10-20 13:11:20 -05:00
JJ Kasper
d22bdeb8d0 Publish Canary
- @vercel/next@2.6.30-canary.0
2020-10-20 12:59:12 -05:00
JJ Kasper
c120fd82f9 [next] Ensure root-most index GSP page is located correctly (#5309) 2020-10-20 19:58:18 +02:00
JJ Kasper
2474a80ff1 Correct i18n trailing slash redirect priority (#5306) 2020-10-20 11:01:31 -05:00
JJ Kasper
cc1cdbe610 Publish Stable
- @vercel/next@2.6.29
2020-10-20 06:15:03 -05:00
JJ Kasper
0b92f8ceee Publish Canary
- @vercel/next@2.6.29-canary.0
 - @vercel/routing-utils@1.9.1-canary.1
2020-10-20 05:08:26 -05:00
JJ Kasper
be82a88d1a [next] Add i18n support handling (#5298)
* Add initial locale output mapping

* Add additional probes

* Add locale specific 404 handling

* Add locale specific 404s, locale redirects, and more tests

* Update wildcard value

* Fix wildcard handling and update route type

* Update addLocale util

* Apply suggestions from code review

Co-authored-by: Steven <steven@ceriously.com>

* Remove redundant console.error

Co-authored-by: Steven <steven@ceriously.com>
Co-authored-by: Leo Lamprecht <leo@zeit.co>
2020-10-20 12:05:06 +02:00
JJ Kasper
64da08f0f2 Publish Stable
- @vercel/next@2.6.28
2020-10-20 05:00:10 -05:00
Steven
2e957fce55 Publish Canary
- @vercel/next@2.6.28-canary.0
2020-10-16 18:19:07 -04:00
Steven
c7ead151f5 [next] Add support for Image Optimization (#5296)
This PR sends the results of the image optimization config from next.config.js to the build output.

x-ref: https://github.com/vercel/next.js/pull/17749
2020-10-16 17:56:14 -04:00
dav-is
e2baf9b00f Publish Canary
- @vercel/routing-utils@1.9.1-canary.0
2020-10-14 16:48:04 -04:00
Connor Davis
ba8ef7bc98 Add custom locale cookie (#5293) 2020-10-14 16:46:40 -04:00
JJ Kasper
c5d04e0d4f Publish Stable
- @vercel/next@2.6.27
2020-10-13 14:40:53 -05:00
JJ Kasper
b4f849418d Publish Canary
- @vercel/next@2.6.27-canary.0
2020-10-13 00:17:38 -05:00
JJ Kasper
b37c4f211e [next] Update next.config backup name to be deterministic (#5288) 2020-10-13 01:13:40 -04:00
Daniel Roe
f06efe167c [docs] Update contributing example of @vercel/nft (#5284) 2020-10-12 15:01:27 -04:00
dependabot[bot]
296d8da676 Bump next from 9.5.1 to 9.5.4 in /examples/nextjs (#5278)
Bumps [next](https://github.com/vercel/next.js) from 9.5.1 to 9.5.4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/vercel/next.js/releases">next's releases</a>.</em></p>
<blockquote>
<h2>v9.5.4</h2>
<p><strong>This upgrade is <em>completely backwards compatible and recommended for all users on versions below 9.5.4.</em> For future security related communications of our OSS projects, please <a href="https://vercel.com/security">join this mailing list</a>.</strong></p>
<p>A security team from one of our partners noticed an issue in Next.js that allowed for open redirects to occur.</p>
<p>Specially encoded paths could be used with the trailing slash redirect to allow an open redirect to occur to an external site.</p>
<p>In general, this redirect does not directly harm users although can allow for phishing attacks by redirecting to an attackers domain from a trusted domain.</p>
<p>We recommend upgrading to the latest version of Next.js to improve the overall security of your application.</p>
<h2>How to Upgrade</h2>
<ul>
<li>We have released patch versions for both the stable and canary channels of Next.js.</li>
<li>To upgrade run <code>npm install next@latest --save</code></li>
</ul>
<h2>Impact</h2>
<ul>
<li><strong>Affected</strong>: Users of Next.js between 9.5.0 and 9.5.3</li>
<li><strong>Not affected</strong>: Deployments on Vercel (<a href="https://vercel.com">https://vercel.com</a>) are not affected</li>
<li><strong>Not affected</strong>: Deployments using <code>next export</code></li>
</ul>
<p>We recommend everyone to upgrade regardless of whether you can reproduce the issue or not.</p>
<h3>How to Assess Impact</h3>
<p>If you think users could have been affected, you can filter logs of affected sites by <code>%2F</code> with a 308 response.</p>
<h2>What is Being Done</h2>
<p>As Next.js has grown in popularity, it has received the attention of security teams and auditors. We are thankful to those that reached out for their investigation and discovery of the original bug and subsequent responsible disclosure.</p>
<p>We've landed a patch that ensures encoding is handled properly for these types of redirects so the open redirect can no longer occur.</p>
<p>Regression tests for this attack were added to the <a href="https://github.com/vercel/next.js/blob/canary/test/integration/production/test/security.js">security</a> integration test suite.</p>
<ul>
<li>We have notified known Next.js users in advance of this publication.</li>
<li>A public CVE was released.</li>
<li>If you want to stay on top of our security related news impacting Next.js or other Vercel projects, please <a href="https://zeit.co/security">join this mailing list</a>.</li>
<li>We encourage responsible disclosure of future issues. Please email us at <strong><a href="https://github.com/vercel/next.js/blob/HEAD/mailto:security@zeit.co">security@vercel.com</a>.</strong> We are actively monitoring this mailbox.</li>
</ul>
<hr />
<h3>Core Changes</h3>
<ul>
<li>Make the image post-processor ignore SVG images: <a href="https://github-redirect.dependabot.com/vercel/next.js/issues/16732">#16732</a></li>
<li>Only update lookups for dev overlay if mounted: <a href="https://github-redirect.dependabot.com/vercel/next.js/issues/16776">#16776</a></li>
<li>Ensure interpolating dynamic href values works correctly: <a href="https://github-redirect.dependabot.com/vercel/next.js/issues/16774">#16774</a></li>
<li>Add automatic reloading when editing GS(S)P methods: <a href="https://github-redirect.dependabot.com/vercel/next.js/issues/16744">#16744</a></li>
<li>Update to show build indicator while re-fetching GS(S)P data in dev: <a href="https://github-redirect.dependabot.com/vercel/next.js/issues/16789">#16789</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="6588108150"><code>6588108</code></a> v9.5.4</li>
<li><a href="7108567b06"><code>7108567</code></a> v9.5.4-canary.25</li>
<li><a href="5d79a8c0c4"><code>5d79a8c</code></a> Update workflow step to restore cache (<a href="https://github-redirect.dependabot.com/vercel/next.js/issues/17656">#17656</a>)</li>
<li><a href="4c38e3ed8e"><code>4c38e3e</code></a> fix typo (<a href="https://github-redirect.dependabot.com/vercel/next.js/issues/17653">#17653</a>)</li>
<li><a href="241f38eaa8"><code>241f38e</code></a> v9.5.4-canary.24</li>
<li><a href="7dec91175c"><code>7dec911</code></a> change anonymous functions to named in docs examples (<a href="https://github-redirect.dependabot.com/vercel/next.js/issues/17510">#17510</a>)</li>
<li><a href="1659e4da61"><code>1659e4d</code></a> Update migrating from Gatsby docs. (<a href="https://github-redirect.dependabot.com/vercel/next.js/issues/17636">#17636</a>)</li>
<li><a href="06a8b1ad67"><code>06a8b1a</code></a> Add docs on how to migrate from Gatsby. (<a href="https://github-redirect.dependabot.com/vercel/next.js/issues/17491">#17491</a>)</li>
<li><a href="04234cc312"><code>04234cc</code></a> Update to use hasNextSupport for custom-routes in next export check (<a href="https://github-redirect.dependabot.com/vercel/next.js/issues/17630">#17630</a>)</li>
<li><a href="742f5d9a46"><code>742f5d9</code></a> test(create-next-app): increase coverage (<a href="https://github-redirect.dependabot.com/vercel/next.js/issues/17507">#17507</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/vercel/next.js/compare/v9.5.1...v9.5.4">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=next&package-manager=npm_and_yarn&previous-version=9.5.1&new-version=9.5.4)](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-10-09 14:32:15 +00:00
Steven
981e4183c6 Publish Stable
- @vercel/build-utils@2.5.4
 - vercel@20.1.2
 - @vercel/client@9.0.3
 - @vercel/node@1.8.4
 - @vercel/routing-utils@1.9.0
2020-10-08 09:10:16 -04:00
Steven
1706a00cb9 Publish Canary
- @vercel/build-utils@2.5.4-canary.0
 - vercel@20.1.2-canary.5
 - @vercel/client@9.0.3-canary.0
2020-10-06 09:10:41 -04:00
Steven
d7bd03cf1d [build-utils] Fix framework "CRA" when Next.js is dependency (#5246)
Fixes https://github.com/vercel/vercel/discussions/4288#discussioncomment-88998

This was fixed when "Framework: Other" in #5009 but this PR fixes it when "Framework: CRA" or any framework selection.
2020-10-06 13:09:02 +00:00
dav-is
e27ff8d2e0 Publish Canary
- vercel@20.1.2-canary.4
2020-10-05 18:14:54 -04:00
RAJPRAKASH
bc6da39cc2 [examples] Fix link to gatsby live example (#5205)
Fixes the link in the gatsby example back to the repo.

Co-authored-by: Steven <steven@ceriously.com>
2020-10-05 18:08:29 -04:00
dav-is
727109c64a Publish Canary
- @vercel/routing-utils@1.8.5-canary.0
2020-10-05 18:03:21 -04:00
Connor Davis
817410a8e2 [routing-utils] Add locale to routes schema (#5259)
We need to add a `locale` property to `routes`: CH-12345, CH-12349
2020-10-05 21:25:21 +00:00
Steven
e022e7b79c Publish Canary
- vercel@20.1.2-canary.3
2020-10-05 15:20:29 -04:00
Steven
dda6c24a3d [cli] Fix progress bar completion (#5260)
In some rare cases, the progress bar will still be in progress when the deployment completes, which causes the  "Inspect" URL to print on the same line as the progress bar instead of a new line.

This PR fixes that corner case.
2020-10-05 19:10:20 +00:00
Steven
7c922a4092 [cli] Remove 1.0 path alias rules (#5258)
We don't support routing path aliases anymore, now that we've completely shut down the ZEIT Now 1.0 infrastructure. This PR removes path alias rules from Vercel CLI.
2020-10-05 17:48:37 +00:00
Steven
376dec8f33 Publish Canary
- vercel@20.1.2-canary.2
2020-10-02 19:18:35 -04:00
Steven
16e101d262 [cli] Fix dev routing when using routes with a frontend framework (#5253)
There was a regression when introducing multiple phases such as `hit` and `miss` which caused `routes` to stop working because the transition from `null` phase to the `filesystem` phase resets any dest rewrites.

The workaround is to detect when we don't have a `filesystem` phase and exit early.
2020-10-02 22:46:53 +00:00
Nathan Rajlich
41ce1a4291 Publish Canary
- vercel@20.1.2-canary.1
 - @vercel/node@1.8.4-canary.0
2020-09-25 10:00:24 -07:00
Nathan Rajlich
449f35cf33 [node] Only use the project's local "typescript" when it has compatible ScriptTarget (#5220)
https://app.clubhouse.io/vercel/story/8304
2020-09-24 15:18:09 -07:00
Nathan Rajlich
d683402bba Publish Canary
- vercel@20.1.2-canary.0
2020-09-23 13:23:44 -07:00
Nathan Rajlich
2051a1cd9b [cli] Ensure the devProcessPort is set during "upgrade" events (#5226)
Related to: https://twitter.com/raymondcamden/status/1308838251902521348
2020-09-23 20:16:51 +00:00
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
Steven
e90521b5a4 Publish Stable
- @vercel/frameworks@0.1.0
 - @vercel/build-utils@2.5.0
 - vercel@20.0.0
 - @vercel/client@9.0.0
 - @vercel/go@1.1.5
 - @vercel/next@2.6.23
 - @vercel/node@1.8.0
 - @vercel/routing-utils@1.8.4
 - @vercel/static-build@0.17.7
 - @vercel/redwood@0.1.0
2020-08-24 08:25:30 -04:00
Steven
10c598834a Publish Canary
- @vercel/build-utils@2.4.3-canary.5
 - vercel@20.0.0-canary.26
 - @vercel/client@8.2.2-canary.10
2020-08-21 17:53:14 -04:00
Steven
e58b34b82c [build-utils] Fix framework "Other" with Next.js for old projects (#5074)
Since released PR #5009, we had some users that depend on the broken behavior. This adds an arbitrary date so that old projects will use the old broken behavior, and new projects will use the new behavior from #5009.

The reason for the date is that we don't want to force users to create new projects who noticed this broken behavior months ago like this discussion: https://github.com/vercel/vercel/discussions/4138

Its better to be a bit aggressive and set the date far back because users with that want the old behavior have a workaround: select Next.js in the framework dropdown. However, users that want the new behavior with an old project will be stuck without a solution.
2020-08-21 21:51:40 +00:00
Steven
02e1c921ac [cli][build-utils] Use handle: error for api 404 (#5064)
This PR does a few things:

- Consolidates build-utils to use both 404 routes in `handle: error` phase
- Fixes `vc dev` to process `handle: error` phase after the `handle: filesystem` phase
- Updates `/api` 404 route to be excluded for frameworks like RedwoodJS which use their own functions
2020-08-21 20:29:39 +00:00
Steven
fcb14fa70e Publish Canary
- @vercel/redwood@0.0.2-canary.8
2020-08-19 18:26:12 -04:00
Steven
46e18128c7 [redwood] Add support for functions and apiProxyPath config (#5063)
This PR adds two missing features to `@vercel/redwood`:

1. Support for [`functions`](https://vercel.com/docs/configuration#project/functions) in `vercel.json`
2. Support for [`apiProxyPath`](https://redwoodjs.com/docs/app-configuration-redwood-toml#apiproxypath) in `redwood.toml`
3. Support for caching yarn workspaces which has `node_modules` outside the root directory
2020-08-19 22:16:53 +00:00
dav-is
e06d5247ef Publish Canary
- vercel@20.0.0-canary.25
 - @vercel/client@8.2.2-canary.9
2020-08-19 16:40:45 -04:00
Connor Davis
02195b92a7 [client][cli] Add Learn More Option to Warnings (#5022)
The deployment API might return a learn more link to address warnings, tips, or notices

CH-568

```
HTTP/2 200
...
x-vercel-warning-bad-error: Something went wrong
x-vercel-link-bad-error: https://vercel.link/bad-error

x-vercel-notice-low-funds: You are low on funds
x-vercel-link-low-funds: https://vercel.link/increase-funds
...
```

Should output as:
```
Warning: Something went wrong
Learn More: https://vercel.link/bad-error

Notice: You are low on funds
Learn More: https://vercel.link/increase-funds
```
2020-08-19 20:19:28 +00:00
Andy Bitz
7945155a0f Publish Canary
- vercel@20.0.0-canary.24
 - @vercel/next@2.6.23-canary.0
 - @vercel/node@1.7.5-canary.2
 - @vercel/routing-utils@1.8.4-canary.5
2020-08-19 15:01:35 +02:00
Andy
edb6043c2c [cli] Always show renewal price for domains inspect (#5060)
* [cli] Always show renwal price for `domains inspect`

* Update test
2020-08-19 15:00:33 +02:00
Markoz Peña
971481ba51 [node] Add res.redirect() helper method (#4947)
This pull request adds a method redirect, the behavior will be the same as that of Next.js with `pages/api`. This PR takes into account the change that is being made in Next.js with redirect due to the [error that was reported](https://github.com/vercel/next.js/issues/15594) a few hours ago.

Co-authored-by: Steven <steven@ceriously.com>
2020-08-18 18:58:54 -04:00
JJ Kasper
db8e456603 Publish canary
- @vercel/routing-utils@1.8.4-canary.4
2020-08-18 12:37:22 -05:00
JJ Kasper
d1b4f24a4a Publish Stable
- @vercel/next@2.6.22
2020-08-18 12:25:16 -05:00
JJ Kasper
4eb39ed53b Publish Canary
- @vercel/next@2.6.22-canary.1
- @vercel/routing-utils@1.8.4-canary.3
2020-08-18 12:19:58 -05:00
JJ Kasper
6c7236ffd5 [routing-utils] Attempt normal path-to-regexp replacing before custom (#5053)
This corrects behavior that was changed when switching to use `safelyCompile` which caused some `path-to-regexp` replacing behavior to be changed like not removing brackets `{}` around params which are removed in Next.js. This updates to first attempt to use the normal replacing behavior from `path-to-regexp` falling back to the safe compiling logic added when that fails. 

Additional tests have been added to ensure the brackets are stripped as expected when compiling with `path-to-regexp`
2020-08-18 16:57:38 +00:00
Steven
f0def040ac Publish Canary
- vercel@20.0.0-canary.23
 - @vercel/next@2.6.22-canary.0
2020-08-17 17:32:42 -04:00
Steven
ee8dff2dc9 [cli] Remove unused dependencies (#5052)
This PR is a follow up to removing v1 in PR #5011
2020-08-17 21:28:17 +00:00
Steven
df86a6d48c [cli] Fix update message (#5051)
The update message was sometimes printed when there was no update.

This PR fixes the update check to ensure the that it is only printed when the latest version differs from the current version.
2020-08-17 16:15:12 -04:00
JJ Kasper
b3958b3d12 Publish Stable
- @vercel/next@2.6.21
2020-08-17 09:48:34 -05:00
JJ Kasper
8dd22703a7 Publish Canary
- @vercel/next@2.6.21-canary.1
2020-08-17 09:36:53 -05:00
JJ Kasper
c7e2280d23 [next] Fix trailing slash and 404 with next export (#5048)
This fixes the case where `trailingSlash: true` is used with `next export` causing the `404` page to be output as `404/index.html` and we were previously only checking for the 404 output at `404`. This also adds a regression test for this behavior. 

Closes: https://github.com/vercel/next.js/issues/16218
2020-08-17 14:12:22 +00:00
Steven
2c239a6ee2 Publish Canary
- vercel@20.0.0-canary.22
 - @vercel/next@2.6.21-canary.0
 - @vercel/routing-utils@1.8.4-canary.2
2020-08-14 18:32:42 -04:00
Steven
43709fbc74 Remove unused dependencies (#5042)
The CLI doesn't depend on `@vercel/redwood` for `vc dev` since PR #5036 so we can remove it.

Similarly, zero config does not install `@vercel/next` or `@vercel/static-build` during `vc dev` so these can be removed too.

In the case where the user defines `builds` in vercel.json, the runtimes will be installed during the first run of `vc dev`.
2020-08-14 18:26:46 -04:00
304 changed files with 96543 additions and 1988 deletions

View File

@@ -34,6 +34,7 @@ packages/now-node-bridge/bridge.*
# now-static-build
packages/now-static-build/test/fixtures
packages/now-static-build/test/build-fixtures
# redwood
packages/redwood/test/fixtures

View File

@@ -68,13 +68,13 @@ 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');
trace(['path/to/entrypoint.js'], {
const { nodeFileTrace } = require('@vercel/nft');
nodeFileTrace(['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

@@ -31,7 +31,7 @@ function Index() {
</h2>
<p>
<a
href="https://github.com/vercel/vercel/blob/master/gatsby"
href="https://github.com/vercel/vercel/tree/master/examples/gatsby"
target="_blank"
rel="noreferrer noopener"
>

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

@@ -8,8 +8,8 @@
"start": "next start"
},
"dependencies": {
"next": "9.5.1",
"react": "16.13.1",
"react-dom": "16.13.1"
"next": "10.0.0",
"react": "17.0.1",
"react-dom": "17.0.1"
}
}

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

@@ -17,6 +17,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `blitz build`"
},
@@ -47,6 +50,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `next build`"
},
@@ -56,10 +62,16 @@
"outputDirectory": {
"placeholder": "Next.js default"
}
}
},
"recommendedIntegrations": [
{
"id": "oac_5lUsiANun1DEzgLg0NZx5Es3",
"dependencies": ["next-plugin-sentry", "next-sentry-source-maps"]
}
]
},
{
"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",
@@ -76,6 +88,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `gatsby build`"
},
@@ -105,6 +120,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `hexo generate`"
},
@@ -134,6 +152,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `npx @11ty/eleventy`"
},
@@ -162,6 +183,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `docusaurus build`"
},
@@ -190,6 +214,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `docusaurus-build`"
},
@@ -218,6 +245,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `preact build`"
},
@@ -249,6 +279,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `dojo build`"
},
@@ -261,7 +294,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",
@@ -277,6 +310,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `ember build`"
},
@@ -305,6 +341,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `vue-cli-service build`"
},
@@ -333,6 +372,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `ng build && scully`"
},
@@ -361,6 +403,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `ng build`"
},
@@ -389,6 +434,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `ng build`"
},
@@ -417,6 +465,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `polymer build`"
},
@@ -445,6 +496,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `rollup -c`"
},
@@ -473,6 +527,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `react-scripts build`"
},
@@ -505,6 +562,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `react-scripts build`"
},
@@ -533,6 +593,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `gridsome build`"
},
@@ -561,6 +624,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `umi build`"
},
@@ -589,6 +655,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `sapper export`"
},
@@ -617,6 +686,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `saber build`"
},
@@ -645,6 +717,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `stencil build`"
},
@@ -673,6 +748,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `nuxt generate`"
},
@@ -703,6 +781,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"value": "yarn rw build && yarn rw db up --no-db-client --auto-approve && yarn rw dataMigrate up"
},
@@ -737,6 +818,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "None"
},
"buildCommand": {
"placeholder": "`npm run build` or `hugo -D --gc`"
},
@@ -764,6 +848,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`bundle install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `jekyll build`"
},
@@ -791,6 +878,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run build` or `brunch build --production`"
},
@@ -818,6 +908,9 @@
]
},
"settings": {
"installCommand": {
"placeholder": "`bundle install`"
},
"buildCommand": {
"value": "`npm run build` or `bundle exec middleman build`"
},
@@ -835,6 +928,9 @@
"logo": "https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/other.svg",
"description": "No framework or a unoptimized framework.",
"settings": {
"installCommand": {
"placeholder": "`yarn install` or `npm install`"
},
"buildCommand": {
"placeholder": "`npm run vercel-build` or `npm run build`"
},

View File

@@ -31,4 +31,8 @@ export interface Framework {
devCommand: Setting;
outputDirectory: Setting;
};
recommendedIntegrations?: {
id: string;
dependencies: string[];
}[];
}

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/frameworks",
"version": "0.0.18-canary.5",
"version": "0.1.2-canary.1",
"main": "frameworks.json",
"license": "UNLICENSED",
"scripts": {

View File

@@ -89,14 +89,39 @@ const Schema = {
},
settings: {
type: 'object',
required: ['buildCommand', 'devCommand', 'outputDirectory'],
required: [
'installCommand',
'buildCommand',
'devCommand',
'outputDirectory',
],
additionalProperties: false,
properties: {
installCommand: SchemaSettings,
buildCommand: SchemaSettings,
devCommand: SchemaSettings,
outputDirectory: SchemaSettings,
},
},
recommendedIntegrations: {
type: 'array',
items: {
type: 'object',
required: ['id', 'dependencies'],
additionalProperties: false,
properties: {
id: {
type: 'string',
},
dependencies: {
type: 'array',
items: {
type: 'string',
},
},
},
},
},
},
},
};

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/build-utils",
"version": "2.4.3-canary.4",
"version": "2.5.5-canary.1",
"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.0.18-canary.5",
"@vercel/frameworks": "0.1.2-canary.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

@@ -26,6 +26,7 @@ interface Options {
devCommand?: string | null;
buildCommand?: string | null;
outputDirectory?: string | null;
createdAt?: number;
};
cleanUrls?: boolean;
trailingSlash?: boolean;
@@ -434,6 +435,7 @@ function detectFrontBuilder(
): Builder {
const { tag, projectSettings = {} } = options;
const withTag = tag ? `@${tag}` : '';
const { createdAt = 0 } = projectSettings;
let { framework } = projectSettings;
const config: Config = {
@@ -456,7 +458,10 @@ function detectFrontBuilder(
config.outputDirectory = projectSettings.outputDirectory;
}
if (pkg && framework !== null) {
if (
pkg &&
(framework === undefined || createdAt < Date.parse('2020-03-01'))
) {
const deps: PackageJson['dependencies'] = {
...pkg.dependencies,
...pkg.devDependencies,
@@ -929,11 +934,10 @@ function getRouteResult(
const redirectRoutes: Route[] = [];
const rewriteRoutes: Route[] = [];
const errorRoutes: Route[] = [];
const isNextjs =
frontendBuilder &&
((frontendBuilder.use && frontendBuilder.use.startsWith('@vercel/next')) ||
(frontendBuilder.config &&
frontendBuilder.config.framework === 'nextjs'));
const framework = frontendBuilder?.config?.framework || '';
const use = frontendBuilder?.use || '';
const isNextjs = framework === 'nextjs' || use.startsWith('@vercel/next');
const ignoreRuntimes = slugToFramework.get(framework)?.ignoreRuntimes;
if (apiRoutes && apiRoutes.length > 0) {
if (options.featHandleMiss) {
@@ -971,11 +975,18 @@ function getRouteResult(
}
rewriteRoutes.push(...dynamicRoutes);
rewriteRoutes.push({
src: '^/api(/.*)?$',
status: 404,
continue: true,
});
if (typeof ignoreRuntimes === 'undefined') {
// This route is only necessary to hide the directory listing
// 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.
rewriteRoutes.push({
src: '^/api(/.*)?$',
status: 404,
continue: true,
});
}
} else {
defaultRoutes.push(...apiRoutes);

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

@@ -1080,7 +1080,47 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(errorRoutes).toStrictEqual([]);
});
it('Using "Other" framework with Storybook should NOT autodetect Next.js', async () => {
it('Using "Create React App" framework with `next` in dependencies should NOT autodetect Next.js for new projects', async () => {
const pkg = {
scripts: {
dev: 'react-scripts start',
build: 'react-scripts build',
},
dependencies: {
next: '9.3.5',
react: '16.13.1',
'react-dom': '16.13.1',
'react-scripts': '2.1.1',
},
};
const files = ['package.json', 'src/index.js', 'public/favicon.ico'];
const projectSettings = {
framework: 'create-react-app',
buildCommand: 'react-scripts build',
createdAt: Date.parse('2020-07-01'),
};
const { builders, errorRoutes } = await detectBuilders(files, pkg, {
projectSettings,
featHandleMiss,
});
expect(builders).toEqual([
{
use: '@vercel/static-build',
src: 'package.json',
config: {
zeroConfig: true,
framework: projectSettings.framework,
buildCommand: projectSettings.buildCommand,
},
},
]);
expect(errorRoutes!.length).toBe(1);
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('Using "Other" framework with Storybook should NOT autodetect Next.js for new projects', async () => {
const pkg = {
scripts: {
dev: 'next dev',
@@ -1104,6 +1144,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
const projectSettings = {
framework: null, // Selected "Other" framework
buildCommand: 'yarn build-storybook',
createdAt: Date.parse('2020-07-01'),
};
const { builders, errorRoutes } = await detectBuilders(files, pkg, {
@@ -1125,6 +1166,41 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect((errorRoutes![0] as Source).status).toBe(404);
});
it('Using "Other" framework should autodetect Next.js for old projects', async () => {
const pkg = {
scripts: {
dev: 'next dev',
build: 'next build',
},
dependencies: {
next: '9.3.5',
react: '16.13.1',
'react-dom': '16.13.1',
},
};
const files = ['package.json', 'pages/api/foo.js', 'index.html'];
const projectSettings = {
framework: null, // Selected "Other" framework
createdAt: Date.parse('2020-02-01'),
};
const { builders, errorRoutes } = await detectBuilders(files, pkg, {
projectSettings,
featHandleMiss,
});
expect(builders).toEqual([
{
use: '@vercel/next',
src: 'package.json',
config: {
zeroConfig: true,
},
},
]);
expect(errorRoutes).toStrictEqual([]);
});
it('api + raw static', async () => {
const files = ['api/endpoint.js', 'index.html', 'favicon.ico'];
@@ -1905,7 +1981,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
]);
});
it('RedwoodJS should allow usage of non-js API', async () => {
it('RedwoodJS should allow usage of non-js API and not add 404 api route', async () => {
const files = [...redwoodFiles, 'api/golang.go', 'api/python.py'].sort();
const projectSettings = {
framework: 'redwoodjs',
@@ -1953,13 +2029,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
check: true,
},
]);
expect(rewriteRoutes).toStrictEqual([
{
status: 404,
src: '^/api(/.*)?$',
continue: true,
},
]);
expect(rewriteRoutes).toStrictEqual([]);
expect(errorRoutes).toStrictEqual([
{
status: 404,

View File

@@ -1,3 +0,0 @@
declare module 'which-promise' {
export default function (name: string): Promise<string>;
}

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "20.0.0-canary.21",
"version": "20.1.3-canary.5",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -13,7 +13,7 @@
"scripts": {
"preinstall": "node ./scripts/preinstall.js",
"test-unit": "nyc ava test/unit.js test/dev-builder.unit.js test/dev-router.unit.js test/dev-server.unit.js test/dev-validate.unit.js --serial --fail-fast --verbose",
"test-integration-cli": "ava test/integration.js --serial --fail-fast --verbose",
"test-integration-cli": "rimraf test/fixtures/integration && ava test/integration.js --serial --fail-fast --verbose",
"test-integration-dev": "ava test/dev/integration.js --serial --fail-fast --verbose",
"prepublishOnly": "yarn build",
"coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov",
@@ -61,14 +61,11 @@
"node": ">= 10"
},
"dependencies": {
"@vercel/build-utils": "2.4.3-canary.4",
"@vercel/go": "1.1.5-canary.0",
"@vercel/next": "2.6.20",
"@vercel/node": "1.7.5-canary.1",
"@vercel/python": "1.2.2",
"@vercel/redwood": "0.0.2-canary.7",
"@vercel/ruby": "1.2.3",
"@vercel/static-build": "0.17.7-canary.3",
"@vercel/build-utils": "2.5.5-canary.1",
"@vercel/go": "1.1.6",
"@vercel/node": "1.8.4",
"@vercel/python": "1.2.3",
"@vercel/ruby": "1.2.4",
"update-notifier": "4.1.0"
},
"devDependencies": {
@@ -103,9 +100,9 @@
"@types/universal-analytics": "0.4.2",
"@types/which": "1.3.2",
"@types/write-json-file": "2.2.1",
"@vercel/frameworks": "0.0.18-canary.5",
"@vercel/frameworks": "0.1.2-canary.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",
@@ -124,13 +121,9 @@
"cpy": "7.2.0",
"credit-card": "3.0.1",
"date-fns": "1.29.0",
"death": "1.1.0",
"debug": "3.1.0",
"deployment-type": "1.0.1",
"docker-file-parser": "1.0.2",
"dot": "1.1.3",
"dotenv": "4.0.0",
"download": "6.2.5",
"email-prompt": "0.3.2",
"email-validator": "1.1.1",
"epipebomb": "1.0.0",
@@ -141,8 +134,7 @@
"fs-extra": "7.0.1",
"get-port": "5.1.1",
"glob": "7.1.2",
"http-proxy": "1.17.0",
"ignore": "4.0.6",
"http-proxy": "1.18.1",
"inquirer": "7.0.4",
"is-port-reachable": "3.0.0",
"is-url": "1.2.2",
@@ -154,21 +146,18 @@
"minimatch": "3.0.4",
"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",
"pcre-to-regexp": "1.0.0",
"pluralize": "7.0.0",
"printf": "0.2.5",
"progress": "2.0.3",
"promisepipe": "3.0.0",
"psl": "1.1.31",
"qr-image": "3.2.0",
"raw-body": "2.4.1",
"read-pkg": "2.0.0",
"rx-lite-aggregates": "4.0.8",
"rimraf": "3.0.2",
"semver": "5.5.0",
"serve-handler": "6.1.1",
"sinon": "4.4.2",
@@ -177,17 +166,14 @@
"tar-fs": "1.16.3",
"test-listen": "1.1.0",
"text-table": "0.2.0",
"then-sleep": "1.0.1",
"through2": "2.0.3",
"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",
"utility-types": "2.1.0",
"which": "2.0.2",
"which-promise": "1.0.0",
"write-json-file": "2.2.0",
"xdg-app-paths": "5.1.0"
}

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

@@ -18,7 +18,7 @@ const help = () => {
${chalk.dim('Commands:')}
ls [app] Show all aliases (or per app name)
ls Show all aliases
set <deployment> <alias> Create a new alias
rm <alias> Remove an alias using its hostname
@@ -39,19 +39,19 @@ const help = () => {
-N, --next Show next page of results
${chalk.dim('Examples:')}
${chalk.gray('')} Add a new alias to ${chalk.underline('my-api.now.sh')}
${chalk.gray('')} Add a new alias to ${chalk.underline('my-api.vercel.app')}
${chalk.cyan(
`$ ${getPkgName()} alias set ${chalk.underline(
'api-ownv3nc9f8.now.sh'
)} ${chalk.underline('my-api.now.sh')}`
'api-ownv3nc9f8.vercel.app'
)} ${chalk.underline('my-api.vercel.app')}`
)}
Custom domains work as alias targets
${chalk.cyan(
`$ ${getPkgName()} alias set ${chalk.underline(
'api-ownv3nc9f8.now.sh'
'api-ownv3nc9f8.vercel.app'
)} ${chalk.underline('my-api.com')}`
)}

View File

@@ -1,6 +1,5 @@
import chalk from 'chalk';
import ms from 'ms';
import plural from 'pluralize';
import table from 'text-table';
import Now from '../../util';
import Client from '../../util/client.ts';
@@ -52,21 +51,17 @@ export default async function ls(ctx, opts, args, output) {
const lsStamp = stamp();
let cancelWait;
if (args.length > 1) {
if (args.length > 0) {
output.error(
`Invalid number of arguments. Usage: ${chalk.cyan(
`${getCommandName('alias ls [alias]')}`
`${getCommandName('alias ls')}`
)}`
);
return 1;
}
cancelWait = output.spinner(
args[0]
? `Fetching alias details for "${args[0]}" under ${chalk.bold(
contextName
)}`
: `Fetching aliases under ${chalk.bold(contextName)}`
`Fetching aliases under ${chalk.bold(contextName)}`
);
const { aliases, pagination } = await getAliases(
@@ -76,32 +71,8 @@ export default async function ls(ctx, opts, args, output) {
);
if (cancelWait) cancelWait();
if (args[0]) {
const alias = aliases.find(
item => item.uid === args[0] || item.alias === args[0]
);
if (!alias) {
output.error(`Could not match path alias for: ${args[0]}`);
now.close();
return 1;
}
if (opts['--json']) {
console.log(JSON.stringify({ rules: alias.rules }, null, 2));
} else {
const rules = alias.rules || [];
output.log(
`${rules.length} path alias ${plural(
'rule',
rules.length
)} found under ${chalk.bold(contextName)} ${lsStamp()}`
);
output.print(`${printPathAliasTable(rules)}\n`);
}
} else {
output.log(`aliases found under ${chalk.bold(contextName)} ${lsStamp()}`);
console.log(printAliasTable(aliases));
}
output.log(`aliases found under ${chalk.bold(contextName)} ${lsStamp()}`);
console.log(printAliasTable(aliases));
if (pagination && pagination.count === 20) {
const flags = getCommandFlags(opts, ['_', '--next']);
@@ -121,14 +92,10 @@ function printAliasTable(aliases) {
[
['source', 'url', 'age'].map(h => chalk.gray(h)),
...aliases.map(a => [
a.rules && a.rules.length
? chalk.cyan(`[${plural('rule', a.rules.length, true)}]`)
: // for legacy reasons, we might have situations
// where the deployment was deleted and the alias
// not collected appropriately, and we need to handle it
a.deployment && a.deployment.url
? a.deployment.url
: chalk.gray(''),
// for legacy reasons, we might have situations
// where the deployment was deleted and the alias
// not collected appropriately, and we need to handle it
a.deployment && a.deployment.url ? a.deployment.url : chalk.gray(''),
a.alias,
ms(Date.now() - new Date(a.createdAt)),
]),
@@ -140,21 +107,3 @@ function printAliasTable(aliases) {
}
).replace(/^/gm, ' ')}\n\n`;
}
function printPathAliasTable(rules) {
const header = [['pathname', 'method', 'dest'].map(s => chalk.gray(s))];
return `${table(
header.concat(
rules.map(rule => [
rule.pathname ? rule.pathname : chalk.cyan('[fallthrough]'),
rule.method ? rule.method : '*',
rule.dest,
])
),
{
align: ['l', 'l', 'l', 'l'],
hsep: ' '.repeat(6),
stringLength: strlen,
}
).replace(/^(.*)/gm, ' $1')}\n`;
}

View File

@@ -7,7 +7,7 @@ import getScope from '../../util/get-scope.ts';
import removeAliasById from '../../util/alias/remove-alias-by-id';
import stamp from '../../util/output/stamp.ts';
import strlen from '../../util/strlen.ts';
import promptBool from '../../util/prompt-bool';
import confirm from '../../util/input/confirm';
import { isValidName } from '../../util/is-valid-name';
import findAliasByAliasOrId from '../../util/alias/find-alias-by-alias-or-id';
import { getCommandName } from '../../util/pkg-name.ts';
@@ -108,5 +108,5 @@ async function confirmAliasRemove(output, alias) {
output.log(`The following alias will be removed permanently`);
output.print(` ${tbl}\n`);
return promptBool(output, chalk.red('Are you sure?'));
return confirm(chalk.red('Are you sure?'), false);
}

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;
}
@@ -388,7 +388,7 @@ function handleCreateAliasError<T>(
}
if (error instanceof ERRORS.InvalidAlias) {
output.error(
`Invalid alias. Please confirm that the alias you provided is a valid hostname. Note: For \`now.sh\`, only sub and sub-sub domains are supported.`
`Invalid alias. Please confirm that the alias you provided is a valid hostname. Note: For \`vercel.app\`, only sub and sub-sub domains are supported.`
);
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,13 +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`
);
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);
}
}
};
@@ -239,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(
@@ -272,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 =
@@ -329,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(
@@ -345,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 &&
@@ -364,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})`);
@@ -521,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,
@@ -542,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

@@ -111,12 +111,11 @@ export default async function inspect(
` ${chalk.cyan('Created At')}\t\t\t${formatDate(domain.createdAt)}\n`
);
output.print(` ${chalk.cyan('Edge Network')}\t\tyes\n`);
if (renewalPrice && domain.boughtAt) {
output.print(
` ${chalk.cyan('Renewal Price')}\t\t$${renewalPrice} USD\n`
);
}
output.print(
` ${chalk.cyan('Renewal Price')}\t\t${
domain.boughtAt && renewalPrice ? `$${renewalPrice} USD` : chalk.gray('-')
}\n`
);
output.print('\n');

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

@@ -1,6 +1,6 @@
import chalk from 'chalk';
import inquirer from 'inquirer';
import { ProjectEnvTarget, Project } from '../../types';
import { ProjectEnvTarget, Project, Secret, ProjectEnvType } from '../../types';
import { Output } from '../../util/output';
import Client from '../../util/client';
import stamp from '../../util/output/stamp';
@@ -11,12 +11,14 @@ import {
getEnvTargetPlaceholder,
getEnvTargetChoices,
} from '../../util/env/env-target';
import { isValidEnvType, getEnvTypePlaceholder } from '../../util/env/env-type';
import readStandardInput from '../../util/input/read-standard-input';
import param from '../../util/output/param';
import withSpinner from '../../util/with-spinner';
import { emoji, prependEmoji } from '../../util/emoji';
import { isKnownError } from '../../util/env/known-error';
import { getCommandName } from '../../util/pkg-name';
import { SYSTEM_ENV_VALUES } from '../../util/env/system-env';
type Options = {
'--debug': boolean;
@@ -29,38 +31,71 @@ export default async function add(
args: string[],
output: Output
) {
const stdInput = await readStandardInput();
let [envName, envTarget] = args;
// improve the way we show inquirer prompts
require('../../util/input/patch-inquirer');
if (args.length > 2) {
const stdInput = await readStandardInput();
let [envTypeArg, envName, envTargetArg] = args;
if (args.length > 3) {
output.error(
`Invalid number of arguments. Usage: ${getCommandName(
`env add <name> ${getEnvTargetPlaceholder()}`
`env add ${getEnvTypePlaceholder()} <name> ${getEnvTargetPlaceholder()}`
)}`
);
return 1;
}
if (stdInput && (!envName || !envTarget)) {
if (stdInput && (!envTypeArg || !envName || !envTargetArg)) {
output.error(
`Invalid number of arguments. Usage: ${getCommandName(
`env add <name> <target> < <file>`
`env add ${getEnvTypePlaceholder()} <name> <target> < <file>`
)}`
);
return 1;
}
let envTargets: ProjectEnvTarget[] = [];
if (envTarget) {
if (!isValidEnvTarget(envTarget)) {
if (envTargetArg) {
if (!isValidEnvTarget(envTargetArg)) {
output.error(
`The Environment ${param(
envTarget
envTargetArg
)} is invalid. It must be one of: ${getEnvTargetPlaceholder()}.`
);
return 1;
}
envTargets.push(envTarget);
envTargets.push(envTargetArg);
}
let envType: ProjectEnvType;
if (envTypeArg) {
if (!isValidEnvType(envTypeArg)) {
output.error(
`The Environment Variable type ${param(
envTypeArg
)} is invalid. It must be one of: ${getEnvTypePlaceholder()}.`
);
return 1;
}
envType = envTypeArg;
} else {
const answers = (await inquirer.prompt({
name: 'inputEnvType',
type: 'list',
message: `Which type of Environment Variable do you want to add?`,
choices: [
{ name: 'Plaintext', value: ProjectEnvType.Plaintext },
{
name: `Secret (can be created using ${getCommandName('secret add')})`,
value: ProjectEnvType.Secret,
},
{ name: 'Provided by System', value: ProjectEnvType.System },
],
})) as { inputEnvType: ProjectEnvType };
envType = answers.inputEnvType;
}
while (!envName) {
@@ -77,7 +112,7 @@ export default async function add(
}
}
const envs = await getEnvVariables(output, client, project.id, 4);
const { envs } = await getEnvVariables(output, client, project.id);
const existing = new Set(
envs.filter(r => r.key === envName).map(r => r.target)
);
@@ -98,15 +133,59 @@ export default async function add(
if (stdInput) {
envValue = stdInput;
} else if (isSystemEnvVariable(envName)) {
envValue = '';
} else {
} else if (envType === ProjectEnvType.Plaintext) {
const { inputValue } = await inquirer.prompt({
type: 'password',
type: 'input',
name: 'inputValue',
message: `Whats the value of ${envName}?`,
});
envValue = inputValue || '';
} else if (envType === ProjectEnvType.Secret) {
let secretId: string | null = null;
while (!secretId) {
let { secretName } = await inquirer.prompt({
type: 'input',
name: 'secretName',
message: `Whats the value of ${envName}?`,
});
secretName = secretName || '';
if (secretName[0] === '@') {
secretName = secretName.slice(1);
}
try {
const secret = await client.fetch<Secret>(
`/v2/now/secrets/${encodeURIComponent(secretName)}`
);
secretId = secret.uid;
} catch (error) {
if (error.status === 404) {
output.error(
`Please enter the name of an existing Secret (can be created with ${getCommandName(
'secret add'
)}).`
);
} else {
throw error;
}
}
}
envValue = secretId;
} else {
const { systemEnvValue } = await inquirer.prompt({
name: 'systemEnvValue',
type: 'list',
message: `Whats the value of ${envName}?`,
choices: SYSTEM_ENV_VALUES.map(value => ({ name: value, value })),
});
envValue = systemEnvValue;
}
while (envTargets.length === 0) {
@@ -127,7 +206,15 @@ export default async function add(
const addStamp = stamp();
try {
await withSpinner('Saving', () =>
addEnvRecord(output, client, project.id, envName, envValue, envTargets)
addEnvRecord(
output,
client,
project.id,
envType,
envName,
envValue,
envTargets
)
);
} catch (error) {
if (isKnownError(error) && error.serverMessage) {
@@ -148,7 +235,3 @@ export default async function add(
return 0;
}
function isSystemEnvVariable(envName: string) {
return envName.startsWith('VERCEL_');
}

View File

@@ -6,6 +6,7 @@ import getArgs from '../../util/get-args';
import getSubcommand from '../../util/get-subcommand';
import getInvalidSubcommand from '../../util/get-invalid-subcommand';
import { getEnvTargetPlaceholder } from '../../util/env/env-target';
import { getEnvTypePlaceholder } from '../../util/env/env-type';
import { getLinkedProject } from '../../util/projects/link';
import Client from '../../util/client';
import handleError from '../../util/handle-error';
@@ -18,16 +19,17 @@ import ls from './ls';
import rm from './rm';
const help = () => {
const placeholder = getEnvTargetPlaceholder();
const typePlaceholder = getEnvTypePlaceholder();
const targetPlaceholder = getEnvTargetPlaceholder();
console.log(`
${chalk.bold(`${logo} ${getPkgName()} env`)} [options] <command>
${chalk.dim('Commands:')}
ls [environment] List all variables for the specified Environment
add [name] [environment] Add an Environment Variable (see examples below)
rm [name] [environment] Remove an Environment Variable (see examples below)
pull [filename] Pull all Development Environment Variables from the cloud and write to a file [.env]
ls [environment] List all variables for the specified Environment
add [type] [name] [environment] Add an Environment Variable (see examples below)
rm [name] [environment] Remove an Environment Variable (see examples below)
pull [filename] Pull all Development Environment Variables from the cloud and write to a file [.env]
${chalk.dim('Options:')}
@@ -42,27 +44,32 @@ const help = () => {
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
'TOKEN'
)} Login token
-N, --next Show next page of results
${chalk.dim('Examples:')}
${chalk.gray('')} Add a new variable to multiple Environments
${chalk.cyan(`$ ${getPkgName()} env add <name>`)}
${chalk.cyan(`$ ${getPkgName()} env add API_TOKEN`)}
${chalk.cyan(`$ ${getPkgName()} env add ${typePlaceholder} <name>`)}
${chalk.cyan(`$ ${getPkgName()} env add secret API_TOKEN`)}
${chalk.gray('')} Add a new variable for a specific Environment
${chalk.cyan(`$ ${getPkgName()} env add <name> ${placeholder}`)}
${chalk.cyan(`$ ${getPkgName()} env add DB_CONNECTION production`)}
${chalk.cyan(
`$ ${getPkgName()} env add ${typePlaceholder} <name> ${targetPlaceholder}`
)}
${chalk.cyan(`$ ${getPkgName()} env add secret DB_PASS production`)}
${chalk.gray('')} Add a new Environment Variable from stdin
${chalk.cyan(
`$ cat <file> | ${getPkgName()} env add <name> ${placeholder}`
`$ cat <file> | ${getPkgName()} env add ${typePlaceholder} <name> ${targetPlaceholder}`
)}
${chalk.cyan(
`$ cat ~/.npmrc | ${getPkgName()} env add plain NPM_RC preview`
)}
${chalk.cyan(
`$ ${getPkgName()} env add plain API_URL production < url.txt`
)}
${chalk.cyan(`$ cat ~/.npmrc | ${getPkgName()} env add NPM_RC preview`)}
${chalk.cyan(`$ ${getPkgName()} env add DB_PASS production < secret.txt`)}
${chalk.gray('')} Remove an variable from multiple Environments
@@ -71,14 +78,8 @@ const help = () => {
${chalk.gray('')} Remove a variable from a specific Environment
${chalk.cyan(`$ ${getPkgName()} env rm <name> ${placeholder}`)}
${chalk.cyan(`$ ${getPkgName()} env rm <name> ${targetPlaceholder}`)}
${chalk.cyan(`$ ${getPkgName()} env rm NPM_RC preview`)}
${chalk.gray('')} Paginate results, where ${chalk.dim(
'`1584722256178`'
)} is the time in milliseconds since the UNIX epoch.
${chalk.cyan(`$ ${getPkgName()} env ls --next 1584722256178`)}
`);
};
@@ -96,8 +97,6 @@ export default async function main(ctx: NowContext) {
argv = getArgs(ctx.argv.slice(2), {
'--yes': Boolean,
'-y': '--yes',
'--next': Number,
'-N': '--next',
});
} catch (error) {
handleError(error);

View File

@@ -1,7 +1,12 @@
import chalk from 'chalk';
import ms from 'ms';
import { Output } from '../../util/output';
import { ProjectEnvVariable, ProjectEnvTarget, Project } from '../../types';
import {
ProjectEnvTarget,
Project,
ProjectEnvVariable,
ProjectEnvType,
} from '../../types';
import Client from '../../util/client';
import formatTable from '../../util/format-table';
import getEnvVariables from '../../util/env/get-env-records';
@@ -11,12 +16,13 @@ import {
} from '../../util/env/env-target';
import stamp from '../../util/output/stamp';
import param from '../../util/output/param';
import getCommandFlags from '../../util/get-command-flags';
import { getCommandName } from '../../util/pkg-name';
import ellipsis from '../../util/output/ellipsis';
// @ts-ignore
import title from 'title';
type Options = {
'--debug': boolean;
'--next'?: number;
};
export default async function ls(
@@ -26,8 +32,6 @@ export default async function ls(
args: string[],
output: Output
) {
const { '--next': nextTimestamp } = opts;
if (args.length > 1) {
output.error(
`Invalid number of arguments. Usage: ${getCommandName(
@@ -50,42 +54,21 @@ export default async function ls(
const lsStamp = stamp();
if (typeof nextTimestamp !== 'undefined' && Number.isNaN(nextTimestamp)) {
output.error('Please provide a number for flag --next');
return 1;
}
const { envs } = await getEnvVariables(output, client, project.id, envTarget);
const data = await getEnvVariables(
output,
client,
project.id,
5,
envTarget,
nextTimestamp
);
const { envs: records, pagination } = data;
output.log(
`${
records.length > 0 ? 'Environment Variables' : 'No Environment Variables'
envs.length > 0 ? 'Environment Variables' : 'No Environment Variables'
} found in Project ${chalk.bold(project.name)} ${chalk.gray(lsStamp())}`
);
console.log(getTable(records));
if (pagination && pagination.count === 20) {
const flags = getCommandFlags(opts, ['_', '--next']);
output.log(
`To display the next page run ${getCommandName(
`env ls${flags} --next ${pagination.next}`
)}`
);
}
console.log(getTable(envs));
return 0;
}
function getTable(records: ProjectEnvVariable[]) {
return formatTable(
['name', 'value', 'environment', 'created'],
['name', 'value', 'environments', 'created'],
['l', 'l', 'l', 'l', 'l'],
[
{
@@ -96,17 +79,27 @@ function getTable(records: ProjectEnvVariable[]) {
);
}
function getRow({
key,
system = false,
target,
createdAt = 0,
}: ProjectEnvVariable) {
function getRow(env: ProjectEnvVariable) {
let value: string;
if (env.type === ProjectEnvType.Plaintext) {
// replace space characters (line-break, etc.) with simple spaces
// to make sure the displayed value is a single line
const singleLineValue = env.value.replace(/\s/g, ' ');
value = chalk.gray(ellipsis(singleLineValue, 19));
} else if (env.type === ProjectEnvType.System) {
value = chalk.gray.italic(env.value);
} else {
value = chalk.gray.italic('Encrypted');
}
const now = Date.now();
return [
chalk.bold(key),
chalk.gray(chalk.italic(system ? 'Populated by System' : 'Encrypted')),
target || '',
`${ms(now - createdAt)} ago`,
chalk.bold(env.key),
value,
(Array.isArray(env.target) ? env.target : [env.target || ''])
.map(title)
.join(', '),
env.createdAt ? `${ms(now - env.createdAt)} ago` : '',
];
}

View File

@@ -1,7 +1,7 @@
import chalk from 'chalk';
import { ProjectEnvTarget, Project } from '../../types';
import { Output } from '../../util/output';
import promptBool from '../../util/prompt-bool';
import confirm from '../../util/input/confirm';
import Client from '../../util/client';
import stamp from '../../util/output/stamp';
import getDecryptedEnvRecords from '../../util/get-decrypted-env-records';
@@ -68,9 +68,9 @@ export default async function pull(
} else if (
exists &&
!skipConfirmation &&
!(await promptBool(
output,
`Found existing file ${param(filename)}. Do you want to overwrite?`
!(await confirm(
`Found existing file ${param(filename)}. Do you want to overwrite?`,
false
))
) {
output.log('Aborted');

View File

@@ -1,8 +1,8 @@
import chalk from 'chalk';
import inquirer from 'inquirer';
import { ProjectEnvTarget, Project } from '../../types';
import { ProjectEnvTarget, Project, ProjectEnvVariableV5 } from '../../types';
import { Output } from '../../util/output';
import promptBool from '../../util/prompt-bool';
import confirm from '../../util/input/confirm';
import removeEnvRecord from '../../util/env/remove-env-record';
import getEnvVariables from '../../util/env/get-env-records';
import {
@@ -30,6 +30,9 @@ export default async function rm(
args: string[],
output: Output
) {
// improve the way we show inquirer prompts
require('../../util/input/patch-inquirer');
if (args.length > 2) {
output.error(
`Invalid number of arguments. Usage: ${getCommandName(
@@ -69,7 +72,20 @@ export default async function rm(
envName = inputName;
}
const envs = await getEnvVariables(output, client, project.id, 4);
const data = await getEnvVariables(output, client, project.id);
// we expand env vars with multiple targets
const envs: ProjectEnvVariableV5[] = [];
for (let env of data.envs) {
if (Array.isArray(env.target)) {
for (let target of env.target) {
envs.push({ ...env, target });
}
} else {
envs.push({ ...env, target: env.target });
}
}
const existing = new Set(
envs.filter(r => r.key === envName).map(r => r.target)
);
@@ -79,7 +95,7 @@ export default async function rm(
return 1;
}
if (envTargets.length === 0) {
while (envTargets.length === 0) {
const choices = getEnvTargetChoices().filter(c => existing.has(c.value));
if (choices.length === 0) {
output.error(
@@ -97,6 +113,13 @@ export default async function rm(
message: `Remove ${envName} from which Environments (select multiple)?`,
choices,
});
if (inputTargets.length === 0) {
output.error(
'Please select an Environment to remove the Environment Variable from.'
);
}
envTargets = inputTargets;
}
}
@@ -104,11 +127,11 @@ export default async function rm(
const skipConfirmation = opts['--yes'];
if (
!skipConfirmation &&
!(await promptBool(
output,
!(await confirm(
`Removing Environment Variable ${param(
envName
)} from Project ${chalk.bold(project.name)}. Are you sure?`
)} from Project ${chalk.bold(project.name)}. Are you sure?`,
false
))
) {
output.log('Aborted');

View File

@@ -13,7 +13,6 @@ try {
process.exit(1);
}
}
import 'core-js/modules/es7.symbol.async-iterator';
import { join } from 'path';
import { existsSync, lstatSync } from 'fs';
import sourceMap from '@zeit/source-map-support';
@@ -135,7 +134,7 @@ const main = async argv_ => {
// (as in: `vercel ls`)
const targetOrSubcommand = argv._[2];
if (notifier.update && isTTY) {
if (notifier.update && notifier.update.latest !== pkg.version && isTTY) {
const { latest } = notifier.update;
console.log(
info(

View File

@@ -117,12 +117,6 @@ export type Deployment = {
creator: { uid: string };
};
type PathAliasRule = {
pathname: string;
method: Array<'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE'>;
dest: string;
};
export type Alias = {
uid: string;
alias: string;
@@ -137,13 +131,6 @@ export type Alias = {
email: string;
};
deploymentId?: string;
rules?: PathAliasRule[];
};
export type PathRule = {
dest: string;
pathname?: string;
method?: Array<string>;
};
export type DNSRecord = {
@@ -216,12 +203,23 @@ export enum ProjectEnvTarget {
Development = 'development',
}
export enum ProjectEnvType {
Plaintext = 'plain',
Secret = 'secret',
System = 'system',
}
export interface ProjectEnvVariable {
key: string;
value: string;
type: ProjectEnvType;
configurationId?: string | null;
createdAt?: number;
updatedAt?: number;
target?: ProjectEnvTarget | ProjectEnvTarget[];
}
export interface ProjectEnvVariableV5 extends ProjectEnvVariable {
target?: ProjectEnvTarget;
system?: boolean;
}

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

@@ -172,6 +172,10 @@ export default async function processDeployment({
if (event.type === 'created') {
deployingSpinner();
if (bar && !bar.complete) {
bar.tick(bar.total + 1);
}
now._host = event.payload.url;
await linkFolderToProject(

View File

@@ -923,9 +923,17 @@ export default class DevServer {
await once(this.watcher, 'ready');
// Configure the server to forward WebSocket "upgrade" events to the proxy.
this.server.on('upgrade', (req, socket, head) => {
this.server.on('upgrade', async (req, socket, head) => {
await this.startPromise;
if (!this.devProcessPort) {
this.output.debug(
`Detected "upgrade" event, but closing socket because no frontend dev server is running`
);
socket.destroy();
return;
}
const target = `http://localhost:${this.devProcessPort}`;
this.output.debug(`Detected upgrade event, proxying to ${target}`);
this.output.debug(`Detected "upgrade" event, proxying to ${target}`);
this.proxy.ws(req, socket, head, { target });
});
@@ -1364,6 +1372,7 @@ export default class DevServer {
const missRoutes = handleMap.get('miss') || [];
const hitRoutes = handleMap.get('hit') || [];
const errorRoutes = handleMap.get('error') || [];
const filesystemRoutes = handleMap.get('filesystem') || [];
const phases: (HandleValue | null)[] = [null, 'filesystem'];
let routeResult: RouteResult | null = null;
@@ -1475,40 +1484,63 @@ export default class DevServer {
routeResult.status = prevStatus;
}
if (!match && errorRoutes.length > 0) {
// error phase
const routeResultForError = await devRouter(
getReqUrl(routeResult),
req.method,
errorRoutes,
this,
nowConfig,
routeResult.headers,
[],
'error'
);
const matchForError = await findBuildMatch(
this.buildMatches,
this.files,
routeResultForError.dest,
this,
nowConfig
);
if (matchForError) {
// error phase only applies if the file was found
routeResult = routeResultForError;
match = matchForError;
}
}
statusCode = routeResult.status;
if (match) {
// end the phase
break;
}
if (phase === null && filesystemRoutes.length === 0) {
// hack to skip the reset from null to filesystem
break;
}
}
if (!match && routeResult && errorRoutes.length > 0) {
// error phase
const routeResultForError = await devRouter(
getReqUrl(routeResult),
req.method,
errorRoutes,
this,
nowConfig,
routeResult.headers,
[],
'error'
);
const { matched_route } = routeResultForError;
const matchForError = await findBuildMatch(
this.buildMatches,
this.files,
routeResultForError.dest,
this,
nowConfig
);
if (matchForError) {
debug(`Route match detected in error phase, breaking loop`);
routeResult = routeResultForError;
statusCode = routeResultForError.status;
match = matchForError;
} else if (matched_route && matched_route.src && !matched_route.dest) {
debug(
'Route without `dest` detected in error phase, attempting to exit early'
);
if (
await this.exitWithStatus(
matchForError,
routeResultForError,
'error',
req,
res,
nowRequestId
)
) {
return;
}
}
}
if (!routeResult) {

View File

@@ -1,60 +1,39 @@
import { Output } from '../output';
import Client from '../client';
import { Secret, ProjectEnvTarget, ProjectEnvVariable } from '../../types';
import { customAlphabet } from 'nanoid';
import slugify from '@sindresorhus/slugify';
import {
Secret,
ProjectEnvTarget,
ProjectEnvVariableV5,
ProjectEnvType,
} from '../../types';
export default async function addEnvRecord(
output: Output,
client: Client,
projectId: string,
envName: string,
envValue: string | undefined,
type: ProjectEnvType,
key: string,
envValue: string,
targets: ProjectEnvTarget[]
): Promise<void> {
output.debug(
`Adding Environment Variable ${envName} to ${targets.length} targets`
`Adding ${type} Environment Variable ${key} to ${targets.length} targets`
);
let values: string[] | undefined;
let value = envValue;
if (envValue) {
const secrets = await Promise.all(
targets.map(target =>
client.fetch<Secret>('/v2/now/secrets', {
method: 'POST',
body: JSON.stringify({
name: generateSecretName(envName, target),
value: envValue,
projectId: projectId,
decryptable: target === ProjectEnvTarget.Development,
}),
})
)
if (type === ProjectEnvType.Secret) {
const secret = await client.fetch<Secret>(
`/v2/now/secrets/${encodeURIComponent(envValue)}`
);
values = secrets.map(secret => secret.uid);
value = secret.uid;
}
const body = targets.map((target, i) => ({
key: envName,
value: values ? values[i] : '',
target,
}));
const body = { type, key, value, target: targets };
const urlProject = `/v4/projects/${projectId}/env`;
await client.fetch<ProjectEnvVariable>(urlProject, {
const urlProject = `/v6/projects/${projectId}/env`;
await client.fetch<ProjectEnvVariableV5>(urlProject, {
method: 'POST',
body: JSON.stringify(body),
});
}
const randomSecretSuffix = customAlphabet(
'123456789abcdefghijklmnopqrstuvwxyz',
4
);
function generateSecretName(envName: string, target: ProjectEnvTarget) {
return `${
slugify(envName).substring(0, 80) // we truncate because the max secret length is 100
}-${target}-${randomSecretSuffix()}`;
}

View File

@@ -0,0 +1,15 @@
import { ProjectEnvType } from '../../types';
function envTypes(): string[] {
return Object.values(ProjectEnvType);
}
export function isValidEnvType(
type?: string
): type is ProjectEnvType | undefined {
return typeof type === 'undefined' || envTypes().includes(type);
}
export function getEnvTypePlaceholder() {
return `<${envTypes().join(' | ')}>`;
}

View File

@@ -1,69 +1,24 @@
import { Output } from '../output';
import Client from '../client';
import {
ProjectEnvVariable,
ProjectEnvTarget,
PaginationOptions,
} from '../../types';
import { ProjectEnvVariable, ProjectEnvTarget } from '../../types';
import { URLSearchParams } from 'url';
type ApiVersion = 4 | 5;
type APIV4Response = ProjectEnvVariable[];
interface APIV5Response {
pagination: PaginationOptions;
envs: ProjectEnvVariable[];
}
export default async function getEnvVariables(
output: Output,
client: Client,
projectId: string,
apiVersion: 4,
target?: ProjectEnvTarget
): Promise<APIV4Response>;
export default async function getEnvVariables(
output: Output,
client: Client,
projectId: string,
apiVersion: 5,
target?: ProjectEnvTarget,
next?: number
): Promise<APIV5Response>;
export default async function getEnvVariables<V extends ApiVersion>(
output: Output,
client: Client,
projectId: string,
apiVersion: V,
target?: ProjectEnvTarget,
next?: number
) {
output.debug(
`Fetching Environment Variables of project ${projectId} and target ${target}`
);
const query = new URLSearchParams();
if (apiVersion >= 5) {
query.set('limit', String(20));
}
if (target) {
query.set('target', target);
}
if (next) {
query.set('until', String(next));
}
const url = `/v6/projects/${projectId}/env?${query}`;
const url = `/v${apiVersion}/projects/${projectId}/env?${query}`;
if (apiVersion === 5) {
return client.fetch<APIV5Response>(url);
} else if (apiVersion === 4) {
return client.fetch<APIV4Response>(url);
} else {
throw new Error('Unknown version: ' + apiVersion);
}
return client.fetch<{ envs: ProjectEnvVariable[] }>(url);
}

View File

@@ -1,6 +1,6 @@
import { Output } from '../output';
import Client from '../client';
import { ProjectEnvTarget, Secret, ProjectEnvVariable } from '../../types';
import { ProjectEnvTarget, Secret, ProjectEnvVariableV5 } from '../../types';
export default async function removeEnvRecord(
output: Output,
@@ -18,7 +18,7 @@ export default async function removeEnvRecord(
envName
)}${qs}`;
const env = await client.fetch<ProjectEnvVariable>(urlProject, {
const env = await client.fetch<ProjectEnvVariableV5>(urlProject, {
method: 'DELETE',
});

View File

@@ -0,0 +1,32 @@
export const SYSTEM_ENV_VALUES = [
'VERCEL_URL',
'VERCEL_GITHUB_COMMIT_ORG',
'VERCEL_GITHUB_COMMIT_REF',
'VERCEL_GITHUB_ORG',
'VERCEL_GITHUB_DEPLOYMENT',
'VERCEL_GITHUB_COMMIT_REPO',
'VERCEL_GITHUB_REPO',
'VERCEL_GITHUB_COMMIT_AUTHOR_LOGIN',
'VERCEL_GITHUB_COMMIT_AUTHOR_NAME',
'VERCEL_GITHUB_COMMIT_SHA',
'VERCEL_GITLAB_DEPLOYMENT',
'VERCEL_GITLAB_PROJECT_NAMESPACE',
'VERCEL_GITLAB_PROJECT_NAME',
'VERCEL_GITLAB_PROJECT_ID',
'VERCEL_GITLAB_PROJECT_PATH',
'VERCEL_GITLAB_COMMIT_REF',
'VERCEL_GITLAB_COMMIT_SHA',
'VERCEL_GITLAB_COMMIT_MESSAGE',
'VERCEL_GITLAB_COMMIT_AUTHOR_LOGIN',
'VERCEL_GITLAB_COMMIT_AUTHOR_NAME',
'VERCEL_BITBUCKET_DEPLOYMENT',
'VERCEL_BITBUCKET_REPO_OWNER',
'VERCEL_BITBUCKET_REPO_SLUG',
'VERCEL_BITBUCKET_REPO_NAME',
'VERCEL_BITBUCKET_COMMIT_REF',
'VERCEL_BITBUCKET_COMMIT_SHA',
'VERCEL_BITBUCKET_COMMIT_MESSAGE',
'VERCEL_BITBUCKET_COMMIT_AUTHOR_NAME',
'VERCEL_BITBUCKET_COMMIT_AUTHOR_URL',
'VERCEL_BITBUCKET_COMMIT_AUTHOR_AVATAR',
];

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

@@ -2,7 +2,7 @@ import getEnvVariables from './env/get-env-records';
import getDecryptedSecret from './env/get-decrypted-secret';
import Client from './client';
import { Output } from './output/create-output';
import { ProjectEnvTarget, Project } from '../types';
import { ProjectEnvTarget, Project, ProjectEnvType } from '../types';
import { Env } from '@vercel/build-utils';
@@ -12,9 +12,15 @@ export default async function getDecryptedEnvRecords(
project: Project,
target: ProjectEnvTarget
): Promise<Env> {
const envs = await getEnvVariables(output, client, project.id, 4, target);
const { envs } = await getEnvVariables(output, client, project.id, target);
const decryptedValues = await Promise.all(
envs.map(async env => {
if (env.type === ProjectEnvType.System) {
return { value: '', found: true };
} else if (env.type === ProjectEnvType.Plaintext) {
return { value: env.value, found: true };
}
try {
const value = await getDecryptedSecret(output, client, env.value);
return { value, found: true };

View File

@@ -1,13 +1,9 @@
import { resolve } from 'path';
import ignore from 'ignore';
import _glob, { IOptions as GlobOptions } from 'glob';
import fs from 'fs-extra';
import { getVercelIgnore } from '@vercel/client';
import IGNORED from './ignored';
import uniqueStrings from './unique-strings';
import getLocalConfigPath from './config/local-path';
import { Output } from './output/create-output';
import { NowConfig } from './dev/types';
type NullableString = string | null;
@@ -33,103 +29,6 @@ async function glob(pattern: string, options: GlobOptions): Promise<string[]> {
});
}
interface WalkOptions {
output: Output;
}
/**
* Will recursivly walk through a directory and return an array of the files found within.
* @param {string} dir the directory to walk
* @param {string} path the path to this directory
* @param {Array[string]} filelist a list of files so far identified
* @param {Object} options
* - `output` {Object} "output" helper object
* @returns {Array}
*/
async function walk(
dir: string,
path: string,
filelist: string[] = [],
opts: WalkOptions
) {
const { debug } = opts.output;
const dirc = await fs.readdir(asAbsolute(dir, path));
for (let file of dirc) {
file = asAbsolute(file, dir);
try {
const fileStat = await fs.stat(file);
filelist = fileStat.isDirectory()
? await walk(file, path, filelist, opts)
: filelist.concat(file);
} catch (e) {
debug(`Ignoring invalid file ${file}`);
}
}
return filelist;
}
interface FilesInWhitelistOptions {
output: Output;
}
/**
* Will return an array containing the expaneded list of all files included in the whitelist.
* @param {Array[string]} whitelist array of files and directories to include.
* @param {string} path the path of the deployment.
* @param {Object} options
* - `output` {Object} "output" helper object
* @returns {Array} the expanded list of whitelisted files.
*/
const getFilesInWhitelist = async function (
whitelist: string[],
path: string,
opts: FilesInWhitelistOptions
) {
const { debug } = opts.output;
const files: string[] = [];
await Promise.all(
whitelist.map(async (file: string) => {
file = asAbsolute(file, path);
try {
const fileStat = await fs.stat(file);
if (fileStat.isDirectory()) {
const dirFiles = await walk(file, path, [], opts);
files.push(...dirFiles);
} else {
files.push(file);
}
} catch (e) {
debug(`Ignoring invalid file ${file}`);
}
})
);
return files;
};
/**
* Remove leading `./` from the beginning of ignores
* because ignore doesn't like them :|
*/
const clearRelative = function (str: string) {
return str.replace(/(\n|^)\.\//g, '$1');
};
/**
* Returns the contents of a file if it exists.
*
* @return {String} results or `''`
*/
const maybeRead = async function <T>(path: string, default_: T) {
try {
return await fs.readFile(path, 'utf8');
} catch (err) {
return default_;
}
};
/**
* Transform relative paths into absolutes,
* and maintains absolutes as such.
@@ -215,100 +114,6 @@ export async function staticFiles(
return uniqueStrings(files);
}
interface NpmOptions {
hasNowJson: boolean;
output: Output;
}
/**
* Returns a list of files in the given
* directory that are subject to be
* synchronized for npm.
*
* @param {String} full path to directory
* @param {String} contents of `package.json` to avoid lookup
* @param {Object} options:
* - `limit` {Number|null} byte limit
* - `output` {Object} "output" helper object
* @return {Array} comprehensive list of paths to sync
*/
export async function npm(
path: string,
pkg: { files?: string[]; now?: { files?: string[] } } = {},
nowConfig: NowConfig = {},
{ hasNowJson = false, output }: NpmOptions
) {
const { debug, time } = output;
const whitelist = nowConfig.files || pkg.files || (pkg.now && pkg.now.files);
let files: string[] = [];
if (whitelist) {
files = await getFilesInWhitelist(whitelist, path, { output });
} else {
// The package.json `files` whitelist still
// honors ignores: https://docs.npmjs.com/files/package.json#files
const search_ = ['.'];
// Convert all filenames into absolute paths
const search = Array.prototype.concat.apply(
[],
await Promise.all(
search_.map(file =>
glob(file, { cwd: path, absolute: true, dot: true })
)
)
);
// Compile list of ignored patterns and files
const npmIgnore = await maybeRead(resolve(path, '.npmignore'), null);
const filter = ignore()
.add(
`${IGNORED}\n${clearRelative(
npmIgnore === null
? await maybeRead(resolve(path, '.gitignore'), '')
: npmIgnore
)}`
)
.createFilter();
const prefixLength = path.length + 1;
const accepts = (file: string) => {
const relativePath = file.substr(prefixLength);
if (relativePath === '') {
return true;
}
const accepted = filter(relativePath);
if (!accepted) {
debug(`Ignoring ${file}`);
}
return accepted;
};
// Locate files
files = await time(
`Locating files ${path}`,
explode(search, {
accepts,
output,
})
);
}
// Always include manifest as npm does not allow ignoring it
// source: https://docs.npmjs.com/files/package.json#files
files.push(asAbsolute('package.json', path));
if (hasNowJson) {
files.push(asAbsolute(getLocalConfigPath(path), path));
}
// Get files
return uniqueStrings(files);
}
interface ExplodeOptions {
accepts: (file: string) => boolean;
output: Output;

View File

@@ -1,26 +0,0 @@
// Base `.gitignore` to which we add entries
// supplied by the user
export default `.hg
.git
.gitmodules
.svn
.cache
.next
.now
.vercel
.npmignore
.dockerignore
.gitignore
.*.swp
.DS_Store
.wafpicke-*
.lock-wscript
.env.local
.env.*.local
.venv
npm-debug.log
config.gypi
node_modules
__pycache__
venv
CVS`;

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

@@ -10,7 +10,7 @@ import chalk from 'chalk';
*/
// adjusted from https://github.com/SBoudrias/Inquirer.js/blob/942908f17319343d1acc7b876f990797c5695918/packages/inquirer/lib/prompts/base.js#L126
const getQuestion = function() {
const getQuestion = function () {
let message = `${chalk.gray('?')} ${this.opt.message} `;
if (this.opt.type === 'confirm') {
@@ -35,7 +35,7 @@ inquirer.prompt.prompts.input.prototype.getQuestion = getQuestion;
inquirer.prompt.prompts.confirm.prototype.getQuestion = getQuestion;
// adjusted from https://github.com/SBoudrias/Inquirer.js/blob/942908f17319343d1acc7b876f990797c5695918/packages/inquirer/lib/prompts/list.js#L80
inquirer.prompt.prompts.list.prototype.render = function() {
inquirer.prompt.prompts.list.prototype.render = function () {
// Render question
let message = this.getQuestion();
@@ -89,11 +89,22 @@ function listRender(choices, pointer) {
}
// adjusted from https://github.com/SBoudrias/Inquirer.js/blob/942908f17319343d1acc7b876f990797c5695918/packages/inquirer/lib/prompts/checkbox.js#L84
inquirer.prompt.prompts.checkbox.prototype.render = function(error) {
inquirer.prompt.prompts.checkbox.prototype.render = function (error) {
// Render question
let message = this.getQuestion();
let bottomContent = '';
if (!this.spaceKeyPressed) {
message +=
'(Press ' +
chalk.cyan.bold('<space>') +
' to select, ' +
chalk.cyan.bold('<a>') +
' to toggle all, ' +
chalk.cyan.bold('<i>') +
' to invert selection)';
}
// Render choices or answer depending on the state
if (this.status === 'answered') {
message += this.selection.length > 0 ? this.selection.join(', ') : 'None';
@@ -118,7 +129,7 @@ function renderChoices(choices, pointer) {
let output = '';
let separatorOffset = 0;
choices.forEach(function(choice, i) {
choices.forEach(function (choice, i) {
if (choice.type === 'separator') {
separatorOffset++;
output += '' + choice + '\n';
@@ -151,7 +162,7 @@ function renderChoices(choices, pointer) {
}
// adjusted from https://github.com/SBoudrias/Inquirer.js/blob/942908f17319343d1acc7b876f990797c5695918/packages/inquirer/lib/prompts/input.js#L44
inquirer.prompt.prompts.input.prototype.render = function(error) {
inquirer.prompt.prompts.input.prototype.render = function (error) {
let bottomContent = '';
let appendContent = '';
let message = this.getQuestion();
@@ -178,7 +189,7 @@ inquirer.prompt.prompts.input.prototype.render = function(error) {
};
// adjusted from https://github.com/SBoudrias/Inquirer.js/blob/942908f17319343d1acc7b876f990797c5695918/packages/inquirer/lib/prompts/confirm.js#L64
inquirer.prompt.prompts.confirm.prototype.render = function(answer) {
inquirer.prompt.prompts.confirm.prototype.render = function (answer) {
let message = this.getQuestion();
if (this.status === 'answered') {

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

@@ -0,0 +1,3 @@
export default function ellipsis(str: string, length: number) {
return str.length > length ? `${str.slice(0, length - 1)}` : str;
}

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,8 +1,7 @@
import chalk from 'chalk';
import printf from 'printf';
const printLine = (data, sizes) =>
data.reduce((line, col, i) => line + printf(`%-${sizes[i]}s`, col), '');
data.reduce((line, col, i) => line + col.padEnd(sizes[i]), '');
// Print a table
export default (fieldNames = [], data = [], margins = []) => {

View File

@@ -1,21 +0,0 @@
import chalk from 'chalk';
import { Output } from './output';
async function promptBool(output: Output, message: string): Promise<boolean> {
return new Promise<boolean>(resolve => {
output.print(`${chalk.gray('>')} ${message} ${chalk.gray('[y/N] ')}`);
process.stdin
.on('data', d => {
process.stdin.pause();
resolve(
d
.toString()
.trim()
.toLowerCase() === 'y'
);
})
.resume();
});
}
export default promptBool;

View File

@@ -0,0 +1,3 @@
node_modules
.next
.vercel

View File

@@ -0,0 +1,8 @@
{
"private": true,
"dependencies": {
"next": "9.5.3",
"react": "16.13.1",
"react-dom": "16.13.1"
}
}

View File

@@ -0,0 +1,3 @@
module.exports = (_req, res) => {
res.end('Hello Routes');
};

View File

@@ -0,0 +1,10 @@
function Index() {
return (
<main>
<h1>Next.js with routes</h1>
<a href="/hello">/hello</a>
</main>
);
}
export default Index;

View File

@@ -0,0 +1,3 @@
{
"routes": [{ "src": "/hello", "dest": "/api/hello" }]
}

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