Compare commits

..

41 Commits

Author SHA1 Message Date
Steven
3407e6bd1a Publish Canary
- @now/build-utils@2.1.1-canary.0
 - @now/ruby@1.0.3-canary.3
2020-02-29 18:40:49 -05:00
Steven
553ad240f0 [now-build-utils] Fix NODE_ENV assignment (#3862)
Fixes a regression in #3847 which was preventing the user from assigning `NODE_ENV`.

The root cause was that the spread operator (`...`) performs a shallow clone, not a deep clone. So we must perform another spread to clone the user-provided `env` object before deleting `NODE_ENV` during `npm install`.
2020-02-29 18:37:59 -05:00
m5o
964ce1bb5a [now-ruby] update bundler on ruby rack examples (#3856)
* update bundler on ruby rack examples
  * bundle with latest bundler `v2.1.4`
  * update rack to `v2.2.2`
  🔗 https://github.com/zeit/now/pull/3626
2020-02-28 23:45:54 +00:00
Steven
995aa6eddf Publish Canary
- now@17.0.5-canary.7
2020-02-28 17:39:42 -05:00
Steven
095805e3ad [tests] Fix missing await (#3860)
Follow up to #3858
2020-02-28 17:35:02 -05:00
Steven
b461ed238c [tests] Fix code coverage upload (#3859)
The code coverage report stopped uploading after we switched to GitHub Actions because its not a recognized CI provider.

This PR adds a secret with the code coverage token from [codecov.io](https://codecov.io/gh/zeit/now/settings).
2020-02-28 22:13:04 +00:00
Steven
01e7124189 Publish Canary
- now@17.0.5-canary.6
 - @now/ruby@1.0.3-canary.2
2020-02-28 16:21:56 -05:00
Steven
acd3ac2f98 [now-cli] Disable sentry during local development (#3858)
This PR changes the behavior of error reporting and metrics so that developers who build and run Now CLI locally won't accidentally report any metrics. It also prevents errors during CI tests from being reported.

The env vars are only assigned during the publishing step so that the official Now CLI hosted on npm is the only way to report metrics.
2020-02-28 21:20:36 +00:00
Steven
b50e4209e1 [now-cli] Fix "The specified token is not valid" (#3857)
Fixes https://sentry.io/organizations/zeithq/issues/1537743736/?project=1323225&referrer=slack
2020-02-28 19:59:51 +00:00
m5o
147b4e870c [now-ruby] Add test fixture for ActiveSupport gem (#3853)
* add ruby ActiveSupport test fixture
  > ActiveSupport is a Ruby module & a stand-alone component of Rails that includes additional functionality to core Ruby classes, like Array, String & Numeric.
  🔗 https://guides.rubyonrails.org/active_support_core_extensions.html

* add `Date.current + 10.years` calculation example
2020-02-28 12:56:06 -05:00
Steven
df8327d14c [docs] Update readme (#3855)
Updates the readme to mention the Git Integration and fixes some misinformation.
2020-02-28 12:53:40 -05:00
Joe Haddad
fb4d4b5953 Publish Stable
- @now/build-utils@2.1.0
 - @now/next@2.4.0
 - @now/routing-utils@1.7.0
2020-02-28 10:19:47 -05:00
Joe Haddad
de3701c045 Publish Canary
- @now/ruby@1.0.3-canary.1
2020-02-28 10:18:46 -05:00
m5o
9f9b7934cb [now-ruby] Fix ruby test indentation (#3854)
* fix ruby indentation example
  * 💅 indent with 2 spaces for consistency
2020-02-28 14:34:47 +00:00
Steven
bcded1dd17 Publish Canary
- @now/build-utils@2.0.1-canary.3
 - @now/next@2.3.19-canary.2
 - @now/python@1.1.5-canary.1
2020-02-28 08:57:36 -05:00
Steven
8503af75ba [now-python] Fix space encoding 2020-02-28 08:35:27 -05:00
Joe Haddad
158a50f1aa [now-next] Allow Immutable Fallback Artifact (#3850)
* [now-next] Allow Immutable Fallback Artifact

* trigger
2020-02-27 22:00:09 -05:00
Steven
61da552dd6 [now-build-utils] Add test for NODE_ENV behavior (#3852)
This PR adds a test for #3847.
2020-02-27 21:47:27 +00:00
Steven
fa838eecac Publish Canary
- @now/go@1.0.5-canary.0
 - @now/next@2.3.19-canary.1
 - @now/node@1.4.2-canary.0
 - @now/python@1.1.5-canary.0
 - @now/ruby@1.0.3-canary.0
 - @now/static-build@0.14.13-canary.1
2020-02-27 15:52:36 -05:00
Steven
71b6a58783 [all] Exclude @now/build-utils in bundled builder to fix tests (#3848)
This fixes a bug in our `@now/build-utils` tests that pair the current build-utils with a stable builder. Since ncc was bundling `@now/build-utils`, we weren't able to configure a different version and these tests were not actually testing the correct version of build-utils.

A nice side-effect is that each builder will be about 50% smaller (compared by measuring `dist`).
2020-02-27 15:48:03 -05:00
Joe Haddad
22dd78e286 Publish Canary
- @now/build-utils@2.0.1-canary.2
 - @now/next@2.3.19-canary.0
2020-02-27 12:35:52 -05:00
Joe Haddad
e63fcf2630 [now-next] Add Support for Prerender v2 (#3845)
* [now-next] Add Support for Prerender v2

* Copy test suite

* Test that fallback doesn't work for fallback: false

* record omitted lambdas

* Improve test case

* improve omitted routes logic

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2020-02-27 12:33:31 -05:00
Steven
98e1553c2e [now-build-utils] Install all deps regardless of NODE_ENV (#3847)
Some build utilities and SSG Frameworks instruct users to set `NODE_ENV=production` which typically means updating `now.json` to the following:

```json
{
  "build": {
    "env": {
      "NODE_ENV": "production"
    }
  }
}
```

The problem is that this environment variable is assigned during `npm install` or `yarn install` which is the equivalent of running install with the `--production` flag. This flag prevents `devDependencies` from installing. This is almost never what the user intends so they have to remove `now.json` and instead updating their build script to `NODE_ENV=production yarn build`.

This PR improves the experience by deleting `NODE_ENV` during the install step.
2020-02-27 12:14:06 -05:00
Steven
4dc506f17a Publish Canary
- @now/build-utils@2.0.1-canary.1
 - now@17.0.5-canary.5
 - @now/routing-utils@1.6.1-canary.1
2020-02-27 08:05:05 -05:00
Steven
3b396f29e9 [now-build-utils][now-routing-utils] Fix appendRoutesToPhase() when input is null (#3843)
This PR fixes `@now/routing-utils` when the input routes are null. It used to return the empty array but now it will still append.

I also added many more tests to `@now/build-utils` when `featureHandleMiss: true` and refactored the code a bit to make dynamic routes and api routes a little more clear.
2020-02-26 23:30:50 +00:00
JJ Kasper
1f128e69e6 Publish Stable
- @now/next@2.3.18
2020-02-26 15:56:41 -06:00
JJ Kasper
f1487c92cb Publish Canary
- now@17.0.5-canary.4
 - @now/next@2.3.18-canary.0
2020-02-26 15:51:27 -06:00
JJ Kasper
45066cdf44 [now-next] Add /_next/data routes for getServerProps pages (#3771)
This adds the `/_next/data` routes for `getServerProps` pages if they exist

x-ref: https://github.com/zeit/next.js/pull/10077
x-ref: https://github.com/zeit/next.js/pull/10622
2020-02-26 21:47:51 +00:00
Ana Trajkovska
7dde9c8207 Publish Canary
- now@17.0.5-canary.3
 - now-client@7.0.1-canary.1
2020-02-26 08:00:09 +01:00
Ana Trajkovska
fd964f825d Handle deployment cancellation (#3823)
Co-authored-by: Max <8418866+rdev@users.noreply.github.com>
2020-02-26 07:21:27 +01:00
Steven
1656c9874e Publish Canary
- @now/build-utils@2.0.1-canary.0
 - now@17.0.5-canary.2
 - @now/routing-utils@1.6.1-canary.0
2020-02-25 17:32:37 -05:00
Steven
d999a3b2ad [now-routing-utils][now-build-utils] Refactor zero-config rewrites (#3832)
This PR refactors the rewrites (the dynamic routes as well as the route that prevents directory listing for zero config deployments) so they are not in the `handle: miss` phase.

This is necessary because the behavior of `handle: miss` will change in an upcoming release.

The solution is to separate these into `rewriteRoutes` that can then be merged properly with the user's routes. They will be appended to the `handle: filesystem` phase (or add the phase if it doesn't exist).
2020-02-25 22:30:36 +00:00
Joe Haddad
cfb7c9e632 Publish Stable
- @now/next@2.3.17
2020-02-25 15:19:05 -05:00
Joe Haddad
06e8472cf7 Publish Canary
- now@17.0.5-canary.1
 - @now/next@2.3.17-canary.0
 - @now/static-build@0.14.13-canary.0
2020-02-25 14:57:42 -05:00
Joe Haddad
92404135d8 [now-next] Always Emit Prerenders (#3837)
This ensures we always emit Prerender objects for bypass tokens.
2020-02-25 19:51:07 +00:00
Nathan Rajlich
8b5cc23d7c [now-cli] Remove v1 "static build" integration tests (#3833)
* [now-cli] Remove v1 "static build" integration tests

These are the last remaining v1 static type deployments being created.

* Remove from `integration.js` as well

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2020-02-24 17:19:22 -08:00
Shu Uesugi
e10b42bfdc Rename zeit.co/new → zeit.co/import (#3834)
* zeit.co/new → zeit.co/import

* Update docs URL
2020-02-25 01:35:12 +01:00
M. Heide
36f7ec4836 [examples] Fix Go build if Windows Git is configured to checkout CRLF line endings (#3821)
Fixes #3820
2020-02-24 19:53:15 +00:00
Joe Haddad
f89d1c463e Remove Backticks from URL Output (#3830)
![image](https://user-images.githubusercontent.com/616428/75176976-44434880-5703-11ea-8ca5-cb49e4a921cf.png)

![image](https://user-images.githubusercontent.com/616428/75176982-473e3900-5703-11ea-90f6-b31844a486ce.png)
2020-02-24 19:22:58 +00:00
Steven
5dc652eba9 Publish Canary
- now@17.0.5-canary.0
 - now-client@7.0.1-canary.0
2020-02-24 12:53:13 -05:00
Steven
821b2bd50b [now-client] Fix root directory with trailing slash (#3827)
There was a bug in `now-client` when deploying a directory that ends with a slash, for example `/Users/styfle/Code/myapp/` instead of the usual `/Users/styfle/Code/myapp`.

This never affected `now-cli` until we added support for defining the `rootDirectory` which allows the user to type whatever they wish in the Project Settings.

The fix is to use `path.relative()` instead of substring.
2020-02-24 17:45:10 +00:00
162 changed files with 2983 additions and 718 deletions

4
.gitattributes vendored
View File

@@ -1,3 +1,7 @@
# Ignore test fixtures in GitHub Languages
# See https://github.com/github/linguist#vendored-code
packages/*/test/* linguist-vendored
# Go build fails with Windows line endings.
*.go text eol=lf
go.mod text eol=lf

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Name](site-link) site that can be deploy
Deploy your own [Name] project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now-examples/tree/master/example-directory)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now-examples/tree/master/example-directory)
### How We Created This Example

View File

@@ -94,7 +94,7 @@ jobs:
coverage:
name: Coverage
timeout-minutes: 10
timeout-minutes: 5
needs: [test-unit, test-now-cli, test-now-dev, test-integration]
runs-on: ubuntu-latest
steps:
@@ -107,3 +107,5 @@ jobs:
path: packages/now-cli/.nyc_output
- run: yarn install
- run: yarn workspace now run coverage
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -20,6 +20,9 @@ jobs:
run: yarn install --check-files --frozen-lockfile
- name: Build
run: yarn build
env:
GA_TRACKING_ID: ${{ secrets.GA_TRACKING_ID }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
- name: Publish
run: yarn publish-from-github
env:

1
.gitignore vendored
View File

@@ -12,6 +12,7 @@ coverage
packages/now-cli/.builders
packages/now-cli/assets
packages/now-cli/src/util/dev/templates/*.ts
packages/now-cli/src/util/constants.ts
packages/now-cli/test/**/yarn.lock
!packages/now-cli/test/dev/**/yarn.lock
packages/now-cli/test/**/node_modules

View File

@@ -5,30 +5,18 @@
## Usage
To install the latest version of Now CLI, visit [zeit.co/download](https://zeit.co/download) or run this command:
```
npm i -g now
```
To quickly start a new project, run the following commands:
```
now init # Pick an example project to clone
cd <PROJECT> # Change directory to the newly created project
now # Deploy to the cloud
```
Get started by [Importing a Git Project](https://zeit.co/import) and use `git push` to deploy. Alternatively, you can [install Now CLI](https://zeit.co/download).
## Documentation
For details on how to use Now CLI, check out our [documentation](https://zeit.co/docs).
For details on how to use ZEIT Now, check out our [documentation](https://zeit.co/docs).
## Caught a Bug?
1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device
2. Install dependencies with `yarn install`
3. Compile the code: `yarn build`
4. Link the package to the global module directory: `yarn link`
4. Link the package to the global module directory: `cd ./packages/now-cli && yarn link`
5. You can now start using `now` anywhere inside the command line
As always, you should use `yarn test-unit` to run the tests and see if your changes have broken anything.

View File

@@ -6,7 +6,7 @@ This directory is a brief example of an [AMP](https://amp.dev/) site that can be
Deploy your own AMP project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/amp)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/amp)
_Live Example: https://amp.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of an [Angular](https://angular.io/) app that
Deploy your own Angular project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/angular)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/angular)
_Live Example: https://angular.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Assemble](http://assemble.io/) app that
Deploy your own Assemble project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/assemble)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/assemble)
_Live Example: https://assemble.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of an [Aurelia](https://aurelia.io/) app that
Deploy your own Aurelia project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/aurelia)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/aurelia)
_Live Example: https://aurelia.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Brunch](https://brunch.io/) site that ca
Deploy your own Brunch project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/brunch)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/brunch)
_Live Example: https://brunch.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Charge.js](https://charge.js.org/) site
Deploy your own Charge.js project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/charge)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/charge)
_Live Example: https://charge.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of a [React](https://reactjs.org/) app with [S
Deploy your own React project, along with Serverless Functions, with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/create-react-app-functions)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/create-react-app-functions)
_Live Example: https://create-react-app.now-examples.now.sh/_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of using a Custom Build script that can be dep
Deploy your own Custom Built project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/custom-build)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/custom-build)
_Live Example: https://custom-build.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of a [Docusaurus](https://docusaurus.io/) site
Deploy your own Docusaurus project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/docusaurus)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/docusaurus)
_Live Example: https://docusaurus.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Docz](https://www.docz.site/) site that
Deploy your own Docz project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/docz)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/docz)
_Live Example: https://docz.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of a [Eleventy](https://www.11ty.io/) site tha
Deploy your own Eleventy project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/eleventy)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/eleventy)
_Live Example: https://eleventy.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of an [Ember](https://emberjs.com/) app that c
Deploy your own Ember project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/ember)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/ember)
_Live Example: https://ember.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Foundation](https://foundation.zurb.com/
Deploy your own Foundation project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/foundation)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/foundation)
_Live Example: https://foundation.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of a [Gatsby](https://www.gatsbyjs.org/) app w
Deploy your own Gatsby project, along with Serverless Functions, with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/gatsby)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/gatsby)
_Live Example: https://gatsby.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of a [Gridsome](https://gridsome.org/) app tha
Deploy your own Gridsome project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/gridsome)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/gridsome)
_Live Example: https://gridsome.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of a [Hexo](https://hexo.io/) site that can be
Deploy your own Hexo project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/hexo)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/hexo)
_Live Example: https://hexo.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Hugo](https://gohugo.io/) app that can b
Deploy your own Hugo project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/hugo)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/hugo)
_Live Example: https://hugo.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [HyperApp](https://github.com/jorgebucara
Deploy your own HyperApp project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/hyperapp)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/hyperapp)
_Live Example: https://hyperapp.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of an [Ionic React](https://ionicframework.com
Deploy your own Ionic React project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/ionic-react)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/ionic-react)
_Live Example: https://ionic-react.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Jekyll](https://jekyllrb.com/) site that
Deploy your own Jekyll project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/jekyll)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/jekyll)
_Live Example: https://jekyll.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Marko.js](https://markojs.com/) app that
Deploy your own Marko.js project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/marko)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/marko)
_Live Example: https://marko.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [mdx-deck](https://github.com/jxnblk/mdx-
Deploy your own mdx-deck project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/mdx-deck)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/mdx-deck)
_Live Example: https://mdx-deck.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Metalsmith](https://metalsmith.io/) app
Deploy your own Metalsmith project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/metalsmith)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/metalsmith)
_Live Example: https://metalsmith.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Middleman](https://middlemanapp.com/) si
Deploy your own Middleman project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/middleman)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/middleman)
_Live Example: https://middleman.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Mithril](https://mithril.js.org/) app th
Deploy your own Mithril project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/mithril)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/mithril)
_Live Example: https://mithril.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [MkDocs](https://www.mkdocs.org/) site th
Deploy your own MkDocs project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/mkdocs)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/mkdocs)
_Live Example: https://mkdocs.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of a [Next.js](https://nextjs.org) app that ca
Deploy your own Next.js project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/nextjs)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/nextjs)
_Live Example: https://nextjs.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Nuxt.js](https://nuxtjs.org) app that ca
Deploy your own Nuxt.js project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/nuxtjs)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/nuxtjs)
_Live Example: https://nuxtjs.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Pelican](https://docs.getpelican.com/en/
Deploy your own Pelican project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/pelican)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/pelican)
_Live Example: https://pelican.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of a [Polymer](https://www.polymer-project.org
Deploy your own Polymer project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/polymer)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/polymer)
_Live Example: https://polymer.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of a [Preact](https://preactjs.com/) app that
Deploy your own Preact project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/preact)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/preact)
_Live Example: https://preact.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Riot.js](https://riot.js.org/) app that
Deploy your own Riot.js project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/riot)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/riot)
_Live Example: https://riot.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of a [Saber](https://saber.land) site that can
Deploy your own Saber project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/saber)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/saber)
_Live Example: https://saber.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Sapper](https://sapper.svelte.dev/) app
Deploy your own Sapper project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/sapper)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/sapper)
_Live Example: https://sapper.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Stencil](https://stenciljs.com/) app tha
Deploy your own Stencil project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/stencil)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/stencil)
_Live Example: https://stencil.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Storybook](https://storybook.js.org/) ap
Deploy your own Storybook project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/storybook)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/storybook)
_Live Example: https://storybook.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Svelte](https://svelte.dev/) app with [S
Deploy your own Svelte project, along with Serverless Functions, with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/svelte)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/svelte)
_Live Example: https://svelte.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of a [UmiJS](https://umijs.org/) app that can
Deploy your own UmiJS project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/umijs)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/umijs)
_Live Example: https://umijs.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a vanilla site that can be deployed with ZE
Deploy your own vanilla website, along with Serverless Functions, with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/vanilla)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/vanilla)
_Live Example: https://vanilla.now-examples.now.sh_

