Compare commits

..

930 Commits

Author SHA1 Message Date
Steven
c5ebaa11ea Publish
- gatsby-plugin-now@1.2.2
 - @now/build-utils@0.10.1
 - now@16.3.0
 - now-client@5.1.4
 - @now/go@0.6.0
 - @now/next@1.0.2
 - @now/node@1.0.1
 - @now/python@0.3.0
 - @now/ruby@0.1.7
 - @now/static-build@0.10.0
2019-09-30 09:41:51 -04:00
Andy
934fbc8992 [now-cli] Fix deployment version output (#3097)
It will print `[v2]` for 1.0 deployments when logging initially:

```
• go $ now --force
> WARN! You are using an old version of the Now Platform. More: https://zeit.co/docs/v2/advanced/platform/changes-in-now-2-0
> Deploying ~/projects/zeit/now-builder-v1/examples/docker/go under andyschneider
> Using project now-v1-go-docker
> now-v1-go-docker-xxxxxxx.now.sh [v2] [1s]
> Build completed
> https://now-v1-go-docker-xxxxxxx.now.sh [v1] [in clipboard] (sfo1) [1m]
> Verifying instantiation in sfo1
> ✔ Scaled 1 instance in sfo1 [22s]
> Success! Deployment ready
```

Expected:

```
• go $ nowl --force
> WARN! You are using an old version of the Now Platform. More: https://zeit.co/docs/v2/advanced/platform/changes-in-now-2-0
> Deploying ~/projects/zeit/now-builder-v1/examples/docker/go under andyschneider
> Using project now-v1-go-docker
> now-v1-go-docker-xxxxxxx.now.sh [v1] [2s]
> Build completed
> https://now-v1-go-docker-xxxxxxx.now.sh [v1] [in clipboard] (sfo1) [1m]
> Verifying instantiation in sfo1
> ✔ Scaled 1 instance in sfo1 [23s]
> Success! Deployment ready
```

For v2 it shouldn't print anything, as it's the default.
2019-09-30 09:38:16 -04:00
Max
72cb5515fd [now-client] Use ignore module to handle file ignoring logic (#3092)
This implements ignore handling using `ignore` module, in the same way CLI stable does it
2019-09-30 09:38:06 -04:00
Steven
c7f0770d53 [now-static-build] Make curl silent (#3090)
We added a message in #3068 so this PR makes curl silent unless it errors.

Also fix typo in Gutenberg 😉 

PRODUCT-7 #close
2019-09-30 09:38:00 -04:00
Max
7ea49e8ada [now-cli] Add not_domain_owner error handling (#3045)
This adds missing error handler for `not_domain_owner` error (fixes #3042)
2019-09-30 09:37:55 -04:00
Nathan Rajlich
cae6ce96b3 [now-client] Export TypeScript types (#3087)
This makes downstream compilation with `tsc` work correctly.

Otherwise, compilation fails with errors such as:

```
../now-client/dist/src/index.d.ts:1:40 - error TS2304: Cannot find name 'CreateDeploymentFunction'.

1 export declare const createDeployment: CreateDeploymentFunction;
                                         ~~~~~~~~~~~~~~~~~~~~~~~~
````
2019-09-30 09:37:49 -04:00
Sophearak Tha
3699dfd756 [now-next] Invoke build script (#3073)
This PR make `@now/next` invoke `build` script if user defined.

PRODUCT-106 #close
2019-09-30 09:37:41 -04:00
Leo Lamprecht
6dca96d877 [now-build-utils] Make grouping prerenders optional (#3082)
As of https://github.com/zeit/now/pull/3081, we make it necessary to group `Prerenders` together for being invalidated at the same time.

However, you might not want that. In turn, we'll make it optional.
2019-09-30 09:37:36 -04:00
Leo Lamprecht
88c14b27a2 [now-build-utils] Allow prerender groups to be defined with an integer (#3081)
This pull request removes the `PrerenderGroup` type in favor of a `group` parameter for the existing `Prerender` type.

This parameter takes in an integer that defines a group of prerenders that should be invalidated at the same time:

```
interface Prerender {
  expiration: number;
  lambda: Lambda;
  fallback: FileBlob | FileFsRef | FileRef;
  group: number;
}
```

**Example:** If two `Prerender` instances exist that have `group` set to `1`, they will both be invalidated at the same time.
2019-09-30 09:37:31 -04:00
Max
0d2a9539f6 [now-cli] Add logging to execa calls in tests (#3077)
This implements #3075 for all integration tests
2019-09-30 09:37:25 -04:00
Max
bae160bd7c [now-client] Retry on network error (#3072)
This PR improves handling of occasional network errors in `now-client` which should improve benchmarking introduced in #3062
2019-09-30 09:37:19 -04:00
Max
92852ecff2 [now-cli] Move hexo test to testFixtureStdio (#3076)
This should fix the `now dev` tests that periodically hang
2019-09-30 09:37:12 -04:00
Max
ac0c841cb8 [now-client] Add debug logs (#2997)
This PR adds extensive debug logging to `now-client` and enables it in CLI based on the `--debug` flag

Debug logging works in either of the following two conditions:
- `debug: true` is provided in the `options` object of `createDeployment`/`createLegacyDeployment`
- `process.env.NOW_CLIENT_DEBUG` environment variable is set
2019-09-30 09:37:05 -04:00
Sophearak Tha
53e4b71f89 [now-cli] Render prompt when deploying home directory (#3057)
Fixes #3069 

PRODUCT-160 #close
2019-09-30 09:36:53 -04:00
Steven
017a2692ca [now-static-build] Add test for BUNDLE_WITHOUT env var (#3070)
This adds a test which confirms that `BUNDLE_WITHOUT="test:development"` works properly.

This env var is equivalent to `bundle install --without test development`.

There's no code change here because groups are defined by the user, therefore they must define which ones to ignore (if any).

- Groups Guide: https://bundler.io/v2.0/guides/groups.html
- BUNDLER_WITHOUT: https://bundler.io/v2.0/bundle_config.html#LIST-OF-AVAILABLE-KEYS
- Example Gemfile: https://github.com/thoughtbot/administrate/blob/master/Gemfile

PRODUCT-133 #close
2019-09-30 09:36:45 -04:00
Steven
311f89eecb Use PR description for merge commit body (#3071) 2019-09-30 09:36:39 -04:00
Steven
40d2bc4743 [now-static-build] Print version of static generator during build (#3068)
* [now-static-build] Print version of static generator

* Use curl progress bar
2019-09-30 09:36:33 -04:00
Steven
37160cbc8b [tests] Add benchmark script to randomly generate projects files (#3062) 2019-09-30 09:36:28 -04:00
Steven
3807a2b018 [now-node] Fix sharp test using lock file (#3064) 2019-09-30 09:36:21 -04:00
Steven
b6697dd432 [now-static-build] Add Eleventy to optimized framework list (#3060)
* [now-static-build] Add eleventy to frameworks

* Add test using eleventy-base-blog

* Fix tests with dot files

* Add now.json to 27-eleventy fixture
2019-09-30 09:36:16 -04:00
Sophearak Tha
6c33496e8a [now-cli] Add NOW_BUILDER_DEBUG to build env if --debug (#3041)
* Add `NOW_BUILDER_DEBUG` to build env if `--debug`

* Add `--debug` build env check

* Add `build-env-debug` to prepare
2019-09-30 09:36:08 -04:00
Sophearak Tha
89f32625ed [now-cli] Fix 02-angular-node test fail (#3058)
* Improve `02-angular-node` test

* Add `yarn.lock` with pin version
2019-09-30 09:35:53 -04:00
Steven
8253e76ec0 [now-python] Fix headers with multiple values (#3053)
* [now-python] Add format_headers()

* Add tests

* Fix filenames

* Fix test probes
2019-09-30 09:35:44 -04:00
Andy
e0b3e9606a [now-cli][now-static-build] Ignore output directory from now dev (#3024)
* [now-cli][now-static-build] Ignore output directory from `now dev`

* Add test

* Logging

* Fix test

* Fix test

* Adjust test

* Log failed test

* Log stderr

* Change now.json

* Change Ready check

* Dynamically create now.json

* Log error

* Log stderr on error

* Create now.json first

* Handle JSON error

* Don't use JSON output

* Join path

* Add quotes

* Use .values
2019-09-30 09:35:38 -04:00
Sophearak Tha
dc75a303f7 [now-build-utils] Remove NOW_BUILDER_ANNOTATE (#3027) 2019-09-30 09:35:33 -04:00
Steven
c1eb8ec78c [now-static-build][now-build-utils] Add python static generators (#3048)
* [now-static-build] Run pip install requirements.txt

* Add test for pelican

* Add test for mkdocs
2019-09-30 09:35:26 -04:00
Sophearak Tha
12435f25fd [builders] Consistently capitalize first letter of logs (#3039)
* Consistency capitalize logs line `@now/next`

* Consistency capitalize logs line `@now/node`

* Consistency capitalize logs line `@now/go`

* Consistency capitalize logs line `@now/python`

* Always show `Installing dependencies...`

* Consistency capitalize logs line `run-user-scripts`

* Capitalize `Running`
2019-09-30 09:35:21 -04:00
Steven
d4dc5222cf [now-static-build] Add prepareCache() function (#3047) 2019-09-30 09:35:14 -04:00
Steven
bf1e59b2d3 [now-static-build] Add support for hugo extended (#3043) 2019-09-30 09:35:06 -04:00
Nathan Rajlich
3657e4a36e [now-cli] Update @zeit/fun to v0.10.2 (#3038)
Fixes #2901.
2019-09-30 09:34:43 -04:00
Nathan Rajlich
09efc1d865 [now-cli] Render logs containing "warning" as yellow (#3035) 2019-09-30 09:34:19 -04:00
Steven
22bded50b6 [master only] Fix merge conflict 2019-09-17 18:39:06 -04:00
Steven
b5b02be3c2 [docs] Update CI badge to use master (#3037) 2019-09-17 18:36:49 -04:00
Steven
776f372eb3 [tests] Add env var FORCE_BUILD_IN_REGION (#3036)
* [tests] Add env var FORCE_BUILD_IN_REGION

* Add missing config
2019-09-17 18:35:42 -04:00
Steven
81279fd40b [now-static-build] Add hugo, zola, and gutenberg versioning (#3025)
* [now-static-build] Add hugo, zola, and gutenberg versioning

* Add tests

* Export spawnAsync

* Change spawnAsync to remove cwd
2019-09-17 18:35:34 -04:00
Leo Lamprecht
3342485d29 [now-build-utils] Add types for SPRv2 (#3021)
* Add `Prerender` type for SPRv2

* Make it a default export

* Added `PrerenderGroup` type

* Renamed interface
2019-09-17 18:35:27 -04:00
Andy
028ee848f5 [now-cli] Fix fetch body and add secrets tests (#3030) 2019-09-17 18:35:19 -04:00
Nathan Rajlich
7e64c3b8a9 [now-cli] Assign process.exitCode (#3028)
No real functional change here, but assigning to `process.exitCode`
is the more proper Node.js way to set the exit code for the process.
2019-09-17 18:35:09 -04:00
Nathan Rajlich
704031f7b2 [now-cli] Render "stderr" as red in now logs (#3026) 2019-09-17 18:35:02 -04:00
Andy
5e3c184735 [now-cli] Adjust the printed version for the deployment (#3014) 2019-09-17 18:34:54 -04:00
Steven
88a8022787 [docs] Add scripts for changelog and diff (#3017)
* [release] Add scripts for changelog and diff

* Remove publish docs since it in the wiki

* Add support for windows
2019-09-17 18:34:49 -04:00
Steven
96844dc4a5 [now-node] Change trace errors to warnings (#3016) 2019-09-17 18:34:44 -04:00
Max
a09acd6969 [now-cli][now-client] Remove fetch-h2 (#3011)
* Remove fetch-h2

* Fix package.json

* Fix migration issue

* Improve time() call and ensure consistent header names

* Remove unused agent.ts
2019-09-17 18:34:38 -04:00
Andy
4e232f78de [now-cli] Add test for zero-config and canary builders (#3009)
* [now-cli] Add test for zero-config and canary builders

* Fix test

* Fix test

* Fix url

* Fix path and export

* Make public
2019-09-17 18:34:29 -04:00
Steven
b146a04772 [now-node] Add support for AWS Gateway Event (#3010)
* [now-node] Add support for AWS Gateway Event

* Fix funcName

* Fix makeAwsLauncher export

* Add missing return
2019-09-17 18:34:20 -04:00
Steven
eaaa50e616 Add release notes script to PUBLISHING.md (#3006) 2019-09-17 18:34:14 -04:00
Andy
c893eaeb7a [now-cli] Default to empty string for undefined env var when checking (#3008) 2019-09-17 18:34:08 -04:00
Andy
5bf7d7fd07 [now-cli] Add changelog link to update message (#3001) 2019-09-17 18:34:00 -04:00
Max
ca8fc92b94 [now-cli] Fix links output during deployment (#2966)
* Fix links output during deployment

* Move "synced" log to `total-fileds` event

* Pluralize synced messages

* Update packages/now-cli/src/util/deploy/process-deployment.ts

Co-Authored-By: Steven <steven@ceriously.com>

* Fix failing tests due to stdout mismatch
2019-09-17 18:33:53 -04:00
Steven
9956e85f12 [now-ruby] Use pre-installed ruby 2.5 (#2991)
* [now-ruby] Use pre-installed ruby 2.5

* Change GEM_HOME

* Add polyfill for Node 8
2019-09-17 18:33:47 -04:00
Nathan Rajlich
7fa4739c78 [now-cli] Show a warning for invalid env vars in now dev (#3002)
* [now-cli] Show a warning for invalid env vars in `now dev`

Closes #2982.

* Add "validate env var names" integration test
2019-09-17 18:33:40 -04:00
Andy
0ef2e2a7ec [now-cli] Add tests for alias rules (#3003) 2019-09-17 18:33:34 -04:00
Sophearak Tha
8fd1752acf [now-go] Improve test for custom build flags (#2999) 2019-09-17 18:33:29 -04:00
Nathan Rajlich
14a1446faf [now-cli] Render correct command for now ls $path_alias_url (#2988)
Previously, if you ran `now ls` with a URL for a path alias, then an
error message `Cannot read property 'replace' of undefined` would occur.

Now, a message is logged saying to instead run `now alias ls $url` which
is the correct command to get path rules relevant to a path alias URL.

> Found matching path alias: rules.domain.com
> Please run `now alias ls rules.domain.com` instead

Fixes #2987.
2019-09-17 18:33:16 -04:00
Steven
0c2c8c5ae5 [now-static-build] Run bundle install when Gemfile is found (#2980)
* [now-static-build] Run `bundle install` for Gemfile

* Add logs

* Add timeout in case proc hangs

* Rename test

* Remove console.log()

* Hide warnings

* Use runBundleInstall()

* [now-build-utils] Remove --deployment flag

* Run tests for build-utils
2019-09-17 18:33:07 -04:00
Steven
511b27ad39 [now-node][now-next] Bump node-file-trace to 0.3.1 (#2990) 2019-09-17 18:33:00 -04:00
Sophearak Tha
e22ce7da0a [now-cli] Hide Init Duration and XRAY TraceId by default (#2984) 2019-09-17 18:32:54 -04:00
Steven
d9a4ce06bc [now-build-utils] Add function runBundleInstall() (#2986)
* [now-build-utils] Add function `runBundleInstall`

* Add additional flags

* Set jobs to number of cpus

* Format

* Fix formatting

* Add BUNDLE_APP_CONFIG
2019-09-17 18:32:46 -04:00
Steven
77fb14cc60 [now-node] Bump node-file-trace to 0.3.0 and print warnings (#2985)
* Bump node-file-trace to 0.3.0

* [now-node] Print warnings from node-file-trace
2019-09-17 18:32:39 -04:00
Clément ALLAIN
17c397211e [now-static-build] Fix dev server port detection (#2879)
* [now-static-build] Fix dev server detection

* Code review

* Remove unused dependency

* Fix the checking by really waiting until the port is reachable
2019-09-17 18:32:20 -04:00
Andy
6ca83644bc [now-build-utils][now-cli] Warn instead of throwing on api and pages/api (#2976)
* [now-build-utils][now-cli] Warn instead of throwing on `api` and `pages/api`

* Remove slash and adjust tests

* Remove @now/build-utils

* Hardcode builders

* Add build-utils

* Change default flag

* More logging

* Add static-build

* Remove other packages from package.json

* New file for bundled function
2019-09-17 18:31:56 -04:00
Andy
d1946ea9b6 [now-cli] Display warning when changing the secret name (#2975) 2019-09-17 18:31:44 -04:00
Nathan Rajlich
cc9eae3b71 [now-cli] Use PackageJson and Builder types from @now/build-utils (#2971)
No functionality change here, this just removes the `Package` and
`BuildConfig` types from `src/util/dev/types.ts` in favor of the
matching types from `@now/build-utils`.

Also a lot of prettier formatting…
2019-09-17 18:31:37 -04:00
Nathan Rajlich
7bbc17df4b [now-build-utils] Add env and buildEnv to Meta type (#2970)
* [now-build-utils] Add `env` and `buildEnv` to `Meta` type

`now dev` passes in these variables to the "meta" object.

* Fix build
2019-09-17 18:31:31 -04:00
Andy
df6b2be482 [now-build-utils] Throw error on Next.js pages/api and api/ (#2964) 2019-09-17 18:30:40 -04:00
Sophearak Tha
5ff6263fb7 [now-cli] Add platform in Sentry report (#2960) 2019-09-17 18:30:33 -04:00
Luc
04dc8aaf73 [gatsby-plugin-now] Add keywords in package.json (#2965)
* add keywords to gatsby-plugin-now

* add #readme in homepage url
2019-09-17 18:30:25 -04:00
Sophearak Tha
5435805e58 [now-build-utils] Use debug() on installing to and missing engines (#2954)
* Use debug() on `installing to` output

* Use debug() on `getSupportedNodeVersion` output
2019-09-17 18:30:16 -04:00
Nathan Rajlich
903f819c5d [now-cli] Fix now alias with no arguments (#2959)
Fixes #2941.
2019-09-17 18:29:41 -04:00
Nathan Rajlich
5d927b2d25 [CircleCI] Remove publish-stable and publish-canary steps (#2957)
Publishing to npm is now handled by GitHub Actions.

Aside from that, the Circle publishing was broken.
See: https://circleci.com/gh/zeit/now/7213
2019-09-17 18:29:11 -04:00
Steven
b7a260cc6d [now-python] Use system python with now dev (#2956) 2019-09-17 18:29:03 -04:00
Steven
e8ba8fb97b [now-cli] Bump @zeit/fun to 0.10.0 (#2955) 2019-09-17 18:28:49 -04:00
Max
dd1d9d856b [now-cli] Implement now-client deployments in Now CLI (#2875)
* Imlement `now-client` deployments in Now CLI

* Move now-client to dev dependencies

* Fix missing config for legacy deployments

* Restore no files warning

* Improve error handling

* Port over `--prod`

* Handle single files and warnings better

* Fix legacy deployment env config

* Handle build errors in events

* Don't use ncc for now-client

* Extract `for...await` logic into a `.ts` file

* Revert "Don't use ncc for now-client"

This reverts commit e481a04058952f7011bf5523445256f1b8882dda.

* Add `typings` field to `now-client`

* Regenerate yarn.lock

* Add bootstrap step to CircleCI

* Add bootstrap step before build

* Revert "Add bootstrap step before build"

This reverts commit db9e1113937f113cca8c7c05d5c800fd5d61e84b.

* Revert "Add bootstrap step to CircleCI"

This reverts commit 02c0006a073614814fd174ccbaf1e4e0d8dd3dbf.

* Build `now-client` before CLI

* Sort build scripts

* Tweak empty deployment detection

* Add bootstrap step before build

* Remove now-client dependency from now-client

* Use local dependencies

* Fix paths and regenerate lockfile

* Bypass broken linting rule

* Remove lint ignore

* Use `tsc` instead of `ncc` for `now-client`

Co-Authored-By: Steven <steven@ceriously.com>

* Fix output path for tsc build

* [test] Supress TS warning

* Update packages/now-cli/src/commands/deploy/latest.js

Co-Authored-By: Steven <steven@ceriously.com>

* Update packages/now-cli/src/commands/deploy/latest.js

Co-Authored-By: Steven <steven@ceriously.com>

* Update packages/now-client/package.json

Co-Authored-By: Steven <steven@ceriously.com>

* Change `now-client` output to `dist`

* Implement file events in now-client and bring back progressbar

* Update build script sorting

* Add new logic tests for `now-client`

* Remove redundant target check

* Remove now-client dependency and use local code

* Set exact dependency versions

* Revert "Set exact dependency versions"

This reverts commit e0a31eaf10e498271c9253439d4bbd650738c694.

* Revert local now-client import

* Revert `now-client` dependency to local path

* Implement feedback

* Fix formatting

* Only handle alias errors if `readyState` is `READY`

* Update packages/now-cli/src/commands/deploy/latest.js

Co-Authored-By: Andy <AndyBitz@users.noreply.github.com>

* Update packages/now-cli/src/commands/deploy/latest.js

Co-Authored-By: Andy <AndyBitz@users.noreply.github.com>
2019-09-17 18:27:13 -04:00
Steven
eef4c65e5f Publish
- @now/next@1.0.1
2019-09-17 17:44:26 -04:00
Joe Haddad
3f64594a22 [now-next] Add monorepo autosetup support (#2961)
* [now-next] Add monorepo autosetup support

* Add actual tests

* Remove invalid test

* Correct contents directory

* Update tests

* Support new Next.js canaries
2019-09-17 17:22:22 -04:00
Max Rovensky
3f5f71f8ab Publish
- now-client@5.1.3
2019-09-09 23:32:19 +08:00
Max
2a44179898 [now-client] Fix windows paths handling (#2974)
* Fix windows paths handling in now-client

* Tweak windows paths  handling
2019-09-09 23:31:16 +08:00
Andy Bitz
4a6ddf8b1d Publish
- gatsby-plugin-now@1.2.1
 - @now/build-utils@0.10.0
 - @now/cgi@0.1.6
 - now@16.2.0
 - now-client@5.1.2
 - @now/go@0.5.12
 - @now/next@1.0.0
 - @now/node-bridge@1.2.5
 - @now/node@1.0.0
 - @now/python@0.2.18
 - @now/routing-utils@1.2.4
 - @now/ruby@0.1.6
 - @now/static-build@0.9.10
2019-09-05 18:25:48 +02:00
Andy Bitz
eeb1b2442c Revert "[now-cli] Implement now-client deployments in Now CLI (#2875)"
This reverts commit 129f234aaa.
2019-09-05 00:03:23 +02:00
Max
129f234aaa [now-cli] Implement now-client deployments in Now CLI (#2875)
* Imlement `now-client` deployments in Now CLI

* Move now-client to dev dependencies

* Fix missing config for legacy deployments

* Restore no files warning

* Improve error handling

* Port over `--prod`

* Handle single files and warnings better

* Fix legacy deployment env config

* Handle build errors in events

* Don't use ncc for now-client

* Extract `for...await` logic into a `.ts` file

* Revert "Don't use ncc for now-client"

This reverts commit e481a04058952f7011bf5523445256f1b8882dda.

* Add `typings` field to `now-client`

* Regenerate yarn.lock

* Add bootstrap step to CircleCI

* Add bootstrap step before build

* Revert "Add bootstrap step before build"

This reverts commit db9e1113937f113cca8c7c05d5c800fd5d61e84b.

* Revert "Add bootstrap step to CircleCI"

This reverts commit 02c0006a073614814fd174ccbaf1e4e0d8dd3dbf.

* Build `now-client` before CLI

* Sort build scripts

* Tweak empty deployment detection

* Add bootstrap step before build

* Remove now-client dependency from now-client

* Use local dependencies

* Fix paths and regenerate lockfile

* Bypass broken linting rule

* Remove lint ignore

* Use `tsc` instead of `ncc` for `now-client`

Co-Authored-By: Steven <steven@ceriously.com>

* Fix output path for tsc build

* [test] Supress TS warning

* Update packages/now-cli/src/commands/deploy/latest.js

Co-Authored-By: Steven <steven@ceriously.com>

* Update packages/now-cli/src/commands/deploy/latest.js

Co-Authored-By: Steven <steven@ceriously.com>

* Update packages/now-client/package.json

Co-Authored-By: Steven <steven@ceriously.com>

* Change `now-client` output to `dist`

* Implement file events in now-client and bring back progressbar

* Update build script sorting

* Add new logic tests for `now-client`

* Remove redundant target check

* Remove now-client dependency and use local code

* Set exact dependency versions

* Revert "Set exact dependency versions"

This reverts commit e0a31eaf10e498271c9253439d4bbd650738c694.

* Revert local now-client import

* Revert `now-client` dependency to local path

* Implement feedback

* Fix formatting

* Only handle alias errors if `readyState` is `READY`

* Update packages/now-cli/src/commands/deploy/latest.js

Co-Authored-By: Andy <AndyBitz@users.noreply.github.com>

* Update packages/now-cli/src/commands/deploy/latest.js

Co-Authored-By: Andy <AndyBitz@users.noreply.github.com>
2019-09-04 23:54:21 +02:00
Nathan Rajlich
331c352e2b [now-cli] Update pcre-to-regexp to v1.0.0 (#2932)
No improvements, per say, but the module has been converted to
TypeScript so it supplies its own type definitions now, and we
can delete our hand-crafted typings from this repo.
2019-09-04 23:46:31 +02:00
Nathan Rajlich
2ccbaea9dd [now-cli] Remove deprecated @now/php builder from bundled builders tarball (#2907)
`@now/php` has been deprecated in favor of community-maintained
`now-php`, so don't bundle the deprecated builder with Now CLI.
2019-09-04 23:45:44 +02:00
Sophearak Tha
069eca3c62 [now-cli] Remove annotate from now logs (#2937)
* Remove annotate from `now logs`

* Filter out runtime logs to be consistency with dashboard logs

* Add integration test
2019-09-04 23:44:13 +02:00
Nathan Rajlich
305e364f8b [now-cli] Output --json to stdout for now alias ls <url> (#2922)
Fixes #1337.
2019-09-04 23:41:27 +02:00
Nathan Rajlich
4068805ae0 [now-cli] Use xdg-app-paths for now dev cache dir (#2921)
* [now-cli] Use `xdg-app-paths` for `now dev` cache dir

For consistency, because #2877 uses this module.
No need for multiple modules that do the same thing.

* Update `@zeit/fun` to v0.9.3
2019-09-04 23:36:16 +02:00
Andy
9a1e7a4a7a [now-cli] Handle now certs ls for users and teams without certificates (#2945)
* [now-cli] Fix `now certs ls` when the user or team has no certs

* Add tests and move to typescript

* Move index and add to typescript

* Fix reduce function in ls

* Added linebreak

* Update packages/now-cli/src/commands/certs/add.ts

Co-Authored-By: Naoyuki Kanezawa <naoyuki.kanezawa@gmail.com>
2019-09-04 23:25:31 +02:00
Naoyuki Kanezawa
bbad3d1b96 Add the nameservers verification check and improve messages (#2943)
* add the nameservers verification check and improve messages

* fix verify message condition
2019-09-04 23:25:23 +02:00
Nathan Rajlich
c62116d9a4 [now-cli] Remove now update from --help output (#2951)
Fixes #2940.
2019-09-04 23:25:11 +02:00
Nathan Rajlich
c94086ff21 [now-cli] Remove scale subcommand from --help (#2923)
Fixes #1998.
2019-09-04 23:25:00 +02:00
Andy
e99caa7b97 Fix the prettier config (#2946)
* Fix the prettier config

* Try prettier
2019-09-04 23:24:52 +02:00
Andy
658b9e9007 [now-cli] Install dependencies before running now dev in tests (#2948)
* [now-cli] Install dependencies before running `now dev` in tests

* Check install exit code

* Add more logging

* Add more logging

* More logging

* Include yarn.lock file

* Add lock files to dev fixtures

* Ignore test

* Ignore another test

* Ignore another test

* Whitespace

* Install deps for unit tests

* Whitespace
2019-09-04 23:24:45 +02:00
Luc
3ef27ae45c [gatsby-plugin-now] Add new package w/support for Gatsby Redirects (#2897)
* add gatsby-plugin-now

* add test

* adjust with lerna

* fix test

* add tests to circleci

* add support for defaultRoutes functions

* add defaultRoutes to gatsby

* fix types

* add test case for gatsby redirects

* remove gatsby, react, react-dom from monorepo deps

* chmod +x build.sh

* add missing build script in fixtures

* do stuff during tests to avoid persistence issue

* move tests setup to build step

* copy gatsby plugin files in test case

* bring back ncc step

* prettier gatsby-plugin-now

* add missing semicolons

* remove eslint, prettier from plugin

* persist build step copied file

* fetch without following redirects

* add files in package.json

* remove force

* fix tests probes

* fetch location is not raw location

* fix test

* add readme

* fix type error

* adjust tests

* add support for `force`

* add tests for `force`

* adjust tests again

* gatsby-plugin-now@1.1.0

* `"` -> `'`

* tweak redirect names in test by precaution

* change file name and delete when consumed

* format files

* gatsby-plugin-now@1.2.0

* Apply suggestions from code review

Co-Authored-By: Steven <steven@ceriously.com>

* tests -> test

* add --verbose

* adjust circleci to persist fixtures

* trigger tests

* add repository and homepage in package.json

* glob files after `defaultRoute` invocation
2019-09-04 23:23:58 +02:00
Andy
e669cd1152 [now-node][now-next] Skip installing user dependencies for now dev (#2926)
* Skip installing user dependencies for `now dev`

* Update type

* Install dependecies for test

* Add comma-dangle for @now/next

* Revert "Add comma-dangle for @now/next"

This reverts commit 720d5630f309ec44eb65e280af29db5b14bd50eb.

* Add trailing commas

* Reset typescript update

* Add trailing commas

* Bump @zeit/node-file-trace

* Readd trailing comma

* Bump @zeit/node-file-trace in @now/node
2019-09-04 23:23:47 +02:00
Sophearak Tha
b22aa7c0cf [now-go] Add GO_BUILD_FLAGS support for go build custom flags (#2916)
* Add `GO_BUILD_FLAGS` support for go build custom flags

* Using string-argv package

* Simplify condition
2019-09-04 23:23:33 +02:00
Joe Haddad
582cbb61fb [now-next] Create default file with correct target (#2924) 2019-09-04 23:23:10 +02:00
Sophearak Tha
7f4197cf43 [now-node] Cleanup debug output (#2927)
* Ensure traced files have annotate present in all lines

* Remove traced file logs

* Remove `compiling es module file` log

* Cleanup debug output
2019-09-04 23:22:49 +02:00
JJ Kasper
30889db487 [now-next] Use patched version of yazl and trace API pages separate (#2919)
* Update to trace API files separately and use modified yazl

* Remove jszip dependency

* Pin yazl dependency and add types

* Update more types
2019-09-04 23:22:30 +02:00
Luc
2d08d5d23e [tests] Unify .editorconfig (#2920) 2019-09-04 23:22:16 +02:00
Luc
59e7367e03 [tests] Unify linting and autoformatting (#2914)
* add prettier and eslint on root

* remove eslint from now-cli

* adjust root package.json

* adjust eslintignore

* adjust now-cli rules

* remove @zeit/git-hooks in packages

* adjust now-client eslint config

* add lint-staged and hook on pre-commit

* add pre-commit script

* replace @zeit/git-hooks with husky

* remove unnecessary script

* fix eslint errors

* trigger tests

* fix fixable errors

* fix fixable errors (bis)

* revert two changes
2019-09-04 23:22:02 +02:00
Naoyuki Kanezawa
84af278e86 [tests] Remove fixtures files for integration tests (#2910) 2019-09-04 23:21:51 +02:00
JJ Kasper
67d9ee39e2 [now-next] Optimize lambda creation (#2892)
* Optimize zipping lambdas for now-next

* Update to use jszip to get around bug in yazl

* Add pseudo layer utils

* Apply suggestions from code review

Co-Authored-By: Joe Haddad <joe.haddad@zeit.co>

* Update sema concurrency from tests

* Update packages/now-next/src/index.ts

* Use custom types to fix broken @types package

* Add license header

* Revert "Use custom types to fix broken @types package"

This reverts commit 82441285155f6e0899c43dffdd5e000ecbd7b1b6.

* Fix CI Yarn installation

* TypeScript types should never be hoisted

* Fix all typechecking
2019-09-04 23:21:32 +02:00
Joe Haddad
6c67bb81f7 [now-next] Do not add initial files to lambda (#2894) 2019-09-04 23:21:03 +02:00
Steven
aba19701c0 [tests] Ignore fixtures in GitHub Languages & fix yarn.lock (#2890) 2019-09-04 23:20:47 +02:00
Sophearak Tha
bb79402999 [now-next] Use debug() from build-utils (#2881)
* [now-next] Use `debug()` from build-utils (#909)

* Use `debug()` from build-utils

* Revert back to warning output

* Remove unnecessary debug check
2019-09-04 23:20:37 +02:00
Sophearak Tha
420bc4b244 [now-go] Use debug() from build-utils (#2885)
* [now-go] Use `debug()` from build-utils (#923)

* Use `debug()` from build-utils

* Apply suggestions from code review

Co-Authored-By: Steven <steven@ceriously.com>

* Print errors

* Apply suggestions from code review

Co-Authored-By: Steven <steven@ceriously.com>
2019-09-04 23:20:27 +02:00
Sophearak Tha
323c3d74cb [now-ruby] Use debug() from build-utils (#2883) 2019-09-04 23:20:20 +02:00
Sophearak Tha
4ecec8a8f6 [now-node] Use debug() from build-utils (#2880)
* Use `debug()` from build-utils

* Remove condition
2019-09-04 23:20:13 +02:00
Sophearak Tha
98883f9978 [now-static-build] Use debug() from build-utils (#2884) 2019-09-04 23:20:04 +02:00
Sophearak Tha
37cf3be437 [now-python] Use debug() from build-utils (#2882)
* Use `debug()` from build-utils

* Apply suggestions from code review

Co-Authored-By: Steven <steven@ceriously.com>
2019-09-04 23:19:45 +02:00
Andy Bitz
62e3949c65 Publish
- @now/build-utils@0.9.14
 - @now/cgi@0.1.5
 - now@16.1.3
 - now-client@5.1.1
 - @now/go@0.5.11
 - @now/next@0.7.1
 - @now/node-bridge@1.2.4
 - @now/node@0.12.8
 - @now/python@0.2.17
 - @now/routing-utils@1.2.3
 - @now/ruby@0.1.5
 - @now/static-build@0.9.9
2019-09-02 22:15:34 +02:00
Sophearak Tha
c191861639 [now-go] Fix analyze.go fails to parse source file with comments (#2911)
* Fix `analyze.go` fails to parse source file with comments

* Add more tests

* Improve fallback

* Improve check for http.HandlerFunc signature`
2019-09-02 21:28:17 +02:00
Joe Haddad
c820509c29 [now-build-utils] Add mutable option for backwards compatibility (#2895) 2019-09-02 21:26:30 +02:00
Andy
199f98153f [now-static-build] Support ejected create-react-app (#2873) 2019-09-02 21:22:38 +02:00
Andy
a64b96f87b [now-cli] Improve check for update command (#2915)
* [now-cli] Improve check for update command

* Use path.sep

* Fix build
2019-09-02 17:50:37 +02:00
Max Strübing
f179864986 [now-cli] Use XDG standard instead of writing to home directory (#2877)
* Use XDG standard instead of writing to home directory

* Fix typos

* Use dependencies as dev dependencies

* Remove lodash dependency

* Use xdg-app-paths instead of xdg-portable

* use find instead of filter(...)[0]
2019-09-02 17:50:29 +02:00
Steven
73af1b3d91 [now-cli] Update readme and links (#2886)
* Update readme and links

* Fix readme image

* Fix homepage

* Update banner image to v3
2019-09-02 17:50:17 +02:00
Nathan Rajlich
56afa1b464 [now-cli] Implement continue: true with dest (#2908)
Closes #2685.
2019-09-02 17:50:06 +02:00
Nathan Rajlich
0e0f453e4e [now-cli] Use a Map for the valid sub-commands (#2913)
Otherwise, JavaScript Object built-ins such as `hasOwnProperty` are
incorrectly considered a valid subcommand, but fail afterwards with
a `require()` error and confusing error message.
2019-09-02 17:49:59 +02:00
Naoyuki Kanezawa
78d25d97fb [now-cli] fix login test (#2909) 2019-09-02 17:49:52 +02:00
Andy
d6ce0e4c23 [now-cli] Allow to fetch more certificates with paging (#2905)
* [now-cli] Allow to fetch more certificates with paging

* Linting

* Update packages/now-cli/src/commands/certs/ls.js

Co-Authored-By: Nathan Rajlich <n@n8.io>
2019-09-02 17:49:40 +02:00
Andy
434de228cc [now-cli] Validate inputs for alias, list and remove (#2903)
* [now-cli] Validate inputs for alias, list and remove

* Log test output

* Add more logging to test

* Change to execa

* Use `split`

* Only validate when it exists
2019-09-02 17:49:34 +02:00
Andy
d75b0c9578 [now-cli] Change success message after login (#2898)
* [now-cli] Change success message after login

* Linting

* Test now login

* Linting

* Revert "Test now login"

This reverts commit 690360db3f148552a456b4ee1bd2a59b8d09216c.

* Revert "Linting"

This reverts commit 3d5ebfaa76ecdcc2152c8344c8e1205b241abe09.

* Adjust test

* Remove binaryPath from args

* Fix loggin test
2019-09-02 17:49:26 +02:00
Kaito Sugimoto
16e24e8464 [now-cli] Update now alias warning for --prod (#2902) 2019-09-02 17:49:19 +02:00
Andy
8365d7c4de [now alias] Improve alias support (#2787)
This enables https://github.com/zeit/now-cli/pull/2747 from @nkzawa again.

We had to revert the previous one, because we didn't want to include it in
the next stable release.

This further makes sure that we don't display `https://` in front of a
wildcard alias, since `https://*.mydomain.tld` is not a valid URL.
2019-09-02 17:49:09 +02:00
Steven
a958492256 Add GH Actions Publish Workflow (#2891) 2019-09-02 17:49:01 +02:00
Andy
6285ac589d [now-cli] Validate builds and routes for now dev (#2871)
* [now-cli] Validate builds and routes for `now dev`

* Remove @ts-ignore

* Sort the matches such that `utils` modules are compiled first

Because other packages may rely on them

* Prettier

* Add `reject: false` to tests

* Prettier

* Make validation async

* Fix syntax

* Fix type

* Linting

* Fix error check
2019-09-02 17:47:54 +02:00
Sophearak Tha
2ac87b0144 [now-cli] Make sure to have event action as string (#2870) 2019-09-02 17:47:49 +02:00
Nathan Rajlich
21fd1761ae [now dev] Update yarn to v1.17.3 (#2780)
* [now dev] Update `yarn` to v1.17.3

* Wait longer for angular integration test

It keeps on failing

* Only run angular test on Node 10.x

* Revert "Wait longer for angular integration test"

This reverts commit 19d70d4ba9aee49a5114b65f00ef97e2a88dc7ef.
2019-09-02 17:47:42 +02:00
Steven
3664a2da8b [tests] Fix unit tests & coverage step (#2876)
* Fix unit tests & coverage

* Add missing compile-templates step
2019-09-02 17:47:33 +02:00
Nathan Rajlich
8a6f3c61bb Update links to now-builders repo to now repo (#2862)
* Update links to `now-builders` repo to `now` repo

Also copies over the `.md` files from the now-builders' `errors`
directory so that the https://err.sh links work correctly.

Part of #2782.

* Update `err.sh` links that were formerly `now-cli`

* Empty commit for CI

* Make CircleCI `run.sh` script a bit better

Before it would fail with exit code 1 if there were no matching modified
files because of the `grep` call failing without any `packages` prefixed
files.
2019-09-02 17:47:26 +02:00
Steven
f5f7dd9e8a [tests] Change run script from bash to node (#2874)
* [tests] Change run script from bash to node

* Fix loop for runScript

* Fix `all` script test

* Improve console.log() messages

* Use -l instead of -p

* Delete yarn.lock from now-python
2019-09-02 17:47:17 +02:00
Steven
b0ad5238f7 Create monorepo (#2812)
* Move now-cli to /packages/now-cli

* Fix .gitignore paths

* Add now-client

* Add lerna to top level

* Add scripts

* Update codeowners

* Fix `/now-cli/build.ts` script

* Fix circleci path to artifacts

* Use relative paths

* Fix path to scripts

* Add test-lint script

* Add missing return type

* Fix typo in test-lint

* Fix string match in shell scripts

* Fix path to hugo

* Add package node_modules

* Delete lock files in packages, use root yarn.lock

* Add missing b.js file

* Add test-integration-now-dev script

* Add missing test files

* Add missing integration test script

* Add missing test files

* Delete travis.yml

* Fix ts-jest in now-client

* Add support for Node 8 (ES2015 target)

* Add support for Node 8

* Add polyfill for Node 8

* Fix polyfill for Node 8

* Only run coverage for now-cli

* Add packages from now-builders

* Run integration tests for builders

* Add node_modules to cache

* Add root readme.md

* Move readme to top level

* Add yarn bootstrap

* Add bootstrap step

* Add dist to `persist_to_workspace`

* Fix 08-yarn-npm integration test

* Remove duplicate path

* Change stdio to inherit

* Add back store_artifacts

* testing - remove bootstrap step

* Add back now-build-utils

* Remove bootstrap step

* Fix test again

* Add console.log()

* Fix lint

* Use local ncc version

* Install go

* Revert changes to stdio and console.log()

* Add missing now-go test

* Add missing integration tests

* Add --runInBand flag

* Fix now-node-bridge persistence

* Add missing symlinks

* Add codeowners

* Consolidate into single run.sh function

* Run uniq

* Fix typo

* Change now-routing-utils to test-unit

* Special case test for node 8

* Add docs from builders

* Only run script for modified packages

* Add test-integration-once which only runs once

* Fix set intersection
2019-08-23 23:57:00 +00:00
Andy Bitz
774e0a0ebb 16.1.2 2019-08-20 22:20:01 +02:00
Andy
ec7a258b37 Use short-form for the update command (#2801)
* Use short-form for the update command

* Adjust test
2019-08-20 19:48:33 +02:00
Andy
5fbe136485 [now deploy] Fix builds output for failed deployments (#2799)
* [now deploy] Fix builds output for failed deployments

* Add test
2019-08-20 18:14:11 +02:00
Andy
e6c56a69ce [now deploy] Fix --prod flag and adjust message for --target (#2797)
* [now deploy] Fix `--prod` flag and adjust message for `--target`

* Fix tests

* Fix fetch

* Change api version

* Fix url

* Fix test
2019-08-20 18:01:44 +02:00
Andy
d93c76d5e6 [now deploy] Added --prod flag (#2789)
* [now deploy] Add `--production` and `--staging` flag

* Change message

* Fix tests

* Fix test

* Add another test

* Fix production test

* Update message and add `--prod`

* Update help

* Remove `--staging`

* Use only `--prod`

* Add test

* Add aliasError output

* Fix output
2019-08-20 10:02:41 +02:00
Andy
e0814d6ed5 Bump @now/build-utils to 0.9.13 (#2784) 2019-08-20 10:02:32 +02:00
Nathan Rajlich
5e6a241baa [now domain] Handle thrown API errors when purchasing domain fails (#2779)
Fixes #2759.
2019-08-20 10:02:23 +02:00
Nathan Rajlich
8cbebc936e Remove a couple unused import (#2777)
Fixes lint
2019-08-20 10:02:16 +02:00
Nathan Rajlich
90f7f8620c Sleep 2 seconds after the now rm integration test (#2776)
Sometimes it fails with a stale 200 status code.
This should make it less flaky.
2019-08-20 10:02:04 +02:00
Nathan Rajlich
59bbe7e0c9 Display rate limit errors message from API response (#2767)
* Display rate limit errors message from API response

Closes #2738.

* Update src/util/handle-error.ts

Co-Authored-By: Steven <steven@ceriously.com>
2019-08-20 10:01:57 +02:00
Naoyuki Kanezawa
151b66a3f9 add misssing defaultArgs (#2770) 2019-08-20 10:01:48 +02:00
Nathan Rajlich
d9f3367a77 Remove leftover console.log() in integration tests (#2768) 2019-08-20 10:01:42 +02:00
Nathan Rajlich
f3f6880632 [now rm] Use the proper client so that the process does not hang (#2762)
* [now rm] Use the proper `client` so that the process does not hang

The crux of this fix is that `getDeploymentByIdOrHost()` and
`getProjectByIdOrName()` were improperly being passed the `Now`
instance instead of the expected `Client` instance, and for some
reason that would cause the process to hang until the underlying
`http.Agent` timed out its connection to the API server.

Also ran `prettier` on this file.

Fixes #2760.

* Remove `console.error()`

* Add integration test

* Fix syntax error

* Add `now rm` 404 integration test

* Remove `.only`
2019-08-20 10:01:35 +02:00
Nathan Rajlich
59335cdd81 [now scale] Fix default max: auto value in --help output (#2763)
Fixes #2368.
Also related to zeit/docs#838.
2019-08-20 10:01:24 +02:00
Nathan Rajlich
a93c09a794 Fix "occured" -> "occurred" typos (#2761)
See: https://tinyurl.com/occured
2019-08-20 10:01:16 +02:00
Andy
b60768a8b3 [now dev] Use canary builders for the canary version (#2753)
* Use canary builders for the canary version

* Use the `getDistTag` function instead

* Fix function call

* Add tests

* Remove unused code

* Remove logging
2019-08-20 10:01:05 +02:00
Nathan Rajlich
da96ead170 Use the correct URL in the auth.json and config.json files (#2755)
Fixes #2754.
2019-08-20 10:00:55 +02:00
Nathan Rajlich
45f7dc126c [now projects] Add subcommand alias for now project (#2750)
Fixes #2162.
2019-08-20 10:00:46 +02:00
Naoyuki Kanezawa
7d41511564 remove unused HTTP/HTTPS Agent (#2749) 2019-08-20 10:00:38 +02:00
Naoyuki Kanezawa
a4e184007d support to set api host for development (#2748) 2019-08-20 10:00:30 +02:00
Nathan Rajlich
2055eb32b8 Update clipboardy to v2.1.0 (#2737)
Fixes #564.

Related to #1924.
2019-08-20 10:00:21 +02:00
Andy
3ae3cbf34b Bump @now/build-utils to 0.9.12 (#2736) 2019-08-20 10:00:14 +02:00
Nathan Rajlich
56d4a75d39 [now dev] Remove leftover console.error() call (#2735)
Accidentally added in #2720.
2019-08-20 10:00:03 +02:00
Leo Lamprecht
c86a9217c4 [now dev] Add --listen / -l flag, deprecate --port / -p (#2720)
* [now dev] Add `--bind` / `-b` flag

This changes the default network interface that `now dev` binds to, in
order to prevent operating system firewalls from showing a confirmation
prompt in order to run.

Fixes #2704.

* Change to `--listen`

* Default port 3000

* Fix unit

* Fix `--port`

* Use `-l` for integration tests

* Add unit tests
2019-08-20 09:59:54 +02:00
Arunoda Susiripala
dc7c6166e3 Update index.js (#2733) 2019-08-20 09:59:47 +02:00
Leo Lamprecht
25facf4934 [now update] Show correct global or local install command (#2719)
* [now update] Show correct global or local install command

* Remove `canRead` check

* Change bin to lib since the actual script will be there

* Use realpath

* Remove console.error
2019-08-20 09:59:39 +02:00
Nathan Rajlich
7f0ce26472 Update serve-handler to v6.1.1 (#2731)
* Update `serve-handler` to v6.1.1

Fixes #2697.

* Fix unit test
2019-08-20 09:59:29 +02:00
Nathan Rajlich
031067869a Print HTTP status code upon API JSON parse errors (#2727)
Fixes #2681.
2019-08-20 09:59:16 +02:00
Nathan Rajlich
2e30bbef7e Add accept: application/json header to API HTTP requests (#2726)
All of the APIs already support JSON by default, so this is a no-op for
our APIs, however the proxy layer _does_ respect the `Accept` header to
send JSON error responses, which is useful for more gracefully handling
outage responses (previously they were being returned as plain text,
which Now CLI blindfully tries to parse as JSON and fails with an
unhelpful error message).

Related to #2681.
2019-08-20 09:58:47 +02:00
Steven
13d04a069e Add automerge config (#2729) 2019-08-20 09:58:40 +02:00
Nathan Rajlich
26b3d36101 [CircleCI] Fix test/dev-server.unit.js being run on CI (#2725)
For some reason, `ava` was silently skipping these tests on CI because
the process was crashing. According to sindre, this is a bug in `ava`,
but with some digging I was able to determine that the root cause of the
crash was that the `builders.tar.gz` file from the `assets` dir was not
being persisted from the previous `build` job in CI.

With the `assets` dir being persisted I now see the `dev-server` unit
tests being executed once again as expected.

Related to: https://twitter.com/sindresorhus/status/1157614353375551493
2019-08-20 09:58:32 +02:00
wtgtybhertgeghgtwtg
3db861fcc4 Remove vestigial mkdirp packages (#2724) 2019-08-20 09:58:24 +02:00
Andy Bitz
df580d4873 16.1.1 2019-08-07 17:33:41 +02:00
Andy
78567ff89b [now deploy] Use the project when checking the platform version (#2722)
* [now deploy] Use the project when checking the platform version

* Update src/util/prefer-v2-deployment.ts

Co-Authored-By: Leo Lamprecht <mindrun@icloud.com>

* Update src/util/prefer-v2-deployment.ts

Co-Authored-By: Leo Lamprecht <mindrun@icloud.com>

* Adjust message

* Fallback for local config
2019-08-07 17:33:24 +02:00
Andy
605a9f68e7 Fix colored text and remove version warning (#2721) 2019-08-07 14:37:28 +02:00
Andy Bitz
4e4bc98194 16.1.0 2019-08-07 12:41:04 +02:00
Andy
3efa988f5e [now dev] Bump @now/build-utils to 0.9.10 (#2715) 2019-08-07 12:25:09 +02:00
Andy
d3366403fe Bump @now/build-utils to 0.9.9 (#2713)
* Bump `@now/build-utils` to 0.9.9

* Log output

* Only log on error

* Fix tests
2019-08-07 12:24:43 +02:00
Nathan Rajlich
5860645cdb Require Node.js >= 8.11 in "engines" (#2714)
Closes #2711.
2019-08-07 12:24:35 +02:00
Nathan Rajlich
3ff2004929 [now dev] Print warning upon empty cwd directory (#2702)
* [now dev] Render warning upon empty `cwd` directory

The warning matches the one that `now deploy` prints, and only
prints the warning once (rather then upon every HTTP request).

Closes #2696.

* Fix eslint warning

* Add "pipe"

* Debugging…

* Fix integration test

* Debugging…

* Add `--verbose` to "test-integration-now-dev" script

* Ignore `yarn.lock` and `node_modules` in test dir

* Ignore `hugo` binary

* Ignore `public` dir in hugo test fixture

* Add `.gitignore` to `empty` test fixture

* Revert "Debugging…"

This reverts commit 27c6d2e06fe7eff12077a0e88915cf46b39b00ea.

* Ignore `public` / `dist` dirs in fixtures
2019-08-07 12:24:26 +02:00
Nathan Rajlich
9a38260a2b Add unhandledRejection and uncaughtException handlers to scripts (#2709)
This is to prevent false-positives like this from occurring,
and fixes the warning from `node`:

```
$ ts-node ./scripts/build.ts
Creating builders tarball with: @now/build-utils@canary, @now/go@canary, @now/next@canary, @now/node@canary, @now/php@canary, @now/static-build@canary
(node:156) UnhandledPromiseRejectionWarning: Error: ENOENT: no such file or directory, open '/home/circleci/repo/assets/builders.tar.gz'
    at ReadStream.evt.error.err (/home/circleci/repo/node_modules/promisepipe/index.js:30:23)
    at ReadStream.emit (events.js:198:13)
    at ReadStream.EventEmitter.emit (domain.js:448:20)
    at /home/circleci/repo/node_modules/graceful-fs/graceful-fs.js:207:14
    at /home/circleci/repo/node_modules/graceful-fs/graceful-fs.js:258:16
    at FSReqWrap.args [as oncomplete] (fs.js:140:20)
(node:156) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:156) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
```
2019-08-07 12:24:18 +02:00
Nathan Rajlich
96fca45a41 Fix format-modified script (#2708)
Before it was only updating _non-staged_ files.

Now, it updates _all_ modified files, staged or not.
2019-08-07 12:24:11 +02:00
Nathan Rajlich
cb106185cb Upgrade ava to v2.2.0 (#2703)
See: https://twitter.com/sindresorhus/status/1157614353375551493
2019-08-07 12:24:01 +02:00
Andy
cd6d98b314 [now deploy] Change the warning messages when the platform version is changed (#2717)
* [now deploy] Change warning message

* Change text

* Add link to message

* Change text
2019-08-07 12:11:32 +02:00
Andy Bitz
0aa8fa09cb [now deploy] Check server.js file when detecting the platform version (#2664)
This reverts commit 3e5ddad5ca.
2019-08-07 12:10:59 +02:00
Andy Bitz
d71f74fa54 [now deploy] Consider --npm and --docker for platform detection (#2640)
This reverts commit 79e0792a57.
2019-08-07 12:10:53 +02:00
Andy Bitz
47ce713a86 [now deploy] Determine platform version through Dockerfile and package.json (#2633)
This reverts commit 8da0534d4f.
2019-08-07 12:10:42 +02:00
Andy Bitz
3c5b94855a [now deploy] Check if builds are ready right away (#2699)
This reverts commit 92cff5c947.
2019-08-07 12:08:43 +02:00
Andy Bitz
0fb6c77dec 16.0.0 2019-08-05 19:58:37 +02:00
Andy Bitz
8da0534d4f Revert "[now deploy] Determine platform version through Dockerfile and package.json (#2633)"
This reverts commit 9244e43ccf.
2019-08-05 18:49:51 +02:00
Andy Bitz
79e0792a57 Revert "[now deploy] Consider --npm and --docker for platform detection (#2640)"
This reverts commit 69e7c57975.
2019-08-05 18:49:12 +02:00
Andy Bitz
3e5ddad5ca Revert "[now deploy] Check server.js file when detecting the platform version (#2664)"
This reverts commit 482ca7a8a6.
2019-08-05 18:44:38 +02:00
Andy Bitz
92cff5c947 Revert "[now deploy] Check if builds are ready right away (#2699)"
This reverts commit 2877563064.
2019-08-05 18:43:26 +02:00
Andy
4f8cf6793b [now update] Remove is-installed-globally (#2700)
* [now update] Remove `is-installed-globally`

* Only suggest global

* Adjust test
2019-08-05 18:40:41 +02:00
Andy
2877563064 [now deploy] Check if builds are ready right away (#2699)
* [now deploy] Check if builds are ready right away

* Adjust tests

* Remove test

* Log more while testing

* Remove check in tests

* Adjust all tests

* Log more
2019-08-05 18:40:34 +02:00
Andy
dea74233c6 Update @now/build-utils to v0.9.8 (#2694)
* Bump `@now/build-utils` to 0.9.7

* Handle 404 status

* Revert "Handle 404 status"

This reverts commit 6aa25097beb96c8d56ab40c91319278da68d5851.

* Render 404 page

* Bump @now/build-utils
2019-08-05 18:40:28 +02:00
Nathan Rajlich
4fbd75f384 Assert 200 response status on "deploy a dockerfile project" integration test (#2684)
* Assert 200 response status on "deploy a dockerfile project" integration test

* Fix
2019-08-05 18:40:22 +02:00
Nathan Rajlich
21bd8297e0 [now dev] Support JSON and HTML redirect responses (#2690)
* [now dev] Support JSON and HTML redirect responses

Matches the production behavior.

* Set Now response headers during redirect

* Set `location` header

* Remove unused `matched_route` var
2019-08-05 18:40:16 +02:00
Nathan Rajlich
188150da26 [now dev] Allow custom 404 pages via routes (#2689)
* [now dev] Allow custom 404 pages via `routes`

This matches the behavior in production, which allows a `dest` to be
provided when defining a `status: 404` in the routes configuration.

Related to #2638.

* Fix typo
2019-08-05 18:40:08 +02:00
Andy
83d50374ff [preinstall/now update] Check if now is installed locally (#2688)
* [preinstall/now update] Check if now is installed locally and adjust messages

* Adjust test

* Add tests

* Wait for deployment to be ready

* Removed log

* Adjust prefix in test

* Adjust path

* Only wait 4 minutes

* More logging

* Change binPrefix to prefix

* Remove all linting warnings

* Adjust env vars for test

* Don't test on node 8

* Log more error information and fail right after 500

* Move docker test up
2019-08-05 18:40:00 +02:00
Nathan Rajlich
2b3d4cd449 Fix routes definition in now-dev-static-routes test fixture (#2687)
This is the proper way to define this route because of the capture of
the initial `/`.

Matches how it works in production.
2019-08-05 18:39:52 +02:00
Nathan Rajlich
0ef680484d [now dev] Support JSON and HTML error responses (#2677)
* [now dev] Support JSON and HTML error responses

Closes #2609.

* Compile templates for unit tests in CircleCI

* Update `ts-node` to v8.3.0

* Convert doT.js compiled templates to TypeScript

* Compile templates for lint tests in CircleCI

* Print convert time

* Add 502 error template

* Remove `message` param from `sendError()`

* Prettier

* Add 404 tests

* Fix test
2019-08-05 18:39:47 +02:00
Andy
54ee476f91 [preinstall] Adjust the error messages (#2682)
* [preinstall] Adjust the error messages

* Remove dot
2019-08-05 18:39:40 +02:00
Nathan Rajlich
4d81ee8c87 [now dev] Use a consistent "pod id" for x-now-id (#2679)
This matches the behavior in production.
2019-08-05 18:39:34 +02:00
Andy
33cd5d6c1d [now deploy] Change link for legacy warning (#2674)
* [now deploy] Change link for legacy warning

* Remove trailing slash

Co-Authored-By: Steven <steven@ceriously.com>

* Simplify `link` function

Co-Authored-By: Nathan Rajlich <n@n8.io>

* Determine which link to show and add test

* Adjust link for configuration

Co-Authored-By: Steven <steven@ceriously.com>

* Adjust Package type
2019-08-05 18:39:28 +02:00
Andy
24525ec768 [now dev] Bump @now/build-utils to 0.9.6 (#2672) 2019-08-05 18:39:19 +02:00
Andy
482ca7a8a6 [now deploy] Check server.js file when detecting the platform version (#2664)
* [now deploy] Check `server.js` file when detecting the platform version

* Fix type
2019-08-05 18:39:11 +02:00
dependabot[bot]
e8c81fbd81 Bump yarn to v1.17.3 (#2669)
Bumps [yarn](https://github.com/yarnpkg/yarn) from 1.13.0 to 1.17.3.
- [Release notes](https://github.com/yarnpkg/yarn/releases)
- [Changelog](https://github.com/yarnpkg/yarn/blob/v1.17.3/CHANGELOG.md)
- [Commits](https://github.com/yarnpkg/yarn/compare/v1.13.0...v1.17.3)

Signed-off-by: dependabot[bot] <support@github.com>
2019-08-05 18:39:05 +02:00
Andy
6322be2bf7 [CircleCI] Add more test suites for macOS support (#2663)
* [CircleCI] Add more tests for macos support

* Change xcode version since node 8.9.x is required

* Log stderr and stdout

* Add custom start script

* Make tests use custom start script

* Made start script executable

* Use correct node path

* Fix script path

* Handle status code

* Use latest Node.js version for macos tests

* Include yarn.lock for ember test

* Only use start script in tests

* Change start script for macos

* Change start script for linux

* Change start script for linux
2019-08-05 18:38:59 +02:00
Sophearak Tha
88a0fb2009 [now dev] Update NOW_BUILDER_DEBUG base on --debug flag (#2655)
* Update `NOW_BUILDER_DEBUG` base on `--debug` flag

* No need to reset `NOW_BUILDER_DEBUG`

* Add comment for `NOW_BUILDER_DEBUG`

* Apply suggestions from code review

Co-Authored-By: Andy <AndyBitz@users.noreply.github.com>
2019-08-05 18:38:52 +02:00
Nathan Rajlich
ba007f89ff [now dev] Bundle canary builders for Now CLI canary (#2661)
* [now dev] Bundle `canary` builders for Now CLI canary

Closes #2641.

* Add unit tests

* More unit tests

* Use `semver.parse()` in `getDistTag()`

* Convert build script to TypeScript, DRY the `getDistTag()` function

* Prettier
2019-08-05 18:38:45 +02:00
Andy
00129ea452 [now dev] Update outdated dependencies in tests (#2666) 2019-08-05 18:38:38 +02:00
Nathan Rajlich
924b0ff427 [CircleCI] Add seperate jobs for now dev integration tests (#2662)
Run the `now dev` integration tests in parallel with the "standard"
integration tests, since they both take a long time. This should
cut the CI testing time in about half.
2019-08-05 18:38:30 +02:00
Andy
70571d10c1 [now dev] Fix aurelia test (#2660)
* [now dev] Fix aurelia test

* Enable aurelia test again
2019-08-05 18:38:21 +02:00
Nathan Rajlich
aee22a3d38 Support Node 8 (#2648)
* Support Node 8

This changes the TypeScript compilation target to "es2015" so that
async generator functions are transpiled, which enables Node 8 to be
supported.

As a side-effect, any of the files that utilize `async function*` or
`for await` needed to be converted to TypeScript so that the
transpilation actually happens.

It was painful to do this process for `src/commands/deploy/legacy.ts`,
and since it is legacy code I did not want to make too many changes to
the code, so there's a log of `@ts-ignore` and `any` types being used.
But the behavior of the file should not have changed at all.

* Make `engines` field be ">= 8"

* Add Node 8 to CircleCI matrix

* Remove `console.error()`

* Remove `.ts` extension on import calls

* Use `Now` instead of `any`

* Use native `url` module instead of `whatwg-url`

* Debug integration test

* Skip `02-angular-node` test on Node 8

* Remove debugging

* Add "Downloading Hugo" step to Node 8 tests

* Skip `03-aurelia` test on Node 8

* Skip `03-aurelia` test for all

All node versions are failing with the same error:

https://circleci.com/gh/zeit/now-cli/29922

* Use `fs-extra` instead of `fs.promises` for Node 8
2019-08-05 18:38:13 +02:00
Andy
81162c0ccf [now update] Change update notification and remove previous Now CLI installation on preinstall (#2659)
* [now update] Change update notification and remove previous Now CLI installation on `preinstall`

* Use plain js for preinstall script

* Removed unused `rename` import

* Simplified code
2019-08-05 18:38:05 +02:00
Andy
69e7c57975 [now deploy] Consider --npm and --docker for platform detection (#2640)
* [now deploy] Consider `--npm` and `--docker` for platform detection

* Change order

* Change prepare

* Await fixtures

* Remove check

* Revert "Remove check"

This reverts commit 7a5c1c901085d4e22c5a34cc48b5d929a9ee3b80.

* Use async-retry

* Fix fetch

* Log token

* Retry user creation

* Add async

* Add try-catch

* Decrease the retries

* Use original way to get context name
2019-08-05 18:37:58 +02:00
Nathan Rajlich
4e796ca952 [now dev] Redirect when request has multiple slashes (#2645)
* [now dev] Redirect when request has multiple slashes

Closes #2642.

* Add POST passthrough
2019-08-05 18:37:53 +02:00
Max Chehab
518d0313f7 [now deploy] Fix variable name typo (#2649) 2019-08-05 18:37:47 +02:00
Andy
6ea080d48b [now dev] Prevent recursive function call for handle: "filesystem" (#2630)
* [now dev] Prevent recursive function call for `handle: "filesystem"`

* Add test

* Update test/dev/integration.js

Co-Authored-By: Nathan Rajlich <n@n8.io>

* Handle recursive `serveProjectAsNowV2` call

* Fix test
2019-08-05 18:37:33 +02:00
Sophearak Tha
748e34757e [now dev] Improve integration tests for now dev (#2597)
* Using `stdio` to resolve `now dev` Ready

* Update test/dev/integration.js

Co-Authored-By: Andy <AndyBitz@users.noreply.github.com>

* Improve `testFixtureStdio` and update aurelia fixture

* Remove duplicate test

* Update `create-react-app` and `gatsby` test fixture

* Update `gridsome` test fixture

* Update `hugo` test fixture

* Update `jekyll` test fixture

* Add `marko` test fixture

* Add `mithril` test fixture

* Add `riot` test fixture

* Add `charge` test fixture

* Add `brunch` test fixture

* Add `docusaurus` and `ember` test fixtures

* Install ruby for `jekyll`

* Update base on platform for `jekyll` and `hugo`

* Use `sudo` to when installing `gem`

* Remove `09-jekyll`

* Extract the right filename

* Remove `-L` flag from `curl` for macOS

* Use different version of `hugo`

* Remove `min_version` from `08-hugo` theme
2019-08-05 18:37:26 +02:00
Nathan Rajlich
c93c458cd4 [CircleCI] Run integration tests on multiple versions of Node.js (#2596)
* [CircleCI] Run integration tests on multiple versions of Node.js

* Test Node 10 and Node 12

* Remove `fs.promises` usage for Node 8

* More `fs.promises` removal

* Remove Node 8, it is unsupported due to `async` function usage
2019-08-05 18:36:05 +02:00
Nathan Rajlich
3c10787621 [now dev] Add server: now response header (#2646)
Matches production.
2019-08-05 18:31:23 +02:00
Nathan Rajlich
f60a9f0c58 Add information when team/user/args parsing fails to Sentry reports (#2635)
* Add information when team/user/args parsing fails to Sentry reports

This should give us some insight into #2627.

* Add `node` reporting
2019-08-05 18:31:17 +02:00
Nathan Rajlich
544d26dea9 [now dev] Remove accidental test.only() (#2644)
This got committed by accident :(
2019-08-05 18:31:11 +02:00
Andy
9244e43ccf [now deploy] Determine platform version through Dockerfile and package.json (#2633)
* [now deploy] Determine platform version through `Dockerfile` and
`packge.json`

* Update src/commands/deploy/index.js

Co-Authored-By: Nathan Rajlich <n@n8.io>

* Change notification, add tests, consider `type`

* Change test

* Adjust test

* Adjust test

* Update src/util/prefer-v2-deployment.ts

Co-Authored-By: Nathan Rajlich <n@n8.io>
2019-08-05 18:31:06 +02:00
Nathan Rajlich
d44b147684 Remove leftover references to pkg (#2632)
* Remove leftover references to `pkg`

We are no longer compiling `now-cli` with `pkg` so this is dead code.

* Enable source maps
2019-08-05 18:30:59 +02:00
Andy
bb5fbc28a0 [now dev] Clean up before calling process.exit (#2629)
* [now dev] Clean up before calling `process.exit`

* Log error

* Update src/util/dev/server.ts

Co-Authored-By: Steven <steven@ceriously.com>
2019-08-05 18:30:53 +02:00
Nathan Rajlich
3a501a0c08 [now dev] Fix routing catch-all with no slash prefix edge case (#2626)
Fixes #2622.
2019-08-05 18:30:47 +02:00
Sophearak Tha
1fe5dbd7cd Remove Buffer() deprecation message (#2604)
* Remove `Buffer()` deprecation message

* Switch `micro` back to `9.1.2`
2019-08-05 18:13:18 +02:00
Nathan Rajlich
7a97a40039 Add "engines" field to package.json for Node 10 or newer (#2603)
`now-cli` does not work on Node 8 and below because generator
functions are not supported.
2019-08-05 18:12:44 +02:00
Nathan Rajlich
cda6a2cbb6 [now update] Render the proper tag and improve yarn detection logic (#2595)
* [now update] Render the proper tag and improve `yarn` detection logic

Before this the suggested command would always have you install the
stable version of `now`.

With this change the `@canary` tag will be suggested if the version of
`now` is from the canary release channel.

Also updates the `isYarn` detection logic to not consider the cwd, and
instead check the installed version of now's `package.json` for clues.

* Move `getUpdateCommand` to util

* Add a unit test

* Use integration test instead
2019-08-05 18:11:49 +02:00
Sophearak Tha
50a87c4965 Remove pkg bundling (#2567)
* Remove `pkg` bundling

* Remove `(dev)` from `--version`

* Remove `test/dev-builder.unit.js`

* Temporary disable `update now to canary test`

* Update `now update` command

* Removed useless jobs

* Removed useless code

* Removed more useless code

* Use update command

* Only run publish upon tag

* Removed code

* No need bin, use dist directly

* Update test, using the right file

* Reslove `iconv-lite@0.5.0` version

* Removed useless file

* Added scripts directory

* Removed useless stuff

* Fixed build script

* Fix `now dev` integration test

* Also block coverage on linting
2019-08-05 18:10:57 +02:00
Andy Bitz
f6552c48d6 15.8.7 2019-07-26 13:40:40 +02:00
Andy Bitz
577cd76ae6 Revert "Add "engines" field to package.json for Node 10 or newer (#2603)"
This reverts commit 91a1a4828a.
2019-07-26 10:45:55 +02:00
Andy Bitz
bed4efeef0 15.8.6 2019-07-25 17:26:59 +02:00
Andy Bitz
53f0adb88a Revert "[now update] Render the proper tag and improve yarn detection logic (#2595)"
This reverts commit 4ceb4c8984.
2019-07-25 17:06:27 +02:00
Nathan Rajlich
61c82890c1 [now deploy] Respect --debug flag for API Client (#2625)
While debugging #2606, I noticed that the `Client` instances for
`now deploy` were not being supplied the appropriate `debug` flag
based on the command line args.
2019-07-25 14:03:52 +02:00
Steven
176a750ece [now init] Download /v1 examples without suggestions (#2623) 2019-07-25 14:03:41 +02:00
Nathan Rajlich
88cdcdf979 [now deploy] Change "Aliases assigned" to "Deployment complete" (#2620)
* [now deploy] Change "Aliases assigned" to "Deployment complete"

Closes #2617.

* Change instances of "Aliased" to "Deployed"
2019-07-25 14:03:30 +02:00
Andy
bf12602aca [now dev] Bump @now/build-utils to 0.9.4 (#2621) 2019-07-25 14:03:23 +02:00
Nathan Rajlich
bafb14526d [now dev] Fix creating duplicate blocking builds upon bootup (#2618)
PR #2562 caused an issue with blocking builds at bootup being built
twice, which is problematic when i.e. running `yarn` simultaneously
on the same directory causing cache corruption issues.
2019-07-25 14:03:16 +02:00
Nathan Rajlich
778b77e829 [now dev] Remove useless debug() call (#2619)
The `getNowConfig(false)` used to be within this `if` branch, so the
debug call made sense there at the time, but as of zero config it got
moved to always be invoked, so this `debug()` call doesn't make sense
anymore.
2019-07-25 14:03:07 +02:00
Nathan Rajlich
91a1a4828a Add "engines" field to package.json for Node 10 or newer (#2603)
`now-cli` does not work on Node 8 and below because generator
functions are not supported.
2019-07-25 14:00:16 +02:00
Andy
5a187b97ab Use fs-extra instead of fs.promises to prevent warnings on Node 10 (#2602) 2019-07-25 14:00:04 +02:00
Nathan Rajlich
d78cd371ed [now dev] Wait for blocking builds to complete before handling requests (#2562)
* [now dev] Wait for blocking builds to complete before handling requests

After the `now dev` server has already booted, if you delete a build
match that previously required a build at bootup time (i.e. `@now/next`)
from the `builds` array in `now.json` (i.e. change the builder to
`@now/static`), and then change it back to `@now/next`, then previously
the build would never execute.

With this change, the blocking build occurs as expected, and any HTTP
requests that occur are blocked until that build has completed.

* Prettier

* Better diff

* Add test
2019-07-25 13:59:20 +02:00
Nathan Rajlich
a720d5b181 [now dev] Add warning when there are no build matches (#2594)
* [now dev] Add warning when there are no build matches

This matches the error in production, except it's just a non-fatal
warning when running in `now dev`. This is so that the user can fix
the warning without having to restart the `now dev` server.

* Add integration test
2019-07-25 13:59:09 +02:00
Andy
dd50eae762 [now update] Don't check for updates on now update (#2599) 2019-07-25 13:58:59 +02:00
Nathan Rajlich
4ceb4c8984 [now update] Render the proper tag and improve yarn detection logic (#2595)
* [now update] Render the proper tag and improve `yarn` detection logic

Before this the suggested command would always have you install the
stable version of `now`.

With this change the `@canary` tag will be suggested if the version of
`now` is from the canary release channel.

Also updates the `isYarn` detection logic to not consider the cwd, and
instead check the installed version of now's `package.json` for clues.

* Move `getUpdateCommand` to util

* Add a unit test

* Use integration test instead
2019-07-25 13:58:53 +02:00
Andy
f9c262f4bb [now dev] Fix directory listing race condition (#2591)
* [now dev] Fix directory listing race condition

* Resolve file names

* Check only matched files

* Log stdout and stderr

* Log expected

* Change test

* Revert "Change test"

This reverts commit 149723be0f2015bd400dd5f2d5cce523303a05cf.

* Add timeout to request

* Adjust retries

* Don't use unref

* Remove tests

* Revert "Remove tests"

This reverts commit 6159d657bfa978719ffb23153058b791b2ce8a2a.

* Adjusted test

* Make sure directory exists

* Fix tests

* Add yarn.lock

* Adjust timeout
2019-07-25 13:58:43 +02:00
Andy
57d9c6e39b [now dev] Print Serving all files as static only once (#2590)
* [now dev] Print `Serving all files as static` only once

* Track the config state

* Revert "Track the config state"

This reverts commit 9766941ca8cd1ffeae5fb0729800f05f2547099c.

* Revert "[now dev] Print `Serving all files as static` only once"

This reverts commit 3e30c2440b6c4deed8a14f2359696e7bf8dcdcad.

* Add `isInitialLoad` param
2019-07-25 13:58:33 +02:00
Sophearak Tha
e45e403bb3 Add configuration and basic integration tests for now dev (#2553)
* Add configuration and basic integration tests for `now dev`

* Add test fixtures from `now-examples`

* Add `include` to `tsconfig.json`

* Increase retries for 00-list-directory

* Increase retries for `03-aurelia-node`

* Enable test fixtures for hexo, hugo, next, polymer, preact, svelte, vue, and vuepress

* Increase retries for `08-hugo-node`

* Disable `08-hugo-node` fixture

* Enable `04-create-react-app-node` test

* Disable `04-create-react-app-node` test

* Better name for now dev test job
2019-07-25 13:58:25 +02:00
Andy
2fe38b1527 Handle more errors when deploying (#2589) 2019-07-25 13:58:18 +02:00
Andy
f6a38717f2 [now dev] Bump @now/build-utils and throw errors (#2588)
* [now dev] Bump `@now/build-utils` and throw errors

* Fix error handling
2019-07-25 13:58:10 +02:00
Steven
31c0ac8a54 [now init] Add suggestions for old examples (#2584)
* [now init] Add suggestions for old examples

* Add support for selecting an old example

* Add message for selection

* Wait for user interaction

* Fix typo

* Use v2 api instead

* Move message label to first param

* Bump api url to latest, update download to v2

* Rename found to visible
2019-07-25 13:58:04 +02:00
Andy Bitz
3774792740 15.8.5 2019-07-19 22:31:53 +02:00
Mark Glagola
a9b3ee96cd handle no-change domain transfer policy (#2570) 2019-07-19 22:31:39 +02:00
Andy
b6946e2f15 Fix update command message (#2581)
* Fix update command

* Update src/commands/update.ts

Co-Authored-By: Leo Lamprecht <mindrun@icloud.com>
2019-07-19 22:31:31 +02:00
Andy
a4ad8c64e6 [now dev] Bump @now/build-utils (#2582)
* [now dev] Bump @now/build-utils

* Replace `apollo` init example fixure with `angular`

* Update more tests

* Remove `now.json` from check
2019-07-19 22:31:24 +02:00
Andy Bitz
29d18dccb2 15.8.4 2019-07-19 14:07:01 +02:00
Andy
89057232eb [now init] Remove now dev suggestion from now init (#2580) 2019-07-19 14:06:16 +02:00
Andy
8a2d3d0c2c [now dev] Remove package.json message (#2576)
* [now dev] Remove package.json message

* Add message that all files are served as static
2019-07-19 14:06:10 +02:00
Sophearak Tha
a01c210bf0 Remove deprecation message from now alias with args (#2578) 2019-07-19 14:06:04 +02:00
Andy
53515e6142 Fix building indicator jittering (#2577) 2019-07-19 14:05:58 +02:00
Andy
2aeab737d9 [now dev] Upgrade @now/build-utils and enable more support for static sites (#2575)
* [now dev] Upgrade `@now/build-utils` and enable more support for static sites

* Add tests

* Upgrade @now/build-utils
2019-07-19 14:05:52 +02:00
Andy Bitz
64caeeb115 15.8.3 2019-07-18 15:24:57 +02:00
Matthew Sweeney
e5e33549f8 Add hint when example not found (#2572)
* add hint when example not found

* update test

* update test
2019-07-18 15:24:35 +02:00
Andy Bitz
d812b18d52 15.8.2 2019-07-18 13:59:11 +02:00
Andy
d7ef4b533f Bump mime-types to 2.1.24 (#2571) 2019-07-18 13:58:27 +02:00
Andy
a5e857df7b Change now update to display npm or yarn command (#2568)
* Change `now update` to display npm or yarn command

* Use `getUpgradeCommand`
2019-07-18 13:58:21 +02:00
Andy Bitz
c3001fe708 15.8.1 2019-07-17 19:46:29 +02:00
Andy
8309ec6327 [now dev] Fix builder sorting when use is undefined (#2566)
* [now dev] Fix function sorting when `use` is undefined

* Update type

* Add filter

* Fix build
2019-07-17 19:35:37 +02:00
Andy
921a54ed22 Fix tests order (#2565) 2019-07-17 19:35:30 +02:00
Andy
c82350dca6 [now dev] Fix builder sorting (#2563)
* [now dev] Fix builder sorting

* Add tests

* Fix path

* Add sleep

* Revert "Add sleep"

This reverts commit 86f0057808eab50f1c977d19989425d633488e23.

* Revert "Fix path"

This reverts commit 14327b83145c8cb24d5e45ac6e91534a7ef093ec.

* Revert "Add tests"

This reverts commit 76849a7a5ce79b54f102a11f66920dccaabeadb6.
2019-07-17 19:35:22 +02:00
Andy
7e3a5a7e2c [now dev] Allow now dev as package.json script (#2559)
* [now dev] Allow `now dev` as package.json script

* Fix absolute path for now dev

* Fix directory issue

* Typo

* Update src/commands/dev/dev.ts

Co-Authored-By: Nathan Rajlich <n@n8.io>

* Whitespace

* Make code simpler

* Extend type

* Update errors/now-dev-as-dev-script.md

Co-Authored-By: Nathan Rajlich <n@n8.io>

* Update errors/now-dev-as-dev-script.md

Co-Authored-By: Nathan Rajlich <n@n8.io>
2019-07-17 19:35:14 +02:00
Nathan Rajlich
ada83ccb63 [now dev] Memoize the getNowConfig() promise (#2561)
The `getNowConfig()` function gets invoked frequently, and it is also
async and makes mutations to the cached now config object. This ends
up being a race condition when `getNowConfig()` is invoked concurrently,
since one of the invocations may end up with an incomplete `NowConfig`
object (namely, with missing `builds`/`routes` arrays due to the
zero-config processing).

This change makes it so that there's only one `getNowConfig()` invocation
being executed at a time, and other concurrent executions will await the
same promise that the original invocation is responsible for.
2019-07-17 19:35:05 +02:00
Nathan Rajlich
a4220a0e7d [now dev] Rename nowJson variables to nowConfig (#2558)
This is only a cosmetic code change, but aligns more nicely with
the new zero-config approach (where there is no `now.json`).
2019-07-17 19:34:58 +02:00
Andy
92be615c3c [now dev] Bump @now/build-utils to 0.8.8 (#2557) 2019-07-17 19:34:51 +02:00
Andy
847dace212 [now dev] Bump @now/build-utils (#2556) 2019-07-17 19:34:45 +02:00
Nathan Rajlich
5a43516354 Update @sentry/node to v5.5.0 (#2542)
Because Sentry gives a big banner saying to update on the error reports.

Related: https://github.com/getsentry/sentry-javascript/blob/master/MIGRATION.md
2019-07-17 19:34:38 +02:00
Nathan Rajlich
868d4522db Update deps of deps in yarn.lock file (#2543)
* Update deps of deps in `yarn.lock` file

To fix #lodashgate:

 * Upgrade `lodash.merge` to version 4.6.2 or later.
 * Upgrade `lodash` to version 4.17.13 or later.

* Regenerate `yarn.lock`
2019-07-17 19:34:33 +02:00
Nathan Rajlich
4d0c638688 [now dev] Wait for updateBuilders() to complete before stop() completes (#2551)
* [now dev] Wait for `updateBuilders()` to complete before `stop()` completes

Since #2477, the unit tests related to `now dev` have become flaky, and
need to be retried a couple of times before running successfully. My
theory is that this is related to having concurrent `yarn` processes
operating on the builders module directory, causing corruption with yarn's
cache. Waiting for the lazy updating `yarn` process to complete makes
sense to me, hopefully CircleCI agrees.

* Debugging "list the scopes" integration test

* Moar debug

* Use regular `require()` when not in a webpack build (ava tests)

* Remove debug
2019-07-17 19:34:27 +02:00
Andy
0080c456d8 [now dev] Apply the ignore pattern to api files (#2548) 2019-07-17 19:34:15 +02:00
Nathan Rajlich
cd36a835eb Add builders.tar.gz to pkg "assets" configuration (#2541)
Fixes this error from the pkg'd binary:

```
Error: File or directory '/**/now-cli/dist/builders.tar.gz'
was not included into executable at compilation stage.
Please recompile adding it as asset or script.
```
2019-07-17 19:34:07 +02:00
Nathan Rajlich
01b9913204 [now dev] Bundle the most popular core builders into CLI binary with lazy builder updates (#2477)
* [now dev] Bundle the most popular core builders into CLI binary

Makes Now CLI bundle a tarball inside its snapshot filesystem that
includes the following builders:

 * @now/go
 * @now/next
 * @now/node
 * @now/php
 * @now/static-build

The tarball is generated by the `build.js` script and ensures the
"latest" version of the builders are included into the tarball.

When `now dev` is run, the tarball will be extracted upon the first
run to make these builders "pre-installed" to avoid the "Installing
builders" phase during boot-up.

Overall, this should make booting up `now dev` a lot faster, and help
with offline support.

* Don't install builders if they are bundled

* Persist `assets` dir to CircleCI workspace

* Delete build assets

* Fix installing builders from URL

* Finish builder installation filtering logic

* Still install `@now/build-utils`

* Implement builders installation "stale-while-revalidate"

* Remove `console.time()`

* Fix unit test

* Add `Readonly<>` to `BuilderWithPackage` type props

* Add debug log stack trace upon builder update failure
2019-07-17 19:33:54 +02:00
Sophearak Tha
d58a189265 [now dev] Improve max lambda size error message (#2539)
* Improve max lambda size error message

* Better wording
2019-07-17 19:33:46 +02:00
Andy Bitz
9f9ce09acc 15.8.0 2019-07-12 15:49:49 +02:00
Andy Bitz
8e1ca16d38 Revert "Include changes from 15.7.0-canary.14"
This reverts commit 6d4a552c96.
2019-07-12 15:25:12 +02:00
Andy Bitz
9291efcfc3 Revert "Include tests from 15.7.0-canary.17"
This reverts commit 350d63eacd.
2019-07-12 15:25:10 +02:00
Nathan Rajlich
6d4a552c96 Include changes from 15.7.0-canary.14 2019-07-12 15:10:34 +02:00
Sophearak Tha
350d63eacd Include tests from 15.7.0-canary.17 2019-07-12 15:05:35 +02:00
Andy
a7d4ce8c3f Bump @now/build-utils (#2535) 2019-07-12 14:54:19 +02:00
Max
a4fdc8561c Disable automatic signup (#2530)
* Disable automatic signup

* Use shorter error message

* Update tests

* Update tests with user info

* Create tmpDir before tests

* Tweak fixtures and assertions for new login

* Don't pre-create the test directory in CI

* Use `os.homedir` instead of `~` in tests

* Pre-create auth directory conditionally
2019-07-12 14:53:12 +02:00
Sophearak Tha
08fff2a145 Increase default maxLambdaSize (#2534) 2019-07-12 14:53:04 +02:00
Luc
6b4b73ee94 Remove "missing alias in now.json" warning (#2533) 2019-07-12 14:52:57 +02:00
Nathan Rajlich
98d511b03c [now dev] Render directory listing for Now v2 projects (#2528)
* [now dev] Render directory listing for Now v2 projects

Before directory listings only worked for "all static" deployments since
`now dev` would shell out to `serve-handler` to do the rendering.

Now the directory listing rendering logic is moved into `now dev` which
allows projects with Lambdas to also serve the directory listing
(previously they would just 404).

This removes the special-casing of "all static" deployments so that
there's only one code path.

Fixes #2161.
Fixes #2417.

* Move `serve-handler/src/directory` types to root

* Set `Content-Length` header for dir listing

* Add unit tests for directory listing

* Fix unit test
2019-07-12 14:52:50 +02:00
Andy
ad5aa576f3 [now dev] Update @now/build-utils and handle warnings (#2523)
* [now dev] Update @now/build-utils and handle warnings

* Display warnings from response headers for deployment creation

* Update src/util/dev/server.ts

Co-Authored-By: Nathan Rajlich <n@n8.io>

* Apply routes only when there are no builds

* Updated the build utils
2019-07-12 14:52:43 +02:00
Nathan Rajlich
855940c6fc [now dev] Update serve-handler to v6.1.0 and enable etag option (#2525)
* [now dev] Update `serve-handler` to v6.1.0 and enable `etag` option

Sending the `ETag` response header matches how Now in production works.

* Test file contents as well
2019-07-12 14:52:34 +02:00
Nathan Rajlich
ac794e704d Add .gitignore file to test/fixtures/unit/now-dev-default-builds-and-routes (#2524) 2019-07-12 14:52:27 +02:00
Nathan Rajlich
09e663d86e Add @AndyBitz to now dev CODEOWNERS (#2522) 2019-07-12 14:52:20 +02:00
Nathan Rajlich
20ee6752ad [now dev] Revert "Add etag response header for Lambda invocations" (#2520)
* [now dev] Revert "Add `etag` response header for Lambda invocations"

This reverts commit f80f1f79a6 (#2502).

`ETag` header is only sent in production when the lambda function sets
the "stale-while-revalidate" cache-control header, which will be
implemented in a separate PR.

* Remove `etag` test assertion
2019-07-12 14:52:10 +02:00
Nathan Rajlich
586e76f930 Add /src/util/dev to CODEOWNERS file (#2521) 2019-07-12 14:51:40 +02:00
Andy
27730b4568 [now dev] Fix @now/static-build sorting (#2519)
* [now dev] Fix @now/static-build sorting

* Change tests

* Update src/util/dev/server.ts

Co-Authored-By: Nathan Rajlich <n@n8.io>
2019-07-12 14:51:32 +02:00
Andy
00c792297a [now dev] Tests for routing and apply default frontend builder last (#2518) 2019-07-12 14:51:25 +02:00
Sophearak Tha
ee80ea59f4 [now-dev] Fix flickering and improve message (#2516)
* Fix flickering and improve message

* Pluralize builds

* Properly handle pluralize form
2019-07-12 14:51:19 +02:00
Andy
d355e9e202 [now dev] Allow the default static build without an api (#2515) 2019-07-12 14:51:09 +02:00
Sophearak Tha
8289c159c5 Handle 400 create alias error (#2514) 2019-07-12 14:50:55 +02:00
Sophearak Tha
d11f8e4ebf Simplify builds output message (#2512)
* Simplify builds output message

* Properly stop the spinner

* Handle stop spinning properly and remove unused import

* Update src/commands/deploy/latest.js

Co-Authored-By: Leo Lamprecht <mindrun@icloud.com>

* Update src/commands/deploy/latest.js

Co-Authored-By: Leo Lamprecht <mindrun@icloud.com>

* Properly handle stop spinning at build failed

* Update build failed message

* Remove unused variable

* Remove punctuation in error message

* Update integration test reflect latest change
2019-07-12 14:50:49 +02:00
Sophearak Tha
43bf805392 Improve now dev output message (#2506)
* Improve `now dev` output message

* Update src/util/dev/builder.ts

Co-Authored-By: Leo Lamprecht <mindrun@icloud.com>
2019-07-12 14:50:41 +02:00
Sophearak Tha
e57cf657fe Throw an error if dev scripts contain now dev in package.json (#2507)
* Throw an error if `dev` scripts contain `now dev` in package.json

* Use proper Package type

* Update src/commands/dev/index.ts
2019-07-12 14:50:33 +02:00
Nathan Rajlich
020f9d8da5 [now dev] Add test case for lazily installing builders (#2510)
This is a follow up for #2509 to add a unit/regression test ensuring
correct functionality.
2019-07-12 14:50:26 +02:00
Andy
a40f0b6d65 [now dev] Add support for deployments without now.json (#2498)
* [now-dev] Add zero config

* Update @now/build-utils

* Update @now/build-utils

* Escape glob

* Fix windows and group globbing

* Made sure routes and builds get updated on file events

* Removed useless check

* Add unit tests

* Use fetch instead of get
2019-07-12 14:50:02 +02:00
Nathan Rajlich
69f81e0ab9 [now dev] Set Now response headers when proxy passing in routes (#2500)
* [now dev] Set Now response headers when proxy passing in `routes`

* Fix unit test
2019-07-12 14:49:53 +02:00
Nathan Rajlich
37a3fb0497 [now dev] Install missing builders during runtime (#2509)
Before this change, the `installBuilders()` function was only run at
bootup, so if you modify `now.json` during runtime and add a builder
that's not installed, then a `MODULE_NOT_FOUND` error occurs.

Now the `installBuilders()` function is run with the missing builder
so that the builder can be properly loaded.
2019-07-12 14:49:47 +02:00
Nathan Rajlich
1a9958c71e [now dev] Move the MissingDotenvVarsError handling to the correct place (#2489)
`validateEnvConfig()` used to be invoked inside of `validateNowConfig()`,
but now it is invoked separately.

Explicitly exiting the process avoids reports going to Sentry.
2019-07-07 16:40:59 +00:00
Sophearak Tha
6688935436 Bump serve-handler version (#2497) 2019-07-07 16:40:49 +00:00
Olli Vanhoja
0541ac8284 Use v3 user tokens API (#2482) 2019-07-07 16:40:34 +00:00
Nathan Rajlich
cf4eebbc95 [now dev] Allow cache-control header to be overwritten (#2501)
* [now dev] Allow `cache-control` header to be overwritten

This matches the behavior in production.

* Add `now-dev-headers` unit test fixture

* Remove `console.error()` call
2019-07-07 16:40:31 +00:00
Nathan Rajlich
3383798bf1 [now dev] Add etag response header for Lambda invocations (#2502)
This matches the behavior in production.
2019-07-07 16:40:28 +00:00
Nathan Rajlich
aba51841a2 [now dev] Set "must-revalidate" cache-control response header (#2499)
This matches the production router behavior, and prevents running `now
dev` on a different project from serving stale content from a different
project.

Also update the `x-now-id` header to match the production behavior (it
changed at some point).
2019-07-07 16:40:22 +00:00
Nathan Rajlich
1712405cd3 [now update] Add message saying that Windows is not supported (#2493)
* [now update] Add message saying that Windows is not supported

And direct the user back to the download page in order to re-install.

Closes #2492.

* Exit 1

Co-Authored-By: Steven <steven@ceriously.com>
2019-07-07 16:40:19 +00:00
Nathan Rajlich
27186a377e 15.7.0 2019-07-05 11:30:08 -07:00
Nathan Rajlich
f5fca3a0fb [now dev] Use system installed version of Node.js for builds (#2480)
* [now dev] Use system installed version of Node.js for builds

Rather than downloading the 8.10 Node.js binary, simply assume that the
user has their preferred version of `node` already installed onto the
system and use that version.

If there is no `node` binary in the $PATH, then `process.execPath` is
used instead, meaning that the pkg binary node version will be used.

* Simplify `getNodeBin()` using `nothrow` option

* Fix build
2019-07-05 11:25:24 -07:00
Sophearak Tha
4b75f20f9b Improve metrics (#2472)
* ignore metrics with environment variable

* collect exception and exit code

* add deprecated warning for `now alias [id] [url]`

* add exception in util error

* consistent format

* ensure no duplicate warning

* using the right error message

* refactor metrics util
2019-07-05 11:25:16 -07:00
Nathan Rajlich
64fe29bfea Remove mkdirp-promise (#2478)
Use the implemention from `fs-extra` instead.
2019-07-05 11:25:10 -07:00
Nathan Rajlich
eea09ca6cc [now dev] Exit the process upon ERR_SERVER_NOT_RUNNING (#2479)
This error happens when Ctrl+C is pressed before the `http.Server`
instance is listening, meaning that the user attempted to quit very
quickly after starting `now dev`.

This change makes the process exit immediately instead of throwing,
which also causes the error to be sent to Sentry (which we do not want).
2019-07-05 11:25:02 -07:00
Mark Glagola
f7919230fc More cert error handling for deploy command (#2475)
* More cert errors handling for deploy command

* Apply suggestions from code review

Co-Authored-By: Andy <AndyBitz@users.noreply.github.com>

* Revisions based on review

* Minor revision

* Adds get-deployment-by-id which uses latest v9 endpoint

* Refactor to use apiVersion
2019-07-05 11:24:55 -07:00
Nathan Rajlich
5e092cde57 Update @now/build-utils to v0.7.0 (#2474) 2019-07-05 11:24:49 -07:00
Mark Glagola
96bb51f266 Adds --target to arg-common (#2473) 2019-07-05 11:24:40 -07:00
Andy Bitz
ad8b141c1c 15.6.2 2019-06-28 12:14:02 +02:00
Andy
9b23d61720 Change url for revert-alias tests to make it more reliable (#2471)
* Change url for revert-alias tests to make it more reliable

* Use project name from now.json

* Remove unused import in tests
2019-06-28 12:12:10 +02:00
Andy
d993650a84 Don't verify the user for now dev (#2470) 2019-06-28 12:12:03 +02:00
Andy
f0dbb33fd1 Don't show warning (#2468) 2019-06-28 12:11:55 +02:00
Andy Bitz
b22b3787ff 15.6.1 2019-06-26 22:57:50 +02:00
Andy
e700ad78ee Make sure to call secrets API only once (#2464)
* Make sure to call secrets API only once

* Use const
2019-06-26 22:57:14 +02:00
Andy
85ccf59a08 Handle deployments rate limit (#2463) 2019-06-26 22:57:05 +02:00
Andy
094277cb2e Upgrade esm (#2458)
* Upgrade esm

* Use version 3.1.0

* Use version 3.1.4
2019-06-26 22:56:57 +02:00
Mark Glagola
e5c7e2d8f0 Handle cert errors in create-deployment (#2455)
* handle cert errors in create-deployment

* Capture challenge_error and txt_record_not_found in mapCertError
2019-06-26 22:56:49 +02:00
Mark Glagola
3ee7babf4a Prompt based DNS add command (#2450)
* Initial prompt based DNS add command

* Adds verify step to dns record prompts

* handle prompt abort
2019-06-26 22:56:41 +02:00
Steven
e630eaebcd 15.6.0 2019-06-21 17:46:51 -04:00
Andy
493e972720 now rm improvements (#2449)
* Handle --safe

* Fix  option

* Slice deployments
2019-06-21 17:13:59 +00:00
Andy
e008b6e1cb Handle --safe (#2448)
* Handle --safe

* Fix  option
2019-06-21 17:13:54 +00:00
Steven
c739d564a9 Bump @zeit/fun to 0.9.0 (#2445) 2019-06-21 11:39:04 +00:00
Steven
dd6dbbfc9b [now dev] Improve tests for @now/build-utils@canary (#2444) 2019-06-21 11:39:00 +00:00
Mark Glagola
498615b6b3 Move dns_error to generic CertError (#2443) 2019-06-21 11:38:56 +00:00
Mark Glagola
491da80c90 Cert error handling revisions/additions (#2437)
* Cert error handling revisions/additions

* Adds certs/add.js back + updated cert error handling to be pipeable

* remove //todo
2019-06-21 11:38:52 +00:00
Steven
7ceeaf9a6a [now dev] Use canary @now/build-utils or stable based on builders (#2441)
* [now dev] Use canary build utils or stable

* Fix version selection

* Fix test

* Fix typo

* Add tests for getBuildUtils

* Add `latest`
2019-06-21 11:38:48 +00:00
Steven
d6e09b098e Bump @now/build-utils to 0.6.0 (#2440) 2019-06-21 11:38:42 +00:00
Andy
9056ba54c3 Update help (#2438)
* Update help

* Make whoami advanced

* Make init basic

* Moved update down
2019-06-21 11:38:37 +00:00
Andy
964d5b3238 Update now rm (#2412)
* Update now rm

* Fixed typo

* Don't use .flat() because of node 10

* Exit process

* Remove only the project instead of all deployments of it

* Changed output text

* Headlines for projects and deployments

* Typo and number prefix
2019-06-21 11:38:32 +00:00
Nathan Rajlich
8c035be63f [now update] Handle permissions errors in the file replacement method (#2430)
1. Handle permissions errors in both update mechanisms
 2. Handle `EBUSY` (Windows) as a file busy error
 3. Update permissions error prompt to say "Administrator Command Prompt" on Windows
 4. Add message about "unexpected end of file" error
2019-06-21 11:38:26 +00:00
Leo Lamprecht
6c264fe243 15.5.0 2019-06-13 14:00:50 +00:00
Nathan Rajlich
1380c9fb2c [now dev] Move helper modules to src/util/dev (#2422)
This organization is consistent with how other commands are structured.
2019-06-13 13:55:57 +00:00
Nathan Rajlich
9827f1cb69 Lowercase the x-forwarded-* and x-real-ip headers (#2420)
Fixes #2238.
2019-06-13 13:55:53 +00:00
Nathan Rajlich
8fe220c330 [now dev] Run prettier (#2419)
Run `prettier` on the `now dev` codebase since the formatting has
gotten out-of-sync over time.

Also removes a stale TODO comment.
2019-06-13 13:55:49 +00:00
Nathan Rajlich
9b5b360465 [now dev] Show a warning when now.json contains a syntax error (#2418)
Rather then throwing which causes the process to exit.
Better to give the developer a chance to fix the syntax
error without having to restart the dev server afterwards.
2019-06-13 13:55:44 +00:00
Nathan Rajlich
a8d4b7826f [now dev] Implement continue: true routes (#2413)
* [now dev] Implement `continue: true` routes

Fixes #2088.

* Add `continue: true` unit test

* Add a `continue: true` unit test that matches
2019-06-13 13:55:39 +00:00
Nathan Rajlich
593bcb1025 Add whoami command back (#2411)
* Add `whoami` command back

It was accidentally removed.

Fixes #2410.

* Add `whoami` regression test
2019-06-13 13:55:34 +00:00
JJ Kasper
ece9f46798 [now-dev] Add checking of RegExp src with beginning slash (#2398)
* Add checking of RegExp src with beginning slash

* Move slash no slash check to same line

* Add unit test for dev-router
2019-06-13 13:55:29 +00:00
Nathan Rajlich
e245b2fd90 15.4.0 2019-06-05 15:13:03 -07:00
Luc
ba6ddc380d [now update] Add integration test (#2405)
* add simple integration to test `now update`

* remove `.only`

* verify that `now --version` includes `canary`
2019-06-05 15:12:45 -07:00
Nathan Rajlich
402ec684eb [now update] No login required (#2406) 2019-06-05 15:12:39 -07:00
Andy
8b8af21445 Fix now rm and decrease total projects for now ls (#2404)
* Use v4 instead to prevent listing the same deployment multiple times

* Remove the latestDeployments since it is depracted and doesn't have the
`readyState` property and only get 35 projects instead of 50 to lower
the rate limit

* Fix tests
2019-06-05 15:12:32 -07:00
Nathan Rajlich
1ead4f2e2c Add now update command (#2388)
* Add `now update` command

Updates the `now` binary in-place.

* Tweaks

* Remove `.ts` suffix in `import` statement

* Remove unused imports

* Implement `getPlatform()`

* Add `ETXTBSY` error fallback method

* Remove `StreamError` import

* Add `chown()` logic

* Remove `console.error()`

* Add `now update` to --help

* Add beta message with feedback URL

* Deprecate `now upgrade` and `now downgrade` commands

* Mention `now upgrade` when a new version is available

* Add `now update` message to `now upgrade`

* Final tweaks
2019-06-05 15:12:27 -07:00
Andy
43047cfa24 Use the projects API for now ls (#2403)
* Use the projects API for `now ls`

* Use recentDeployments
2019-06-05 15:12:18 -07:00
Mark Glagola
33dc9a5767 Handle transfer-in registration_failed (#2402) 2019-06-05 15:12:10 -07:00
Mark
8bf7ed52c4 Update @zeit/ncc to v0.18.5 (#2389) 2019-06-05 15:12:01 -07:00
Nathan Rajlich
a495b19793 Update @zeit/fun to v0.8.1 (#2391) 2019-06-05 15:11:54 -07:00
Nathan Rajlich
42b24b4904 [now dev] Strip prefixed / when doing routes matching (#2361)
* [now dev] Strip prefixed `/` when doing routes matching

The prefixed `/` is implicit when matching routes, so strip them
so that they are optional. This matches the behavior in production.

* Fix unit tests

* More readable

* Add unit test
2019-06-05 15:11:48 -07:00
Steven
10347279ba [now-init] Check for dir existence prior to download (#2379) 2019-06-05 15:11:39 -07:00
Nathan Rajlich
a31c29fc13 [now dev] Use empty string for missing matches (#2376)
Rather than `undefined`. This matches the behavior in production.

Fixes #2375.
2019-06-05 15:11:32 -07:00
Sophearak Tha
9d110bd1c9 Mimic browser user agent (#2372) 2019-06-05 15:11:25 -07:00
Nathan Rajlich
de7c0aec39 15.3.0 2019-05-20 13:11:18 -07:00
Sophearak Tha
6232078ad3 Add .now ignore by default (#2365) 2019-05-20 19:15:30 +00:00
Andy
418d550f2a Increase the time we wait for the aliasing (#2360) 2019-05-20 19:15:25 +00:00
Sophearak Tha
81b0e995e1 Integrate universal metrics (#2346)
* integrate universal metrics

* Update src/index.js

Co-Authored-By: Leo Lamprecht <mindrun@icloud.com>

* Add default `collectMetrics` config

* Remove flag, only using global config to disable metrics

* Add GA tracking ID

* Move constant to file

* Rename constant to constants

* Rename `dsn` to `SENTRY_DSN`

* Apply suggestions from code review

Co-Authored-By: Leo Lamprecht <mindrun@icloud.com>

* Remove extra space

* Update event category and action

* Remove usagestate to use universal-analytics

* Chain timing and event function

* Make sure to user are unique

* Ensure unique User ID

* Add extra User-Agent and move metrics into its own file

* Use default export
2019-05-20 19:15:18 +00:00
Samuel Hapák
22fd52c8db Help users to deal with secrets starting with dash (#2253)
People are often trying to store secrets starting with dashes such as 
private keys. These dashes get interpreted as command line options which
effectively prevents a storage of private keys.

Fortunately, this is easily resolved by using bash -- convention to mark
an end of options, such as:

`now secret add google-secret-key -- "-----BEGIN PRIVATE KEY-----
abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVXYZ+/a
-----END PRIVATE KEY-----"

The problem is also discussed in following issues: 
https://github.com/zeit/now-cli/issues/749
https://github.com/zeit/now-cli/issues/80
2019-05-20 19:15:14 +00:00
Nathan Rajlich
6a20529b89 [now dev] Create yarn.cmd file on Windows (#2358)
The `yarn.cmd` file is necessary for `yarn` to be executable
when running `now dev` through cmd.exe
2019-05-20 19:15:10 +00:00
Nathan Rajlich
1988f820bf [now dev] Use chokidar for file watching (#2350)
* [now dev] Use `chokidar` for file watching

`nsfw` is not suitable for very large projects because it does not
have any "ignore" functionality implemented.

For macOS, the `useFsEvents` option is _disabled_, so that the
`fsevents.node` binary file does not need to be cached onto the
filesystem, which simplifies things for use with `pkg` binaries.

* Delete the `fsevents` module during build

* Add proper `.nowignore` logic to the chokidar watcher
2019-05-20 19:15:06 +00:00
Nathan Rajlich
0bafb6286a [now dev] Consider devDependencies when looking up package name (#2352)
Alpha versions of `now dev` that used npm instead of yarn were
installing the packages to `devDependencies` rather than `dependencies`,
so this fixes package name lookup when a legacy cache like that is on
the user's machine.
2019-05-20 19:15:01 +00:00
Nathan Rajlich
80ebd659fc [now dev] Use the dev server cwd as builder's workPath (#2326)
* [now dev] Use the dev server `cwd` as builder's `workPath`

Rather than copying the source files into a temporary directory,
simply use the existing source files in the `cwd`. This will make
subsequent boots of `now dev` be faster (i.e. because the `node_modules`
directory will already be in place), as well as use much less space on
the filesystem because temporary directory are no longer being used.

This will require some changes to the builders and `@now/build-utils`,
to ensure that the `download()` function is always installing into
`workPath`, and that the `meta` object passed to the `build()` function
is also passed into the `download()` function.

For example:

 - https://github.com/zeit/now-builders/pull/474
 - https://github.com/zeit/now-builders/pull/475

* Update `@now/build-utils` to v0.5.5-canary.1

This makes `download()` be a no-op when running in `now dev`.

* Add test case for `@now/next`

* Fix debug log formatting
2019-05-20 19:14:56 +00:00
Nathan Rajlich
2d16c36f8d Re-enable "try to create a builds deployments with wrong config" integration test (#2337)
It was temporarily disabled due to server-side issues, but that has been
fixed now.
2019-05-20 19:14:51 +00:00
Mark Glagola
ca1930cb44 Fix transfer in price for some TLDs (#2334) 2019-05-20 19:14:45 +00:00
Nathan Rajlich
91b4e7a308 [now dev] Mix in routes query params when proxying to a URL (#2330)
* [now dev] Mix in routes query params when proxying to a URL

Fixes #2289.

* Refactor unit tests and add a unit test for proxy passing with query params

* Fix TypeScript compile error

* [DEBUG] Disable proxy pass unit test

* Run unit tests serially

* Remove `console.error()` in unit test

* Temporarily disable integration test "try to create a builds deployments with wrong config"
2019-05-20 19:14:40 +00:00
Nathan Rajlich
4fac67f39e Adjust now init and now dev to not require a login token (#2325)
* Adjust `now init` and `now dev` to not require a login token

These two commands should not require a login token because
they do not interact with the Now API.

* Remove `config` from `subcommandsWithoutToken` array

It's not an existing command.
2019-05-20 19:14:35 +00:00
Nathan Rajlich
7c4ab3989a 15.2.0 2019-05-06 18:16:47 -07:00
Nathan Rajlich
2c6faa5eab [now dev] Inherit env vars from now.json (#2321)
* [now dev] Inherit env vars from `now.json`

Before it was only using env vars defined in the `.env` and `.env.build`
dotenv files.

* Fix secrets validation
2019-05-06 18:15:29 -07:00
Andy
2707149352 Fix Git Bash and make update/uninstall work on Windows (#2322)
* Update index.js

* Fix bash file
2019-05-06 18:15:23 -07:00
Nathan Rajlich
2834c188e7 [now dev] Add meta.env and meta.buildEnv for builders (#2320)
Some builders require access to the runtime env vars, i.e. `@now/next`
since it spawns a `next dev` subprocess and should be passing the
runtime env vars to that.
2019-05-06 18:15:18 -07:00
Nathan Rajlich
0f31bc1f68 15.1.0 2019-05-03 17:24:33 -07:00
Steven
6f3ff2abf0 Update Readme with now dev workflow (#2308) 2019-05-03 17:21:52 -07:00
Nathan Rajlich
3398e6da27 [now dev] Implement methods in routes config (#2306)
Fixes #2148.
2019-05-03 17:21:51 -07:00
Nathan Rajlich
22f7d69a7e [now dev] Send all status codes if routes config contains one (#2307)
Before it was only respecting the status code for 301, 302 and 303
status codes. Now it handles any status code defined in the routes
config.

Fixes #2294.
2019-05-03 17:21:51 -07:00
Matthew Sweeney
cb76d02dcc [now init] Add line breaks to success message (#2285)
* add line break to success message

* change to using original util

* Update src/commands/init/init.ts

Co-Authored-By: msweeneydev <26944716+msweeneydev@users.noreply.github.com>
2019-05-03 17:21:50 -07:00
Nathan Rajlich
49d5802e3d [now dev] Update @zeit/fun and @now/build-utils for Windows (#2302)
Not all builders will be working yet, but this adds minimal Windows
support for `now dev`.
2019-05-03 17:21:50 -07:00
Nathan Rajlich
38164f980b Convert the build script to Node.js (#2301)
Because, you know, Windows.
2019-05-03 17:21:50 -07:00
Nathan Rajlich
1cff0342e8 [now dev] Show build logs if a build fails during bootup (#2297)
* [now dev] Show build logs if a build fails during bootup

Before, the logs were never shown because `buildProcess` does not emit
an `error` event when the child process exits.

Also updates `ora` to the latest version.

* Remove `@types/ora`

`ora` includes its own TypeScript definitions now.
2019-05-03 17:21:49 -07:00
Nathan Rajlich
b6117e4a63 [now dev] Set NOW_REGION: 'dev1' env on the builder processes (#2298) 2019-05-03 17:21:49 -07:00
Steven
48c6510135 Add .next and .cache to default ignore (#2295) 2019-05-03 17:21:49 -07:00
Nathan Rajlich
4e505f40f7 Update pkg to v4.3.8 (#2293)
Which includes this fix: https://github.com/zeit/pkg/issues/671

Relevant to `now dev` invoking `yarn` when a package includes
a postinstall script that invokes `node`.
2019-05-03 17:21:48 -07:00
Steven
a3fe672b2a Create CODE_OF_CONDUCT.md (#2290) 2019-05-03 17:21:48 -07:00
Nathan Rajlich
e029e875d8 [now dev] Use consistent cache directory for nsfw module download (#2280) 2019-05-03 17:21:48 -07:00
Shuying
ef6e6c8d0d Update feedback url (#2278) 2019-05-03 17:21:47 -07:00
Nathan Rajlich
4a4e9764de [now dev] Convert path backslashes to forward slashes for Windows (#2279) 2019-05-03 17:21:47 -07:00
Spellar Bot
4260b6c390 Fix a few typos in err.sh pages (#2311) 2019-05-03 13:22:33 -07:00
Timothy
d47591ccda Update missing-env-file.md (#2281)
* Update missing-env-file.md

* Update missing-env-file.md
2019-04-30 20:16:36 +02:00
Leo Lamprecht
6e5915a664 15.0.11 2019-04-30 10:31:36 +00:00
Nathan Rajlich
a1631dfd9f [now dev] Enable cleanUrls option when deployment is all static (#2277)
So that rendering `index.html` as root works as expected.
2019-04-30 10:14:26 +00:00
Nathan Rajlich
db15047cc1 [now dev] Install builders with yarn instead of npm (#2272)
* [now dev] Install builders with `yarn` instead of `npm`

Also invokes via `process.execPath` so that the pkg'd node is used
instead of a global one.

Depends on #2270.

* Install `yarn` to the builder cache dir

Not the `node_modules/.bin` dir, because `yarn` cleans up that directory
when installing modules, so it deletes itself.

* Remove unnecessary unit test

* Always install `yarn`

* Pass in the `yarnPath` to `installBuilders()`

* Restore unit test

* Remove unused `delimiter` import

Co-Authored-By: TooTallNate <n@n8.io>
2019-04-30 10:14:22 +00:00
Steven
ba8c641c58 [now dev] Install yarn into builder cache (#2270)
Closes #2063.
2019-04-30 10:14:18 +00:00
Nathan Rajlich
3d17f3b38b Update CODEOWNERS for dev, certs and domains commands (#2275)
* Update CODEOWNERS for `dev` command

Also added a fallback for @leo

* Remove `init`, add `domains` and `certs`
2019-04-30 10:14:14 +00:00
Nathan Rajlich
5ca3cae9e8 [now dev] Show build timestamps (#2273)
* [now dev] Show build timestamps

Except when running the initial builds

* Fix bad logic
2019-04-30 10:14:09 +00:00
Steven
97d3413621 [now-dev] Fix .nowignore to match production (#2233)
* Fix now dev usage of .nowignore

* Fix now dev usage of .nowignore

* Move env before nowjson

* Remove console.log()

* Remove comments & unused imports

* Fix merge conflicts

* Fix merge conflicts

* Add docs

* Fix stat mode
2019-04-30 10:14:05 +00:00
Nathan Rajlich
bddab3c5d1 [now dev] Don't render initial builds spinner when debug is enabled (#2271) 2019-04-30 10:14:00 +00:00
Leo Lamprecht
14aaf3b375 15.0.10 2019-04-29 19:04:10 +00:00
Leo Lamprecht
ecaee451c8 Revert "Enable cleanUrls for entirely static projects (#2268)"
This reverts commit c7ed5d7850.
2019-04-29 19:04:04 +00:00
Nathan Rajlich
a43d6f9792 [now dev] Show builder logs, even after build completes (#2269)
This is important for builders like `@now/next` and `@now/static-build`
which launch a child process dev server, and we want those logs to be
visible from the `now dev` console output.
2019-04-29 19:04:00 +00:00
Leo Lamprecht
78aea6ab13 15.0.9 2019-04-29 15:14:34 +00:00
Leo Lamprecht
3fa104a531 Enable cleanUrls for entirely static projects (#2268) 2019-04-29 14:59:55 +00:00
Leo Lamprecht
864c937de1 Correctly log when setting up Builders (#2267)
* Correctly log when setting up Builders

* Added message about beta
2019-04-29 14:59:52 +00:00
Leo Lamprecht
8114ede173 Do not print installing builders for no builds (#2266)
* Do not print installing builders for no builds

* Added unit test
2019-04-29 14:59:48 +00:00
Andy
7294f8f2e1 Display handle in now inspect (#2265) 2019-04-29 14:59:45 +00:00
Leo Lamprecht
f53feed8f5 Make the message for when the server is running shorter (#2262) 2019-04-29 14:59:40 +00:00
Leo Lamprecht
18dc7cb3f4 Fixed error for .env and .env.build (#2261)
* Do not report env errors to Sentry

* Added guide for missing env file in dev mode

* Update errors/missing-env-file.md

Co-Authored-By: leo <mindrun@icloud.com>

* Update errors/missing-env-file.md

Co-Authored-By: leo <mindrun@icloud.com>
2019-04-29 14:59:37 +00:00
Nathan Rajlich
5d8b27ebbe [now dev] Refactor builders installation logic (#2254)
* [now dev] Refactor builders installation logic

 - Don't run `npm update`, only `npm install`, so no more "Checking for
   builder updates".
 - Don't save `package-lock.json`, to allow builders with newer versions
   than already installed to be updated.
 - Properly supports non-npm-registry builders (i.e. an HTTP URL,
   `github:` syntax, etc.

* Use `Object.entries()`
2019-04-29 14:59:33 +00:00
Matthew Sweeney
8a347d0a7a Adds 'to develop' to now init (#2260)
Adds 'to develop' to now init
2019-04-29 14:59:29 +00:00
Amio
4e884fb59d [now dev] fix directory listing (#2256) 2019-04-29 14:59:25 +00:00
Andy
1bf4af7269 Wait for aliases in tests (#2257) 2019-04-29 14:59:22 +00:00
Leo Lamprecht
e383c2c4d6 Revert "Add a logout test case" (#2258)
This reverts commit 5754360684c1e34b0351fadd9e2a6e5ef4b8b82f.
2019-04-29 14:59:18 +00:00
Olli Vanhoja
8fce8bb75d Use the single request logout endpoint (#2201)
Logout by deleting the currently used auth token.
2019-04-29 14:59:14 +00:00
Nathan Rajlich
ee158a7862 [now dev] Don't render building/built logging for @now/static
Since it's a built-in builder.
2019-04-29 14:59:10 +00:00
Leo Lamprecht
c80a5b6f9d Do not check for @now/static Builder updates (#2251) 2019-04-29 14:59:01 +00:00
Leo Lamprecht
97763ce5e8 Print missing line when stopping server (#2250) 2019-04-29 14:58:58 +00:00
Leo Lamprecht
f5f0c9eccd Only print stopping server if already printed URL (#2249) 2019-04-29 14:58:55 +00:00
JJ Kasper
2822c314eb Update to make sure query isn't stripped (#2246)
* Update to make sure query isn't stripped
before ProxyPass in dev-server

* Add test for stripping query

* normalize semis in test
2019-04-29 14:58:51 +00:00
Nathan Rajlich
2f170dbd45 [now dev] Better logging while building and error recovery (#2244)
- Have the builder exit if a rejection occurs
 - Respawn the builder upon next rebuild after the builder has exited
 - Log when builder is starting and completed with build time
 - Render build error in the HTTP response
2019-04-29 14:58:48 +00:00
Amio
b5ed4c48ed Refine dev log layout (#2245) 2019-04-29 14:58:44 +00:00
Nathan Rajlich
672cd5efbb [now dev] Lazily initialize the nodejs8.10 runtime for builds (#2243) 2019-04-29 14:58:40 +00:00
Leo Lamprecht
37d410c6cf Bumped @zeit/nsfw to latest (#2242) 2019-04-29 14:58:35 +00:00
Leo Lamprecht
d270a07e2a Support Windows when downloading file watcher (#2240) 2019-04-29 14:58:31 +00:00
Andy
1f66976beb Modify the gitbash file correctly (#2223) 2019-04-29 14:58:27 +00:00
Amio
ff601a4c70 [now dev] exit on MissingDotenvVarsError (#2237) 2019-04-29 14:58:24 +00:00
Steven
73d23126f5 Convert get-files from JS to TS (#2207)
* Convert get-files from JS to TS

* Bump @zeit/dockerignore to 0.0.5

* Fix types

* Fix typo

* Remove arr-flatten dependency
2019-04-29 14:58:19 +00:00
Steven
5a1b6e6569 Add python virtual environment to default ignore (#2241) 2019-04-26 15:56:02 -04:00
Leo Lamprecht
f8f5a554e1 15.0.8 2019-04-25 20:57:35 +00:00
Nathan Rajlich
b93e8edb83 [now dev] Supply empty default now.json if one does not exist (#2231)
This forces all the files to be served as static assets using
`@now/static`, rather than having a special branch that dishes
out to `serve-static`. This is better because it keeps the logic
consistent with when a `now.json` is supplied vs. when it is not,
and allows the code to be simplified by removing checks for if
`getNowJson()` returned anything (previously it could return `null`,
but now that is not the case). Also allows us to remove the now-unused
`serveProjectAsStatic()` function.
2019-04-25 20:57:24 +00:00
Nathan Rajlich
4fe1a3831d [now dev] Force @now/static to run in-memory (#2230)
* [now dev] Force `@now/static` to run in-memory

The logic for `@now/static` builder is bundled into the `pkg` binary,
and thus is not requireable, so it must instead be run in-memory.

* Also check for stdout TTY before doing the erase lines stuff
2019-04-25 20:57:17 +00:00
Leo Lamprecht
2be128639c 15.0.7 2019-04-25 15:05:38 +00:00
Nathan Rajlich
8557c4baf0 [now dev] Invoke builders in a forked child process (#2227)
* Update `@zeit/fun` to v0.7.0

* Remove `builderCachePromise`

No longer used.

* Remove `intercept-stdout`

* WIP invoke the builder in a forked child process

* WIP Add `builder.js` file

* Remove `BuildResultV1 | BuildResultV2` distinction

Prefer normalizing the `build()` function result to `BuildResult` v2
shape so that we don't have to cast everywhere else.

* Apply build env vars to builder child process

* Copy the `builder.js` file from the pkg filesystem snapshot to the builder cache dir

* Map `FileFsRef` and `FileBlob` of the builder's output back into instances

* Fix `@now/next` :/

* Cleanup

* Print number of initial builds

* Add spinner for building process

* Refine logs

* Support none-tty

* Crop long lines

* Clean up imports

* Refine logs wording
2019-04-25 15:03:19 +00:00
Nathan Rajlich
037283ed07 [now dev] Always watch the entrypoint for triggering rebuilds (#2226)
The `entrypoint` should always be watched, since we know that it was used
to produce the build output. This is for builders that don't implement
a fully featured `watch` return value.
2019-04-25 15:03:13 +00:00
Nathan Rajlich
122a83e556 [now dev] Don't include a file in both filesChanged and filesRemoved list (#2225)
* [now dev] Don't include a file in both `filesChanged` and `filesRemoved` list

This makes it so that if a file is added to the "changed" array, then it
is also removed from the "deleted" array, and vice-versa.

* Only render the "files changed/remove" debug log if there are entries
2019-04-25 15:03:09 +00:00
Leo Lamprecht
c13fc9d406 Bumped @now/build-utils to latest version (#2220) 2019-04-25 15:03:03 +00:00
Amio
4595449561 [now-dev] Exit when incorrect cwd config (#2218)
* [now-dev] Exit when incorrect cwd config

* better wording
2019-04-25 15:02:58 +00:00
Nathan Rajlich
fb474e5a5f [now dev] Use minimatch on the watch array to support globs (#2216)
This will be necessary for `@now/static-build` since it needs to watch
all files in the dir containing the entrypoint. For example:

```
watch: [ path.join(path.dirname(entrypoint), '**/*') ]
```
2019-04-25 15:02:53 +00:00
Nathan Rajlich
582fb18c22 [now dev] Allow a builder watch array to contain "./" prefixed paths (#2217)
The file watcher logic expects that there is no `'./'` prefix on the
watched file paths/patterns, but `path.dirname('foo')` returns `'.'`
which turns into `'./foo'` with `path.join()`. So this allows those
file paths to be returned from the builder and `now dev` normalizes the
paths after the build has completed.
2019-04-25 15:02:49 +00:00
Nathan Rajlich
26c4f91c58 [now dev] Add xfwd option to http-proxy (#2215)
This makes the `http-proxy` module set the `X-Forwarded-*` HTTP request
headers to the destination endpoint.
2019-04-25 15:02:44 +00:00
Nathan Rajlich
aa1d41f89c [now dev] Pass in the builder-specific workPath to shouldServe() (#2214)
The dev server `cwd` is not correct working path of a build match, so
pass in the correct one. This property will be used by
`@now/static-build`'s dev mode.
2019-04-25 15:02:38 +00:00
Steven
a23ad79c99 Ignore __pycache__ directories (#2213) 2019-04-25 15:02:34 +00:00
Mark
18f3c50003 Update @zeit/ncc to v0.18.1 (#2210) 2019-04-25 15:02:28 +00:00
Nathan Rajlich
28a478311c [now dev] Remove requiresInitialBuild and make shouldServe() optional for v2 Builders (#2209)
* [now dev] Remove `requiresInitialBuild` and make `shouldServe()` optional for v2 Builders

`@now/next` will be removing `shouldServe()` in favor of returning
a `routes` config array upon bootup. This makes now dev's
`shouldServe()` wrapper function support matching a `routes` config
entry when `shouldServe()` is not defined.

* Remove `console.error()` debugging calls

* Remove `mergeRoutes()` logic

This was incorrect behavior, and more like what `continue: true` is
supposed to do.

* Remove invalid test case

* Remove from the `files` array when ENOENT occurs in file watcher

* Prettier

* Pass workPath to builder.shouldServe() (#2211)
2019-04-25 15:01:05 +00:00
Amio
01d380a7e7 Support env NOW_BUILDER_CACHE_DIR for debugging builders (#2212)
* Support env NOW_BUILDER_CACHE_DIR for debugging builders

* resolve NOW_BUILDER_CACHE_DIR
2019-04-25 15:01:01 +00:00
Nathan Rajlich
276860aead [now dev] Resolve built routes after matching builder (#2208)
* [now dev] Resolve built routes after matching builder

This removes the `combineRoutes()` function since it was problematic and
triggered rebuilds upon every HTTP request, which is not necessary and
makes development slower.

Now, when an HTTP request comes in, the `now.json` routes are resolved
first, and then the matched build is checked if it defines any `routes`
in the build output. If it does, and a matching route is found then the
route is handled accordingly.

* Fix dev router unit tests

* Only try to match build routes if `.length > 0`

* Remove `routes` config from `@now/static` build results

This would cause an infinite loop of resolving `entrypoint` to
`entrypoint`, and is not necessary for this builder.
2019-04-25 15:00:56 +00:00
Leo Lamprecht
2ccbaba654 Initial build should set requestPath to null (#2200)
* Initial build should set `requestPath` to `null`

* Fixed types

* Fixed type
2019-04-25 15:00:52 +00:00
Nathan Rajlich
737aa45a81 [now dev] Fix typo in debug log (#2206)
Also switch to present-tense wording.
2019-04-25 15:00:48 +00:00
Amio
e39dfdd329 [now-dev] make routes from v2 builders optional (#2204) 2019-04-25 15:00:44 +00:00
Leo Lamprecht
71f6711ab4 Better name for continuous property (#2199) 2019-04-25 15:00:39 +00:00
Leo Lamprecht
4849381e60 Prevent exit if client closes proxy connection (#2198) 2019-04-25 15:00:35 +00:00
Leo Lamprecht
1dcd5a7e4e Match only the important part while routing (#2195) 2019-04-25 15:00:31 +00:00
Amio
8e4d7d769e Made sure support for routes works as expected (#2194)
* Fix lost concat result

* Made it work

* Fixed several tests

* Fixed more tests

* Fixed tests
2019-04-25 15:00:27 +00:00
Amio
56fabb8b87 Added support for routes (#2191)
* Add types for updated builder v2 api

* Fix type errors

* outputs => output

* Combine builder routes before routing

* Combine builder routes for all v2 builders

* [temporarily] reveal logs from builder

* Revert "[temporarily] reveal logs from builder"

This reverts commit 9dac764f33d96b5fd004e0839b41228786f83d14.
2019-04-25 15:00:23 +00:00
Amio
c4bd356fc7 Reveal builder logs when --debug (#2193)
And added a `debug` flag to `DevServer` class
2019-04-25 15:00:19 +00:00
Nathan Rajlich
97ec2d1011 [now dev] Reuse the same workPath for subsequent builds (#2185)
* [now dev] Reuse the same `workPath` for subsequent builds

Reusing the same `workPath` for subsequent builds makes rebuilding
faster, as well as it's necessary for webpack's watcher to work
correctly as it relies on the full filesystem paths being intact.

`prepareCache()` also no longer needs to be invoked, since the
previous `workPath` directory will already contain the necessary files
that the cache would otherwise produce.

* Prettier
2019-04-25 15:00:08 +00:00
Nathan Rajlich
35e9bb4e5e [now dev] Don't trigger a rebuild if an asset was deleted (#2184)
* [now dev] Don't trigger a rebuild if an asset was deleted

This handles the case where an asset was deleted and should no longer be
served after a filesystem watcher event. For example, if a Next.js page
was previously built and the files was deleted from the `pages`
directory, then the rebuild should not happen since it will fail in the
`build()` function anyways.

* Add `config` to `shouldServe()`

* Remove unused `builder` var
2019-04-25 14:59:51 +00:00
Andy
5a0ff896a2 Show a upgrade message if the build limit is exceeded (#2182)
* Show a upgrade message if the build limit is exceeded

* Typo

* Update src/commands/deploy/latest.js

Co-Authored-By: AndyBitz <AndyBitz@users.noreply.github.com>
2019-04-25 14:59:46 +00:00
Andy
03915685eb Show the domain purchase UI (#2168)
* Show the domain purchase UI

* Show the correct error message

* Exit after the domain purchase
2019-04-25 14:59:41 +00:00
Amio
0dae0401ee Add some debug logs for now-dev (#2181)
* Add some debug logs

* Fix eslint warnings
2019-04-25 14:59:21 +00:00
Nathan Rajlich
b706a526a4 [now dev] Handle filesystem events where the file has already been deleted (#2179)
Editors like `vim` like to use temporary files in the file's working
directory and quickly rename / delete them. This makes `now dev` handle
that gracefully and not crash.
2019-04-25 14:59:12 +00:00
Nathan Rajlich
071c523dd6 [now dev] Default the Content-Type to "application/octet-stream" (#2177)
This matches the behavior in production, so it is more correct.

This new common `getMimeType()` function also centralizes a place where
we can overwrite the `mime-types` return value to other values to match
production for other future discrepancies.
2019-04-25 14:59:02 +00:00
Amio
8de99d13f5 Mute install logs from @now/node builder (#2171)
* [wip] Mute install logs from @now/node builder

* Bumped build utils
2019-04-25 14:58:54 +00:00
Nathan Rajlich
db9ed9ea54 Pass filesChanges and filesRemoved array to builder's build() (#2174)
This will be required to implement the `@now/node` ncc watcher logic.
2019-04-25 14:58:48 +00:00
Nathan Rajlich
defb2f1776 Added file watcher to now dev (#2153)
* [now dev] Add `nsfw` file watcher

WIP for triggering background rebuilds. So far the `files` mapping is
now kept in sync via the events produced by `nsfw`.

* Add `now.json` caching and invalidation from nsfw events

* Add initial rebuilding logic from filesystem watching

* Remove previously built assets when a rebuild occurs

* Make `@now/static` not require a hard refresh

* Shut down the `nsfw` instance when stopping the DevServer

* Prettier and some minor tweaks

* Ship module

* Support private deps

* Fixed tests

* Fixed integration tests

* Revert "Support private deps"

This reverts commit 0b4991b87641d693fa61f81223e0efc2b7006f83.

* Support multiple platforms

* Typed

* Consider Alpine

* Bumped @zeit/nsfw to latest version

* Update src/commands/dev/lib/nsfw-module.ts

Co-Authored-By: leo <mindrun@icloud.com>

* Pass module path differently

* Bumped package

* Make binary executable

* Wait until piping is complete

* Added debug statements
2019-04-25 14:58:43 +00:00
Amio
de560ea31a Enable '@typescript-eslint/no-unused-vars': 'warn' (#2172)
* Enable '@typescript-eslint/no-unused-vars': 'warn'

* Clean comments
2019-04-25 14:58:37 +00:00
Nathan Rajlich
f90179761f Enable source maps for development builds of now-cli (#2170)
If you run `yarn build-dev`, then now source maps are enabled, allowing
us to see the proper line of an error in the source code file instead of
the huge `dist/index.js` file.

Previously they were only enabled for production builds.
2019-04-25 14:58:32 +00:00
Ana Trajkovska
e35ce0591f Handle additional errors when issuing a certificate (#2165)
* Handle additional errors when issuing a certificate

* Rename errors

* Provide more context in CertsDNSError

* Fix CertsDNSError structure

* Display cns with join

* Fix CertsDNSError
2019-04-25 14:58:26 +00:00
Nathan Rajlich
5ccf7013fe [now dev] Add host property to the invoke payload (#2164)
Fixes https://github.com/zeit/now-builders/issues/390.
2019-04-25 14:58:06 +00:00
Nathan Rajlich
74d2a7da58 [now dev] Use empty version string for @now/static (#2159)
This is just a cosmetic fix so that "vbuilt-in" isn't printed when
`--debug` is enabled.
2019-04-25 14:58:01 +00:00
Nathan Rajlich
691e9ea1ee [now dev] Don't run every build when a v1 builder is detected (#2151)
Before this, if a v1 builder was detected then every build match was
built instead of only the matches that use a v1 builder.
2019-04-25 14:57:55 +00:00
Nathan Rajlich
3ea00009aa [now dev] Fix index-based asset lookup logic (#2138)
There was a bug in the index lookup logic such that `GET /404` would be
matching the `/index.*` file. Fixed in this commit.
2019-04-25 14:57:41 +00:00
Andy Bitz
10af9ce5c5 15.0.6 2019-04-18 21:26:53 +02:00
Andy
d4fbbd6dfe Show all aliases instead of just the first one (#2188) 2019-04-18 21:26:07 +02:00
Andy
9994fc0824 Now CLI gets a fixed alias (#2189) 2019-04-18 21:25:57 +02:00
Andy Bitz
c7beaaab94 Revert "Revert "Fix batch file command to work from paths with spaces. (#2144)""
This reverts commit 16c2946e32.
2019-04-18 21:25:08 +02:00
Andy Bitz
ba02d56a4e 15.0.5 2019-04-17 21:12:45 +02:00
Andy
e03d16462f Add tests for the new automatic aliasing in the v9 API (#2180)
* Add tests for the new automatic aliasing in the v9 API

* Show a more descriptive message

* Await sleep

* Add sleep to test

* Decrease sleep
2019-04-17 21:05:48 +02:00
Andy
0547a82a5c Use the v9 deployments API (#2176) 2019-04-17 21:05:40 +02:00
Andy Bitz
16c2946e32 Revert "Fix batch file command to work from paths with spaces. (#2144)"
This reverts commit ce4d9d21d6.
2019-04-17 10:57:19 +02:00
Duncan
ce4d9d21d6 Fix batch file command to work from paths with spaces. (#2144)
Fixes #2413.
2019-04-17 10:53:29 +02:00
William Li
479f224240 [BUG-FIX] team invite ignored scope error (#2140)
* expose teams command to --scope change, fixes #2139
2019-04-12 18:36:37 +08:00
Leo Lamprecht
b8abd8e6b2 15.0.4 2019-04-11 11:36:22 +00:00
Nathan Rajlich
6748053233 [now dev] Refactor to support shouldServe() in Now Builders (#2134)
* WIP refactor to Now Builders v2 API

* More WIP

* Finish up refactor

* Remove `BuiltAsset` type

These properties are on the the `BuildMatch` interface now.

* Fix `handle: filesystem` route post-refactor

* Prettier

* Update src/commands/dev/lib/builder-cache.ts

Co-Authored-By: leo <mindrun@icloud.com>
2019-04-11 11:30:46 +00:00
Amio
3cc3b17b1d Improve eslint config (#2042)
- Get `.ts` files covered 🎉
- Update eslint related dependencies
- Add typescript-eslint [recommended rules](3e26ab684a/packages/eslint-plugin/src/configs/recommended.json), but only enabled ones we already followed, commented ones causing errors.

Commented rules including:

```yaml
  # '@typescript-eslint/no-unused-vars': 1
  # '@typescript-eslint/indent': ['error', 2]
  # '@typescript-eslint/array-type': error
  # '@typescript-eslint/ban-types': error
  # '@typescript-eslint/explicit-member-accessibility': error
  # '@typescript-eslint/member-delimiter-style': error
  # '@typescript-eslint/no-angle-bracket-type-assertion': error
  # '@typescript-eslint/no-explicit-any': warn
  # '@typescript-eslint/no-object-literal-type-assertion': error
  # '@typescript-eslint/no-use-before-define': error
  # '@typescript-eslint/no-var-requires': error
  # '@typescript-eslint/prefer-interface': error
```

### TODO

Go through these commented rules one by one, enable & fix for it or confirm it's disabled. Since enabling some rules would cause massive code change (like `'@typescript-eslint/indent': ['error', 2]`), which might conflict with our ongoing development, we better do this in separated PRs.
2019-04-11 11:30:40 +00:00
Mark Glagola
1d525023df Handle CAA cert conflict error (#2121)
* Handle CAA cert conflict error

* Fixed error description

* using output.success instead of console.log(...)

* Revert "using output.success instead of console.log(...)"

This reverts commit 2db9a834f3d22ec2da7c692b0e67ea2863078489.
2019-04-11 11:30:35 +00:00
Leo Lamprecht
be1ebdbdd3 Add a note about the CDN always being enabled (#2133)
* Revert "Stop indicating whether CDN is enabled (#2132)"

This reverts commit 3dda3e84bf.

* Add a note about the CDN always being enabled

* Removed useless flag

* Added correct table heading
2019-04-11 11:30:32 +00:00
Leo Lamprecht
90aae568c5 Stop indicating whether CDN is enabled (#2132) 2019-04-11 11:30:27 +00:00
Leo Lamprecht
c311ecbc07 Print full validation error message (#2131)
* Print full validation error message

* Shortened second message

* Updated latest pipeline too
2019-04-11 11:30:19 +00:00
Mark Glagola
1a676c0203 fixes certs rate limited cns arg (#2130) 2019-04-11 11:30:15 +00:00
Amio
692a08c134 Bump ava to 1.4.1 (#2128) 2019-04-11 11:30:11 +00:00
Mark Glagola
321ee681c5 Handle unsupported tld purchase (#2129) 2019-04-11 11:30:07 +00:00
Nathan Rajlich
8847783063 [now dev] Add logging of the builder package versions (#2125)
* [now dev] Add logging of the builder package versions

To aid in debugging errors reported by users.

* Remove bad
2019-04-11 11:29:59 +00:00
Mark Glagola
9c0cf1eb9e Fix getCertsById + handle cert not found by id error (#2101)
* fix certs delete + handle not found error

* Converted rm.js -> rm.ts
2019-04-11 11:29:54 +00:00
Nathan Rajlich
688d50b662 [now dev] Add build de-duping for the lazy initial builds case (#2124)
This is the same de-duping logic that occurs when you hard refresh,
but the unbuilt case was still not being considered. This fixes clicking
on an unbuilt link more than once from triggering multiple builds of the
same asset.
2019-04-11 11:29:48 +00:00
Leo Lamprecht
4039ae9772 15.0.3 2019-04-08 12:16:20 +00:00
Nathan Rajlich
88842d5a54 [now dev] Update @now/build-utils to v0.4.40 (#2119) 2019-04-08 12:03:52 +00:00
Nathan Rajlich
44d02b78ac [now dev] Update @now/build-utils to v0.4.40-canary.0 (#2118) 2019-04-08 12:03:48 +00:00
Nathan Rajlich
c3d5a7b8ff [now dev] Add handle: filesystem support (#2116) 2019-04-08 12:03:42 +00:00
Nathan Rajlich
403d24d934 [now dev] Run npm update to get builder updates (#2117) 2019-04-08 12:03:35 +00:00
Mark
943fe8989b Update @zeit/ncc to v0.17.4 (#2107) 2019-04-08 12:03:30 +00:00
Nathan Rajlich
893fe29514 [now dev] Run prepareCache() asynchronous (#2105)
* [now dev] Run `prepareCache()` asynchronous

And also wait a few seconds before running the actual logic,
since the `prepareCache()` function may be computationally expensive,
and its run in the same process as `now dev` (for now), so allow
some time for the current HTTP request to complete.

* Add symlinks support to `glob()`, instrument prepareCache time
2019-04-08 12:03:26 +00:00
Nathan Rajlich
568559daa5 [now dev] Invoke prepareCache() from Builders (#2104)
If a builder defines the `prepareCache()` function, then it gets invoked
after `build()` has completed to set up the initial build state of the
next build for this same asset.

For example, the goal for `@now/node` if the package.json has not
changed is to have yarn produce the "Already up-to-date" message on the
next build, because installing dependencies ends up taking a long time
on bigger projects.
2019-04-08 12:03:21 +00:00
Andy
9e713e0565 Exit if assigning an alias failed while deploying (#2103)
* Error if aliasFinal is an empty array

* Return if alias assignment failed
2019-04-08 12:03:14 +00:00
Leo Lamprecht
583b566133 15.0.2 2019-04-05 14:00:22 +00:00
Leo Lamprecht
4f639e608b Make npm not prefer offline (#2102) 2019-04-05 15:48:53 +02:00
Nathan Rajlich
70c2c42416 [now dev] Use a different workPath for every build (#2100)
This is more inline with how a fresh Now deployment works, where
is has to download fresh files each time. This will also fix the issue
with `@now/next` that deleted the `.next` output dir and deleting static
files upon subsequent builds.

This is still a bit unoptimized because `prepareCache()` from the
builder is not yet being invoked, but it's still more correct than
reusing the `workPath`.
2019-04-05 13:33:35 +00:00
Nathan Rajlich
ec56091f98 Ignore .env and .env.build for deployments by default (#2083)
Because `now dev` uses these dotenv files to define the Now secrets to
use, it would be bad practice to include them in the deployment files
since they will be using development values instead of production values.
2019-04-05 13:33:31 +00:00
Nathan Rajlich
4325aa9eb4 [now dev] Clean up dev-router a bit (#2099)
* [now dev] Clean up `dev-router` a bit

This is a follow up to #2095 to move the `resolveRouteParameters()`
funcrtion to the top-level and other slight optimizations like not
re-parsing the URL multiple times.

* Remove unused `qs` import
2019-04-05 13:33:27 +00:00
Nathan Rajlich
e01549a978 [now dev] Remove now dev cache clean (#2097) 2019-04-05 13:33:24 +00:00
William Li
2d855391b6 [now dev] Apply route params to headers (#2095)
* version bump (canary)

* inject paramters into headers.Location fixes #2092

* refactored route parameter resolving function

* Revert "version bump (canary)"

This reverts commit 5857489ceffcbcce07eb6e5d6fcc20279d0ba5fd.

* Update src/commands/dev/lib/dev-router.ts

Co-Authored-By: williamli <email@williamli.dev>

* refactor headers resolution

* try to resolve all parameters inside each child of headers
2019-04-05 13:33:20 +00:00
Nathan Rajlich
feb88e5aa3 [now dev] Set the same MemorySize on the lambdas as production (#2096)
This should fix https://spectrum.chat/zeit/now/now-dev-javascript-heap-out-of-memory~3fd6e823-59de-426b-ade0-af48d18f3494
2019-04-05 13:33:15 +00:00
Nathan Rajlich
257a8e7be1 Remove 'output logs of a 1.0 deployment' integration test (#2085)
This test is very flaky causing us to constantly restart CircleCI jobs
in order to do releases of `now-cli`. Considering that it's testing the
1.0 pipeline, let's just remove this one to make life easier.
2019-04-05 13:33:11 +00:00
Nathan Rajlich
f0473e9155 [now dev] Fix the requestPath for the hard-refresh case (#2086)
This passes in the resolved `assetKey` instead of `req.url` to the
builder `requestPath` when a hard-refresh is requested, allowing the
proper single-page rebuild to happen.
2019-04-05 13:33:05 +00:00
Nathan Rajlich
e0a3a39faa [now dev] Fix subscription resolving logic (#2082)
* [now dev] Fix subscription resolving logic

Strip the leading `/` since the builder outputs don't have one, match
index routes, and pass the resulting subscription key to the builder.

* Fix `index` matching

* Update `@now/build-utils` to v0.4.39-canary.0

* Update `@now/build-utils` to v0.4.39
2019-04-05 13:33:00 +00:00
Nathan Rajlich
c24afe3714 [now dev] Respond with 404 once the server is shutting down (#2070)
In the case of a keep-alive connection from the web browser, and a page
continuing to send HTTP requests to the dev server, sometimes the server
never shuts down. So send a 404 response with `Connection: close` to
force the web browser to close the connection.
2019-04-05 13:32:56 +00:00
Nathan Rajlich
705fdfba38 [now dev] Add support for Builder "subscriptions" (#2071)
If the builder has a `subscribe()` function, then the initial
builds are not run and instead an array of "subscriptions" is
created. When an HTTP request comes in that matches one of the
subscription patterns, then this builder will be actually be
executed.
2019-04-05 13:32:52 +00:00
Nathan Rajlich
210d4f9d5c [now dev] Pass meta object to Builders' build() function (#2069)
This introduces a new object called `meta` that gets passed to the
Now Builders' `build()` function. The `isDev` property is moved to
this object, and a new property `requestPath` is also introduced.

`requestPath` represents the URL that was requested to trigger the
`build()` to be called. It may be used by builders to do incremental
compilation and only re-build the assets related to the URL that was
requested. For example, `@now/next` may use this property to only build
the page that was requested.
2019-04-05 13:32:48 +00:00
Nathan Rajlich
8396f17c40 Update pcre-to-regexp to v0.0.5 (#2068)
For `now dev`, this fixes an edge case in named capture groups
in some `routes` definitions that would lead to an error being thrown:

```
Cannot read property '1' of null
```

Also ignoring "handler" routes for now.
2019-04-05 13:32:44 +00:00
Nathan Rajlich
cc22b4a005 Update @zeit/ncc to v0.17.3 (#2058) 2019-04-05 13:32:39 +00:00
William Li
f8cbe364be Don't forget to do a yarn install before linking (#2094) 2019-04-05 02:11:35 +02:00
Leo Lamprecht
242be8da28 15.0.1 2019-04-01 15:51:50 +00:00
Nathan Rajlich
67157c5a92 [now dev] Update bootup message (#2056)
This looks a bit cleaner since the user just typed `now dev` into their
CLI so no need to print the same command again.
2019-04-01 15:42:12 +00:00
Nathan Rajlich
f3764abd19 Update @now/build-utils to v0.4.38 (#2055) 2019-04-01 15:42:09 +00:00
Leo Lamprecht
5a49c41b20 15.0.0 2019-04-01 11:13:50 +00:00
Leo Lamprecht
810e27c08d Adjusted aliasing error message to match server (#2030)
* Adjusted aliasing error message to match server

* Correctly escape
2019-04-01 11:03:45 +00:00
Leo Lamprecht
37e3c6132c Made aliases clickable after assigning (#2035)
* Made aliases clickable after assigning

* Set in correct place

* Fixed URL

* Attached alias

* Added missing https
2019-04-01 11:03:30 +00:00
Andy
4a6e565027 Group builds with similar paths together to reduce the output (#2015)
* Group builds with similar paths together to reduce the output

* Style the new output

* Ensure space between state and time

* Update src/util/output/builds.js

Co-Authored-By: AndyBitz <AndyBitz@users.noreply.github.com>

* Add comma between ready states

* Tell what is hidden

* Change builds and items
2019-04-01 11:03:16 +00:00
Amio
03f45f5d3e Refine test jobs (#2028)
- Include `.ts` extension
- Include all `test/*unit.js` (`test-unit` task)
- Make coverage reporting a separate job in circleci config
2019-04-01 11:03:11 +00:00
Nathan Rajlich
0c5bae6f37 [now dev] Add support for .env and .env.build file to define Now secrets (#2048)
* [now dev] Add support for `.env` file to define Now secrets

If a `now.json` files relies on secret env vars, then they must be
defined in the user's local `.env` file otherwise `now dev` exits with
an error.

* Prettier

* Fix multi-line error output

* Use `code()` to format the dotenv file name

* Add "file" to error message for clarity

* Use `hasOwnProperty()` instead of `in`

* Apply `build.env` vars during builder `build()` invocations

Fixes #2046.
2019-04-01 13:01:57 +02:00
Nathan Rajlich
f9f29485ad Update @zeit/fun to v0.6.0 (#2049) 2019-04-01 13:01:57 +02:00
Nathan Rajlich
9033bcddfe [now dev] Use cyan for link color
Blue is hard to read on terminals with a black background.
2019-04-01 13:01:57 +02:00
Nathan Rajlich
f1873c51d2 [now dev] Add build deduping (#2044)
Consider the scenario where an HTML asset is built and references other
files that were produced by the build (CSS/JS/img/etc. files). The build
will happen and then the HTML page will be served, and then the browser
will request the assets on the page also with the `no-cache` header,
which would cause a second build right after the first one completed,
which is bad DX and unnecessary.

This commit introduces "build deduping logic" so that this scenario is
avoided by doing two things:

1. Not allowing the same entrypoint to be built at the same time (so if
   a concurrent request happens for an asset that was produced by the same
   entrypoint, the subsequent requests will wait on the already running build
   instead of triggering a new one in parallel.

2. Not allowing an asset to be rebuilt if the previous build completed
   less than two seconds ago. This is to catch the scenario where the
   HTML page is served and the browser quickly requests the assets on
   the page to avoid triggering a second rebuild.
2019-04-01 13:01:57 +02:00
Nathan Rajlich
af3594e106 [now dev] Set the Now proxy and response headers (#2041)
* [now dev] Set the Now proxy and response headers

* Add `X-Real-IP` proxy header

* Set any headers defined in the matched `route` config

* Apply @amio's suggestions
2019-04-01 13:01:57 +02:00
Nathan Rajlich
3e8a8ac79f [now dev] Send INTERNAL_LAMBDA_NOT_FOUND (#2039)
This is mostly to appease TypeScript since `fn` is an optional prop,
but this shouldn't really ever happen since we run the builds before
responding to HTTP requests.
2019-04-01 13:01:57 +02:00
Nathan Rajlich
bc7153883d [now dev] Use the Output helper (#2038)
* [now dev] Use the `Output` helper

For more consistent logging / styling with the other `now` commands.

* Put `setStatusError()` back
2019-04-01 13:01:57 +02:00
Nathan Rajlich
92826db86b [now dev] Send the NO_STATUS_CODE_FROM_LAMBDA upon lambda error (#2037) 2019-04-01 13:01:57 +02:00
Nathan Rajlich
9ea2216d4a [now dev] Fix the path provided to lambda invocations (#2036)
This matches how the Now proxy invokes the lambdas, where the route
`dest` query params are mixed-in to the provided `req.url`, with the
dest query params taking precedence over any conflicting user-provided
query params.
2019-04-01 13:01:57 +02:00
Nathan Rajlich
df6eb070d8 Add output to DevServer class (#2034) 2019-04-01 13:01:57 +02:00
Nathan Rajlich
632d7b0651 [now dev] Listen on the next available port when requested port is taken (#2032)
Fixes #2024.
2019-04-01 13:01:57 +02:00
Nathan Rajlich
fd3c110c02 [now dev] Use pcre-to-regexp to match routes (#2027)
* [now dev] Use `pcre-to-regexp` to match `routes`

The now.json `routes` support PCRE syntax like named captures,
so use the `pcre-to-regexp` module to match the routes.

Fixes #2023.

* Pass the resolved router `dest` and query params to the Lambda
2019-04-01 13:01:57 +02:00
Nathan Rajlich
6c8dc90267 [now dev] Centralize error responses logic (#2026)
This just DRYs up the code a bit and centralizes the error sending logic
so that we can more easily add the HTML and JSON versions of the
responses as well.
2019-04-01 13:01:57 +02:00
Nathan Rajlich
3f57d1381e [now dev] Don't add .gitignore to the ignore list (#2025)
`.gitignore` is not respected anymore for Now v2, so this was a bug.

Also removes `ncc` and `user` from the ignore list, since that issue was
fixed a while back as well.

Fixes #2021.
2019-04-01 13:01:57 +02:00
Amio
02b3c5f535 Add now dev (#1883)
* [WIP] now-dev

* try invoking lambda

* add error status to dev-server

* add basic routing

* add entry for custom @now/static builder

* honor .gitignore & .nowignore while collecting files

* add route for single static file

* add test fixtures for now-dev (nodejs)

* fix miss typed @now/statics

* import types from @now/build-utils

* fix typo @now/statics -> @now/static

* revamped router

* typescript-eslint-parser -> @typescript-eslint/parser

Eliminate error while running pre-commit hooks:

  SUPPORTED TYPESCRIPT VERSIONS: ~3.1.1
  YOUR TYPESCRIPT VERSION: 3.2.2

* send files from local @now/static builder

* use serve-handler when no now.json

* remove http-proxy

* add type def for serve-handler

* code cleanup

* move type declarations to types.ts

* dont rely on `this.cwd` while running builder

* more type definitions

* fix invoking error

* clean code

* better debug logging

* refined request handler logic

* handle /favicon.ico with serve-handler

* make builder-cache self contained

* move builder works to dev-builder.ts

* add proxy_pass handler

* support named groups in routes

* fix creating cache dir error

* add "--nodejs-preview" solely for nodejs

* clean require.cache after required user js

* fix router & header issue in nodejs preview

* [wip] add tests for dev-router

* add tests for dev-router

* lookup "/index.*" for indexes

* refine logging

* [WIP] `now dev` progress point

Actually invoking the `@zeit/fun` module at this point.

Still lots of work to be done…

* Update `@zeit/fun` to v0.0.4

* Remove `--nodejs-preview`

To be replaced by `@zeit/fun`.

* Remove `decache` and `import-fresh`

Leftover from the `--nodejs-preview`.

* Remove "declaration: true" from `tsconfig.json`

Otherwise the ncc `dist` dir ends up full of generated `.d.ts` files.

* Remove `ignore` dep, always use `@zeit/dockerignore`

* Use tarball URL for `@zeit/fun`

Because `@zeit/fun` is not yet public on npm.

* Regenerate `yarn.lock` to fix bad integrity check on fun tarball

* Upgrade to `@zeit/fun` v0.0.6

With re-written unzipping logic utilizing `yauzl`.

* Add lambda function handling logic for the HTTP response

* Match the lambda invoke shape that Now's proxy provides

* Move deps to devDependencies

* Update `@zeit/fun` to v0.0.8

* Update `@zeit/ncc` to v0.15.0

* Attempt to fix unit test for `wait()` helper function

* Add `build.sh` script to work around ncc issues

* Fix `build.sh` script for BSD's chmod

No `--changes` flag.

* Update `@zeit/fun` to v0.0.11

* Update `@zeit/fun` to v0.0.12

* Tweak some comments

* Update `@zeit/fun` to v0.0.13

* Add `now.json` env vars to lambda functions

* Finish removing `--nodejs-preview` flag

* Style tweaks

* Use `npm-package-arg` to parse the "use" builder

* Styling

* Use the parsed `pathname` when matching routes

The querystring portion needs to be removed to match properly.

* Update `@zeit/fun` to v0.1.1

* Support `-d` for debug flag

It was already listed as such in the `--help` output.

* List the `dist/runtimes` dir as pkg "assets"

* Update `@now/build-utils` to v0.4.37-canary.0

* Update `@zeit/fun` to v0.2.0

* Update `@zeit/fun` to v0.2.1

* Rewrite the `req.url` to fix serving FileFsRef assets

* Disable re-building, build all `builds` upon server bootup

* 404 is not a redirect

* warning on more than one argument

* Fix `index` without a file extension matching

* Update `@zeit/fun` to v0.2.2

* Use `async-listen`

* Add shutdown cleanup logic

* Rename `buildLambdas()` to `executeBuilds()`

* Rename `lambda` prop to `fn`

* Misc tweaks

* Pass `isDev: true` to the builder `build()` function

* Use `Object.assign()` instead of object spread

* Set `res.statusCode` instead of `writeHead()`

* Create Lambda functions during build-time

This way, the lambda instance is re-used for subsequent HTTP requests

* Wait for cleanup operations to complete in `stop()`

* Destructure `path` for join()

* Add some missing types

* Store the `buildConfig` on the assets for reverse lookup

* Remove `console.log()`

* Attempt to make globbing faster and ignore files more accurately

* Rewrite `installBuilders()` to be idempotent

So that npm is not executed for canary tags, for example.

This is done by comparing the contents of the package.json file rather
then the `node_modules` directory.

* Use `ignore` instead of `@zeit/dockerignore` for glob-gitignore

It seems that the object produced by `@zeit/dockerignore` is not
compatible with the `glob-gitignore` module, so use the vanilla
`ignore` module instead for now as a workaround.

* Implement a `GlobIgnore` class to replace `glob-gitignore`

This allows us to continue using `@zeit/dockerignore` for proper
consistency.

Closes #1899.

* Prettier

* Skip installing built-in builders (i.e. `@now/static`)

* Remove `console.error()` calls

* Use a deterministic `workPath` directory

So that the same one is re-used in-between subsequent boots of `now dev`

* Add `now.json` validation logic

* Fix serving static assets outside the project working directory

This fixes, for example, `@now/mdx-deck` which outputs static files
from its build process.

* Add comment

* Validate the `now.json` file before launching the dev server

* Respect `maxLambdaSize` config

Closes #1950.

* Add `@types/bytes` dependency

* Make `maxLambdaSize` be optional

Co-Authored-By: TooTallNate <n@n8.io>

* WIP force reload in browser = rebuild asset behavior

* Resolve the `asset` again after re-build

* Remove logging

* Update `@zeit/fun` to v0.3.0

* Update `@now/build-utils` to v0.4.37-canary.1

Sets `npm_config_target` to the proper Node.js version for native
modules.

* Update `@zeit/fun` to v0.3.1

* Fix "hard refresh to reload" after the first rebuild

The `buildConfig` and `buildEntry` proper were not being set on the
rebuilt assets, causing the rebuild to only work the first time.

Now fixed.

* Add logic for the `now dev cache clean` command (#1977)

* Added the cache-clean command

* censer code :)

* Fix non-route match `dest` param

This makes the `go-image-to-ascii` work, since the query param URL gets
properly routed to the `/` route.

* Add support for `FileBlob` outputs

Fixes `@now/optipng`, `@now/html-minifier` and `@now/md` builders.

* Remove `console.error()` call

* Add `now dev cache clean` command

* Use the `assetKey` to look up the Content-Type on FileBlobs

Instead of the `fsPath` of the entrypoint file.

This fixes `@now/md` to return `text/html` Content-Type instead of
`text/markdown` which does not render properly in the web browser.

* Update `@zeit/ncc` to v0.16.1

Co-Authored-By: TooTallNate <n@n8.io>

* Regenerate `yarn.lock` file

* Remove leading `/` on build `src` specifications

* Use `rsync` to copy over all of `fun`'s runtime files

* Update `@zeit/fun` to v0.5.0

* Update `@zeit/fun` to v0.5.1

* try/catch the lambda invoke and send 500 upon error

* Add `rsync` to CircleCI build

* Convert `errors.js` to TypeScript to fix compilation errors

* Also accept `Cache-Control: no-cache` for rebuilding

* Prettier

* Update `@now/build-utils` to v0.4.38-canary.1

* Update `@zeit/ncc` to v0.17.0 (#2017)

* Install `@zeit/fun` from npm

* Remove `console.error()` call

Co-Authored-By: TooTallNate <n@n8.io>

* Create `NowError` subclasses

* Add `LambdaSizeExceededError`

* Return early if there's no builds
2019-04-01 13:01:57 +02:00
Julian Gruber
4e11f7f064 14.2.4 2019-03-28 14:38:21 +01:00
Julian Gruber
52d214f1ff Fixed the handling of user errors (#1989)
* Fixed duplicate `--local-config` option
* Fixed uncaught `ERRORS.DomainPermissionDenied`
* Fixed uncaught `ERRORS.DeploymentNotFound`
* Added arguments parsing errors to Sentry scope
* Fixed stale stream in `cleanup()` of `promptOptions()`
* Fixed uncaught `USER_ABORT`
* Fixed uncaught `ENOENT`
2019-03-28 14:34:39 +01:00
Julian Gruber
3a0b5c33cd Fix the handling of unexpected user errors (#2022)
* fix unexpected `DNSConflictingRecord`

* fix unexpected `EBADF`

* fix unexpected `InvalidDeploymentId`

* fix unexpected `InvalidDomain`

* fix unexpected `DomainNotFound`
2019-03-28 14:30:12 +01:00
Julian Gruber
809356afed Fixed GET /v3/now/certs (#2005)
* Fixed `GET /v3/now/certs`

- Limit the response size to 20 because the endpoint doesn't have a default limit
- If the id in `/v3/now/certs/{id}` isn't a valid id the endpoint responds with a set or certs instead
- The route `/v3/now/certs/{idOrCn}` isn't supported any more

* removed limit of 20, the endpoint was updated
2019-03-28 14:30:02 +01:00
Julian Gruber
1b01015a8c Fixed the handling of user errors in legacy deploy command (#2006)
* fix disconnected promise chain in legacy deploy
* fix `size_limit_exceeded` in legacy
2019-03-28 14:29:56 +01:00
Julian Gruber
ef2d75394a Fixed the handling of unexpected DeploymentFailedAliasImpossible (#2020) 2019-03-28 14:29:40 +01:00
Joe Cohen
c0c4a7f254 fix typo on domains inspect (#2016) 2019-03-28 14:22:42 +01:00
Leo Lamprecht
121343e1dd 14.2.3 2019-03-22 01:02:53 +00:00
Leo Lamprecht
a4294cfe84 Make deployments without builds work (#2004)
* Make deployments without builds work

* Added integration test

* Fixed test
2019-03-22 01:02:37 +00:00
Leo Lamprecht
c86e750883 14.2.2 2019-03-21 03:01:24 +00:00
Leo Lamprecht
75dd772811 Only block deployment exit if not error (#2000) 2019-03-21 03:01:16 +00:00
Leo Lamprecht
f4849cd55e 14.2.1 2019-03-21 01:30:42 +00:00
Leo Lamprecht
ce7d75d6b2 Only announce deployment as ready if alias is set (#1997) 2019-03-20 23:52:14 +00:00
Leo Lamprecht
720aee7250 14.2.0 2019-03-19 12:17:42 +00:00
Leo Lamprecht
47ca5f3072 Made -S short flag work properly (#1988) 2019-03-19 09:44:41 +00:00
Julian Gruber
0ce633a1ea Add always report stdarg to Sentry (#1982)
Before this change, only if `user` or `team` could be read from
the scope would stdarg be reported to Sentry, however it's
completely unrelated to the existence of the former and is always
useful debugging information.
2019-03-19 09:13:42 +00:00
Julian Gruber
93d0019153 Fix the handling of user errors (#1984)
* fix `ms(null)` in `certs rm`

* fix uncaught `InvalidDomain`
2019-03-19 09:13:37 +00:00
Julian Gruber
f89417c06c Fix null pointer access in error reporting (#1983)
* fix null pointer access in error reporting

* refactor
2019-03-19 09:13:33 +00:00
Amio
6344a08c91 Add hint about -f in now init error message (#1971) 2019-03-19 09:13:14 +00:00
Andy
a981c711b6 Handle the DomainNotVerified error for deployments (#1973) 2019-03-19 09:13:08 +00:00
Leo Lamprecht
3b250af6d6 Warn of now alias was used (#1972)
* Warn of `now alias` was used

* Mention deploy command
2019-03-19 09:13:04 +00:00
Leo Lamprecht
70de080be7 Improved deployment output (#1968)
* Prefix all aliases that are printed

* Pass local config

* Print if --target production is defined, but not alias prop

* Moved warning message
2019-03-19 09:12:59 +00:00
Julian Gruber
f629787d04 Fix the handling of user errors (#1959)
* fix unexpected `size_limit_exceeded`

* fix unexpected `deployment_type_unsupported`

* fix unexpected `JSONError`

* check if err.sizeLimit exists
2019-03-19 09:12:54 +00:00
Julian Gruber
e20ba6e741 Added back sending process args to Sentry (#1966)
* add `process.argv` to Sentry, without sensitive data

* refactor using `arg` parser

* add secret alias support
2019-03-19 09:12:51 +00:00
Mark Glagola
00d30d2ddc adds prompt when moving domain to team user is not member of (#1965) 2019-03-19 09:12:47 +00:00
Leo Lamprecht
9921d282d3 Improved output for deploy command (#1962)
* Make alias links clickable

* Make output print Ready instead of Success

* Fixed missing export
2019-03-19 09:12:42 +00:00
Leo Lamprecht
b70678a8a9 Allow --target to be set to staging (#1955)
* Allow `--target` to be set to `staging`

* Properly format output

* Added clipboard support

* Send target to server

* Make target optional
2019-03-19 09:12:38 +00:00
Andy
3fc9051268 Added support for the --target flag (#1893)
* Add support for the target flag

* Show the given alias at the end

* Use the proper naming for the alias properies and include arrays

* Use the correct output

* Make sure that aliasFinal has properties
2019-03-19 09:12:32 +00:00
Leo Lamprecht
436c7fe0ad 14.1.1 2019-03-18 13:17:10 +00:00
Leo Lamprecht
7c837caef9 Make --scope take priority over scope (#1985) 2019-03-18 13:16:59 +00:00
Leo Lamprecht
fbe751e348 Revert "Added support for the --target flag (#1893)"
This reverts commit 2fea26772d.
2019-03-18 13:10:01 +00:00
Leo Lamprecht
dc95b8584d Revert "Allow --target to be set to staging (#1955)"
This reverts commit d8d51b7128.
2019-03-18 13:10:00 +00:00
Leo Lamprecht
4e715bc408 Revert "Improved output for deploy command (#1962)"
This reverts commit 0e2d23f01c.
2019-03-18 13:09:59 +00:00
Leo Lamprecht
9093fcebcd Revert "adds prompt when moving domain to team user is not member of (#1965)"
This reverts commit 8d33b2c866.
2019-03-18 13:09:58 +00:00
Leo Lamprecht
d6e1508ffc Revert "Added back sending process args to Sentry (#1966)"
This reverts commit 8ee47fbc90.
2019-03-18 13:09:57 +00:00
Leo Lamprecht
02b59926d5 Revert "Fix the handling of user errors (#1959)"
This reverts commit d059597a63.
2019-03-18 13:09:56 +00:00
Leo Lamprecht
a78770c11e Revert "Improved deployment output (#1968)"
This reverts commit b0ab91d794.
2019-03-18 13:09:54 +00:00
Leo Lamprecht
d3d72f0bb3 Revert "Warn of now alias was used (#1972)"
This reverts commit 473eae1c65.
2019-03-18 13:09:53 +00:00
Leo Lamprecht
09aa8400ab Revert "Handle the DomainNotVerified error for deployments (#1973)"
This reverts commit ae2dfd41d2.
2019-03-18 13:09:52 +00:00
Leo Lamprecht
41cea25bb0 "Revert "Add hint about -f in now init error message (#1971)"
This reverts commit 6f386e7ca2.
2019-03-18 13:09:41 +00:00
Amio
6f386e7ca2 Add hint about -f in now init error message (#1971) 2019-03-18 09:45:15 +00:00
Andy
ae2dfd41d2 Handle the DomainNotVerified error for deployments (#1973) 2019-03-18 09:45:11 +00:00
Leo Lamprecht
473eae1c65 Warn of now alias was used (#1972)
* Warn of `now alias` was used

* Mention deploy command
2019-03-18 09:45:05 +00:00
Leo Lamprecht
b0ab91d794 Improved deployment output (#1968)
* Prefix all aliases that are printed

* Pass local config

* Print if --target production is defined, but not alias prop

* Moved warning message
2019-03-18 09:45:00 +00:00
Julian Gruber
d059597a63 Fix the handling of user errors (#1959)
* fix unexpected `size_limit_exceeded`

* fix unexpected `deployment_type_unsupported`

* fix unexpected `JSONError`

* check if err.sizeLimit exists
2019-03-18 09:44:48 +00:00
Julian Gruber
8ee47fbc90 Added back sending process args to Sentry (#1966)
* add `process.argv` to Sentry, without sensitive data

* refactor using `arg` parser

* add secret alias support
2019-03-18 09:44:42 +00:00
Mark Glagola
8d33b2c866 adds prompt when moving domain to team user is not member of (#1965) 2019-03-18 09:44:36 +00:00
Leo Lamprecht
0e2d23f01c Improved output for deploy command (#1962)
* Make alias links clickable

* Make output print Ready instead of Success

* Fixed missing export
2019-03-18 09:44:08 +00:00
Leo Lamprecht
d8d51b7128 Allow --target to be set to staging (#1955)
* Allow `--target` to be set to `staging`

* Properly format output

* Added clipboard support

* Send target to server

* Make target optional
2019-03-18 09:43:29 +00:00
Andy
2fea26772d Added support for the --target flag (#1893)
* Add support for the target flag

* Show the given alias at the end

* Use the proper naming for the alias properies and include arrays

* Use the correct output

* Make sure that aliasFinal has properties
2019-03-18 09:42:21 +00:00
Leo Lamprecht
d430953d1e 14.1.0 2019-03-14 15:29:28 +00:00
Leo Lamprecht
f099496aba Added warning message about files with no deployments (#1960)
* Added warning message about files with no deployments

* Added integration test

* Fixed charset of test
2019-03-14 15:17:14 +00:00
Julian Gruber
78ac52c3b4 Fixed the handling of user errors (#1958) 2019-03-14 15:17:10 +00:00
Julian Gruber
60ea982ed8 Refactored flow error checks (#1953) 2019-03-14 15:17:04 +00:00
Leo Lamprecht
dc80b099bf Soft-deprecate the --team flag (#1956)
* Soft-deprecate the `--team` flag

* Check for warning message

* Removed useless error
2019-03-14 15:16:58 +00:00
Amio /
f40e0a8ff9 Added a deploy hint after now init. (#1952)
* [now-init] add a deploy hint after init

* add CODEOWNERS
2019-03-14 15:16:52 +00:00
Leo Lamprecht
9341136f16 Added --scope flag and scope config property (#1939)
* Added basics for new --scope flag

* Fixed usage information

* Fixed integration test

* Fixed usage information about whoami

* Brought back missing whitespace

* Do not push scope property to API

* Ensure we're only reading local config in one place

* Fixed build

* Added test

* Made scope from config work

* Correctly handle error

* Handle Now errors too when loading local config

* Removed NowError

* Revert "Removed NowError"

This reverts commit cfeebc65251d3eb07f9aeb3e548af1d23c00a18e.

* Fixed CI

* Fixed final bug

* Do not consider switch command

* Made it work as expected

* Added test

* Added yet another test for the scope property

* Added space
2019-03-14 15:16:45 +00:00
Mark Glagola
d1261dd0a5 Fallback to descriptive api error message if we cannot resolve domain rm|move conflict (#1951)
* On domain conflict error, use api error message & check resolvable flag

* Updated domain rm w/ attempt precaution

* smaller domain removal conflict construction
2019-03-14 15:13:59 +00:00
Julian Gruber
7486b6fb60 Fixed the handling of user errors
* fix unexpected `payment_error`

* fix unexpected `deployment_not_found`

* fix unexpected `not_authorized` and `team_deleted`

* make id optional in DeploymentNotFound
2019-03-14 15:13:53 +00:00
Mark Glagola
6e3993ecf8 Adds alias removal warning on domains move (#1933)
* fixes double caret for domains move

* using output.success

* Adds alias removal warning to domains move
2019-03-14 15:13:46 +00:00
Mark Glagola
81c5c15437 Revised domains move flow (#1928)
* Revised domains move flow (rm move-in & move-out for move)

* fixed integration tests for domains move api changes

* handle immediate domain moves

* fixed list scopes integration test

* more integration test fixes
2019-03-14 15:13:39 +00:00
Mark Glagola
d66bf78e23 Added warning for domains-move token expiration (#1916) 2019-03-14 15:13:23 +00:00
Mark Glagola
48786382ec Domain move-in & move-out implementation (#1906)
* Initial domain move-in & move-out implementation

* adjusted move apis

* domains move revisions based on API changes

* root domain func fix

* Minor copy fixes + added some integration test for move-in/out

* Handling move in|out conflict

* rm random quotes
2019-03-14 15:13:16 +00:00
Andy Bitz
4440bb3741 14.0.3 2019-03-03 22:47:26 +01:00
Andy
ef7ead405c Overwrite the default batch file on windows (#1922)
* Overwrite the default batch file on windows

* Suppress echoing of the command
2019-03-03 22:46:43 +01:00
Leo Lamprecht
c61c90a224 14.0.2 2019-03-01 12:05:25 +00:00
Javi Velasco
bb222b2466 Add --no-scale option (#1918)
* Add no-scale option

* Reword --no-scale warning
2019-03-01 12:04:11 +00:00
Olli Vanhoja
1a0cc26f69 Set verify-deployment-scale timeout to 5 minutes (#1915)
The current client side timeout is shorter than the backend
timeout.
2019-03-01 12:03:54 +00:00
Leo Lamprecht
f95cdb30a1 14.0.1 2019-02-26 08:21:58 +00:00
Leo Lamprecht
8308b2a4f3 Prevent error in now inspect if no dest (#1913) 2019-02-26 08:21:41 +00:00
Mark Glagola
c89a19ab84 Using @types/psl typings + handling all potential error cases with psl (#1911) 2019-02-26 08:21:22 +00:00
Javi Velasco
8eaebdee4e Fix wrong error message (#1904) 2019-02-26 08:20:56 +00:00
Leo Lamprecht
07041e1b7b 14.0.0 2019-02-15 11:18:38 +00:00
Mark Glagola
f0c97a33d9 Revised the way conflicts are handled when removing a domain (#1884)
* Revised the way conflicts are handled when rm domain

* agent.ts accepts absolute urls

* "delete" copy -> "remove" for consistency

* Revert "agent.ts accepts absolute urls"

This reverts commit 200158d06fcb80417f197910c40e364f8ea5abb2.

* using proper set custom suffix endpoint

* Reuse InvalidDomain error
2019-02-14 10:30:59 +00:00
Sergii Paryzhskyi
424ad79c36 Add a hint to an error message about missing token (#1877) 2019-02-14 10:29:57 +00:00
Steve Kaliski
c51f902a0c fix typo in alias command (#1870) 2019-02-14 10:29:52 +00:00
Olli Vanhoja
9a5d097f57 Handle dns add 400 errors properly (#1867)
Currently 400 errors are left unhandled.
2019-02-14 10:29:48 +00:00
Mark Glagola
3b9e5b91b1 Handle domain rm attempt for an in progress transfer (#1880) 2019-02-14 10:29:43 +00:00
Mark Glagola
19c74080b8 Catch SourceNotFound error for domains transfer-in (#1879) 2019-02-14 10:29:40 +00:00
Javi Velasco
a5dd13912c Update inspect copy (#1875) 2019-02-14 10:29:36 +00:00
Mark Glagola
046fb8c38e Added import help info to now-cli (now dns -h) (#1876) 2019-02-14 10:29:30 +00:00
Leo Lamprecht
16acc6c424 Bumped fetch-h2 to latest version (#1869)
* Bumped `fetch-h2` to latest version

* Fixed code
2019-02-14 10:29:22 +00:00
Olli Vanhoja
9b74c2db3e Show builds rate limit message correctly (#1866) 2019-02-14 10:29:17 +00:00
Mark Glagola
c462c27751 Handle known domains rm errors (#1868) 2019-02-14 10:29:11 +00:00
Mark Glagola
ba33cd9106 Added transferredAt and transferStartedAt (#1865) 2019-02-14 10:27:00 +00:00
Javi Velasco
e26f31babd Remove cf cdn enabled flag (#1852)
* Remove CDN toggling

* Rename cdnEnabled to cfEnabled

* Rename cfEnabled to cloudfareEnabled

* Remove missing error
2019-02-14 10:26:56 +00:00
Andy
618bcf236c Check if deploymentId exists (#1857)
* Check if deploymentId exists

* Make deploymentId optional for Alias
2019-02-14 10:26:52 +00:00
Arunoda Susiripala
1264b33b49 Check the existence of the project before we delete it (#1837) 2019-02-14 10:26:48 +00:00
Leo Lamprecht
101de40cc6 Render validation errors for Now 1.0 (#1862) 2019-02-14 10:26:43 +00:00
Mark Glagola
9e4dc9e0db Domain transfer in copy change (#1861) 2019-02-14 10:26:39 +00:00
Javi Velasco
d851a5b2d0 Add import zonefile copy (#1860) 2019-02-14 10:26:34 +00:00
Javi Velasco
16fed01d72 Add ability to import a zone file (#1851)
* Add ability to import a zone file

* Use an arg instead of an option for the zone file
2019-02-14 10:26:30 +00:00
Javi Velasco
3ad9b03066 Add missing error: InvalidAuthCode (#1859) 2019-02-14 10:26:24 +00:00
Mark Glagola
f794c99462 Add domain transfer in pricing (#1849)
* Display transfer renewal price for domain transfers

* Check domain transferable status immediately on transfer-in

* Transfer status endpoint change to .../registry

* spelling fix

* Enable transferable check

* Update dependencies
2019-02-14 10:26:19 +00:00
George Tsiolis
9e79e06da9 Update legacy note structure (#1855) 2019-02-14 10:26:12 +00:00
Mark Glagola
45bf56671a "now domains transfer-in" support (#1767) 2019-02-14 10:26:07 +00:00
Andy
937fb75eb2 Added default script that will run if now fails to install (#1832)
* Added default script that will run if now fails to install

* Don't overwrite the default now script before publishing

* Copy the default now binary on publish instead of keeping it inside the dist folder

* Removed download/dist/now

* Changed text
2019-02-14 10:26:01 +00:00
Javi Velasco
5405828d4d 13.1.3 2019-02-04 04:22:52 +01:00
Javi Velasco
5b16110d0b Enhance login (#1873)
* Enhance login

* Consume error from api
2019-02-04 04:20:57 +01:00
Leo Lamprecht
258d7a3feb 13.1.2 2019-01-17 12:23:48 +00:00
Leo Lamprecht
2dd5cd3f63 Ensure name in package.json works for Now 1.0 (#1835)
* Ensure `name` in `package.json` works for Now 1.0

* Fixed integration test
2019-01-17 12:16:12 +00:00
Leo Lamprecht
7e92912972 13.1.1 2019-01-16 23:14:06 +00:00
Arunoda Susiripala
bf2abe724f Fix formatting issues on project rm confirmation (#1834) 2019-01-16 23:13:57 +00:00
Leo Lamprecht
5d6e1e6210 13.1.0 2019-01-16 22:01:50 +00:00
Leo Lamprecht
ba9cae2d56 Ensure project name is always defined (#1833) 2019-01-16 18:45:04 +00:00
Max
4b243346e8 Support new invite format (#1831)
* Support new invite format

* Use null as initial userInfo value

Co-Authored-By: rdev <8418866+rdev@users.noreply.github.com>

* Add missing semicolon

Co-Authored-By: rdev <8418866+rdev@users.noreply.github.com>

* Add missing semicolon

Co-Authored-By: rdev <8418866+rdev@users.noreply.github.com>
2019-01-16 18:44:56 +00:00
Arunoda Susiripala
a9fe32611f Get back the --name property (#1828)
* Get back the --name property
This also removes --project and consider --name as the project name

* Fix unit tests.

* Fix integration tests
2019-01-16 18:44:46 +00:00
Arunoda Susiripala
7d54ccc668 Added support for projects (#1719)
* Send project property to api-deployments.

* Allow to talk to local api-deployments temporarly.

* Introduce the getProjectName utility.

* Use getProjectName on both legacy and latest deploy commands.

* Add now projects ls support.

* Implement 'now project add' and 'now project rm'

* Show project id

* Add basic now ls support with projects.

* Add some cosmetics changes.

* Make the UI colorful.

* Set the name as project

* Notify the user about the project name

* Remove legacy list

* Make sure 'now projects xxx' possible

* Set the project name in the list header

* Remove unwanted package

* Use --project in tests

* Force --project instead of --name

* Force the use of project property inside now.json

* Update ncc to the latest

* Remove -w from ncc

* Deprecate --name and .name instead of throwing errors

* Use the built-in fetch client

* Fix tests

* Change the order of tests

* Reset integration tests

* Remove some debug logs
2019-01-16 18:44:31 +00:00
Javi Velasco
946e5cb78c Move all dns commands and subcommands to typescript (#1825) 2019-01-16 18:44:15 +00:00
Leo Lamprecht
402b9e3daa 13.0.6 2019-01-15 16:03:55 +00:00
Leo Lamprecht
3c20c4b690 Allow user to abort now init (#1826) 2019-01-15 15:57:25 +00:00
Leo Lamprecht
3ee1cf1eee 13.0.5 2019-01-15 10:07:41 +00:00
Leo Lamprecht
d2931a540a Improved test suite (#1820)
* Bumped `@zeit/ncc` to latest

* Reverted lockfile

* Make linking build for dev

* Cover line 21 in util/config/local-path.js

* Heavily improved unit test coverage

* Fixed space

* Got to 90% coverage

* Removed useless code

* Made builds work

* Fixed a few lines

* Fully covered read-metadata.js

* Brought coverage to 95.38

* Removed code that was never executed

* Track everything

* Don't show badge for now
2019-01-15 09:55:59 +00:00
Andy
9596a415bf Add the command to sentry (#1824)
Add the current command to sentry as extra
2019-01-15 09:55:54 +00:00
Timothy
4e1ebfc541 Fix config file message (#1821) 2019-01-15 09:55:49 +00:00
Amio /
ca086e01c7 better did-you-mean (#1817)
ensure 'node' => 'nodejs' insteadof 'node-server'
2019-01-15 09:55:44 +00:00
Leo Lamprecht
4dae0cd0d5 13.0.4 2019-01-10 11:32:38 +00:00
Leo Lamprecht
4dfacb63a1 Fixed now logs for 2.0 deployments (#1819)
* Fixed `now logs` for 2.0 deploymens

* Added log test for 2.0

* Make test work
2019-01-10 11:26:56 +00:00
Leo Lamprecht
531a2dc12c 13.0.3 2019-01-09 22:13:13 +00:00
Leo Lamprecht
0e011570be Do not render that status was inferred (#1816) 2019-01-09 22:13:02 +00:00
Leo Lamprecht
e785d967bf 13.0.2 2019-01-09 14:35:47 +00:00
Leo Lamprecht
55004d4a6a Made now domains inspect match now inspect (#1815) 2019-01-09 14:30:12 +00:00
Leo Lamprecht
ac7ff6a4a7 13.0.1 2019-01-09 12:00:15 +00:00
Leo Lamprecht
d768b93441 Bumped update-check to latest version (#1814) 2019-01-09 10:55:43 +00:00
Leo Lamprecht
ecf0df8c6e Fixed several errors (#1811)
* Fixed NOW-CLI-HB

* Fixed code
2019-01-08 20:35:04 +00:00
Leo Lamprecht
2da216d9ca Fixed several errors and removed useless file (#1807)
* Fixed NOW-CLI-FK

* Fixed NOW-CLI-F0

* Fixed NOW-CLI-D2

* Fixed NOW-CLI-GK

* Do not render clipboard indicator if error occured

* Removed useless file

* Fixed NOW-CLI-GW

* Fixed NOW-CLI-H3
2019-01-07 23:00:43 +00:00
Timothy
9e512690ff Add domain verification error document (#1806) 2019-01-07 23:00:40 +00:00
Leo Lamprecht
ec25aae9ea Overhauled now inspect (#1804)
* Show routes in `now inspect`

* Removed whitespace

* Made UI gorgeous

* Use cyan for meta keys
2019-01-07 23:00:36 +00:00
Leo Lamprecht
4c96c2feef 13.0.0 2019-01-05 07:50:55 +00:00
Amio /
25eeafb6c3 Add now-init (#1780)
* Add now-init

* fix ci error

* refactor: (now-init) js => ts, some improvements.

- now-init works like git-clone
  (create new directory / complain about overwritten / can be forced)

- Better guess user intention
  (use jaro-winkler algorithm with "-" awareness)

- Stricter on arguments

- Non-TTY frendly

* add now-init to main help message

* fix miss typed args in didYouMean

* clean console.log

* output a new-line after any response to promptBool

Fix the missing '\n' when promptBool get an negative input ("n"/"N"/Enter/Abort).

Before:

~/git » now init koa
> Did you mean nodejs-koa? [y|N] > No changes made.

After:

~/git » now init koa
> Did you mean nodejs-koa? [y|N]
> No changes made.

* refine now-init output messages

* prettier code format

* update tests for now-init

* put "init" before "help" in now-help message

* remove redundant semicolon
2019-01-04 21:16:25 +00:00
Javi Velasco
da8801d236 Style fixes (#1796) 2019-01-04 21:16:23 +00:00
Javi Velasco
60da071e7d Domains improvements (#1795)
* More flexible response error

* Consider async domain purchases

* Jumpline for domains ls

* Jumpline in domains verify

* Remove not needed body performing verification

* Add orderedAt to domains inspect
2019-01-04 13:14:53 +00:00
Leo Lamprecht
80fe47ef79 Only run prettier for JS/TS files (#1791)
* Only pass modified js files

* Look for TS too
2019-01-04 13:14:49 +00:00
Leo Lamprecht
c0e4ed05bf Improved performance when creating deployment (#1787) 2019-01-04 13:14:44 +00:00
Leo Lamprecht
a300096620 Moved docs about publishing a release to Wiki (#1786) 2019-01-04 13:14:38 +00:00
Olli Vanhoja
c3281a6cbc Fix now dns ls misalignment when a domain is not found (#1777)
If a domain is not found the DNS record arrays are aligned
incorrectly and finally some records are shown under wrong domains.
It happens because the length of the domains array differs from the
length of array of record arrays.
2019-01-04 13:14:32 +00:00
Javi Velasco
fcf3f63796 Remove extra request when adding a domain (#1762) 2019-01-04 13:14:27 +00:00
Javi Velasco
a86c1d980b Do not use certs and aliases in now domains rm (#1761)
* Update types to the new API contract

* Do not use aliases and certs from domain fetch

* Add a dash per row in ns table
2019-01-04 13:14:22 +00:00
Leo Lamprecht
4f1e6c4a6f Wait for unhandled rejections to be reported before exiting (#1760) 2019-01-04 13:14:17 +00:00
Javi Velasco
d0ffac21d3 Fix issue when we define aliases in now.json array (#1757) 2019-01-04 13:14:12 +00:00
Javi Velasco
721639ae6b Domains enhancements (#1755)
* Show a dash where there are no nameservers

* Show actual serviceType in domains

* Format ns table with ticks

* More enhancements
2019-01-04 13:14:05 +00:00
Leo Lamprecht
0ade88209d Render better error when source missing (#1754)
* Render better error when source missing

* Added integration test

* Fixed missing
2019-01-04 13:14:00 +00:00
Leo Lamprecht
553f299299 Ran prettier over the entire codebase (#1749)
* Use correct parser

* Ran prettier over the entire codebase
2019-01-04 13:13:55 +00:00
Javi Velasco
07dd59b017 Fix list DNS issue and migrate certs issue to Typescript (#1747)
* Migrate getDomainDNSRecords to Typescript

* Migrate getDNSRecords to Typescript and fix it

* Migrate cert functions to Typescript and fix issues

* Migrate certs issue to Typescript

* Minor fixes
2019-01-04 13:13:50 +00:00
Leo Lamprecht
869a48f392 Use our own @zeit/git-hooks package (#1748)
* Removed legacy dependencies

* Added @zeit/git-hooks

* Added scripts to run before commit

* Format only the modified files

* Revert "Format only the modified files"

This reverts commit 9f4a58d2b978fa286eb7fcf38186bd9d53a2cda1.

* Revert "Added scripts to run before commit"

This reverts commit 07636d945374e404161ad281feed4180801b3509.

* Revert "Added @zeit/git-hooks"

This reverts commit 3f44f401f36fa6965d36ef28b81907c137c08abc.

* Revert "Removed legacy dependencies"

This reverts commit bb02465c59d75bf6b32bd449a04832cf4e2f4bf4.

* Fixed setup

* Print important test parts

* Logged kind

* Added more logs

* No need to remove deployments, we will prune
2019-01-04 13:13:45 +00:00
Javi Velasco
5ffa933b7f New domains API + Typescript migrations (#1728)
New domains API + Typescript migrations
2019-01-04 13:13:37 +00:00
Leo Lamprecht
e14681e6c4 Revert "Use single call on aliases and certs on domain rm (#1763)"
This reverts commit 4f549a1fa5.
2019-01-04 13:13:23 +00:00
Leo Lamprecht
48f790c60f Revert "Stop using domains v4 in stable (#1764)"
This reverts commit 61bd0b7038.
2019-01-04 13:12:37 +00:00
Javi Velasco
df01e07f66 12.1.14 2018-12-19 14:53:06 +01:00
Javi Velasco
61bd0b7038 Stop using domains v4 in stable (#1764) 2018-12-19 14:52:32 +01:00
Javi Velasco
e8570dd47f 12.1.13 2018-12-19 12:20:30 +01:00
Joe Cohen
4f549a1fa5 Use single call on aliases and certs on domain rm (#1763) 2018-12-19 12:06:48 +01:00
Leo Lamprecht
e160e4e578 12.1.12 2018-12-12 22:05:10 +00:00
Mudit Ameta
2378b78c69 Update now alias error to mention potentially missing name config (#1742)
* Update `now alias` error to mention potentially missing name config

Running `now alias` in a project that has no `package.json` and doesn't
have a `name` property defined in `now.json` fails with a cryptic
error currently. This, in combination with
https://github.com/zeit/docs/pull/378 tries to better guide the user.

* Add a link to the `name` config property
2018-12-12 17:25:37 +00:00
Joe Cohen
3b500bad64 Use single domain call to remove add domains domains (#1743)
* use single domain call to remove add domains domains

* update sigle domain endpoint and error handling
2018-12-12 17:25:31 +00:00
Leo Lamprecht
ab81bbea68 12.1.11 2018-12-10 14:49:22 +00:00
Leo Lamprecht
1f2a0d6163 Hot fix for now teams ls (#1737)
* Hot fix for `now teams ls`

* Added integration test
2018-12-10 14:27:41 +00:00
Leo Lamprecht
9b922c9f7d 12.1.10 2018-12-10 11:05:52 +00:00
Leo Lamprecht
b1bce843d4 Make download script work properly (#1729) 2018-12-07 23:07:33 +00:00
Leo Lamprecht
067bd9f75e Re-enabled minification and source map reporting (#1727)
* Test tag logging

* Track source maps on Sentry

* Bumped @zeit/ncc to the latest version
2018-12-07 22:38:45 +00:00
Leo Lamprecht
b6213b17ae Fixed even more Sentry errors (#1726)
* Fixed NOW-CLI-A5

* Fixed NOW-CLI-AW

* Fixed NOW-CLI-B4

* Fixed NOW-CLI-8G

* Fixed NOW-CLI-BV

* Fixed NOW-CLI-6Z

* Fixed NOW-CLI-AV

* Fixed NOW-CLI-6A

* Fixed NOW-CLI-24
2018-12-07 15:19:06 +00:00
Leo Lamprecht
869375a6ac Downgrade @zeit/ncc (#1725)
* Downgrade `@zeit/ncc`

* Fixed package.json
2018-12-06 22:32:45 +00:00
Leo Lamprecht
cb460beb86 Fixed several errors (#1724)
* Handle EPERM errors when creating config files

* Catch errors when retrieving scope

* Added validation for the API URL

* Removed useless whitespace

* Removed useless file

* Cleaned up `setRawMode` mess

* Removed tests that are erroring on non-TTY

* Set environment based on release channel

* Fixed syntax
2018-12-06 22:15:54 +00:00
Leo Lamprecht
6e8cc57b65 Improved error reporting system (#1723)
* Configure releases and environment for Sentry

* Correctly send development errors away

* Report Sentry errors with metadata

* Report username and full name of user too

* Better release name
2018-12-06 22:15:43 +00:00
Leo Lamprecht
d18ae25c19 Added legacy preferGlobal flag (#1722) 2018-12-06 22:15:39 +00:00
Leo Lamprecht
62176311c9 Improved Sentry error reporting (#1720)
* Bumped `@zeit/ncc` to latest version

* Do not report user errors

* Do not report mistyped arguments to Sentry

* Do not report when user aborts action

* Removed all occurances of user errors

* Do not report arg errors

* Correctly report teams and billing errors

* Prevent `setRawMode` from causing an error

* Do not report errors while developing

* Revert "Prevent `setRawMode` from causing an error"

This reverts commit 323296f30bfcca70ea5bb736db98357212f86a0a.

* Fixed whitespace
2018-12-05 22:18:05 +00:00
Leo Lamprecht
ae03014b87 12.1.9 2018-12-05 17:06:02 +00:00
Leo Lamprecht
6defc8eb31 Made npm run link work (#1715) 2018-11-30 23:33:33 +00:00
Leo Lamprecht
6635e72598 Replaced webpack with ncc (#1710)
* Removed useless stuff

* Removed types

* Removed types file

* Made the build work

* Fixed bundling

* Fixed linting

* Fixed download compiler

* Try to fix bundling problem

* Ignored two things

* Upgraded pkg to stable

* Fixed syntax finally

* Fixed unit tests

* Removed shebangs

* Fixed integration tests

* Made download script work
2018-11-30 23:33:26 +00:00
Leo Lamprecht
0eacea6fcd Changed default of sessionAffinity to random (#1713) 2018-11-30 23:33:20 +00:00
Gustaf Räntilä
fae3c2e1bd Improved http2 stability (#1705) 2018-11-29 18:33:26 +00:00
Leo Lamprecht
ed89a92f39 Correctly report code coverage (#1709) 2018-11-29 18:33:20 +00:00
Leo Lamprecht
c4e2a63f76 Added code coverage report (#1708)
* Added code coverage report

* Correctly include everything

* Ignored useless stuff

* Combine all the coverages

* Corrected requiring

* Persist only what is needed
2018-11-29 18:33:16 +00:00
Leo Lamprecht
0baa065fce 12.1.8 2018-11-29 16:13:52 +00:00
Leo Lamprecht
075c1522f8 Ensured now -V 1 owner/repo continues working (#1707)
* Ensured `now -V 1 owner/repo` continues working

* Added newline

* Added tests
2018-11-29 16:04:02 +00:00
Leo Lamprecht
9c52309fb3 12.1.7 2018-11-28 12:00:48 +00:00
Leo Lamprecht
ebaa5dc70b Render more accurate error when offline (#1704) 2018-11-27 22:47:55 +00:00
Leo Lamprecht
5f9c5b1cf4 Render more detailed error when files are not there (#1700) 2018-11-27 21:59:22 +01:00
Leo Lamprecht
57f6895f92 Render a proper error when offline (#1702)
* Made debugging entry file work

* Render proper error when offline

* Return proper exit code
2018-11-27 21:58:59 +01:00
Leo Lamprecht
fee4e23c11 12.1.6 2018-11-26 13:07:40 +01:00
Leo Lamprecht
adac5826bd Do not render instance count for 2.0 deployments (#1697)
* Do not render instance count for 2.0 deployments

* Added integration test
2018-11-26 11:09:44 +01:00
Leo Lamprecht
e2885e2a00 Do not send github property to API (#1694) 2018-11-23 12:11:47 +01:00
Leo Lamprecht
6879e0e819 Do not send alias to the API (#1690) 2018-11-22 16:48:32 +01:00
Leo Lamprecht
d3fd83c2ac Properly render schema validation errors (#1689)
* Properly render schema validation errors

* Added integration test

* Removed useless properties
2018-11-22 13:47:01 +01:00
Leo Lamprecht
da5c75c911 12.1.5 2018-11-21 22:15:35 +01:00
Leo Lamprecht
e6802d89aa Make now teams add work (#1684)
* Make `now teams add` work

* Added integration test

* Added comment
2018-11-21 18:22:37 +01:00
Leo Lamprecht
731e36a393 12.1.4 2018-11-20 21:16:27 +01:00
Leo Lamprecht
e94b0dfa88 Do not store a backup of the binary (#1676) 2018-11-19 13:25:50 +01:00
Leo Lamprecht
5cf6016d50 Build for dev and not for prod when linking (#1671) 2018-11-19 13:25:45 +01:00
Leo Lamprecht
cde888ed2b Made publishing work (#1669) 2018-11-19 13:25:38 +01:00
Leo Lamprecht
fe07405971 Upgrade to Webpack 4.0 (#1667)
* Added support for Webpack 4

* Brought performance back

* Default output dir

* Made it take effect

* Made binary work
2018-11-19 13:25:23 +01:00
Leo Lamprecht
c154d600fd 12.1.3 2018-11-15 17:25:59 +01:00
Leo Lamprecht
25bdc3b5a8 Report server errors that are unhandled (#1658) 2018-11-15 01:33:11 +01:00
Evil Rabbit
71dce28494 Update repo banner (#1659) 2018-11-15 01:33:06 +01:00
Leo Lamprecht
cf39c76986 Send unexpected errors away for inspection (#1657)
* Send errors away for inspection

* Allow Sentry to send them away

* Fixed dependency

* Fix credit card input

* Do not test for something that requires TTY

* Track properly

* Make it extra safe

* Added back test
2018-11-15 01:33:00 +01:00
Leo Lamprecht
e779b8342d Added new now upgrade and now downgrade commands (#1656)
* Handle cancelation

* Fixed imports

* Added support for old plans

* Removed test that does not apply anymore
2018-11-15 01:32:53 +01:00
Leo Lamprecht
f229f09715 Fixed error message for minimum instance count (#1655) 2018-11-15 01:32:46 +01:00
Leo Lamprecht
80d166ad0d 12.1.2 2018-11-14 00:39:26 +01:00
Leo Lamprecht
2b7e21b31d Allow re-using aliases that point to deleted deployments (#1653)
* Allow re-using aliases that point to deleted deployments

* Removed
2018-11-13 23:58:05 +01:00
Leo Lamprecht
c157e08179 Log version when debugging (#1652) 2018-11-13 20:20:57 +01:00
Leo Lamprecht
96ff68a8a1 Decrease amount of retries for download (#1651)
This fixes #1622.
2018-11-13 20:20:51 +01:00
Leo Lamprecht
46fc00918e Return code 0 if no deployments found when removing (#1650)
* Return code 0 if no deployments found when removing

This fixes #1605.

* Fixed integration test

* Fixed second example too

* Fixed all occurances
2018-11-13 20:20:45 +01:00
Leo Lamprecht
be98a38c9a 12.1.1 2018-11-12 22:24:47 +01:00
Leo Lamprecht
59717b32a5 Made default value for --dotenv (v1) work again (#1649) 2018-11-12 22:13:21 +01:00
Leo Lamprecht
0ee868e009 12.1.0 2018-11-12 13:29:37 +01:00
Leo Lamprecht
075dea2b8f Added -V to the usage information (#1648) 2018-11-12 12:59:39 +01:00
Leo Lamprecht
a6ab26f93c Added tests for -V option (#1647)
* Added tests for `-V` option

* Pushed for testing

* Correctly set it

* Revert "Correctly set it"

This reverts commit c76286082d90f091ecec4a317856e91b4558e781.

* Create a new deployment each time
2018-11-12 12:48:58 +01:00
Leo Lamprecht
520d3e2a06 Added support for -V option (#1644) 2018-11-10 20:56:39 +01:00
Leo Lamprecht
f3ed32e06b 12.0.1 2018-11-08 23:25:25 +01:00
Leo Lamprecht
eded40049d Made --build-env, --meta and --dotenv work for v1 (#1637)
Made `--build-env`, `--meta` and `--dotenv` work for v1

* Locked multi static file test to v1

* Correct fix

* Final fix

* Config also adds to count

* Fixed single file test

* legacy => old

* Correctly set it
2018-11-08 23:01:46 +01:00
Bart Deslagmulder
56e1a37ae1 Updated error documentation about not nameservers (#1629) 2018-11-08 23:01:37 +01:00
Leo Lamprecht
49d29b2a0d 12.0.0 2018-11-08 16:44:13 +01:00
Leo Lamprecht
f330d2c7ed Added support for Now 2.0 (#1636)
* Removed external providers

* Renamed sh provider

* Removed serverless stuff

* Fixed paths

* Properly pass token

* Fixed paths

* Check for token correctly

* Remove useless properties

* Fixed unit tests

* Keep certain things

* Adjusted remaining parts

* Fixed login

* Remove user properties that are not needed

* Store `platformVersion` for teams

* Store `platformVersion` for users

* Delete team order when logging out

* Made team commands work with tiny config

* Load data dynamically

* Made billing command show correct context

* Fixed remaining occurences of context name

* Fixed remaining pieces

* Test CI

* Clean strings when testing

* Better error check

* Render correct information when asking for credit card

* Migrate from objects to strings

* Better migration message and keep tips

* Remove the old property

* Use note for migration message

* Don't show spinner for loading missing data

* Allow for current team or user to be deleted

* Two deploy files

* Consume context name correctly

* Removed deployment types from new deployer

* Also check for bigger than 1

* Better file names

* Added upgrade message for legacy deployer

* Make help work when logged out

* Error if sub command doesn't exist when requesting help

* Fixed wording

* Support for version property added

* Better handling

* Removed useless props from deploy help

* Don't show version warnings when rendering help

* Fixed wording in readme

* Migrate even if in the middleground

* Make `now whoami` work

* Deprecated support for deploying Git repo in latest deployer

* Added usage information

* Load config separately

* Don't need local config on root

* Correct status code for help test

* Show error only in correct case

* Properly error if path does not exist

* Fixed types

* Fixed remaining occurances of old config

* Don't show warning when rendering help

* Consider version when outputting help

* Only error if path does not exist if it's not help

* Remove testing logging

* Don't error for no-verify

* Stop logging

* Fixed last test

* Added missing semicolons

* Fix indent

* Fix indent again

* Ran prettier over everything

* Added missing types

* Brought test hashes back to normal

* Exit properly when deploying

* Show clipboard note in gray and remove Node.js version

* Completed usage information

* Ensure `now whoami` only outputs the user

* Don not save user data to config

* Removed last traces of `user` and `.api` and `--team` work

* Made `now upgrade` and `now downgrade` correctly render context

* Fixed upgrade/downgrade URL for teams

* Ability to load required data

* Better file name

* Corrected check for current scope

* Don't render version warning when showing help

* Keep polling for handlers

* Render handlers

* Removed useless file

* Much better transpilation setup

* Sweetened logging

* Shortened time it takes to render ready

* Support for error ready states

* Make sure table is not wobbling

* Show times for every handler

* Attach env and build env

* Don't pass useless stuff

* Re-structured pipeline

* Allow empty config

* Do not support package.json config for new pipeline

* Removed occurances of AWS

* Drop useless packages

* Removed useless file

* Ensure the legacy pipeline is working

* Test staging proxy with legacy pipeline

* Adjust test

* Stop testing staging proxy

* Allow for anything

* Pass `handlers` and `routes` to creation endpoint

* Fixed tests

* Revert "Fixed tests"

This reverts commit e0d18a61b9520728089cb2f9e6877c1b91016312.

* Running tests should not be optional

* Support for `-m` and `--meta` added

* Support reading `meta` in local config

* Allow reading `name` from local config

* The `public` prop in local config should be considered

* Handlers deployments should use `.nowignore` and nothing else

* Allow handlers deployments without `handlers` and `routes` in the config

* Locked legacy tests to legacy platform version

* Support aliasing handlers deployments

* Removed useless condition

* Don't allow scaling handlers deployments

* Don't show warning message when deploying single file

* Fixed tests

* Made `now inspect` work

* No type for handlers deployments in list

* Indicate whether a deployment is legacy in `now inspect`

* Made `--force` work for handlers deployments

* Do not document `--dotenv` for handlers (not supported)

* Do not strip `hdl_` from handler IDs

* Fixed for upgrading to latest platform

* Better error for when `version` property is missing

* Render platform version while deploying

* Strip `hdl_` from handler IDs

This reverts commit 750d38ba9074bdc3e63ad2dab8538e51dbba5f03.

* Removed `https://` from handler list

* Removed demo mock

* Cleaner errors

* Make times and erroring work properly

* Print final deployment error

* Removed useless promise

* Prettified code

* Put config utils into correct location

* Moved even more config files

* Removed useless directory

* Removed last useless file

* Fixed wrong paths

* Fixed unit tests

* Update deployment according to handler state, like the server-side loop

* More robust deployment mechanism

* Poll every 1.5 seconds

* Prevent many requests

* Show spinner while waiting for deployment to be ready

* Render how long the deployment took

* Avoid unnecessary repainting

* Automatically remove useless `user` property from config when migrating

* Fixed property names in `now inspect`

* Render platform version for legacy pipeline

* Shortened error messages

* Support `regions` in the local config

* Support for `--regions` added

* Add metadata support for legacy deployments (#2)

* Share handlers table between deploying and inspecting

* Make `now inspect` work nicely

* Renamed handlers to builds

* Stop sending away description

* Bare UI support for builds

* Simper logic for rendering builds

* Render output of builds

* Indicate lambdas in a better way

* Render size for build output

* Do not show type for version 2 deployments

* Fixed time output for `now inspect`

* Don't handle BUILDS type

* Allow for 100% non-config deployments

* Add metadata support for now ls (#3)

* Add metadata support for now ls
So, we can do things like this:
  now ls -m key1=value1 -m key2=value2

* Better description

* Fix wording

* Added final newline

* Add sentry (#4)

* Revert "Add sentry (#4)"

This reverts commit 851d1bdb0e1bbc8f329a45388865b2c41395d8c2.

* Only render build output if it was not copied

* Made `now alias` work with latest staging proxy

* Revert "Made `now alias` work with latest staging proxy"

This reverts commit 16e8998435ef03c50d2737f3ef17fa5c0c2dd33f.

* Bumped deployments API to the latest version

* Made `now rm` work

* Do not print `version` warning for single files

* Removed useless `fs-extra` dependency

* Removed useless dependencies

* Default binaries to Node 10

* Bumped Node.js in Circle CI to latest

* Bumped Xcode to get latest Node.js for integration tests

* Enabled HTTP/2 support

* Removed useless code

* Added integration test for builds

* Bumped `fetch-h2` to the latest version

* Avoid performing network request for rendering help

* Render note when viewing latest help

* Return status code `2` when exiting with help

* Fixed test for usage information

* Removed wrong text in usage info for Now 2.0

* Removed support for `--links` from v2 pipeline

* migrated => upgraded

* Added default routing for single files

* Make `--token` work as expected

* Better message for build errors

* Prevent update notification

* Prevent update notifications from showing

* Only show migration message in debug output

* Prevent flickering of state

* Improved output

* Removed useless assignment

* Corrected padding

* Less padding before state

* Corrected links for global configuration

* Fixed integration tests

* Render region for Lambdas

* Join regions in a better way

* Ensure `now.json` and `.nowignore` (the latter worked anyways) are uploaded

* Fix `build.env` in new deployment API call (#6)

* JSON log the deployment body when debugging (#8)

Otherwise it's just `[object Object]` which is useless.

* Retry to fetch on error on follow mode (#5)

* retry fetch on error on follow mode

* improve logging

* Fixed `--env` and `--build-env` CLI args (#7)

* Fix `--env` and `--build-env` CLI args

* Fall back to `undefined`

* Ensure `now switch` lists active scope in the beginning

* Removed useless code

* Error if `env` or `build.env` have wrong types

* Made `now inspect` look great

* Fixed wrong protocol in URL

* Made `now --team` work with users

* Leave PHP out of integration test for now

* Do not select PHP build

* Fixed integration tests

* Revert "12.0.0-canary.93"

This reverts commit 70a0a594b4.

* Revert "Revert "Add support for top-level "sh" auth""

This reverts commit 4273d62460.

* Revert "12.0.0-canary.92"

This reverts commit 847c71ecf2.

* Revert "Add support for top-level "sh" auth"

This reverts commit c493d651db.

* Revert "12.0.0-canary.91"

This reverts commit 06c954f8fe.

* Revert "Added metadata support for `now inspect` (#1634)"

This reverts commit 9567656b45.

* Revert "12.0.0-canary.90"

This reverts commit 966737be23.

* Revert "Added support for deployment metadata (#1604)"

This reverts commit 6c1188a787.
2018-11-08 16:29:05 +01:00
Leo Lamprecht
dbdc0ed52f 11.5.2 2018-11-03 18:09:20 +01:00
Leo Lamprecht
fd59f931fa Revert "Add support for top-level "sh" auth"
This reverts commit b78f61e03d.
2018-11-03 18:09:06 +01:00
Leo Lamprecht
5139c1fa3f 11.5.1 2018-11-03 14:03:59 +01:00
Nathan Rajlich
b78f61e03d Add support for top-level "sh" auth 2018-11-03 14:03:40 +01:00
Leo Lamprecht
42253cdb53 11.5.0 2018-11-02 21:48:39 +01:00
Arunoda Susiripala
e4bcb809f3 Added metadata support for now inspect (#1634) 2018-11-02 21:26:53 +01:00
Arunoda Susiripala
3d2edff0d3 Added support for deployment metadata (#1604)
* Allow to add metadata in the now deploy command.
Use can add multiple items of metadata with:
  '-m key1=val1 -m key2=val2'

* Add a test case.

* Update to accept and send metadata as meta.

* Use correct fields in now.create

* Add now ls support.

* Add an integration tests for ls with metadata

* Added newline

* Removed semicolon
2018-11-02 21:15:06 +01:00
Leo Lamprecht
f93538cf1e 11.4.6 2018-09-23 17:40:59 +02:00
Evil Rabbit
69d5c480a1 Update repo banner 2018-09-23 17:32:52 +02:00
Mark
550ce4ea2a Suppress the warning of a dependency based on an expression (#1588) 2018-09-20 16:01:51 +02:00
Leo Lamprecht
57aa4dbce4 11.4.5 2018-09-18 23:43:18 +02:00
Javi Velasco
16b351de2e Change copy for finish cert message (#1590) 2018-09-18 23:08:06 +02:00
Leo Lamprecht
badd37e150 11.4.4 2018-09-14 20:57:08 +02:00
Javi Velasco
60de863a2c Bring back now certs add (#1583) 2018-09-14 20:44:05 +02:00
Leo Lamprecht
6272e1fba3 11.4.3 2018-09-14 20:05:49 +02:00
Nathan Rajlich
d717381df4 Render Cloud v2 info about deployments in now inspect (#1577)
`slot` and `limits` are now rendered when it is a Cloud v2 deployment.

Also fixes an issue with static deployments always
rendering `affinity: undefined`.
2018-09-12 23:52:16 +02:00
Nathan Rajlich
3fa28867bd Add "all" pseudo-DC to the constants mapping (#1581) 2018-09-12 23:52:12 +02:00
Nathan Rajlich
e1058f0ab3 Add now inspect to --help (#1578) 2018-09-12 23:52:07 +02:00
Leo Lamprecht
aa2913ea07 11.4.2 2018-09-11 18:42:57 +02:00
Matheus Fernandes
2f07212e20 Added new iad1 data center (#1575) 2018-09-11 18:34:59 +02:00
Nathan Rajlich
43eeaa1abf Add now whoami to --help (#1573) 2018-09-10 19:10:45 +02:00
Cygnusfear
164ae1fac1 Changed error to log to avoid breaking automatic deployments (#1572)
throwing an error re-opened this issue:
https://github.com/zeit/now-cli/issues/1044

breaks automation when no deployments are found or deployment name is changed
2018-09-10 19:08:49 +02:00
Javi Velasco
6123df568c Restructure certs command (#1567)
* Restructure add command

* Remove cert start and finish

* Rename certs add to issue

* Better errors and add cant-solve-challenge

* Show err.sh for dns configuration errors generating certs

* Add err.sh to solve challenges manually

* Add deprecation message to certs add

* Improve grammar

* Minor fixes
2018-09-06 20:58:52 +02:00
Javi Velasco
705cb5fed3 Allow to generate certs solving challenges manually (#1566)
* Move getDomainNameservers function

* Don't show an error as unexpected if there is a code in the error payload

* Add start and finish cert order functions

* Integrate add wildcard cert for external domains

* Use a different endpoint to get a cert by id

* Add new command to download a certificate

* If there are no pending challenges, try to generate the cert right away

* Remove cert download

* Move DNS table options to an object

* Bugfix: cancel spinner message when finish order fails

* Restore add to work only with cert add

* Refactor obtaining cns

* Add start and finish order commands
2018-09-06 20:58:45 +02:00
Zeke Sikelianos
c5ce183705 Use consistent wording in usage (#1541) 2018-09-06 20:58:25 +02:00
Nathan Rajlich
2cf750b309 Update @zeit/dockerignore to v0.0.3 (#1560)
* Update `@zeit/dockerignore` to v0.0.2

To fix https://github.com/zeit/now-cli/issues/1441.

* Update `@zeit/dockerignore` to v0.0.3
2018-09-06 20:58:21 +02:00
Jaga Santagostino
ac85a4f313 Add changelog link when new version is available (#1530)
* add changelog link if new version is available

* Linked directly
2018-09-06 20:47:21 +02:00
Jarmo Isotalo
76904d1d13 Prefer URL over deployment ID as the ID not shown in now ls (#1554) 2018-09-06 20:40:30 +02:00
Leo Lamprecht
bb110697a3 11.4.1 2018-09-01 13:05:43 +02:00
Olli Vanhoja
2d2f671681 Fix scaling v1 deployments to all DCs (#1556)
```
> Error! An unexpected error occurred in scale: Error: This region (gru1) only accepts Serverless Docker Deployments (400)
```

This is happening because `now-cli` is validating DC names and
expanding "all" locally. However not all DCs have same features but
the client can't be aware of that. Instead of making the client
aware of the differing capabilities of the available DCs we should
pass "all" as a special DC selector, and let the backend handle
scaling properly.
2018-09-01 12:20:06 +02:00
timothyis
ff7f6c5a19 11.4.0 2018-08-25 16:30:47 +01:00
Timothy
e03d036131 Add gru1 (#1545)
* Add gru1

* Add gru to errors

* Hard code sfo,bru scale

* Add --regions argument

* Push with console.log

* Scale to `bru`

* Scale down in bru only
2018-08-25 16:29:22 +01:00
Javi Velasco
5bb5f18b7e 11.3.13 2018-08-24 02:42:31 +02:00
Javi Velasco
33b9c6b03c Pass domain to verify insted of alias when verifying on alias (#1548) 2018-08-24 02:42:00 +02:00
Javi Velasco
11e03c331a 11.3.12 2018-08-20 20:34:44 +02:00
Javi Velasco
417901d048 Return scaling validation errors on alias (#1538)
* Return scaling errors on alias

* Join pattern match error in one expression
2018-08-20 20:33:50 +02:00
Javi Velasco
fc7b267ccf Fix updating scale (#1536) 2018-08-20 20:33:50 +02:00
Javi Velasco
5c78a80923 11.3.11 2018-08-19 18:27:40 +02:00
Javi Velasco
8f365cdd66 Try to verify against domain name instead of alias (#1534) 2018-08-19 18:27:10 +02:00
Leo Lamprecht
bff8c8d549 11.3.10 2018-08-14 12:30:44 +02:00
Arunoda Susiripala
e189ab86be Remove @zeit/schemas (#1507)
We no longer use it inside this repository.
2018-08-13 19:28:16 +02:00
Leo Lamprecht
1563cc9b4f 11.3.9 2018-08-09 12:33:29 +02:00
Luciano Pellacani Franca
ec09c16e0a fixing typo (#1509) 2018-08-09 12:33:21 +02:00
Leo Lamprecht
12d3a2057b Point Spectrum badge to correct location (#1516) 2018-08-09 12:33:17 +02:00
Sean
fb7e0b9fb6 Less cryptic invalid alias message (#1506)
* Less cryptic invalid alias message

* URL -> hostname
2018-08-09 12:22:23 +02:00
Pranay Prakash
6d32834716 11.3.8 2018-08-04 03:24:57 +00:00
Pranay Prakash
5121541af3 Bugfixes and improvements for deployment READY status detection (#1501)
* Have returnify use generators and reinstantiate them upon error

* check for status not_ready instead of 412

* poll every 5s instead of 1s for ready state notification

* poll every 2s for scale verification
2018-08-04 03:24:45 +00:00
Leo Lamprecht
40514cd51c 11.3.7 2018-08-03 22:39:19 +02:00
Olli Vanhoja
24e302ac06 Show selected session affinity when inspecting a deployment (#1489) 2018-08-03 08:14:51 +02:00
yairhaimo
8d3095ecf3 Include correct help command in now domains (#1492) 2018-08-03 08:14:46 +02:00
Leo Lamprecht
563b16e180 11.3.6 2018-08-03 08:03:40 +02:00
Pranay Prakash
47a646f5f1 Retry 412 errors (#1494)
* retry on 412

* add comment for returnify and exit when the iterator ends
2018-08-02 10:59:03 +02:00
Pranay Prakash
1d2dfcd686 poll every 5s (#1496) 2018-08-02 10:58:58 +02:00
Leo Lamprecht
dcb2508a0d Better error message for rate limiting deployments (#1495)
* Better error message for rate limiting deployments

* Fixed typo

* Show time until reset

* Removed logging
2018-08-02 07:32:12 +02:00
Aria Malkani
2bb4c2e467 Checks if it is an npm deployment before getting the aliased name (#1490)
* checks it is a npm deployment before reading package.json

* checks if you have a config.type first

* checks if you have a config.type first

* fixed logic for config.type
2018-08-01 13:57:03 +02:00
Leo Lamprecht
790a7c577e 11.3.5 2018-07-31 10:39:08 +02:00
Leo Lamprecht
4d29f1a848 Bumped configuration schemas to the latest version (#1488) 2018-07-31 10:28:05 +02:00
Leo Lamprecht
1a19e1df42 11.3.4 2018-07-31 09:13:21 +02:00
Robin Millette
be5ba54a3f Updated link about authentication file (#1483)
* Fix link to config help

* Update get-default-auth-cfg.js
2018-07-30 13:37:32 +02:00
Robin Millette
4eaa10f104 Updated link about global configuration file (#1482)
* Fix link to config help

* Update get-default-cfg.js
2018-07-30 13:37:26 +02:00
Leo Lamprecht
6001899745 Added schema for static header configuration (#1486)
* Added schema for static header configuration

* Bumped yet again
2018-07-30 13:24:53 +02:00
Pranay Prakash
87e2339b26 11.3.3 2018-07-29 22:30:48 +00:00
Pranay Prakash
c1659eae06 Don't downscale previous slot deployment on alias (#1485)
* don't downscale

* use /now/v4/deployments/:id
2018-07-29 22:29:10 +00:00
Leo Lamprecht
edc397209c 11.3.2 2018-07-27 10:20:29 +02:00
Leo Lamprecht
975def8281 Fixed now billing and use new API (#1477)
* Use correct source when listing

* Use correct source when buying domains

* Replaced the rest too

* Make adding work nicely

* Make listing work for all scopes

* Don't require address

* Bumped lockfile

* Removed more useless code

* Renamed file

* Fixed weird zlib error

* Fixed output

* Added some tests
2018-07-24 23:50:24 +02:00
Leo Lamprecht
d910135e84 11.3.1 2018-07-22 02:01:19 +02:00
Leo Lamprecht
186d1e452a Fixed integration tests (#1476) 2018-07-22 01:55:32 +02:00
Leo Lamprecht
68820cb76a 11.3.0 2018-07-19 20:00:37 +02:00
Pranay Prakash
2c725b0360 Improvements to the CLI to handle slot specific flows (#1475)
* Handle scale slots error

* generate and send a requestID when verifying instantiation

* Don't compy incompatible scale settings

* deprecate BinaryDeployment

* add err.sh link

* swap cuid for uuid
2018-07-19 20:00:17 +02:00
Nathan Rajlich
cb525d368d Add --build-env to now deploy command (#1459)
* Add `--build-env` to `now deploy` command

Build env vars are only visible during build-time, compared to
regular env vars which are only exposed during runtime.

This also removes the client-side validation of the deployment
schema, because it makes it difficult to keep the client and server
in sync, especially as new features are added. Instead `now-cli`
should be responsible for knowing how to render the server's error
message in an informative and future-proof way so that we can
update the server and even older clients would show the validation
error properly.

* Remove `only` dependency

* Add `--build-env` CLI flag integration test
2018-07-19 20:00:04 +02:00
Leo Lamprecht
a62a60b5e6 11.2.10 2018-07-17 09:57:40 +02:00
Arunoda Susiripala
d4382007d6 Add more integration tests (#1466)
* Add more integration tests related to static builds and env
Here we are adding a few more integration tests for static builds and for using env vars in the build step.

* Add build-env related test case.
2018-07-17 09:50:02 +02:00
Nathan Rajlich
d27963dd32 Remove shallow deployment verification (#1474)
Remove shallow deployment verification
2018-07-17 09:49:47 +02:00
Igor Klopov
a8839d1904 retry createDeploy if files are missing. addresses #1463 (#1465) 2018-07-16 16:47:09 +03:00
Leo Lamprecht
a7283efe8e 11.2.9 2018-07-11 15:46:03 +02:00
Javi Velasco
c46e70ba8c Control can't solve challenge errors (#1458) 2018-07-11 15:38:32 +02:00
Javi Velasco
72e0ec6af7 Check domain after adding (#1455)
* Check domain info after adding it

* Add message spiner to show while adding a domain
2018-07-10 19:29:49 +02:00
Leo Lamprecht
8873c3fe28 Brought stable dependencies in sync with canary (#1453) 2018-07-10 12:35:37 +02:00
Javi Velasco
8c4d54e50b Refactor DNS and update domains with CDN improvements (#1438)
* Do not allow adding domains with subdomains

* Do not ask for confirmation when the domain exists

* Improve message when the domain is under a different account

* Fix flow errors

* Revamp domains add command

* Remove setting dns records when setting up the domain

* Refactor DNS commands

* Hide fields in system dns records and show creator

* Better formatting for dns ls

* Remove exhaustive check of dns record type

* Remove domain ids from responses in domain commands

* Change all `domains` API references to use `v3`

* Update to domains API v3

* Remove NeedUpgrade error and use CDNNeedsUpgrade where it proceeds

* Update copies when adding domains

* Remove extra blank line

* Fix flow errors
2018-07-10 12:26:35 +02:00
Nathan Rajlich
be926ae491 Remove legacy atlas logic (#1451)
* Remove legacy `atlas` logic

No longer used for anything.

* Remove another `atlas`
2018-07-10 12:26:30 +02:00
Javi Velasco
6547bb709e Dont try to generate always wildcard certs when aliasing (#1445)
* Change params order in createAlias

* Make setupDomain return domainInfo

* Do not try to get a wildcard cert for alias when domain is external

* Update setup-domain.js
2018-07-10 12:26:27 +02:00
Javi Velasco
c9e88b6ca4 Add retryAfter info to rate limit errors (#1442) 2018-07-10 12:26:22 +02:00
Nathan Rajlich
a94136c3a7 Wait for static builds to be ready and show logs (#1452)
Implicitly sets the `noVerify` option since there is nothing to verify.
2018-07-10 12:26:17 +02:00
Javi Velasco
3672f3e925 11.2.8 2018-07-09 13:11:43 +02:00
Javi Velasco
9ccea637ab Fix typo when checking NS during setup domain (#1450) 2018-07-09 13:07:09 +02:00
Arunoda Susiripala
8b2efb6367 11.2.7 2018-07-09 10:09:32 +05:30
Matheus Fernandes
a5e3f0d65a Revert "Upgrade to webpack 4 and latest Babel" (#1448)
* Revert "12.0.0-canary.51"

This reverts commit 5e17fe5ad6.

* Revert "Update `@zeit/schemas` to v1.6.0"

This reverts commit b216adadc0.

* Revert "Upload the Dockerfile if it's a static deployment. (#1437)"

This reverts commit 5078c95667.

* Revert "Upgrade to webpack 4 and latest Babel (#1436)"

This reverts commit 7612d77647.
2018-07-08 20:49:20 -07:00
Leo Lamprecht
cd5ca57ca3 11.2.6 2018-07-06 10:20:57 +02:00
Nathan Rajlich
fd59680b8e Update @zeit/schemas to v1.6.0 2018-07-06 10:20:09 +02:00
Arunoda Susiripala
24a1561ddc Upload the Dockerfile if it's a static deployment. (#1437)
* Upload the Dockerfile if it's a static deployment.
This allows us to build the Dockerfile and upload static assets

* Allow to upload package.json as well for static deployments.
2018-07-06 10:20:01 +02:00
Javi Velasco
64ae48dc93 Upgrade to webpack 4 and latest Babel (#1436)
* Upgrade to webpack 4 and last latest

* Fix building commands

* Do not call yarn build when yarn link

* Use resolved paths in webpack config
2018-07-06 10:19:55 +02:00
Javi Velasco
09b366b273 Allow to deploy and alias when non essential APIs are down (#1435)
* Try to purchase a domain only when there is no other choice

* Allow eventsStream to fail during deployment

* Allow to verify instantiation without events API
2018-07-03 21:23:57 +02:00
Leo Lamprecht
cfee3bfff4 11.2.5 2018-07-02 11:46:55 +02:00
Leo Lamprecht
fca499925c Fixed the tests (#1430)
* Fixed the tests

* Wrapped up
2018-07-02 11:31:50 +02:00
Javi Velasco
d379ce1011 Small fixes (#1418)
* Remove FlowFixMe in deploy command

* Show success message when creating a cert for alias based on response cns
2018-06-22 21:51:06 +02:00
Leo Lamprecht
cb87e8f21c Improved error message for schema validation (#1416)
* Bumped schema

* Improved error message for schema validation
2018-06-21 13:00:17 +02:00
Javi Velasco
d4c90da151 Allow to enable and disable CDN for domains and refactor domains (#1413)
* Move domains command to its own folder

* Refactor domains commands

* Add cdn to domain ls

* Add function to patch domains

* Support toggling cdnEnabled

* Better messages

* Add new cdn options to help command in domains
2018-06-20 22:24:46 +02:00
Javi Velasco
722c0a8bc2 Deeply nested wildcard certs (#1407)
* Better error when we can't verify a domain during alias

* Remove preferDNS option from CLI and allow wildcard certs for deeply nested
2018-06-20 22:24:41 +02:00
Pranay Prakash
55585204b3 Improve the progress bar during upload (#1406)
* use push instead of read

* don't auto-clear

* single progress bar that hangs till last chink

* print symmary beofre link

* print smmary faster

* print more discreet timestamps

* fix tests

* fix flow error
2018-06-20 22:24:35 +02:00
Javi Velasco
4156f465da 11.2.4 2018-06-13 20:56:38 +02:00
Javi Velasco
90905d598b Request normal cert for deeply nested alias (#1404)
* Request normal cert for deeply nested alias

* When is a deeply nested domain request a normal cert
2018-06-13 20:56:10 +02:00
Leo Lamprecht
0e3f241389 11.2.3 2018-06-11 14:52:53 +02:00
Felix Yan
83abedf811 Fix a typo in unique-strings.js (#1400) 2018-06-11 10:41:46 +02:00
Igor Klopov
94128271ed test-integration: test deployment logs output (#1398) 2018-06-11 10:41:39 +02:00
Nathan Rajlich
759442edac Fix shallow verify (#1397) 2018-06-08 10:32:08 +02:00
Javi Velasco
38c90e29ad Ensure there is scale rules before trying to apply (#1389) 2018-06-07 11:21:48 +02:00
Javi Velasco
83a853054c Fixed unexpected error while aliasing (#1387) 2018-06-07 11:21:42 +02:00
Nathan Rajlich
eb51f69c8a Add shallow deployment verification (#1367)
* Add shallow deployment verification

* Add Flow type for `now.retry()`

* Add 3 fetch retries to shallow verify

* Use generics

* Collapse

* Fix

* Add `X-Now-Shallow` verification
2018-06-07 11:21:35 +02:00
Leo Lamprecht
835679cd0c 11.2.2 2018-06-07 11:19:13 +02:00
Leo Lamprecht
76bff85b7f Updated configuration schema (#1394) 2018-06-07 11:03:20 +02:00
Matheus Fernandes
861a193446 11.2.1 2018-06-01 16:00:51 -07:00
Igor Klopov
a4935c33b4 reuse getSafeAlias function for all callers of findAliasByAliasOrId (#1385) 2018-06-01 16:00:42 -07:00
Leo Lamprecht
aa3919f870 11.2.0 2018-06-01 10:21:05 +02:00
Javi Velasco
0e18114d6d Support for Custom Deployment Suffix (#1378)
* Allow to fallback to passed body parsing a response error

* Extract domain purchase from setup-domain

* Move getCertRequestSettings

* Add create method to Now interface

* Extract print dns table and zeit world table functions

* Add support to generate certificates during deploy

* Point to v5 in deploy endpoint

* Add feedback messages when creating a cert during deployment

* Remove hardcoded references to now.sh

* Dont bump create endpoint version

* Support empty reponses in fetch
2018-05-29 20:16:11 +02:00
Leo Lamprecht
0e5a300a14 11.1.16 2018-05-29 20:13:32 +02:00
Leo Lamprecht
95a68395b9 Bumped configuration schemas to the latest version (#1379) 2018-05-29 20:10:37 +02:00
Leo Lamprecht
6d7917c879 11.1.15 2018-05-28 13:21:52 +02:00
Leo Lamprecht
686b9aa92f Bumped configuration schemas to the latest version (#1374) 2018-05-28 13:17:11 +02:00
Pranay Prakash
381d5993e6 add @zeit/dockerignore (#1373) 2018-05-28 13:16:54 +02:00
Leo Lamprecht
8475cde41b Updated configuration schemas to the latest version (#1372) 2018-05-25 20:59:05 +02:00
Leo Lamprecht
e82c550da8 11.1.14 2018-05-25 10:37:00 +02:00
Pranay Prakash
baa1404771 Make the progress bar for uploads consider bytes, not number of files (#1335)
* use got and propogate uploadProgress

* Accept comma separated cns (#1336)

* use got and propogate uploadProgress

* hook into stream.read

* revert `got` stuff

* remove stray whitespace
2018-05-24 22:17:30 +02:00
Pranay Prakash
9beb114ae5 fix clipboard arg parsing (#1358) 2018-05-24 22:17:25 +02:00
Timothy
1162463777 Fix error message via #1350 (#1361) 2018-05-24 22:17:19 +02:00
Pranay Prakash
33356b3240 Strip quotes from Dockerfile labels (#1351)
* Strip quotes from Dockerfile labels

* remove console.log

* add test

* issue normal cert for nested subdomain (#1344)

* Prefer HTTP challenge for regular certs

* 12.0.0-canary.31

* Update non-existing team test

* 12.0.0-canary.32

* Bumped `update-check` to the latest version (#1354)

* 12.0.0-canary.33

* Strip quotes from Dockerfile labels

* remove console.log

* add test
2018-05-24 22:17:15 +02:00
Leo Lamprecht
3b3faa21a1 11.1.13 2018-05-23 20:49:53 +02:00
Tim Neutkens
776d89b70a Make sure subdomain is correctly typed / checked (#1364)
Fixes an error introduced in #1344 when running `now alias` on a naked domain like `example.com`.
2018-05-23 20:49:43 +02:00
Leo Lamprecht
afc2b0380a 11.1.12 2018-05-18 14:18:34 +02:00
Leo Lamprecht
e4ba6040cc Bumped update-check to the latest version (#1354) 2018-05-18 14:08:02 +02:00
Javi Velasco
7d19db4686 Update non-existing team test 2018-05-18 09:40:56 +02:00
Javi Velasco
0371874dbb Prefer HTTP challenge for regular certs 2018-05-18 09:40:50 +02:00
Pranay Prakash
6cbd61554a issue normal cert for nested subdomain (#1344) 2018-05-18 09:40:45 +02:00
Leo Lamprecht
48a490790c 11.1.11 2018-05-17 10:26:00 +02:00
Leo Lamprecht
b96b7fc3a7 Store config on platform & load schema from package (#1349)
* Load schema from package

* Send config to deployment endpoint

* Upgraded @zeit/schemas to the latest version

* Removed type for now

* Added config correctly
2018-05-16 21:29:54 +02:00
Tim Neutkens
dfdd002708 11.1.10 2018-05-16 18:22:22 +02:00
Javi Velasco
001c5f04b2 Fix table import (#1348) 2018-05-16 18:21:53 +02:00
Leo Lamprecht
7ef2be299d 11.1.9 2018-05-15 22:52:46 +02:00
Leo Lamprecht
9feb6ebff2 Account for npm being down (#1346)
* Corrected license file name

* Corrected readme name

* Added editorconfig

* Account for npm being down

* Print full error

* Only show full error while debugging
2018-05-15 22:09:27 +02:00
Leo Lamprecht
12a8aa8a40 11.1.8 2018-05-15 10:18:56 +02:00
Javi Velasco
ea18c2c7ce Accept comma separated cns (#1336) 2018-05-15 10:14:25 +02:00
Igor Klopov
b721acb49e ignore keep-alive packets for now logs -f (#1331) 2018-05-15 10:14:19 +02:00
Javi Velasco
024a3d16db Safe deployment polling and other minor fixes (#1330)
* Initialize polling function from args

* Remove rule of having a mandatory dest field in path alias rules

* Wait 5 seconds after getting the deployment ready

* Ignore errors coming from events stream
2018-05-15 10:14:13 +02:00
Javi Velasco
75e493332e Refactor scale and remove old alias and scale (#1321)
* Migrate to arg@2.0.0

* Refactor scale command

* Move alias.js to alias/index.js

* Move alias set to its own file

* Move alias ls to its own file

* Move alias rm to its own file

* Remove old alias and scale files

* Update alias integration test

* Fix scaling to 0

* Read scale params from now.json on deploy
2018-05-15 10:14:06 +02:00
Igor Klopov
ff0b772b62 handle keep-alive event in inspect command (#1326) 2018-05-15 10:13:56 +02:00
Guillermo Rauch
eb746ae0f8 Updated error message about verification timeout 2018-05-15 10:04:38 +02:00
Javi Velasco
82eefe68e2 11.1.7 2018-04-18 11:35:50 -07:00
Javi Velasco
538e1e7b9c Handle ENOENT error when deploying unexistent path (#1320)
* Handle ENOENT error when deploying unexistent path

* Show success on dedupped deployments
2018-04-18 11:35:11 -07:00
Javi Velasco
c12d2f4226 Migrate to arg@2.0.0 (#1316) 2018-04-18 11:35:11 -07:00
Javi Velasco
b4428d099b Fix double ambiguous deploy prompt (#1318) 2018-04-18 11:35:11 -07:00
Javi Velasco
0acf907f47 Fix 0 min scale (#1317) 2018-04-18 11:35:11 -07:00
Naoyuki Kanezawa
d837756200 improve image upload (#1293) 2018-04-18 11:35:11 -07:00
Javi Velasco
f54566725e 11.1.6 2018-04-17 12:10:00 -07:00
Javi Velasco
ff34e3dfb1 Fix number of instances verification (#1315) 2018-04-17 12:09:45 -07:00
Leo Lamprecht
0b7a726f08 11.1.5 2018-04-16 19:37:45 -07:00
Javi Velasco
b53aef6254 Improve instance verification for deploy (#1313)
* Refactor verify instances for deploy

* Don't rely on return

* Use new verify instances in alias

* Use new verify instances in alias
2018-04-16 19:37:02 -07:00
Javi Velasco
ba4612042c Replace combine-async-generators (#1305)
* Replace combine-asyng-generators

* Ignore empty objects from events stream

* Update type for alias event
2018-04-16 19:36:55 -07:00
Javi Velasco
0d22fef2a0 Print response in docker test (#1304)
* Print response when failing in docker test file

* Add line

* Parse response text as JSON, print if it fails
2018-04-16 19:36:49 -07:00
Leo Lamprecht
6f6ff45062 Added missing dependencies (#1303) 2018-04-16 19:36:42 -07:00
Javi Velasco
8ba2ae634f Refactor deploy events printing (#1302)
* Move deploy command to its own directory

* Do not show success on downscale message

* Move getDeploymentByIdOrHost to /util/deploy

* Remove unneeded parameter in getAppName

* Better types for copyToClipboard

* Update to babel 7

* Add generator utility functions

* Add function to get deployment events

* Finish  getDeploymentEvents after getting one state-change event

* Refactor deploy events and reduce verification timeout

* Reduce verification timeout for scale and alias

* Use output.log for success message in scale

* Fix integration tests
2018-04-16 19:36:36 -07:00
Leo Lamprecht
fc1eae21ea 11.1.4 2018-04-11 12:32:03 -07:00
Javi Velasco
454a15cb25 Remove old certs command (#1295) 2018-04-11 12:23:51 -07:00
Leo Lamprecht
84b8b85f8d 11.1.3 2018-04-11 11:53:18 -07:00
Javi Velasco
2a2a7a7bd9 Remove old alias command (#1294) 2018-04-11 11:44:03 -07:00
Leo Lamprecht
addc237f7a 11.1.2 2018-04-10 18:07:23 -07:00
Leo Lamprecht
034763218b Fixed typo in release instructions 2018-04-10 18:02:20 -07:00
387 changed files with 133001 additions and 3077 deletions

View File

@@ -1,6 +1,5 @@
version: 2
jobs:
install:
docker:
- image: circleci/node:10
@@ -11,9 +10,9 @@ jobs:
- checkout
- restore_cache:
keys:
- v1-dependencies-{{ checksum "yarn.lock" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- v1-dependencies-{{ checksum "yarn.lock" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run:
name: Updating apt packages
command: sudo apt-get update
@@ -26,6 +25,7 @@ jobs:
- save_cache:
paths:
- node_modules
- packages/gatsby-plugin-now/node_modules
- packages/now-build-utils/node_modules
- packages/now-cgi/node_modules
- packages/now-cli/node_modules
@@ -43,6 +43,7 @@ jobs:
root: .
paths:
- node_modules
- packages/gatsby-plugin-now/node_modules
- packages/now-build-utils/node_modules
- packages/now-cgi/node_modules
- packages/now-cli/node_modules
@@ -67,6 +68,9 @@ jobs:
command: sudo apt install -y rsync
- attach_workspace:
at: .
- run:
name: Linking dependencies
command: yarn bootstrap
- run:
name: Building
command: yarn build
@@ -75,6 +79,7 @@ jobs:
- persist_to_workspace:
root: .
paths:
- packages/gatsby-plugin-now/test/fixtures
- packages/now-build-utils/dist
- packages/now-cgi/dist
- packages/now-cli/dist
@@ -91,6 +96,7 @@ jobs:
- packages/now-routing-utils/dist
- packages/now-ruby/dist
- packages/now-static-build/dist
- packages/now-static-build/test/fixtures/10a-gatsby-redirects/plugins
test-lint:
docker:
@@ -107,25 +113,6 @@ jobs:
name: Linting Code
command: yarn test-lint
# test-unit:
# docker:
# - image: circleci/node:10
# working_directory: ~/repo
# steps:
# - checkout
# - attach_workspace:
# at: .
# - run:
# name: Compiling `now dev` HTML error templates
# command: node packages/now-cli/scripts/compile-templates.js
# - run:
# name: Running Unit Tests
# command: yarn test-unit --clean false
# - persist_to_workspace:
# root: .
# paths:
# - packages/now-cli/.nyc_output
test-integration-macos-node-8:
macos:
xcode: '9.2.0'
@@ -384,36 +371,6 @@ jobs:
name: Finalize Sentry Release
command: sentry-cli releases finalize now-cli@`git describe --tags`
publish-stable:
docker:
- image: circleci/node:10
working_directory: ~/repo
steps:
- checkout
- attach_workspace:
at: .
- run:
name: Saving Authentication Information
command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
- run:
name: Publishing to Stable Channel
command: npm publish --tag latest
publish-canary:
docker:
- image: circleci/node:10
working_directory: ~/repo
steps:
- checkout
- attach_workspace:
at: .
- run:
name: Saving Authentication Information
command: echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc
- run:
name: Publishing to Canary Channel
command: npm publish --tag canary
workflows:
version: 2
unscheduled:
@@ -434,12 +391,6 @@ workflows:
filters:
tags:
only: /.*/
# - test-unit:
# requires:
# - build
# filters:
# tags:
# only: /.*/
- test-integration-macos-node-8:
requires:
- build
@@ -520,7 +471,6 @@ workflows:
only: /.*/
- coverage:
requires:
#- test-unit
- test-integration-macos-node-8
- test-integration-macos-node-10
- test-integration-macos-node-12
@@ -538,19 +488,3 @@ workflows:
filters:
tags:
only: /.*/
- publish-canary:
requires:
- coverage
filters:
tags:
only: /^.*canary.*($|\b)/
branches:
ignore: /.*/
- publish-stable:
requires:
- coverage
filters:
tags:
only: /^(\d+\.)?(\d+\.)?(\*|\d+)$/
branches:
ignore: /.*/

View File

@@ -1,6 +1,9 @@
node_modules
dist
# gatsby-plugin-now
packages/gatsby-plugin-now/test/fixtures
# now-cli
packages/now-cli/@types
packages/now-cli/download

View File

@@ -9,7 +9,7 @@ on:
- '!*'
jobs:
publish:
Publish:
runs-on: ubuntu-latest

1
.gitignore vendored
View File

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

View File

@@ -12,5 +12,6 @@ optimistic_updates = true
[merge.message]
title = "pull_request_title"
body = "pull_request_body"
include_pr_number = true
body_type = "markdown"

View File

@@ -1,3 +1,4 @@
{
"singleQuote": true
}
"singleQuote": true,
"trailingComma": "es5"
}

View File

@@ -1,40 +0,0 @@
# Publishing to npm
Always publish to the Canary Channel as soon as a PR is merged into the `canary` branch.
```
yarn publish-canary
```
Publish the Stable Channel weekly.
- Cherry pick each commit from `canary` to `master` branch
- Verify that you are _in-sync_ with canary (with the exception of the `version` line in `package.json`)
- Deploy the modified Builders
```
# View differences excluding "Publish" commits
git checkout canary && git pull
git log --pretty=format:"$ad- %s [%an]" | grep -v Publish > ~/Desktop/canary.txt
git checkout master && git pull
git log --pretty=format:"$ad- %s [%an]" | grep -v Publish > ~/Desktop/master.txt
diff ~/Desktop/canary.txt ~/Desktop/master.txt
# Cherry pick all PRs from canary into master ...
git cherry-pick <PR501_COMMIT_SHA>
git cherry-pick <PR502_COMMIT_SHA>
git cherry-pick <PR503_COMMIT_SHA>
git cherry-pick <PR504_COMMIT_SHA>
# Verify the only difference is "version" in package.json
git diff origin/canary
# Ship it
yarn publish-stable
```
After running this publish step, GitHub Actions will take care of publishing the modified Builder packages to npm.
If for some reason GitHub Actions fails to publish the npm package, you may do so
manually by running `npm publish` from the package directory. Make sure to
use `npm publish --tag canary` if you are publishing a canary release!

View File

@@ -1,6 +1,6 @@
![now](https://assets.zeit.co/image/upload/v1542240976/repositories/now-cli/now-cli-repo-banner-v3.png)
[![Build Status](https://circleci.com/gh/zeit/now.svg?&style=shield)](https://circleci.com/gh/zeit/workflows/now)
[![Build Status](https://badgen.net/circleci/github/zeit/now/master)](https://circleci.com/gh/zeit/workflows/now/tree/master)
[![Join the community on Spectrum](https://withspectrum.github.io/badge/badge.svg)](https://spectrum.chat/zeit)
**Note**: The [canary](https://github.com/zeit/now/tree/canary) branch is under heavy development the stable release branch is [master](https://github.com/zeit/now/tree/master).

18
changelog.js Normal file
View File

@@ -0,0 +1,18 @@
const { execSync } = require('child_process');
const commit = execSync('git log --pretty=format:"%s %H"')
.toString()
.trim()
.split('\n')
.find(line => line.startsWith('Publish '))
.split(' ')
.pop();
if (!commit) {
throw new Error('Unable to find last publish commit');
}
const log = execSync(`git log --pretty=format:"- %s [%an]" ${commit}...HEAD`).toString().trim();
console.log(`Changes since the last publish commit ${commit}:`);
console.log(`\n${log}\n`);

36
diff.js Normal file
View File

@@ -0,0 +1,36 @@
const { execSync } = require('child_process');
const { join } = require('path');
const { tmpdir } = require('os');
const { mkdirSync, writeFileSync } = require('fs');
function getCommits(count) {
return execSync('git log --pretty=format:"%s [%an]"')
.toString()
.trim()
.split('\n')
.slice(0, count)
.filter(line => !line.startsWith('Publish '))
.join('\n');
}
function main(count = '100') {
console.log(`Generating diff using last ${count} commits...`);
const randomTmpId = Math.random().toString().slice(2);
const dir = join(tmpdir(), 'now-diff' + randomTmpId);
mkdirSync(dir);
execSync('git checkout canary && git pull');
const canary = getCommits(count);
execSync('git checkout master && git pull');
const master = getCommits(count);
writeFileSync(join(dir, 'log.txt'), '# canary\n' + canary);
execSync('git init && git add -A && git commit -m "init"', { cwd: dir });
writeFileSync(join(dir, 'log.txt'), '# master\n' + master);
console.log(`Done generating diff. Run the following:`);
console.log(`cd ${dir}`);
console.log('Then use `git diff` or `git difftool` to view the differences.');
}
main(process.argv[2]);

View File

@@ -33,6 +33,8 @@
"publish-stable": "git checkout master && git pull && lerna version --exact",
"publish-canary": "git checkout canary && git pull && lerna version prerelease --preid canary --exact",
"publish-from-github": "./.circleci/publish.sh",
"diff": "node diff.js",
"changelog": "node changelog.js",
"build": "node run.js build all",
"test-lint": "node run.js test-lint",
"test-unit": "node run.js test-unit",

View File

@@ -0,0 +1,6 @@
#!/bin/bash
set -euo pipefail
# build fixtures for tests
yarn --cwd test/fixtures install
yarn --cwd test/fixtures run build

View File

@@ -0,0 +1,33 @@
const path = require('path');
const writeFile = require('util').promisify(require('fs').writeFile);
const REDIRECT_FILE_NAME = '__now_routes_g4t5bY.json';
exports.onPostBuild = async ({ store }) => {
const { redirects, program } = store.getState();
if (!redirects.length === 0) {
return;
}
const routes = [{ handle: 'filesystem' }];
for (const redirect of redirects) {
const route = {
src: redirect.fromPath,
status: redirect.statusCode || (redirect.isPermanent ? 301 : 302),
headers: { Location: redirect.toPath }
};
if (redirect.force) {
routes.unshift(route);
} else {
routes.push(route);
}
}
await writeFile(
path.join(program.directory, 'public', REDIRECT_FILE_NAME),
JSON.stringify(routes)
);
};

View File

@@ -0,0 +1 @@
// noop

View File

@@ -0,0 +1,36 @@
{
"name": "gatsby-plugin-now",
"version": "1.2.2",
"main": "index.js",
"license": "MIT",
"homepage": "https://github.com/zeit/now/tree/canary/packages/gatsby-plugin-now#readme",
"repository": {
"type": "git",
"url": "https://github.com/zeit/now.git",
"directory": "packages/gatsby-plugin-now"
},
"keywords": [
"gatsby",
"gatsby-plugin"
],
"scripts": {
"build": "./build.sh",
"test-integration-once": "jest --verbose"
},
"files": [
"index.js",
"gatsby-node.js"
],
"peerDependencies": {
"gatsby": ">=2.0.0"
},
"devDependencies": {
"jest": "24.9.0"
},
"jest": {
"testPathIgnorePatterns": [
"/node_modules/",
"<rootDir>/test/fixtures/"
]
}
}

View File

@@ -0,0 +1,24 @@
# gatsby-plugin-now
This plugin generates [Now Routes](https://zeit.co/docs/v2/advanced/routes) for [redirects](https://www.gatsbyjs.org/docs/actions/#createRedirect) you configured for to your Gatsby project.
### Usage
1. Install the plugin:
```
npm install gatsby-plugin-now --save-dev
```
2. Add it to the configuration file:
```
// gatsby-config.js
module.exports = {
plugins: [
'gatsby-plugin-now'
]
}
```
3. [Deploy your project to ZEIT Now](https://www.gatsbyjs.org/docs/deploying-to-zeit-now/)

View File

@@ -0,0 +1,86 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`test generated now routes 1`] = `
Array [
Object {
"headers": Object {
"Location": "/",
},
"src": "/my-special-redirect",
"status": 302,
},
Object {
"handle": "filesystem",
},
Object {
"headers": Object {
"Location": "/page-2",
},
"src": "/page2",
"status": 301,
},
Object {
"headers": Object {
"Location": "/page-2/",
},
"src": "/page2/",
"status": 301,
},
Object {
"headers": Object {
"Location": "/",
},
"src": "/orange",
"status": 302,
},
Object {
"headers": Object {
"Location": "/",
},
"src": "/grape",
"status": 302,
},
Object {
"headers": Object {
"Location": "/page-2/",
},
"src": "/blue",
"status": 302,
},
Object {
"headers": Object {
"Location": "/page-2/",
},
"src": "/randirect",
"status": 302,
},
Object {
"headers": Object {
"Location": "/",
},
"src": "/juice",
"status": 302,
},
Object {
"headers": Object {
"Location": "/",
},
"src": "/soda",
"status": 302,
},
Object {
"headers": Object {
"Location": "/page-2/",
},
"src": "/donut",
"status": 302,
},
Object {
"headers": Object {
"Location": "/page-2/",
},
"src": "/randorect",
"status": 302,
},
]
`;

View File

@@ -0,0 +1,4 @@
public
node_modules
.cache
yarn.lock

View File

@@ -0,0 +1,3 @@
module.exports = {
plugins: [{ resolve: require.resolve('../../') }]
};

View File

@@ -0,0 +1,105 @@
'use strict';
// Implement the Gatsby API “createPages”. This is called once the
// data layer is bootstrapped to let plugins create pages from data.
exports.createPages = ({ actions }) => {
// need createRedirect action in actions collection
// to make the redirection magic happen.
// https://www.gatsbyjs.org/docs/bound-action-creators/
const { createRedirect } = actions;
// Lets set up some string consts to use thoroughout the following.
// MDN > JavaScript reference > Statements and declarations
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
// Maybe we usually redirect to page 2, with trailing slash.
const page2Path = `/page-2/`;
// But sometimes to homepage.
const homePath = `/`;
// One-off redirect, note trailing slash missing on fromPath and
// toPath here.
createRedirect({
fromPath: `/page2`,
isPermanent: true,
redirectInBrowser: true,
toPath: `/page-2`
});
// Another one-off redirect, note trailing slash on toPath here.
// This time we want trailing slash on toPath so we use
// page2Path. Need to handle trailing-slashed and non-trailing-
// slashed fromPaths separately, Gatsby serves page components
// at either version by default, but we need to explicitly redirect
// both versions independently, more on page components:
// Docs > Building with Components
// https://www.gatsbyjs.org/docs/building-with-components/
// and handling trailing slashes:
// Docs > Creating and modifying pages > Removing trailing slashes
// https://www.gatsbyjs.org/docs/creating-and-modifying-pages/#removing-trailing-slashes
createRedirect({
fromPath: `/page2/`,
isPermanent: true,
redirectInBrowser: true,
toPath: page2Path
});
// One approach to handle several redirects at once is to create an
// array of from/to path pairs.
let redirectBatch1 = [
{ f: `/orange`, t: `/` },
// We could use homePath and page2Path directly here.
{ f: `/grape`, t: homePath },
{ f: `/blue`, t: page2Path },
// or leave to empty and swap for page2Path later on.
{ f: `/randirect`, t: `` }
];
// Then we can loop through the array of object literals to create
// each redirect. A for loop would do the trick
for (var { f: f, t: t } of redirectBatch1) {
// Here we swap any empty toPath values for trusty page 2 via
// page2Path.
if (t === ``) {
t = page2Path;
}
createRedirect({
fromPath: f,
redirectInBrowser: true,
toPath: t
});
// Uncomment next line to see loop in action during build
// console.log('\nRedirecting:\n' + f + '\nTo:\n' + t + '\n');
// or check .cache/redirects.json post-compile.
}
// A more modern approach might use forEach rather than for...of
// Compare
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Loops_and_iteration#for...of_statement
// and
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
let redirectBatch2 = [
{ f: `/juice`, t: `/` },
{ f: `/soda`, t: `/` },
{ f: `/donut`, t: page2Path },
{ f: `/randorect`, t: `` }
];
redirectBatch2.forEach(({ f, t }) => {
if (t === ``) {
t = page2Path;
}
createRedirect({
fromPath: f,
redirectInBrowser: true,
toPath: t
});
// Uncomment next line to see forEach in action during build
// console.log('\nRedirecting:\n' + f + '\nTo:\n' + t + '\n');
});
createRedirect({
fromPath: '/my-special-redirect',
toPath: homePath,
force: true
});
};

View File

@@ -0,0 +1,11 @@
{
"name": "fixtures",
"dependencies": {
"gatsby": "2.14.0",
"react": "16.9.0",
"react-dom": "16.9.0"
},
"scripts": {
"build": "gatsby build"
}
}

View File

@@ -0,0 +1,9 @@
import React from 'react';
const IndexPage = () => (
<div>
<h1>Hi people</h1>
</div>
);
export default IndexPage;

View File

@@ -0,0 +1,5 @@
test('test generated now routes', async () => {
const nowRoutes = require('./fixtures/public/__now_routes_g4t5bY.json');
expect(nowRoutes).toMatchSnapshot();
});

View File

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

View File

@@ -1,7 +1,5 @@
export default function debug(message: string, ...additional: any[]) {
if (process.env.NOW_BUILDER_DEBUG) {
console.log(message, ...additional);
} else if (process.env.NOW_BUILDER_ANNOTATE) {
console.log(`[now-builder-debug] ${message}`, ...additional);
}
}

View File

@@ -17,13 +17,13 @@ const MISSING_BUILD_SCRIPT_ERROR: ErrorResponse = {
code: 'missing_build_script',
message:
'Your `package.json` file is missing a `build` property inside the `script` property.' +
'\nMore details: https://zeit.co/docs/v2/advanced/platform/frequently-asked-questions#missing-build-script'
'\nMore details: https://zeit.co/docs/v2/advanced/platform/frequently-asked-questions#missing-build-script',
};
// Static builders are special cased in `@now/static-build`
function getBuilders(): Map<string, Builder> {
return new Map<string, Builder>([
['next', { src, use: '@now/next', config }]
['next', { src, use: '@now/next', config }],
]);
}
@@ -35,7 +35,7 @@ function getApiBuilders(): Builder[] {
{ src: 'api/**/*.ts', use: '@now/node', config },
{ src: 'api/**/*.go', use: '@now/go', config },
{ src: 'api/**/*.py', use: '@now/python', config },
{ src: 'api/**/*.rb', use: '@now/ruby', config }
{ src: 'api/**/*.rb', use: '@now/ruby', config },
];
}
@@ -107,6 +107,31 @@ async function detectApiBuilders(files: string[]): Promise<Builder[]> {
return finishedBuilds as Builder[];
}
// When a package has files that conflict with `/api` routes
// e.g. Next.js pages/api we'll check it here and return an error.
async function checkConflictingFiles(
files: string[],
builders: Builder[]
): Promise<ErrorResponse | null> {
// For Next.js
if (builders.some(builder => builder.use.startsWith('@now/next'))) {
const hasApiPages = files.some(file => file.startsWith('pages/api/'));
const hasApiBuilders = builders.some(builder =>
builder.src.startsWith('api/')
);
if (hasApiPages && hasApiBuilders) {
return {
code: 'conflicting_files',
message:
'It is not possible to use `api` and `pages/api` at the same time, please only use one option',
};
}
}
return null;
}
// When zero config is used we can call this function
// to determine what builders to use
export async function detectBuilders(
@@ -116,20 +141,28 @@ export async function detectBuilders(
): Promise<{
builders: Builder[] | null;
errors: ErrorResponse[] | null;
warnings: ErrorResponse[];
}> {
const errors: ErrorResponse[] = [];
const warnings: ErrorResponse[] = [];
// Detect all builders for the `api` directory before anything else
let builders = await detectApiBuilders(files);
if (pkg && hasBuildScript(pkg)) {
builders.push(await detectBuilder(pkg));
const conflictError = await checkConflictingFiles(files, builders);
if (conflictError) {
warnings.push(conflictError);
}
} else {
if (pkg && builders.length === 0) {
// We only show this error when there are no api builders
// since the dependencies of the pkg could be used for those
errors.push(MISSING_BUILD_SCRIPT_ERROR);
return { errors, builders: null };
return { errors, warnings, builders: null };
}
// We allow a `public` directory
@@ -138,7 +171,7 @@ export async function detectBuilders(
builders.push({
use: '@now/static',
src: 'public/**/*',
config
config,
});
} else if (builders.length > 0) {
// We can't use pattern matching, since `!(api)` and `!(api)/**/*`
@@ -150,7 +183,7 @@ export async function detectBuilders(
.map(name => ({
use: '@now/static',
src: name,
config
config,
}))
);
}
@@ -177,6 +210,7 @@ export async function detectBuilders(
return {
builders: builders.length ? builders : null,
errors: errors.length ? errors : null
errors: errors.length ? errors : null,
warnings,
};
}

View File

@@ -1,5 +1,6 @@
import { intersects } from 'semver';
import { NodeVersion } from '../types';
import debug from '../debug';
const supportedOptions: NodeVersion[] = [
{ major: 10, range: '10.x', runtime: 'nodejs10.x' },
@@ -20,7 +21,7 @@ export async function getSupportedNodeVersion(
if (!engineRange) {
if (!silent) {
console.log(
debug(
'missing `engines` in `package.json`, using default range: ' +
selection.range
);
@@ -34,7 +35,7 @@ export async function getSupportedNodeVersion(
});
if (found) {
if (!silent) {
console.log(
debug(
'Found `engines` in `package.json`, selecting range: ' +
selection.range
);

View File

@@ -1,21 +1,22 @@
import assert from 'assert';
import fs from 'fs-extra';
import path from 'path';
import debug from '../debug';
import spawn from 'cross-spawn';
import { SpawnOptions } from 'child_process';
import { deprecate } from 'util';
import { cpus } from 'os';
import { Meta, PackageJson, NodeVersion, Config } from '../types';
import { getSupportedNodeVersion } from './node-version';
function spawnAsync(
export function spawnAsync(
command: string,
args: string[],
cwd: string,
opts: SpawnOptions = {}
) {
return new Promise<void>((resolve, reject) => {
const stderrLogs: Buffer[] = [];
opts = { stdio: 'inherit', cwd, ...opts };
opts = { stdio: 'inherit', ...opts };
const child = spawn(command, args, opts);
if (opts.stdio === 'pipe' && child.stderr) {
@@ -54,7 +55,10 @@ export async function runShellScript(
assert(path.isAbsolute(fsPath));
const destPath = path.dirname(fsPath);
await chmodPlusX(fsPath);
await spawnAsync(`./${path.basename(fsPath)}`, args, destPath, spawnOpts);
await spawnAsync(`./${path.basename(fsPath)}`, args, {
cwd: destPath,
...spawnOpts,
});
return true;
}
@@ -128,38 +132,100 @@ async function scanParentDirs(destPath: string, readPackageJson = false) {
export async function runNpmInstall(
destPath: string,
args: string[] = [],
spawnOpts?: SpawnOptions
spawnOpts?: SpawnOptions,
meta?: Meta
) {
if (meta && meta.isDev) {
debug('Skipping dependency installation because dev mode is enabled');
return;
}
assert(path.isAbsolute(destPath));
let commandArgs = args;
console.log(`installing to ${destPath}`);
debug(`Installing to ${destPath}`);
const { hasPackageLockJson } = await scanParentDirs(destPath);
const opts = spawnOpts || { env: process.env };
const opts = { cwd: destPath, ...spawnOpts } || {
cwd: destPath,
env: process.env,
};
if (hasPackageLockJson) {
commandArgs = args.filter(a => a !== '--prefer-offline');
await spawnAsync(
'npm',
commandArgs.concat(['install', '--unsafe-perm']),
destPath,
opts
);
} else {
await spawnAsync(
'yarn',
commandArgs.concat(['--ignore-engines', '--cwd', destPath]),
destPath,
opts
);
}
}
export async function runBundleInstall(
destPath: string,
args: string[] = [],
spawnOpts?: SpawnOptions,
meta?: Meta
) {
if (meta && meta.isDev) {
debug('Skipping dependency installation because dev mode is enabled');
return;
}
assert(path.isAbsolute(destPath));
const opts = { cwd: destPath, ...spawnOpts } || {
cwd: destPath,
env: process.env,
};
await spawnAsync(
'bundle',
args.concat([
'install',
'--no-prune',
'--retry',
'3',
'--jobs',
String(cpus().length || 1),
]),
opts
);
}
export async function runPipInstall(
destPath: string,
args: string[] = [],
spawnOpts?: SpawnOptions,
meta?: Meta
) {
if (meta && meta.isDev) {
debug('Skipping dependency installation because dev mode is enabled');
return;
}
assert(path.isAbsolute(destPath));
const opts = { cwd: destPath, ...spawnOpts } || {
cwd: destPath,
env: process.env,
};
await spawnAsync(
'pip3',
['install', '--disable-pip-version-check', ...args],
opts
);
}
export async function runPackageJsonScript(
destPath: string,
scriptName: string,
opts?: SpawnOptions
spawnOpts?: SpawnOptions
) {
assert(path.isAbsolute(destPath));
const { packageJson, hasPackageLockJson } = await scanParentDirs(
@@ -174,17 +240,14 @@ export async function runPackageJsonScript(
);
if (!hasScript) return false;
const opts = { cwd: destPath, ...spawnOpts };
if (hasPackageLockJson) {
console.log(`running "npm run ${scriptName}"`);
await spawnAsync('npm', ['run', scriptName], destPath, opts);
console.log(`Running "npm run ${scriptName}"`);
await spawnAsync('npm', ['run', scriptName], opts);
} else {
console.log(`running "yarn run ${scriptName}"`);
await spawnAsync(
'yarn',
['--cwd', destPath, 'run', scriptName],
destPath,
opts
);
console.log(`Running "yarn run ${scriptName}"`);
await spawnAsync('yarn', ['--cwd', destPath, 'run', scriptName], opts);
}
return true;

View File

@@ -2,14 +2,18 @@ import FileBlob from './file-blob';
import FileFsRef from './file-fs-ref';
import FileRef from './file-ref';
import { Lambda, createLambda } from './lambda';
import { Prerender } from './prerender';
import download, { DownloadedFiles } from './fs/download';
import getWriteableDirectory from './fs/get-writable-directory';
import glob from './fs/glob';
import rename from './fs/rename';
import {
spawnAsync,
installDependencies,
runPackageJsonScript,
runNpmInstall,
runBundleInstall,
runPipInstall,
runShellScript,
getNodeVersion,
getSpawnOptions,
@@ -26,14 +30,18 @@ export {
FileRef,
Lambda,
createLambda,
Prerender,
download,
DownloadedFiles,
getWriteableDirectory,
glob,
rename,
spawnAsync,
installDependencies,
runPackageJsonScript,
runNpmInstall,
runBundleInstall,
runPipInstall,
runShellScript,
getNodeVersion,
getSpawnOptions,

View File

@@ -0,0 +1,35 @@
import FileBlob from './file-blob';
import FileFsRef from './file-fs-ref';
import FileRef from './file-ref';
import { Lambda } from './lambda';
interface PrerenderOptions {
expiration: number;
lambda: Lambda;
fallback: FileBlob | FileFsRef | FileRef;
group?: number;
}
export class Prerender {
public type: 'Prerender';
public expiration: number;
public lambda: Lambda;
public fallback: FileBlob | FileFsRef | FileRef;
public group?: number;
constructor({ expiration, lambda, fallback, group }: PrerenderOptions) {
this.type = 'Prerender';
this.expiration = expiration;
this.lambda = lambda;
this.fallback = fallback;
if (
typeof group !== 'undefined' &&
(group <= 0 || !Number.isInteger(group))
) {
throw new Error('The `group` argument for `Prerender` needs to be a natural number.');
}
this.group = group;
}
}

View File

@@ -1,6 +1,10 @@
import FileRef from './file-ref';
import FileFsRef from './file-fs-ref';
export interface Env {
[name: string]: string | undefined;
}
export interface File {
type: string;
mode: number;
@@ -52,6 +56,8 @@ export interface Meta {
requestPath?: string;
filesChanged?: string[];
filesRemoved?: string[];
env?: Env;
buildEnv?: Env;
}
export interface AnalyzeOptions {
@@ -185,8 +191,8 @@ export interface ShouldServeOptions {
}
export interface PackageJson {
name: string;
version: string;
name?: string;
version?: string;
engines?: {
[key: string]: string;
node: string;

View File

@@ -6,11 +6,11 @@ const { createZip } = require('../dist/lambda');
const { glob, download, detectBuilders, detectRoutes } = require('../');
const {
getSupportedNodeVersion,
defaultSelection
defaultSelection,
} = require('../dist/fs/node-version');
const {
packAndDeploy,
testDeployment
testDeployment,
} = require('../../../test/lib/deployment/test-deployment');
jest.setTimeout(4 * 60 * 1000);
@@ -38,7 +38,7 @@ it('should re-create symlinks properly', async () => {
const [linkStat, aStat] = await Promise.all([
fs.lstat(path.join(outDir, 'link.txt')),
fs.lstat(path.join(outDir, 'a.txt'))
fs.lstat(path.join(outDir, 'a.txt')),
]);
assert(linkStat.isSymbolicLink());
assert(aStat.isFile());
@@ -60,7 +60,7 @@ it('should create zip files with symlinks properly', async () => {
const [linkStat, aStat] = await Promise.all([
fs.lstat(path.join(outDir, 'link.txt')),
fs.lstat(path.join(outDir, 'a.txt'))
fs.lstat(path.join(outDir, 'a.txt')),
]);
assert(linkStat.isSymbolicLink());
assert(aStat.isFile());
@@ -120,7 +120,7 @@ it('should support require by path for legacy builders', () => {
const glob2 = require('@now/build-utils/fs/glob.js');
const rename2 = require('@now/build-utils/fs/rename.js');
const {
runNpmInstall: runNpmInstall2
runNpmInstall: runNpmInstall2,
} = require('@now/build-utils/fs/run-user-scripts.js');
const streamToBuffer2 = require('@now/build-utils/fs/stream-to-buffer.js');
@@ -206,7 +206,7 @@ it('Test `detectBuilders`', async () => {
// package.json + no build + next
const pkg = {
scripts: { build: 'next build' },
dependencies: { next: '9.0.0' }
dependencies: { next: '9.0.0' },
};
const files = ['package.json', 'pages/index.js'];
const { builders, errors } = await detectBuilders(files, pkg);
@@ -218,7 +218,7 @@ it('Test `detectBuilders`', async () => {
// package.json + no build + next
const pkg = {
scripts: { build: 'next build' },
devDependencies: { next: '9.0.0' }
devDependencies: { next: '9.0.0' },
};
const files = ['package.json', 'pages/index.js'];
const { builders, errors } = await detectBuilders(files, pkg);
@@ -282,7 +282,7 @@ it('Test `detectBuilders`', async () => {
const files = [
'api/_utils/handler.js',
'api/[endpoint]/.helper.js',
'api/[endpoint]/[id].js'
'api/[endpoint]/[id].js',
];
const { builders } = await detectBuilders(files);
@@ -295,7 +295,7 @@ it('Test `detectBuilders`', async () => {
// api + next + public
const pkg = {
scripts: { build: 'next build' },
devDependencies: { next: '9.0.0' }
devDependencies: { next: '9.0.0' },
};
const files = ['package.json', 'api/endpoint.js', 'public/index.html'];
@@ -311,7 +311,7 @@ it('Test `detectBuilders`', async () => {
// api + next + raw static
const pkg = {
scripts: { build: 'next build' },
devDependencies: { next: '9.0.0' }
devDependencies: { next: '9.0.0' },
};
const files = ['package.json', 'api/endpoint.js', 'index.html'];
@@ -343,7 +343,7 @@ it('Test `detectBuilders`', async () => {
'api/endpoint.js',
'public/index.html',
'public/favicon.ico',
'README.md'
'README.md',
];
const { builders } = await detectBuilders(files);
@@ -367,7 +367,7 @@ it('Test `detectBuilders`', async () => {
// next + public
const pkg = {
scripts: { build: 'next build' },
devDependencies: { next: '9.0.0' }
devDependencies: { next: '9.0.0' },
};
const files = ['package.json', 'public/index.html', 'README.md'];
@@ -381,7 +381,7 @@ it('Test `detectBuilders`', async () => {
// nuxt
const pkg = {
scripts: { build: 'nuxt build' },
dependencies: { nuxt: '2.8.1' }
dependencies: { nuxt: '2.8.1' },
};
const files = ['package.json', 'pages/index.js'];
@@ -433,12 +433,12 @@ it('Test `detectBuilders`', async () => {
// package.json + api + canary
const pkg = {
scripts: { build: 'next build' },
dependencies: { next: '9.0.0' }
dependencies: { next: '9.0.0' },
};
const files = [
'pages/index.js',
'api/[endpoint].js',
'api/[endpoint]/[id].js'
'api/[endpoint]/[id].js',
];
const { builders } = await detectBuilders(files, pkg, { tag: 'canary' });
@@ -452,12 +452,12 @@ it('Test `detectBuilders`', async () => {
// package.json + api + latest
const pkg = {
scripts: { build: 'next build' },
dependencies: { next: '9.0.0' }
dependencies: { next: '9.0.0' },
};
const files = [
'pages/index.js',
'api/[endpoint].js',
'api/[endpoint]/[id].js'
'api/[endpoint]/[id].js',
];
const { builders } = await detectBuilders(files, pkg, { tag: 'latest' });
@@ -471,12 +471,12 @@ it('Test `detectBuilders`', async () => {
// package.json + api + random tag
const pkg = {
scripts: { build: 'next build' },
dependencies: { next: '9.0.0' }
dependencies: { next: '9.0.0' },
};
const files = [
'pages/index.js',
'api/[endpoint].js',
'api/[endpoint]/[id].js'
'api/[endpoint]/[id].js',
];
const { builders } = await detectBuilders(files, pkg, { tag: 'haha' });
@@ -485,6 +485,23 @@ it('Test `detectBuilders`', async () => {
expect(builders[2].use).toBe('@now/next@haha');
expect(builders.length).toBe(3);
}
{
// next.js pages/api + api
const pkg = {
scripts: { build: 'next build' },
dependencies: { next: '9.0.0' },
};
const files = ['api/user.js', 'pages/api/user.js'];
const { warnings, errors, builders } = await detectBuilders(files, pkg);
expect(errors).toBe(null);
expect(warnings[0].code).toBe('conflicting_files');
expect(builders).toBeDefined();
expect(builders.length).toBe(2);
expect(builders[0].use).toBe('@now/node');
expect(builders[1].use).toBe('@now/next');
}
});
it('Test `detectRoutes`', async () => {
@@ -545,7 +562,7 @@ it('Test `detectRoutes`', async () => {
const files = [
'public/index.html',
'api/[endpoint].js',
'api/[endpoint]/[id].js'
'api/[endpoint]/[id].js',
];
const { builders } = await detectBuilders(files);
@@ -560,7 +577,7 @@ it('Test `detectRoutes`', async () => {
{
const pkg = {
scripts: { build: 'next build' },
devDependencies: { next: '9.0.0' }
devDependencies: { next: '9.0.0' },
};
const files = ['public/index.html', 'api/[endpoint].js'];
@@ -617,7 +634,7 @@ it('Test `detectRoutes`', async () => {
'api/users/index.ts',
'api/users/index.d.ts',
'api/food.ts',
'api/ts/gold.ts'
'api/ts/gold.ts',
];
const { builders } = await detectBuilders(files);
const { defaultRoutes } = await detectRoutes(files, builders);
@@ -641,39 +658,39 @@ it('Test `detectBuilders` and `detectRoutes`', async () => {
{
path: '/api/my-endpoint',
mustContain: 'my-endpoint',
status: 200
status: 200,
},
{
path: '/api/other-endpoint',
mustContain: 'other-endpoint',
status: 200
status: 200,
},
{
path: '/api/team/zeit',
mustContain: 'team/zeit',
status: 200
status: 200,
},
{
path: '/api/user/myself',
mustContain: 'user/myself',
status: 200
status: 200,
},
{
path: '/api/not-okay/',
status: 404
status: 404,
},
{
path: '/api',
status: 404
status: 404,
},
{
path: '/api/',
status: 404
status: 404,
},
{
path: '/',
mustContain: 'hello from index.txt'
}
mustContain: 'hello from index.txt',
},
];
const { builders } = await detectBuilders(files, pkg);
@@ -701,32 +718,32 @@ it('Test `detectBuilders` and `detectRoutes` with `index` files', async () => {
const probes = [
{
path: '/api/not-okay',
status: 404
status: 404,
},
{
path: '/api',
mustContain: 'hello from api/index.js',
status: 200
status: 200,
},
{
path: '/api/',
mustContain: 'hello from api/index.js',
status: 200
status: 200,
},
{
path: '/api/index',
mustContain: 'hello from api/index.js',
status: 200
status: 200,
},
{
path: '/api/index.js',
mustContain: 'hello from api/index.js',
status: 200
status: 200,
},
{
path: '/api/date.js',
mustContain: 'hello from api/date.js',
status: 200
status: 200,
},
{
// Someone might expect this to be `date.js`,
@@ -735,27 +752,27 @@ it('Test `detectBuilders` and `detectRoutes` with `index` files', async () => {
// so it is not special cased
path: '/api/date',
mustContain: 'hello from api/date/index.js',
status: 200
status: 200,
},
{
path: '/api/date/',
mustContain: 'hello from api/date/index.js',
status: 200
status: 200,
},
{
path: '/api/date/index',
mustContain: 'hello from api/date/index.js',
status: 200
status: 200,
},
{
path: '/api/date/index.js',
mustContain: 'hello from api/date/index.js',
status: 200
status: 200,
},
{
path: '/',
mustContain: 'hello from index.txt'
}
mustContain: 'hello from index.txt',
},
];
const { builders } = await detectBuilders(files, pkg);

View File

@@ -1,6 +1,6 @@
{
"name": "@now/cgi",
"version": "0.1.5-canary.1",
"version": "0.1.6",
"license": "MIT",
"repository": {
"type": "git",

View File

@@ -1,3 +0,0 @@
declare module 'cache-or-tmp-directory' {
export default function (appName: string) : string | null
}

View File

@@ -1,3 +0,0 @@
declare module 'pcre-to-regexp' {
export default function (pattern: string, keys?: string[]): RegExp
}

View File

@@ -1,6 +1,6 @@
{
"name": "now",
"version": "16.1.3-canary.3",
"version": "16.3.0",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Now",
@@ -61,12 +61,6 @@
"node": ">= 8.11"
},
"devDependencies": {
"@now/build-utils": "0.9.14-canary.2",
"@now/go": "latest",
"@now/next": "latest",
"@now/node": "latest",
"@now/routing-utils": "1.2.3-canary.1",
"@now/static-build": "latest",
"@sentry/node": "5.5.0",
"@types/ansi-escapes": "3.0.0",
"@types/ansi-regex": "4.0.0",
@@ -98,7 +92,7 @@
"@types/which": "1.3.1",
"@types/write-json-file": "2.2.1",
"@zeit/dockerignore": "0.0.5",
"@zeit/fun": "0.9.1",
"@zeit/fun": "0.10.2",
"@zeit/ncc": "0.18.5",
"@zeit/source-map-support": "0.6.2",
"ajv": "6.10.2",
@@ -111,7 +105,6 @@
"async-sema": "2.1.4",
"ava": "2.2.0",
"bytes": "3.0.0",
"cache-or-tmp-directory": "1.0.0",
"chalk": "2.4.2",
"chokidar": "2.1.6",
"clipboardy": "2.1.0",
@@ -132,10 +125,10 @@
"escape-html": "1.0.3",
"esm": "3.1.4",
"execa": "1.0.0",
"fetch-h2": "2.0.3",
"fs-extra": "7.0.1",
"glob": "7.1.2",
"http-proxy": "1.17.0",
"ignore": "4.0.6",
"ini": "1.3.4",
"inquirer": "3.3.0",
"is-url": "1.2.2",
@@ -146,12 +139,13 @@
"mime-types": "2.1.24",
"minimatch": "3.0.4",
"mri": "1.1.0",
"ms": "2.1.1",
"ms": "2.1.2",
"node-fetch": "1.7.3",
"now-client": "./packages/now-client",
"npm-package-arg": "6.1.0",
"nyc": "13.2.0",
"ora": "3.4.0",
"pcre-to-regexp": "0.0.5",
"pcre-to-regexp": "1.0.0",
"pluralize": "7.0.0",
"pre-commit": "1.2.2",
"printf": "0.2.5",

View File

@@ -8,16 +8,13 @@ import { createWriteStream, mkdirp, remove, writeJSON } from 'fs-extra';
import { getDistTag } from '../src/util/get-dist-tag';
import pkg from '../package.json';
import { getBundledBuilders } from '../src/util/dev/get-bundled-builders';
const dirRoot = join(__dirname, '..');
const bundledBuilders = Object.keys(pkg.devDependencies).filter(d =>
d.startsWith('@now/')
);
async function createBuildersTarball() {
const distTag = getDistTag(pkg.version);
const builders = Array.from(bundledBuilders).map(b => `${b}@${distTag}`);
const builders = Array.from(getBundledBuilders()).map(b => `${b}@${distTag}`);
console.log(`Creating builders tarball with: ${builders.join(', ')}`);
const buildersDir = join(dirRoot, '.builders');
@@ -39,7 +36,7 @@ async function createBuildersTarball() {
const yarn = join(dirRoot, '../../node_modules/yarn/bin/yarn.js');
await execa(process.execPath, [yarn, 'add', '--no-lockfile', ...builders], {
cwd: buildersDir,
stdio: 'inherit'
stdio: 'inherit',
});
const packer = tar.pack(buildersDir);
@@ -66,7 +63,7 @@ async function main() {
// Compile the `doT.js` template files for `now dev`
console.log();
await execa(process.execPath, [join(__dirname, 'compile-templates.js')], {
stdio: 'inherit'
stdio: 'inherit',
});
// Do the initial `ncc` build
@@ -92,20 +89,22 @@ async function main() {
// get compiled into the final ncc bundle file, however, we want them to be
// present in the npm package because the contents of those files are involved
// with `fun`'s cache invalidation mechanism and they need to be shasum'd.
const runtimes = join(dirRoot, '../../node_modules/@zeit/fun/dist/src/runtimes');
const runtimes = join(
dirRoot,
'../../node_modules/@zeit/fun/dist/src/runtimes'
);
const dest = join(dirRoot, 'dist/runtimes');
await cpy('**/*', dest, { parents: true, cwd: runtimes });
console.log('Finished building `now-cli`');
}
process.on('unhandledRejection', (err: any) => {
console.error('Unhandled Rejection:');
console.error(err);
process.on('unhandledRejection', (reason: any, promise: Promise<any>) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
process.exit(1);
});
process.on('uncaughtException', (err: any) => {
process.on('uncaughtException', err => {
console.error('Uncaught Exception:');
console.error(err);
process.exit(1);

View File

@@ -11,7 +11,10 @@ import strlen from '../../util/strlen.ts';
import wait from '../../util/output/wait';
export default async function ls(ctx, opts, args, output) {
const { authConfig: { token }, config } = ctx;
const {
authConfig: { token },
config
} = ctx;
const { currentTeam } = config;
const { apiUrl } = ctx;
const { '--debug': debugEnabled } = opts;
@@ -48,15 +51,13 @@ export default async function ls(ctx, opts, args, output) {
return 1;
}
if (!opts['--json']) {
cancelWait = wait(
args[0]
? `Fetching alias details for "${args[0]}" under ${chalk.bold(
contextName
)}`
: `Fetching aliases under ${chalk.bold(contextName)}`
);
}
cancelWait = wait(
args[0]
? `Fetching alias details for "${args[0]}" under ${chalk.bold(
contextName
)}`
: `Fetching aliases under ${chalk.bold(contextName)}`
);
const aliases = await getAliases(now);
if (cancelWait) cancelWait();
@@ -72,7 +73,7 @@ export default async function ls(ctx, opts, args, output) {
}
if (opts['--json']) {
output.print(JSON.stringify({ rules: alias.rules }, null, 2));
console.log(JSON.stringify({ rules: alias.rules }, null, 2));
} else {
const rules = alias.rules || [];
output.log(
@@ -105,11 +106,11 @@ function printAliasTable(aliases) {
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(''),
// 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.created))
])

View File

@@ -38,7 +38,7 @@ export default async function set(
const {
authConfig: { token },
config,
localConfig
localConfig,
} = ctx;
const { currentTeam } = config;
@@ -48,14 +48,14 @@ export default async function set(
const {
'--debug': debugEnabled,
'--no-verify': noVerify,
'--rules': rulesPath
'--rules': rulesPath,
} = opts;
const client = new Client({
apiUrl,
token,
currentTeam,
debug: debugEnabled
debug: debugEnabled,
});
let contextName = null;
let user = null;
@@ -79,12 +79,14 @@ export default async function set(
return 1;
}
if (!isValidName(args[0])) {
output.error(`The provided argument "${args[0]}" is not a valid deployment`);
if (args.length >= 1 && !isValidName(args[0])) {
output.error(
`The provided argument "${args[0]}" is not a valid deployment`
);
return 1;
}
if (!isValidName(args[1])) {
if (args.length >= 2 && !isValidName(args[1])) {
output.error(`The provided argument "${args[1]}" is not a valid domain`);
return 1;
}
@@ -212,6 +214,7 @@ export default async function set(
for (const target of targets) {
output.log(`Assigning alias ${target} to deployment ${deployment.url}`);
const isWildcard = isWildcardAlias(target);
const record = await assignAlias(
output,
client,
@@ -222,13 +225,14 @@ export default async function set(
);
const handleResult = handleSetupDomainError(
output,
handleCreateAliasError(output, record)
handleCreateAliasError(output, record),
isWildcard
);
if (handleResult === 1) {
return 1;
}
const prefix = isWildcardAlias(handleResult.alias) ? '' : 'https://';
const prefix = isWildcard ? '' : 'https://';
console.log(
`${chalk.cyan('> Success!')} ${chalk.bold(
@@ -246,10 +250,15 @@ type SetupDomainError = Exclude<SetupDomainResolve, Domain>;
function handleSetupDomainError<T>(
output: Output,
error: SetupDomainError | T
error: SetupDomainError | T,
isWildcard: boolean = false
): T | 1 {
if (error instanceof ERRORS.DomainVerificationFailed) {
const { nsVerification, txtVerification, domain } = error.meta;
if (
error instanceof ERRORS.DomainVerificationFailed ||
error instanceof ERRORS.DomainNsNotVerifiedForWildcard
) {
const { nsVerification, domain } = error.meta;
output.error(
`We could not alias since the domain ${domain} could not be verified due to the following reasons:\n`
);
@@ -265,25 +274,34 @@ function handleSetupDomainError<T>(
{ extraSpace: ' ' }
)}\n\n`
);
output.print(
` ${chalk.gray(
'b)'
)} DNS TXT verification failed since found no matching records.`
);
output.print(
`\n${formatDnsTable(
[['_now', 'TXT', txtVerification.verificationRecord]],
{ extraSpace: ' ' }
)}\n\n`
);
output.print(
` Once your domain uses either the nameservers or the TXT DNS record from above, run again ${cmd(
'now domains verify <domain>'
)}.\n`
);
output.print(
` We will also periodically run a verification check for you and you will receive an email once your domain is verified.\n`
);
if (error instanceof ERRORS.DomainVerificationFailed && !isWildcard) {
const { txtVerification } = error.meta;
output.print(
` ${chalk.gray(
'b)'
)} DNS TXT verification failed since found no matching records.`
);
output.print(
`\n${formatDnsTable(
[['_now', 'TXT', txtVerification.verificationRecord]],
{ extraSpace: ' ' }
)}\n\n`
);
output.print(
` Once your domain uses either the nameservers or the TXT DNS record from above, run again ${cmd(
'now domains verify <domain>'
)}.\n`
);
output.print(
` We will also periodically run a verification check for you and you will receive an email once your domain is verified.\n`
);
} else {
output.print(
` Once your domain uses the nameservers from above, run again ${cmd(
'now domains verify <domain>'
)}.\n`
);
}
output.print(' Read more: https://err.sh/now/domain-verification\n');
return 1;
}
@@ -349,9 +367,7 @@ function handleSetupDomainError<T>(
if (error instanceof ERRORS.DomainPurchasePending) {
output.error(
`The domain ${
error.meta.domain
} is processing and will be available once the order is completed.`
`The domain ${error.meta.domain} is processing and will be available once the order is completed.`
);
output.print(
` An email will be sent upon completion so you can alias to your new domain.\n`
@@ -467,9 +483,7 @@ function handleCreateAliasError<T>(
}
if (error instanceof ERRORS.ForbiddenScaleMinInstances) {
output.error(
`You can't scale to more than ${
error.meta.max
} min instances with your current plan.`
`You can't scale to more than ${error.meta.max} min instances with your current plan.`
);
return 1;
}
@@ -490,9 +504,7 @@ function handleCreateAliasError<T>(
if (error instanceof ERRORS.CertMissing) {
output.error(
`There is no certificate for the domain ${
error.meta.domain
} and it could not be created.`
`There is no certificate for the domain ${error.meta.domain} and it could not be created.`
);
output.log(
`Please generate a new certificate manually with ${cmd(

View File

@@ -1,12 +1,15 @@
import chalk from 'chalk';
// @ts-ignore
import Now from '../../util';
import Client from '../../util/client.ts';
import getScope from '../../util/get-scope.ts';
import stamp from '../../util/output/stamp.ts';
import Client from '../../util/client';
import getScope from '../../util/get-scope';
import stamp from '../../util/output/stamp';
import wait from '../../util/output/wait';
import createCertFromFile from '../../util/certs/create-cert-from-file';
import createCertForCns from '../../util/certs/create-cert-for-cns';
import { NowContext } from '../../types';
import { Output } from '../../util/output';
import {
DomainPermissionDenied,
@@ -14,7 +17,20 @@ import {
} from '../../util/errors-ts';
import handleCertError from '../../util/certs/handle-cert-error';
async function add(ctx, opts, args, output) {
interface Options {
'--overwrite'?: boolean;
'--debug'?: boolean;
'--crt'?: string;
'--key'?: string;
'--ca'?: string;
}
async function add(
ctx: NowContext,
opts: Options,
args: string[],
output: Output
): Promise<number> {
const {
authConfig: { token },
config
@@ -77,10 +93,12 @@ async function add(ctx, opts, args, output) {
// Create a custom certificate from the given file paths
cert = await createCertFromFile(now, keyPath, crtPath, caPath, contextName);
if (cert instanceof InvalidCert) {
output.error(`The provided certificate is not valid and can't be added.`);
return 1;
}
if (cert instanceof DomainPermissionDenied) {
output.error(
`You don't have permissions over domain ${chalk.underline(
@@ -97,6 +115,7 @@ async function add(ctx, opts, args, output) {
'now certs issue <cn> <cns>'
)} instead`
);
if (args.length < 1) {
output.error(
`Invalid number of arguments to create a custom certificate entry. Usage:`
@@ -107,34 +126,43 @@ async function add(ctx, opts, args, output) {
}
// Create the certificate from the given array of CNs
const cns = args.reduce((res, item) => [...res, ...item.split(',')], []);
const cns = args.reduce<string[]>((res, item) => res.concat(item.split(',')), []);
const cancelWait = wait(
`Generating a certificate for ${chalk.bold(cns.join(', '))}`
);
cert = await createCertForCns(now, cns, contextName);
cancelWait();
const result = handleCertError(output, cert);
if (result === 1) {
return result
}
if (cert instanceof DomainPermissionDenied) {
output.error(
`You don't have permissions over domain ${chalk.underline(
cert.meta.domain
)} under ${chalk.bold(cert.meta.context)}.`
);
return 1;
}
}
// Print success message
output.success(
`Certificate entry for ${chalk.bold(
cert.cns.join(', ')
)} created ${addStamp()}`
);
const result = handleCertError(output, cert);
if (result === 1) {
return result;
}
if (cert instanceof DomainPermissionDenied) {
output.error(
`You don't have permissions over domain ${chalk.underline(
cert.meta.domain
)} under ${chalk.bold(cert.meta.context)}.`
);
return 1;
}
if (cert instanceof Error) {
// All cert errors are handled above,
// so this is only for typescript
throw cert;
} else {
// Print success message
output.success(
`Certificate entry for ${chalk.bold(
cert.cns.join(', ')
)} created ${addStamp()}`
);
}
return 0;
}

View File

@@ -1,6 +1,6 @@
//
import chalk from 'chalk';
// @ts-ignore
import { handleError } from '../../util/error';
import createOutput from '../../util/output';
@@ -12,6 +12,7 @@ import add from './add';
import issue from './issue';
import ls from './ls';
import rm from './rm';
import { NowContext } from '../../types';
const help = () => {
console.log(`
@@ -71,7 +72,7 @@ const COMMAND_CONFIG = {
rm: ['rm', 'remove']
};
export default async function main(ctx) {
export default async function main(ctx: NowContext) {
let argv;
try {

View File

@@ -3,16 +3,29 @@ import ms from 'ms';
import plural from 'pluralize';
import psl from 'psl';
import table from 'text-table';
// @ts-ignore
import Now from '../../util';
import cmd from '../../util/output/cmd';
import Client from '../../util/client.ts';
import getScope from '../../util/get-scope.ts';
import stamp from '../../util/output/stamp.ts';
import Client from '../../util/client';
import getScope from '../../util/get-scope';
import stamp from '../../util/output/stamp';
import getCerts from '../../util/certs/get-certs';
import { CertNotFound } from '../../util/errors-ts';
import strlen from '../../util/strlen.ts';
import strlen from '../../util/strlen';
import { Output } from '../../util/output';
import { NowContext, Cert } from '../../types';
async function ls(ctx, opts, args, output) {
interface Options {
'--debug'?: boolean;
'--after'?: string;
}
async function ls(
ctx: NowContext,
opts: Options,
args: string[],
output: Output
): Promise<number> {
const { authConfig: { token }, config } = ctx;
const { currentTeam } = config;
const { apiUrl } = ctx;
@@ -32,7 +45,6 @@ async function ls(ctx, opts, args, output) {
throw err;
}
// $FlowFixMe
const now = new Now({ apiUrl, token, debug, currentTeam });
const lsStamp = stamp();
@@ -55,7 +67,6 @@ async function ls(ctx, opts, args, output) {
throw certificates;
}
const { uid: lastCert } = certificates[certificates.length - 1];
const certs = sortByCn(certificates);
output.log(
@@ -65,7 +76,8 @@ async function ls(ctx, opts, args, output) {
);
if (certs.length >= 100) {
output.note(`There may be more certificates that can be retrieved with ${cmd(`now ${process.argv.slice(2).join(' ')} --after=${lastCert}`)}.`);
const { uid: lastCert } = certificates[certificates.length - 1];
output.note(`There may be more certificates that can be retrieved with ${cmd(`now ${process.argv.slice(2).join(' ')} --after=${lastCert}`)}.\n`);
}
if (certs.length > 0) {
@@ -75,7 +87,7 @@ async function ls(ctx, opts, args, output) {
return 0;
}
function formatCertsTable(certsList) {
function formatCertsTable(certsList: Cert[]) {
return `${table(
[formatCertsTableHead(), ...formatCertsTableBody(certsList)],
{
@@ -86,7 +98,7 @@ function formatCertsTable(certsList) {
).replace(/^(.*)/gm, ' $1')}\n`;
}
function formatCertsTableHead() {
function formatCertsTableHead(): string[] {
return [
chalk.dim('id'),
chalk.dim('cns'),
@@ -96,15 +108,12 @@ function formatCertsTableHead() {
];
}
function formatCertsTableBody(certsList) {
function formatCertsTableBody(certsList: Cert[]) {
const now = new Date();
return certsList.reduce(
(result, cert) => [...result, ...formatCert(now, cert)],
[]
);
return certsList.reduce<string[][]>((result, cert) => result.concat(formatCert(now, cert)), []);
}
function formatCert(time, cert) {
function formatCert(time: Date, cert: Cert) {
return cert.cns.map(
(cn, idx) =>
idx === 0
@@ -113,26 +122,26 @@ function formatCert(time, cert) {
);
}
function formatCertNonFirstCn(cn, multiple) {
function formatCertNonFirstCn(cn: string, multiple: boolean): string[] {
return ['', formatCertCn(cn, multiple), '', '', ''];
}
function formatCertCn(cn, multiple) {
function formatCertCn(cn: string, multiple: boolean) {
return multiple ? `${chalk.gray('-')} ${chalk.bold(cn)}` : chalk.bold(cn);
}
function formatCertFirstCn(time, cert, cn, multiple) {
function formatCertFirstCn(time: Date, cert: Cert, cn: string, multiple: boolean): string[] {
return [
cert.uid,
formatCertCn(cn, multiple),
formatExpirationDate(new Date(cert.expiration)),
cert.autoRenew ? 'yes' : 'no',
chalk.gray(ms(time - new Date(cert.created)))
chalk.gray(ms(time.getTime() - new Date(cert.created).getTime()))
];
}
function formatExpirationDate(date) {
const diff = date - Date.now();
function formatExpirationDate(date: Date) {
const diff = date.getTime() - Date.now();
return diff < 0
? chalk.gray(`${ms(-diff)} ago`)
: chalk.gray(`in ${ms(diff)}`);
@@ -143,8 +152,8 @@ function formatExpirationDate(date) {
* to 'wildcard' since that will allow psl get the root domain
* properly to make the comparison.
*/
function sortByCn(certsList) {
return certsList.concat().sort((a, b) => {
function sortByCn(certsList: Cert[]) {
return certsList.concat().sort((a: Cert, b: Cert) => {
const domainA = psl.get(a.cns[0].replace('*', 'wildcard'));
const domainB = psl.get(b.cns[0].replace('*', 'wildcard'));
if (!domainA || !domainB) return 0;

View File

@@ -10,7 +10,9 @@ export const latestHelp = () => `
${chalk.dim('Basic')}
deploy [path] Performs a deployment ${chalk.bold('(default)')}
deploy [path] Performs a deployment ${chalk.bold(
'(default)'
)}
dev Start a local development server
init [example] Initialize an example project
ls | list [app] Lists deployments
@@ -18,7 +20,6 @@ export const latestHelp = () => `
login [email] Logs into your account or creates a new one
logout Logs out of your account
switch [scope] Switches between teams and your personal account
update Updates Now CLI to the latest version
help [cmd] Displays complete help for [cmd]
${chalk.dim('Advanced')}
@@ -29,7 +30,6 @@ export const latestHelp = () => `
certs [cmd] Manages your SSL certificates
secrets [name] Manages your secret environment variables
logs [url] Displays the logs for a deployment
scale [args] Scales the instance count of a deployment
teams Manages your teams
whoami Shows the username of the currently logged in user
@@ -115,7 +115,7 @@ export const latestArgs = {
'-e': '--env',
'-b': '--build-env',
'-C': '--no-clipboard',
'-m': '--meta'
'-m': '--meta',
};
export const legacyArgsMri = {
@@ -126,7 +126,7 @@ export const legacyArgsMri = {
'meta',
'session-affinity',
'regions',
'dotenv'
'dotenv',
],
boolean: [
'help',
@@ -143,11 +143,11 @@ export const legacyArgsMri = {
'public',
'no-scale',
'no-verify',
'dotenv'
'dotenv',
],
default: {
C: false,
clipboard: true
clipboard: true,
},
alias: {
env: 'e',
@@ -164,8 +164,8 @@ export const legacyArgsMri = {
'session-affinity': 'S',
name: 'n',
project: 'P',
alias: 'a'
}
alias: 'a',
},
};
// The following arg parsing is simply to make it compatible

View File

@@ -3,18 +3,14 @@ import bytes from 'bytes';
import { write as copy } from 'clipboardy';
import chalk from 'chalk';
import title from 'title';
import Progress from 'progress';
import Client from '../../util/client';
import wait from '../../util/output/wait';
import { handleError } from '../../util/error';
import getArgs from '../../util/get-args';
import toHumanPath from '../../util/humanize-path';
import Now from '../../util';
import stamp from '../../util/output/stamp.ts';
import { isReady, isDone, isFailed } from '../../util/build-state';
import createDeploy from '../../util/deploy/create-deploy';
import getDeploymentByIdOrHost from '../../util/deploy/get-deployment-by-id-or-host';
import sleep from '../../util/sleep';
import parseMeta from '../../util/parse-meta';
import code from '../../util/output/code';
import param from '../../util/output/param';
@@ -36,12 +32,15 @@ import {
AliasDomainConfigured,
MissingBuildScript,
ConflictingFilePath,
ConflictingPathSegment
ConflictingPathSegment,
BuildError,
NotDomainOwner,
} from '../../util/errors-ts';
import { SchemaValidationFailed } from '../../util/errors';
import purchaseDomainIfAvailable from '../../util/domains/purchase-domain-if-available';
import handleCertError from '../../util/certs/handle-cert-error';
import isWildcardAlias from '../../util/alias/is-wildcard-alias';
import shouldDeployDir from '../../util/deploy/should-deploy-dir';
const addProcessEnv = async (log, env) => {
let val;
@@ -72,11 +71,12 @@ const addProcessEnv = async (log, env) => {
};
const deploymentErrorMsg = `Your deployment failed. Please retry later. More: https://err.sh/now/deployment-error`;
const prepareAlias = input => isWildcardAlias(input) ? input : `https://${input}`;
const prepareAlias = input =>
isWildcardAlias(input) ? input : `https://${input}`;
const printDeploymentStatus = async (
output,
{ url, readyState, alias: aliasList, aliasError },
{ readyState, alias: aliasList, aliasError },
deployStamp,
clipboardEnabled,
localConfig,
@@ -94,10 +94,18 @@ const printDeploymentStatus = async (
const preparedAlias = prepareAlias(firstAlias);
try {
await copy(`https://${firstAlias}`);
output.ready(`Deployed to ${chalk.bold(chalk.cyan(preparedAlias))} ${chalk.gray('[in clipboard]')} ${deployStamp()}`);
output.ready(
`Deployed to ${chalk.bold(
chalk.cyan(preparedAlias)
)} ${chalk.gray('[in clipboard]')} ${deployStamp()}`
);
} catch (err) {
output.debug(`Error copying to clipboard: ${err}`);
output.ready(`Deployed to ${chalk.bold(chalk.cyan(preparedAlias))} ${deployStamp()}`);
output.ready(
`Deployed to ${chalk.bold(
chalk.cyan(preparedAlias)
)} ${deployStamp()}`
);
}
}
} else {
@@ -109,13 +117,17 @@ const printDeploymentStatus = async (
for (const alias of aliasList) {
const index = aliasList.indexOf(alias);
const isLast = index === (aliasList.length - 1);
const isLast = index === aliasList.length - 1;
const shouldCopy = matching ? alias === matching : isLast;
if (shouldCopy && clipboardEnabled) {
try {
await copy(`https://${alias}`);
output.print(`- ${chalk.bold(chalk.cyan(prepareAlias(alias)))} ${chalk.gray('[in clipboard]')}\n`);
output.print(
`- ${chalk.bold(chalk.cyan(prepareAlias(alias)))} ${chalk.gray(
'[in clipboard]'
)}\n`
);
continue;
} catch (err) {
@@ -138,20 +150,6 @@ const printDeploymentStatus = async (
return 1;
}
const failedBuilds = builds.filter(isFailed);
const amount = failedBuilds.length;
if (amount > 0) {
output.error('Build failed');
output.error(
`Check your logs at https://${url}/_logs or run ${code(
`now logs ${url}`
)}`
);
return 1;
}
output.error(deploymentErrorMsg);
return 1;
};
@@ -206,7 +204,15 @@ export default async function main(
return 1;
}
const { apiUrl, authConfig: { token }, config: { currentTeam } } = ctx;
if (!(await shouldDeployDir(argv._[0], output))) {
return 0;
}
const {
apiUrl,
authConfig: { token },
config: { currentTeam },
} = ctx;
const { log, debug, error, warn } = output;
const paths = Object.keys(stats);
const debugEnabled = argv['--debug'];
@@ -236,7 +242,6 @@ export default async function main(
parseMeta(argv['--meta'])
);
let syncCount;
let deployStamp = stamp();
let deployment = null;
@@ -289,11 +294,15 @@ export default async function main(
parseEnv(argv['--env'])
);
// Enable debug mode for builders
const buildDebugEnv = debugEnabled ? { NOW_BUILDER_DEBUG: '1' } : {};
// Merge build env out of `build.env` from now.json, and `--build-env` args
const deploymentBuildEnv = Object.assign(
{},
parseEnv(localConfig.build && localConfig.build.env),
parseEnv(argv['--build-env'])
parseEnv(argv['--build-env']),
buildDebugEnv
);
// If there's any undefined values, then inherit them from this process
@@ -313,33 +322,45 @@ export default async function main(
try {
// $FlowFixMe
const project = getProjectName({argv, nowConfig: localConfig, isFile, paths});
const project = getProjectName({
argv,
nowConfig: localConfig,
isFile,
paths,
});
log(`Using project ${chalk.bold(project)}`);
const createArgs = {
name: project,
env: deploymentEnv,
build: { env: deploymentBuildEnv },
forceNew: argv['--force'],
quiet,
wantsPublic: argv['--public'] || localConfig.public,
isFile,
type: null,
nowConfig: localConfig,
regions,
meta
name: project,
env: deploymentEnv,
build: { env: deploymentBuildEnv },
forceNew: argv['--force'],
quiet,
wantsPublic: argv['--public'] || localConfig.public,
isFile,
type: null,
nowConfig: localConfig,
regions,
meta,
deployStamp,
};
if (argv['--target']) {
const deprecatedTarget = argv['--target'];
if (!['staging', 'production'].includes(deprecatedTarget)) {
error(`The specified ${param('--target')} ${code(deprecatedTarget)} is not valid`);
error(
`The specified ${param('--target')} ${code(
deprecatedTarget
)} is not valid`
);
return 1;
}
if (deprecatedTarget === 'production') {
warn('We recommend using the much shorter `--prod` option instead of `--target production` (deprecated)');
warn(
'We recommend using the much shorter `--prod` option instead of `--target production` (deprecated)'
);
}
output.debug(`Setting target to ${deprecatedTarget}`);
@@ -351,7 +372,7 @@ export default async function main(
deployStamp = stamp();
const firstDeployCall = await createDeploy(
deployment = await createDeploy(
output,
now,
contextName,
@@ -360,13 +381,49 @@ export default async function main(
ctx
);
if (deployment instanceof NotDomainOwner) {
output.error(deployment);
return 1;
}
const deploymentResponse = handleCertError(
output,
await getDeploymentByIdOrHost(now, contextName, deployment.id, 'v9')
);
if (deploymentResponse === 1) {
return deploymentResponse;
}
if (
firstDeployCall instanceof DomainNotFound &&
firstDeployCall.meta && firstDeployCall.meta.domain
deploymentResponse instanceof DeploymentNotFound ||
deploymentResponse instanceof DeploymentPermissionDenied ||
deploymentResponse instanceof InvalidDeploymentId
) {
output.debug(`The domain ${
firstDeployCall.meta.domain
} was not found, trying to purchase it`);
output.error(deploymentResponse.message);
return 1;
}
if (handleCertError(output, deployment) === 1) {
return 1;
}
if (deployment === null) {
error('Uploading failed. Please try again.');
return 1;
}
} catch (err) {
debug(`Error: ${err}\n${err.stack}`);
if (err instanceof NotDomainOwner) {
output.error(err.message);
return 1;
}
if (err instanceof DomainNotFound && err.meta && err.meta.domain) {
output.debug(
`The domain ${err.meta.domain} was not found, trying to purchase it`
);
const purchase = await purchaseDomainIfAvailable(
output,
@@ -374,16 +431,14 @@ export default async function main(
apiUrl: ctx.apiUrl,
token: ctx.authConfig.token,
currentTeam: ctx.config.currentTeam,
debug: debugEnabled
debug: debugEnabled,
}),
firstDeployCall.meta.domain,
err.meta.domain,
contextName
);
if (purchase === true) {
output.success(`Successfully purchased the domain ${
firstDeployCall.meta.domain
}!`);
output.success(`Successfully purchased the domain ${err.meta.domain}!`);
// We exit if the purchase is completed since
// the domain verification can take some time
@@ -391,7 +446,7 @@ export default async function main(
}
if (purchase === false || purchase instanceof UserAborted) {
handleCreateDeployError(output, firstDeployCall);
handleCreateDeployError(output, deployment);
return 1;
}
@@ -399,120 +454,36 @@ export default async function main(
return 1;
}
if (handleCertError(output, firstDeployCall) === 1) {
return 1;
}
if (
firstDeployCall instanceof DomainNotFound ||
firstDeployCall instanceof DomainNotVerified ||
firstDeployCall instanceof DomainPermissionDenied ||
firstDeployCall instanceof DomainVerificationFailed ||
firstDeployCall instanceof SchemaValidationFailed ||
firstDeployCall instanceof InvalidDomain ||
firstDeployCall instanceof DeploymentNotFound ||
firstDeployCall instanceof BuildsRateLimited ||
firstDeployCall instanceof DeploymentsRateLimited ||
firstDeployCall instanceof AliasDomainConfigured ||
firstDeployCall instanceof MissingBuildScript ||
firstDeployCall instanceof ConflictingFilePath ||
firstDeployCall instanceof ConflictingPathSegment
err instanceof DomainNotFound ||
err instanceof DomainNotVerified ||
err instanceof NotDomainOwner ||
err instanceof DomainPermissionDenied ||
err instanceof DomainVerificationFailed ||
err instanceof SchemaValidationFailed ||
err instanceof InvalidDomain ||
err instanceof DeploymentNotFound ||
err instanceof BuildsRateLimited ||
err instanceof DeploymentsRateLimited ||
err instanceof AliasDomainConfigured ||
err instanceof MissingBuildScript ||
err instanceof ConflictingFilePath ||
err instanceof ConflictingPathSegment
) {
handleCreateDeployError(output, firstDeployCall);
handleCreateDeployError(output, err);
return 1;
}
deployment = firstDeployCall;
if (err instanceof BuildError) {
output.error('Build failed');
output.error(
`Check your logs at ${now.url}/_logs or run ${code(
`now logs ${now.url}`
)}`
);
if (now.syncFileCount > 0) {
const uploadStamp = stamp();
await new Promise((resolve, reject) => {
if (now.syncFileCount !== now.fileCount) {
debug(`Total files ${now.fileCount}, ${now.syncFileCount} changed`);
}
const size = bytes(now.syncAmount);
syncCount = `${now.syncFileCount} file${now.syncFileCount > 1
? 's'
: ''}`;
const bar = new Progress(
`${chalk.gray(
'>'
)} Upload [:bar] :percent :etas (${size}) [${syncCount}]`,
{
width: 20,
complete: '=',
incomplete: '',
total: now.syncAmount,
clear: true
}
);
now.upload({ scale: {} });
now.on('upload', ({ names, data }) => {
debug(`Uploaded: ${names.join(' ')} (${bytes(data.length)})`);
});
now.on('uploadProgress', progress => {
bar.tick(progress);
});
now.on('complete', resolve);
now.on('error', err => {
error('Upload failed');
reject(err);
});
});
if (!quiet && syncCount) {
log(`Synced ${syncCount} (${bytes(now.syncAmount)}) ${uploadStamp()}`);
}
for (let i = 0; i < 4; i += 1) {
deployStamp = stamp();
const secondDeployCall = await createDeploy(
output,
now,
contextName,
paths,
createArgs
);
if (handleCertError(output, secondDeployCall) === 1) {
return 1;
}
if (
secondDeployCall instanceof DomainPermissionDenied ||
secondDeployCall instanceof DomainVerificationFailed ||
secondDeployCall instanceof SchemaValidationFailed ||
secondDeployCall instanceof DeploymentNotFound ||
secondDeployCall instanceof DeploymentsRateLimited ||
secondDeployCall instanceof AliasDomainConfigured ||
secondDeployCall instanceof MissingBuildScript ||
secondDeployCall instanceof ConflictingFilePath ||
secondDeployCall instanceof ConflictingPathSegment
) {
handleCreateDeployError(output, secondDeployCall);
return 1;
}
if (now.syncFileCount === 0) {
deployment = secondDeployCall;
break;
}
}
if (deployment === null) {
error('Uploading failed. Please try again.');
return 1;
}
return 1;
}
} catch (err) {
debug(`Error: ${err}\n${err.stack}`);
if (err.keyword === 'additionalProperties' && err.dataPath === '.scale') {
const { additionalProperty = '' } = err.params || {};
@@ -531,114 +502,14 @@ export default async function main(
return 1;
}
const { url } = now;
if (isTTY) {
log(`${url} ${chalk.gray(`[v2]`)} ${deployStamp()}`);
} else {
process.stdout.write(url);
}
// If an error occurred, we want to let it fall down to rendering
// builds so the user can see in which build the error occurred.
if (isReady(deployment)) {
return printDeploymentStatus(output, deployment, deployStamp, !argv['--no-clipboard'], localConfig);
}
const sleepingTime = ms('1.5s');
const allBuildsTime = stamp();
const times = {};
const buildsUrl = `/v1/now/deployments/${deployment.id}/builds`;
let builds = [];
let buildsCompleted = false;
let buildSpinner = null;
let deploymentSpinner = null;
// eslint-disable-next-line no-constant-condition
while (true) {
if (!buildsCompleted) {
const { builds: freshBuilds } = await now.fetch(buildsUrl);
// If there are no builds, we need to exit.
if (freshBuilds.length === 0 || freshBuilds.every(isDone)) {
builds = freshBuilds;
buildsCompleted = true;
} else {
for (const build of freshBuilds) {
const id = build.id;
const done = isDone(build);
if (times[id]) {
if (done && typeof times[id] === 'function') {
times[id] = times[id]();
}
} else {
times[id] = done ? allBuildsTime() : stamp();
}
}
if (JSON.stringify(builds) !== JSON.stringify(freshBuilds)) {
builds = freshBuilds;
if (buildSpinner === null) {
buildSpinner = wait('Building...');
}
buildsCompleted = builds.every(isDone);
if (builds.some(isFailed)) {
break;
}
}
}
} else {
const deploymentResponse = handleCertError(
output,
await getDeploymentByIdOrHost(now, contextName, deployment.id, 'v9')
)
if (deploymentResponse === 1) {
return deploymentResponse;
}
if (
deploymentResponse instanceof DeploymentNotFound ||
deploymentResponse instanceof DeploymentPermissionDenied ||
deploymentResponse instanceof InvalidDeploymentId
) {
output.error(deploymentResponse.message);
return 1;
}
if (isReady(deploymentResponse) || isFailed(deploymentResponse)) {
deployment = deploymentResponse;
if (typeof deploymentSpinner === 'function') {
// This stops it
deploymentSpinner();
}
break;
} else if (!deploymentSpinner) {
if (typeof buildSpinner === 'function') {
buildSpinner();
}
deploymentSpinner = wait('Finalizing...');
}
}
await sleep(sleepingTime);
}
if (typeof buildSpinner === 'function') {
buildSpinner();
}
return printDeploymentStatus(output, deployment, deployStamp, !argv['--no-clipboard'], localConfig, builds);
};
return printDeploymentStatus(
output,
deployment,
deployStamp,
!argv['--no-clipboard'],
localConfig
);
}
function handleCreateDeployError(output, error) {
if (error instanceof InvalidDomain) {
@@ -708,18 +579,20 @@ function handleCreateDeployError(output, error) {
}
if (error instanceof TooManyRequests) {
output.error(
`Too many requests detected for ${error.meta
.api} API. Try again in ${ms(error.meta.retryAfter * 1000, {
long: true
})}.`
`Too many requests detected for ${error.meta.api} API. Try again in ${ms(
error.meta.retryAfter * 1000,
{
long: true,
}
)}.`
);
return 1;
}
if (error instanceof DomainNotVerified) {
output.error(
`The domain used as an alias ${
chalk.underline(error.meta.domain)
} is not verified yet. Please verify it.`
`The domain used as an alias ${chalk.underline(
error.meta.domain
)} is not verified yet. Please verify it.`
);
return 1;
}
@@ -730,6 +603,7 @@ function handleCreateDeployError(output, error) {
}
if (
error instanceof DeploymentNotFound ||
error instanceof NotDomainOwner ||
error instanceof DeploymentsRateLimited ||
error instanceof AliasDomainConfigured ||
error instanceof MissingBuildScript ||

View File

@@ -2,7 +2,6 @@ import { resolve, basename, join } from 'path';
import { eraseLines } from 'ansi-escapes';
// @ts-ignore
import { write as copy } from 'clipboardy';
import bytes from 'bytes';
import chalk from 'chalk';
import dotenv from 'dotenv';
import fs from 'fs-extra';
@@ -13,7 +12,6 @@ import ms from 'ms';
// @ts-ignore
import title from 'title';
import plural from 'pluralize';
import Progress from 'progress';
// @ts-ignore
import { handleError } from '../../util/error';
import chars from '../../util/output/chars';
@@ -34,19 +32,16 @@ import promptOptions from '../../util/prompt-options';
// @ts-ignore
import readMetaData from '../../util/read-metadata';
import toHumanPath from '../../util/humanize-path';
import combineAsyncGenerators from '../../util/combine-async-generators';
// @ts-ignore
import createDeploy from '../../util/deploy/create-deploy';
import eventListenerToGenerator from '../../util/event-listener-to-generator';
// @ts-ignore
import formatLogCmd from '../../util/output/format-log-cmd';
// @ts-ignore
import formatLogOutput from '../../util/output/format-log-output';
// @ts-ignore
import getEventsStream from '../../util/deploy/get-events-stream';
import shouldDeployDir from '../../util/deploy/should-deploy-dir';
// @ts-ignore
import getInstanceIndex from '../../util/deploy/get-instance-index';
import getStateChangeFromPolling from '../../util/deploy/get-state-change-from-polling';
import joinWords from '../../util/output/join-words';
// @ts-ignore
import normalizeRegionsList from '../../util/scale/normalize-regions-list';
@@ -67,11 +62,12 @@ import {
DomainVerificationFailed,
TooManyRequests,
VerifyScaleTimeout,
DeploymentsRateLimited
DeploymentsRateLimited,
NotDomainOwner,
} from '../../util/errors-ts';
import {
InvalidAllForScale,
InvalidRegionOrDCForScale
InvalidRegionOrDCForScale,
} from '../../util/errors';
import { SchemaValidationFailed } from '../../util/errors';
import handleCertError from '../../util/certs/handle-cert-error';
@@ -198,7 +194,7 @@ const promptForEnvFields = async (list: string[]) => {
for (const field of list) {
questions.push({
name: field,
message: field
message: field,
});
}
@@ -220,7 +216,7 @@ const promptForEnvFields = async (list: string[]) => {
async function canUseZeroConfig(cwd: string): Promise<boolean> {
try {
const pkg = (await readPackage(join(cwd, 'package.json')));
const pkg = await readPackage(join(cwd, 'package.json'));
if (!pkg || pkg instanceof Error) {
return false;
@@ -250,7 +246,7 @@ async function canUseZeroConfig(cwd: string): Promise<boolean> {
) {
return true;
}
} catch(_) {}
} catch (_) {}
return false;
}
@@ -275,6 +271,10 @@ export default async function main(
paths = [process.cwd()];
}
if (!(await shouldDeployDir(argv._[0], output))) {
return 0;
}
// Options
forceNew = argv.force;
deploymentName = argv.name;
@@ -296,15 +296,17 @@ export default async function main(
quiet = !isTTY;
({ log, error, note, debug, warn } = output);
const infoUrl = await canUseZeroConfig(paths[0])
const infoUrl = (await canUseZeroConfig(paths[0]))
? 'https://zeit.co/guides/migrate-to-zeit-now'
: 'https://zeit.co/docs/v2/advanced/platform/changes-in-now-2-0'
: 'https://zeit.co/docs/v2/advanced/platform/changes-in-now-2-0';
warn(`You are using an old version of the Now Platform. More: ${link(infoUrl)}`);
warn(
`You are using an old version of the Now Platform. More: ${link(infoUrl)}`
);
const {
authConfig: { token },
config
config,
} = ctx;
try {
@@ -314,7 +316,7 @@ export default async function main(
token,
config,
firstRun: true,
deploymentType: undefined
deploymentType: undefined,
});
} catch (err) {
await stopDeployment(err);
@@ -327,7 +329,7 @@ async function sync({
token,
config: { currentTeam },
firstRun,
deploymentType
deploymentType,
}: SyncOptions): Promise<void> {
return new Promise(async (_resolve, reject) => {
let deployStamp = stamp();
@@ -476,7 +478,7 @@ async function sync({
// XXX: legacy
deploymentType,
sessionAffinity
sessionAffinity,
};
}
@@ -486,7 +488,7 @@ async function sync({
meta,
deploymentName,
deploymentType,
sessionAffinity
sessionAffinity,
} = await readMeta(
paths[0],
deploymentName,
@@ -499,7 +501,7 @@ async function sync({
'dockerfile_missing',
'no_dockerfile_commands',
'unsupported_deployment_type',
'multiple_manifests'
'multiple_manifests',
];
if (
@@ -537,7 +539,7 @@ async function sync({
// Read scale and fail if we have both regions and scale
if (regions.length > 0 && Object.keys(scaleFromConfig).length > 0) {
error(
'Can\'t set both `regions` and `scale` options simultaneously',
"Can't set both `regions` and `scale` options simultaneously",
'regions-and-scale-at-once'
);
await exit(1);
@@ -548,9 +550,7 @@ async function sync({
dcIds = normalizeRegionsList(regions);
if (dcIds instanceof InvalidRegionOrDCForScale) {
error(
`The value "${
dcIds.meta.regionOrDC
}" is not a valid region or DC identifier`
`The value "${dcIds.meta.regionOrDC}" is not a valid region or DC identifier`
);
await exit(1);
return 1;
@@ -565,7 +565,7 @@ async function sync({
scale = dcIds.reduce(
(result: DcScale, dcId: string) => ({
...result,
[dcId]: { min: 0, max: 1 }
[dcId]: { min: 0, max: 1 },
}),
{}
);
@@ -661,8 +661,9 @@ async function sync({
}
const hasSecrets = Object.keys(deploymentEnv).some(key =>
deploymentEnv[key].startsWith('@')
(deploymentEnv[key] || '').startsWith('@')
);
const secretsPromise = hasSecrets ? now.listSecrets() : null;
const findSecret = async (uidOrName: string) => {
@@ -754,15 +755,13 @@ async function sync({
parseMeta(argv.meta)
);
let syncCount;
try {
meta.name = getProjectName({
argv,
nowConfig,
isFile,
paths,
pre: meta.name
pre: meta.name,
});
log(`Using project ${chalk.bold(meta.name)}`);
const createArgs = Object.assign(
@@ -776,13 +775,15 @@ async function sync({
scale,
wantsPublic,
sessionAffinity,
isFile
isFile,
nowConfig,
deployStamp,
},
meta
);
deployStamp = stamp();
const firstDeployCall = await createDeploy(
deployment = await createDeploy(
output,
now,
contextName,
@@ -790,118 +791,24 @@ async function sync({
createArgs
);
const handledResult = handleCertError(output, firstDeployCall);
const handledResult = handleCertError(output, deployment);
if (handledResult === 1) {
return handledResult;
}
if (
firstDeployCall instanceof DomainNotFound ||
firstDeployCall instanceof DomainPermissionDenied ||
firstDeployCall instanceof DomainVerificationFailed ||
firstDeployCall instanceof SchemaValidationFailed ||
firstDeployCall instanceof DeploymentNotFound ||
firstDeployCall instanceof DeploymentsRateLimited
deployment instanceof DomainNotFound ||
deployment instanceof NotDomainOwner ||
deployment instanceof DomainPermissionDenied ||
deployment instanceof DomainVerificationFailed ||
deployment instanceof SchemaValidationFailed ||
deployment instanceof DeploymentNotFound ||
deployment instanceof DeploymentsRateLimited
) {
handleCreateDeployError(output, firstDeployCall);
handleCreateDeployError(output, deployment);
await exit(1);
return;
}
deployment = firstDeployCall;
if (now.syncFileCount > 0) {
const uploadStamp = stamp();
await new Promise(resolve => {
if (now.syncFileCount !== now.fileCount) {
debug(`Total files ${now.fileCount}, ${now.syncFileCount} changed`);
}
const size = bytes(now.syncAmount);
syncCount = `${now.syncFileCount} file${
now.syncFileCount > 1 ? 's' : ''
}`;
const bar = new Progress(
`${chalk.gray(
'>'
)} Upload [:bar] :percent :etas (${size}) [${syncCount}]`,
{
width: 20,
complete: '=',
incomplete: '',
total: now.syncAmount,
clear: true
}
);
now.upload({ scale });
now.on(
'upload',
({ names, data }: { names: string[]; data: Buffer }) => {
debug(`Uploaded: ${names.join(' ')} (${bytes(data.length)})`);
}
);
now.on('uploadProgress', (progress: number) => {
bar.tick(progress);
});
now.on('complete', resolve);
now.on('error', (err: Error) => {
error('Upload failed');
reject(err);
});
});
if (!quiet && syncCount) {
log(
`Synced ${syncCount} (${bytes(now.syncAmount)}) ${uploadStamp()}`
);
}
for (let i = 0; i < 4; i += 1) {
deployStamp = stamp();
const secondDeployCall = await createDeploy(
output,
now,
contextName,
paths,
createArgs
);
const handledResult = handleCertError(output, secondDeployCall);
if (handledResult === 1) {
return handledResult;
}
if (
secondDeployCall instanceof DomainNotFound ||
secondDeployCall instanceof DomainPermissionDenied ||
secondDeployCall instanceof DomainVerificationFailed ||
secondDeployCall instanceof SchemaValidationFailed ||
secondDeployCall instanceof TooManyRequests ||
secondDeployCall instanceof DeploymentNotFound ||
secondDeployCall instanceof DeploymentsRateLimited
) {
handleCreateDeployError(output, secondDeployCall);
await exit(1);
return;
}
if (now.syncFileCount === 0) {
deployment = secondDeployCall;
break;
}
}
if (deployment === null) {
error('Uploading failed. Please try again.');
await exit(1);
return;
}
}
} catch (err) {
if (err.code === 'plan_requires_public') {
if (!wantsPublic) {
@@ -914,7 +821,7 @@ async function sync({
if (isTTY) {
proceed = await promptBool('Are you sure you want to proceed?', {
trailing: eraseLines(1)
trailing: eraseLines(1),
});
}
@@ -954,10 +861,10 @@ async function sync({
output,
token,
config: {
currentTeam
currentTeam,
},
firstRun: false,
deploymentType
deploymentType,
});
}
@@ -1002,8 +909,6 @@ async function sync({
} else {
log(`${chalk.bold(chalk.cyan(url))}${dcs} ${deployStamp()}`);
}
} else {
process.stdout.write(url);
}
if (deploymentType === 'static') {
@@ -1022,96 +927,52 @@ async function sync({
// Show build logs
// (We have to add this check for flow but it will never happen)
if (deployment !== null) {
// If the created deployment is ready it was a deduping and we should exit
if (deployment.readyState !== 'READY') {
require('assert')(deployment); // mute linter
const instanceIndex = getInstanceIndex();
const eventsStream = await maybeGetEventsStream(now, deployment);
const eventsGenerator = getEventsGenerator(
const instanceIndex = getInstanceIndex();
const eventsStream = await maybeGetEventsStream(now, deployment);
if (!noVerify) {
output.log(
`Verifying instantiation in ${joinWords(
Object.keys(deployment.scale).map(dc => chalk.bold(dc))
)}`
);
const verifyStamp = stamp();
const verifyDCsGenerator = getVerifyDCsGenerator(
output,
now,
contextName,
deployment,
eventsStream
);
for await (const _event of eventsGenerator) {
const event = _event as any;
// Stop when the deployment is ready
if (
event.type === 'state-change' &&
event.payload.value === 'READY'
) {
output.log(`Build completed`);
break;
}
// Stop then there is an error state
if (
event.type === 'state-change' &&
event.payload.value === 'ERROR'
) {
output.error(`Build failed`);
await exit(1);
}
// For any relevant event we receive, print the result
if (event.type === 'build-start') {
output.log('Building…');
} else if (event.type === 'command') {
output.log(formatLogCmd(event.payload.text));
} else if (event.type === 'stdout' || event.type === 'stderr') {
formatLogOutput(event.payload.text).forEach((msg: string) =>
output.log(msg)
for await (const _dcOrEvent of verifyDCsGenerator) {
const dcOrEvent = _dcOrEvent as any;
if (dcOrEvent instanceof VerifyScaleTimeout) {
output.error(
`Instance verification timed out (${ms(dcOrEvent.meta.timeout)})`
);
output.log(
'Read more: https://err.sh/now-cli/verification-timeout'
);
await exit(1);
} else if (Array.isArray(dcOrEvent)) {
const [dc, instances] = dcOrEvent;
output.log(
`${chalk.cyan(chars.tick)} Scaled ${plural(
'instance',
instances,
true
)} in ${chalk.bold(dc)} ${verifyStamp()}`
);
} else if (
dcOrEvent &&
(dcOrEvent.type === 'stdout' || dcOrEvent.type === 'stderr')
) {
const prefix = chalk.gray(
`[${instanceIndex(dcOrEvent.payload.instanceId)}] `
);
formatLogOutput(dcOrEvent.payload.text, prefix).forEach(
(msg: string) => output.log(msg)
);
}
}
if (!noVerify) {
output.log(
`Verifying instantiation in ${joinWords(
Object.keys(deployment.scale).map(dc => chalk.bold(dc))
)}`
);
const verifyStamp = stamp();
const verifyDCsGenerator = getVerifyDCsGenerator(
output,
now,
deployment,
eventsStream
);
for await (const _dcOrEvent of verifyDCsGenerator) {
const dcOrEvent = _dcOrEvent as any;
if (dcOrEvent instanceof VerifyScaleTimeout) {
output.error(
`Instance verification timed out (${ms(
dcOrEvent.meta.timeout
)})`
);
output.log(
'Read more: https://err.sh/now/verification-timeout'
);
await exit(1);
} else if (Array.isArray(dcOrEvent)) {
const [dc, instances] = dcOrEvent;
output.log(
`${chalk.cyan(chars.tick)} Scaled ${plural(
'instance',
instances,
true
)} in ${chalk.bold(dc)} ${verifyStamp()}`
);
} else if (
dcOrEvent &&
(dcOrEvent.type === 'stdout' || dcOrEvent.type === 'stderr')
) {
const prefix = chalk.gray(
`[${instanceIndex(dcOrEvent.payload.instanceId)}] `
);
formatLogOutput(dcOrEvent.payload.text, prefix).forEach(
(msg: string) => output.log(msg)
);
}
}
}
}
@@ -1133,7 +994,7 @@ async function readMeta(
deploymentType,
deploymentName: _deploymentName,
quiet: true,
sessionAffinity: _sessionAffinity
sessionAffinity: _sessionAffinity,
});
if (!deploymentType) {
@@ -1150,7 +1011,7 @@ async function readMeta(
meta,
deploymentName: _deploymentName,
deploymentType,
sessionAffinity: _sessionAffinity
sessionAffinity: _sessionAffinity,
};
} catch (err) {
if (isTTY && err.code === 'multiple_manifests') {
@@ -1164,7 +1025,7 @@ async function readMeta(
try {
deploymentType = await promptOptions([
['npm', `${chalk.bold('package.json')}\t${chalk.gray(' --npm')} `],
['docker', `${chalk.bold('Dockerfile')}\t${chalk.gray('--docker')} `]
['docker', `${chalk.bold('Dockerfile')}\t${chalk.gray('--docker')} `],
]);
} catch (_) {
throw err;
@@ -1190,35 +1051,13 @@ async function maybeGetEventsStream(now: Now, deployment: any) {
try {
return await getEventsStream(now, deployment.deploymentId, {
direction: 'forward',
follow: true
follow: true,
});
} catch (error) {
return null;
}
}
function getEventsGenerator(
now: Now,
contextName: string,
deployment: any,
eventsStream: any
) {
const stateChangeFromPollingGenerator = getStateChangeFromPolling(
now,
contextName,
deployment.deploymentId,
deployment.readyState
);
if (eventsStream !== null) {
return combineAsyncGenerators(
eventListenerToGenerator('data', eventsStream),
stateChangeFromPollingGenerator
);
}
return stateChangeFromPollingGenerator;
}
function getVerifyDCsGenerator(
output: Output,
now: Now,
@@ -1228,7 +1067,7 @@ function getVerifyDCsGenerator(
const verifyDeployment = verifyDeploymentScale(
output,
now,
deployment.deploymentId,
deployment.deploymentId || deployment.uid,
deployment.scale
);
@@ -1295,9 +1134,9 @@ function handleCreateDeployError(output: Output, error: Error) {
output.error(
`Failed to validate ${highlight(
'now.json'
)}: ${message}\nDocumentation: ${
link('https://zeit.co/docs/v2/advanced/configuration')
}`
)}: ${message}\nDocumentation: ${link(
'https://zeit.co/docs/v2/advanced/configuration'
)}`
);
return 1;
@@ -1307,7 +1146,7 @@ function handleCreateDeployError(output: Output, error: Error) {
`Too many requests detected for ${error.meta.api} API. Try again in ${ms(
error.meta.retryAfter * 1000,
{
long: true
long: true,
}
)}.`
);

View File

@@ -1,5 +1,6 @@
import path from 'path';
import chalk from 'chalk';
import { PackageJson } from '@now/build-utils';
import getArgs from '../../util/get-args';
import getSubcommand from '../../util/get-subcommand';
@@ -11,11 +12,10 @@ import logo from '../../util/output/logo';
import cmd from '../../util/output/cmd';
import dev from './dev';
import readPackage from '../../util/read-package';
import { Package } from '../../util/dev/types';
import readConfig from '../../util/config/read-config';
const COMMAND_CONFIG = {
dev: ['dev']
dev: ['dev'],
};
const help = () => {
@@ -54,7 +54,7 @@ export default async function main(ctx: NowContext) {
// Deprecated
'--port': Number,
'-p': '--port'
'-p': '--port',
});
const debug = argv['--debug'];
args = getSubcommand(argv._.slice(1), COMMAND_CONFIG).args;
@@ -90,7 +90,7 @@ export default async function main(ctx: NowContext) {
const pkg = await readPackage(path.join(dir, 'package.json'));
if (pkg) {
const { scripts } = pkg as Package;
const { scripts } = pkg as PackageJson;
if (scripts && scripts.dev && /\bnow\b\W+\bdev\b/.test(scripts.dev)) {
output.error(
@@ -98,9 +98,7 @@ export default async function main(ctx: NowContext) {
'package.json'
)} must not contain ${cmd('now dev')}`
);
output.error(
`More details: http://err.sh/now/now-dev-as-dev-script`
);
output.error(`More details: http://err.sh/now/now-dev-as-dev-script`);
return 1;
}
}

View File

@@ -23,7 +23,7 @@ export default async function verify(
) {
const {
authConfig: { token },
config
config,
} = ctx;
const { currentTeam } = config;
const { apiUrl } = ctx;
@@ -122,16 +122,11 @@ export default async function verify(
return 1;
}
if (result.txtVerifiedAt) {
if (result.nsVerifiedAt) {
console.log(
`${chalk.cyan('> Success!')} Domain ${chalk.bold(
domain.name
)} was verified using DNS TXT record. ${verifyStamp()}`
);
output.print(
` You can verify with nameservers too. Run ${cmd(
`now domains inspect ${domain.name}`
)} to find out the intended set.\n`
)} was verified using nameservers. ${verifyStamp()}`
);
return 0;
}
@@ -139,7 +134,12 @@ export default async function verify(
console.log(
`${chalk.cyan('> Success!')} Domain ${chalk.bold(
domain.name
)} was verified using nameservers. ${verifyStamp()}`
)} was verified using DNS TXT record. ${verifyStamp()}`
);
output.print(
` You can verify with nameservers too. Run ${cmd(
`now domains inspect ${domain.name}`
)} to find out the intended set.\n`
);
return 0;
}

View File

@@ -74,7 +74,7 @@ export default async function main(ctx) {
'--all': Boolean,
'--meta': [String],
'-a': '--all',
'-m': '--meta'
'-m': '--meta',
});
} catch (err) {
handleError(err);
@@ -84,7 +84,7 @@ export default async function main(ctx) {
const debugEnabled = argv['--debug'];
const { print, log, error, note, debug } = createOutput({
debug: debugEnabled
debug: debugEnabled,
});
if (argv._.length > 2) {
@@ -103,13 +103,16 @@ export default async function main(ctx) {
}
const meta = parseMeta(argv['--meta']);
const { authConfig: { token }, config } = ctx;
const {
authConfig: { token },
config,
} = ctx;
const { currentTeam, includeScheme } = config;
const client = new Client({
apiUrl,
token,
currentTeam,
debug: debugEnabled
debug: debugEnabled,
});
let contextName = null;
@@ -202,7 +205,16 @@ export default async function main(ctx) {
const item = aliases.find(e => e.uid === app || e.alias === app);
if (item) {
debug('Found alias that matches app name');
debug(`Found alias that matches app name: ${item.alias}`);
if (Array.isArray(item.rules)) {
now.close();
stopSpinner();
log(`Found matching path alias: ${chalk.cyan(item.alias)}`);
log(`Please run ${cmd(`now alias ls ${item.alias}`)} instead`);
return 0;
}
const match = await now.findDeployment(item.deploymentId);
const instances = await getDeploymentInstances(
now,
@@ -250,7 +262,9 @@ export default async function main(ctx) {
// information to help the user find other deployments or instances
if (app == null) {
log(`To list more deployments for a project run ${cmd('now ls [project]')}`);
log(
`To list more deployments for a project run ${cmd('now ls [project]')}`
);
} else if (!argv['--all']) {
log(`To list deployment instances run ${cmd('now ls --all [project]')}`);
}
@@ -260,7 +274,9 @@ export default async function main(ctx) {
console.log(
`${table(
[
['project', 'latest deployment', 'inst #', 'type', 'state', 'age'].map(s => chalk.dim(s)),
['project', 'latest deployment', 'inst #', 'type', 'state', 'age'].map(
s => chalk.dim(s)
),
...deployments
.sort(sortRecent())
.map(dep => [
@@ -272,7 +288,7 @@ export default async function main(ctx) {
: dep.instanceCount,
dep.type === 'LAMBDAS' ? chalk.gray('-') : dep.type,
stateString(dep.state),
chalk.gray(ms(Date.now() - new Date(dep.created)))
chalk.gray(ms(Date.now() - new Date(dep.created))),
],
...(argv['--all']
? dep.instances.map(i => [
@@ -280,9 +296,9 @@ export default async function main(ctx) {
` ${chalk.gray('-')} ${i.url} `,
'',
'',
''
'',
])
: [])
: []),
])
// flatten since the previous step returns a nested
// array of the deployment and (optionally) its instances
@@ -293,12 +309,12 @@ export default async function main(ctx) {
// we only want to render one deployment per app
filterUniqueApps()
: () => true
)
),
],
{
align: ['l', 'l', 'r', 'l', 'b'],
hsep: ' '.repeat(4),
stringLength: strlen
stringLength: strlen,
}
).replace(/^/gm, ' ')}\n\n`
);
@@ -310,7 +326,7 @@ function getProjectName(d) {
return 'files';
}
return d.name
return d.name;
}
// renders the state string

View File

@@ -84,8 +84,8 @@ export default async function main(ctx) {
debug: 'd',
query: 'q',
follow: 'f',
output: 'o'
}
output: 'o',
},
});
argv._ = argv._.slice(1);
@@ -136,14 +136,17 @@ export default async function main(ctx) {
types = argv.all ? [] : ['command', 'stdout', 'stderr', 'exit'];
outputMode = argv.output in logPrinters ? argv.output : 'short';
const { authConfig: { token }, config } = ctx;
const {
authConfig: { token },
config,
} = ctx;
const { currentTeam } = config;
const now = new Now({ apiUrl, token, debug, currentTeam });
const client = new Client({
apiUrl,
token,
currentTeam,
debug: debugEnabled
debug: debugEnabled,
});
let contextName = null;
@@ -206,7 +209,7 @@ export default async function main(ctx) {
types,
instanceId,
since,
until
until,
}; // no follow
const storage = [];
const storeEvent = event => storage.push(event);
@@ -216,7 +219,7 @@ export default async function main(ctx) {
onEvent: storeEvent,
quiet: false,
debug,
findOpts: findOpts1
findOpts: findOpts1,
});
const printedEventIds = new Set();
@@ -238,14 +241,14 @@ export default async function main(ctx) {
types,
instanceId,
since: since2,
follow: true
follow: true,
};
await printEvents(now, deployment.uid || deployment.id, currentTeam, {
mode: 'logs',
onEvent: printEvent,
quiet: false,
debug,
findOpts: findOpts2
findOpts: findOpts2,
});
}
@@ -280,25 +283,53 @@ function printLogShort(log) {
` ${obj.status} ${obj.bodyBytesSent}`;
} else if (log.type === 'event') {
data = `EVENT ${log.event} ${JSON.stringify(log.payload)}`;
} else if (obj) {
data = JSON.stringify(obj, null, 2);
} else {
data = obj
? JSON.stringify(obj, null, 2)
: (log.text || '')
data = (log.text || '')
.replace(/\n$/, '')
.replace(/^\n/, '')
// eslint-disable-next-line no-control-regex
.replace(/\x1b\[1000D/g, '')
.replace(/\x1b\[0K/g, '')
.replace(/\x1b\[1A/g, '');
if (/warning/i.test(data)) {
data = chalk.yellow(data);
} else if (log.type === 'stderr') {
data = chalk.red(data);
}
}
const date = new Date(log.created).toISOString();
data.split('\n').forEach((line, i) => {
if (
line.includes('START RequestId:') ||
line.includes('END RequestId:') ||
line.includes('XRAY TraceId:')
) {
return;
}
if (line.includes('REPORT RequestId:')) {
line = line.substring(line.indexOf('Duration:'), line.length);
if (line.includes('Init Duration:')) {
line = line.substring(0, line.indexOf('Init Duration:'));
}
}
if (i === 0) {
console.log(`${chalk.dim(date)} ${line}`);
console.log(
`${chalk.dim(date)} ${line.replace('[now-builder-debug] ', '')}`
);
} else {
console.log(`${' '.repeat(date.length)} ${line}`);
console.log(
`${' '.repeat(date.length)} ${line.replace(
'[now-builder-debug] ',
''
)}`
);
}
});
@@ -327,7 +358,7 @@ function printLogRaw(log) {
const logPrinters = {
short: printLogShort,
raw: printLogRaw
raw: printLogRaw,
};
function toTimestamp(datestr) {

View File

@@ -70,11 +70,12 @@ let subcommand;
const main = async ctx => {
argv = mri(ctx.argv.slice(2), {
boolean: ['help', 'debug'],
boolean: ['help', 'debug', 'yes'],
alias: {
help: 'h',
debug: 'd'
}
debug: 'd',
yes: 'y',
},
});
argv._ = argv._.slice(1);
@@ -88,7 +89,10 @@ const main = async ctx => {
await exit(0);
}
const { authConfig: { token }, config: { currentTeam } } = ctx;
const {
authConfig: { token },
config: { currentTeam },
} = ctx;
const output = createOutput({ debug });
const client = new Client({ apiUrl, token, currentTeam, debug });
let contextName = null;
@@ -105,7 +109,7 @@ const main = async ctx => {
}
try {
await run({ token, contextName, currentTeam });
await run({ output, token, contextName, currentTeam });
} catch (err) {
handleError(err);
exit(1);
@@ -121,7 +125,7 @@ export default async ctx => {
}
};
async function run({ token, contextName, currentTeam }) {
async function run({ output, token, contextName, currentTeam }) {
const secrets = new NowSecrets({ apiUrl, token, debug, currentTeam });
const args = argv._.slice(1);
const start = Date.now();
@@ -153,13 +157,13 @@ async function run({ token, contextName, currentTeam }) {
list.map(secret => [
'',
chalk.bold(secret.name),
chalk.gray(`${ms(cur - new Date(secret.created))} ago`)
chalk.gray(`${ms(cur - new Date(secret.created))} ago`),
])
),
{
align: ['l', 'l', 'l'],
hsep: ' '.repeat(2),
stringLength: strlen
stringLength: strlen,
}
);
@@ -185,7 +189,7 @@ async function run({ token, contextName, currentTeam }) {
const theSecret = list.find(secret => secret.name === args[0]);
if (theSecret) {
const yes = await readConfirmation(theSecret);
const yes = argv.yes || (await readConfirmation(theSecret));
if (!yes) {
console.error(error('User abort'));
return exit(0);
@@ -250,6 +254,10 @@ async function run({ token, contextName, currentTeam }) {
await secrets.add(name, value);
const elapsed = ms(new Date() - start);
if (name !== name.toLowerCase()) {
output.warn(`Your secret name was converted to lower-case`);
}
console.log(
`${chalk.cyan('> Success!')} Secret ${chalk.bold(
name.toLowerCase()
@@ -275,7 +283,7 @@ function readConfirmation(secret) {
const time = chalk.gray(`${ms(new Date() - new Date(secret.created))} ago`);
const tbl = table([[chalk.bold(secret.name), time]], {
align: ['r', 'l'],
hsep: ' '.repeat(6)
hsep: ' '.repeat(6),
});
process.stdout.write(

View File

@@ -17,7 +17,7 @@ import info from './util/output/info';
import getNowDir from './util/config/global-path';
import {
getDefaultConfig,
getDefaultAuthConfig
getDefaultAuthConfig,
} from './util/config/get-default';
import hp from './util/humanize-path';
import commands from './commands/index.ts';
@@ -53,7 +53,7 @@ sourceMap.install();
Sentry.init({
dsn: SENTRY_DSN,
release: `now-cli@${pkg.version}`,
environment: pkg.version.includes('canary') ? 'canary' : 'stable'
environment: pkg.version.includes('canary') ? 'canary' : 'stable',
});
let debug = () => {};
@@ -71,7 +71,7 @@ const main = async argv_ => {
'--version': Boolean,
'-v': '--version',
'--debug': Boolean,
'-d': '--debug'
'-d': '--debug',
},
{ permissive: true }
);
@@ -102,7 +102,10 @@ const main = async argv_ => {
return 1;
}
if (localConfig instanceof NowError && !(localConfig instanceof ERRORS.CantFindConfig)) {
if (
localConfig instanceof NowError &&
!(localConfig instanceof ERRORS.CantFindConfig)
) {
output.error(`Failed to load local config file: ${localConfig.message}`);
return 1;
}
@@ -118,7 +121,7 @@ const main = async argv_ => {
if (targetOrSubcommand !== 'update') {
update = await checkForUpdate(pkg, {
interval: ms('1d'),
distTag: pkg.version.includes('canary') ? 'canary' : 'latest'
distTag: pkg.version.includes('canary') ? 'canary' : 'latest',
});
}
} catch (err) {
@@ -135,7 +138,15 @@ const main = async argv_ => {
console.log(
info(
`${chalk.bgRed('UPDATE AVAILABLE')} ` +
`Run ${cmd(await getUpdateCommand())} to install Now CLI ${update.latest}`
`Run ${cmd(await getUpdateCommand())} to install Now CLI ${
update.latest
}`
)
);
console.log(
info(
`Changelog: https://github.com/zeit/now/releases/tag/now@${update.latest}`
)
);
}
@@ -307,9 +318,9 @@ const main = async argv_ => {
console.error(
error(
`${'An unexpected error occurred while trying to write the ' +
`default now config to "${hp(
NOW_AUTH_CONFIG_PATH
)}" `}${err.message}`
`default now config to "${hp(NOW_AUTH_CONFIG_PATH)}" `}${
err.message
}`
)
);
return 1;
@@ -329,7 +340,7 @@ const main = async argv_ => {
config,
authConfig,
localConfig,
argv: argv_
argv: argv_,
};
let subcommand;
@@ -339,7 +350,8 @@ const main = async argv_ => {
const targetPath = join(process.cwd(), targetOrSubcommand);
const targetPathExists = existsSync(targetPath);
const subcommandExists =
GLOBAL_COMMANDS.has(targetOrSubcommand) || commands.has(targetOrSubcommand);
GLOBAL_COMMANDS.has(targetOrSubcommand) ||
commands.has(targetOrSubcommand);
if (targetPathExists && subcommandExists) {
console.error(
@@ -412,7 +424,7 @@ const main = async argv_ => {
message:
'No existing credentials found. Please run ' +
`${param('now login')} or pass ${param('--token')}`,
slug: 'no-credentials-found'
slug: 'no-credentials-found',
})
);
@@ -426,7 +438,7 @@ const main = async argv_ => {
message: `This command doesn't work with ${param(
'--token'
)}. Please use ${param('--scope')}.`,
slug: 'no-token-allowed'
slug: 'no-token-allowed',
})
);
@@ -440,7 +452,7 @@ const main = async argv_ => {
console.error(
error({
message: `You defined ${param('--token')}, but it's missing a value`,
slug: 'missing-token-value'
slug: 'missing-token-value',
})
);
@@ -459,11 +471,22 @@ const main = async argv_ => {
const targetCommand = commands.get(subcommand);
if (argv['--team']) {
output.warn(`The ${param('--team')} flag is deprecated. Please use ${param('--scope')} instead.`);
output.warn(
`The ${param('--team')} flag is deprecated. Please use ${param(
'--scope'
)} instead.`
);
}
if (typeof scope === 'string' && targetCommand !== 'login' && targetCommand !== 'dev' && !(targetCommand === 'teams' && argv._[3] !== 'invite')) {
const { authConfig: { token } } = ctx;
if (
typeof scope === 'string' &&
targetCommand !== 'login' &&
targetCommand !== 'dev' &&
!(targetCommand === 'teams' && argv._[3] !== 'invite')
) {
const {
authConfig: { token },
} = ctx;
const client = new Client({ apiUrl, token });
let user = null;
@@ -475,7 +498,7 @@ const main = async argv_ => {
console.error(
error({
message: `You do not have access to the specified account`,
slug: 'scope-not-accessible'
slug: 'scope-not-accessible',
})
);
@@ -499,7 +522,7 @@ const main = async argv_ => {
console.error(
error({
message: `You do not have access to the specified team`,
slug: 'scope-not-accessible'
slug: 'scope-not-accessible',
})
);
@@ -517,7 +540,7 @@ const main = async argv_ => {
console.error(
error({
message: 'The specified scope does not exist',
slug: 'scope-not-existent'
slug: 'scope-not-existent',
})
);
@@ -577,7 +600,8 @@ const main = async argv_ => {
if (shouldCollectMetrics) {
metric
.event(eventCategory, '1', pkg.version)
.exception(err.message).send();
.exception(err.message)
.send();
}
return 1;
@@ -586,7 +610,8 @@ const main = async argv_ => {
if (shouldCollectMetrics) {
metric
.event(eventCategory, '1', pkg.version)
.exception(err.message).send();
.exception(err.message)
.send();
}
// Otherwise it is an unexpected error and we should show the trace
@@ -647,9 +672,7 @@ process.on('uncaughtException', handleUnexpected);
// subcommands waiting for further data won't work (like `logs` and `logout`)!
main(process.argv)
.then(exitCode => {
process.exitCode = exitCode;
process.emit('nowExit');
process.on('beforeExit', () => {
process.exit(exitCode);
});
})
.catch(handleUnexpected);

View File

@@ -1,142 +0,0 @@
import { JsonBody, StreamBody, context } from 'fetch-h2';
// Packages
import { parse } from 'url';
import Sema from 'async-sema';
import createOutput, { Output } from './output/create-output';
const MAX_REQUESTS_PER_CONNECTION = 1000;
type CurrentContext = ReturnType<typeof context> & {
fetchesMade: number;
ongoingFetches: number;
};
export interface AgentFetchOptions {
method?: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';
body?: NodeJS.ReadableStream | string;
headers: { [key: string]: string };
}
/**
* Returns a `fetch` version with a similar API to the browser's configured with a
* HTTP2 agent. It encodes `body` automatically as JSON.
*
* @param {String} host
* @return {Function} fetch
*/
export default class NowAgent {
_contexts: ReturnType<typeof context>[];
_currContext: CurrentContext;
_output: Output;
_protocol?: string;
_sema: Sema;
_url: string;
constructor(url: string, { debug = false } = {}) {
// We use multiple contexts because each context represent one connection
// With nginx, we're limited to 1000 requests before a connection is closed
// http://nginx.org/en/docs/http/ngx_http_v2_module.html#http2_max_requests
// To get arround this, we keep track of requests made on a connection. when we're about to hit 1000
// we start up a new connection, and re-route all future traffic through the new connection
// and when the final request from the old connection resolves, we auto-close the old connection
this._contexts = [context()];
this._currContext = {
...this._contexts[0],
fetchesMade: 0,
ongoingFetches: 0
};
const parsed = parse(url);
this._url = url;
this._protocol = parsed.protocol;
this._sema = new Sema(20);
this._output = createOutput({ debug });
}
setConcurrency({
maxStreams,
capacity
}: {
maxStreams: number;
capacity: number;
}) {
this._sema = new Sema(maxStreams || 20, { capacity });
}
async fetch(path: string, opts: AgentFetchOptions) {
const { debug } = this._output;
await this._sema.acquire();
let currentContext: CurrentContext;
this._currContext.fetchesMade++;
if (this._currContext.fetchesMade >= MAX_REQUESTS_PER_CONNECTION) {
const ctx = { ...context(), fetchesMade: 1, ongoingFetches: 0 };
this._contexts.push(ctx);
this._currContext = ctx;
}
// If we're changing contexts, we don't want to record the ongoingFetch on the old context
// That'll cause an off-by-one error when trying to close the old socket later
this._currContext.ongoingFetches++;
currentContext = this._currContext;
debug(
`Total requests made on socket #${this._contexts.length}: ${this
._currContext.fetchesMade}`
);
debug(
`Concurrent requests on socket #${this._contexts.length}: ${this
._currContext.ongoingFetches}`
);
let body: JsonBody | StreamBody | string | undefined;
if (opts.body && typeof opts.body === 'object') {
if (typeof (<NodeJS.ReadableStream>opts.body).pipe === 'function') {
body = new StreamBody(<NodeJS.ReadableStream>opts.body);
} else {
opts.headers['Content-Type'] = 'application/json';
body = new JsonBody(opts.body);
}
} else {
body = opts.body;
}
const { host, protocol } = parse(path);
const url = host ? `${protocol}//${host}` : this._url;
const handleCompleted = async <T>(res: T) => {
currentContext.ongoingFetches--;
if (
(currentContext !== this._currContext || host) &&
currentContext.ongoingFetches <= 0
) {
// We've completely moved on to a new socket
// close the old one
// TODO: Fix race condition:
// If the response is a stream, and the server is still streaming data
// we should check if the stream has closed before disconnecting
// hasCompleted CAN technically be called before the res body stream is closed
debug('Closing old socket');
currentContext.disconnect(url);
}
this._sema.release();
return res;
};
return currentContext
.fetch((host ? '' : this._url) + path, { ...opts, body })
.then(res => handleCompleted(res))
.catch((err: Error) => {
handleCompleted(null);
throw err;
});
}
close() {
const { debug } = this._output;
debug('Closing agent');
this._currContext.disconnect(this._url);
}
}

View File

@@ -34,6 +34,11 @@ export default async function getDeploymentForAlias(
}
const appName = await getAppName(output, localConfig, localConfigPath);
if (!appName) {
return null;
}
const deployment = await getAppLastDeployment(
output,
client,

View File

@@ -7,7 +7,11 @@ export default async function getInferredTargets(
output: Output,
config: Config
) {
output.warn(`The ${cmd('now alias')} command (no arguments) was deprecated in favour of ${cmd('now --prod')}.`);
output.warn(
`The ${cmd(
'now alias'
)} command (no arguments) was deprecated in favor of ${cmd('now --prod')}.`
);
// This field is deprecated, warn about it
if (config.aliases) {

View File

@@ -1,9 +1,9 @@
import qs from 'querystring';
import { EventEmitter } from 'events';
import { parse as parseUrl } from 'url';
import fetch, { RequestInit } from 'node-fetch';
import retry, { RetryFunction, Options as RetryOptions } from 'async-retry';
import createOutput, { Output } from './output/create-output';
import Agent, { AgentFetchOptions } from './agent';
import responseError from './response-error';
import ua from './ua';
@@ -17,7 +17,6 @@ export type FetchOptions = {
};
export default class Client extends EventEmitter {
_agent: Agent;
_apiUrl: string;
_debug: boolean;
_forceNew: boolean;
@@ -30,7 +29,7 @@ export default class Client extends EventEmitter {
token,
currentTeam,
forceNew = false,
debug = false
debug = false,
}: {
apiUrl: string;
token: string;
@@ -44,30 +43,23 @@ export default class Client extends EventEmitter {
this._forceNew = forceNew;
this._output = createOutput({ debug });
this._apiUrl = apiUrl;
this._agent = new Agent(apiUrl, { debug });
this._onRetry = this._onRetry.bind(this);
this.currentTeam = currentTeam;
const closeAgent = () => {
this._agent.close();
process.removeListener('nowExit', closeAgent);
};
// @ts-ignore
process.on('nowExit', closeAgent);
}
retry<T>(fn: RetryFunction<T>, { retries = 3, maxTimeout = Infinity } = {}) {
return retry(fn, {
retries,
maxTimeout,
onRetry: this._onRetry
onRetry: this._onRetry,
});
}
_fetch(_url: string, opts: FetchOptions = {}) {
const parsedUrl = parseUrl(_url, true);
const apiUrl = parsedUrl.host ? `${parsedUrl.protocol}//${parsedUrl.host}` : '';
const apiUrl = parsedUrl.host
? `${parsedUrl.protocol}//${parsedUrl.host}`
: '';
if (opts.useCurrentTeam !== false && this.currentTeam) {
const query = parsedUrl.query;
@@ -80,20 +72,19 @@ export default class Client extends EventEmitter {
Object.assign(opts, {
body: JSON.stringify(opts.body),
headers: Object.assign({}, opts.headers, {
'Content-Type': 'application/json'
})
'Content-Type': 'application/json',
}),
});
}
opts.headers = opts.headers || {};
opts.headers.authorization = `Bearer ${this._token}`;
opts.headers.Authorization = `Bearer ${this._token}`;
opts.headers['user-agent'] = ua;
const url = `${apiUrl ? '' : this._apiUrl}${_url}`;
return this._output.time(
`${opts.method || 'GET'} ${apiUrl ? '' : this._apiUrl}${_url} ${JSON.stringify(
opts.body
) || ''}`,
this._agent.fetch(_url, opts as AgentFetchOptions)
`${opts.method || 'GET'} ${url} ${JSON.stringify(opts.body) || ''}`,
fetch(url, opts as RequestInit)
);
}
@@ -126,7 +117,5 @@ export default class Client extends EventEmitter {
this._output.debug(`Retrying: ${error}\n${error.stack}`);
}
close() {
this._agent.close();
}
close() {}
}

View File

@@ -15,40 +15,45 @@ export default async function createDeploy(
return await now.create(paths, createArgs);
} catch (error) {
if (error.code === 'rate_limited') {
return new ERRORS_TS.DeploymentsRateLimited(error.message);
throw new ERRORS_TS.DeploymentsRateLimited(error.message);
}
// Means that the domain used as a suffix no longer exists
if (error.code === 'domain_missing') {
return new ERRORS_TS.DomainNotFound(error.value);
throw new ERRORS_TS.DomainNotFound(error.value);
}
if (error.code === 'domain_not_found' && error.domain) {
return new ERRORS_TS.DomainNotFound(error.domain);
throw new ERRORS_TS.DomainNotFound(error.domain);
}
// This error occures when a domain used in the `alias`
// is not yet verified
if (error.code === 'domain_not_verified' && error.domain) {
return new ERRORS_TS.DomainNotVerified(error.domain);
throw new ERRORS_TS.DomainNotVerified(error.domain);
}
// If the domain used as a suffix is not verified, we fail
if (error.code === 'domain_not_verified' && error.value) {
return new ERRORS_TS.DomainVerificationFailed(error.value);
throw new ERRORS_TS.DomainVerificationFailed(error.value);
}
// If the domain isn't owned by the user
if (error.code === 'not_domain_owner') {
throw new ERRORS_TS.NotDomainOwner(error.message);
}
if (error.code === 'builds_rate_limited') {
return new ERRORS_TS.BuildsRateLimited(error.message);
throw new ERRORS_TS.BuildsRateLimited(error.message);
}
// If the user doesn't have permissions over the domain used as a suffix we fail
if (error.code === 'forbidden') {
return new ERRORS_TS.DomainPermissionDenied(error.value, contextName);
throw new ERRORS_TS.DomainPermissionDenied(error.value, contextName);
}
if (error.code === 'bad_request' && error.keyword) {
return new ERRORS.SchemaValidationFailed(
throw new ERRORS.SchemaValidationFailed(
error.message,
error.keyword,
error.dataPath,
@@ -57,19 +62,19 @@ export default async function createDeploy(
}
if (error.code === 'domain_configured') {
return new ERRORS_TS.AliasDomainConfigured(error);
throw new ERRORS_TS.AliasDomainConfigured(error);
}
if (error.code === 'missing_build_script') {
return new ERRORS_TS.MissingBuildScript(error);
throw new ERRORS_TS.MissingBuildScript(error);
}
if (error.code === 'conflicting_file_path') {
return new ERRORS_TS.ConflictingFilePath(error);
throw new ERRORS_TS.ConflictingFilePath(error);
}
if (error.code === 'conflicting_path_segment') {
return new ERRORS_TS.ConflictingPathSegment(error);
throw new ERRORS_TS.ConflictingPathSegment(error);
}
// If the cert is missing we try to generate a new one and the retry
@@ -87,10 +92,10 @@ export default async function createDeploy(
}
if (error.code === 'not_found') {
return new ERRORS_TS.DeploymentNotFound({ context: contextName });
throw new ERRORS_TS.DeploymentNotFound({ context: contextName });
}
const certError = mapCertError(error)
const certError = mapCertError(error);
if (certError) {
return certError;
}

View File

@@ -1,35 +0,0 @@
//
import sleep from '../sleep';
import createPollingFn from '../create-polling-fn';
import getDeploymentByIdOrThrow from './get-deployment-by-id-or-throw';
const POLLING_INTERVAL = 5000;
async function* getStatusChangeFromPolling(
now: any,
contextName: string,
idOrHost: string,
initialState: string
) {
const pollDeployment = createPollingFn(
getDeploymentByIdOrThrow,
POLLING_INTERVAL
);
let prevState = initialState;
for await (const deployment of pollDeployment(now, contextName, idOrHost)) {
if (prevState !== deployment.state) {
await sleep(5000);
yield {
type: 'state-change',
created: Date.now(),
payload: { value: deployment.state }
};
} else {
prevState = deployment.state;
}
}
}
export default getStatusChangeFromPolling;

View File

@@ -0,0 +1,201 @@
import bytes from 'bytes';
import Progress from 'progress';
import chalk from 'chalk';
import pluralize from 'pluralize';
import {
createDeployment,
createLegacyDeployment,
} from '../../../../now-client';
import wait from '../output/wait';
import createOutput from '../output';
export default async function processDeployment({
now,
debug,
hashes,
paths,
requestBody,
uploadStamp,
deployStamp,
legacy,
env,
quiet,
}: any) {
const { warn, log } = createOutput({ debug });
let bar: Progress | null = null;
if (!legacy) {
let buildSpinner = null;
let deploySpinner = null;
for await (const event of createDeployment(paths[0], {
...requestBody,
debug: now._debug,
})) {
if (event.type === 'hashes-calculated') {
hashes = event.payload;
}
if (event.type === 'warning') {
warn(event.payload);
}
if (event.type === 'file_count') {
debug(
`Total files ${event.payload.total.size}, ${event.payload.missing.length} changed`
);
if (!quiet) {
log(
`Synced ${pluralize(
'file',
event.payload.missing.length,
true
)} ${uploadStamp()}`
);
}
const missingSize = event.payload.missing
.map((sha: string) => event.payload.total.get(sha).data.length)
.reduce((a: number, b: number) => a + b, 0);
bar = new Progress(`${chalk.gray('>')} Upload [:bar] :percent :etas`, {
width: 20,
complete: '=',
incomplete: '',
total: missingSize,
clear: true,
});
}
if (event.type === 'file-uploaded') {
debug(
`Uploaded: ${event.payload.file.names.join(' ')} (${bytes(
event.payload.file.data.length
)})`
);
if (bar) {
bar.tick(event.payload.file.data.length);
}
}
if (event.type === 'created') {
now._host = event.payload.url;
if (!quiet) {
const version = legacy ? `${chalk.grey('[v1]')} ` : '';
log(`https://${event.payload.url} ${version}${deployStamp()}`);
} else {
process.stdout.write(`https://${event.payload.url}`);
}
}
if (event.type === 'build-state-changed') {
if (buildSpinner === null) {
buildSpinner = wait('Building...');
}
}
if (event.type === 'all-builds-completed') {
if (buildSpinner) {
buildSpinner();
}
deploySpinner = wait('Finalizing...');
}
// Handle error events
if (event.type === 'error') {
if (buildSpinner) {
buildSpinner();
}
if (deploySpinner) {
deploySpinner();
}
throw await now.handleDeploymentError(event.payload, { hashes, env });
}
// Handle ready event
if (event.type === 'ready') {
if (deploySpinner) {
deploySpinner();
}
return event.payload;
}
}
} else {
for await (const event of createLegacyDeployment(paths[0], {
...requestBody,
debug: now._debug,
})) {
if (event.type === 'hashes-calculated') {
hashes = event.payload;
}
if (event.type === 'file_count') {
debug(
`Total files ${event.payload.total.size}, ${event.payload.missing.length} changed`
);
if (!quiet) {
log(
`Synced ${pluralize(
'file',
event.payload.missing.length,
true
)} ${uploadStamp()}`
);
}
const missingSize = event.payload.missing
.map((sha: string) => event.payload.total.get(sha).data.length)
.reduce((a: number, b: number) => a + b, 0);
bar = new Progress(`${chalk.gray('>')} Upload [:bar] :percent :etas`, {
width: 20,
complete: '=',
incomplete: '',
total: missingSize,
clear: true,
});
}
if (event.type === 'file-uploaded') {
debug(
`Uploaded: ${event.payload.file.names.join(' ')} (${bytes(
event.payload.file.data.length
)})`
);
if (bar) {
bar.tick(event.payload.file.data.length);
}
}
if (event.type === 'created') {
now._host = event.payload.url;
if (!quiet) {
const version = legacy ? `${chalk.grey('[v1]')} ` : '';
log(`${event.payload.url} ${version}${deployStamp()}`);
} else {
process.stdout.write(`https://${event.payload.url}`);
}
}
// Handle error events
if (event.type === 'error') {
throw await now.handleDeploymentError(event.payload, { hashes, env });
}
// Handle ready event
if (event.type === 'ready') {
log(`Build completed`);
return event.payload;
}
}
}
}

View File

@@ -0,0 +1,18 @@
import { homedir } from 'os';
import promptBool from '../input/prompt-bool';
import { Output } from '../output';
export default async function shouldDeployDir(argv0: string, output: Output) {
let yes = true;
if (argv0 === homedir()) {
if (
!(await promptBool(
'You are deploying your home directory. Do you want to continue?'
))
) {
output.log('Aborted');
yes = false;
}
}
return yes;
}

View File

@@ -8,14 +8,15 @@ import { createHash } from 'crypto';
import { createGunzip } from 'zlib';
import { join, resolve } from 'path';
import { funCacheDir } from '@zeit/fun';
import cacheDirectory from 'cache-or-tmp-directory';
import { PackageJson } from '@now/build-utils';
import XDGAppPaths from 'xdg-app-paths';
import {
createReadStream,
mkdirp,
readFile,
readJSON,
writeFile,
remove
remove,
} from 'fs-extra';
import pkg from '../../../package.json';
@@ -23,10 +24,10 @@ import { NoBuilderCacheError, BuilderCacheCleanError } from '../errors-ts';
import wait from '../output/wait';
import { Output } from '../output';
import { getDistTag } from '../get-dist-tag';
import { devDependencies } from '../../../package.json';
import * as staticBuilder from './static-builder';
import { BuilderWithPackage, Package } from './types';
import { BuilderWithPackage } from './types';
import { getBundledBuilders } from './get-bundled-builders';
const registryTypes = new Set(['version', 'tag', 'range']);
@@ -34,14 +35,10 @@ const localBuilders: { [key: string]: BuilderWithPackage } = {
'@now/static': {
runInProcess: true,
builder: Object.freeze(staticBuilder),
package: Object.freeze({ name: '@now/static', version: '' })
}
package: Object.freeze({ name: '@now/static', version: '' }),
},
};
const bundledBuilders = Object.keys(devDependencies).filter(d =>
d.startsWith('@now/')
);
const distTag = getDistTag(pkg.version);
export const cacheDirPromise = prepareCacheDir();
@@ -80,7 +77,7 @@ export async function prepareCacheDir() {
const { NOW_BUILDER_CACHE_DIR } = process.env;
const designated = NOW_BUILDER_CACHE_DIR
? resolve(NOW_BUILDER_CACHE_DIR)
: cacheDirectory('co.zeit.now');
: XDGAppPaths('co.zeit.now').cache();
if (!designated) {
throw new NoBuilderCacheError();
@@ -117,7 +114,7 @@ export async function prepareBuilderDir() {
export async function prepareBuilderModulePath() {
const [builderDir, builderContents] = await Promise.all([
builderDirPromise,
readFile(join(__dirname, 'builder-worker.js'))
readFile(join(__dirname, 'builder-worker.js')),
]);
let needsWrite = false;
const builderSha = getSha(builderContents);
@@ -179,7 +176,7 @@ export function getBuildUtils(packages: string[]): string {
export function filterPackage(
builderSpec: string,
distTag: string,
buildersPkg: Package
buildersPkg: PackageJson
) {
if (builderSpec in localBuilders) return false;
const parsed = npa(builderSpec);
@@ -187,7 +184,7 @@ export function filterPackage(
parsed.name &&
parsed.type === 'tag' &&
parsed.fetchSpec === distTag &&
bundledBuilders.includes(parsed.name) &&
getBundledBuilders().includes(parsed.name) &&
buildersPkg.dependencies
) {
const parsedInstalled = npa(
@@ -259,10 +256,10 @@ export async function installBuilders(
'--exact',
'--no-lockfile',
'--non-interactive',
...packagesToInstall
...packagesToInstall,
],
{
cwd: builderDir
cwd: builderDir,
}
);
} finally {
@@ -294,10 +291,10 @@ export async function updateBuilders(
'--exact',
'--no-lockfile',
'--non-interactive',
...packages.filter(p => p !== '@now/static')
...packages.filter(p => p !== '@now/static'),
],
{
cwd: builderDir
cwd: builderDir,
}
);
@@ -336,7 +333,7 @@ export async function getBuilder(
const pkg = require(join(dest, 'package.json'));
builderWithPkg = {
builder: Object.freeze(mod),
package: Object.freeze(pkg)
package: Object.freeze(pkg),
};
} catch (err) {
if (err.code === 'MODULE_NOT_FOUND') {
@@ -357,7 +354,7 @@ export async function getBuilder(
function getPackageName(
parsed: npa.Result,
buildersPkg: Package
buildersPkg: PackageJson
): string | null {
if (registryTypes.has(parsed.type)) {
return parsed.name;
@@ -378,7 +375,7 @@ function getSha(buffer: Buffer): string {
}
function hasBundledBuilders(dependencies: { [name: string]: string }): boolean {
for (const name of bundledBuilders) {
for (const name of getBundledBuilders()) {
if (!(name in dependencies)) {
return false;
}

View File

@@ -5,7 +5,7 @@ import bytes from 'bytes';
import { delimiter, dirname, join } from 'path';
import { fork, ChildProcess } from 'child_process';
import { createFunction } from '@zeit/fun';
import { File, Lambda, FileBlob, FileFsRef } from '@now/build-utils';
import { Builder, File, Lambda, FileBlob, FileFsRef } from '@now/build-utils';
import stripAnsi from 'strip-ansi';
import chalk from 'chalk';
import which from 'which';
@@ -23,12 +23,11 @@ import { builderModulePathPromise, getBuilder } from './builder-cache';
import {
EnvConfig,
NowConfig,
BuildConfig,
BuildMatch,
BuildResult,
BuilderInputs,
BuilderOutput,
BuilderOutputs
BuilderOutputs,
} from './types';
interface BuildMessage {
@@ -69,7 +68,7 @@ async function createBuildProcess(
}
const [execPath, modulePath] = await Promise.all([
nodeBinPromise,
builderModulePathPromise
builderModulePathPromise,
]);
let PATH = `${dirname(execPath)}${delimiter}${process.env.PATH}`;
if (yarnPath) {
@@ -81,11 +80,11 @@ async function createBuildProcess(
...process.env,
PATH,
...buildEnv,
NOW_REGION: 'dev1'
NOW_REGION: 'dev1',
},
execPath,
execArgv: [],
stdio: ['ignore', 'pipe', 'pipe', 'ipc']
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
});
match.buildProcess = buildProcess;
@@ -122,7 +121,7 @@ export async function executeBuild(
filesRemoved?: string[]
): Promise<void> {
const {
builderWithPkg: { runInProcess, builder, package: pkg }
builderWithPkg: { runInProcess, builder, package: pkg },
} = match;
const { src: entrypoint } = match;
const { env, debug, buildEnv, yarnPath, cwd: workPath } = devServer;
@@ -165,8 +164,8 @@ export async function executeBuild(
filesChanged,
filesRemoved,
env,
buildEnv
}
buildEnv,
},
};
let buildResultOrOutputs: BuilderOutputs | BuildResult;
@@ -203,7 +202,7 @@ export async function executeBuild(
buildProcess.send({
type: 'build',
builderName: pkg.name,
buildParams
buildParams,
});
buildResultOrOutputs = await new Promise((resolve, reject) => {
@@ -260,7 +259,11 @@ export async function executeBuild(
result = {
output: buildResultOrOutputs as BuilderOutputs,
routes: [],
watch: []
watch: [],
distPath:
typeof buildResultOrOutputs.distPath === 'string'
? buildResultOrOutputs.distPath
: undefined,
};
} else {
result = buildResultOrOutputs as BuildResult;
@@ -346,9 +349,9 @@ export async function executeBuild(
...nowConfig.env,
...asset.environment,
...env,
NOW_REGION: 'dev1'
}
}
NOW_REGION: 'dev1',
},
},
});
}
@@ -382,7 +385,7 @@ export async function getBuildMatches(
return matches;
}
const noMatches: BuildConfig[] = [];
const noMatches: Builder[] = [];
const builds = nowConfig.builds || [{ src: '**', use: '@now/static' }];
for (const buildConfig of builds) {
@@ -420,7 +423,7 @@ export async function getBuildMatches(
builderWithPkg,
buildOutput: {},
buildResults: new Map(),
buildTimestamp: 0
buildTimestamp: 0,
});
}
}

View File

@@ -12,13 +12,13 @@ export const httpStatusDescriptionMap = new Map([
[502, 'BAD_GATEWAY'],
[503, 'SERVICE_UNAVAILABLE'],
[504, 'GATEWAY_TIMEOUT'],
[508, 'INFINITE_LOOP']
[508, 'INFINITE_LOOP'],
]);
export const errorMessageMap = new Map([
[400, 'Bad request'],
[402, 'Payment required'],
[403, 'You don\'t have the required permissions'],
[403, "You don't have the required permissions"],
[404, 'The page could not be found'],
[405, 'Method not allowed'],
[410, 'The deployment has been removed'],
@@ -28,7 +28,7 @@ export const errorMessageMap = new Map([
[501, 'Not implemented'],
[503, 'The deployment is currently unavailable'],
[504, 'An error occurred with your deployment'],
[508, 'Infinite loop detected']
[508, 'Infinite loop detected'],
]);
interface ErrorMessage {
@@ -40,20 +40,20 @@ interface ErrorMessage {
const appError = {
title: 'An error occurred with this application.',
subtitle: 'This is an error with the application itself, not the platform.',
app_error: true
app_error: true,
};
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const infrastructureError = {
title: 'An internal error occurred with ZEIT Now.',
subtitle: 'This is an error with the platform itself, not the application.',
app_error: false
app_error: false,
};
const pageNotFoundError = {
title: 'The page could not be found.',
subtitle: 'The page could not be found in the application.',
app_error: true
app_error: true,
};
export function generateErrorMessage(
@@ -68,7 +68,7 @@ export function generateErrorMessage(
}
return {
title: errorMessageMap.get(statusCode) || 'Error occurred',
app_error: false
app_error: false,
};
}

View File

@@ -0,0 +1,11 @@
export function getBundledBuilders() {
return [
'@now/go',
'@now/next',
'@now/node',
'@now/ruby',
'@now/python',
'@now/static-build',
'@now/build-utils',
];
}

View File

@@ -98,7 +98,7 @@ export default async function(
headers: combinedHeaders,
uri_args: query,
matched_route: routeConfig,
matched_route_idx: idx
matched_route_idx: idx,
};
break;
} else {
@@ -114,7 +114,7 @@ export default async function(
headers: combinedHeaders,
uri_args: query,
matched_route: routeConfig,
matched_route_idx: idx
matched_route_idx: idx,
};
break;
}
@@ -127,7 +127,7 @@ export default async function(
found: false,
dest: reqPathname,
uri_args: query,
headers: combinedHeaders
headers: combinedHeaders,
};
}

View File

@@ -16,10 +16,11 @@ import { basename, dirname, extname, join } from 'path';
import directoryTemplate from 'serve-handler/src/directory';
import {
Builder,
FileFsRef,
PackageJson,
detectBuilders,
detectRoutes
detectRoutes,
} from '@now/build-utils';
import { once } from '../once';
@@ -33,7 +34,7 @@ import { version as cliVersion } from '../../../package.json';
import {
createIgnore,
staticFiles as getFiles,
getAllProjectFiles
getAllProjectFiles,
} from '../get-files';
import { validateNowConfigBuilds, validateNowConfigRoutes } from './validate';
@@ -46,7 +47,7 @@ import { generateErrorMessage, generateHttpStatusDescription } from './errors';
import {
builderDirPromise,
installBuilders,
updateBuilders
updateBuilders,
} from './builder-cache';
// HTML templates
@@ -60,7 +61,6 @@ import {
EnvConfig,
NowConfig,
DevServerOptions,
BuildConfig,
BuildMatch,
BuildResult,
BuilderInputs,
@@ -70,7 +70,7 @@ import {
InvokeResult,
ListenSpec,
RouteConfig,
RouteResult
RouteResult,
} from './types';
interface FSEvent {
@@ -87,7 +87,7 @@ interface NodeRequire {
declare const __non_webpack_require__: NodeRequire;
function sortBuilders(buildA: BuildConfig, buildB: BuildConfig) {
function sortBuilders(buildA: Builder, buildB: Builder) {
if (buildA && buildA.use && buildA.use.startsWith('@now/static-build')) {
return 1;
}
@@ -182,6 +182,20 @@ export default class DevServer {
const filesChanged: Set<string> = new Set();
const filesRemoved: Set<string> = new Set();
const distPaths: string[] = [];
for (const buildMatch of this.buildMatches.values()) {
for (const buildResult of buildMatch.buildResults.values()) {
if (buildResult.distPath) {
distPaths.push(buildResult.distPath);
}
}
}
events = events.filter(event =>
distPaths.every(distPath => !event.path.startsWith(distPath))
);
// First, update the `files` mapping of source files
for (const event of events) {
if (event.type === 'add') {
@@ -255,9 +269,7 @@ export default class DevServer {
});
} else {
this.output.debug(
`Not rebuilding because \`shouldServe()\` returned \`false\` for "${
match.use
}" request path "${requestPath}"`
`Not rebuilding because \`shouldServe()\` returned \`false\` for "${match.use}" request path "${requestPath}"`
);
}
}
@@ -376,7 +388,7 @@ export default class DevServer {
// Sort build matches to make sure `@now/static-build` is always last
this.buildMatches = new Map(
[...this.buildMatches.entries()].sort((matchA, matchB) => {
return sortBuilders(matchA[1] as BuildConfig, matchB[1] as BuildConfig);
return sortBuilders(matchA[1] as Builder, matchB[1] as Builder);
})
);
}
@@ -413,10 +425,10 @@ export default class DevServer {
for (const buildMatch of this.buildMatches.values()) {
const {
src,
builderWithPkg: { package: pkg }
builderWithPkg: { package: pkg },
} = buildMatch;
if (pkg.name === '@now/static') continue;
if (updatedBuilders.includes(pkg.name)) {
if (pkg.name && updatedBuilders.includes(pkg.name)) {
this.buildMatches.delete(src);
this.output.debug(`Invalidated build match for "${src}"`);
}
@@ -441,7 +453,7 @@ export default class DevServer {
}
}
try {
this.validateEnvConfig(fileName, base || {}, env);
return this.validateEnvConfig(fileName, base || {}, env);
} catch (err) {
if (err instanceof MissingDotenvVarsError) {
this.output.error(err.message);
@@ -450,7 +462,7 @@ export default class DevServer {
throw err;
}
}
return { ...base, ...env };
return {};
}
async getNowConfig(
@@ -516,8 +528,8 @@ export default class DevServer {
`filtered out ${allFiles.length - files.length} files`
);
const { builders, errors } = await detectBuilders(files, pkg, {
tag: getDistTag(cliVersion) === 'canary' ? 'canary' : 'latest'
const { builders, warnings, errors } = await detectBuilders(files, pkg, {
tag: getDistTag(cliVersion) === 'canary' ? 'canary' : 'latest',
});
if (errors) {
@@ -525,6 +537,10 @@ export default class DevServer {
await this.exit();
}
if (warnings && warnings.length > 0) {
warnings.forEach(warning => this.output.warn(warning.message));
}
if (builders) {
const { defaultRoutes, error: routesError } = await detectRoutes(
files,
@@ -608,7 +624,9 @@ export default class DevServer {
type: string,
env: EnvConfig = {},
localEnv: EnvConfig = {}
): void {
): EnvConfig {
// Validate if there are any missing env vars defined in `now.json`,
// but not in the `.env` / `.build.env` file
const missing: string[] = Object.entries(env)
.filter(
([name, value]) =>
@@ -617,9 +635,36 @@ export default class DevServer {
!hasOwnProperty(localEnv, name)
)
.map(([name]) => name);
if (missing.length >= 1) {
if (missing.length > 0) {
throw new MissingDotenvVarsError(type, missing);
}
const merged: EnvConfig = { ...env, ...localEnv };
// Validate that the env var name matches what AWS Lambda allows:
// - https://docs.aws.amazon.com/lambda/latest/dg/env_variables.html
let hasInvalidName = false;
for (const key of Object.keys(merged)) {
if (!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(key)) {
this.output.warn(
`Ignoring ${type
.split('.')
.slice(1)
.reverse()
.join(' ')} var ${JSON.stringify(key)} because name is invalid`
);
hasInvalidName = true;
delete merged[key];
}
}
if (hasInvalidName) {
this.output.log(
'Env var names must start with letters, and can only contain alphanumeric characters and underscores'
);
}
return merged;
}
/**
@@ -652,7 +697,7 @@ export default class DevServer {
const nowConfigBuild = nowConfig.build || {};
const [env, buildEnv] = await Promise.all([
this.getLocalEnv('.env', nowConfig.env),
this.getLocalEnv('.env.build', nowConfigBuild.env)
this.getLocalEnv('.env.build', nowConfigBuild.env),
]);
Object.assign(process.env, buildEnv);
this.env = env;
@@ -670,8 +715,8 @@ export default class DevServer {
const builders: Set<string> = new Set(
(nowConfig.builds || [])
.filter((b: BuildConfig) => b.use)
.map((b: BuildConfig) => b.use as string)
.filter((b: Builder) => b.use)
.map((b: Builder) => b.use as string)
);
await installBuilders(builders, this.yarnPath, this.output);
@@ -716,7 +761,7 @@ export default class DevServer {
ignoreInitial: true,
useFsEvents: false,
usePolling: false,
persistent: true
persistent: true,
});
this.watcher.on('add', (path: string) => {
this.enqueueFsEvent('add', path);
@@ -856,8 +901,8 @@ export default class DevServer {
const json = JSON.stringify({
error: {
code: statusCode,
message: errorMessage.title
}
message: errorMessage.title,
},
});
body = `${json}\n`;
} else if (accept.includes('html')) {
@@ -870,7 +915,7 @@ export default class DevServer {
http_status_code: statusCode,
http_status_description,
error_code,
now_id: nowRequestId
now_id: nowRequestId,
});
} else if (statusCode === 502) {
view = errorTemplate502({
@@ -878,19 +923,19 @@ export default class DevServer {
http_status_code: statusCode,
http_status_description,
error_code,
now_id: nowRequestId
now_id: nowRequestId,
});
} else {
view = errorTemplate({
http_status_code: statusCode,
http_status_description,
now_id: nowRequestId
now_id: nowRequestId,
});
}
body = errorTemplateBase({
http_status_code: statusCode,
http_status_description,
view
view,
});
} else {
res.setHeader('content-type', 'text/plain; charset=utf-8');
@@ -917,7 +962,7 @@ export default class DevServer {
res.setHeader('content-type', 'application/json');
const json = JSON.stringify({
redirect: location,
status: String(statusCode)
status: String(statusCode),
});
body = `${json}\n`;
} else if (accept.includes('html')) {
@@ -949,7 +994,7 @@ export default class DevServer {
server: 'now',
'x-now-trace': 'dev1',
'x-now-id': nowRequestId,
'x-now-cache': 'MISS'
'x-now-cache': 'MISS',
};
for (const [name, value] of Object.entries(allHeaders)) {
res.setHeader(name, value);
@@ -976,7 +1021,7 @@ export default class DevServer {
'x-now-deployment-url': host,
'x-now-id': nowRequestId,
'x-now-log-id': nowRequestId.split('-')[2],
'x-zeit-co-forwarded-for': ip
'x-zeit-co-forwarded-for': ip,
};
}
@@ -1183,9 +1228,7 @@ export default class DevServer {
Object.assign(origUrl.query, uri_args);
const newUrl = url.format(origUrl);
this.output.debug(
`Checking build result's ${
buildResult.routes.length
} \`routes\` to match ${newUrl}`
`Checking build result's ${buildResult.routes.length} \`routes\` to match ${newUrl}`
);
const matchedRoute = await devRouter(
newUrl,
@@ -1238,17 +1281,17 @@ export default class DevServer {
headers: [
{
key: 'Content-Type',
value: getMimeType(assetKey)
}
]
}
]
value: getMimeType(assetKey),
},
],
},
],
});
case 'FileBlob':
const headers: http.OutgoingHttpHeaders = {
'Content-Length': asset.data.length,
'Content-Type': getMimeType(assetKey)
'Content-Type': getMimeType(assetKey),
};
this.setResponseHeaders(res, nowRequestId, headers);
res.end(asset.data);
@@ -1273,7 +1316,7 @@ export default class DevServer {
Object.assign(parsed.query, uri_args);
const path = url.format({
pathname: parsed.pathname,
query: parsed.query
query: parsed.query,
});
const body = await rawBody(req);
@@ -1283,7 +1326,7 @@ export default class DevServer {
path,
headers: this.getNowProxyHeaders(req, nowRequestId),
encoding: 'base64',
body: body.toString('base64')
body: body.toString('base64'),
};
this.output.debug(`Invoking lambda: "${assetKey}" with ${path}`);
@@ -1292,7 +1335,7 @@ export default class DevServer {
try {
result = await asset.fn<InvokeResult>({
Action: 'Invoke',
body: JSON.stringify(payload)
body: JSON.stringify(payload),
});
} catch (err) {
console.error(err);
@@ -1379,7 +1422,7 @@ export default class DevServer {
relative: href,
ext,
title: href,
base
base,
};
});
@@ -1391,13 +1434,13 @@ export default class DevServer {
const paths = [
{
name: directory,
url: requestPath
}
url: requestPath,
},
];
const directoryHtml = directoryTemplate({
files,
paths,
directory
directory,
});
this.setResponseHeaders(res, nowRequestId);
res.setHeader('Content-Type', 'text/html; charset=utf-8');
@@ -1459,7 +1502,7 @@ function proxyPass(
ws: true,
xfwd: true,
ignorePath: true,
target: dest
target: dest,
});
proxy.on('error', (error: NodeJS.ErrnoException) => {
@@ -1490,7 +1533,7 @@ function serveStaticFile(
public: cwd,
cleanUrls: false,
etag: true,
...opts
...opts,
});
}
@@ -1546,7 +1589,7 @@ async function shouldServe(
const {
src: entrypoint,
config,
builderWithPkg: { builder }
builderWithPkg: { builder },
} = match;
if (typeof builder.shouldServe === 'function') {
const shouldServe = await builder.shouldServe({
@@ -1554,7 +1597,7 @@ async function shouldServe(
files,
config,
requestPath,
workPath: devServer.cwd
workPath: devServer.cwd,
});
if (shouldServe) {
return true;

View File

@@ -5,7 +5,7 @@ export const version = 2;
export function build({ files, entrypoint }: BuilderParams): BuildResult {
const output = {
[entrypoint]: files[entrypoint]
[entrypoint]: files[entrypoint],
};
const watch = [entrypoint];
@@ -15,7 +15,7 @@ export function build({ files, entrypoint }: BuilderParams): BuildResult {
export function shouldServe({
entrypoint,
files,
requestPath
requestPath,
}: ShouldServeParams) {
if (isIndex(entrypoint)) {
const indexPath = join(requestPath, basename(entrypoint));

View File

@@ -1,7 +1,13 @@
import http from 'http';
import { ChildProcess } from 'child_process';
import { Lambda as FunLambda } from '@zeit/fun';
import { FileBlob, FileFsRef, Lambda } from '@now/build-utils';
import {
Builder as BuildConfig,
FileBlob,
FileFsRef,
Lambda,
PackageJson,
} from '@now/build-utils';
import { Output } from '../output';
export interface DevServerOptions {
@@ -13,12 +19,6 @@ export interface EnvConfig {
[name: string]: string | undefined;
}
export interface BuildConfig {
src: string;
use?: string;
config?: object;
}
export interface BuildMatch extends BuildConfig {
builderWithPkg: BuilderWithPackage;
buildOutput: BuilderOutputs;
@@ -119,6 +119,7 @@ export interface BuildResult {
output: BuilderOutputs;
routes: RouteConfig[];
watch: string[];
distPath?: string;
}
export interface ShouldServeParams {
@@ -129,18 +130,10 @@ export interface ShouldServeParams {
workPath: string;
}
export interface Package {
name: string;
version: string;
scripts?: { [key: string]: string };
dependencies?: { [name: string]: string };
devDependencies?: { [name: string]: string };
}
export interface BuilderWithPackage {
runInProcess?: boolean;
builder: Readonly<Builder>;
package: Readonly<Package>;
package: Readonly<PackageJson>;
}
export interface HttpHeadersConfig {

View File

@@ -16,16 +16,16 @@ const buildsSchema = {
src: {
type: 'string',
minLength: 1,
maxLength: 4096
maxLength: 4096,
},
use: {
type: 'string',
minLength: 3,
maxLength: 256
maxLength: 256,
},
config: { type: 'object' }
}
}
config: { type: 'object' },
},
},
};
const validateBuilds = ajv.compile(buildsSchema);

View File

@@ -5,7 +5,7 @@ import {
writeFile,
statSync,
chmodSync,
createReadStream
createReadStream,
} from 'fs-extra';
import pipe from 'promisepipe';
import { join } from 'path';
@@ -63,7 +63,7 @@ async function installYarn(output: Output): Promise<string> {
output.debug(`Downloading ${YARN_URL}`);
const response = await fetch(YARN_URL, {
compress: false,
redirect: 'follow'
redirect: 'follow',
});
if (response.status !== 200) {
@@ -90,7 +90,7 @@ async function installYarn(output: Output): Promise<string> {
'@echo off',
'@SETLOCAL',
'@SET PATHEXT=%PATHEXT:;.JS;=;%',
'node "%~dp0\\yarn" %*'
'node "%~dp0\\yarn" %*',
].join('\r\n')
);
}

View File

@@ -1,22 +1,24 @@
import chalk from 'chalk';
import { readFileSync } from 'fs';
import { resolve } from 'path';
import { Response } from 'fetch-h2'
import { Response } from 'node-fetch';
import { DomainNotFound, InvalidDomain } from '../errors-ts';
import Client from '../client';
import wait from '../output/wait';
type JSONResponse = {
recordIds: string[]
}
recordIds: string[];
};
export default async function importZonefile(
client: Client,
contextName: string,
domain: string,
zonefilePath: string,
zonefilePath: string
) {
const cancelWait = wait(`Importing Zone file for domain ${domain} under ${chalk.bold(contextName)}`);
const cancelWait = wait(
`Importing Zone file for domain ${domain} under ${chalk.bold(contextName)}`
);
const zonefile = readFileSync(resolve(zonefilePath), 'utf8');
try {
@@ -27,7 +29,7 @@ export default async function importZonefile(
json: false,
});
const { recordIds } = await res.json() as JSONResponse;
const { recordIds } = (await res.json()) as JSONResponse;
cancelWait();
return recordIds;
} catch (error) {

View File

@@ -9,6 +9,7 @@ import maybeGetDomainByName from './maybe-get-domain-by-name';
import purchaseDomainIfAvailable from './purchase-domain-if-available';
import verifyDomain from './verify-domain';
import extractDomain from '../alias/extract-domain';
import isWildcardAlias from '../alias/is-wildcard-alias';
export default async function setupDomain(
output: Output,
@@ -34,7 +35,7 @@ export default async function setupDomain(
if (info) {
output.debug(`Domain ${domain} found for the given context`);
if (!info.verified) {
if (!info.verified || (!info.nsVerifiedAt && isWildcardAlias(alias))) {
output.debug(
`Domain ${domain} is not verified, trying to perform a verification`
);
@@ -47,8 +48,17 @@ export default async function setupDomain(
output.debug(`Domain ${domain} verification failed`);
return verificationResult;
}
if (!verificationResult.nsVerifiedAt && isWildcardAlias(alias)) {
return new ERRORS.DomainNsNotVerifiedForWildcard({
domain,
nsVerification: {
intendedNameservers: verificationResult.intendedNameservers,
nameservers: verificationResult.nameservers
}
});
}
output.debug(`Domain ${domain} successfuly verified`);
output.debug(`Domain ${domain} successfuly verified`);
return maybeGetDomainByName(client, contextName, domain) as Promise<
Domain
>;

View File

@@ -1,5 +1,5 @@
import bytes from 'bytes';
import { Response } from 'fetch-h2';
import { Response } from 'node-fetch';
import { NowError } from './now-error';
import param from './output/param';
import cmd from './output/cmd';
@@ -53,7 +53,7 @@ export class TeamDeleted extends NowError<'TEAM_DELETED', {}> {
message: `Your team was deleted. You can switch to a different one using ${param(
'now switch'
)}.`,
meta: {}
meta: {},
});
}
}
@@ -67,7 +67,7 @@ export class InvalidToken extends NowError<'NOT_AUTHORIZED', {}> {
super({
code: `NOT_AUTHORIZED`,
message: `The specified token is not valid`,
meta: {}
meta: {},
});
}
}
@@ -81,7 +81,7 @@ export class MissingUser extends NowError<'MISSING_USER', {}> {
super({
code: 'MISSING_USER',
message: `Not able to load user, missing from response`,
meta: {}
meta: {},
});
}
}
@@ -98,7 +98,7 @@ export class DomainAlreadyExists extends NowError<
super({
code: 'DOMAIN_ALREADY_EXISTS',
meta: { domain },
message: `The domain ${domain} already exists under a different context.`
message: `The domain ${domain} already exists under a different context.`,
});
}
}
@@ -115,7 +115,7 @@ export class DomainPermissionDenied extends NowError<
super({
code: 'DOMAIN_PERMISSION_DENIED',
meta: { domain, context },
message: `You don't have access to the domain ${domain} under ${context}.`
message: `You don't have access to the domain ${domain} under ${context}.`,
});
}
}
@@ -128,7 +128,7 @@ export class DomainExternal extends NowError<
super({
code: 'DOMAIN_EXTERNAL',
meta: { domain },
message: `The domain ${domain} must point to zeit.world.`
message: `The domain ${domain} must point to zeit.world.`,
});
}
}
@@ -143,7 +143,7 @@ export class SourceNotFound extends NowError<'SOURCE_NOT_FOUND', {}> {
meta: {},
message: `Not able to purchase. Please add a payment method using ${cmd(
'now billing add'
)}.`
)}.`,
});
}
}
@@ -156,7 +156,7 @@ export class InvalidTransferAuthCode extends NowError<
super({
code: 'INVALID_TRANSFER_AUTH_CODE',
meta: { domain, authCode },
message: `The provided auth code does not match with the one expected by the current registar`
message: `The provided auth code does not match with the one expected by the current registar`,
});
}
}
@@ -169,7 +169,7 @@ export class DomainRegistrationFailed extends NowError<
super({
code: 'DOMAIN_REGISTRATION_FAILED',
meta: { domain },
message
message,
});
}
}
@@ -185,7 +185,7 @@ export class DomainNotFound extends NowError<
super({
code: 'DOMAIN_NOT_FOUND',
meta: { domain },
message: `The domain ${domain} can't be found.`
message: `The domain ${domain} can't be found.`,
});
}
}
@@ -198,7 +198,7 @@ export class DomainNotVerified extends NowError<
super({
code: 'DOMAIN_NOT_VERIFIED',
meta: { domain },
message: `The domain ${domain} is not verified.`
message: `The domain ${domain} is not verified.`,
});
}
}
@@ -221,7 +221,7 @@ export class DomainVerificationFailed extends NowError<
domain,
nsVerification,
txtVerification,
purchased = false
purchased = false,
}: {
domain: string;
nsVerification: NSVerificationError;
@@ -231,7 +231,7 @@ export class DomainVerificationFailed extends NowError<
super({
code: 'DOMAIN_VERIFICATION_FAILED',
meta: { domain, nsVerification, txtVerification, purchased },
message: `We can't verify the domain ${domain}. Both Name Servers and DNS TXT verifications failed.`
message: `We can't verify the domain ${domain}. Both Name Servers and DNS TXT verifications failed.`,
});
}
}
@@ -252,6 +252,31 @@ export type TXTVerificationError = {
values: string[];
};
/**
* This error is returned when the domain is not verified by nameservers for wildcard alias.
*/
export class DomainNsNotVerifiedForWildcard extends NowError<
'DOMAIN_NS_NOT_VERIFIED_FOR_WILDCARD',
{
domain: string;
nsVerification: NSVerificationError;
}
> {
constructor({
domain,
nsVerification,
}: {
domain: string;
nsVerification: NSVerificationError;
}) {
super({
code: 'DOMAIN_NS_NOT_VERIFIED_FOR_WILDCARD',
meta: { domain, nsVerification },
message: `The domain ${domain} is not verified by nameservers for wildcard alias.`,
});
}
}
/**
* Used when a domain is validated because we tried to add it to an account
* via API or for any other reason.
@@ -264,7 +289,17 @@ export class InvalidDomain extends NowError<
super({
code: 'INVALID_DOMAIN',
meta: { domain },
message: message || `The domain ${domain} is not valid.`
message: message || `The domain ${domain} is not valid.`,
});
}
}
export class NotDomainOwner extends NowError<'NOT_DOMAIN_OWNER', {}> {
constructor(message: string) {
super({
code: 'NOT_DOMAIN_OWNER',
meta: {},
message,
});
}
}
@@ -277,7 +312,7 @@ export class InvalidDeploymentId extends NowError<
super({
code: 'INVALID_DEPLOYMENT_ID',
meta: { id },
message: `The deployment id "${id}" is not valid.`
message: `The deployment id "${id}" is not valid.`,
});
}
}
@@ -294,7 +329,7 @@ export class UnsupportedTLD extends NowError<
super({
code: 'UNSUPPORTED_TLD',
meta: { domain },
message: `The TLD for domain name ${domain} is not supported.`
message: `The TLD for domain name ${domain} is not supported.`,
});
}
}
@@ -311,7 +346,7 @@ export class DomainNotAvailable extends NowError<
super({
code: 'DOMAIN_NOT_AVAILABLE',
meta: { domain },
message: `The domain ${domain} is not available to be purchased.`
message: `The domain ${domain} is not available to be purchased.`,
});
}
}
@@ -328,7 +363,7 @@ export class DomainServiceNotAvailable extends NowError<
super({
code: 'DOMAIN_SERVICE_NOT_AVAILABLE',
meta: { domain },
message: `The domain purchase is unavailable, try again later.`
message: `The domain purchase is unavailable, try again later.`,
});
}
}
@@ -345,7 +380,7 @@ export class DomainNotTransferable extends NowError<
super({
code: 'DOMAIN_NOT_TRANSFERABLE',
meta: { domain },
message: `The domain ${domain} is not available to be transferred.`
message: `The domain ${domain} is not available to be transferred.`,
});
}
}
@@ -361,7 +396,7 @@ export class UnexpectedDomainPurchaseError extends NowError<
super({
code: 'UNEXPECTED_DOMAIN_PURCHASE_ERROR',
meta: { domain },
message: `An unexpected error happened while purchasing.`
message: `An unexpected error happened while purchasing.`,
});
}
}
@@ -374,7 +409,7 @@ export class DomainPaymentError extends NowError<'DOMAIN_PAYMENT_ERROR', {}> {
super({
code: 'DOMAIN_PAYMENT_ERROR',
meta: {},
message: `Your card was declined.`
message: `Your card was declined.`,
});
}
}
@@ -391,7 +426,7 @@ export class DomainPurchasePending extends NowError<
super({
code: 'DOMAIN_PURCHASE_PENDING',
meta: { domain },
message: `The domain purchase for ${domain} is pending.`
message: `The domain purchase for ${domain} is pending.`,
});
}
}
@@ -405,7 +440,7 @@ export class UserAborted extends NowError<'USER_ABORTED', {}> {
super({
code: 'USER_ABORTED',
meta: {},
message: `The user aborted the operation.`
message: `The user aborted the operation.`,
});
}
}
@@ -415,7 +450,7 @@ export class CertNotFound extends NowError<'CERT_NOT_FOUND', { id: string }> {
super({
code: 'CERT_NOT_FOUND',
meta: { id },
message: `The cert ${id} can't be found.`
message: `The cert ${id} can't be found.`,
});
}
}
@@ -428,7 +463,7 @@ export class CertsPermissionDenied extends NowError<
super({
code: 'CERTS_PERMISSION_DENIED',
meta: { domain },
message: `You don't have access to ${domain}'s certs under ${context}.`
message: `You don't have access to ${domain}'s certs under ${context}.`,
});
}
}
@@ -441,7 +476,7 @@ export class CertOrderNotFound extends NowError<
super({
code: 'CERT_ORDER_NOT_FOUND',
meta: { cns },
message: `No cert order could be found for cns ${cns.join(' ,')}`
message: `No cert order could be found for cns ${cns.join(' ,')}`,
});
}
}
@@ -459,7 +494,7 @@ export class TooManyRequests extends NowError<
super({
code: 'TOO_MANY_REQUESTS',
meta: { api, retryAfter },
message: `Rate limited. Too many requests to the same endpoint.`
message: `Rate limited. Too many requests to the same endpoint.`,
});
}
}
@@ -493,7 +528,7 @@ export class CertError extends NowError<
cns,
code,
message,
helpUrl
helpUrl,
}: {
cns: string[];
code: CertErrorCode;
@@ -503,7 +538,7 @@ export class CertError extends NowError<
super({
code: `CERT_ERROR`,
meta: { cns, code, helpUrl },
message
message,
});
}
}
@@ -522,7 +557,7 @@ export class CertConfigurationError extends NowError<
message,
external,
type,
helpUrl
helpUrl,
}: {
cns: string[];
message: string;
@@ -533,7 +568,7 @@ export class CertConfigurationError extends NowError<
super({
code: `CERT_CONFIGURATION_ERROR`,
meta: { cns, helpUrl, external, type },
message
message,
});
}
}
@@ -550,7 +585,7 @@ export class DeploymentNotFound extends NowError<
super({
code: 'DEPLOYMENT_NOT_FOUND',
meta: { id, context },
message: `Can't find the deployment ${id} under the context ${context}`
message: `Can't find the deployment ${id} under the context ${context}`,
});
}
}
@@ -561,13 +596,13 @@ export class DeploymentNotFound extends NowError<
*/
export class DeploymentNotReady extends NowError<
'DEPLOYMENT_NOT_READY',
{ url: string; }
{ url: string }
> {
constructor({ url = '' }: { url: string }) {
super({
code: 'DEPLOYMENT_NOT_READY',
meta: { url },
message: `The deployment https://${url} is not ready.`
message: `The deployment https://${url} is not ready.`,
});
}
}
@@ -580,7 +615,7 @@ export class DeploymentFailedAliasImpossible extends NowError<
super({
code: 'DEPLOYMENT_FAILED_ALIAS_IMPOSSIBLE',
meta: {},
message: `The deployment build has failed and cannot be aliased`
message: `The deployment build has failed and cannot be aliased`,
});
}
}
@@ -597,7 +632,7 @@ export class DeploymentPermissionDenied extends NowError<
super({
code: 'DEPLOYMENT_PERMISSION_DENIED',
meta: { id, context },
message: `You don't have access to the deployment ${id} under ${context}.`
message: `You don't have access to the deployment ${id} under ${context}.`,
});
}
}
@@ -610,7 +645,7 @@ export class DeploymentTypeUnsupported extends NowError<
super({
code: 'DEPLOYMENT_TYPE_UNSUPPORTED',
meta: {},
message: `This region only accepts Serverless Docker Deployments`
message: `This region only accepts Serverless Docker Deployments`,
});
}
}
@@ -624,7 +659,7 @@ export class InvalidAlias extends NowError<'INVALID_ALIAS', { alias: string }> {
super({
code: 'INVALID_ALIAS',
meta: { alias },
message: `The given alias ${alias} is not valid`
message: `The given alias ${alias} is not valid`,
});
}
}
@@ -638,7 +673,7 @@ export class AliasInUse extends NowError<'ALIAS_IN_USE', { alias: string }> {
super({
code: 'ALIAS_IN_USE',
meta: { alias },
message: `The alias is already in use`
message: `The alias is already in use`,
});
}
}
@@ -653,7 +688,7 @@ export class CertMissing extends NowError<'ALIAS_IN_USE', { domain: string }> {
super({
code: 'ALIAS_IN_USE',
meta: { domain },
message: `The alias is already in use`
message: `The alias is already in use`,
});
}
}
@@ -666,7 +701,7 @@ export class ForbiddenScaleMinInstances extends NowError<
super({
code: 'FORBIDDEN_SCALE_MIN_INSTANCES',
meta: { url, max },
message: `You can't scale to more than ${max} min instances with your current plan.`
message: `You can't scale to more than ${max} min instances with your current plan.`,
});
}
}
@@ -679,7 +714,7 @@ export class ForbiddenScaleMaxInstances extends NowError<
super({
code: 'FORBIDDEN_SCALE_MAX_INSTANCES',
meta: { url, max },
message: `You can't scale to more than ${max} max instances with your current plan.`
message: `You can't scale to more than ${max} max instances with your current plan.`,
});
}
}
@@ -692,7 +727,7 @@ export class InvalidScaleMinMaxRelation extends NowError<
super({
code: 'INVALID_SCALE_MIN_MAX_RELATION',
meta: { url },
message: `Min number of instances can't be higher than max.`
message: `Min number of instances can't be higher than max.`,
});
}
}
@@ -705,7 +740,7 @@ export class NotSupportedMinScaleSlots extends NowError<
super({
code: 'NOT_SUPPORTED_MIN_SCALE_SLOTS',
meta: { url },
message: `Cloud v2 does not yet support setting a non-zero min scale setting.`
message: `Cloud v2 does not yet support setting a non-zero min scale setting.`,
});
}
}
@@ -718,7 +753,7 @@ export class VerifyScaleTimeout extends NowError<
super({
code: 'VERIFY_SCALE_TIMEOUT',
meta: { timeout },
message: `Instance verification timed out (${timeout}ms)`
message: `Instance verification timed out (${timeout}ms)`,
});
}
}
@@ -731,7 +766,7 @@ export class CantParseJSONFile extends NowError<
super({
code: 'CANT_PARSE_JSON_FILE',
meta: { file },
message: `Can't parse json file`
message: `Can't parse json file`,
});
}
}
@@ -744,7 +779,7 @@ export class CantFindConfig extends NowError<
super({
code: 'CANT_FIND_CONFIG',
meta: { paths },
message: `Can't find a configuration file in the given locations.`
message: `Can't find a configuration file in the given locations.`,
});
}
}
@@ -754,7 +789,7 @@ export class FileNotFound extends NowError<'FILE_NOT_FOUND', { file: string }> {
super({
code: 'FILE_NOT_FOUND',
meta: { file },
message: `Can't find a file in provided location '${file}'.`
message: `Can't find a file in provided location '${file}'.`,
});
}
}
@@ -767,7 +802,7 @@ export class RulesFileValidationError extends NowError<
super({
code: 'PATH_ALIAS_VALIDATION_ERROR',
meta: { location, message },
message: `The provided rules format in file for path alias are invalid`
message: `The provided rules format in file for path alias are invalid`,
});
}
}
@@ -777,7 +812,7 @@ export class NoAliasInConfig extends NowError<'NO_ALIAS_IN_CONFIG', {}> {
super({
code: 'NO_ALIAS_IN_CONFIG',
meta: {},
message: `There is no alias set up in config file.`
message: `There is no alias set up in config file.`,
});
}
}
@@ -790,7 +825,7 @@ export class InvalidAliasInConfig extends NowError<
super({
code: 'INVALID_ALIAS_IN_CONFIG',
meta: { value },
message: `Invalid alias option in configuration.`
message: `Invalid alias option in configuration.`,
});
}
}
@@ -803,7 +838,7 @@ export class RuleValidationFailed extends NowError<
super({
code: 'RULE_VALIDATION_FAILED',
meta: { message },
message: `The server validation for rules failed`
message: `The server validation for rules failed`,
});
}
}
@@ -816,7 +851,7 @@ export class InvalidMinForScale extends NowError<
super({
code: 'INVALID_MIN_FOR_SCALE',
meta: { value },
message: `Invalid <min> parameter "${value}". A number or "auto" were expected`
message: `Invalid <min> parameter "${value}". A number or "auto" were expected`,
});
}
}
@@ -829,7 +864,7 @@ export class InvalidArgsForMinMaxScale extends NowError<
super({
code: 'INVALID_ARGS_FOR_MIN_MAX_SCALE',
meta: { min },
message: `Invalid number of arguments: expected <min> ("${min}") and [max]`
message: `Invalid number of arguments: expected <min> ("${min}") and [max]`,
});
}
}
@@ -842,7 +877,7 @@ export class InvalidMaxForScale extends NowError<
super({
code: 'INVALID_MAX_FOR_SCALE',
meta: { value },
message: `Invalid <max> parameter "${value}". A number or "auto" were expected`
message: `Invalid <max> parameter "${value}". A number or "auto" were expected`,
});
}
}
@@ -852,7 +887,7 @@ export class InvalidCert extends NowError<'INVALID_CERT', {}> {
super({
code: 'INVALID_CERT',
meta: {},
message: `The provided custom certificate is invalid and couldn't be added`
message: `The provided custom certificate is invalid and couldn't be added`,
});
}
}
@@ -865,7 +900,7 @@ export class DNSPermissionDenied extends NowError<
super({
code: 'DNS_PERMISSION_DENIED',
meta: { domain },
message: `You don't have access to the DNS records of ${domain}.`
message: `You don't have access to the DNS records of ${domain}.`,
});
}
}
@@ -875,7 +910,7 @@ export class DNSInvalidPort extends NowError<'DNS_INVALID_PORT', {}> {
super({
code: 'DNS_INVALID_PORT',
meta: {},
message: `Invalid <port> parameter. A number was expected`
message: `Invalid <port> parameter. A number was expected`,
});
}
}
@@ -888,7 +923,7 @@ export class DNSInvalidType extends NowError<
super({
code: 'DNS_INVALID_TYPE',
meta: { type },
message: `Invalid <type> parameter "${type}". Expected one of A, AAAA, ALIAS, CAA, CNAME, MX, SRV, TXT`
message: `Invalid <type> parameter "${type}". Expected one of A, AAAA, ALIAS, CAA, CNAME, MX, SRV, TXT`,
});
}
}
@@ -901,7 +936,7 @@ export class DNSConflictingRecord extends NowError<
super({
code: 'DNS_CONFLICTING_RECORD',
meta: { record },
message: ` A conflicting record exists "${record}".`
message: ` A conflicting record exists "${record}".`,
});
}
}
@@ -924,7 +959,7 @@ export class DomainRemovalConflict extends NowError<
pendingAsyncPurchase,
resolvable,
suffix,
transferring
transferring,
}: {
aliases: string[];
certs: string[];
@@ -942,9 +977,9 @@ export class DomainRemovalConflict extends NowError<
pendingAsyncPurchase,
suffix,
transferring,
resolvable
resolvable,
},
message
message,
});
}
}
@@ -957,7 +992,7 @@ export class DomainMoveConflict extends NowError<
message,
pendingAsyncPurchase,
resolvable,
suffix
suffix,
}: {
message: string;
pendingAsyncPurchase: boolean;
@@ -969,9 +1004,9 @@ export class DomainMoveConflict extends NowError<
meta: {
pendingAsyncPurchase,
resolvable,
suffix
suffix,
},
message
message,
});
}
}
@@ -981,17 +1016,23 @@ export class InvalidEmail extends NowError<'INVALID_EMAIL', { email: string }> {
super({
code: 'INVALID_EMAIL',
message,
meta: { email }
meta: { email },
});
}
}
export class AccountNotFound extends NowError<'ACCOUNT_NOT_FOUND', { email: string }> {
constructor(email: string, message: string = `Please sign up: https://zeit.co/signup`) {
export class AccountNotFound extends NowError<
'ACCOUNT_NOT_FOUND',
{ email: string }
> {
constructor(
email: string,
message: string = `Please sign up: https://zeit.co/signup`
) {
super({
code: 'ACCOUNT_NOT_FOUND',
message,
meta: { email }
meta: { email },
});
}
}
@@ -1004,7 +1045,7 @@ export class InvalidMoveDestination extends NowError<
super({
code: 'INVALID_MOVE_DESTINATION',
message: `Invalid move destination "${destination}"`,
meta: { destination }
meta: { destination },
});
}
}
@@ -1017,7 +1058,7 @@ export class InvalidMoveToken extends NowError<
super({
code: 'INVALID_MOVE_TOKEN',
message: `Invalid move token "${token}"`,
meta: { token }
meta: { token },
});
}
}
@@ -1027,7 +1068,7 @@ export class NoBuilderCacheError extends NowError<'NO_BUILDER_CACHE', {}> {
super({
code: 'NO_BUILDER_CACHE',
message: 'Could not find cache directory for now-builders.',
meta: {}
meta: {},
});
}
}
@@ -1040,7 +1081,7 @@ export class BuilderCacheCleanError extends NowError<
super({
code: 'BUILDER_CACHE_CLEAN_FAILED',
message: `Error cleaning builder cache: ${message}`,
meta: { path }
meta: { path },
});
}
}
@@ -1057,7 +1098,7 @@ export class LambdaSizeExceededError extends NowError<
).toLowerCase()}) exceeds the maximum size limit (${bytes(
maxLambdaSize
).toLowerCase()}). Learn more: https://zeit.co/docs/v2/deployments/concepts/lambdas/#maximum-bundle-size`,
meta: { size, maxLambdaSize }
meta: { size, maxLambdaSize },
});
}
}
@@ -1076,7 +1117,7 @@ export class MissingDotenvVarsError extends NowError<
} else {
message = [
`The following env vars are not defined in ${code(type)} file:`,
...missing.map(name => ` - ${JSON.stringify(name)}`)
...missing.map(name => ` - ${JSON.stringify(name)}`),
].join('\n');
}
@@ -1085,17 +1126,20 @@ export class MissingDotenvVarsError extends NowError<
super({
code: 'MISSING_DOTENV_VARS',
message,
meta: { type, missing }
meta: { type, missing },
});
}
}
export class DeploymentsRateLimited extends NowError<'DEPLOYMENTS_RATE_LIMITED', {}> {
export class DeploymentsRateLimited extends NowError<
'DEPLOYMENTS_RATE_LIMITED',
{}
> {
constructor(message: string) {
super({
code: 'DEPLOYMENTS_RATE_LIMITED',
meta: {},
message
message,
});
}
}
@@ -1105,7 +1149,7 @@ export class BuildsRateLimited extends NowError<'BUILDS_RATE_LIMITED', {}> {
super({
code: 'BUILDS_RATE_LIMITED',
meta: {},
message
message,
});
}
}
@@ -1115,47 +1159,66 @@ export class ProjectNotFound extends NowError<'PROJECT_NOT_FOUND', {}> {
super({
code: 'PROJECT_NOT_FOUND',
meta: {},
message: `There is no project for "${nameOrId}"`
message: `There is no project for "${nameOrId}"`,
});
}
}
export class AliasDomainConfigured extends NowError<'DOMAIN_CONFIGURED', {}> {
constructor({ message }: { message: string; }) {
constructor({ message }: { message: string }) {
super({
code: 'DOMAIN_CONFIGURED',
meta: {},
message
message,
});
}
}
export class MissingBuildScript extends NowError<'MISSING_BUILD_SCRIPT', {}> {
constructor({ message }: { message: string; }) {
constructor({ message }: { message: string }) {
super({
code: 'MISSING_BUILD_SCRIPT',
meta: {},
message
message,
});
}
}
export class ConflictingFilePath extends NowError<'CONFLICTING_FILE_PATH', {}> {
constructor({ message }: { message: string; }) {
constructor({ message }: { message: string }) {
super({
code: 'CONFLICTING_FILE_PATH',
meta: {},
message
message,
});
}
}
export class ConflictingPathSegment extends NowError<'CONFLICTING_PATH_SEGMENT', {}> {
constructor({ message }: { message: string; }) {
export class ConflictingPathSegment extends NowError<
'CONFLICTING_PATH_SEGMENT',
{}
> {
constructor({ message }: { message: string }) {
super({
code: 'CONFLICTING_PATH_SEGMENT',
meta: {},
message
message,
});
}
}
export class BuildError extends NowError<'BUILD_ERROR', {}> {
constructor({
message,
meta,
}: {
message: string;
meta: { entrypoint: string };
}) {
super({
code: 'BUILD_ERROR',
meta,
message,
});
}
}

View File

@@ -18,7 +18,10 @@ export default function handleError(
if ((<APIError>error).status === 403) {
console.error(
errorOutput('Authentication error. Run `now login` to log-in again.')
errorOutput(
error.message ||
'Authentication error. Run `now login` to log-in again.'
)
);
} else if ((<APIError>error).status === 429) {
// Rate limited: display the message from the server-side,

View File

@@ -1,5 +1,5 @@
import { homedir } from 'os';
import { resolve as resolvePath, join, basename } from 'path';
import { resolve as resolvePath } from 'path';
import EventEmitter from 'events';
import qs from 'querystring';
import { parse as parseUrl } from 'url';
@@ -7,24 +7,22 @@ import bytes from 'bytes';
import chalk from 'chalk';
import retry from 'async-retry';
import { parse as parseIni } from 'ini';
import { createReadStream } from 'fs';
import fs from 'fs-extra';
import ms from 'ms';
import fetch from 'node-fetch';
import { URLSearchParams } from 'url';
import {
staticFiles as getFiles,
npm as getNpmFiles,
docker as getDockerFiles
docker as getDockerFiles,
} from './get-files';
import Agent from './agent.ts';
import ua from './ua.ts';
import hash from './hash';
import processDeployment from './deploy/process-deployment.ts';
import highlight from './output/highlight';
import createOutput from './output';
import { responseError } from './error';
// How many concurrent HTTP/2 stream uploads
const MAX_CONCURRENT = 50;
import stamp from './output/stamp';
import { BuildError } from './errors-ts';
// Check if running windows
const IS_WIN = process.platform.startsWith('win');
@@ -39,14 +37,8 @@ export default class Now extends EventEmitter {
this._forceNew = forceNew;
this._output = createOutput({ debug });
this._apiUrl = apiUrl;
this._agent = new Agent(apiUrl, { debug });
this._onRetry = this._onRetry.bind(this);
this.currentTeam = currentTeam;
const closeAgent = () => {
this._agent.close();
process.removeListener('nowExit', closeAgent);
};
process.on('nowExit', closeAgent);
}
async create(
@@ -61,7 +53,6 @@ export default class Now extends EventEmitter {
nowConfig = {},
hasNowJson = false,
sessionAffinity = 'random',
isFile = false,
atlas = false,
// Latest
@@ -73,361 +64,150 @@ export default class Now extends EventEmitter {
quiet = false,
env,
build,
followSymlinks = true,
forceNew = false,
target = null
target = null,
deployStamp,
}
) {
const { log, warn, time } = this._output;
const opts = { output: this._output, hasNowJson };
const { log, warn, debug } = this._output;
const isBuilds = type === null;
let files = [];
let hashes = {};
const relatives = {};
let engines;
let deployment;
let requestBody = {};
await time('Getting files', async () => {
const opts = { output: this._output, hasNowJson };
if (isBuilds) {
requestBody = {
token: this._token,
teamId: this.currentTeam,
env,
build,
public: wantsPublic || nowConfig.public,
name,
project,
meta,
regions,
force: forceNew,
};
if (type === 'npm') {
files = await getNpmFiles(paths[0], pkg, nowConfig, opts);
if (target) {
requestBody.target = target;
}
} else if (type === 'npm') {
files = await getNpmFiles(paths[0], pkg, nowConfig, opts);
// A `start` or `now-start` npm script, or a `server.js` file
// in the root directory of the deployment are required
if (
!isBuilds &&
!hasNpmStart(pkg) &&
!hasFile(paths[0], files, 'server.js')
) {
const err = new Error(
'Missing `start` (or `now-start`) script in `package.json`. ' +
'See: https://docs.npmjs.com/cli/start'
);
throw err;
// A `start` or `now-start` npm script, or a `server.js` file
// in the root directory of the deployment are required
if (
!isBuilds &&
!hasNpmStart(pkg) &&
!hasFile(paths[0], files, 'server.js')
) {
const err = new Error(
'Missing `start` (or `now-start`) script in `package.json`. ' +
'See: https://docs.npmjs.com/cli/start'
);
throw err;
}
engines = nowConfig.engines || pkg.engines;
forwardNpm = forwardNpm || nowConfig.forwardNpm;
} else if (type === 'static') {
if (paths.length === 1) {
files = await getFiles(paths[0], nowConfig, opts);
} else {
if (!files) {
files = [];
}
engines = nowConfig.engines || pkg.engines;
forwardNpm = forwardNpm || nowConfig.forwardNpm;
} else if (type === 'static') {
if (isFile) {
files = [resolvePath(paths[0])];
} else if (paths.length === 1) {
files = await getFiles(paths[0], nowConfig, opts);
} else {
if (!files) {
files = [];
}
for (const path of paths) {
const list = await getFiles(path, {}, opts);
files = files.concat(list);
for (const path of paths) {
const list = await getFiles(path, {}, opts);
files = files.concat(list);
for (const file of list) {
relatives[file] = path;
}
}
}
} else if (type === 'docker') {
files = await getDockerFiles(paths[0], nowConfig, opts);
} else if (isBuilds) {
opts.isBuilds = isBuilds;
if (isFile) {
files = [resolvePath(paths[0])];
} else if (paths.length === 1) {
files = await getFiles(paths[0], {}, opts);
} else {
if (!files) {
files = [];
}
for (const path of paths) {
const list = await getFiles(path, {}, opts);
files = files.concat(list);
for (const file of list) {
relatives[file] = path;
}
for (const file of list) {
relatives[file] = path;
}
}
}
});
// Read `registry.npmjs.org` authToken from .npmrc
let authToken;
if (type === 'npm' && forwardNpm) {
authToken =
(await readAuthToken(paths[0])) || (await readAuthToken(homedir()));
} else if (type === 'docker') {
files = await getDockerFiles(paths[0], nowConfig, opts);
}
const hashes = await time('Computing hashes', () => {
const pkgDetails = Object.assign({ name }, pkg);
return hash(files, pkgDetails);
});
const uploadStamp = stamp();
this._files = hashes;
if (isBuilds) {
deployment = await processDeployment({
now: this,
debug,
hashes,
paths,
requestBody,
uploadStamp,
deployStamp,
quiet,
});
} else {
// Read `registry.npmjs.org` authToken from .npmrc
let authToken;
const deployment = await this.retry(async bail => {
// Flatten the array to contain files to sync where each nested input
// array has a group of files with the same sha but different path
const files = await time(
'Get files ready for deployment',
Promise.all(
Array.prototype.concat.apply(
[],
await Promise.all(
Array.from(this._files).map(async ([sha, { data, names }]) => {
const statFn = followSymlinks ? fs.stat : fs.lstat;
return names.map(async name => {
const getMode = async () => {
const st = await statFn(name);
return st.mode;
};
const mode = await getMode();
const multipleStatic = Object.keys(relatives).length !== 0;
let file;
if (isFile) {
file = basename(paths[0]);
} else if (multipleStatic) {
file = toRelative(name, join(relatives[name], '..'));
} else {
file = toRelative(name, paths[0]);
}
return {
sha,
size: data.length,
file,
mode
};
});
})
)
)
)
);
// This is a useful warning because it prevents people
// from getting confused about a deployment that renders 404.
if (
files.length === 0 ||
files.every(item => item.file.startsWith('.'))
) {
warn(
'There are no files (or only files starting with a dot) inside your deployment.'
);
if (type === 'npm' && forwardNpm) {
authToken =
(await readAuthToken(paths[0])) || (await readAuthToken(homedir()));
}
const queryProps = {};
const requestBody = isBuilds
? {
version: 2,
env,
build,
public: wantsPublic || nowConfig.public,
name,
project,
files,
meta,
regions
}
: {
env,
build,
meta,
public: wantsPublic || nowConfig.public,
forceNew,
name,
project,
description,
deploymentType: type,
registryAuthToken: authToken,
files,
engines,
scale,
sessionAffinity,
limits: nowConfig.limits,
atlas
};
requestBody = {
token: this._token,
teamId: this.currentTeam,
env,
build,
meta,
public: wantsPublic || nowConfig.public,
forceNew,
name,
project,
description,
deploymentType: type,
registryAuthToken: authToken,
engines,
scale,
sessionAffinity,
limits: nowConfig.limits,
atlas,
config: nowConfig,
};
if (Object.keys(nowConfig).length > 0) {
if (isBuilds) {
// These properties are only used inside Now CLI and
// are not supported on the API.
const exclude = ['github', 'scope'];
// Request properties that are made of a combination of
// command flags and config properties were already set
// earlier. Here, we are setting request properties that
// are purely made of their equally-named config property.
for (const key of Object.keys(nowConfig)) {
const value = nowConfig[key];
if (!requestBody[key] && !exclude.includes(key)) {
requestBody[key] = value;
}
}
} else {
requestBody.config = nowConfig;
}
}
if (isBuilds) {
if (forceNew) {
queryProps.forceNew = 1;
}
if (target) {
requestBody.target = target;
}
if (isFile) {
requestBody.routes = [
{
src: '/',
dest: `/${files[0].file}`
}
];
}
}
const query = qs.stringify(queryProps);
const version = isBuilds ? 'v9' : 'v4';
const res = await this._fetch(
`/${version}/now/deployments${query ? `?${query}` : ''}`,
{
method: 'POST',
body: requestBody
}
);
// No retry on 4xx
let body;
try {
body = await res.json();
} catch (err) {
throw new Error(
`Unexpected response error: ${err.message} (${
res.status
} status code)`
);
}
if (res.status === 429) {
if (body.error && body.error.code === 'builds_rate_limited') {
const err = new Error(body.error.message);
err.status = res.status;
err.retryAfter = 'never';
err.code = body.error.code;
return bail(err);
}
let msg = 'You have been creating deployments at a very fast pace. ';
if (body.error && body.error.limit && body.error.limit.reset) {
const { reset } = body.error.limit;
const difference = reset * 1000 - Date.now();
msg += `Please retry in ${ms(difference, { long: true })}.`;
} else {
msg += 'Please slow down.';
}
const err = new Error(msg);
err.status = res.status;
err.retryAfter = 'never';
return bail(err);
}
// If the deployment domain is missing a cert, bail with the error
if (
res.status === 400 &&
body.error &&
body.error.code === 'cert_missing'
) {
bail(await responseError(res, null, body));
}
if (
res.status === 400 &&
body.error &&
body.error.code === 'missing_files'
) {
return body;
}
if (res.status === 404 && body.error && body.error.code === 'not_found') {
return body;
}
if (res.status >= 400 && res.status < 500) {
const err = new Error();
if (body.error) {
const { code, unreferencedBuildSpecs } = body.error;
if (code === 'env_value_invalid_type') {
const { key } = body.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/env-value-invalid-type)';
} else if (code === 'unreferenced_build_specifications') {
const count = unreferencedBuildSpecs.length;
const prefix = count === 1 ? 'build' : 'builds';
err.message =
`You defined ${count} ${prefix} that did not match any source files (please ensure they are NOT defined in ${highlight(
'.nowignore'
)}):` +
`\n- ${unreferencedBuildSpecs
.map(item => JSON.stringify(item))
.join('\n- ')}`;
} else {
Object.assign(err, body.error);
}
} else {
err.message = 'Not able to create deployment';
}
return bail(err);
}
if (res.status !== 200) {
throw new Error(body.error.message);
}
for (const [name, value] of res.headers.entries()) {
if (name.startsWith('x-now-warning-')) {
this._output.warn(value);
}
}
return body;
});
deployment = await processDeployment({
legacy: true,
now: this,
debug,
hashes,
paths,
requestBody,
uploadStamp,
deployStamp,
quiet,
env,
});
}
// We report about files whose sizes are too big
let missingVersion = false;
if (deployment.warnings) {
if (deployment && deployment.warnings) {
let sizeExceeded = 0;
deployment.warnings.forEach(warning => {
if (warning.reason === 'size_limit_exceeded') {
const { sha, limit } = warning;
const n = hashes.get(sha).names.pop();
const n = hashes[sha].names.pop();
warn(`Skipping file ${n} (size exceeded ${bytes(limit)}`);
hashes.get(sha).names.unshift(n); // Move name (hack, if duplicate matches we report them in order)
hashes[sha].names.unshift(n); // Move name (hack, if duplicate matches we report them in order)
sizeExceeded++;
} else if (warning.reason === 'node_version_not_found') {
warn(`Requested node version ${warning.wanted} is not available`);
@@ -445,19 +225,10 @@ export default class Now extends EventEmitter {
}
}
if (deployment.error && deployment.error.code === 'missing_files') {
this._missing = deployment.error.missing || [];
this._fileCount = files.length;
return null;
}
if (!isBuilds && !quiet && type === 'npm' && deployment.nodeVersion) {
if (engines && engines.node && !missingVersion) {
log(
chalk`Using Node.js {bold ${
deployment.nodeVersion
}} (requested: {dim \`${engines.node}\`})`
chalk`Using Node.js {bold ${deployment.nodeVersion}} (requested: {dim \`${engines.node}\`})`
);
} else {
log(chalk`Using Node.js {bold ${deployment.nodeVersion}} (default)`);
@@ -472,81 +243,90 @@ export default class Now extends EventEmitter {
return deployment;
}
upload({ atlas = false, scale = {} } = {}) {
const { debug, time } = this._output;
debug(`Will upload ${this._missing.length} files`);
async handleDeploymentError(error, { hashes, env }) {
if (error.status === 429) {
if (error.code === 'builds_rate_limited') {
const err = new Error(error.message);
err.status = error.status;
err.retryAfter = 'never';
err.code = error.code;
this._agent.setConcurrency({
maxStreams: MAX_CONCURRENT,
capacity: this._missing.length
});
return err;
}
time(
'Uploading files',
Promise.all(
this._missing.map(sha =>
retry(
async bail => {
const file = this._files.get(sha);
const fPath = file.names[0];
const stream = createReadStream(fPath);
const { data } = file;
let msg = 'You have been creating deployments at a very fast pace. ';
const fstreamPush = stream.push;
if (error.limit && error.limit.reset) {
const { reset } = error.limit;
const difference = reset * 1000 - Date.now();
let uploadedSoFar = 0;
stream.push = chunk => {
// If we're about to push the last chunk, then don't do it here
// But instead, we'll "hang" the progress bar and do it on 200
if (chunk && uploadedSoFar + chunk.length < data.length) {
this.emit('uploadProgress', chunk.length);
uploadedSoFar += chunk.length;
}
return fstreamPush.call(stream, chunk);
};
msg += `Please retry in ${ms(difference, { long: true })}.`;
} else {
msg += 'Please slow down.';
}
const url = atlas ? '/v1/now/images' : '/v2/now/files';
const additionalHeaders = atlas
? {
'x-now-dcs': Object.keys(scale).join(',')
}
: {};
const res = await this._fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/octet-stream',
'x-now-digest': sha,
'x-now-size': data.length,
...additionalHeaders
},
body: stream
});
const err = new Error(msg);
if (res.status === 200) {
// What we want
this.emit('uploadProgress', file.data.length - uploadedSoFar);
this.emit('upload', file);
} else if (res.status > 200 && res.status < 500) {
// If something is wrong with our request, we don't retry
return bail(await responseError(res, `Failed to upload file with status: ${res.status}`));
} else {
// If something is wrong with the server, we retry
throw await responseError(res, 'Failed to upload file');
}
},
{
retries: 3,
randomize: true,
onRetry: this._onRetry
}
)
)
)
)
.then(() => {
this.emit('complete');
})
.catch(err => this.emit('error', err));
err.status = error.status;
err.retryAfter = 'never';
return err;
}
// If the deployment domain is missing a cert, bail with the error
if (error.status === 400 && error.code === 'cert_missing') {
return responseError(error, null, error);
}
if (error.status === 400 && error.code === 'missing_files') {
this._missing = error.missing || [];
this._fileCount = hashes.length;
return error;
}
if (error.status === 404 && error.code === 'not_found') {
return error;
}
if (error.status >= 400 && error.status < 500) {
const err = new Error();
const { code, unreferencedBuildSpecs } = error;
if (code === 'env_value_invalid_type') {
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)';
} else if (code === 'unreferenced_build_specifications') {
const count = unreferencedBuildSpecs.length;
const prefix = count === 1 ? 'build' : 'builds';
err.message =
`You defined ${count} ${prefix} that did not match any source files (please ensure they are NOT defined in ${highlight(
'.nowignore'
)}):` +
`\n- ${unreferencedBuildSpecs
.map(item => JSON.stringify(item))
.join('\n- ')}`;
} else {
Object.assign(err, error);
}
return err;
}
// Handle build errors
if (error.id && error.id.startsWith('bld_')) {
return new BuildError({
meta: {
entrypoint: error.entrypoint,
},
});
}
return new Error(error.message);
}
async listSecrets() {
@@ -589,7 +369,7 @@ export default class Now extends EventEmitter {
{
retries: 3,
minTimeout: 2500,
onRetry: this._onRetry
onRetry: this._onRetry,
}
);
};
@@ -647,7 +427,7 @@ export default class Now extends EventEmitter {
{
retries: 3,
minTimeout: 2500,
onRetry: this._onRetry
onRetry: this._onRetry,
}
);
@@ -727,7 +507,7 @@ export default class Now extends EventEmitter {
await this.retry(async bail => {
const res = await this._fetch(url, {
method: 'DELETE'
method: 'DELETE',
});
if (res.status === 200) {
@@ -748,7 +528,7 @@ export default class Now extends EventEmitter {
return retry(fn, {
retries,
maxTimeout,
onRetry: this._onRetry
onRetry: this._onRetry,
});
}
@@ -756,9 +536,7 @@ export default class Now extends EventEmitter {
this._output.debug(`Retrying: ${err}\n${err.stack}`);
}
close() {
this._agent.close();
}
close() {}
get id() {
return this._id;
@@ -802,14 +580,21 @@ export default class Now extends EventEmitter {
opts.headers = opts.headers || {};
opts.headers.accept = 'application/json';
opts.headers.authorization = `Bearer ${this._token}`;
opts.headers.Authorization = `Bearer ${this._token}`;
opts.headers['user-agent'] = ua;
if (
opts.body &&
typeof opts.body === 'object' &&
opts.body.constructor === Object
) {
opts.body = JSON.stringify(opts.body);
opts.headers['Content-Type'] = 'application/json';
}
return this._output.time(
`${opts.method || 'GET'} ${this._apiUrl}${_url} ${JSON.stringify(
opts.body
) || ''}`,
this._agent.fetch(_url, opts)
`${opts.method || 'GET'} ${this._apiUrl}${_url} ${opts.body || ''}`,
fetch(`${this._apiUrl}${_url}`, opts)
);
}
@@ -827,8 +612,8 @@ export default class Now extends EventEmitter {
opts = Object.assign({}, opts, {
body: JSON.stringify(opts.body),
headers: Object.assign({}, opts.headers, {
'Content-Type': 'application/json'
})
'Content-Type': 'application/json',
}),
});
}
const res = await this._fetch(url, opts);
@@ -875,6 +660,7 @@ function hasNpmStart(pkg) {
function hasFile(base, files, name) {
const relative = files.map(file => toRelative(file, base));
console.log(731, relative);
return relative.indexOf(name) !== -1;
}

View File

@@ -1,8 +1,9 @@
import { join } from 'path';
import { exists } from 'fs-extra';
import { PackageJson } from '@now/build-utils';
import Client from './client';
import { Config } from '../types';
import { Package } from './dev/types';
import { CantParseJSONFile, ProjectNotFound } from './errors-ts';
import getProjectByIdOrName from './projects/get-project-by-id-or-name';
@@ -26,14 +27,14 @@ export default async function preferV2Deployment({
hasServerfile,
pkg,
localConfig,
projectName
projectName,
}: {
client?: Client,
hasDockerfile: boolean,
hasServerfile: boolean,
pkg: Package | CantParseJSONFile | null,
localConfig: Config | undefined,
projectName?: string
client?: Client;
hasDockerfile: boolean;
hasServerfile: boolean;
pkg: PackageJson | CantParseJSONFile | null;
localConfig: Config | undefined;
projectName?: string;
}): Promise<null | string> {
if (localConfig && localConfig.version) {
// We will prefer anything that is set here
@@ -52,10 +53,14 @@ export default async function preferV2Deployment({
const { scripts = {} } = pkg;
if (!scripts.start && !scripts['now-start']) {
return `Deploying to Now 2.0, because ${highlight('package.json')} is missing a ${cmd('start')} script. ${INFO}`;
return `Deploying to Now 2.0, because ${highlight(
'package.json'
)} is missing a ${cmd('start')} script. ${INFO}`;
}
} else if (!pkg && !hasDockerfile) {
return `Deploying to Now 2.0, because no ${highlight('Dockerfile')} was found. ${INFO}`;
return `Deploying to Now 2.0, because no ${highlight(
'Dockerfile'
)} was found. ${INFO}`;
}
if (client && projectName) {

View File

@@ -2,10 +2,10 @@ import path from 'path';
import { CantParseJSONFile } from './errors-ts';
import readJSONFile from './read-json-file';
import { Config } from '../types';
import { Package } from './dev/types';
import { PackageJson } from '@now/build-utils';
interface CustomPackage extends Package {
now?: Config
interface CustomPackage extends PackageJson {
now?: Config;
}
export default async function readPackage(file?: string) {
@@ -16,8 +16,8 @@ export default async function readPackage(file?: string) {
return result;
}
if (result){
return result as CustomPackage
if (result) {
return result as CustomPackage;
}
return null;

View File

@@ -22,7 +22,7 @@ export default async (sentry, error, apiUrl, configFiles) => {
if (user) {
const spec = {
email: user.email,
id: user.uid
id: user.uid,
};
if (user.username) {
@@ -44,7 +44,7 @@ export default async (sentry, error, apiUrl, configFiles) => {
scope.setExtra('scopeError', {
name: scopeError.name,
message: scopeError.message,
stack: scopeError.stack
stack: scopeError.stack,
});
}
@@ -81,7 +81,8 @@ export default async (sentry, error, apiUrl, configFiles) => {
// Report information about the version of `node` being used
scope.setExtra('node', {
execPath: process.execPath,
version: process.version
version: process.version,
platform: process.platform,
});
sentry.captureException(error);

View File

@@ -1,4 +1,4 @@
import { Response } from 'fetch-h2';
import { Response } from 'node-fetch';
import { APIError } from './errors-ts';
export default async function responseError(

View File

@@ -1,5 +1,4 @@
import test from 'ava';
import { filterPackage } from '../src/util/dev/builder-cache';
test('[dev-builder] filter install "latest", cached canary', async t => {

View File

@@ -1,5 +1,4 @@
import test from 'ava';
import devRouter from '../src/util/dev/router';
test('[dev-router] 301 redirection', async t => {

View File

@@ -1,6 +1,8 @@
import url from 'url';
import test from 'ava';
import path from 'path';
import execa from 'execa';
import fs from 'fs-extra';
import fetch from 'node-fetch';
import listen from 'async-listen';
import { request, createServer } from 'http';
@@ -9,9 +11,20 @@ import DevServer from '../src/util/dev/server';
import { installBuilders, getBuildUtils } from '../src/util/dev/builder-cache';
import parseListen from '../src/util/dev/parse-listen';
async function runNpmInstall(fixturePath) {
if (await fs.exists(path.join(fixturePath, 'package.json'))) {
return execa('yarn', ['install'], { cwd: fixturePath });
}
}
function testFixture(name, fn) {
return async t => {
let server;
const fixturePath = path.join(__dirname, 'fixtures', 'unit', name);
await runNpmInstall(fixturePath);
try {
let readyResolve;
let readyPromise = new Promise(resolve => {
@@ -29,7 +42,6 @@ function testFixture(name, fn) {
origReady(msg);
};
const fixturePath = path.join(__dirname, `fixtures/unit/${name}`);
server = new DevServer(fixturePath, { output, debug });
await server.start(0);

View File

@@ -0,0 +1,8 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
moment@^2.24.0:
version "2.24.0"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b"
integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==

View File

@@ -14,37 +14,37 @@
},
"private": true,
"dependencies": {
"@angular/animations": "~8.1.0",
"@angular/common": "~8.1.0",
"@angular/compiler": "~8.1.0",
"@angular/core": "~8.1.0",
"@angular/forms": "~8.1.0",
"@angular/platform-browser": "~8.1.0",
"@angular/platform-browser-dynamic": "~8.1.0",
"@angular/router": "~8.1.0",
"rxjs": "~6.4.0",
"tslib": "^1.9.0",
"zone.js": "~0.9.1"
"@angular/animations": "8.1.0",
"@angular/common": "8.1.0",
"@angular/compiler": "8.1.0",
"@angular/core": "8.1.0",
"@angular/forms": "8.1.0",
"@angular/platform-browser": "8.1.0",
"@angular/platform-browser-dynamic": "8.1.0",
"@angular/router": "8.1.0",
"rxjs": "6.4.0",
"tslib": "1.9.0",
"zone.js": "0.9.1"
},
"devDependencies": {
"@angular-devkit/build-angular": "~0.801.0",
"@angular/cli": "~8.1.0",
"@angular/compiler-cli": "~8.1.0",
"@angular/language-service": "~8.1.0",
"@types/node": "~8.9.4",
"@types/jasmine": "~3.3.8",
"@types/jasminewd2": "~2.0.3",
"codelyzer": "^5.0.0",
"jasmine-core": "~3.4.0",
"jasmine-spec-reporter": "~4.2.1",
"karma": "~4.1.0",
"karma-chrome-launcher": "~2.2.0",
"karma-coverage-istanbul-reporter": "~2.0.1",
"karma-jasmine": "~2.0.1",
"karma-jasmine-html-reporter": "^1.4.0",
"protractor": "~5.4.0",
"ts-node": "~7.0.0",
"tslint": "~5.15.0",
"typescript": "~3.4.3"
"@angular-devkit/build-angular": "0.801.0",
"@angular/cli": "8.1.0",
"@angular/compiler-cli": "8.1.0",
"@angular/language-service": "8.1.0",
"@types/node": "8.9.4",
"@types/jasmine": "3.3.8",
"@types/jasminewd2": "2.0.3",
"codelyzer": "5.0.0",
"jasmine-core": "3.4.0",
"jasmine-spec-reporter": "4.2.1",
"karma": "4.1.0",
"karma-chrome-launcher": "2.2.0",
"karma-coverage-istanbul-reporter": "2.0.1",
"karma-jasmine": "2.0.1",
"karma-jasmine-html-reporter": "1.4.0",
"protractor": "5.4.0",
"ts-node": "7.0.0",
"tslint": "5.15.0",
"typescript": "3.4.3"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -34,3 +34,5 @@ node_modules
/public
/test/coverage-jest
/test/coverage-karma
!yarn.lock

View File

@@ -1,2 +1 @@
README.md
yarn.lock

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

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