Compare commits

...

112 Commits

Author SHA1 Message Date
JJ Kasper
e2ae497762 Publish Stable
- @now/next@2.5.2
2020-04-06 15:35:12 -05:00
JJ Kasper
89989719c2 Publish Canary
- @now/next@2.5.2-canary.0
 - @now/node@1.5.1-canary.0
 - @now/static-build@0.15.2-canary.3
2020-04-06 15:27:03 -05:00
Joe Haddad
8166b8e1e7 [now-next] Correctly Exclude API Routes from Pages (#4018)
This pull request correctly omits dependencies for API Routes from pages.
2020-04-06 20:19:08 +00:00
Logan McAnsh
1ceeac498c [now-node] Add NowApiHandler type (#4001)
* add NowApiHandler type

`now` equivalent of `NextApiHandler` introduced https://github.com/zeit/next.js/pull/10573

* chore: add fixture

Signed-off-by: Logan McAnsh <logan@mcan.sh>
2020-04-03 18:29:56 -04:00
Arunoda Susiripala
1c47d1360d [now-next] Fix some typos related to fixtures (#3995)
They should be `probes` I guess.
2020-04-03 13:43:22 +00:00
Leo Lamprecht
ddcd0918e9 Removed Environment Variables (#3997) 2020-04-03 01:52:02 +02:00
Steven
573b6b8110 [now-static-build] Fix 12-creact-react-app test fixture (#3990)
Since enabling `CI` environment variable for cloud builds, this test fails because it is meant to emit a warning however that warning has turned into an error.

```
05:40:53.148  Treating warnings as errors because process.env.CI = true.
05:40:53.148  Most CI servers set it automatically.
05:40:53.148  Failed to compile.
05:40:53.149  ./src/App.js
05:40:53.149    Line 1:  'useState' is defined but never used  no-unused-vars
05:40:53.172  error Command failed with exit code 1.
```

We can again treat lint errors as warnings by setting `CI=false`.
2020-04-01 14:27:11 +00:00
Steven
40039d7f9b Publish Canary
- @now/build-utils@2.2.1-canary.0
2020-03-31 17:18:32 -04:00
Steven
dcb37e92f5 [now-build-utils] Hide internal stack trace for errors (#3988)
Example build output given a user's build script named `shouldfail.js`:

## Before

```
/zeit/4af70cdc/shouldfail.js:3
throw new Error('This is my failure')
^
Error: This is my failure
    at Object.<anonymous> (/zeit/4af70cdc/shouldfail.js:3:7)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
    at internal/main/run_main_module.js:17:11
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Error: Exited with 1
    at ChildProcess.<anonymous> (/zeit/687b1c64/.build-utils/node_modules/@now/build-utils/dist/index.js:31350:24)
    at ChildProcess.emit (events.js:223:5)
    at ChildProcess.EventEmitter.emit (domain.js:475:20)
    at maybeClose (internal/child_process.js:1021:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:283:5)
worker exited with code 20 and signal null
Done with "package.json"
```

## After 

```
/zeit/255bfdd/shouldfail.js:3
throw new Error('This is my failure')
^
Error: This is my failure
    at Object.<anonymous> (/zeit/255bfdd/shouldfail.js:3:7)
    at Module._compile (internal/modules/cjs/loader.js:955:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:991:10)
    at Module.load (internal/modules/cjs/loader.js:811:32)
    at Function.Module._load (internal/modules/cjs/loader.js:723:14)
    at Function.Module.runMain (internal/modules/cjs/loader.js:1043:10)
    at internal/main/run_main_module.js:17:11
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Error: Command "yarn run build" exited with 1
worker exited with code 20 and signal null
Done with "package.json"
```
2020-03-31 21:09:57 +00:00
Steven
fe7f875549 Publish Canary
- now@17.1.2-canary.8
2020-03-31 12:20:59 -04:00
Steven
a516ed6fb8 [now-cli] Fix error message link to build logs (#3986)
The current error message prints a link that is not clickable from the terminal.

This PR adds the missing `https://` protocol prefix, so that the link is clickable.
2020-03-31 12:09:11 -04:00
Steven
ca2c5f85ef [now-cli] Fix for adding secret with hyphen prefix (#3983)
Follow up to #3982 which didn't actually fix the secret value. Instead it was adding `true` as the value.
2020-03-31 13:06:46 +00:00
Tim Neutkens
adb5a01cc0 Upgrade Next.js (#3984) 2020-03-31 12:24:21 +02:00
Steven
6b4d39ab4d Publish Canary
- now@17.1.2-canary.7
2020-03-30 18:27:55 -04:00
Steven
07ce3d2e34 [now-cli] Bump mri to 1.1.5 (#3982)
This fixes the error when attempting to add a secret with a hyphen and underscore such as the following:

```
$ now secret add name '-foo_bar'
Error! argv._.slice is not a function
```
2020-03-30 22:13:00 +00:00
JJ Kasper
93ffcf487b Publish Canary
- @now/routing-utils@1.8.1-canary.0
2020-03-30 14:18:01 -05:00
JJ Kasper
3631f0f4cf [now-routing-utils] Update to not add path segments to redirect query automatically (#3981)
As discussed this removes automatically adding path segments to redirect's destination query and only adds them if manually specified

x-ref: https://github.com/zeit/next.js/pull/11497
2020-03-30 18:57:24 +00:00
Steven
b67b5be8a9 Publish Canary
- now@17.1.2-canary.6
 - now-client@7.0.2-canary.2
 - @now/static-build@0.15.2-canary.2
2020-03-30 14:06:57 -04:00
Steven
bf67b1a29e [now-static-build][now-client] Ignore known static outputs (#3980)
We already ignore specific files such as `node_modules` and `.env` during the upload phase so these never make it to the build. However, if those files are generated during the build, that are still emitted.

This PR will ignore these specific files even if they end up in the output directory (for example, when the user assigns `outputDirectory='.'` in project settings)
2020-03-30 17:53:47 +00:00
Max Rovensky
ed86473f74 Publish Canary
- now@17.1.2-canary.5
 - now-client@7.0.2-canary.1
2020-03-30 17:57:56 +08:00
Max
399a3cd114 [now-cli][now-client] Change forceNewWithCache to withCache (#3966)
Follow up to https://github.com/zeit/now/pull/3953 that makes the flag composable
2020-03-30 09:51:05 +00:00
Steven
d0fd09810a Publish Stable
- @now/go@1.0.6
2020-03-28 18:33:40 -04:00
Steven
f298f2e894 Publish Canary
- @now/go@1.0.6-canary.0
2020-03-28 18:21:06 -04:00
Steven
569200ae0e [now-go] Fix import for go-bridge (#3976)
Somehow, PR #3973 broke Go since the bridge is imported from this repo's master branch.

Go has very strict file name constraints and the file `[...path].js` is not compatible.


Here's what a `@now/go` deployment error message looks like:

```
Error: Command failed: go mod tidy
go: finding github.com/zeit/now latest
go: downloading github.com/zeit/now v0.0.0-20200326223129-c91495338d5e
go: extracting github.com/zeit/now v0.0.0-20200326223129-c91495338d5e
-> unzip /tmp/5a0676f5/pkg/mod/cache/download/github.com/zeit/now/@v/v0.0.0-20200326223129-c91495338d5e.zip: malformed file path "packages/now-next/test/fixtures/22-ssg-v2-catchall/pages/[...path].js": double dot
handler imports
github.com/zeit/now/utils/go/bridge: unzip /tmp/5a0676f5/pkg/mod/cache/download/github.com/zeit/now/@v/v0.0.0-20200326223129-c91495338d5e.zip: malformed file path "packages/now-next/test/fixtures/22-ssg-v2-catchall/pages/[...path].js": double dot
```

The solution is to move Go Bridge into a separate repository: https://github.com/zeit/now-go-bridge

This will also have the side effect of speeding up Go imports because the repo will be much smaller.
2020-03-28 22:16:42 +00:00
Nathan Rajlich
c91495338d Update signal-exit to v3.0.3 (#3974)
@tootallnate's bug fix for `SIGHUB` on Windows has been merged and
published as `signal-exit@3.0.3`, so no more need for the "resolutions"
field in `package.json`.

The `yarn.lock` file has been updated accordingly.
2020-03-26 22:31:29 +00:00
JJ Kasper
7eed5574e0 Publish Stable
- @now/next@2.5.1
2020-03-26 16:12:48 -05:00
JJ Kasper
91e6b85cec Publish Canary
- @now/next@2.5.1-canary.0
 - @now/static-build@0.15.2-canary.1
2020-03-26 16:01:00 -05:00
JJ Kasper
3ae83172ec [now-next] Fix dynamic routes and data routes order (#3973)
When using a catch-all route at the base of the project it would cause it to be prioritized over any GS(S)P `/_next/data` routes. This fixes the order putting `/_next/data` routes first as they have higher specificity and adds tests to ensure we don't regress on this
2020-03-26 20:08:51 +00:00
Steven
7c51446e5e [tests] Add additional env vars (#3968)
These are used for testing and health checks.
2020-03-25 22:42:37 +00:00
Steven
400a5c73e8 [examples][now-static-build] Bump ionic-react to latest typescript (#3967)
Fixes an issue with a dependency that was bumped but typescript was pinned in `ionic-react`.


```
$ react-scripts build
Creating an optimized production build...
Failed to compile.
/zeit/333ecfab/node_modules/@types/testing-library__react/node_modules/pretty-format/build/index.d.ts
TypeScript error in /zeit/333ecfab/node_modules/@types/testing-library__react/node_modules/pretty-format/build/index.d.ts(7,13):
'=' expected.  TS1005
     5 |  * LICENSE file in the root directory of this source tree.
     6 |  */
  >  7 | import type * as PrettyFormat from './types';
       |             ^
     8 | /**
     9 |  * Returns a presentation string of your `val` object
    10 |  * @param val any potential JavaScript object
error Command failed with exit code 1.
```
2020-03-25 19:20:59 +00:00
Steven
ec917ace69 Publish Canary
- @now/frameworks@0.0.13-canary.0
 - now@17.1.2-canary.4
 - @now/static-build@0.15.2-canary.0
2020-03-25 13:41:04 -04:00
Anthony Gubler
f5e0afdd7e [examples] Add Dojo Example (#3882)
Adds an example for Dojo applications with ZEIT Now.

Co-Authored-By: Steven <steven@ceriously.com>
Co-Authored-By: Andy <AndyBitz@users.noreply.github.com>
2020-03-25 13:32:33 -04:00
Steven
c1b4c62714 [tests] Cancel previous workflows on push (#3965)
Follow up to #3961

Workflow IDs are found here: from https://api.github.com/repos/zeit/now/actions/workflows
2020-03-25 16:05:32 +00:00
Steven
5e4bdfbe11 [tests] Separate into workflows (#3961)
This PR does a few things:

- Separate tests into multiple workflows
- Rename a few package.json scripts to make naming consistent
- Rename workflows to be uppercase and jobs to be lowercase

The benefits here are:
- Restart a workflow if it fails, for example only restart `now dev` tests
- Easier to read when we need to understand a workflow or modify env vars

After merging, we'll need to modify the required checks in the repo settings.
We'll also need to update the cancel workflow (that will need to be a separate PR).
2020-03-25 11:40:11 -04:00
Andy Bitz
bd4a0cbd32 Publish Stable
- @now/frameworks@0.0.12
 - @now/static-build@0.15.1
2020-03-25 15:57:19 +01:00
Andy Bitz
7ff9adc90e Publish Canary
- @now/frameworks@0.0.12-canary.1
 - @now/static-build@0.15.1-canary.1
2020-03-25 15:56:44 +01:00
Andy
b279f1ffae [frameworks][now-static-build] Support Docusaurus v2 and v1 (#3964)
Support Docusaurus v2 and v1
2020-03-25 14:42:56 +00:00
Ana Trajkovska
344cc103ee Publish Canary
- now@17.1.2-canary.3
2020-03-25 14:11:11 +01:00
Ana Trajkovska
83249b3685 [now-cli] Add pagination for now alias ls (#3915)
* Implement pagination for `now alias ls`

* Fix issue retrieving aliases

* Add help text for pagiting aliases
2020-03-25 14:08:26 +01:00
Andy
79e7a9f477 [now-cli] Update docusaurus test (#3963) 2020-03-25 13:43:53 +01:00
Steven
b3dce70271 Publish Canary
- @now/frameworks@0.0.12-canary.0
 - now@17.1.2-canary.2
 - @now/static-build@0.15.1-canary.0
2020-03-24 19:24:57 -04:00
Steven
cff8d8b8a0 [tests] Fix test initialize existing directory --f -> -f (#3960)
Fixes test after PR #3958
2020-03-24 22:46:42 +00:00
Andy
da892100d9 [frameworks][now-static-build] Fix Docusaurus build command (#3959)
* [frameworks][now-static-build] Fix Docusaurus build command

* Update dev command
2020-03-24 23:03:31 +01:00
Max Leiter
72e87ee6e4 Fix slight spelling mistake: --f -> -f in now --force error (#3958) 2020-03-24 12:51:15 -07:00
Max Rovensky
3f9afad167 Publish Canary
- now@17.1.2-canary.1
 - now-client@7.0.2-canary.0
2020-03-25 03:12:23 +08:00
Max
1527447914 Add --force-with-cache flag support (#3953)
Adds support for an upcoming `forceNewWithCache` API flag
2020-03-24 19:09:10 +00:00
Steven
9ca35df5fb [tests] Fix coverage checks (#3957)
The CodeCov GitHub integration is confused about the monorepo and started reporting failures recently.

<img src="https://user-images.githubusercontent.com/229881/77462927-2983f280-6ddb-11ea-9ee2-38b660b2fd2f.png" height=120 />

We run `codecov` from the CLI so we can disable the integration. 

## References

- https://docs.codecov.io/docs/codecovyml-reference
- https://docs.codecov.io/docs/commit-status#section-disabling-a-status
2020-03-24 18:47:25 +00:00
Ana Trajkovska
05b2e2216c Publish Canary
- now@17.1.2-canary.0
2020-03-24 19:12:47 +01:00
Ana Trajkovska
167fd5750a [now-cli] Add pagination for now domains ls (#3922)
* Implement pagination for listing domains

* Add helpi list for paginating domains
2020-03-24 19:08:52 +01:00
Andy
4a3cd7ec72 [now-cli] Ignore 404 for aliases and certs when removing a domain (#3955) 2020-03-24 01:56:13 +01:00
Andy Bitz
9aef718917 Publish Stable
- now@17.1.1
2020-03-24 00:16:28 +01:00
Ana Trajkovska
3cdc261802 [now-cli] Fix broken message when a deployment is canceled (#3954)
* Fix broken message when a deployment is canceled

* Add \n in the message
2020-03-24 00:14:52 +01:00
Steven
5c71f672b3 Publish Stable
- @now/frameworks@0.0.11
 - @now/build-utils@2.2.0
 - @now/cgi@1.0.4
 - now@17.1.0
 - now-client@7.0.1
 - @now/go@1.0.5
 - @now/next@2.5.0
 - @now/node@1.5.0
 - @now/python@1.1.5
 - @now/routing-utils@1.8.0
 - @now/ruby@1.1.0
 - @now/static-build@0.15.0
2020-03-23 13:59:31 -04:00
Steven
dbc5f73984 Publish Canary
- now@17.0.5-canary.15
2020-03-23 11:03:05 -04:00
Steven
1d269fffc8 [now-cli] Fix ambiguous argument error (#3952)
This updates the error message to offer action items when an ambiguous argument is provided.

## Before

```
Error! The supplied argument "secrets" is ambiguous. Both a directory and a subcommand are known 
```

## After

```
Error! The supplied argument "secrets" is ambiguous.
If you wish to deploy the subdirectory "secrets", first run "cd secrets".
If you wish to use the subcommand "secrets", use "secret" instead.
```
2020-03-23 14:57:59 +00:00
Ana Trajkovska
cc146ba0f5 Publish Canary
- now@17.0.5-canary.14
2020-03-23 00:24:37 +01:00
Ana Trajkovska
f8a2519838 Add help text for paginating deployments for a project (#3948) 2020-03-23 00:21:47 +01:00
Steven
1781376d47 Publish Canary
- @now/build-utils@2.1.2-canary.3
 - @now/ruby@1.0.3-canary.4
 - @now/static-build@0.14.13-canary.6
2020-03-20 15:04:52 -04:00
Steven
d9fda14969 [now-ruby] Upgrade to Ruby 2.7 (#3872)
- Change default version to Ruby `2.7.x` to match our static builds such as jekyll
- Detect ruby version in `Gemfile` in case the user wishes to downgrade to Ruby `2.5.x`
- Print nicer error message in `now dev`

cc @nathancahill @m5o
2020-03-20 18:54:57 +00:00
Steven
a4de9272e7 [now-static-build] Add test for puppeteer during build (#3911)
We recently updated the build image to add the necessary dependencies so that `puppeteer` can run during the build step.

This PR adds a test that takes a screenshot and prints metrics during a static build.

This is necessary to support `react-snap` (along with a few flags in `package.json`).

```json
{
  "reactSnap": {
    "puppeteerArgs": [
      "--no-sandbox",
      "--disable-setuid-sandbox"
    ]
  }
}
```

- Fixes https://github.com/zeit/now-builders/issues/517
- Fixes #2357
2020-03-20 11:54:51 -04:00
Andy Bitz
9b9037de91 Publish Canary
- @now/build-utils@2.1.2-canary.2
 - @now/next@2.4.1-canary.4
 - @now/static-build@0.14.13-canary.5
2020-03-20 15:37:07 +01:00
Andy
8d18c65e3e [now-next][now-static-build][now-build-utils] Use util to get node .bin in path (#3946)
https://zeit.atlassian.net/browse/PRODUCT-1380

This makes `now-next` consider the `node_modules/.bin` path if a custom build command was specified, which makes it work like `now-static-build`.
2020-03-20 14:31:53 +00:00
Ana Trajkovska
e7d7de61b6 Publish Canary
- now@17.0.5-canary.13
 - @now/next@2.4.1-canary.3
2020-03-20 13:04:29 +01:00
Ana Trajkovska
11927883c3 Fix pagination on now ls project (#3945) 2020-03-20 13:03:03 +01:00
Andy
57d25b184b [now-next] Add support for the outputDirectory option (#3897)
* [now-next] Add support for the outputDirectory option

* Add test

* Remove build command

* Remove check

* Add build command

* Rename directory

* Rename

* Fix test and output directory
2020-03-20 11:42:54 +01:00
Steven
95f716fb3f Publish Canary
- now@17.0.5-canary.12
 - @now/next@2.4.1-canary.2
2020-03-19 16:55:36 -04:00
Steven
8dd52605be [now-cli] Print link to more details on error (#3944)
This PR updates API Errors to support the `error.link` property.

Unlike `error.slug` which is only a path to an error message, `error.link` contains the full URL.


### Example Output

```
$ now
Error! Serverless Functions.........etc
> More details: https://zeit.ink/...etc
```
2020-03-19 20:49:57 +00:00
JJ Kasper
4b9c6a2a2a [now-next] Make sure to set 404 status for /404 route itself (#3924)
As discussed this makes sure to set the `404` status on the `/404` path itself
2020-03-19 18:24:20 +00:00
Steven
17f92a5ad3 Publish Canary
- now@17.0.5-canary.11
2020-03-19 13:59:08 -04:00
Ana Trajkovska
0aab7cc509 Fix error on now ls (#3942)
Co-authored-by: Leo Lamprecht <leo@zeit.co>
2020-03-19 18:45:24 +01:00
Steven
b39622b271 [tests] Fix publish job environment variables (#3943) 2020-03-19 18:44:59 +01:00
Ana Trajkovska
1e9aeee8e9 Publish Canary
- now@17.0.5-canary.10
2020-03-19 17:37:56 +01:00
Ana Trajkovska
49fac0dfad Paginate listing deployments for a project (#3933) 2020-03-19 17:21:13 +01:00
Steven
a668df829f Publish Canary
- @now/build-utils@2.1.2-canary.1
 - now@17.0.5-canary.9
 - now-client@7.0.1-canary.4
 - @now/static-build@0.14.13-canary.4
2020-03-19 10:30:33 -04:00
Steven
3d4ef1f825 [now-cli][now-client] Revert major version per #3939 2020-03-19 10:30:07 -04:00
Steven
f986daa1cc [now-client] Fix lint error: forbidden non-null assertion (#3941)
Fixes the following lint error: `Forbidden non-null assertion`.

<img src="https://user-images.githubusercontent.com/229881/77072131-98b8ab80-69c3-11ea-84f5-e45be43951f9.png" height=200 />

I realized this logic was somewhat brittle because it relied on `/` path separators so I switched it to use the native file name function `basename()` to determine if a file begins with a dot.
2020-03-19 13:44:51 +00:00
Steven
549c8777ba [tests] Fix test retry and allow local token (#3940)
This PR updates the way we run integration tests (the ones that create test deployments) so that it will be less likely to fail. 

A couple side effects to this PR:

- To run the tests locally, you must set `NOW_TOKEN` env var (can be found in `~/.now/auth.json`).
- PRs from forked repos won't run tests because they now rely on a secret in GH Actions.
- A couple alias tests that require certs need to be disabled because they will fail.

[PRODUCT-2093]

[PRODUCT-2093]: https://zeit.atlassian.net/browse/PRODUCT-2093
2020-03-19 13:08:46 +00:00
Andy
51d7242fda Revert "[now-cli][now-client] (Major) Remove legacy code (#3840)" (#3939)
* Revert "[now-cli][now-client] (Major) Remove legacy code (#3840)"

* Remove get

* Add projectId to .now/project.json
2020-03-19 00:16:51 +01:00
Nathan Rajlich
36db0e5bab [now-cli] Catch process.kill() for dev process and mute "ESRCH" (#3927)
"ESRCH" error means that the process is no longer running, and thus
already shut down. No need to throw in that case so just ignore the
error.

Fixes: https://sentry.io/organizations/zeithq/issues/1568104652

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2020-03-18 13:49:22 -07:00
Steven
99368b4248 [all] Fix test fixture pkg names and increase retry (#3935)
Fixes test warnings from `jest-hast-map`:

```
[now-static-build] Running yarn test-integration-once
$ jest --env node --verbose --runInBand test/integration.test.js
jest-haste-map: Haste module naming collision: 12-create-react-app
  The following files share their name; please adjust your hasteImpl:
    * <rootDir>/test/fixtures/12-create-react-app/package.json
    * <rootDir>/test/fixtures/26-ejected-cra/package.json

jest-haste-map: Haste module naming collision: gatsby-starter-default
  The following files share their name; please adjust your hasteImpl:
    * <rootDir>/test/fixtures/10-gatsby/package.json
    * <rootDir>/test/fixtures/10-gatsby-without-build-script/package.json

jest-haste-map: Haste module naming collision: gohugo-default-theme
  The following files share their name; please adjust your hasteImpl:
    * <rootDir>/test/fixtures/31-hugo/themes/ananke/package.json
    * <rootDir>/test/fixtures/46-hugo-with-framework/themes/ananke/package.json

jest-haste-map: Haste module naming collision: gohugo-default-styles
  The following files share their name; please adjust your hasteImpl:
    * <rootDir>/test/fixtures/31-hugo/themes/ananke/src/package.json
    * <rootDir>/test/fixtures/46-hugo-with-framework/themes/ananke/src/package.json

jest-haste-map: Haste module naming collision: 47-nuxt-with-custom-output
  The following files share their name; please adjust your hasteImpl:
    * <rootDir>/test/fixtures/47-nuxt-with-custom-output/package.json
    * <rootDir>/test/fixtures/48-nuxt-without-framework/package.json
```

Also increased test retry to 5.
2020-03-18 16:37:19 -04:00
Andy Bitz
95daf0e292 Publish Canary
- @now/frameworks@0.0.11-canary.2
 - now@18.0.0-canary.12
 - @now/static-build@0.14.13-canary.3
2020-03-18 12:53:21 +01:00
Andy
8bfa9c1a42 [now-cli] Fix ID check for orgs (#3934)
* [now-cli] Fix ID check for orgs

* Validate project settings

* Fix check
2020-03-18 12:51:52 +01:00
Shu Uesugi
4208dc0466 Add missing websites to frameworks (#3814) 2020-03-18 00:08:07 +01:00
Leo Lamprecht
00ae011b95 Use correct frameworks endpoint (#3932) 2020-03-17 23:02:30 +01:00
Andy
a770991a81 [now-cli] Restore now alias <domain> (#3910)
* [now-cli] Restore `now alias <domain>`

* Fix test

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2020-03-17 22:57:02 +01:00
Leo Lamprecht
f80a6d6392 Add support for /api/v1/frameworks to the framework API (#3931)
* Add support for `/api/v1/frameworks` to the framework API

* Update now.json

* Add another rewrite

Co-authored-by: Andy <AndyBitz@users.noreply.github.com>
Co-authored-by: Andy Bitz <artzbitz@gmail.com>
2020-03-17 22:37:38 +01:00
Andy
30777384ec Revert "Rewrite all paths to frameworks API (#3929)" (#3930)
This reverts commit ff18788b20.
2020-03-17 22:13:06 +01:00
Yamagishi Kazutoshi
0c719b7f6a [now-static-build] Add defaultRoutes for docusaurus v2 (#3909)
Add a default router for Docusaurus v2 to add strong asset caching and 404 page fallback.
2020-03-17 17:12:06 -04:00
Leo Lamprecht
ff18788b20 Rewrite all paths to frameworks API (#3929) 2020-03-17 22:11:22 +01:00
Steven
752ab39787 Publish Canary
- @now/frameworks@0.0.11-canary.1
 - now@18.0.0-canary.11
 - @now/static-build@0.14.13-canary.2
2020-03-17 16:33:13 -04:00
Steven
c1df8c8bd1 [now-static-build] Update error message to mention project settings (#3926)
This PR improves the error message to make it actionable.

The docs will be updated in https://github.com/zeit/docs/pull/1661 with even more detail.
2020-03-17 16:29:43 -04:00
Andy
25fd1df35d [frameworks] Adjust placeholder for build command (#3928) 2020-03-17 20:31:19 +01:00
Steven
d32ab1e0d9 [examples] Update jekyll and middleman to use bundler 2.1.4 (#3923)
These examples were using an old version of Bundler which didn't match our tests and would fail with:

```
/ruby27/lib/ruby/2.7.0/rubygems.rb:275:in `find_spec_for_exe': Could not find 'bundler' (1.17.2) required by your /zeit/6f4b9e46/Gemfile.lock. (Gem::GemNotFoundException)
To update to the latest version installed on your system, run `bundle update --bundler`.
To install the missing version, run `gem install bundler:1.17.2`
	from /ruby27/lib/ruby/2.7.0/rubygems.rb:294:in `activate_bin_path'
	from /ruby27/bin/bundle:23:in `<main>'
```

I ran `bundle update --bundler` in each of these directories and it only updated the version in `Gemfile.lock` because 2.x is mostly backwards compatible.
2020-03-17 11:54:20 -04:00
Steven
a69c460760 [now-cli] Fix test for username (#3916)
We renamed the CI Bot so this will use the name from the context rather than hardcoding the name.
2020-03-17 11:23:21 -04:00
Andy
b985853f15 [frameworks] Remove quotes from placeholder (#3921) 2020-03-17 15:37:24 +01:00
Andy
94e607a93a [frameworks] Fix more placeholders (#3920)
* [frameworks] Fix order in build placeholder

* [frameworks] Adjust order for more frameworks
2020-03-17 15:31:01 +01:00
Andy
f97a81fa14 [frameworks] Fix order in build placeholder (#3918) 2020-03-17 15:20:47 +01:00
Andy
6e28438eb4 [frameworks] Change build placeholder (#3917) 2020-03-17 15:08:28 +01:00
Shu Ding
8fcdf3f458 improve brunch example (#3906) 2020-03-17 00:33:08 +08:00
dependabot[bot]
dbf0cc3562 Bump acorn from 5.7.3 to 5.7.4 (#3913)
Bumps [acorn](https://github.com/acornjs/acorn) from 5.7.3 to 5.7.4.
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/5.7.3...5.7.4)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-03-15 11:55:13 +01:00
Steven
27ccfa7e7a Publish Canary
- now@18.0.0-canary.10
2020-03-13 14:22:52 -04:00
Steven
f37edbc670 [now-cli] Fix invalid token error message during project link (#3907)
This PR improves the error message and prevents "An unexpected error occurred" when the token is invalid during a project link step.

I also added the `--token` option to `now dev --help` .

Lastly, I updated `now logout` to work correctly when the token is invalid.

- Fixes #3772 
- Fixes #3786
2020-03-13 00:10:11 +00:00
JJ Kasper
b7943e83d2 Publish Canary
- @now/next@2.4.1-canary.1
 - @now/routing-utils@1.7.1-canary.1
2020-03-12 11:45:18 -05:00
JJ Kasper
300ed5b952 [now-next] Implement new handles for custom routes (#3892)
This implements the new handles from https://github.com/zeit/now/pull/3876 to allow us to ensure the proper order for `rewrites`, `redirects`, and `headers` in Next.js. I also added in the tests from the Next.js [custom-routes test suite](https://github.com/zeit/next.js/tree/canary/test/integration/custom-routes) to ensure we're matching behavior. 

To help keep track of what each probe is testing I added support for parsing the `now.json` files in `testDeployment` as [JSON5](https://www.npmjs.com/package/json5) to allow adding comments before each probe. If this is undesired I can remove this specific change even though it makes managing the fixture tests much easier
2020-03-12 03:18:33 +00:00
Andy Bitz
9e6ebfb3ec Publish Canary
- now@18.0.0-canary.9
2020-03-11 23:02:30 +01:00
Andy
f49620790c [now-cli] Proper error message when now alias misses arguments (#3904)
We need to show a proper error message when `now alias` misses arguments.
2020-03-11 21:57:02 +00:00
Steven
84065688b5 Publish Canary
- now@18.0.0-canary.8
2020-03-11 16:15:11 -04:00
Steven
5a1012fb0f [now-cli] Prevent framework from clearing console in now dev (#3903)
When running a framework like Create React App or Gridsome, the console gets cleared. This prevented the user from seeing the message printed from `now dev` which is typically `http://localhost:3000`. Instead the user would see the framework's URL such as `http://localhost:54684`.

See #3497 for an example.

The solution is to change the child process to pipe stdout/stderr. Since most frameworks detect [`process.stdout.isTTY`](7e6d6cd05f/packages/react-scripts/scripts/start.js (L141-L143)) before clearing the console, this will solve the problem. I was also able to intercept stdout to replace the framework's port with the `now dev` port and I think this will also help prevent confusion.

I also had to set `FORCE_COLOR=1` to avoid losing ANSI colors.

- Related to https://github.com/facebook/create-react-app/issues/2495
- Fixes #3497
2020-03-11 16:11:51 -04:00
Nathan Rajlich
4b6143c293 [now-cli] Remove "Serving all files as static" message (#3901) 2020-03-11 13:03:16 +00:00
Mark Glagola
b6601b0d9a Publish Canary
- now@18.0.0-canary.7
2020-03-10 13:59:46 -05:00
Mark Glagola
2870a1dd49 Fix setup-domain to use aliasDomain for gets (#3871) 2020-03-10 13:35:50 -05:00
Steven
6249f7e293 [now-cli] Change suggestion for rootDirectory to ./ (#3899)
When we ask the question "In which directory is your code located?" we were displaying a prefix  of `cwd/` which is confusing because it seems like you are supposed to type in the current directory. It also doesn't match what is displayed in the Project Settings after it is deployed.

This changes the prefix to `./` so that `rootDirectory` is set to the current directory and the user can type in a subdirectory if they wish such as `./packages/web` for example.

### Before

```
? Set up and deploy “~/Code/app”? [Y/n] y
? Which scope do you want to deploy to? Testing
? Link to existing project? [y/N] n
? What’s your project’s name? app
? In which directory is your code located? app/
```

### After

```
? Set up and deploy “~/Code/app”? [Y/n] y
? Which scope do you want to deploy to? Testing
? Link to existing project? [y/N] n
? What’s your project’s name? app
? In which directory is your code located? ./
```
2020-03-10 10:50:50 -04:00
394 changed files with 30365 additions and 3729 deletions

View File

@@ -1,7 +1,7 @@
name: Cancel
on:
push:
branches:
branches:
- '*'
- '!master'
@@ -11,8 +11,8 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 3
steps:
- uses: styfle/cancel-workflow-action@0.2.0
- uses: styfle/cancel-workflow-action@0.3.1
with:
workflow_id: 435869
workflow_id: 849295, 849296, 849297, 849298
access_token: ${{ secrets.GITHUB_WORKFLOW_TOKEN }}

View File

@@ -1,111 +0,0 @@
name: CI
on:
push:
branches:
- master
tags:
- '!*'
pull_request:
jobs:
test-unit:
name: Unit Tests
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: [10, 12]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- run: git fetch origin master --depth=10
- run: git fetch origin ${{ github.ref }} --depth=10
- uses: actions/setup-node@v1
- run: yarn install
- run: yarn run build
- run: yarn run test-lint
- run: yarn run test-unit --clean false
- name: Upload Artifact
if: matrix.os == 'ubuntu-latest' && matrix.node == 12 # only run once
uses: actions/upload-artifact@v1
with:
name: test-unit-output
path: packages/now-cli/.nyc_output
test-integration:
name: Integration Tests
timeout-minutes: 120
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: git fetch origin master --depth=10
- run: git fetch origin ${{ github.ref }} --depth=10
- run: yarn install
- run: yarn run build
- run: yarn test-integration-once --clean false
test-now-cli:
name: Now CLI Tests
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
node: [10, 12]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- run: git fetch origin master --depth=10
- run: git fetch origin ${{ github.ref }} --depth=10
- name: Install Hugo
if: matrix.os == 'macos-latest'
run: curl -L -O https://github.com/gohugoio/hugo/releases/download/v0.56.0/hugo_0.56.0_macOS-64bit.tar.gz && tar -xzf hugo_0.56.0_macOS-64bit.tar.gz && mv ./hugo packages/now-cli/test/dev/fixtures/08-hugo/
- run: yarn install
- run: yarn run build
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- run: yarn test-integration --clean false
test-now-dev:
name: "`now dev` Tests"
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
node: [10, 12]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- run: git fetch origin master --depth=10
- run: git fetch origin ${{ github.ref }} --depth=10
- name: Install Hugo
if: matrix.os == 'macos-latest'
run: curl -L -O https://github.com/gohugoio/hugo/releases/download/v0.56.0/hugo_0.56.0_macOS-64bit.tar.gz && tar -xzf hugo_0.56.0_macOS-64bit.tar.gz && mv ./hugo packages/now-cli/test/dev/fixtures/08-hugo/
- run: yarn install
- run: yarn run build
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- run: yarn test-integration-now-dev --clean false
coverage:
name: Coverage
timeout-minutes: 5
needs: [test-unit, test-now-cli, test-now-dev, test-integration]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: git fetch origin master --depth=10
- run: git fetch origin ${{ github.ref }} --depth=10
- uses: actions/download-artifact@v1
with:
name: test-unit-output
path: packages/now-cli/.nyc_output
- run: yarn install
- run: yarn workspace now run coverage
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -27,3 +27,5 @@ jobs:
run: yarn publish-from-github
env:
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
GA_TRACKING_ID: ${{ secrets.GA_TRACKING_ID }}
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}

View File

@@ -0,0 +1,36 @@
name: CLI
on:
push:
branches:
- master
tags:
- '!*'
pull_request:
jobs:
test:
name: CLI
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
node: [10, 12]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- run: git fetch origin master --depth=10
- run: git fetch origin ${{ github.ref }} --depth=10
- name: Install Hugo
if: matrix.os == 'macos-latest'
run: curl -L -O https://github.com/gohugoio/hugo/releases/download/v0.56.0/hugo_0.56.0_macOS-64bit.tar.gz && tar -xzf hugo_0.56.0_macOS-64bit.tar.gz && mv ./hugo packages/now-cli/test/dev/fixtures/08-hugo/
- run: yarn install
- run: yarn run build
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- run: yarn test-integration-cli --clean false
env:
ZEIT_TEAM_TOKEN: ${{ secrets.ZEIT_TEAM_TOKEN }}
ZEIT_REGISTRATION_URL: ${{ secrets.ZEIT_REGISTRATION_URL }}

View File

@@ -0,0 +1,33 @@
name: Dev
on:
push:
branches:
- master
tags:
- '!*'
pull_request:
jobs:
test:
name: Dev
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
node: [10, 12]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- run: git fetch origin master --depth=10
- run: git fetch origin ${{ github.ref }} --depth=10
- name: Install Hugo
if: matrix.os == 'macos-latest'
run: curl -L -O https://github.com/gohugoio/hugo/releases/download/v0.56.0/hugo_0.56.0_macOS-64bit.tar.gz && tar -xzf hugo_0.56.0_macOS-64bit.tar.gz && mv ./hugo packages/now-cli/test/dev/fixtures/08-hugo/
- run: yarn install
- run: yarn run build
- uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node }}
- run: yarn test-integration-dev --clean false

View File

@@ -0,0 +1,25 @@
name: E2E
on:
push:
branches:
- master
tags:
- '!*'
pull_request:
jobs:
test:
name: E2E
timeout-minutes: 120
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: git fetch origin master --depth=10
- run: git fetch origin ${{ github.ref }} --depth=10
- run: yarn install
- run: yarn run build
- run: yarn test-integration-once --clean false
env:
ZEIT_TEAM_TOKEN: ${{ secrets.ZEIT_TEAM_TOKEN }}
ZEIT_REGISTRATION_URL: ${{ secrets.ZEIT_REGISTRATION_URL }}

33
.github/workflows/test-unit.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
name: Unit
on:
push:
branches:
- master
tags:
- '!*'
pull_request:
jobs:
test:
name: Unit
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: [10, 12]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v2
- run: git fetch origin master --depth=10
- run: git fetch origin ${{ github.ref }} --depth=10
- uses: actions/setup-node@v1
- run: yarn install
- run: yarn run build
- run: yarn run test-lint
- run: yarn run test-unit --clean false
- run: yarn workspace now run coverage
if: matrix.os == 'ubuntu-latest' && matrix.node == 12 # only run once
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

8
codecov.yml Normal file
View File

@@ -0,0 +1,8 @@
codecov:
require_ci_to_pass: yes
coverage:
status:
project: off
patch: off

View File

@@ -0,0 +1,115 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 17.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="256px" height="256px" viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve">
<rect x="65" y="68" fill="#7C7C7C" width="127" height="124"/>
<rect x="83.392" y="22.163" transform="matrix(-0.7071 0.7071 -0.7071 -0.7071 266.9294 23.9747)" fill="#86AD8A" width="90.215" height="90.215"/>
<path fill="#FFFFFF" d="M117.601,167.637c3.788-11.191,5.795-45.647,4.728-62.795c-0.128-2.057-0.333-4.445-0.692-6.351
c-0.112-0.607-0.244-1.168-0.391-1.651c0-6.672,0-62.892,0-67.02c0-5.717,5.242-8.419,10.166,4.128
c4.925,12.547,3.495,57.175,3.495,60.348c0,0.673-0.611,1.469-1.57,2.25c-0.383,0.247-0.73,0.499-1.051,0.754
c-2.949,2.366-3.379,5.095-3.533,7.542c-1.067,17.148-1.554,51.604,2.234,62.795c4.438,13.112-4.004,14.759-6.691,14.759
C121.605,182.395,113.163,180.748,117.601,167.637z"/>
<path fill="#FFFFFF" d="M103.019,47.413c-0.472,0.049-1.062,9.387-1.257,16.131c-0.238,8.194-0.607,15.482-2.908,15.482
c-1.728,0-2.8-2.853-2.517-10.094c0.407-10.427,0.395-21.519-0.219-21.519c-0.774,0-4.358,22.999-4.358,31.09
c0,5.803,2.487,11.269,5.603,14.115c0.01,0.008,0.019,0.019,0.033,0.027c0.093,0.081,0.191,0.166,0.278,0.247
c0.005,0.004,0.01,0.004,0.01,0.008c2.252,2.053,2.819,4.283,2.971,6.32c1.286,17.143-1.128,59.614-5.678,70.804
c-5.33,13.108,4.811,14.759,8.042,14.759c3.227,0,13.368-1.651,8.037-14.759c-4.55-11.191-6.96-53.661-5.678-70.804
c0.153-2.037,0.719-4.267,2.971-6.32c0-0.004,0.005-0.004,0.01-0.008c0.088-0.081,0.185-0.166,0.278-0.247
c0.014-0.008,0.023-0.019,0.033-0.027c3.116-2.845,5.764-8.314,5.604-14.115c-0.635-23.017-3.263-31.09-4.037-31.09
c-0.614,0-0.613,12.286-0.438,21.024c0.143,7.158-0.471,10.383-2.49,10.383c-1.923,0-2.504-6.972-2.748-15.368
c-0.196-6.762-0.804-16.039-1.54-16.039"/>
<path fill="#FFFFFF" d="M154.075,179.591c-2.546,0-10.532-1.562-6.332-13.967c3.585-10.59,5.483-50.779,4.474-67.007
c-0.051-0.826-0.256-1.664-0.413-2.55c-0.443-2.504-3.543-4.555-5.338-6.356c-3.486-3.498-5.725-9.38-5.725-16.013
c0-10.77,5.97-24.4,13.334-24.4c7.364,0,13.334,13.63,13.334,24.4c0,6.633-2.24,12.515-5.725,16.013
c-1.795,1.801-4.895,3.852-5.338,6.356c-0.157,0.886-0.361,1.724-0.413,2.55c-1.01,16.227,0.889,56.416,4.474,67.007
C164.607,178.03,156.621,179.591,154.075,179.591z"/>
<polyline fill="#CECCAE" points="65,68 65,192 192,192 "/>
<polygon fill="#3F894A" points="65,191.835 65,253 192,253 192,191.835 192,66.938 "/>
<g>
<g>
<line fill="none" stroke="#FFFFFF" stroke-width="0.5" stroke-miterlimit="10" x1="191.658" y1="82.55" x2="190.946" y2="83.253"/>
<line fill="none" stroke="#FFFFFF" stroke-width="0.5" stroke-miterlimit="10" stroke-dasharray="2.02,2.02" x1="189.509" y1="84.672" x2="66.629" y2="206.035"/>
<line fill="none" stroke="#FFFFFF" stroke-width="0.5" stroke-miterlimit="10" x1="65.91" y1="206.745" x2="65.199" y2="207.448"/>
</g>
</g>
<g>
<path fill="#FFFFFF" d="M85.353,211.117h6.328c0.827,0,1.665,0.067,2.513,0.201c0.848,0.135,1.608,0.414,2.28,0.838
c0.672,0.424,1.22,1.014,1.644,1.768c0.424,0.756,0.636,1.753,0.636,2.994c0,1.116-0.331,2.089-0.993,2.916
c-0.662,0.827-1.644,1.376-2.947,1.645v0.062c0.724,0.062,1.385,0.232,1.985,0.512c0.6,0.279,1.117,0.651,1.551,1.117
c0.434,0.465,0.77,1.019,1.008,1.659c0.238,0.642,0.357,1.345,0.357,2.109c0,1.262-0.243,2.291-0.729,3.087
c-0.486,0.797-1.097,1.422-1.83,1.877c-0.734,0.455-1.531,0.766-2.389,0.931c-0.858,0.166-1.66,0.248-2.404,0.248h-7.011V211.117z
M87.4,220.609h4.25c1.055,0,1.913-0.129,2.575-0.388c0.662-0.259,1.179-0.574,1.551-0.946c0.373-0.372,0.621-0.771,0.745-1.194
s0.186-0.812,0.186-1.163c0-0.765-0.129-1.401-0.388-1.908c-0.259-0.506-0.605-0.909-1.039-1.21
c-0.435-0.299-0.941-0.512-1.52-0.636c-0.579-0.124-1.189-0.186-1.831-0.186H87.4V220.609z M87.4,231.219h4.684
c1.199,0,2.166-0.145,2.9-0.435c0.734-0.289,1.298-0.651,1.691-1.085c0.393-0.435,0.656-0.895,0.791-1.381
c0.134-0.485,0.202-0.926,0.202-1.318c0-0.807-0.155-1.499-0.465-2.078s-0.713-1.05-1.21-1.412c-0.496-0.361-1.06-0.625-1.69-0.791
c-0.631-0.165-1.267-0.248-1.908-0.248H87.4V231.219z"/>
<path fill="#FFFFFF" d="M103.73,222.781c0-0.269-0.011-0.595-0.031-0.978c-0.021-0.383-0.036-0.771-0.046-1.163
c-0.011-0.393-0.026-0.76-0.047-1.102c-0.021-0.341-0.031-0.604-0.031-0.791h1.861c0.021,0.538,0.036,1.055,0.046,1.551
c0.01,0.497,0.036,0.817,0.078,0.962c0.476-0.848,1.086-1.54,1.83-2.078c0.745-0.538,1.654-0.807,2.73-0.807
c0.186,0,0.367,0.016,0.543,0.047c0.175,0.03,0.357,0.067,0.543,0.108l-0.217,1.83c-0.248-0.082-0.486-0.124-0.713-0.124
c-0.807,0-1.504,0.129-2.094,0.388c-0.589,0.259-1.075,0.615-1.458,1.07s-0.667,0.987-0.853,1.598s-0.279,1.267-0.279,1.97v7.817
h-1.861V222.781z"/>
<path fill="#FFFFFF" d="M126,229.047c0,0.27,0.01,0.595,0.031,0.978c0.021,0.383,0.036,0.771,0.046,1.163
c0.01,0.394,0.026,0.761,0.047,1.102c0.02,0.341,0.031,0.604,0.031,0.791h-1.861c-0.021-0.537-0.036-1.055-0.046-1.551
c-0.011-0.497-0.036-0.817-0.078-0.962h-0.093c-0.373,0.786-0.993,1.463-1.861,2.032c-0.869,0.568-1.882,0.853-3.04,0.853
c-1.117,0-2.032-0.176-2.746-0.527s-1.272-0.812-1.675-1.38c-0.403-0.569-0.678-1.226-0.822-1.971
c-0.145-0.744-0.217-1.509-0.217-2.295v-8.531h1.861v8.438c0,0.58,0.051,1.144,0.155,1.691s0.284,1.039,0.543,1.474
c0.258,0.434,0.621,0.78,1.086,1.039s1.07,0.388,1.815,0.388c0.682,0,1.329-0.119,1.938-0.356c0.61-0.238,1.137-0.6,1.582-1.086
s0.796-1.097,1.055-1.83c0.258-0.734,0.388-1.598,0.388-2.591v-7.166H126V229.047z"/>
<path fill="#FFFFFF" d="M130.584,222.781c0-0.269-0.01-0.595-0.029-0.978c-0.021-0.383-0.037-0.771-0.047-1.163
c-0.012-0.393-0.027-0.76-0.047-1.102c-0.021-0.341-0.031-0.604-0.031-0.791h1.861c0.02,0.538,0.035,1.055,0.047,1.551
c0.01,0.497,0.035,0.817,0.076,0.962h0.094c0.373-0.785,0.992-1.463,1.861-2.032c0.869-0.568,1.883-0.853,3.041-0.853
c1.115,0,2.025,0.176,2.729,0.527s1.258,0.812,1.66,1.381c0.404,0.568,0.684,1.225,0.838,1.97c0.154,0.744,0.232,1.51,0.232,2.295
v8.531h-1.861v-8.438c0-0.579-0.051-1.143-0.154-1.691c-0.104-0.547-0.285-1.039-0.543-1.473c-0.26-0.435-0.621-0.781-1.086-1.04
c-0.465-0.258-1.07-0.388-1.814-0.388c-0.684,0-1.33,0.119-1.939,0.357c-0.609,0.237-1.137,0.6-1.582,1.085
c-0.445,0.486-0.797,1.097-1.055,1.831c-0.26,0.734-0.389,1.598-0.389,2.59v7.166h-1.861V222.781z"/>
<path fill="#FFFFFF" d="M159.28,230.971c-0.703,0.849-1.5,1.474-2.389,1.877c-0.89,0.403-1.852,0.604-2.885,0.604
c-1.097,0-2.11-0.186-3.041-0.559c-0.931-0.372-1.727-0.894-2.389-1.566c-0.662-0.672-1.179-1.468-1.551-2.389
c-0.372-0.92-0.559-1.928-0.559-3.024c0-1.096,0.187-2.104,0.559-3.024s0.889-1.717,1.551-2.389s1.458-1.194,2.389-1.566
c0.931-0.373,1.944-0.559,3.041-0.559c1.055,0,2.031,0.217,2.931,0.651c0.9,0.435,1.701,1.045,2.404,1.83l-1.489,1.117
c-0.537-0.6-1.127-1.07-1.768-1.412c-0.642-0.341-1.334-0.512-2.078-0.512c-0.869,0-1.655,0.155-2.358,0.466
c-0.703,0.31-1.303,0.729-1.799,1.256s-0.874,1.148-1.133,1.861c-0.259,0.714-0.388,1.474-0.388,2.28s0.129,1.566,0.388,2.28
c0.259,0.713,0.637,1.334,1.133,1.861s1.096,0.946,1.799,1.256c0.703,0.311,1.489,0.466,2.358,0.466
c0.785,0,1.504-0.181,2.155-0.543c0.651-0.361,1.215-0.843,1.69-1.442L159.28,230.971z"/>
<path fill="#FFFFFF" d="M161.925,209.628h1.861v11.633h0.062c0.372-0.785,0.992-1.463,1.861-2.032
c0.868-0.568,1.882-0.853,3.04-0.853c1.116,0,2.026,0.176,2.729,0.527s1.257,0.812,1.66,1.381c0.403,0.568,0.683,1.225,0.837,1.97
c0.155,0.744,0.233,1.51,0.233,2.295v8.531h-1.861v-8.438c0-0.579-0.052-1.143-0.155-1.691c-0.104-0.547-0.285-1.039-0.543-1.473
c-0.259-0.435-0.62-0.781-1.086-1.04c-0.465-0.258-1.07-0.388-1.814-0.388c-0.683,0-1.329,0.119-1.939,0.357
c-0.609,0.237-1.137,0.6-1.582,1.085c-0.444,0.486-0.796,1.097-1.055,1.831s-0.388,1.598-0.388,2.59v7.166h-1.861V209.628z"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.1 KiB

View File

@@ -10,7 +10,8 @@
</head>
<body>
<div class="brunch">
<a href="http://brunch.io"><img src="http://brunch.io/images/logo.png" alt="Brunch"></a>
<p>Bon Appétit.</p>
<img src="/brunch-napkin.svg" alt="Brunch">
<h4>Bon Appétit.</h4>
<h6>A <a href="http://brunch.io" target="_blank">Brunch</a> website deployed on <a href="https://zeit.co" target="_blank">ZEIT Now</a></h6>
</div>
</body>

View File

@@ -1,6 +1,21 @@
html, body {
height: 100%;
}
body {
display: flex;
margin: 0;
align-items: center;
justify-content: center;
}
.brunch {
font-family: -apple-system, Sans-Serif;
text-align: center;
font-size: 24pt;
color: #3f894a;
}
a {
color: inherit;
}

6
examples/dojo/.dojorc Normal file
View File

@@ -0,0 +1,6 @@
{
"build-app": {},
"test-intern": {},
"create-app": {},
"create-widget": {}
}

4
examples/dojo/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
node_modules/
_build/
output/
.cert/

25
examples/dojo/README.md Normal file
View File

@@ -0,0 +1,25 @@
# Dojo Example
This directory is a brief example of a [Dojo](https://dojo.io) site that can be deployed with ZEIT Now and zero configuration.
## Deploy Your Own
Deploy your own Dojo project with ZEIT Now.
[![Deploy with ZEIT Now](https://zeit.co/button)](https://zeit.co/import/project?template=https://github.com/zeit/now-examples/tree/master/dojo)
### How We Created This Example
To get started with Dojo on Now, you can use the [Dojo CLI](https://github.com/dojo/cli) to initialize the project:
```shell
$ now init dojo
```
### Deploying From Your Terminal
Once initialized, you can deploy the Dojo example with just a single command:
```shell
$ now
```

View File

@@ -0,0 +1,26 @@
{
"name": "dojo",
"version": "1.0.0",
"scripts": {
"dev": "dojo build --mode dev --watch --serve",
"build": "dojo build --mode dist",
"build:dev": "dojo build --mode dev",
"test": "dojo test",
"test:unit": "dojo build --mode unit && dojo test --unit --config local",
"test:functional": "dojo build --mode functional && dojo test --functional --config local",
"test:all": "dojo build --mode unit && dojo build --mode functional && dojo test --all --config local"
},
"dependencies": {
"@dojo/framework": "^6.0.0",
"@dojo/themes": "^6.0.0",
"@dojo/widgets": "^6.0.0",
"tslib": "~1.9.1"
},
"devDependencies": {
"@dojo/cli": "^6.0.0",
"@dojo/cli-build-app": "^6.0.0",
"@dojo/cli-test-intern": "^6.0.0",
"@types/node": "~9.6.5",
"typescript": "~3.4.5"
}
}

View File

@@ -0,0 +1,3 @@
.root {
}

1
examples/dojo/src/App.m.css.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
export const root: string;

27
examples/dojo/src/App.ts Normal file
View File

@@ -0,0 +1,27 @@
import { create, v, w } from '@dojo/framework/core/vdom';
import theme from '@dojo/framework/core/middleware/theme';
import Outlet from '@dojo/framework/routing/Outlet';
import dojo from '@dojo/themes/dojo';
import Menu from './widgets/Menu';
import Home from './widgets/Home';
import About from './widgets/About';
import Profile from './widgets/Profile';
import * as css from './App.m.css';
const factory = create({ theme });
export default factory(function App({ middleware: { theme } }) {
if (!theme.get()) {
theme.set(dojo);
}
return v('div', { classes: [css.root] }, [
w(Menu, {}),
v('div', [
w(Outlet, { key: 'home', id: 'home', renderer: () => w(Home, {}) }),
w(Outlet, { key: 'about', id: 'about', renderer: () => w(About, {}) }),
w(Outlet, { key: 'profile', id: 'profile', renderer: () => w(Profile, { username: 'Dojo User' }) })
])
]);
});

View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en-us" dir="ltr">
<head>
<meta charset="utf-8">
<title>dojo</title>
<meta name="theme-color" content="#222127">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
</body>
</html>

View File

@@ -0,0 +1,6 @@
/* Put your styles and imports here */
body {
margin: 0;
padding: 0;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

13
examples/dojo/src/main.ts Normal file
View File

@@ -0,0 +1,13 @@
import renderer, { w } from '@dojo/framework/core/vdom';
import Registry from '@dojo/framework/core/Registry';
import { registerRouterInjector } from '@dojo/framework/routing/RouterInjector';
import '@dojo/themes/dojo/index.css';
import routes from './routes';
import App from './App';
const registry = new Registry();
registerRouterInjector(routes, registry);
const r = renderer(() => w(App, {}));
r.mount({ registry });

View File

@@ -0,0 +1,15 @@
export default [
{
path: 'home',
outlet: 'home',
defaultRoute: true
},
{
path: 'about',
outlet: 'about'
},
{
path: 'profile',
outlet: 'profile'
}
];

View File

@@ -0,0 +1,9 @@
import { v, create } from '@dojo/framework/core/vdom';
import * as css from './styles/About.m.css';
const factory = create();
export default factory(function Profile() {
return v('h1', { classes: [css.root] }, ['About Page']);
});

View File

@@ -0,0 +1,9 @@
import { v, create } from '@dojo/framework/core/vdom';
import * as css from './styles/Home.m.css';
const factory = create();
export default factory(function Profile() {
return v('h1', { classes: [css.root] }, ['Home Page']);
});

View File

@@ -0,0 +1,39 @@
import { create, w } from '@dojo/framework/core/vdom';
import Link from '@dojo/framework/routing/ActiveLink';
import Toolbar from '@dojo/widgets/toolbar';
import * as css from './styles/Menu.m.css';
const factory = create();
export default factory(function Menu() {
return w(Toolbar, { heading: 'My Dojo App!', collapseWidth: 600 }, [
w(
Link,
{
to: 'home',
classes: [css.link],
activeClasses: [css.selected]
},
['Home']
),
w(
Link,
{
to: 'about',
classes: [css.link],
activeClasses: [css.selected]
},
['About']
),
w(
Link,
{
to: 'profile',
classes: [css.link],
activeClasses: [css.selected]
},
['Profile']
)
]);
});

View File

@@ -0,0 +1,14 @@
import { v, create } from '@dojo/framework/core/vdom';
import * as css from './styles/Profile.m.css';
export interface ProfileProperties {
username: string;
}
const factory = create().properties<ProfileProperties>();
export default factory(function Profile({ properties }) {
const { username } = properties();
return v('h1', { classes: [css.root] }, [`Welcome ${username}!`]);
});

View File

@@ -0,0 +1,3 @@
.root {
}

View File

@@ -0,0 +1 @@
export const root: string;

View File

@@ -0,0 +1,3 @@
.root {
}

View File

@@ -0,0 +1 @@
export const root: string;

View File

@@ -0,0 +1,23 @@
.root {
flex: 1;
overflow: hidden;
}
.link:hover {
color: #4db3ff;
background-color:#ccddee;
}
.link {
min-width: 140px;
text-align: center;
text-transform: uppercase;
text-decoration: none;
padding: 18px;
color: black;
box-sizing: border-box;
}
.selected {
color: darkorange;
}

View File

@@ -0,0 +1,3 @@
export const root: string;
export const link: string;
export const selected: string;

View File

@@ -0,0 +1,3 @@
.root {
}

View File

@@ -0,0 +1 @@
export const root: string;

View File

@@ -0,0 +1 @@
import './main';

View File

@@ -0,0 +1 @@
/* Write your app tests here */

View File

@@ -0,0 +1,46 @@
const { describe, it } = intern.getInterface('bdd');
import harness from '@dojo/framework/testing/harness';
import { v, w } from '@dojo/framework/core/vdom';
import Outlet from '@dojo/framework/routing/Outlet';
import Menu from '../../src/widgets/Menu';
import Home from '../../src/widgets/Home';
import About from '../../src/widgets/About';
import Profile from '../../src/widgets/Profile';
import App from '../../src/App';
import * as css from '../../src/App.m.css';
describe('App', () => {
it('default renders correctly', () => {
const h = harness(() => w(App, {}));
h.expect(() =>
v('div', { classes: [css.root] }, [
w(Menu, {}),
v('div', [
w(Outlet, { key: 'home', id: 'home', renderer: () => w(Home, {}) }),
w(Outlet, { key: 'about', id: 'about', renderer: () => w(About, {}) }),
w(Outlet, { key: 'profile', id: 'profile', renderer: () => w(Profile, { username: 'Dojo User' }) })
])
])
);
});
it('home outlet renderer', () => {
const h = harness(() => w(App, {}));
const renderer = h.trigger('@home', 'renderer');
h.expect(() => w(Home, {}), () => renderer);
});
it('about outlet renderer', () => {
const h = harness(() => w(App, {}));
const renderer = h.trigger('@about', 'renderer');
h.expect(() => w(About, {}), () => renderer);
});
it('profile outlet renderer', () => {
const h = harness(() => w(App, {}));
const renderer = h.trigger('@profile', 'renderer');
h.expect(() => w(Profile, { username: 'Dojo User' }), () => renderer);
});
});

View File

@@ -0,0 +1,2 @@
import './App';
import './widgets/all';

View File

@@ -0,0 +1 @@
/* Write your app tests here */

View File

@@ -0,0 +1,13 @@
const { describe, it } = intern.getInterface('bdd');
import harness from '@dojo/framework/testing/harness';
import { w, v } from '@dojo/framework/core/vdom';
import About from '../../../src/widgets/About';
import * as css from '../../../src/widgets/styles/About.m.css';
describe('About', () => {
it('default renders correctly', () => {
const h = harness(() => w(About, {}));
h.expect(() => v('h1', { classes: [css.root] }, ['About Page']));
});
});

View File

@@ -0,0 +1,13 @@
const { describe, it } = intern.getInterface('bdd');
import harness from '@dojo/framework/testing/harness';
import { w, v } from '@dojo/framework/core/vdom';
import Home from '../../../src/widgets/Home';
import * as css from '../../../src/widgets/styles/Home.m.css';
describe('Home', () => {
it('default renders correctly', () => {
const h = harness(() => w(Home, {}));
h.expect(() => v('h1', { classes: [css.root] }, ['Home Page']));
});
});

View File

@@ -0,0 +1,45 @@
const { describe, it } = intern.getInterface('bdd');
import harness from '@dojo/framework/testing/harness';
import { w } from '@dojo/framework/core/vdom';
import Link from '@dojo/framework/routing/ActiveLink';
import Toolbar from '@dojo/widgets/toolbar';
import Menu from '../../../src/widgets/Menu';
import * as css from '../../../src/widgets/styles/Menu.m.css';
describe('Menu', () => {
it('default renders correctly', () => {
const h = harness(() => w(Menu, {}));
h.expect(() =>
w(Toolbar, { heading: 'My Dojo App!', collapseWidth: 600 }, [
w(
Link,
{
to: 'home',
classes: [css.link],
activeClasses: [css.selected]
},
['Home']
),
w(
Link,
{
to: 'about',
classes: [css.link],
activeClasses: [css.selected]
},
['About']
),
w(
Link,
{
to: 'profile',
classes: [css.link],
activeClasses: [css.selected]
},
['Profile']
)
])
);
});
});

View File

@@ -0,0 +1,13 @@
const { describe, it } = intern.getInterface('bdd');
import harness from '@dojo/framework/testing/harness';
import { w, v } from '@dojo/framework/core/vdom';
import Profile from '../../../src/widgets/Profile';
import * as css from '../../../src/widgets/styles/Profile.m.css';
describe('Profile', () => {
it('default renders correctly', () => {
const h = harness(() => w(Profile, { username: 'Dojo User' }));
h.expect(() => v('h1', { classes: [css.root] }, ['Welcome Dojo User!']));
});
});

View File

@@ -0,0 +1,4 @@
import './About';
import './Home';
import './Profile';
import './Menu';

View File

@@ -0,0 +1,31 @@
{
"compilerOptions": {
"declaration": false,
"experimentalDecorators": true,
"jsx": "react",
"jsxFactory": "tsx",
"lib": [
"dom",
"es5",
"es2015.promise",
"es2015.iterable",
"es2015.symbol",
"es2015.symbol.wellknown"
],
"module": "umd",
"moduleResolution": "node",
"noUnusedLocals": true,
"outDir": "_build/",
"removeComments": false,
"importHelpers": true,
"downlevelIteration": true,
"sourceMap": true,
"strict": true,
"target": "es5",
"types": [ "intern" ]
},
"include": [
"./src/**/*.ts",
"./tests/**/*.ts"
]
}

View File

@@ -1,6 +1,6 @@
{
"private": true,
"name": "gatsby-starter-default",
"name": "gatsby",
"version": "1.0.0",
"dependencies": {
"gatsby": "^2.18.14",

View File

@@ -1,5 +1,5 @@
{
"name": "gridsomee",
"name": "gridsome",
"private": true,
"scripts": {
"build": "gridsome build",

View File

@@ -20,7 +20,7 @@
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
"react-scripts": "3.3.0",
"typescript": "3.7.4"
"typescript": "3.8.3"
},
"scripts": {
"start": "react-scripts start",

View File

@@ -79,4 +79,4 @@ DEPENDENCIES
wdm (~> 0.1.0)
BUNDLED WITH
1.17.2
2.1.4

View File

@@ -105,4 +105,4 @@ DEPENDENCIES
wdm (~> 0.1)
BUNDLED WITH
1.17.2
2.1.4

View File

@@ -24,3 +24,7 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Environment Variables
.env
.env.build

View File

@@ -8,8 +8,8 @@
"start": "next start"
},
"dependencies": {
"next": "9.2.2",
"react": "16.13.0",
"react-dom": "16.13.0"
"next": "^9.3.3",
"react": "^16.13.0",
"react-dom": "^16.13.0"
}
}

View File

@@ -3,12 +3,12 @@
{
"source": "/",
"destination": "/api/frameworks"
},
{
"source": "/api/v1/frameworks",
"destination": "/api/frameworks"
}
],
"env": {
"GITHUB_ACCESS_TOKEN": "@now-api-examples-github-token",
"SENTRY_DSN": "@sentry-product-dsn"
},
"github": {
"silent": true,
"autoJobCancelation": true

View File

@@ -23,6 +23,7 @@
"eslint": "6.2.2",
"eslint-config-prettier": "6.1.0",
"husky": "3.0.4",
"json5": "2.1.1",
"lint-staged": "9.2.5",
"node-fetch": "2.6.0",
"prettier": "1.18.2"
@@ -37,9 +38,9 @@
"build": "node utils/run.js build all",
"test-lint": "node utils/run.js test-lint",
"test-unit": "node utils/run.js test-unit",
"test-integration": "node utils/run.js test-integration",
"test-integration-cli": "node utils/run.js test-integration-cli",
"test-integration-once": "node utils/run.js test-integration-once",
"test-integration-now-dev": "node utils/run.js test-integration-now-dev",
"test-integration-dev": "node utils/run.js test-integration-dev",
"lint": "eslint . --ext .ts,.js"
},
"lint-staged": {
@@ -58,9 +59,6 @@
"pre-commit": "lint-staged"
}
},
"resolutions": {
"signal-exit": "TooTallNate/signal-exit#update/sighub-to-sigint-on-windows"
},
"prettier": {
"trailingComma": "es5",
"singleQuote": true

View File

@@ -17,7 +17,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`build` from `package.json` or `next build`"
"placeholder": "`npm run build` or `next build`"
},
"devCommand": {
"value": "next dev --port $PORT"
@@ -45,7 +45,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`gatsby build` or `build` from `package.json`"
"placeholder": "`npm run build` or `gatsby build`"
},
"devCommand": {
"value": "gatsby develop --port $PORT"
@@ -62,6 +62,7 @@
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/hexo.svg",
"tagline": "Hexo is a fast, simple & powerful blog framework powered by Node.js.",
"description": "A Hexo site, created with the Hexo CLI.",
"website": "https://hexo.io/",
"detectors": {
"every": [
{
@@ -72,7 +73,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`hexo generate` or `build` from `package.json`"
"placeholder": "`npm run build` or `hexo generate`"
},
"devCommand": {
"value": "hexo server --port $PORT"
@@ -89,6 +90,7 @@
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/eleventy.svg",
"tagline": "11ty is a simpler static site generator written in JavaScript, created to be an alternative to Jekyll.",
"description": "An Eleventy site, created with npm init.",
"website": "https://www.11ty.dev/",
"detectors": {
"every": [
{
@@ -99,7 +101,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`npx @11ty/eleventy` or `build` from `package.json`"
"placeholder": "`npm run build` or `npx @11ty/eleventy`"
},
"devCommand": {
"value": "npx @11ty/eleventy --serve --watch --port $PORT"
@@ -110,18 +112,15 @@
}
},
{
"name": "Docusaurus",
"slug": "docusaurus",
"name": "Docusaurus 2",
"slug": "docusaurus-2",
"demo": "https://docusaurus.now-examples.now.sh",
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/docusaurus.svg",
"tagline": "Docusaurus makes it easy to maintain Open Source documentation websites.",
"description": "A static Docusaurus site that makes it easy to maintain OSS documentation.",
"website": "https://v2.docusaurus.io",
"detectors": {
"some": [
{
"path": "package.json",
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"docusaurus\":\\s*\".+?\"[^}]*}"
},
{
"path": "package.json",
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"@docusaurus\\/core\":\\s*\".+?\"[^}]*}"
@@ -130,7 +129,35 @@
},
"settings": {
"buildCommand": {
"placeholder": "`docusaurus-build` or `build` from `package.json`"
"placeholder": "`npm run build` or `docusaurus build`"
},
"devCommand": {
"value": "docusaurus start --port $PORT"
},
"outputDirectory": {
"value": "build"
}
}
},
{
"name": "Docusaurus 1",
"slug": "docusaurus",
"demo": "https://docusaurus.now-examples.now.sh",
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/docusaurus.svg",
"tagline": "Docusaurus makes it easy to maintain Open Source documentation websites.",
"description": "A static Docusaurus site that makes it easy to maintain OSS documentation.",
"website": "https://docusaurus.io/",
"detectors": {
"some": [
{
"path": "package.json",
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"docusaurus\":\\s*\".+?\"[^}]*}"
}
]
},
"settings": {
"buildCommand": {
"placeholder": "`npm run build` or `docusaurus-build`"
},
"devCommand": {
"value": "docusaurus-start --port $PORT"
@@ -158,7 +185,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`preact build` or `build` from `package.json`"
"placeholder": "`npm run build` or `preact build`"
},
"devCommand": {
"value": "preact watch --port $PORT"
@@ -168,6 +195,37 @@
}
}
},
{
"name": "Dojo",
"slug": "dojo",
"demo": "https://dojo.now-examples.now.sh",
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/dojo.svg",
"tagline": "Dojo is a modern progressive, TypeScript first framework.",
"description": "A Dojo app, created with the Dojo CLI's cli-create-app command.",
"website": "https://dojo.io",
"detectors": {
"some": [
{
"path": "package.json",
"matchContent": "\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"@dojo\\/framework\":\\s*\".+?\"[^}]*}"
},
{
"path": ".dojorc"
}
]
},
"settings": {
"buildCommand": {
"placeholder": "`npm run build` or `dojo build`"
},
"devCommand": {
"value": "dojo build -m dev -w -s -p $PORT"
},
"outputDirectory": {
"value": "output/dist"
}
}
},
{
"name": "Ember",
"slug": "ember",
@@ -175,6 +233,7 @@
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/ember.svg",
"tagline": "Ember.js helps webapp developers be more productive out of the box.",
"description": "An Ember app, created with the Ember CLI.",
"website": "https://emberjs.com/",
"detectors": {
"every": [
{
@@ -185,7 +244,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`ember build` or `build` from `package.json`"
"placeholder": "`npm run build` or `ember build`"
},
"devCommand": {
"value": "ember serve --port $PORT"
@@ -213,7 +272,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`vue-cli-service build` or `build` from `package.json`"
"placeholder": "`npm run build` or `vue-cli-service build`"
},
"devCommand": {
"value": "vue-cli-service serve --port $PORT"
@@ -229,6 +288,7 @@
"demo": "https://scully.now-examples.now.sh",
"tagline": "Scully is a static site generator for Angular.",
"description": "The Static Site Generator for Angular apps.",
"website": "https://github.com/scullyio/scully",
"detectors": {
"every": [
{
@@ -239,7 +299,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`ng build && scully` or `build` from `package.json`"
"placeholder": "`npm run build` or `ng build && scully`"
},
"devCommand": {
"value": "ng serve --port $PORT"
@@ -267,7 +327,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`ng build` or `build` from `package.json`"
"placeholder": "`npm run build` or `ng build`"
},
"devCommand": {
"value": "ng serve --port $PORT"
@@ -284,6 +344,7 @@
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/polymer.svg",
"tagline": "Polymer is an open-source webapps library from Google, for building using Web Components.",
"description": "A Polymer app, created with the Polymer CLI.",
"website": "https://www.polymer-project.org/",
"detectors": {
"every": [
{
@@ -294,7 +355,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`polymer build` or `build` from `package.json`"
"placeholder": "`npm run build` or `polymer build`"
},
"devCommand": {
"value": "polymer serve --port $PORT"
@@ -322,7 +383,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`rollup -c` or `build` from `package.json`"
"placeholder": "`npm run build` or `rollup -c`"
},
"devCommand": {
"value": "sirv public --single --dev --port $PORT"
@@ -350,7 +411,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`build` from `package.json`"
"placeholder": "npm run build"
},
"devCommand": {
"value": "stencil build --dev --watch --serve --port $PORT"
@@ -382,7 +443,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`react-scripts build` or `build` from `package.json`"
"placeholder": "`npm run build` or `react-scripts build`"
},
"devCommand": {
"value": "react-scripts start"
@@ -399,6 +460,7 @@
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/gridsome.svg",
"tagline": "Gridsome is a Vue.js-powered framework for building websites & apps that are fast by default.",
"description": "A Gridsome app, created with the Gridsome CLI.",
"website": "https://gridsome.org/",
"detectors": {
"every": [
{
@@ -409,7 +471,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`gridsome build` or `build` from `package.json`"
"placeholder": "`npm run build` or `gridsome build`"
},
"devCommand": {
"value": "gridsome develop -p $PORT"
@@ -437,7 +499,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`umi build` or `build` from `package.json`"
"placeholder": "`npm run build` or `umi build`"
},
"devCommand": {
"value": "umi dev --port $PORT"
@@ -465,7 +527,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`sapper export` or `build` from `package.json`"
"placeholder": "`npm run build` or `sapper export`"
},
"devCommand": {
"value": "sapper dev --port $PORT"
@@ -482,6 +544,7 @@
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/saber.svg",
"tagline": "Saber is a framework for building static sites in Vue.js that supports data from any source.",
"description": "A Saber site, created with npm init.",
"website": "https://saber.land/",
"detectors": {
"every": [
{
@@ -492,7 +555,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`saber build` or `build` from `package.json`"
"placeholder": "`npm run build` or `saber build`"
},
"devCommand": {
"value": "saber --port $PORT"
@@ -509,6 +572,7 @@
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/stencil.svg",
"tagline": "Stencil is a powerful toolchain for building Progressive Web Apps and Design Systems.",
"description": "A Stencil site, created with the Stencil CLI.",
"website": "https://stenciljs.com/",
"detectors": {
"every": [
{
@@ -519,7 +583,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`stencil build` or `build` from `package.json`"
"placeholder": "`npm run build` or `stencil build`"
},
"devCommand": {
"value": "stencil build --dev --watch --serve --port $PORT"
@@ -547,7 +611,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`nuxt build` or `build` from `package.json`"
"placeholder": "`npm run build` or `nuxt build`"
},
"devCommand": {
"value": "nuxt"
@@ -580,7 +644,7 @@
},
"settings": {
"buildCommand": {
"value": "hugo -D --gc"
"placeholder": "`npm run build` or `hugo -D --gc`"
},
"devCommand": {
"value": "hugo server -D -w -p $PORT"
@@ -597,6 +661,7 @@
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/jekyll.svg",
"tagline": "Jekyll makes it super easy to transform your plain text into static websites and blogs.",
"description": "A Jekyll site, created with the Jekyll CLI.",
"website": "https://jekyllrb.com/",
"detectors": {
"every": [
{
@@ -606,7 +671,7 @@
},
"settings": {
"buildCommand": {
"value": "jekyll build"
"placeholder": "`npm run build` or `jekyll build`"
},
"devCommand": {
"value": "bundle exec jekyll serve --watch --port $PORT"
@@ -623,6 +688,7 @@
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/brunch.svg",
"tagline": "Brunch is a fast and simple webapp build tool with seamless incremental compilation for rapid development.",
"description": "A Brunch app, created with the Brunch CLI.",
"website": "https://brunch.io/",
"detectors": {
"every": [
{
@@ -632,7 +698,7 @@
},
"settings": {
"buildCommand": {
"placeholder": "`brunch build --production` or `build` from `package.json`"
"placeholder": "`npm run build` or `brunch build --production`"
},
"devCommand": {
"value": "brunch watch --server --port $PORT"
@@ -649,6 +715,7 @@
"logo": "https://raw.githubusercontent.com/zeit/now/master/packages/frameworks/logos/middleman.svg",
"tagline": "Middleman is a static site generator that uses all the shortcuts and tools in modern web development.",
"description": "A Middleman app, created with the Middleman CLI.",
"website": "https://middlemanapp.com/",
"detectors": {
"every": [
{
@@ -658,7 +725,7 @@
},
"settings": {
"buildCommand": {
"value": "bundle exec middleman build"
"value": "`npm run build` or `bundle exec middleman build`"
},
"devCommand": {
"value": "bundle exec middleman server -p $PORT"
@@ -675,7 +742,7 @@
"description": "No framework or a unoptimized framework.",
"settings": {
"buildCommand": {
"placeholder": "`build` or `now-build` from `package.json` if it exists"
"placeholder": "`npm run now-build` or `npm run build`"
},
"devCommand": {
"placeholder": "None"

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -1,6 +1,6 @@
{
"name": "@now/frameworks",
"version": "0.0.11-canary.0",
"version": "0.0.13-canary.0",
"main": "frameworks.json",
"license": "UNLICENSED"
}

View File

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

View File

@@ -6,13 +6,18 @@ import spawn from 'cross-spawn';
import { SpawnOptions } from 'child_process';
import { deprecate } from 'util';
import { cpus } from 'os';
import { NowBuildError } from '../errors';
import { Meta, PackageJson, NodeVersion, Config } from '../types';
import { getSupportedNodeVersion, getLatestNodeVersion } from './node-version';
interface SpawnOptionsExtended extends SpawnOptions {
prettyCommand?: string;
}
export function spawnAsync(
command: string,
args: string[],
opts: SpawnOptions = {}
opts: SpawnOptionsExtended = {}
) {
return new Promise<void>((resolve, reject) => {
const stderrLogs: Buffer[] = [];
@@ -29,12 +34,18 @@ export function spawnAsync(
return resolve();
}
const errorLogs = stderrLogs.map(line => line.toString()).join('');
if (opts.stdio !== 'inherit') {
reject(new Error(`Exited with ${code || signal}\n${errorLogs}`));
} else {
reject(new Error(`Exited with ${code || signal}`));
}
const cmd = opts.prettyCommand
? `Command "${opts.prettyCommand}"`
: 'Command';
reject(
new NowBuildError({
code: `NOW_BUILD_UTILS_SPAWN_${code || signal}`,
message:
opts.stdio === 'inherit'
? `${cmd} exited with ${code || signal}`
: stderrLogs.map(line => line.toString()).join(''),
})
);
});
});
}
@@ -42,7 +53,7 @@ export function spawnAsync(
export function execAsync(
command: string,
args: string[],
opts: SpawnOptions = {}
opts: SpawnOptionsExtended = {}
) {
return new Promise<{ stdout: string; stderr: string; code: number }>(
(resolve, reject) => {
@@ -64,10 +75,15 @@ export function execAsync(
child.on('error', reject);
child.on('close', (code, signal) => {
if (code !== 0) {
const cmd = opts.prettyCommand
? `Command "${opts.prettyCommand}"`
: 'Command';
return reject(
new Error(
`Program "${command}" exited with non-zero exit code ${code} ${signal}.`
)
new NowBuildError({
code: `NOW_BUILD_UTILS_EXEC_${code || signal}`,
message: `${cmd} exited with ${code || signal}`,
})
);
}
@@ -82,23 +98,30 @@ export function execAsync(
}
export function spawnCommand(command: string, options: SpawnOptions = {}) {
const opts = { ...options, prettyCommand: command };
if (process.platform === 'win32') {
return spawn('cmd.exe', ['/C', command], options);
return spawn('cmd.exe', ['/C', command], opts);
}
return spawn('sh', ['-c', command], options);
return spawn('sh', ['-c', command], opts);
}
export async function execCommand(command: string, options: SpawnOptions = {}) {
const opts = { ...options, prettyCommand: command };
if (process.platform === 'win32') {
await spawnAsync('cmd.exe', ['/C', command], options);
await spawnAsync('cmd.exe', ['/C', command], opts);
} else {
await spawnAsync('sh', ['-c', command], options);
await spawnAsync('sh', ['-c', command], opts);
}
return true;
}
export async function getNodeBinPath({ cwd }: { cwd: string }) {
const { stdout } = await execAsync('npm', ['bin'], { cwd });
return stdout.trim();
}
async function chmodPlusX(fsPath: string) {
const s = await fs.stat(fsPath);
const newMode = s.mode | 64 | 8 | 1; // eslint-disable-line no-bitwise
@@ -115,9 +138,11 @@ export async function runShellScript(
assert(path.isAbsolute(fsPath));
const destPath = path.dirname(fsPath);
await chmodPlusX(fsPath);
await spawnAsync(`./${path.basename(fsPath)}`, args, {
cwd: destPath,
const command = `./${path.basename(fsPath)}`;
await spawnAsync(command, args, {
...spawnOpts,
cwd: destPath,
prettyCommand: command,
});
return true;
}
@@ -189,6 +214,46 @@ async function scanParentDirs(destPath: string, readPackageJson = false) {
return { hasPackageLockJson, packageJson };
}
interface WalkParentDirsProps {
/**
* The highest directory, typically the workPath root of the project.
* If this directory is reached and it doesn't contain the file, null is returned.
*/
base: string;
/**
* The directory to start searching, typically the same directory of the entrypoint.
* If this directory doesn't contain the file, the parent is checked, etc.
*/
start: string;
/**
* The name of the file to search for, typically `package.json` or `Gemfile`.
*/
filename: string;
}
export async function walkParentDirs({
base,
start,
filename,
}: WalkParentDirsProps): Promise<string | null> {
assert(path.isAbsolute(base), 'Expected "base" to be absolute path');
assert(path.isAbsolute(start), 'Expected "start" to be absolute path');
let parent = '';
for (let current = start; base.length <= current.length; current = parent) {
const fullPath = path.join(current, filename);
// eslint-disable-next-line no-await-in-loop
if (await fs.pathExists(fullPath)) {
return fullPath;
}
parent = path.dirname(current);
}
return null;
}
export async function runNpmInstall(
destPath: string,
args: string[] = [],
@@ -204,7 +269,7 @@ export async function runNpmInstall(
debug(`Installing to ${destPath}`);
const { hasPackageLockJson } = await scanParentDirs(destPath);
const opts: SpawnOptions = { cwd: destPath, ...spawnOpts };
const opts: SpawnOptionsExtended = { cwd: destPath, ...spawnOpts };
const env = opts.env ? { ...opts.env } : { ...process.env };
delete env.NODE_ENV;
opts.env = env;
@@ -213,11 +278,13 @@ export async function runNpmInstall(
let commandArgs: string[];
if (hasPackageLockJson) {
opts.prettyCommand = 'npm install';
command = 'npm';
commandArgs = args
.filter(a => a !== '--prefer-offline')
.concat(['install', '--no-audit', '--unsafe-perm']);
} else {
opts.prettyCommand = 'yarn install';
command = 'yarn';
commandArgs = args.concat(['install', '--ignore-engines']);
}
@@ -240,7 +307,7 @@ export async function runBundleInstall(
}
assert(path.isAbsolute(destPath));
const opts = { cwd: destPath, ...spawnOpts };
const opts = { ...spawnOpts, cwd: destPath, prettyCommand: 'bundle install' };
await spawnAsync(
'bundle',
@@ -268,7 +335,7 @@ export async function runPipInstall(
}
assert(path.isAbsolute(destPath));
const opts = { cwd: destPath, ...spawnOpts };
const opts = { ...spawnOpts, cwd: destPath, prettyCommand: 'pip3 install' };
await spawnAsync(
'pip3',
@@ -295,18 +362,22 @@ 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], opts);
const prettyCommand = `npm run ${scriptName}`;
console.log(`Running "${prettyCommand}"`);
await spawnAsync('npm', ['run', scriptName], {
...spawnOpts,
cwd: destPath,
prettyCommand,
});
} else {
console.log(`Running "yarn run ${scriptName}"`);
await spawnAsync(
'yarn',
['--ignore-engines', '--cwd', destPath, 'run', scriptName],
opts
);
const prettyCommand = `yarn run ${scriptName}`;
console.log(`Running "${prettyCommand}"`);
await spawnAsync('yarn', ['--ignore-engines', 'run', scriptName], {
...spawnOpts,
cwd: destPath,
prettyCommand,
});
}
return true;

View File

@@ -12,6 +12,7 @@ import {
spawnAsync,
execCommand,
spawnCommand,
walkParentDirs,
installDependencies,
runPackageJsonScript,
runNpmInstall,
@@ -20,6 +21,7 @@ import {
runShellScript,
getNodeVersion,
getSpawnOptions,
getNodeBinPath,
} from './fs/run-user-scripts';
import {
getLatestNodeVersion,
@@ -48,6 +50,8 @@ export {
runPackageJsonScript,
execCommand,
spawnCommand,
walkParentDirs,
getNodeBinPath,
runNpmInstall,
runBundleInstall,
runPipInstall,

View File

@@ -18,7 +18,7 @@ module.exports = {
{
resolve: `gatsby-plugin-manifest`,
options: {
name: `gatsby-starter-default`,
name: `05-zero-config-gatsby`,
short_name: `starter`,
start_url: `/`,
background_color: `#663399`,

View File

@@ -1,5 +1,5 @@
{
"name": "gatsby-starter-default",
"name": "05-zero-config-gatsby",
"private": true,
"description": "A simple starter to get up and developing quickly with Gatsby",
"version": "0.1.0",

View File

@@ -0,0 +1,109 @@
import { walkParentDirs } from '../';
import { strict } from 'assert';
import { join } from 'path';
import { promises } from 'fs';
const { deepEqual, notDeepEqual, fail } = strict;
const { readFile } = promises;
const fixture = (name: string) => join(__dirname, 'walk', name);
const filename = 'file.txt';
async function assertContent(target: string | null, contents: string) {
notDeepEqual(target, null);
const actual = await readFile(target!, 'utf8');
deepEqual(actual.trim(), contents.trim());
}
describe('Test `walkParentDirs`', () => {
it('should throw when `base` is relative', async () => {
const base = './relative';
const start = __dirname;
try {
await walkParentDirs({ base, start, filename });
fail('Expected error');
} catch (error) {
console.log(error);
deepEqual(
(error as Error).message,
'Expected "base" to be absolute path'
);
}
});
it('should throw when `start` is relative', async () => {
const base = __dirname;
const start = './relative';
try {
await walkParentDirs({ base, start, filename });
fail('Expected error');
} catch (error) {
console.log(error);
deepEqual(
(error as Error).message,
'Expected "start" to be absolute path'
);
}
});
it('should find nested one', async () => {
const base = fixture('every-directory');
const start = base;
const target = await walkParentDirs({ base, start, filename });
await assertContent(target, 'First');
});
it('should find nested two', async () => {
const base = fixture('every-directory');
const start = join(base, 'two');
const target = await walkParentDirs({ base, start, filename });
await assertContent(target, 'Second');
});
it('should find nested three', async () => {
const base = fixture('every-directory');
const start = join(base, 'two', 'three');
const target = await walkParentDirs({ base, start, filename });
await assertContent(target, 'Third');
});
it('should not find nested one', async () => {
const base = fixture('not-found');
const start = base;
const target = await walkParentDirs({ base, start, filename });
deepEqual(target, null);
});
it('should not find nested two', async () => {
const base = fixture('not-found');
const start = join(base, 'two');
const target = await walkParentDirs({ base, start, filename });
deepEqual(target, null);
});
it('should not find nested three', async () => {
const base = fixture('not-found');
const start = join(base, 'two', 'three');
const target = await walkParentDirs({ base, start, filename });
deepEqual(target, null);
});
it('should find only one', async () => {
const base = fixture('only-one');
const start = join(base, 'two', 'three');
const target = await walkParentDirs({ base, start, filename });
await assertContent(target, 'First');
});
it('should find only two', async () => {
const base = fixture('only-two');
const start = join(base, 'two', 'three');
const target = await walkParentDirs({ base, start, filename });
await assertContent(target, 'Second');
});
it('should find only three', async () => {
const base = fixture('only-three');
const start = join(base, 'two', 'three');
const target = await walkParentDirs({ base, start, filename });
await assertContent(target, 'Third');
});
});

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
First

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
Second

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
Third

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
First

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
Third

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
Another

View File

@@ -0,0 +1 @@
Second

View File

@@ -0,0 +1 @@
Another

View File

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

View File

@@ -1,6 +1,6 @@
{
"name": "now",
"version": "18.0.0-canary.6",
"version": "17.1.2-canary.8",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Now",
@@ -13,8 +13,9 @@
"scripts": {
"preinstall": "node ./scripts/preinstall.js",
"test-unit": "nyc ava test/unit.js test/dev-builder.unit.js test/dev-router.unit.js test/dev-server.unit.js --serial --fail-fast --verbose",
"test-integration": "ava test/integration.js --serial --fail-fast",
"test-integration-now-dev": "ava test/dev/integration.js --serial --fail-fast --verbose",
"test-integration-cli": "ava test/integration.js --serial --fail-fast",
"test-integration-v1": "ava test/integration-v1.js --serial --fail-fast",
"test-integration-dev": "ava test/dev/integration.js --serial --fail-fast --verbose",
"prepublishOnly": "yarn build",
"coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov",
"build": "ts-node ./scripts/build.ts",
@@ -91,10 +92,12 @@
"@types/universal-analytics": "0.4.2",
"@types/which": "1.3.2",
"@types/write-json-file": "2.2.1",
"@zeit/dockerignore": "0.0.5",
"@zeit/fun": "0.11.2",
"@zeit/ncc": "0.18.5",
"@zeit/source-map-support": "0.6.2",
"ajv": "6.10.2",
"alpha-sort": "2.0.1",
"ansi-escapes": "3.0.0",
"ansi-regex": "3.0.0",
"arg": "2.0.0",
@@ -127,6 +130,8 @@
"get-port": "5.1.1",
"glob": "7.1.2",
"http-proxy": "1.17.0",
"ignore": "4.0.6",
"ini": "1.3.4",
"inquirer": "7.0.4",
"is-port-reachable": "3.0.0",
"is-url": "1.2.2",
@@ -136,7 +141,7 @@
"micro": "9.1.2",
"mime-types": "2.1.24",
"minimatch": "3.0.4",
"mri": "1.1.0",
"mri": "1.1.5",
"ms": "2.1.2",
"node-fetch": "2.6.0",
"npm-package-arg": "6.1.0",

View File

@@ -1,3 +1,4 @@
//
import chalk from 'chalk';
import { handleError } from '../../util/error';
@@ -30,12 +31,16 @@ const help = () => {
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
'DIR'
)} Path to the global ${'`.now`'} directory
-r ${chalk.bold.underline('RULES_FILE')}, --rules=${chalk.bold.underline(
'RULES_FILE'
)} Rules file
-d, --debug Debug mode [off]
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
'TOKEN'
)} Login token
-S, --scope Set a custom scope
-n, --no-verify Don't wait until instance count meets the previous alias constraints
-N, --next Show next page of results
${chalk.dim('Examples:')}
${chalk.gray('')} Add a new alias to ${chalk.underline('my-api.now.sh')}
@@ -60,6 +65,28 @@ const help = () => {
${chalk.dim('')} ${chalk.dim(
'Protocols'
)} in the URLs are unneeded and ignored.
${chalk.gray('')} Add and modify path based aliases for ${chalk.underline(
'zeit.ninja'
)}
${chalk.cyan(
`$ now alias ${chalk.underline('zeit.ninja')} -r ${chalk.underline(
'rules.json'
)}`
)}
Export effective routing rules
${chalk.cyan(
`$ now alias ls aliasId --json > ${chalk.underline('rules.json')}`
)}
${chalk.gray('')} Paginate results, where ${chalk.dim(
'`1584722256178`'
)} is the time in milliseconds since the UNIX epoch.
${chalk.cyan(`$ now alias ls --next 1584722256178`)}
`);
};
@@ -76,8 +103,14 @@ export default async function main(ctx) {
try {
argv = getArgs(ctx.argv.slice(2), {
'--json': Boolean,
'--no-verify': Boolean,
'--rules': String,
'--yes': Boolean,
'--next': Number,
'-n': '--no-verify',
'-r': '--rules',
'-y': '--yes',
'-N': '--next',
});
} catch (err) {
handleError(err);

View File

@@ -2,7 +2,7 @@ import chalk from 'chalk';
import ms from 'ms';
import plural from 'pluralize';
import table from 'text-table';
import Now from '../../util/now';
import Now from '../../util';
import Client from '../../util/client.ts';
import getAliases from '../../util/alias/get-aliases';
import getScope from '../../util/get-scope.ts';
@@ -16,7 +16,7 @@ export default async function ls(ctx, opts, args, output) {
} = ctx;
const { currentTeam } = config;
const { apiUrl } = ctx;
const { '--debug': debugEnabled } = opts;
const { '--debug': debugEnabled, '--next': nextTimestamp } = opts;
const client = new Client({
apiUrl,
token,
@@ -36,7 +36,17 @@ export default async function ls(ctx, opts, args, output) {
throw err;
}
const now = new Now({ apiUrl, token, debug: debugEnabled, currentTeam });
if (typeof nextTimestamp !== undefined && Number.isNaN(nextTimestamp)) {
output.error('Please provide a number for flag --next');
return 1;
}
const now = new Now({
apiUrl,
token,
debug: debugEnabled,
currentTeam,
});
const lsStamp = stamp();
let cancelWait;
@@ -57,7 +67,11 @@ export default async function ls(ctx, opts, args, output) {
: `Fetching aliases under ${chalk.bold(contextName)}`
);
const aliases = await getAliases(now);
const { aliases, pagination } = await getAliases(
now,
undefined,
nextTimestamp
);
if (cancelWait) cancelWait();
if (args[0]) {
@@ -83,15 +97,16 @@ export default async function ls(ctx, opts, args, output) {
output.print(`${printPathAliasTable(rules)}\n`);
}
} else {
aliases.sort((a, b) => new Date(b.created) - new Date(a.created));
output.log(
`${plural('alias', aliases.length, true)} found under ${chalk.bold(
contextName
)} ${lsStamp()}`
);
output.log(`aliases found under ${chalk.bold(contextName)} ${lsStamp()}`);
console.log(printAliasTable(aliases));
}
if (pagination && aliases.length === 20) {
output.log(
`To display the next page use the flag --next ${pagination.next}`
);
}
now.close();
return 0;
}
@@ -110,7 +125,7 @@ function printAliasTable(aliases) {
? a.deployment.url
: chalk.gray(''),
a.alias,
ms(Date.now() - new Date(a.created)),
ms(Date.now() - new Date(a.createdAt)),
]),
],
{

View File

@@ -1,7 +1,7 @@
import chalk from 'chalk';
import ms from 'ms';
import table from 'text-table';
import Now from '../../util/now';
import Now from '../../util';
import cmd from '../../util/output/cmd.ts';
import Client from '../../util/client.ts';
import getScope from '../../util/get-scope.ts';
@@ -39,6 +39,7 @@ export default async function rm(ctx, opts, args, output) {
throw err;
}
// $FlowFixMe
const now = new Now({ apiUrl, token, debug: debugEnabled, currentTeam });
const [aliasOrId] = args;

View File

@@ -1,24 +1,34 @@
import ms from 'ms';
import chalk from 'chalk';
import { SetDifference } from 'utility-types';
import { AliasRecord } from '../../util/alias/create-alias';
import { NowContext, Domain } from '../../types';
import { Output } from '../../util/output';
import * as ERRORS from '../../util/errors';
import * as ERRORS from '../../util/errors-ts';
import assignAlias from '../../util/alias/assign-alias';
import Client from '../../util/client';
import cmd from '../../util/output/cmd';
import formatDnsTable from '../../util/format-dns-table';
import formatNSTable from '../../util/format-ns-table';
import getDeploymentByIdOrHost from '../../util/deploy/get-deployment-by-id-or-host';
import getDeploymentForAlias from '../../util/alias/get-deployment-for-alias';
import getRulesFromFile from '../../util/alias/get-rules-from-file';
import getScope from '../../util/get-scope';
import { getTargetsForAlias } from '../../util/alias/get-targets-for-alias';
import humanizePath from '../../util/humanize-path';
import setupDomain from '../../util/domains/setup-domain';
import stamp from '../../util/output/stamp';
import { isValidName } from '../../util/is-valid-name';
import upsertPathAlias from '../../util/alias/upsert-path-alias';
import handleCertError from '../../util/certs/handle-cert-error';
import isWildcardAlias from '../../util/alias/is-wildcard-alias';
import link from '../../util/output/link';
import { User } from '../../types';
type Options = {
'--debug': boolean;
'--local-config': string;
'--no-verify': boolean;
'--rules': string;
};
export default async function set(
@@ -30,13 +40,18 @@ export default async function set(
const {
authConfig: { token },
config,
localConfig,
} = ctx;
const { currentTeam } = config;
const { apiUrl } = ctx;
const setStamp = stamp();
const { '--debug': debugEnabled } = opts;
const {
'--debug': debugEnabled,
'--no-verify': noVerify,
'--rules': rulesPath,
} = opts;
const client = new Client({
apiUrl,
@@ -44,10 +59,12 @@ export default async function set(
currentTeam,
debug: debugEnabled,
});
let contextName = null;
let user: User;
let contextName: string | null = null;
try {
({ contextName } = await getScope(client));
({ contextName, user } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
@@ -77,7 +94,35 @@ export default async function set(
return 1;
}
if (args.length === 0) {
// Read the path alias rules in case there is is given
const rules = await getRulesFromFile(rulesPath);
if (rules instanceof ERRORS.FileNotFound) {
output.error(`Can't find the provided rules file at location:`);
output.print(` ${chalk.gray('-')} ${rules.meta.file}\n`);
return 1;
}
if (rules instanceof ERRORS.CantParseJSONFile) {
output.error(`Error parsing provided rules.json file at location:`);
output.print(` ${chalk.gray('-')} ${rules.meta.file}\n`);
return 1;
}
if (rules instanceof ERRORS.RulesFileValidationError) {
output.error(`Path Alias validation error: ${rules.meta.message}`);
output.print(` ${chalk.gray('-')} ${rules.meta.location}\n`);
return 1;
}
// If the user provided rules and also a deployment target, we should fail
if (args.length === 2 && rules) {
output.error(
`You can't supply a deployment target and target rules simultaneously.`
);
return 1;
}
if (args.length === 0 && !rules) {
output.error(
`To ship to production, optionally configure your domains (${link(
'https://zeit.co/docs/v2/custom-domains/'
@@ -86,11 +131,62 @@ export default async function set(
return 1;
}
const [deploymentIdOrHost, aliasTarget] = args;
// Find the targets to perform the alias
const targets = getTargetsForAlias(args, localConfig);
if (targets instanceof ERRORS.NoAliasInConfig) {
output.error(`Couldn't find an alias in config`);
return 1;
}
if (targets instanceof ERRORS.InvalidAliasInConfig) {
output.error(
`Wrong value for alias found in config. It must be a string or array of string.`
);
return 1;
}
if (rules) {
// If we have rules for path alias we assign them to the domain
for (const target of targets) {
output.log(
`Assigning path alias rules from ${humanizePath(
rulesPath
)} to ${target}`
);
const pathAlias = await upsertPathAlias(
output,
client,
rules,
target,
contextName
);
const remaining = handleCreateAliasError(output, pathAlias);
if (handleSetupDomainError(output, remaining) !== 1) {
console.log(
`${chalk.cyan('> Success!')} ${
rules.length
} rules configured for ${chalk.underline(target)} ${setStamp()}`
);
}
}
return 0;
}
// If there are no rules for path alias we should find out a deployment and perform the alias
const deployment = handleCertError(
output,
await getDeploymentByIdOrHost(client, contextName, deploymentIdOrHost)
await getDeploymentForAlias(
client,
output,
args,
opts['--local-config'],
user,
contextName,
localConfig
)
);
if (deployment === 1) {
@@ -127,34 +223,37 @@ export default async function set(
return 1;
}
output.log(`Assigning alias ${aliasTarget} to deployment ${deployment.url}`);
// Assign the alias for each of the targets in the array
for (const target of targets) {
output.log(`Assigning alias ${target} to deployment ${deployment.url}`);
const isWildcard = isWildcardAlias(aliasTarget);
const record = await assignAlias(
output,
client,
deployment,
aliasTarget,
contextName
);
const isWildcard = isWildcardAlias(target);
const record = await assignAlias(
output,
client,
deployment,
target,
contextName,
noVerify
);
const handleResult = handleSetupDomainError(
output,
handleCreateAliasError(output, record),
isWildcard
);
if (handleResult === 1) {
return 1;
}
const handleResult = handleSetupDomainError(
output,
handleCreateAliasError(output, record)
);
const prefix = isWildcard ? '' : 'https://';
if (handleResult === 1) {
return 1;
console.log(
`${chalk.cyan('> Success!')} ${chalk.bold(
`${prefix}${handleResult.alias}`
)} now points to https://${deployment.url} ${setStamp()}`
);
}
const prefix = isWildcard ? '' : 'https://';
console.log(
`${chalk.cyan('> Success!')} ${chalk.bold(
`${prefix}${handleResult.alias}`
)} now points to https://${deployment.url} ${setStamp()}`
);
return 0;
}
@@ -164,7 +263,8 @@ 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 ||
@@ -176,7 +276,9 @@ function handleSetupDomainError<T>(
`We could not alias since the domain ${domain} could not be verified due to the following reasons:\n`
);
output.print(
`Nameservers verification failed since we see a different set than the intended set:`
` ${chalk.gray(
'a)'
)} Nameservers verification failed since we see a different set than the intended set:`
);
output.print(
`\n${formatNSTable(
@@ -185,6 +287,34 @@ function handleSetupDomainError<T>(
{ extraSpace: ' ' }
)}\n\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;
}
@@ -325,6 +455,66 @@ function handleCreateAliasError<T>(
return 1;
}
if (error instanceof ERRORS.RuleValidationFailed) {
output.error(`Rule validation error: ${error.meta.message}.`);
output.print(` Make sure your rules file is written correctly.\n`);
return 1;
}
if (error instanceof ERRORS.VerifyScaleTimeout) {
output.error(`Instance verification timed out (${ms(error.meta.timeout)})`);
output.log('Read more: https://err.sh/now/verification-timeout');
return 1;
}
if (error instanceof ERRORS.NotSupportedMinScaleSlots) {
output.error(
`Scale rules from previous aliased deployment ${chalk.dim(
error.meta.url
)} could not be copied since Cloud v2 deployments cannot have a non-zero min`
);
output.log(
`Update the scale settings on ${chalk.dim(
error.meta.url
)} with \`now scale\` and try again`
);
output.log('Read more: https://err.sh/now/v2-no-min');
return 1;
}
if (error instanceof ERRORS.ForbiddenScaleMaxInstances) {
output.error(
`Scale rules from previous aliased deployment ${chalk.dim(
error.meta.url
)} could not be copied since the given number of max instances (${
error.meta.max
}) is not allowed.`
);
output.log(
`Update the scale settings on ${chalk.dim(
error.meta.url
)} with \`now scale\` and try again`
);
return 1;
}
if (error instanceof ERRORS.ForbiddenScaleMinInstances) {
output.error(
`You can't scale to more than ${error.meta.max} min instances with your current plan.`
);
return 1;
}
if (error instanceof ERRORS.InvalidScaleMinMaxRelation) {
output.error(
`Scale rules from previous aliased deployment ${chalk.dim(
error.meta.url
)} could not be copied becuase the relation between min and max instances is wrong.`
);
output.log(
`Update the scale settings on ${chalk.dim(
error.meta.url
)} with \`now scale\` and try again`
);
return 1;
}
if (error instanceof ERRORS.CertMissing) {
output.error(
`There is no certificate for the domain ${error.meta.domain} and it could not be created.`

View File

@@ -300,13 +300,10 @@ async function run({ token, config: { currentTeam } }) {
const deletedCard = cards.sources.find(card => card.id === cardId);
const remainingCards = cards.sources.filter(card => card.id !== cardId);
let text = `The provided card does not exist`;
if (deletedCard) {
text = `${deletedCard.brand ||
deletedCard.card.brand} ending in ${deletedCard.last4 ||
deletedCard.card.last4} was deleted`;
}
let text = `${deletedCard.brand ||
deletedCard.card.brand} ending in ${deletedCard.last4 ||
deletedCard.card.last4} was deleted`;
// ${chalk.gray(`[${elapsed}]`)}
if (cardId === cards.defaultSource) {
if (remainingCards.length === 0) {

View File

@@ -1,5 +1,7 @@
import chalk from 'chalk';
import Now from '../../util/now';
// @ts-ignore
import Now from '../../util';
import Client from '../../util/client';
import getScope from '../../util/get-scope';
import stamp from '../../util/output/stamp';
@@ -59,6 +61,7 @@ async function add(
throw err;
}
// $FlowFixMe
const now = new Now({ apiUrl, token, debug: debugEnabled, currentTeam });
if (overwite) {

View File

@@ -3,7 +3,7 @@ import chalk from 'chalk';
import { NowContext } from '../../types';
import { Output } from '../../util/output';
import * as ERRORS from '../../util/errors';
import * as ERRORS from '../../util/errors-ts';
import Client from '../../util/client';
import createCertForCns from '../../util/certs/create-cert-for-cns';
import createCertFromFile from '../../util/certs/create-cert-from-file';

View File

@@ -3,13 +3,14 @@ import ms from 'ms';
import plural from 'pluralize';
import psl from 'psl';
import table from 'text-table';
import Now from '../../util/now';
// @ts-ignore
import Now from '../../util';
import cmd from '../../util/output/cmd';
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';
import { CertNotFound } from '../../util/errors-ts';
import strlen from '../../util/strlen';
import { Output } from '../../util/output';
import { NowContext, Cert } from '../../types';

View File

@@ -3,7 +3,7 @@ import ms from 'ms';
import plural from 'pluralize';
import table from 'text-table';
import { NowContext, Cert } from '../../types';
import * as ERRORS from '../../util/errors';
import * as ERRORS from '../../util/errors-ts';
import { Output } from '../../util/output';
import deleteCertById from '../../util/certs/delete-cert-by-id';
import getCertById from '../../util/certs/get-cert-by-id';

View File

@@ -1,7 +1,9 @@
import chalk from 'chalk';
import logo from '../../util/output/logo';
import code from '../../util/output/code';
import note from '../../util/output/note';
export const help = () => `
export const latestHelp = () => `
${chalk.bold(`${logo} now`)} [options] <command | path>
${chalk.dim('Commands:')}
@@ -35,6 +37,7 @@ export const help = () => `
-h, --help Output usage information
-v, --version Output the version number
-V, --platform-version Set the platform version to deploy to
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
'FILE'
)} Path to the local ${'`now.json`'} file
@@ -43,6 +46,7 @@ export const help = () => `
)} Path to the global ${'`.now`'} directory
-d, --debug Debug mode [off]
-f, --force Force a new deployment even if nothing has changed
--with-cache Retain build cache when using "--force"
-t ${chalk.underline('TOKEN')}, --token=${chalk.underline(
'TOKEN'
)} Login token
@@ -64,6 +68,12 @@ export const help = () => `
--prod Create a production deployment
-c, --confirm Confirm default options and skip questions
${note(
`To view the usage information for Now 1.0, run ${code(
'now help deploy-v1'
)}`
)}
${chalk.dim('Examples:')}
${chalk.gray('')} Deploy the current directory
@@ -86,13 +96,15 @@ export const help = () => `
`;
export const args = {
export const latestArgs = {
'--force': Boolean,
'--with-cache': Boolean,
'--public': Boolean,
'--no-clipboard': Boolean,
'--env': [String],
'--build-env': [String],
'--meta': [String],
'--no-scale': Boolean,
// This is not an array in favor of matching
// the config property name.
'--regions': String,
@@ -111,3 +123,180 @@ export const args = {
'-n': '--name',
'--target': String,
};
export const legacyArgsMri = {
string: [
'name',
'build-env',
'alias',
'meta',
'session-affinity',
'regions',
'dotenv',
'target',
],
boolean: [
'help',
'version',
'debug',
'force',
'links',
'C',
'clipboard',
'forward-npm',
'docker',
'npm',
'static',
'public',
'no-scale',
'no-verify',
'dotenv',
'prod',
],
default: {
C: false,
clipboard: true,
},
alias: {
env: 'e',
meta: 'm',
'build-env': 'b',
dotenv: 'E',
help: 'h',
debug: 'd',
version: 'v',
force: 'f',
links: 'l',
public: 'p',
'forward-npm': 'N',
'session-affinity': 'S',
name: 'n',
project: 'P',
alias: 'a',
},
};
// The following arg parsing is simply to make it compatible
// with the index. Let's not migrate it to the new args parsing, as
// we are gonna delete this file soon anyways.
const argList = {};
for (const item of legacyArgsMri.string) {
argList[`--${item}`] = String;
}
for (const item of legacyArgsMri.boolean) {
argList[`--${item}`] = Boolean;
}
for (const item of Object.keys(legacyArgsMri.alias)) {
argList[`-${legacyArgsMri.alias[item]}`] = `--${item}`;
}
export const legacyArgs = argList;
export const legacyHelp = () => `
${chalk.bold(`${logo} now`)} [options] <command | path>
${chalk.dim('Commands:')}
${chalk.dim('Cloud')}
deploy [path] Performs a deployment ${chalk.bold(
'(default)'
)}
ls | list [app] Lists deployments
rm | remove [id] Removes a deployment
ln | alias [id] [url] Configures aliases for deployments
inspect [id] Displays information related to a deployment
domains [name] Manages your domain names
certs [cmd] Manages your SSL certificates
secrets [name] Manages your secret environment variables
dns [name] Manages your DNS records
logs [url] Displays the logs for a deployment
scale [args] Scales the instance count of a deployment
init [example] Initialize an example project
help [cmd] Displays complete help for [cmd]
${chalk.dim('Administrative')}
billing | cc [cmd] Manages your credit cards and billing methods
upgrade | downgrade [plan] Upgrades or downgrades your plan
teams Manages your teams
switch [scope] Switches between teams and your account
login [email] Logs into your account or creates a new one
logout Logs out of your account
whoami Shows the username of the currently logged in user
${chalk.dim('Options:')}
-h, --help Output usage information
-v, --version Output the version number
-V, --platform-version Set the platform version to deploy to
-n, --name Set the project name of the deployment
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
'FILE'
)} Path to the local ${'`now.json`'} file
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
'DIR'
)} Path to the global ${'`.now`'} directory
-d, --debug Debug mode [off]
-f, --force Force a new deployment even if nothing has changed
-t ${chalk.underline('TOKEN')}, --token=${chalk.underline(
'TOKEN'
)} Login token
-l, --links Copy symlinks without resolving their target
-p, --public Deployment is public (${chalk.dim(
'`/_src`'
)} is exposed) [on for oss, off for premium]
-e, --env Include an env var during run time (e.g.: ${chalk.dim(
'`-e KEY=value`'
)}). Can appear many times.
-b, --build-env Similar to ${chalk.dim(
'`--env`'
)} but for build time only.
-m, --meta Add metadata for the deployment (e.g.: ${chalk.dim(
'`-m KEY=value`'
)}). Can appear many times.
-E ${chalk.underline('FILE')}, --dotenv=${chalk.underline(
'FILE'
)} Include env vars from .env file. Defaults to '.env'
-C, --no-clipboard Do not attempt to copy URL to clipboard
-N, --forward-npm Forward login information to install private npm modules
--session-affinity Session affinity, \`ip\` or \`random\` (default) to control session affinity
-S, --scope Set a custom scope
--regions Set default regions or DCs to enable the deployment on
--no-scale Skip scaling rules deploying with the default presets
--no-verify Skip step of waiting until instance count meets given constraints
${chalk.dim(`Enforceable Types (by default, it's detected automatically):`)}
--npm Node.js application
--docker Docker container
--static Static file hosting
${chalk.dim('Examples:')}
${chalk.gray('')} Deploy the current directory
${chalk.cyan('$ now')}
${chalk.gray('')} Deploy a custom path
${chalk.cyan('$ now /usr/src/project')}
${chalk.gray('')} Deploy a GitHub repository
${chalk.cyan('$ now user/repo#ref')}
${chalk.gray('')} Deploy with environment variables
${chalk.cyan('$ now -e NODE_ENV=production -e SECRET=@mysql-secret')}
${chalk.gray('')} Show the usage information for the sub command ${chalk.dim(
'`list`'
)}
${chalk.cyan('$ now help list')}
`;

View File

@@ -1,13 +1,21 @@
import fs from 'fs-extra';
import { resolve, basename } from 'path';
import { resolve, basename, parse, join } from 'path';
import Client from '../../util/client.ts';
import getScope from '../../util/get-scope.ts';
import createOutput from '../../util/output';
import code from '../../util/output/code';
import highlight from '../../util/output/highlight';
import param from '../../util/output/param.ts';
import { readLocalConfig } from '../../util/config/files';
import getArgs from '../../util/get-args';
import { help, args } from './args';
import * as parts from './args';
import { handleError } from '../../util/error';
import deploy from './deploy';
import readPackage from '../../util/read-package';
import preferV2Deployment, {
hasDockerfile,
hasServerfile,
} from '../../util/prefer-v2-deployment';
import getProjectName from '../../util/get-project-name';
export default async ctx => {
const {
@@ -15,11 +23,14 @@ export default async ctx => {
config: { currentTeam },
apiUrl,
} = ctx;
const combinedArgs = Object.assign({}, parts.legacyArgs, parts.latestArgs);
let platformVersion = null;
let contextName = currentTeam || 'current user';
let argv = null;
try {
argv = getArgs(ctx.argv.slice(2), args);
argv = getArgs(ctx.argv.slice(2), combinedArgs);
} catch (error) {
handleError(error);
return 1;
@@ -46,8 +57,12 @@ export default async ctx => {
const debugEnabled = argv['--debug'];
const output = createOutput({ debug: debugEnabled });
const stats = {};
const versionFlag = argv['--platform-version'];
if (argv['--help']) {
const lastArg = argv._[argv._.length - 1];
const help = lastArg === 'deploy-v1' ? parts.legacyHelp : parts.latestHelp;
output.print(help());
return 2;
}
@@ -56,15 +71,28 @@ export default async ctx => {
try {
stats[path] = await fs.lstat(path);
} catch (err) {
output.error(
`The specified file or directory "${basename(path)}" does not exist.`
);
return 1;
const { ext } = parse(path);
if (versionFlag === 1 && !ext) {
// This will ensure `-V 1 zeit/serve` (GitHub deployments) work. Since
// GitHub repositories are never just one file, we need to set
// the `isFile` property accordingly.
stats[path] = {
isFile: () => false,
};
} else {
output.error(
`The specified file or directory "${basename(path)}" does not exist.`
);
return 1;
}
}
}
let client = null;
const isFile = Object.keys(stats).length === 1 && stats[paths[0]].isFile();
if (authConfig && authConfig.token) {
client = new Client({
apiUrl,
@@ -73,7 +101,7 @@ export default async ctx => {
debug: debugEnabled,
});
try {
({ contextName } = await getScope(client));
({ contextName, platformVersion } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
@@ -84,5 +112,89 @@ export default async ctx => {
}
}
return deploy(ctx, contextName, output, stats, localConfig, args);
const file = highlight('now.json');
const prop = code('version');
if (localConfig) {
const { version } = localConfig;
if (version) {
if (typeof version === 'number') {
if (version !== 1 && version !== 2) {
const first = code(1);
const second = code(2);
output.error(
`The value of the ${prop} property within ${file} can only be ${first} or ${second}.`
);
return 1;
}
platformVersion = version;
} else {
output.error(
`The ${prop} property inside your ${file} file must be a number.`
);
return 1;
}
}
}
if (versionFlag) {
if (versionFlag !== 1 && versionFlag !== 2) {
output.error(
`The ${param('--platform-version')} option must be either ${code(
'1'
)} or ${code('2')}.`
);
return 1;
}
platformVersion = versionFlag;
}
if (
platformVersion === 1 &&
versionFlag !== 1 &&
!argv['--docker'] &&
!argv['--npm']
) {
// Only check when it was not set via CLI flag
const reason = await preferV2Deployment({
client,
localConfig,
projectName: getProjectName({
argv,
nowConfig: localConfig || {},
isFile,
paths,
}),
hasServerfile: await hasServerfile(paths[0]),
hasDockerfile: await hasDockerfile(paths[0]),
pkg: await readPackage(join(paths[0], 'package.json')),
});
if (reason) {
output.note(reason);
platformVersion = 2;
}
}
if (platformVersion === null || platformVersion > 1) {
return require('./latest').default(
ctx,
contextName,
output,
stats,
localConfig,
parts.latestArgs
);
}
return require('./legacy').default(
ctx,
contextName,
output,
parts.legacyArgsMri
);
};

View File

@@ -8,7 +8,7 @@ import Client from '../../util/client';
import { handleError } from '../../util/error';
import getArgs from '../../util/get-args';
import toHumanPath from '../../util/humanize-path';
import Now from '../../util/now';
import Now from '../../util';
import stamp from '../../util/output/stamp.ts';
import createDeploy from '../../util/deploy/create-deploy';
import getDeploymentByIdOrHost from '../../util/deploy/get-deployment-by-id-or-host';
@@ -35,7 +35,7 @@ import {
ConflictingPathSegment,
BuildError,
NotDomainOwner,
} from '../../util/errors';
} from '../../util/errors-ts';
import { SchemaValidationFailed } from '../../util/errors';
import purchaseDomainIfAvailable from '../../util/domains/purchase-domain-if-available';
import isWildcardAlias from '../../util/alias/is-wildcard-alias';
@@ -45,7 +45,7 @@ import {
getLinkedProject,
linkFolderToProject,
} from '../../util/projects/link';
import { getProjectName } from '../../util/get-project-name';
import getProjectName from '../../util/get-project-name';
import selectOrg from '../../util/input/select-org';
import inputProject from '../../util/input/input-project';
import { prependEmoji, emoji } from '../../util/emoji';
@@ -225,6 +225,7 @@ export default async function main(
const paths = Object.keys(stats);
const debugEnabled = argv['--debug'];
// $FlowFixMe
const isTTY = process.stdout.isTTY;
const quiet = !isTTY;
@@ -505,6 +506,7 @@ export default async function main(
env: deploymentEnv,
build: { env: deploymentBuildEnv },
forceNew: argv['--force'],
withCache: argv['--with-cache'],
quiet,
wantsPublic: argv['--public'] || localConfig.public,
isFile,
@@ -575,7 +577,7 @@ export default async function main(
}
if (deployment.readyState === 'CANCELED') {
output.log('The deployment has been canceled.');
output.print('The deployment has been canceled.\n');
return 1;
}
@@ -664,7 +666,7 @@ export default async function main(
if (err instanceof BuildError) {
output.error('Build failed');
output.error(
`Check your logs at ${now.url}/_logs or run ${code(
`Check your logs at https://${now.url}/_logs or run ${code(
`now logs ${now.url}`,
{
// Backticks are interpreted as part of the URL, causing CMD+Click

File diff suppressed because it is too large Load Diff

View File

@@ -29,6 +29,7 @@ const help = () => {
-h, --help Output usage information
-d, --debug Debug mode [off]
-l, --listen [uri] Specify a URI endpoint on which to listen [0.0.0.0:3000]
-t, --token [token] Specify an Authorization Token
${chalk.dim('Examples:')}

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