View File

@@ -8,7 +8,7 @@ This directory is a brief example of a [Vue.js](https://vuejs.org/) app that can
Deploy your own Vue.js project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/vue)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/vue)
_Live Example: https://vue.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [VuePress](https://vuepress.vuejs.org/) a
Deploy your own VuePress project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/vuepress)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/vuepress)
_Live Example: https://vuepress.now-examples.now.sh_

View File

@@ -6,7 +6,7 @@ This directory is a brief example of a [Zola](https://www.getzola.org/) site tha
Deploy your own Zola project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/new/project?template=https://github.com/zeit/now/tree/master/examples/zola)
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now/tree/master/examples/zola)
_Live Example: https://zola.now-examples.now.sh_

View File

@@ -1,6 +1,6 @@
{
"name": "@now/build-utils",
"version": "2.0.0",
"version": "2.1.1-canary.0",
"license": "MIT",
"main": "./dist/index.js",
"types": "./dist/index.d.js",

View File

@@ -80,6 +80,7 @@ export async function detectBuilders(
warnings: ErrorResponse[];
defaultRoutes: Route[] | null;
redirectRoutes: Route[] | null;
rewriteRoutes: Route[] | null;
}> {
const errors: ErrorResponse[] = [];
const warnings: ErrorResponse[] = [];
@@ -87,9 +88,6 @@ export async function detectBuilders(
const apiBuilders: Builder[] = [];
let frontendBuilder: Builder | null = null;
const defaultRoutes: Route[] = [];
const redirectRoutes: Route[] = [];
const functionError = validateFunctions(options);
if (functionError) {
@@ -99,6 +97,7 @@ export async function detectBuilders(
warnings,
defaultRoutes: null,
redirectRoutes: null,
rewriteRoutes: null,
};
}
@@ -131,15 +130,15 @@ export async function detectBuilders(
let fallbackEntrypoint: string | null = null;
const preDefaultRoutes: Source[] = [];
const preDynamicRoutes: Source[] = [];
const apiRoutes: Source[] = [];
const dynamicRoutes: Source[] = [];
// API
for (const fileName of sortedFiles) {
const apiBuilder = maybeGetApiBuilder(fileName, apiMatches, options);
if (apiBuilder) {
const { routeError, defaultRoute, dynamicRoute } = getApiRoute(
const { routeError, apiRoute, isDynamic } = getApiRoute(
fileName,
apiSortedFiles,
options,
@@ -153,15 +152,15 @@ export async function detectBuilders(
warnings,
defaultRoutes: null,
redirectRoutes: null,
rewriteRoutes: null,
};
}
if (dynamicRoute) {
preDynamicRoutes.push(dynamicRoute);
}
if (defaultRoute) {
preDefaultRoutes.push(defaultRoute);
if (apiRoute) {
apiRoutes.push(apiRoute);
if (isDynamic) {
dynamicRoutes.push(apiRoute);
}
}
addToUsedFunctions(apiBuilder);
@@ -224,6 +223,7 @@ export async function detectBuilders(
builders: null,
redirectRoutes: null,
defaultRoutes: null,
rewriteRoutes: null,
};
}
@@ -264,6 +264,7 @@ export async function detectBuilders(
warnings,
redirectRoutes: null,
defaultRoutes: null,
rewriteRoutes: null,
};
}
@@ -285,24 +286,22 @@ export async function detectBuilders(
}
}
const routesResult = mergeRoutes(
preDefaultRoutes,
preDynamicRoutes,
const routesResult = getRouteResult(
apiRoutes,
dynamicRoutes,
usedOutputDirectory,
apiBuilders,
frontendBuilder,
options
);
defaultRoutes.push(...routesResult.defaultRoutes);
redirectRoutes.push(...routesResult.redirectRoutes);
return {
warnings,
builders: builders.length ? builders : null,
errors: errors.length ? errors : null,
redirectRoutes,
defaultRoutes,
redirectRoutes: routesResult.redirectRoutes,
defaultRoutes: routesResult.defaultRoutes,
rewriteRoutes: routesResult.rewriteRoutes,
};
}
@@ -622,16 +621,16 @@ function getApiRoute(
options: Options,
absolutePathCache: Map<string, string>
): {
defaultRoute: Source | null;
dynamicRoute: Source | null;
apiRoute: Source | null;
isDynamic: boolean;
routeError: ErrorResponse | null;
} {
const conflictingSegment = getConflictingSegment(fileName);
if (conflictingSegment) {
return {
defaultRoute: null,
dynamicRoute: null,
apiRoute: null,
isDynamic: false,
routeError: {
code: 'conflicting_path_segment',
message:
@@ -650,8 +649,8 @@ function getApiRoute(
);
return {
defaultRoute: null,
dynamicRoute: null,
apiRoute: null,
isDynamic: false,
routeError: {
code: 'conflicting_file_path',
message:
@@ -669,8 +668,8 @@ function getApiRoute(
);
return {
defaultRoute: out.route,
dynamicRoute: out.isDynamic ? out.route : null,
apiRoute: out.route,
isDynamic: out.isDynamic,
routeError: null,
};
}
@@ -835,10 +834,10 @@ function createRouteFromPath(
} else if (isLast) {
const { name: fileName, ext } = parsePath(segment);
const isIndex = fileName === 'index';
const prefix = isIndex ? '\\/' : '';
const prefix = isIndex ? '/' : '';
const names = [
isIndex ? prefix : `${fileName}\\/`,
isIndex ? prefix : `${fileName}/`,
prefix + escapeName(fileName),
featHandleMiss && cleanUrls
? ''
@@ -881,9 +880,9 @@ function createRouteFromPath(
return { route, isDynamic };
}
function mergeRoutes(
preDefaultRoutes: Source[],
preDynamicRoutes: Source[],
function getRouteResult(
apiRoutes: Source[],
dynamicRoutes: Source[],
outputDirectory: string,
apiBuilders: Builder[],
frontendBuilder: Builder | null,
@@ -891,14 +890,14 @@ function mergeRoutes(
): {
defaultRoutes: Route[];
redirectRoutes: Route[];
rewriteRoutes: Route[];
} {
const defaultRoutes: Route[] = [];
const redirectRoutes: Route[] = [];
const rewriteRoutes: Route[] = [];
if (preDefaultRoutes && preDefaultRoutes.length > 0) {
if (apiRoutes && apiRoutes.length > 0) {
if (options.featHandleMiss) {
defaultRoutes.push({ handle: 'miss' });
const extSet = detectApiExtensions(apiBuilders);
if (extSet.size > 0) {
@@ -923,6 +922,7 @@ function mergeRoutes(
status: 308,
});
} else {
defaultRoutes.push({ handle: 'miss' });
defaultRoutes.push({
src: `^/api/(.+)${extGroup}$`,
dest: '/api/$1',
@@ -931,21 +931,16 @@ function mergeRoutes(
}
}
if (preDynamicRoutes) {
defaultRoutes.push(...preDynamicRoutes);
}
if (preDefaultRoutes.length) {
defaultRoutes.push({
src: '^/api(/.*)?$',
status: 404,
continue: true,
});
}
rewriteRoutes.push(...dynamicRoutes);
rewriteRoutes.push({
src: '^/api(/.*)?$',
status: 404,
continue: true,
});
} else {
defaultRoutes.push(...preDefaultRoutes);
defaultRoutes.push(...apiRoutes);
if (preDefaultRoutes.length) {
if (apiRoutes.length) {
defaultRoutes.push({
status: 404,
src: '^/api(/.*)?$',
@@ -969,6 +964,7 @@ function mergeRoutes(
return {
defaultRoutes,
redirectRoutes,
rewriteRoutes,
};
}

View File

@@ -206,10 +206,10 @@ export async function runNpmInstall(
debug(`Installing to ${destPath}`);
const { hasPackageLockJson } = await scanParentDirs(destPath);
const opts = { cwd: destPath, ...spawnOpts } || {
cwd: destPath,
env: process.env,
};
const opts: SpawnOptions = { cwd: destPath, ...spawnOpts };
const env = opts.env ? { ...opts.env } : { ...process.env };
delete env.NODE_ENV;
opts.env = env;
if (hasPackageLockJson) {
commandArgs = args.filter(a => a !== '--prefer-offline');
@@ -239,10 +239,7 @@ export async function runBundleInstall(
}
assert(path.isAbsolute(destPath));
const opts = { cwd: destPath, ...spawnOpts } || {
cwd: destPath,
env: process.env,
};
const opts = { cwd: destPath, ...spawnOpts };
await spawnAsync(
'bundle',
@@ -270,10 +267,7 @@ export async function runPipInstall(
}
assert(path.isAbsolute(destPath));
const opts = { cwd: destPath, ...spawnOpts } || {
cwd: destPath,
env: process.env,
};
const opts = { cwd: destPath, ...spawnOpts };
await spawnAsync(
'pip3',

View File

@@ -4,7 +4,7 @@ import FileRef from './file-ref';
import { Lambda } from './lambda';
interface PrerenderOptions {
expiration: number;
expiration: number | false;
lambda: Lambda;
fallback: FileBlob | FileFsRef | FileRef | null;
group?: number;
@@ -13,7 +13,7 @@ interface PrerenderOptions {
export class Prerender {
public type: 'Prerender';
public expiration: number;
public expiration: number | false;
public lambda: Lambda;
public fallback: FileBlob | FileFsRef | FileRef | null;
public group?: number;

View File

@@ -0,0 +1,21 @@
function checkPkgOrThrow(pkgname) {
try {
const dep = require(pkgname);
if (!dep) {
throw new Error('Undefined');
}
} catch (e) {
console.error(`Expected package "${pkgname}" to be installed.`);
process.exit(1);
}
}
// We expect both `dependencies` and `devDependencies` to be installed
// even when NODE_ENV=production.
checkPkgOrThrow('tls-check');
checkPkgOrThrow('exeggcute');
// This is to satisfy `@now/static-build` which needs a `dist` directory.
const { exec } = require('exeggcute');
exec('mkdir dist', __dirname);
exec('echo "node-env:RANDOMNESS_PLACEHOLDER" > dist/index.html', __dirname);

View File

@@ -0,0 +1,6 @@
{
"version": 2,
"builds": [{ "src": "package.json", "use": "@now/static-build" }],
"build": { "env": { "NODE_ENV": "production" } },
"probes": [{ "path": "/", "mustContain": "node-env:RANDOMNESS_PLACEHOLDER" }]
}

View File

@@ -0,0 +1,12 @@
{
"private": true,
"scripts": {
"build": "node build.js"
},
"dependencies": {
"tls-check": "1.0.0"
},
"devDependencies": {
"exeggcute": "1.0.0"
}
}

View File

@@ -0,0 +1,8 @@
{
"version": 2,
"builds": [{ "src": "package.json", "use": "@now/static-build" }],
"build": { "env": { "NODE_ENV": "custom-value:RANDOMNESS_PLACEHOLDER" } },
"probes": [
{ "path": "/", "mustContain": "custom-value:RANDOMNESS_PLACEHOLDER" }
]
}

View File

@@ -0,0 +1,6 @@
{
"private": true,
"scripts": {
"build": "mkdir public && echo $NODE_ENV > public/index.html"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,6 @@ To quickly start a new project, run the following commands:
```
now init # Pick an example project
cd <PROJECT> # Change directory to the new project
now dev # Run locally during development
now # Deploy to the cloud
```

View File

@@ -1,6 +1,6 @@
{
"name": "now",
"version": "17.0.4",
"version": "17.0.5-canary.7",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Now",

View File

@@ -4,7 +4,13 @@ import execa from 'execa';
import { join } from 'path';
import pipe from 'promisepipe';
import { createGzip } from 'zlib';
import { createWriteStream, mkdirp, remove, writeJSON } from 'fs-extra';
import {
createWriteStream,
mkdirp,
remove,
writeJSON,
writeFile,
} from 'fs-extra';
import { getDistTag } from '../src/util/get-dist-tag';
import pkg from '../package.json';
@@ -47,10 +53,34 @@ async function createBuildersTarball() {
);
}
async function createConstants() {
console.log('Creating constants.ts');
const filename = join(dirRoot, 'src/util/constants.ts');
const contents = `// This file is auto-generated
export const GA_TRACKING_ID: string | undefined = ${envToString(
'GA_TRACKING_ID'
)};
export const SENTRY_DSN: string | undefined = ${envToString('SENTRY_DSN')};
`;
await writeFile(filename, contents, 'utf8');
}
function envToString(key: string) {
const value = process.env[key];
if (!value) {
console.log(`- Constant ${key} is not assigned`);
}
return JSON.stringify(value);
}
async function main() {
const isDev = process.argv[2] === '--dev';
if (!isDev) {
// Read the secrets from GitHub Actions and generate a file.
// During local development, these secrets will be empty.
await createConstants();
// Create a tarball from all the `@now` scoped builders which will be bundled
// with Now CLI
await createBuildersTarball();

View File

@@ -284,13 +284,22 @@ export default async function main(
return 0;
}
org = await selectOrg(
output,
'Which scope do you want to deploy to?',
client,
ctx.config.currentTeam,
autoConfirm
);
try {
org = await selectOrg(
output,
'Which scope do you want to deploy to?',
client,
ctx.config.currentTeam,
autoConfirm
);
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}
throw err;
}
// We use `localConfig` here to read the name
// even though the `now.json` file can change
@@ -566,6 +575,11 @@ export default async function main(
return 1;
}
if (deployment.readyState === 'CANCELED') {
output.log('The deployment has been canceled');
return 1;
}
const deploymentResponse = await getDeploymentByIdOrHost(
now,
contextName,
@@ -652,7 +666,12 @@ export default async function main(
output.error('Build failed');
output.error(
`Check your logs at ${now.url}/_logs or run ${code(
`now logs ${now.url}`
`now logs ${now.url}`,
{
// Backticks are interpreted as part of the URL, causing CMD+Click
// behavior to fail in editors like VSCode.
backticks: false,
}
)}`
);

View File

@@ -37,7 +37,7 @@ export default async function add(
try {
({ contextName } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED') {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}

View File

@@ -27,7 +27,7 @@ export default async function add(
try {
({ contextName } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED') {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}

View File

@@ -42,7 +42,7 @@ export default async function move(
try {
({ contextName, user } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED') {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}
@@ -214,4 +214,4 @@ async function findDestinationMatch(
}
return null;
}
}

View File

@@ -40,7 +40,7 @@ export default async function transferIn(
try {
({ contextName } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED') {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}

View File

@@ -9,6 +9,7 @@ import exit from '../util/exit';
import Client from '../util/client.ts';
import logo from '../util/output/logo';
import getScope from '../util/get-scope';
import createOutput from '../util/output';
const e = encodeURIComponent;
@@ -63,13 +64,26 @@ const main = async ctx => {
await exit(0);
}
const output = createOutput({ debug });
const {
authConfig: { token },
config: { currentTeam },
} = ctx;
const client = new Client({ apiUrl, token, currentTeam, debug });
const { contextName } = await getScope(client);
let contextName = null;
try {
({ contextName } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}
throw err;
}
try {
await run({ client, contextName });

View File

@@ -76,7 +76,17 @@ export default async function({
const stopUserSpinner = wait('Fetching user information');
const client = new Client({ apiUrl, token });
const user = await getUser(client);
let user;
try {
user = await getUser(client);
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
console.error(error(err.message));
return 1;
}
throw err;
}
stopUserSpinner();

View File

@@ -21,7 +21,17 @@ export default async function({ teams, config, apiUrl, token }) {
const stopUserSpinner = wait('Fetching user information');
const client = new Client({ apiUrl, token, currentTeam });
const user = await getUser(client);
let user;
try {
user = await getUser(client);
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
console.error(error(err.message));
return 1;
}
throw err;
}
stopUserSpinner();

View File

@@ -40,13 +40,23 @@ export default async function({ apiUrl, token, debug, args, config }) {
const stopUserSpinner = wait('Fetching user information');
const client = new Client({ apiUrl, token });
const user = await getUser(client);
let user;
try {
user = await getUser(client);
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
console.error(error(err.message));
return 1;
}
throw err;
}
stopUserSpinner();
if (accountIsCurrent) {
currentTeam = {
slug: user.username || user.email
slug: user.username || user.email,
};
} else {
currentTeam = list.find(team => team.id === currentTeam);

View File

@@ -1,2 +0,0 @@
export const GA_TRACKING_ID = 'UA-117491914-3';
export const SENTRY_DSN = 'https://26a24e59ba954011919a524b341b6ab5@sentry.io/1323225';

View File

@@ -202,6 +202,13 @@ export default async function processDeployment({
}
}
if (event.type === 'canceled') {
if (buildSpinner) {
buildSpinner();
}
return event.payload;
}
if (event.type === 'ready') {
if (queuedSpinner) {
queuedSpinner();

View File

@@ -133,6 +133,9 @@ export async function devRouter(
);
if (missResult.found) {
return missResult;
} else {
reqPathname = destPath;
continue;
}
} else {
if (routeConfig.status && phase === 'miss') {

View File

@@ -12,7 +12,11 @@ import serveHandler from 'serve-handler';
import { watch, FSWatcher } from 'chokidar';
import { parse as parseDotenv } from 'dotenv';
import { basename, dirname, extname, join } from 'path';
import { getTransformedRoutes, HandleValue } from '@now/routing-utils';
import {
getTransformedRoutes,
appendRoutesToPhase,
HandleValue,
} from '@now/routing-utils';
import directoryTemplate from 'serve-handler/src/directory';
import getPort from 'get-port';
import { ChildProcess } from 'child_process';
@@ -553,6 +557,7 @@ export default class DevServer {
errors,
defaultRoutes,
redirectRoutes,
rewriteRoutes,
} = await detectBuilders(files, pkg, {
tag: getDistTag(cliVersion) === 'canary' ? 'canary' : 'latest',
functions: config.functions,
@@ -582,7 +587,13 @@ export default class DevServer {
const routes: RouteConfig[] = [];
const { routes: nowConfigRoutes } = config;
routes.push(...(redirectRoutes || []));
routes.push(...(nowConfigRoutes || []));
routes.push(
...appendRoutesToPhase({
routes: nowConfigRoutes,
newRoutes: rewriteRoutes,
phase: 'filesystem',
})
);
routes.push(...(defaultRoutes || []));
config.routes = routes;
}
@@ -1176,6 +1187,35 @@ export default class DevServer {
}
};
/**
* This is the equivalent to now-proxy exit_with_status() function.
*/
exitWithStatus = async (
match: BuildMatch | null,
routeResult: RouteResult,
phase: HandleValue | null,
req: http.IncomingMessage,
res: http.ServerResponse,
nowRequestId: string
): Promise<boolean> => {
const { status, headers, dest } = routeResult;
const location = headers['location'] || dest;
if (status && location && (300 <= status && status <= 399)) {
this.output.debug(`Route found with redirect status code ${status}`);
await this.sendRedirect(req, res, nowRequestId, location, status);
return true;
}
if (!match && status && phase !== 'miss') {
this.output.debug(`Route found with with status code ${status}`);
await this.sendError(req, res, nowRequestId, '', status);
return true;
}
return false;
};
/**
* Serve project directory as a Now v2 deployment.
*/
@@ -1259,6 +1299,19 @@ export default class DevServer {
this
);
if (
await this.exitWithStatus(
match,
routeResult,
phase,
req,
res,
nowRequestId
)
) {
return;
}
if (!match && missRoutes.length > 0) {
// Since there was no build match, enter the miss phase
routeResult = await devRouter(
@@ -1277,6 +1330,18 @@ export default class DevServer {
routeResult.dest,
this
);
if (
await this.exitWithStatus(
match,
routeResult,
phase,
req,
res,
nowRequestId
)
) {
return;
}
} else if (match && hitRoutes.length > 0) {
// Since there was a build match, enter the hit phase.
// The hit phase must not set status code.
@@ -1295,28 +1360,6 @@ export default class DevServer {
statusCode = routeResult.status;
if (match && statusCode === 404 && routeResult.phase === 'miss') {
statusCode = undefined;
}
const location = routeResult.headers['location'] || routeResult.dest;
if (statusCode && location && (300 <= statusCode && statusCode <= 399)) {
// Equivalent to now-proxy exit_with_status() function
this.output.debug(
`Route found with redirect status code ${statusCode}`
);
await this.sendRedirect(req, res, nowRequestId, location, statusCode);
return;
}
if (!match && statusCode && routeResult.phase !== 'miss') {
// Equivalent to now-proxy exit_with_status() function
this.output.debug(`Route found with with status code ${statusCode}`);
await this.sendError(req, res, nowRequestId, '', statusCode);
return;
}
if (match) {
// end the phase
break;

View File

@@ -8,22 +8,26 @@ import * as configFiles from './config/files';
const config: any = configFiles.getConfigFilePath();
export const shouldCollectMetrics = (
config.collectMetrics === undefined
|| config.collectMetrics === true)
&& process.env.NOW_CLI_COLLECT_METRICS !== '0';
export const shouldCollectMetrics =
(config.collectMetrics === undefined || config.collectMetrics === true) &&
process.env.NOW_CLI_COLLECT_METRICS !== '0' &&
GA_TRACKING_ID;
export const metrics = () => {
const token = typeof config.token === 'string' ? config.token : platform() + release();
export const metrics = (): ua.Visitor => {
const token =
typeof config.token === 'string' ? config.token : platform() + release();
const salt = userInfo().username;
const hash = crypto.pbkdf2Sync(token, salt, 1000, 64, 'sha512').toString('hex').substring(0, 24);
const hash = crypto
.pbkdf2Sync(token, salt, 1000, 64, 'sha512')
.toString('hex')
.substring(0, 24);
return ua(GA_TRACKING_ID, {
return ua(GA_TRACKING_ID || '', {
cid: hash,
strictCidFormat: false,
uid: hash,
headers: {
'User-Agent': userAgent
}
'User-Agent': userAgent,
},
});
}
};

View File

@@ -4,6 +4,7 @@ import chalk from 'chalk';
// The equivalent of <code>, for embedding anything
// you may want to take a look at ./cmd.js
export default function code(cmd: string): string {
return `${chalk.gray('`')}${chalk.bold(cmd)}${chalk.gray('`')}`;
export default function code(cmd: string, { backticks = true } = {}): string {
const tick = backticks ? chalk.gray('`') : '';
return `${tick}${chalk.bold(cmd)}${tick}`;
}

View File

@@ -1,10 +0,0 @@
{
"version": 2,
"routes": [
{ "handle": "filesystem" },
{ "src": "/([^/]+/dir/.+)", "dest": "/$1.html", "check": true },
{ "handle": "miss" },
{ "src": "/pathA(?:/.+)?", "status": 404, "continue": true },
{ "src": "/pathB(?:/.+)?", "status": 404, "continue": true }
]
}

View File

@@ -10,14 +10,14 @@
"dest": "/blog/$1",
"check": true
},
{
"handle": "miss"
},
{
"src": "/.*",
"status": 404,
"continue": true
},
{
"handle": "miss"
},
{
"src": "/(.*)",
"dest": "/src/$1",

View File

@@ -1,8 +0,0 @@
{
"version": 2,
"routes": [
{ "handle": "miss" },
{ "src": "/pathA(?:/.+)?", "status": 404, "continue": true },
{ "src": "/pathB(?:/.+)?", "status": 404, "continue": true }
]
}

View File

@@ -1,7 +0,0 @@
{
"functions": {
"server/**/*.js": {
"runtime": "@now/node@1.2.1"
}
}
}

View File

@@ -1,3 +0,0 @@
export default (req, res) => {
res.end(`current hour: ${Math.floor(Date.now() / 10000)}`);
};

View File

@@ -0,0 +1,2 @@
module.exports = (req, res) =>
res.send(req.query.username);

View File

@@ -0,0 +1 @@
module.exports = (req, res) => res.end('42');

View File

@@ -0,0 +1,2 @@
module.exports = (req, res) =>
res.send(req.query.id);

View File

@@ -0,0 +1,3 @@
{
"rewrites": [{ "source": "/rand", "destination": "/api/fourty-two" }]
}

View File

@@ -247,12 +247,14 @@ function testFixtureStdio(directory, fn) {
if (stderr.includes(`Requested port ${port} is already in use`)) {
dev.kill('SIGTERM');
throw new Error(`Failed for "${directory}" with port ${port}.`);
throw new Error(
`Failed for "${directory}" with port ${port} with stderr "${stderr}".`
);
}
if (stderr.includes('Command failed') || stderr.includes('Error!')) {
dev.kill('SIGTERM');
throw new Error(`Failed for "${directory}".`);
throw new Error(`Failed for "${directory}" with stderr "${stderr}".`);
}
});
@@ -411,28 +413,6 @@ test(
})
);
test(
'[now dev] does not display directory listing after multiple 404',
testFixtureStdio('handle-miss-multiple-404', async (t, port) => {
t.is((await fetch(`http://localhost:${port}/pathA/dir`)).status, 404);
t.is((await fetch(`http://localhost:${port}/pathB/dir`)).status, 404);
t.is((await fetch(`http://localhost:${port}/pathC/dir`)).status, 200);
})
);
test(
'[now dev] does not display directory listing after `handle: miss` and 404',
testFixtureStdio('handle-miss-handle-filesystem-404', async (t, port) => {
t.is((await fetch(`http://localhost:${port}/pathA/dir`)).status, 404);
t.is((await fetch(`http://localhost:${port}/pathB/dir`)).status, 404);
t.is((await fetch(`http://localhost:${port}/pathC/dir`)).status, 200);
t.is((await fetch(`http://localhost:${port}/pathA/dir/one`)).status, 200);
t.is((await fetch(`http://localhost:${port}/pathB/dir/two`)).status, 200);
t.is((await fetch(`http://localhost:${port}/pathC/dir/three`)).status, 200);
})
);
test(
'[now dev] handles hit after handle: filesystem',
testFixtureStdio('handle-hit-after-fs', async (t, port) => {
@@ -483,6 +463,8 @@ test(
t.regex(await rand.text(), /random number/gm);
const rand2 = await fetchWithRetry(`http://localhost:${port}/api/rand.js`);
t.regex(await rand2.text(), /random number/gm);
const notfound = await fetch(`http://localhost:${port}/api`);
t.is(notfound.status, 404);
})
);
@@ -606,6 +588,31 @@ test('[now dev] validate env var names', async t => {
t.pass();
});
test(
'[now dev] test rewrites with segments serve correct content',
testFixtureStdio('test-rewrites-with-segments', async (t, port) => {
const users = await fetchWithRetry(
`http://localhost:${port}/api/users/first`,
3
);
t.regex(await users.text(), /first/gm);
const fourtytwo = await fetchWithRetry(
`http://localhost:${port}/api/fourty-two`,
3
);
t.regex(await fourtytwo.text(), /42/gm);
const rand = await fetchWithRetry(`http://localhost:${port}/rand`, 3);
t.regex(await rand.text(), /42/gm);
const dynamic = await fetchWithRetry(
`http://localhost:${port}/api/dynamic`,
3
);
t.regex(await dynamic.text(), /dynamic/gm);
const notfound = await fetch(`http://localhost:${port}/api`);
t.is(notfound.status, 404);
})
);
test(
'[now dev] test rewrites serve correct content',
testFixtureStdio('test-rewrites', async (t, port) => {

View File

@@ -156,33 +156,6 @@ RUN mkdir /public
RUN echo hello > /public/index.html
`,
},
'build-env': {
'now.json': JSON.stringify({
version: 1,
type: 'static',
build: {
env: { FOO: 'bar' },
},
}),
Dockerfile: `
FROM alpine
ARG FOO
RUN mkdir /public
RUN echo $FOO > /public/index.html
`,
},
'build-env-arg': {
'now.json': JSON.stringify({
version: 1,
type: 'static',
}),
Dockerfile: `
FROM alpine
ARG NONCE
RUN mkdir /public
RUN echo $NONCE > /public/index.html
`,
},
'build-env-debug': {
'now.json':
'{ "builds": [ { "src": "index.js", "use": "@now/node" } ], "version": 2 }',

View File

@@ -1859,79 +1859,6 @@ test('deploy a static build deployment', async t => {
t.is(content.trim(), 'hello');
});
test('use build-env', async t => {
const directory = fixture('build-env');
const { stdout, stderr, exitCode } = await execa(
binaryPath,
[directory, '--public', '--name', session, ...defaultArgs],
{
reject: false,
}
);
console.log(stderr);
console.log(stdout);
console.log(exitCode);
// Ensure the exit code is right
t.is(exitCode, 0);
// Test if the output is really a URL
const deploymentUrl = pickUrl(stdout);
const { href, host } = new URL(deploymentUrl);
t.is(host.split('-')[0], session);
await waitForDeployment(href);
// get the content
const response = await fetch(href);
const content = await response.text();
t.is(content.trim(), 'bar');
});
test('use `--build-env` CLI flag', async t => {
const directory = fixture('build-env-arg');
const nonce = Math.random()
.toString(36)
.substring(2);
const { stderr, stdout, exitCode } = await execa(
binaryPath,
[
directory,
'--public',
'--name',
session,
'--build-env',
`NONCE=${nonce}`,
...defaultArgs,
],
{
reject: false,
}
);
console.log(stderr);
console.log(stdout);
console.log(exitCode);
// Ensure the exit code is right
t.is(exitCode, 0, `Received:\n"${stderr}"\n"${stdout}"`);
// Test if the output is really a URL
const deploymentUrl = pickUrl(stdout);
const { href, host } = new URL(deploymentUrl);
t.is(host.split('-')[0], session);
await waitForDeployment(href);
// get the content
const response = await fetch(href);
const content = await response.text();
t.is(content.trim(), nonce);
});
test('use `--debug` CLI flag', async t => {
const directory = fixture('build-env-debug');

View File

@@ -1329,80 +1329,6 @@ test('deploying more than 1 path should fail', async t => {
t.true(stderr.trim().endsWith(`Can't deploy more than one path.`));
});
test('use build-env', async t => {
const directory = fixture('build-env');
const { stdout, stderr, exitCode } = await execa(
binaryPath,
[directory, '--public', '--name', session, ...defaultArgs, '--confirm'],
{
reject: false,
}
);
console.log(stderr);
console.log(stdout);
console.log(exitCode);
// Ensure the exit code is right
t.is(exitCode, 0);
// Test if the output is really a URL
const deploymentUrl = pickUrl(stdout);
const { href, host } = new URL(deploymentUrl);
t.is(host.split('-')[0], session);
await waitForDeployment(href);
// get the content
const response = await fetch(href);
const content = await response.text();
t.is(content.trim(), 'bar');
});
test('use `--build-env` CLI flag', async t => {
const directory = fixture('build-env-arg');
const nonce = Math.random()
.toString(36)
.substring(2);
const { stderr, stdout, exitCode } = await execa(
binaryPath,
[
directory,
'--public',
'--name',
session,
'--build-env',
`NONCE=${nonce}`,
...defaultArgs,
'--confirm',
],
{
reject: false,
}
);
console.log(stderr);
console.log(stdout);
console.log(exitCode);
// Ensure the exit code is right
t.is(exitCode, 0, `Received:\n"${stderr}"\n"${stdout}"`);
// Test if the output is really a URL
const deploymentUrl = pickUrl(stdout);
const { href, host } = new URL(deploymentUrl);
t.is(host.split('-')[0], session);
await waitForDeployment(href);
// get the content
const response = await fetch(href);
const content = await response.text();
t.is(content.trim(), nonce);
});
test('use `--debug` CLI flag', async t => {
const directory = fixture('build-env-debug');

View File

@@ -69,9 +69,7 @@ const getStaticFiles = async (dir, isBuilds = false) => {
const normalizeWindowsPaths = files => {
if (process.platform === 'win32') {
const prefix = 'D:/a/now/now/packages/now-cli/test/fixtures/unit/';
return files.map(f =>
f.replace(/\\/g, '/').slice(prefix.length)
);
return files.map(f => f.replace(/\\/g, '/').slice(prefix.length));
}
return files;
};

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