mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-23 09:59:12 +00:00
Compare commits
151 Commits
@vercel/bu
...
@vercel/bu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1706a00cb9 | ||
|
|
d7bd03cf1d | ||
|
|
e27ff8d2e0 | ||
|
|
bc6da39cc2 | ||
|
|
727109c64a | ||
|
|
817410a8e2 | ||
|
|
e022e7b79c | ||
|
|
dda6c24a3d | ||
|
|
7c922a4092 | ||
|
|
376dec8f33 | ||
|
|
16e101d262 | ||
|
|
41ce1a4291 | ||
|
|
449f35cf33 | ||
|
|
d683402bba | ||
|
|
2051a1cd9b | ||
|
|
1eeeaf23a1 | ||
|
|
f347164b6c | ||
|
|
ea4be8a001 | ||
|
|
19ac74d59e | ||
|
|
9a87d4ea8e | ||
|
|
35fd7b5f9c | ||
|
|
eb8db25845 | ||
|
|
5c3cd17074 | ||
|
|
72572ba6be | ||
|
|
b69a41a0aa | ||
|
|
7c35d7992b | ||
|
|
290fdc0506 | ||
|
|
fc2d9f99e6 | ||
|
|
1fd24fb4fc | ||
|
|
17c72f1d35 | ||
|
|
9c1154c108 | ||
|
|
613c384ce8 | ||
|
|
a9598d14e3 | ||
|
|
48935e92d8 | ||
|
|
1b1e72ab88 | ||
|
|
0f574f67f6 | ||
|
|
0d4be3f5f2 | ||
|
|
a971c2aa3a | ||
|
|
66414bd65a | ||
|
|
3b021993b5 | ||
|
|
c9597dc199 | ||
|
|
1b5c94b392 | ||
|
|
bd1393a9d6 | ||
|
|
47ddd36fec | ||
|
|
bd047cdc6a | ||
|
|
477f9e8753 | ||
|
|
183ea42f94 | ||
|
|
57a17eb416 | ||
|
|
be24510f16 | ||
|
|
05c534d855 | ||
|
|
910169dba7 | ||
|
|
0fc74feddc | ||
|
|
a9ea294514 | ||
|
|
42e0450d87 | ||
|
|
08c0feb58a | ||
|
|
60aaf76ed2 | ||
|
|
bd706beba5 | ||
|
|
b85a0a349a | ||
|
|
a97bc2af6d | ||
|
|
a5dc90c8cd | ||
|
|
e90521b5a4 | ||
|
|
10c598834a | ||
|
|
e58b34b82c | ||
|
|
02e1c921ac | ||
|
|
fcb14fa70e | ||
|
|
46e18128c7 | ||
|
|
e06d5247ef | ||
|
|
02195b92a7 | ||
|
|
7945155a0f | ||
|
|
edb6043c2c | ||
|
|
971481ba51 | ||
|
|
db8e456603 | ||
|
|
d1b4f24a4a | ||
|
|
4eb39ed53b | ||
|
|
6c7236ffd5 | ||
|
|
f0def040ac | ||
|
|
ee8dff2dc9 | ||
|
|
df86a6d48c | ||
|
|
b3958b3d12 | ||
|
|
8dd22703a7 | ||
|
|
c7e2280d23 | ||
|
|
2c239a6ee2 | ||
|
|
43709fbc74 | ||
|
|
52cd486e1d | ||
|
|
175f302a7f | ||
|
|
070bbd5825 | ||
|
|
cdeb4004c9 | ||
|
|
6bb162e5f5 | ||
|
|
8282442939 | ||
|
|
1f4f2af2f2 | ||
|
|
f1bb0e465a | ||
|
|
6dab4399c2 | ||
|
|
e87465d076 | ||
|
|
2f53b0dcdb | ||
|
|
b2e5212d0f | ||
|
|
28c9999c10 | ||
|
|
edb31fb412 | ||
|
|
2f0ea24552 | ||
|
|
7d09fdc5a4 | ||
|
|
23dce48b23 | ||
|
|
d7d308ca09 | ||
|
|
0e412361ad | ||
|
|
d563a99fb8 | ||
|
|
6ce4c2e182 | ||
|
|
e31d6d4062 | ||
|
|
f2f421b494 | ||
|
|
46836e12b5 | ||
|
|
3fc2611bf0 | ||
|
|
b4d8c411bd | ||
|
|
82b7d6980c | ||
|
|
895b233605 | ||
|
|
d9e6b5348b | ||
|
|
1934a64864 | ||
|
|
c412642668 | ||
|
|
793fe9aee1 | ||
|
|
ddc54d2ca4 | ||
|
|
39e5f0a364 | ||
|
|
43ed9ec859 | ||
|
|
8ba44fca79 | ||
|
|
27dbefaecf | ||
|
|
b4a13913c7 | ||
|
|
f842266b2e | ||
|
|
ad0cc858ed | ||
|
|
4bb7180de9 | ||
|
|
7a4faa480d | ||
|
|
421be5d738 | ||
|
|
b8eaf10974 | ||
|
|
92a4bf27cf | ||
|
|
2672838b64 | ||
|
|
1c96071ddc | ||
|
|
71cdf759da | ||
|
|
93ebd213de | ||
|
|
a32ba8f214 | ||
|
|
d416f70a6e | ||
|
|
ba9e1dd0ba | ||
|
|
d513f74b70 | ||
|
|
47f92f8f14 | ||
|
|
9aa669d735 | ||
|
|
99cab6f34a | ||
|
|
547e7dccf7 | ||
|
|
dce9a89407 | ||
|
|
c1cdddd974 | ||
|
|
4bce77dd4b | ||
|
|
3a79810944 | ||
|
|
5b3fbdddb3 | ||
|
|
25e9ecb5a2 | ||
|
|
415515840c | ||
|
|
9ba14be12e | ||
|
|
f1321946c5 | ||
|
|
230b69abf4 | ||
|
|
0d96f80ac8 |
8
.github/CONTRIBUTING.md
vendored
8
.github/CONTRIBUTING.md
vendored
@@ -68,12 +68,12 @@ In such cases you can visit the URL of the failed deployment and append `/_logs`
|
|||||||
|
|
||||||
The logs of this deployment will contain the actual error which may help you to understand what went wrong.
|
The logs of this deployment will contain the actual error which may help you to understand what went wrong.
|
||||||
|
|
||||||
### @zeit/node-file-trace
|
### @vercel/nft
|
||||||
|
|
||||||
Some of the Builders use `@zeit/node-file-trace` to tree-shake files before deployment. If you suspect an error with this tree-shaking mechanism, you can create the following script in your project:
|
Some of the Builders use `@vercel/nft` to tree-shake files before deployment. If you suspect an error with this tree-shaking mechanism, you can create the following script in your project:
|
||||||
|
|
||||||
```js
|
```js
|
||||||
const trace = require('@zeit/node-file-trace');
|
const trace = require('@vercel/nft');
|
||||||
trace(['path/to/entrypoint.js'], {
|
trace(['path/to/entrypoint.js'], {
|
||||||
ts: true,
|
ts: true,
|
||||||
mixedModules: true,
|
mixedModules: true,
|
||||||
@@ -82,7 +82,7 @@ trace(['path/to/entrypoint.js'], {
|
|||||||
.then(e => console.error(e));
|
.then(e => console.error(e));
|
||||||
```
|
```
|
||||||
|
|
||||||
When you run this script, you'll see all imported files. If anything file is missing, the bug is in [@zeit/node-file-trace](https://github.com/vercel/node-file-trace) and not the Builder.
|
When you run this script, you'll see all imported files. If anything file is missing, the bug is in [@vercel/nft](https://github.com/vercel/nft) and not the Builder.
|
||||||
|
|
||||||
## Deploy a Builder with existing project
|
## Deploy a Builder with existing project
|
||||||
|
|
||||||
|
|||||||
2
.github/workflows/cancel.yml
vendored
2
.github/workflows/cancel.yml
vendored
@@ -11,7 +11,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 2
|
timeout-minutes: 2
|
||||||
steps:
|
steps:
|
||||||
- uses: styfle/cancel-workflow-action@0.3.2
|
- uses: styfle/cancel-workflow-action@0.4.1
|
||||||
with:
|
with:
|
||||||
workflow_id: 849295, 849296, 849297, 849298
|
workflow_id: 849295, 849296, 849297, 849298
|
||||||
access_token: ${{ github.token }}
|
access_token: ${{ github.token }}
|
||||||
|
|||||||
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: 10
|
node-version: 12
|
||||||
- name: Install
|
- name: Install
|
||||||
run: yarn install --check-files --frozen-lockfile
|
run: yarn install --check-files --frozen-lockfile
|
||||||
- name: Build
|
- name: Build
|
||||||
|
|||||||
8
.github/workflows/test-integration-cli.yml
vendored
8
.github/workflows/test-integration-cli.yml
vendored
@@ -20,8 +20,12 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: git fetch origin master --depth=10
|
with:
|
||||||
- run: git fetch origin ${{ github.ref }} --depth=10
|
fetch-depth: 100
|
||||||
|
- run: git --version
|
||||||
|
- run: git fetch origin master --depth=100
|
||||||
|
- run: git fetch origin ${{ github.ref }} --depth=100
|
||||||
|
- run: git diff origin/master...HEAD --name-only
|
||||||
- run: yarn install
|
- run: yarn install
|
||||||
- run: yarn run build
|
- run: yarn run build
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
|
|||||||
8
.github/workflows/test-integration-dev.yml
vendored
8
.github/workflows/test-integration-dev.yml
vendored
@@ -20,8 +20,12 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: git fetch origin master --depth=10
|
with:
|
||||||
- run: git fetch origin ${{ github.ref }} --depth=10
|
fetch-depth: 100
|
||||||
|
- run: git --version
|
||||||
|
- run: git fetch origin master --depth=100
|
||||||
|
- run: git fetch origin ${{ github.ref }} --depth=100
|
||||||
|
- run: git diff origin/master...HEAD --name-only
|
||||||
- name: Install Hugo
|
- name: Install Hugo
|
||||||
if: matrix.os == 'macos-latest'
|
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: 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/
|
||||||
|
|||||||
8
.github/workflows/test-integration-once.yml
vendored
8
.github/workflows/test-integration-once.yml
vendored
@@ -15,8 +15,12 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: git fetch origin master --depth=10
|
with:
|
||||||
- run: git fetch origin ${{ github.ref }} --depth=10
|
fetch-depth: 100
|
||||||
|
- run: git --version
|
||||||
|
- run: git fetch origin master --depth=100
|
||||||
|
- run: git fetch origin ${{ github.ref }} --depth=100
|
||||||
|
- run: git diff origin/master...HEAD --name-only
|
||||||
- run: yarn install
|
- run: yarn install
|
||||||
- run: yarn run build
|
- run: yarn run build
|
||||||
- run: yarn test-integration-once --clean false
|
- run: yarn test-integration-once --clean false
|
||||||
|
|||||||
10
.github/workflows/test-unit.yml
vendored
10
.github/workflows/test-unit.yml
vendored
@@ -20,9 +20,15 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: git fetch origin master --depth=10
|
with:
|
||||||
- run: git fetch origin ${{ github.ref }} --depth=10
|
fetch-depth: 100
|
||||||
|
- run: git --version
|
||||||
|
- run: git fetch origin master --depth=100
|
||||||
|
- run: git fetch origin ${{ github.ref }} --depth=100
|
||||||
|
- run: git diff origin/master...HEAD --name-only
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node }}
|
||||||
- run: yarn install
|
- run: yarn install
|
||||||
- run: yarn run build
|
- run: yarn run build
|
||||||
- run: yarn run lint
|
- run: yarn run lint
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,5 +1,4 @@
|
|||||||
node_modules
|
node_modules
|
||||||
package-lock.json
|
|
||||||
dist
|
dist
|
||||||
.vscode
|
.vscode
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
#### Why This Error Occurred
|
#### Why This Error Occurred
|
||||||
|
|
||||||
When supplying `regions` or `scale` settings, you
|
When supplying `regions` configuration, you
|
||||||
used an unknown or invalid dc identifier.
|
used an unknown or invalid DC identifier.
|
||||||
|
|
||||||
#### Possible Ways to Fix It
|
#### Possible Ways to Fix It
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ and DCs have to be in _lowercase_.
|
|||||||
- `gru`
|
- `gru`
|
||||||
- `iad`
|
- `iad`
|
||||||
|
|
||||||
In `now-cli`, they currently are transformed to
|
In Vercel CLI, they currently are transformed to
|
||||||
DC identifiers before being sent to our APIs.
|
DC identifiers before being sent to our APIs.
|
||||||
|
|
||||||
**Valid DC identifiers**:
|
**Valid DC identifiers**:
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
# Missing `--dotenv` Target
|
|
||||||
|
|
||||||
#### Why This Error Occurred
|
|
||||||
|
|
||||||
You specified a path as the value for the `--dotenv` flag, but the target of the path doesn't exist.
|
|
||||||
|
|
||||||
#### Possible Ways to Fix It
|
|
||||||
|
|
||||||
Make sure the target file you've specified exists and is readable by Vercel CLI. In addition, please ensure that the filename starts with a dot (example: `.env`) - then it should work.
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#### Why This Error Occurred
|
#### Why This Error Occurred
|
||||||
|
|
||||||
This error occurs when you have your application is not configured for Serverless Next.js build output.
|
This error occurs when your application is not configured for Serverless Next.js build output.
|
||||||
|
|
||||||
#### Possible Ways to Fix It
|
#### Possible Ways to Fix It
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
# Can't Set `regions` and `scale` Options Simultaneously
|
|
||||||
|
|
||||||
#### Why This Error Occurred
|
|
||||||
|
|
||||||
Your deployment's configuration contains a `regions` and `scale`
|
|
||||||
configuration simultaneously.
|
|
||||||
|
|
||||||
#### Possible Ways to Fix It
|
|
||||||
|
|
||||||
The `regions` setting is intended to be used to scale the
|
|
||||||
deployment to the supplied regions or datacenters identifiers
|
|
||||||
with default scale settings.
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"regions": ["sfo", "bru", "gru", "iad"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The `scale` object allows you to be more granular: you can decide a
|
|
||||||
`min` and `max` number of instances per region:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"scale": {
|
|
||||||
"sfo": { "min": 0, "max": 10 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
To solve this problem, use only one of the two ways of deciding
|
|
||||||
where to scale your deployment to.
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
# Invalid Region or DC Identifier
|
|
||||||
|
|
||||||
#### Why This Error Occurred
|
|
||||||
|
|
||||||
When supplying a region or DC identifier in `vercel scale`,
|
|
||||||
we weren't able to recognize the value as valid.
|
|
||||||
|
|
||||||
#### Possible Ways to Fix It
|
|
||||||
|
|
||||||
Check your `vercel scale` command make sure you are using a
|
|
||||||
valid string after the URL. Regions
|
|
||||||
and DCs have to be in _lowercase_.
|
|
||||||
|
|
||||||
**Valid region identifiers**:
|
|
||||||
|
|
||||||
- `all` (special, used to scale to all DCs, can only appear once)
|
|
||||||
- `sfo`
|
|
||||||
- `bru`
|
|
||||||
- `gru`
|
|
||||||
- `iad`
|
|
||||||
|
|
||||||
In Vercel CLI, they currently are transformed to
|
|
||||||
DC identifiers before being sent to our APIs.
|
|
||||||
|
|
||||||
**Valid DC identifiers**:
|
|
||||||
|
|
||||||
- `sfo1`
|
|
||||||
- `bru1`
|
|
||||||
- `gru1`
|
|
||||||
- `iad1`
|
|
||||||
|
|
||||||
To pass multiple ones, use a comma:
|
|
||||||
|
|
||||||
```
|
|
||||||
vercel scale my-url-123.now.sh sfo,bru,gru 1 5
|
|
||||||
```
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
# `vercel scale ls` is deprecated
|
|
||||||
|
|
||||||
#### Why This Error Occurred
|
|
||||||
|
|
||||||
We have stopped supporting this command, in favor of
|
|
||||||
better alternatives.
|
|
||||||
|
|
||||||
`vercel scale ls` used to list all the scaling rules
|
|
||||||
for all your deployments. The output would be too long,
|
|
||||||
and it would often be hard to find the information
|
|
||||||
you needed in a long list of items.
|
|
||||||
|
|
||||||
#### Possible Ways to Fix It
|
|
||||||
|
|
||||||
Instead of using `vercel scale ls` to list all your deployments
|
|
||||||
and their scaling rules, first use `vercel ls` to find
|
|
||||||
your deployment:
|
|
||||||
|
|
||||||
```console
|
|
||||||
vercel ls
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, select the URL of your deployment, which uniquely identifies it, and run:
|
|
||||||
|
|
||||||
```console
|
|
||||||
vercel inspect my-deployment-12345.now.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
The `inspect` subcommand will give you your deployment's scale information, including what datacenters it's enabled on, the
|
|
||||||
current number of instances and minimums/maximums.
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
# Scaling path alias
|
|
||||||
|
|
||||||
#### Why This Error Occurred
|
|
||||||
|
|
||||||
You tried to use `vercel scale` on a path alias (`vercel alias -r rules.json`).
|
|
||||||
|
|
||||||
#### Possible Ways to Fix It
|
|
||||||
|
|
||||||
Path aliases are routes to instances. Instances can be scaled independent from each other.
|
|
||||||
You can view path aliases by running `vercel alias ls <id>`.
|
|
||||||
|
|
||||||
Documentation for Path Aliases can be found [here](https://vercel.com/docs/features/path-aliases).
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
# No minimum scale settings on Cloud v2 deployments
|
|
||||||
|
|
||||||
#### Why This Error Occurred
|
|
||||||
|
|
||||||
An attempt was made at scaling a Cloud v2 deployment with a `min` scale
|
|
||||||
setting. This isn't supported yet.
|
|
||||||
|
|
||||||
#### Possible Ways to Fix It
|
|
||||||
|
|
||||||
Ensure your scale settings (in `vercel.json`, the command you're running
|
|
||||||
or from a previous deployment who's alias you're trying to overwrite) has
|
|
||||||
the `min` scale setting set to `0`. You can do this by running
|
|
||||||
|
|
||||||
```
|
|
||||||
vercel scale <deployment> 0 10
|
|
||||||
```
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
# Verification Timeout
|
|
||||||
|
|
||||||
#### Why This Error Occurred
|
|
||||||
|
|
||||||
After the deployment build completed and the deployment state was set to `READY`,
|
|
||||||
instances failed to initialize properly.
|
|
||||||
|
|
||||||
The CLI attempted to verify that the scale settings of your instances matched,
|
|
||||||
but it couldn't do so within the allotted time (defaults to 2 minutes).
|
|
||||||
|
|
||||||
#### Possible Ways to Fix It
|
|
||||||
|
|
||||||
Instance verification is the process of ensuring that after
|
|
||||||
your deployment is ready, we can actually run (instantiate) your code.
|
|
||||||
|
|
||||||
If you configured [regions or scale](https://vercel.com/docs/features/scaling),
|
|
||||||
we ensure the minimums and maximums are met for the regions you enabled.
|
|
||||||
|
|
||||||
If you think your code is taking too long to instantiate, this can be due
|
|
||||||
to slow boot up times. You can supply `--no-verify` to skip verification
|
|
||||||
if you are confident your code runs properly.
|
|
||||||
|
|
||||||
If your application is not listening on a HTTP port, we might be failing to
|
|
||||||
instantiate your deployment as well. It might not be showing any errors,
|
|
||||||
but the deployment instance is effectively not routable and cannot be
|
|
||||||
verified.
|
|
||||||
|
|
||||||
If your instances are crashing before an HTTP port is exposed, verification
|
|
||||||
will fail as well. Double check your logs (e.g.: by running `vercel logs <url>`)
|
|
||||||
@@ -17,11 +17,3 @@ To get started deploying AMP with Vercel, you can use the [Vercel CLI](https://v
|
|||||||
```shell
|
```shell
|
||||||
$ vercel init amp
|
$ vercel init amp
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new AMP project with a single command from your terminal using Vercel CLI:
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -19,11 +19,3 @@ To get started with Angular, you can use the [Angular CLI](https://cli.angular.i
|
|||||||
```shell
|
```shell
|
||||||
$ ng new
|
$ ng new
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Angular project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,21 +1,19 @@
|
|||||||

|

|
||||||
|
|
||||||
This is a [Blitz.js](https://blitzjs.com/) project bootstrapped with `npx blitz new`.
|
# Blitz.js Example
|
||||||
|
|
||||||
## Getting Started
|
This directory is a brief example of a [Blitz.js](https://blitzjs.com/) project that can be deployed with Vercel and zero configuration.
|
||||||
|
|
||||||
First, run the development server:
|
## Deploy Your Own
|
||||||
|
|
||||||
```bash
|
Deploy your own Blitz.js project with Vercel by viewing the [documentation on deploying to Vercel](https://blitzjs.com/docs/deploy-vercel)
|
||||||
npx blitz start
|
|
||||||
|
[](https://vercel.com/import/project?template=https://github.com/vercel/vercel/tree/master/examples/blitzjs)
|
||||||
|
|
||||||
|
### How We Created This Example
|
||||||
|
|
||||||
|
To get started with Blitz.js, you can use [npx](https://www.npmjs.com/package/npx) to initialize the project:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ npx blitz new
|
||||||
```
|
```
|
||||||
|
|
||||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
|
||||||
|
|
||||||
## Learn More
|
|
||||||
|
|
||||||
To learn more about Blitz.js, view [Blitzjs.com](https://blitzjs.com)
|
|
||||||
|
|
||||||
## Deploy on Vercel
|
|
||||||
|
|
||||||
View the [documentation on deploying to Vercel](https://blitzjs.com/docs/deploy-vercel)
|
|
||||||
|
|||||||
@@ -17,11 +17,3 @@ To get started deploying Brunch with Vercel, you can use the [Brunch CLI](https:
|
|||||||
```shell
|
```shell
|
||||||
$ brunch new project-name -s es6
|
$ brunch new project-name -s es6
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Brunch project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -19,11 +19,3 @@ To get started with React, along with [Serverless Functions](https://vercel.com/
|
|||||||
```shell
|
```shell
|
||||||
$ npx create-react-app my-app
|
$ npx create-react-app my-app
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new React project, along with [Serverless Functions](https://vercel.com/docs/v2/serverless-functions/introduction), with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -17,11 +17,3 @@ To get started deploying a Custom Built project with Vercel, you can use the [Ve
|
|||||||
```shell
|
```shell
|
||||||
$ vercel init custom-build
|
$ vercel init custom-build
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Custom Built project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -15,11 +15,3 @@ To get started with Docusaurus on Vercel, you can use the [Docusaurus CLI](https
|
|||||||
```shell
|
```shell
|
||||||
$ npx @docusaurus/init@next init my-website classic
|
$ npx @docusaurus/init@next init my-website classic
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Docusaurus project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -19,11 +19,3 @@ To get started with Docusaurus for deployment with Vercel, you can use the [Docu
|
|||||||
```shell
|
```shell
|
||||||
$ docusaurus-init
|
$ docusaurus-init
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Docusaurus project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -15,11 +15,3 @@ To get started with Dojo on Vercel, you can use the [Dojo CLI](https://github.co
|
|||||||
```shell
|
```shell
|
||||||
$ vercel init dojo
|
$ vercel init dojo
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Dojo project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -19,11 +19,3 @@ To get started with Eleventy for deployment with Vercel, you can use [npx](https
|
|||||||
```shell
|
```shell
|
||||||
$ npx degit 11ty/eleventy-base-blog my-11ty-project
|
$ npx degit 11ty/eleventy-base-blog my-11ty-project
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Eleventy project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
3
examples/ember/.gitignore
vendored
3
examples/ember/.gitignore
vendored
@@ -27,3 +27,6 @@
|
|||||||
# Environment Variables
|
# Environment Variables
|
||||||
.env
|
.env
|
||||||
.env.build
|
.env.build
|
||||||
|
|
||||||
|
# Vercel
|
||||||
|
.vercel
|
||||||
|
|||||||
@@ -19,11 +19,3 @@ To get started with Ember for deployment with Vercel, you can use the [Ember CLI
|
|||||||
```shell
|
```shell
|
||||||
$ npx ember-cli new ember-project
|
$ npx ember-cli new ember-project
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Ember project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
3
examples/ember/public/robots.txt
Normal file
3
examples/ember/public/robots.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# http://www.robotstxt.org
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
||||||
@@ -19,11 +19,3 @@ To get started with Gatsby on Vercel, you can use the [Gatsby CLI](https://www.g
|
|||||||
```shell
|
```shell
|
||||||
$ gatsby new gatsby-site
|
$ gatsby new gatsby-site
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Gatsby project, along with [Serverless Functions](https://vercel.com/docs/v2/serverless-functions/introduction), with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ function Index() {
|
|||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
<a
|
<a
|
||||||
href="https://github.com/vercel/vercel/blob/master/gatsby"
|
href="https://github.com/vercel/vercel/tree/master/examples/gatsby"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer noopener"
|
rel="noreferrer noopener"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -19,11 +19,3 @@ To get started with Gridsome for deployment with Vercel, you can use the [Gridso
|
|||||||
```shell
|
```shell
|
||||||
$ gridsome create my-website
|
$ gridsome create my-website
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Gridsome project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -19,11 +19,3 @@ To get started with Hexo for deployment with Vercel, you can use the [Hexo CLI](
|
|||||||
```shell
|
```shell
|
||||||
$ hexo init project-name
|
$ hexo init project-name
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Hexo project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -17,11 +17,3 @@ To get started with Hugo for deployment with Vercel, you can use the [Hugo CLI](
|
|||||||
```shell
|
```shell
|
||||||
$ hugo new site project-name
|
$ hugo new site project-name
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Hugo project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -15,13 +15,5 @@ _Live Example: https://ionic-angular.now-examples.now.sh_
|
|||||||
To get started with Ionic Angular deployed with Vercel, you can use the [Ionic CLI](https://ionicframework.com/docs/cli) to initialize the project:
|
To get started with Ionic Angular deployed with Vercel, you can use the [Ionic CLI](https://ionicframework.com/docs/cli) to initialize the project:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ npx ionic start [project-name] conference --type angular && cd [project-name]
|
$ npx @ionic/cli start [project-name] conference --type angular && cd [project-name]
|
||||||
```
|
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Ionic Angular project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
```
|
||||||
|
|||||||
13585
examples/ionic-angular/package-lock.json
generated
Normal file
13585
examples/ionic-angular/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -31,7 +31,7 @@
|
|||||||
"@ionic-native/in-app-browser": "5.0.0-beta.15",
|
"@ionic-native/in-app-browser": "5.0.0-beta.15",
|
||||||
"@ionic-native/splash-screen": "5.0.0-beta.15",
|
"@ionic-native/splash-screen": "5.0.0-beta.15",
|
||||||
"@ionic-native/status-bar": "5.0.0-beta.15",
|
"@ionic-native/status-bar": "5.0.0-beta.15",
|
||||||
"@ionic/angular": "^5.0.6",
|
"@ionic/angular": "^5.1.1",
|
||||||
"@ionic/storage": "^2.1.3",
|
"@ionic/storage": "^2.1.3",
|
||||||
"cordova-android": "^8.1.0",
|
"cordova-android": "^8.1.0",
|
||||||
"cordova-ios": "^5.1.1",
|
"cordova-ios": "^5.1.1",
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ export class MapPage implements AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const googleMaps = await getGoogleMaps(
|
const googleMaps = await getGoogleMaps(
|
||||||
'AIzaSyB8pf6ZdFQj5qw7rc_HSGrhUwQKfIe9ICw'
|
'YOUR_API_KEY_HERE'
|
||||||
);
|
);
|
||||||
|
|
||||||
let map;
|
let map;
|
||||||
|
|||||||
@@ -17,11 +17,3 @@ To get started with Ionic React deployed with Vercel, you can use the [Ionic CLI
|
|||||||
```shell
|
```shell
|
||||||
$ npx ionic start [project-name] conference --type react && cd [project-name]
|
$ npx ionic start [project-name] conference --type react && cd [project-name]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Ionic React project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -17,11 +17,3 @@ To get started with Jekyll for deployment with Vercel, you can use the [Jekyll C
|
|||||||
```shell
|
```shell
|
||||||
$ jekyll new my-blog
|
$ jekyll new my-blog
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Jekyll project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -17,11 +17,3 @@ To get started with Middleman for deployment with Vercel, you can use the [Middl
|
|||||||
```shell
|
```shell
|
||||||
$ middleman init project-name
|
$ middleman init project-name
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Middleman project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
14
examples/nextjs/.gitignore
vendored
14
examples/nextjs/.gitignore
vendored
@@ -11,20 +11,24 @@
|
|||||||
# next.js
|
# next.js
|
||||||
/.next/
|
/.next/
|
||||||
/out/
|
/out/
|
||||||
!public/
|
|
||||||
|
|
||||||
# production
|
# production
|
||||||
/build
|
/build
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.env*
|
*.pem
|
||||||
|
|
||||||
# debug
|
# debug
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
yarn-debug.log*
|
yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
|
|
||||||
# Environment Variables
|
# local env files
|
||||||
.env
|
.env.local
|
||||||
.env.build
|
.env.development.local
|
||||||
|
.env.test.local
|
||||||
|
.env.production.local
|
||||||
|
|
||||||
|
# vercel
|
||||||
|
.vercel
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/zeit/next.js/tree/canary/packages/create-next-app).
|
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ To learn more about Next.js, take a look at the following resources:
|
|||||||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
|
||||||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
|
||||||
|
|
||||||
You can check out [the Next.js GitHub repository](https://github.com/zeit/next.js) - your feedback and contributions are welcome!
|
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
|
||||||
|
|
||||||
## Deploy on Vercel
|
## Deploy on Vercel
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
"start": "next start"
|
"start": "next start"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"next": "^9.3.3",
|
"next": "9.5.1",
|
||||||
"react": "^16.13.0",
|
"react": "16.13.1",
|
||||||
"react-dom": "^16.13.0"
|
"react-dom": "16.13.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
examples/nextjs/pages/_app.js
Normal file
7
examples/nextjs/pages/_app.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import '../styles/globals.css'
|
||||||
|
|
||||||
|
function MyApp({ Component, pageProps }) {
|
||||||
|
return <Component {...pageProps} />
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MyApp
|
||||||
6
examples/nextjs/pages/api/hello.js
Normal file
6
examples/nextjs/pages/api/hello.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
|
||||||
|
|
||||||
|
export default (req, res) => {
|
||||||
|
res.statusCode = 200
|
||||||
|
res.json({ name: 'John Doe' })
|
||||||
|
}
|
||||||
@@ -1,203 +1,65 @@
|
|||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
|
import styles from '../styles/Home.module.css'
|
||||||
|
|
||||||
const Home = () => (
|
export default function Home() {
|
||||||
<div className="container">
|
return (
|
||||||
<Head>
|
<div className={styles.container}>
|
||||||
<title>Create Next App</title>
|
<Head>
|
||||||
<link rel="icon" href="/favicon.ico" />
|
<title>Create Next App</title>
|
||||||
</Head>
|
<link rel="icon" href="/favicon.ico" />
|
||||||
|
</Head>
|
||||||
|
|
||||||
<main>
|
<main className={styles.main}>
|
||||||
<h1 className="title">
|
<h1 className={styles.title}>
|
||||||
Welcome to <a href="https://nextjs.org">Next.js!</a>
|
Welcome to <a href="https://nextjs.org">Next.js!</a>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p className="description">
|
<p className={styles.description}>
|
||||||
Get started by editing <code>pages/index.js</code>
|
Get started by editing{' '}
|
||||||
</p>
|
<code className={styles.code}>pages/index.js</code>
|
||||||
|
</p>
|
||||||
|
|
||||||
<div className="grid">
|
<div className={styles.grid}>
|
||||||
<a href="https://nextjs.org/docs" className="card">
|
<a href="https://nextjs.org/docs" className={styles.card}>
|
||||||
<h3>Documentation →</h3>
|
<h3>Documentation →</h3>
|
||||||
<p>Find in-depth information about Next.js features and API.</p>
|
<p>Find in-depth information about Next.js features and API.</p>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a href="https://nextjs.org/learn" className="card">
|
<a href="https://nextjs.org/learn" className={styles.card}>
|
||||||
<h3>Learn →</h3>
|
<h3>Learn →</h3>
|
||||||
<p>Learn about Next.js in an interactive course with quizzes!</p>
|
<p>Learn about Next.js in an interactive course with quizzes!</p>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="https://github.com/vercel/next.js/tree/master/examples"
|
||||||
|
className={styles.card}
|
||||||
|
>
|
||||||
|
<h3>Examples →</h3>
|
||||||
|
<p>Discover and deploy boilerplate example Next.js projects.</p>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="https://vercel.com/import?filter=next.js&utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
||||||
|
className={styles.card}
|
||||||
|
>
|
||||||
|
<h3>Deploy →</h3>
|
||||||
|
<p>
|
||||||
|
Instantly deploy your Next.js site to a public URL with Vercel.
|
||||||
|
</p>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer className={styles.footer}>
|
||||||
<a
|
<a
|
||||||
href="https://github.com/zeit/next.js/tree/master/examples"
|
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
||||||
className="card"
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
<h3>Examples →</h3>
|
Powered by{' '}
|
||||||
<p>Discover and deploy boilerplate example Next.js projects.</p>
|
<img src="/vercel.svg" alt="Vercel Logo" className={styles.logo} />
|
||||||
</a>
|
</a>
|
||||||
|
</footer>
|
||||||
<a
|
</div>
|
||||||
href="https://vercel.com/new?filter=next.js&utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
)
|
||||||
className="card"
|
}
|
||||||
>
|
|
||||||
<h3>Deploy →</h3>
|
|
||||||
<p>
|
|
||||||
Instantly deploy your Next.js site to a public URL with Vercel.
|
|
||||||
</p>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<a
|
|
||||||
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
Powered by <img src="/vercel.svg" alt="Vercel Logo" />
|
|
||||||
</a>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<style jsx>{`
|
|
||||||
.container {
|
|
||||||
min-height: 100vh;
|
|
||||||
padding: 0 0.5rem;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
padding: 5rem 0;
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
width: 100%;
|
|
||||||
height: 100px;
|
|
||||||
border-top: 1px solid #eaeaea;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer img {
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer a {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title a {
|
|
||||||
color: #0070f3;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title a:hover,
|
|
||||||
.title a:focus,
|
|
||||||
.title a:active {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
margin: 0;
|
|
||||||
line-height: 1.15;
|
|
||||||
font-size: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title,
|
|
||||||
.description {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
line-height: 1.5;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
code {
|
|
||||||
background: #fafafa;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 0.75rem;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
font-family: Menlo, Monaco, Lucida Console, Liberation Mono,
|
|
||||||
DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
|
|
||||||
max-width: 800px;
|
|
||||||
margin-top: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card {
|
|
||||||
margin: 1rem;
|
|
||||||
flex-basis: 45%;
|
|
||||||
padding: 1.5rem;
|
|
||||||
text-align: left;
|
|
||||||
color: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
border: 1px solid #eaeaea;
|
|
||||||
border-radius: 10px;
|
|
||||||
transition: color 0.15s ease, border-color 0.15s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card:hover,
|
|
||||||
.card:focus,
|
|
||||||
.card:active {
|
|
||||||
color: #0070f3;
|
|
||||||
border-color: #0070f3;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card h3 {
|
|
||||||
margin: 0 0 1rem 0;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card p {
|
|
||||||
margin: 0;
|
|
||||||
font-size: 1.25rem;
|
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
.grid {
|
|
||||||
width: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
|
|
||||||
<style jsx global>{`
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
|
||||||
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
`}</style>
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
|
|
||||||
export default Home
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
<svg width="70" height="16" viewBox="0 0 70 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="283" height="64" viewBox="0 0 283 64" fill="none"
|
||||||
<path d="M9.255.05l9.108 15.753H.148L9.255.05zM39.434 8.418c0-2.535-1.87-4.307-4.554-4.307-2.683 0-4.554 1.772-4.554 4.307 0 2.487 2.019 4.308 4.8 4.308 1.526 0 2.905-.566 3.79-1.6l-1.673-.96c-.517.517-1.28.837-2.117.837-1.23 0-2.29-.665-2.658-1.674l-.074-.172h6.966a3.76 3.76 0 00.074-.739zm-7.065-.738l.05-.148c.32-1.058 1.255-1.698 2.436-1.698 1.207 0 2.117.64 2.437 1.698l.05.148h-4.973zM65.945 8.418c0-2.535-1.871-4.307-4.554-4.307-2.683 0-4.554 1.772-4.554 4.307 0 2.487 2.018 4.308 4.8 4.308 1.526 0 2.904-.566 3.79-1.6l-1.673-.96c-.517.517-1.28.837-2.117.837-1.23 0-2.29-.665-2.659-1.674l-.073-.172h6.966a3.76 3.76 0 00.074-.739zM58.88 7.68l.05-.148c.32-1.058 1.255-1.698 2.436-1.698 1.206 0 2.117.64 2.437 1.698l.05.148H58.88zM54.13 7.015l1.673-.96c-.788-1.23-2.19-1.92-3.89-1.92-2.682 0-4.553 1.773-4.553 4.308 0 2.536 1.87 4.308 4.554 4.308 1.698 0 3.101-.69 3.89-1.92l-1.675-.96c-.443.738-1.23 1.157-2.215 1.157-1.55 0-2.585-1.034-2.585-2.585 0-1.55 1.034-2.585 2.585-2.585.96 0 1.772.419 2.215 1.157zM69.637 1.428h-1.97v11.077h1.97V1.428zM31.779 1.428h-2.265L25.182 8.91l-4.333-7.483H18.56l6.622 11.421 6.597-11.421zM45.71 6.4c.222 0 .444.025.665.074V4.382c-1.673.049-3.249.984-3.249 2.141V4.382h-1.97v8.123h1.97v-3.52c0-1.527 1.059-2.585 2.585-2.585z" fill="#000"/>
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
</svg>
|
<path d="M141.04 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.46 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM248.72 16c-11.04 0-19 7.2-19 18s8.96 18 20 18c6.67 0 12.55-2.64 16.19-7.09l-7.65-4.42c-2.02 2.21-5.09 3.5-8.54 3.5-4.79 0-8.86-2.5-10.37-6.5h28.02c.22-1.12.35-2.28.35-3.5 0-10.79-7.96-17.99-19-17.99zm-9.45 14.5c1.25-3.99 4.67-6.5 9.45-6.5 4.79 0 8.21 2.51 9.45 6.5h-18.9zM200.24 34c0 6 3.92 10 10 10 4.12 0 7.21-1.87 8.8-4.92l7.68 4.43c-3.18 5.3-9.14 8.49-16.48 8.49-11.05 0-19-7.2-19-18s7.96-18 19-18c7.34 0 13.29 3.19 16.48 8.49l-7.68 4.43c-1.59-3.05-4.68-4.92-8.8-4.92-6.07 0-10 4-10 10zm82.48-29v46h-9V5h9zM36.95 0L73.9 64H0L36.95 0zm92.38 5l-27.71 48L73.91 5H84.3l17.32 30 17.32-30h10.39zm58.91 12v9.69c-1-.29-2.06-.49-3.2-.49-5.81 0-10 4-10 10V51h-9V17h9v9.2c0-5.08 5.91-9.2 13.2-9.2z" fill="#000"/>
|
||||||
|
</svg>
|
||||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.1 KiB |
123
examples/nextjs/styles/Home.module.css
Normal file
123
examples/nextjs/styles/Home.module.css
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
.container {
|
||||||
|
min-height: 100vh;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
padding: 5rem 0;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
width: 100%;
|
||||||
|
height: 100px;
|
||||||
|
border-top: 1px solid #eaeaea;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer img {
|
||||||
|
margin-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer a {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title a {
|
||||||
|
color: #0070f3;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title a:hover,
|
||||||
|
.title a:focus,
|
||||||
|
.title a:active {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.15;
|
||||||
|
font-size: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title,
|
||||||
|
.description {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
|
line-height: 1.5;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code {
|
||||||
|
background: #fafafa;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0.75rem;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono,
|
||||||
|
Bitstream Vera Sans Mono, Courier New, monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
|
||||||
|
max-width: 800px;
|
||||||
|
margin-top: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
margin: 1rem;
|
||||||
|
flex-basis: 45%;
|
||||||
|
padding: 1.5rem;
|
||||||
|
text-align: left;
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
border: 1px solid #eaeaea;
|
||||||
|
border-radius: 10px;
|
||||||
|
transition: color 0.15s ease, border-color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card:hover,
|
||||||
|
.card:focus,
|
||||||
|
.card:active {
|
||||||
|
color: #0070f3;
|
||||||
|
border-color: #0070f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card h3 {
|
||||||
|
margin: 0 0 1rem 0;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
height: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
.grid {
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
examples/nextjs/styles/globals.css
Normal file
16
examples/nextjs/styles/globals.css
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
html,
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
|
||||||
|
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
@@ -19,11 +19,3 @@ $ npx create-nuxt-app my-app
|
|||||||
```
|
```
|
||||||
|
|
||||||
> The only change made is to amend the output directory in `nuxt.config.js` to `"/public"`.
|
> The only change made is to amend the output directory in `nuxt.config.js` to `"/public"`.
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Nuxt.js project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -19,11 +19,3 @@ To get started with Polymer deployed with Vercel, you can use the [Polymer CLI](
|
|||||||
```shell
|
```shell
|
||||||
$ polymer init
|
$ polymer init
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Polymer project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -19,11 +19,3 @@ To get started with Preact for deployment with Vercel, you can use the [Preact C
|
|||||||
```shell
|
```shell
|
||||||
$ preact create default my-project
|
$ preact create default my-project
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Preact project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||

|

|
||||||
|
|
||||||
# RedwoodJS Example
|
# RedwoodJS Example
|
||||||
|
|
||||||
@@ -19,11 +19,3 @@ To get started with RedwoodJS on Vercel, you can [use Yarn to initialize](https:
|
|||||||
```shell
|
```shell
|
||||||
$ yarn create redwood-app ./my-redwood-app
|
$ yarn create redwood-app ./my-redwood-app
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new RedwoodJS project, along with [Serverless Functions](https://vercel.com/docs/v2/serverless-functions/introduction), with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@redwoodjs/api": "0.14.0"
|
"@redwoodjs/api": "0.15.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@redwoodjs/core": "0.14.0"
|
"@redwoodjs/core": "0.15.0"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "@redwoodjs/eslint-config"
|
"extends": "@redwoodjs/eslint-config"
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
"defaults"
|
"defaults"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@redwoodjs/router": "0.14.0",
|
"@redwoodjs/router": "0.15.0",
|
||||||
"@redwoodjs/web": "0.14.0",
|
"@redwoodjs/web": "0.15.0",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1"
|
"react-dom": "^16.13.1"
|
||||||
|
|||||||
14339
examples/redwoodjs/yarn.lock
Normal file
14339
examples/redwoodjs/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -19,11 +19,3 @@ To get started with Saber on Vercel, you can use [`npm init`](https://docs.npmjs
|
|||||||
```shell
|
```shell
|
||||||
$ npm init site my-saber-site
|
$ npm init site my-saber-site
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Saber project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -19,11 +19,3 @@ $ npx degit "sveltejs/sapper-template#webpack" my-sapper-app
|
|||||||
```
|
```
|
||||||
|
|
||||||
> The only change made is to change the build script in `package.json` to be `"sapper export"`.
|
> The only change made is to change the build script in `package.json` to be `"sapper export"`.
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Sapper project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -19,11 +19,3 @@ To get started deploying Scully with Vercel, you can use the [Vercel CLI](https:
|
|||||||
```shell
|
```shell
|
||||||
$ vercel init scully
|
$ vercel init scully
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Scully project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -17,11 +17,3 @@ To get started with Stencil deployed with Vercel, you can use the [Stencil proje
|
|||||||
```shell
|
```shell
|
||||||
$ npm init stencil
|
$ npm init stencil
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Stencil project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -17,11 +17,3 @@ To get started with Svelte, along with [Serverless Functions](https://vercel.com
|
|||||||
```shell
|
```shell
|
||||||
$ npx degit sveltejs/template my-svelte-project
|
$ npx degit sveltejs/template my-svelte-project
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new Svelte project, along with [Serverless Functions](https://vercel.com/docs/v2/serverless-functions/introduction), with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -2,17 +2,17 @@
|
|||||||
"name": "svelte-app",
|
"name": "svelte-app",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@rollup/plugin-commonjs": "^13.0.0",
|
||||||
|
"@rollup/plugin-node-resolve": "^8.1.0",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"rollup": "^1.10.1",
|
"rollup": "^2.18.0",
|
||||||
"rollup-plugin-commonjs": "^9.3.4",
|
|
||||||
"rollup-plugin-livereload": "^1.0.0",
|
"rollup-plugin-livereload": "^1.0.0",
|
||||||
"rollup-plugin-node-resolve": "^4.2.3",
|
|
||||||
"rollup-plugin-svelte": "^5.0.3",
|
"rollup-plugin-svelte": "^5.0.3",
|
||||||
"rollup-plugin-terser": "^4.0.4",
|
"rollup-plugin-terser": "^6.1.0",
|
||||||
"svelte": "^3.0.0"
|
"svelte": "^3.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"sirv-cli": "^0.4.4"
|
"sirv-cli": "^1.0.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rollup -c",
|
"build": "rollup -c",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import svelte from 'rollup-plugin-svelte';
|
import svelte from 'rollup-plugin-svelte';
|
||||||
import resolve from 'rollup-plugin-node-resolve';
|
import resolve from '@rollup/plugin-node-resolve';
|
||||||
import commonjs from 'rollup-plugin-commonjs';
|
import commonjs from '@rollup/plugin-commonjs';
|
||||||
import livereload from 'rollup-plugin-livereload';
|
import livereload from 'rollup-plugin-livereload';
|
||||||
import { terser } from 'rollup-plugin-terser';
|
import { terser } from 'rollup-plugin-terser';
|
||||||
|
|
||||||
|
|||||||
@@ -19,11 +19,3 @@ To get started with UmiJS deployed with Vercel, you can use the [Umi CLI](https:
|
|||||||
```shell
|
```shell
|
||||||
$ yarn create umi app-name
|
$ yarn create umi app-name
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deploying From Your Terminal
|
|
||||||
|
|
||||||
You can deploy your new UmiJS project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
|
||||||
|
|
||||||
```shell
|
|
||||||
$ vercel
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@typescript-eslint/eslint-plugin": "2.0.0",
|
"@typescript-eslint/eslint-plugin": "2.0.0",
|
||||||
"@typescript-eslint/parser": "2.0.0",
|
"@typescript-eslint/parser": "2.0.0",
|
||||||
"@zeit/ncc": "0.20.4",
|
"@vercel/ncc": "0.24.0",
|
||||||
"async-retry": "1.2.3",
|
"async-retry": "1.2.3",
|
||||||
"buffer-replace": "1.0.0",
|
"buffer-replace": "1.0.0",
|
||||||
"cheerio": "1.0.0-rc.3",
|
"cheerio": "1.0.0-rc.3",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"husky": "3.0.4",
|
"husky": "3.0.4",
|
||||||
"json5": "2.1.1",
|
"json5": "2.1.1",
|
||||||
"lint-staged": "9.2.5",
|
"lint-staged": "9.2.5",
|
||||||
"node-fetch": "2.6.0",
|
"node-fetch": "2.6.1",
|
||||||
"npm-package-arg": "6.1.0",
|
"npm-package-arg": "6.1.0",
|
||||||
"prettier": "2.0.5"
|
"prettier": "2.0.5"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
"tagline": "Blitz.js: The Fullstack React Framework",
|
"tagline": "Blitz.js: The Fullstack React Framework",
|
||||||
"description": "A brand new Blitz.js app - the result of running `npx blitz new`.",
|
"description": "A brand new Blitz.js app - the result of running `npx blitz new`.",
|
||||||
"website": "https://blitzjs.com",
|
"website": "https://blitzjs.com",
|
||||||
|
"useRuntime": { "src": "package.json", "use": "@vercel/next" },
|
||||||
"detectors": {
|
"detectors": {
|
||||||
"every": [
|
"every": [
|
||||||
{
|
{
|
||||||
@@ -36,6 +37,7 @@
|
|||||||
"description": "A Next.js app and a Serverless Function API.",
|
"description": "A Next.js app and a Serverless Function API.",
|
||||||
"website": "https://nextjs.org",
|
"website": "https://nextjs.org",
|
||||||
"sort": 1,
|
"sort": 1,
|
||||||
|
"useRuntime": { "src": "package.json", "use": "@vercel/next" },
|
||||||
"detectors": {
|
"detectors": {
|
||||||
"every": [
|
"every": [
|
||||||
{
|
{
|
||||||
@@ -57,7 +59,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Gatsby",
|
"name": "Gatsby.js",
|
||||||
"slug": "gatsby",
|
"slug": "gatsby",
|
||||||
"demo": "https://gatsby.now-examples.now.sh",
|
"demo": "https://gatsby.now-examples.now.sh",
|
||||||
"logo": "https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/gatsby.svg",
|
"logo": "https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/gatsby.svg",
|
||||||
@@ -259,7 +261,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Ember",
|
"name": "Ember.js",
|
||||||
"slug": "ember",
|
"slug": "ember",
|
||||||
"demo": "https://ember.now-examples.now.sh",
|
"demo": "https://ember.now-examples.now.sh",
|
||||||
"logo": "https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/ember.svg",
|
"logo": "https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/ember.svg",
|
||||||
@@ -685,10 +687,13 @@
|
|||||||
{
|
{
|
||||||
"name": "RedwoodJS",
|
"name": "RedwoodJS",
|
||||||
"slug": "redwoodjs",
|
"slug": "redwoodjs",
|
||||||
"logo": "https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/redwood.svg",
|
"demo": "https://redwoodjs.now-examples.now.sh",
|
||||||
|
"logo": "https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/redwoodjs.svg",
|
||||||
"tagline": "RedwoodJS is a full-stack framework for the Jamstack.",
|
"tagline": "RedwoodJS is a full-stack framework for the Jamstack.",
|
||||||
"description": "A RedwoodJS app, bootstraped with create-redwood-app.",
|
"description": "A RedwoodJS app, bootstraped with create-redwood-app.",
|
||||||
"website": "https://redwoodjs.com",
|
"website": "https://redwoodjs.com",
|
||||||
|
"useRuntime": { "src": "package.json", "use": "@vercel/redwood" },
|
||||||
|
"ignoreRuntimes": ["@vercel/node"],
|
||||||
"detectors": {
|
"detectors": {
|
||||||
"every": [
|
"every": [
|
||||||
{
|
{
|
||||||
@@ -699,13 +704,13 @@
|
|||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"buildCommand": {
|
"buildCommand": {
|
||||||
"value": "yarn rw db up --no-db-client --auto-approve && yarn rw build"
|
"value": "yarn rw build && yarn rw db up --no-db-client --auto-approve && yarn rw dataMigrate up"
|
||||||
},
|
},
|
||||||
"devCommand": {
|
"devCommand": {
|
||||||
"value": "yarn rw dev"
|
"value": "yarn rw dev --fwd=\"--port=$PORT --open=false\""
|
||||||
},
|
},
|
||||||
"outputDirectory": {
|
"outputDirectory": {
|
||||||
"value": "RedwoodJS default"
|
"placeholder": "RedwoodJS default"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -831,7 +836,7 @@
|
|||||||
"description": "No framework or a unoptimized framework.",
|
"description": "No framework or a unoptimized framework.",
|
||||||
"settings": {
|
"settings": {
|
||||||
"buildCommand": {
|
"buildCommand": {
|
||||||
"placeholder": "`npm run now-build` or `npm run build`"
|
"placeholder": "`npm run vercel-build` or `npm run build`"
|
||||||
},
|
},
|
||||||
"devCommand": {
|
"devCommand": {
|
||||||
"placeholder": "None"
|
"placeholder": "None"
|
||||||
|
|||||||
2
packages/frameworks/index.d.ts
vendored
2
packages/frameworks/index.d.ts
vendored
@@ -20,6 +20,8 @@ export interface Framework {
|
|||||||
website?: string;
|
website?: string;
|
||||||
description: string;
|
description: string;
|
||||||
sort?: number;
|
sort?: number;
|
||||||
|
useRuntime?: { src: string; use: string };
|
||||||
|
ignoreRuntimes?: string[];
|
||||||
detectors?: {
|
detectors?: {
|
||||||
every?: FrameworkDetectionItem[];
|
every?: FrameworkDetectionItem[];
|
||||||
some?: FrameworkDetectionItem[];
|
some?: FrameworkDetectionItem[];
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
<svg fill="none" height="1000" viewBox="0 0 917 1000" width="917" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="m249.557 144.582 194.171 132.54c4.383 2.918 9.502 4.516 14.755 4.606 5.261-.038 10.394-1.641 14.755-4.606l194.319-132.986c7.55-5.406 11.714-14.418 10.957-23.717-.757-9.298-6.322-17.507-14.646-21.6024l-194.171-96.13614c-7.366-3.573948-15.947-3.573948-23.313 0l-193.581 96.13614c-8.474 4.1174-14.113 12.4854-14.783 21.9354-.67 9.451 3.73 18.541 11.537 23.83zm274.879 174.144c.016 8.789 4.318 17.01 11.509 21.991l155.662 106.389c9.965 6.87 23.298 6.012 32.313-2.081l130.579-116.789c5.819-5.199 9.051-12.729 8.823-20.56s-3.892-15.158-10.004-20.005l-124.677-99.702c-9.062-7.199-21.704-7.68-31.28-1.189l-161.416 110.401c-7.064 4.89-11.35 12.914-11.509 21.545zm-387.163 144.724c6.292 5.652 9.526 13.988 8.706 22.437-.817 8.499-5.726 16.052-13.132 20.208l-92.9545 55.72c-9.4227 5.633-21.32 4.82-29.90183-2.041-8.5818-6.861-12.06543-18.346-8.75546-28.865l34.37839-108.172c2.6969-8.57 9.5328-15.175 18.1483-17.533 8.609-2.505 17.8924-.309 24.4928 5.795zm504.168 11.293-168.056-115.007c-8.931-6.01-20.578-6.01-29.509 0l-168.056 115.007c-6.684 4.626-10.919 12.061-11.509 20.208-.435 8.203 2.816 16.169 8.853 21.693l167.909 150.222c4.842 4.319 11.089 6.698 17.558 6.687 6.465-.002 12.708-2.38 17.558-6.687l167.908-150.222c6.056-5.501 9.265-13.5 8.705-21.693-.469-8.146-4.666-15.612-11.361-20.208zm-448.247-29.718-130.4316-116.79c-5.8687-5.331-9.1073-12.995-8.8528-20.95.1419-7.841 3.7705-15.204 9.8856-20.06l124.6768-100.296c9.126-7.179 21.793-7.658 31.428-1.189l161.269 110.401c7.484 4.908 11.998 13.293 11.998 22.288 0 8.994-4.514 17.38-11.998 22.288l-155.515 106.388c-10.025 6.841-23.376 5.985-32.46-2.08zm669.715 167.756-132.792-79.495c-9.862-5.943-22.415-4.739-30.985 2.972l-162.301 144.873c-6.846 6.114-10.062 15.362-8.499 24.441 1.563 9.08 7.681 16.698 16.171 20.135l225.157 91.233c3.088 1.283 6.397 1.939 9.738 1.932 10.449.033 19.936-6.142 24.197-15.751l69.79-156.314c5.68-12.37 1.157-27.062-10.476-34.026zm18.443-190.043 34.379 108.171h-.295c2.542 8.091 1.097 16.919-3.889 23.761-4.986 6.841-12.915 10.876-21.342 10.86-4.728.016-9.37-1.269-13.427-3.715l-93.102-55.72c-7.254-4.243-11.992-11.789-12.689-20.208-.87-8.456 2.373-16.814 8.705-22.436l59.019-52.6c6.668-5.976 15.881-8.156 24.493-5.795 8.609 2.459 15.423 9.098 18.148 17.682zm-492.511 282.761c1.587-9.042-1.597-18.266-8.41-24.368l-162.302-144.873c-8.57-7.711-21.123-8.915-30.985-2.972l-132.7921 79.495c-11.4977 6.995-16.0467 21.502-10.6233 33.878l69.9374 156.314c5.794 13.034 20.774 19.134 33.936 13.818l225.009-91.232c8.492-3.407 14.632-10.995 16.23-20.06zm79.675 44.577 180.598 73.105c8.83 3.779 14.93 12.084 15.935 21.694 1.143 9.729-3.178 19.291-11.214 24.814l-180.745 125.556c-4.331 3.043-9.473 4.7-14.754 4.755-5.277-.082-10.411-1.737-14.755-4.755l-180.597-125.556c-8.066-5.508-12.439-15.061-11.362-24.814 1.206-9.71 7.526-18.006 16.526-21.694l180.597-73.105c6.351-2.532 13.421-2.532 19.771 0z" fill="#bf4722" fill-rule="evenodd"/></svg>
|
|
||||||
|
Before Width: | Height: | Size: 3.0 KiB |
1
packages/frameworks/logos/redwoodjs.svg
Normal file
1
packages/frameworks/logos/redwoodjs.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg fill="none" width="48" height="48" viewBox="0 0 917 1000" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="m249.557 144.582 194.171 132.54c4.383 2.918 9.502 4.516 14.755 4.606 5.261-.038 10.394-1.641 14.755-4.606l194.319-132.986c7.55-5.406 11.714-14.418 10.957-23.717-.757-9.298-6.322-17.507-14.646-21.6024l-194.171-96.13614c-7.366-3.573948-15.947-3.573948-23.313 0l-193.581 96.13614c-8.474 4.1174-14.113 12.4854-14.783 21.9354-.67 9.451 3.73 18.541 11.537 23.83zm274.879 174.144c.016 8.789 4.318 17.01 11.509 21.991l155.662 106.389c9.965 6.87 23.298 6.012 32.313-2.081l130.579-116.789c5.819-5.199 9.051-12.729 8.823-20.56s-3.892-15.158-10.004-20.005l-124.677-99.702c-9.062-7.199-21.704-7.68-31.28-1.189l-161.416 110.401c-7.064 4.89-11.35 12.914-11.509 21.545zm-387.163 144.724c6.292 5.652 9.526 13.988 8.706 22.437-.817 8.499-5.726 16.052-13.132 20.208l-92.9545 55.72c-9.4227 5.633-21.32 4.82-29.90183-2.041-8.5818-6.861-12.06543-18.346-8.75546-28.865l34.37839-108.172c2.6969-8.57 9.5328-15.175 18.1483-17.533 8.609-2.505 17.8924-.309 24.4928 5.795zm504.168 11.293-168.056-115.007c-8.931-6.01-20.578-6.01-29.509 0l-168.056 115.007c-6.684 4.626-10.919 12.061-11.509 20.208-.435 8.203 2.816 16.169 8.853 21.693l167.909 150.222c4.842 4.319 11.089 6.698 17.558 6.687 6.465-.002 12.708-2.38 17.558-6.687l167.908-150.222c6.056-5.501 9.265-13.5 8.705-21.693-.469-8.146-4.666-15.612-11.361-20.208zm-448.247-29.718-130.4316-116.79c-5.8687-5.331-9.1073-12.995-8.8528-20.95.1419-7.841 3.7705-15.204 9.8856-20.06l124.6768-100.296c9.126-7.179 21.793-7.658 31.428-1.189l161.269 110.401c7.484 4.908 11.998 13.293 11.998 22.288 0 8.994-4.514 17.38-11.998 22.288l-155.515 106.388c-10.025 6.841-23.376 5.985-32.46-2.08zm669.715 167.756-132.792-79.495c-9.862-5.943-22.415-4.739-30.985 2.972l-162.301 144.873c-6.846 6.114-10.062 15.362-8.499 24.441 1.563 9.08 7.681 16.698 16.171 20.135l225.157 91.233c3.088 1.283 6.397 1.939 9.738 1.932 10.449.033 19.936-6.142 24.197-15.751l69.79-156.314c5.68-12.37 1.157-27.062-10.476-34.026zm18.443-190.043 34.379 108.171h-.295c2.542 8.091 1.097 16.919-3.889 23.761-4.986 6.841-12.915 10.876-21.342 10.86-4.728.016-9.37-1.269-13.427-3.715l-93.102-55.72c-7.254-4.243-11.992-11.789-12.689-20.208-.87-8.456 2.373-16.814 8.705-22.436l59.019-52.6c6.668-5.976 15.881-8.156 24.493-5.795 8.609 2.459 15.423 9.098 18.148 17.682zm-492.511 282.761c1.587-9.042-1.597-18.266-8.41-24.368l-162.302-144.873c-8.57-7.711-21.123-8.915-30.985-2.972l-132.7921 79.495c-11.4977 6.995-16.0467 21.502-10.6233 33.878l69.9374 156.314c5.794 13.034 20.774 19.134 33.936 13.818l225.009-91.232c8.492-3.407 14.632-10.995 16.23-20.06zm79.675 44.577 180.598 73.105c8.83 3.779 14.93 12.084 15.935 21.694 1.143 9.729-3.178 19.291-11.214 24.814l-180.745 125.556c-4.331 3.043-9.473 4.7-14.754 4.755-5.277-.082-10.411-1.737-14.755-4.755l-180.597-125.556c-8.066-5.508-12.439-15.061-11.362-24.814 1.206-9.71 7.526-18.006 16.526-21.694l180.597-73.105c6.351-2.532 13.421-2.532 19.771 0z" fill="#bf4722" fill-rule="evenodd"/></svg>
|
||||||
|
After Width: | Height: | Size: 3.0 KiB |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/frameworks",
|
"name": "@vercel/frameworks",
|
||||||
"version": "0.0.18-canary.0",
|
"version": "0.1.1",
|
||||||
"main": "frameworks.json",
|
"main": "frameworks.json",
|
||||||
"license": "UNLICENSED",
|
"license": "UNLICENSED",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
15
packages/frameworks/test/frameworks.unit.test.ts
vendored
15
packages/frameworks/test/frameworks.unit.test.ts
vendored
@@ -64,6 +64,21 @@ const Schema = {
|
|||||||
tagline: { type: 'string' },
|
tagline: { type: 'string' },
|
||||||
website: { type: 'string' },
|
website: { type: 'string' },
|
||||||
description: { type: 'string' },
|
description: { type: 'string' },
|
||||||
|
useRuntime: {
|
||||||
|
type: 'object',
|
||||||
|
required: ['src', 'use'],
|
||||||
|
additionalProperties: false,
|
||||||
|
properties: {
|
||||||
|
src: { type: 'string' },
|
||||||
|
use: { type: 'string' },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
ignoreRuntimes: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'string',
|
||||||
|
},
|
||||||
|
},
|
||||||
detectors: {
|
detectors: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/build-utils",
|
"name": "@vercel/build-utils",
|
||||||
"version": "2.4.3-canary.2",
|
"version": "2.5.4-canary.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.js",
|
"types": "./dist/index.d.js",
|
||||||
@@ -29,6 +29,8 @@
|
|||||||
"@types/node-fetch": "^2.1.6",
|
"@types/node-fetch": "^2.1.6",
|
||||||
"@types/semver": "6.0.0",
|
"@types/semver": "6.0.0",
|
||||||
"@types/yazl": "^2.4.1",
|
"@types/yazl": "^2.4.1",
|
||||||
|
"@vercel/frameworks": "0.1.1",
|
||||||
|
"@vercel/ncc": "0.24.0",
|
||||||
"aggregate-error": "3.0.1",
|
"aggregate-error": "3.0.1",
|
||||||
"async-retry": "1.2.3",
|
"async-retry": "1.2.3",
|
||||||
"async-sema": "2.1.4",
|
"async-sema": "2.1.4",
|
||||||
@@ -42,7 +44,7 @@
|
|||||||
"js-yaml": "3.13.1",
|
"js-yaml": "3.13.1",
|
||||||
"minimatch": "3.0.4",
|
"minimatch": "3.0.4",
|
||||||
"multistream": "2.1.1",
|
"multistream": "2.1.1",
|
||||||
"node-fetch": "2.2.0",
|
"node-fetch": "2.6.1",
|
||||||
"semver": "6.1.1",
|
"semver": "6.1.1",
|
||||||
"ts-jest": "24.1.0",
|
"ts-jest": "24.1.0",
|
||||||
"typescript": "3.9.3",
|
"typescript": "3.9.3",
|
||||||
|
|||||||
@@ -2,8 +2,13 @@ import minimatch from 'minimatch';
|
|||||||
import { valid as validSemver } from 'semver';
|
import { valid as validSemver } from 'semver';
|
||||||
import { parse as parsePath, extname } from 'path';
|
import { parse as parsePath, extname } from 'path';
|
||||||
import { Route, Source } from '@vercel/routing-utils';
|
import { Route, Source } from '@vercel/routing-utils';
|
||||||
|
import _frameworks, { Framework } from '@vercel/frameworks';
|
||||||
import { PackageJson, Builder, Config, BuilderFunctions } from './types';
|
import { PackageJson, Builder, Config, BuilderFunctions } from './types';
|
||||||
import { isOfficialRuntime } from './';
|
import { isOfficialRuntime } from './';
|
||||||
|
const frameworkList = _frameworks as Framework[];
|
||||||
|
const slugToFramework = new Map<string | null, Framework>(
|
||||||
|
frameworkList.map(f => [f.slug, f])
|
||||||
|
);
|
||||||
|
|
||||||
interface ErrorResponse {
|
interface ErrorResponse {
|
||||||
code: string;
|
code: string;
|
||||||
@@ -21,6 +26,7 @@ interface Options {
|
|||||||
devCommand?: string | null;
|
devCommand?: string | null;
|
||||||
buildCommand?: string | null;
|
buildCommand?: string | null;
|
||||||
outputDirectory?: string | null;
|
outputDirectory?: string | null;
|
||||||
|
createdAt?: number;
|
||||||
};
|
};
|
||||||
cleanUrls?: boolean;
|
cleanUrls?: boolean;
|
||||||
trailingSlash?: boolean;
|
trailingSlash?: boolean;
|
||||||
@@ -106,7 +112,6 @@ export async function detectBuilders(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiMatches = getApiMatches(options);
|
|
||||||
const sortedFiles = files.sort(sortFiles);
|
const sortedFiles = files.sort(sortFiles);
|
||||||
const apiSortedFiles = files.sort(sortFilesBySegmentCount);
|
const apiSortedFiles = files.sort(sortFilesBySegmentCount);
|
||||||
|
|
||||||
@@ -122,6 +127,16 @@ export async function detectBuilders(
|
|||||||
|
|
||||||
const { projectSettings = {} } = options;
|
const { projectSettings = {} } = options;
|
||||||
const { buildCommand, outputDirectory, framework } = projectSettings;
|
const { buildCommand, outputDirectory, framework } = projectSettings;
|
||||||
|
const ignoreRuntimes = new Set(
|
||||||
|
slugToFramework.get(framework || '')?.ignoreRuntimes
|
||||||
|
);
|
||||||
|
const withTag = options.tag ? `@${options.tag}` : '';
|
||||||
|
const apiMatches = getApiMatches()
|
||||||
|
.filter(b => !ignoreRuntimes.has(b.use))
|
||||||
|
.map(b => {
|
||||||
|
b.use = `${b.use}${withTag}`;
|
||||||
|
return b;
|
||||||
|
});
|
||||||
|
|
||||||
// If either is missing we'll make the frontend static
|
// If either is missing we'll make the frontend static
|
||||||
const makeFrontendStatic = buildCommand === '' || outputDirectory === '';
|
const makeFrontendStatic = buildCommand === '' || outputDirectory === '';
|
||||||
@@ -309,13 +324,6 @@ export async function detectBuilders(
|
|||||||
options
|
options
|
||||||
);
|
);
|
||||||
|
|
||||||
if (frontendBuilder && framework === 'redwoodjs') {
|
|
||||||
// RedwoodJS uses the /api directory differently so we must
|
|
||||||
// clear any existing builders and only use `@vercel/redwood`.
|
|
||||||
builders.length = 0;
|
|
||||||
builders.push(frontendBuilder);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
warnings,
|
warnings,
|
||||||
builders: builders.length ? builders : null,
|
builders: builders.length ? builders : null,
|
||||||
@@ -401,16 +409,15 @@ function getFunction(fileName: string, { functions = {} }: Options) {
|
|||||||
: { fnPattern: null, func: null };
|
: { fnPattern: null, func: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
function getApiMatches({ tag }: Options = {}) {
|
function getApiMatches() {
|
||||||
const withTag = tag ? `@${tag}` : '';
|
|
||||||
const config = { zeroConfig: true };
|
const config = { zeroConfig: true };
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{ src: 'api/**/*.js', use: `@vercel/node${withTag}`, config },
|
{ src: 'api/**/*.js', use: `@vercel/node`, config },
|
||||||
{ src: 'api/**/*.ts', use: `@vercel/node${withTag}`, config },
|
{ src: 'api/**/*.ts', use: `@vercel/node`, config },
|
||||||
{ src: 'api/**/!(*_test).go', use: `@vercel/go${withTag}`, config },
|
{ src: 'api/**/!(*_test).go', use: `@vercel/go`, config },
|
||||||
{ src: 'api/**/*.py', use: `@vercel/python${withTag}`, config },
|
{ src: 'api/**/*.py', use: `@vercel/python`, config },
|
||||||
{ src: 'api/**/*.rb', use: `@vercel/ruby${withTag}`, config },
|
{ src: 'api/**/*.rb', use: `@vercel/ruby`, config },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,6 +435,7 @@ function detectFrontBuilder(
|
|||||||
): Builder {
|
): Builder {
|
||||||
const { tag, projectSettings = {} } = options;
|
const { tag, projectSettings = {} } = options;
|
||||||
const withTag = tag ? `@${tag}` : '';
|
const withTag = tag ? `@${tag}` : '';
|
||||||
|
const { createdAt = 0 } = projectSettings;
|
||||||
let { framework } = projectSettings;
|
let { framework } = projectSettings;
|
||||||
|
|
||||||
const config: Config = {
|
const config: Config = {
|
||||||
@@ -450,7 +458,10 @@ function detectFrontBuilder(
|
|||||||
config.outputDirectory = projectSettings.outputDirectory;
|
config.outputDirectory = projectSettings.outputDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pkg) {
|
if (
|
||||||
|
pkg &&
|
||||||
|
(framework === undefined || createdAt < Date.parse('2020-03-01'))
|
||||||
|
) {
|
||||||
const deps: PackageJson['dependencies'] = {
|
const deps: PackageJson['dependencies'] = {
|
||||||
...pkg.dependencies,
|
...pkg.dependencies,
|
||||||
...pkg.devDependencies,
|
...pkg.devDependencies,
|
||||||
@@ -471,12 +482,10 @@ function detectFrontBuilder(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (framework === 'nextjs' || framework === 'blitzjs') {
|
const f = slugToFramework.get(framework || '');
|
||||||
return { src: 'package.json', use: `@vercel/next${withTag}`, config };
|
if (f && f.useRuntime) {
|
||||||
}
|
const { src, use } = f.useRuntime;
|
||||||
|
return { src, use: `${use}${withTag}`, config };
|
||||||
if (framework === 'redwoodjs') {
|
|
||||||
return { src: 'package.json', use: `@vercel/redwood${withTag}`, config };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entrypoints for other frameworks
|
// Entrypoints for other frameworks
|
||||||
@@ -925,11 +934,10 @@ function getRouteResult(
|
|||||||
const redirectRoutes: Route[] = [];
|
const redirectRoutes: Route[] = [];
|
||||||
const rewriteRoutes: Route[] = [];
|
const rewriteRoutes: Route[] = [];
|
||||||
const errorRoutes: Route[] = [];
|
const errorRoutes: Route[] = [];
|
||||||
const isNextjs =
|
const framework = frontendBuilder?.config?.framework || '';
|
||||||
frontendBuilder &&
|
const use = frontendBuilder?.use || '';
|
||||||
((frontendBuilder.use && frontendBuilder.use.startsWith('@vercel/next')) ||
|
const isNextjs = framework === 'nextjs' || use.startsWith('@vercel/next');
|
||||||
(frontendBuilder.config &&
|
const ignoreRuntimes = slugToFramework.get(framework)?.ignoreRuntimes;
|
||||||
frontendBuilder.config.framework === 'nextjs'));
|
|
||||||
|
|
||||||
if (apiRoutes && apiRoutes.length > 0) {
|
if (apiRoutes && apiRoutes.length > 0) {
|
||||||
if (options.featHandleMiss) {
|
if (options.featHandleMiss) {
|
||||||
@@ -967,11 +975,18 @@ function getRouteResult(
|
|||||||
}
|
}
|
||||||
|
|
||||||
rewriteRoutes.push(...dynamicRoutes);
|
rewriteRoutes.push(...dynamicRoutes);
|
||||||
rewriteRoutes.push({
|
|
||||||
src: '^/api(/.*)?$',
|
if (typeof ignoreRuntimes === 'undefined') {
|
||||||
status: 404,
|
// This route is only necessary to hide the directory listing
|
||||||
continue: true,
|
// to avoid enumerating serverless function names.
|
||||||
});
|
// But it causes issues in `vc dev` for frameworks that handle
|
||||||
|
// their own functions such as redwood, so we ignore.
|
||||||
|
rewriteRoutes.push({
|
||||||
|
src: '^/api(/.*)?$',
|
||||||
|
status: 404,
|
||||||
|
continue: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
defaultRoutes.push(...apiRoutes);
|
defaultRoutes.push(...apiRoutes);
|
||||||
|
|
||||||
@@ -1041,5 +1056,5 @@ function sortFilesBySegmentCount(fileA: string, fileB: string): number {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return fileA.localeCompare(fileB);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,6 +107,13 @@ export interface BuildOptions {
|
|||||||
*/
|
*/
|
||||||
workPath: string;
|
workPath: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The "Root Directory" is assigned to the `workPath` so the `repoRootPath`
|
||||||
|
* is the Git Repository Root. This is only relevant for Monorepos.
|
||||||
|
* See https://vercel.com/blog/monorepos
|
||||||
|
*/
|
||||||
|
repoRootPath?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An arbitrary object passed by the user in the build definition defined
|
* An arbitrary object passed by the user in the build definition defined
|
||||||
* in `vercel.json`.
|
* in `vercel.json`.
|
||||||
|
|||||||
@@ -1080,6 +1080,127 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
|||||||
expect(errorRoutes).toStrictEqual([]);
|
expect(errorRoutes).toStrictEqual([]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Using "Create React App" framework with `next` in dependencies should NOT autodetect Next.js for new projects', async () => {
|
||||||
|
const pkg = {
|
||||||
|
scripts: {
|
||||||
|
dev: 'react-scripts start',
|
||||||
|
build: 'react-scripts build',
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
next: '9.3.5',
|
||||||
|
react: '16.13.1',
|
||||||
|
'react-dom': '16.13.1',
|
||||||
|
'react-scripts': '2.1.1',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const files = ['package.json', 'src/index.js', 'public/favicon.ico'];
|
||||||
|
const projectSettings = {
|
||||||
|
framework: 'create-react-app',
|
||||||
|
buildCommand: 'react-scripts build',
|
||||||
|
createdAt: Date.parse('2020-07-01'),
|
||||||
|
};
|
||||||
|
|
||||||
|
const { builders, errorRoutes } = await detectBuilders(files, pkg, {
|
||||||
|
projectSettings,
|
||||||
|
featHandleMiss,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(builders).toEqual([
|
||||||
|
{
|
||||||
|
use: '@vercel/static-build',
|
||||||
|
src: 'package.json',
|
||||||
|
config: {
|
||||||
|
zeroConfig: true,
|
||||||
|
framework: projectSettings.framework,
|
||||||
|
buildCommand: projectSettings.buildCommand,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
expect(errorRoutes!.length).toBe(1);
|
||||||
|
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Using "Other" framework with Storybook should NOT autodetect Next.js for new projects', async () => {
|
||||||
|
const pkg = {
|
||||||
|
scripts: {
|
||||||
|
dev: 'next dev',
|
||||||
|
build: 'next build',
|
||||||
|
storybook: 'start-storybook -p 6006',
|
||||||
|
'build-storybook': 'build-storybook',
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
next: '9.3.5',
|
||||||
|
react: '16.13.1',
|
||||||
|
'react-dom': '16.13.1',
|
||||||
|
},
|
||||||
|
devDependencies: {
|
||||||
|
'@babel/core': '7.9.0',
|
||||||
|
'@storybook/addon-links': '5.3.18',
|
||||||
|
'@storybook/addons': '5.3.18',
|
||||||
|
'@storybook/react': '5.3.18',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const files = ['package.json', 'pages/api/foo.js', 'index.html'];
|
||||||
|
const projectSettings = {
|
||||||
|
framework: null, // Selected "Other" framework
|
||||||
|
buildCommand: 'yarn build-storybook',
|
||||||
|
createdAt: Date.parse('2020-07-01'),
|
||||||
|
};
|
||||||
|
|
||||||
|
const { builders, errorRoutes } = await detectBuilders(files, pkg, {
|
||||||
|
projectSettings,
|
||||||
|
featHandleMiss,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(builders).toEqual([
|
||||||
|
{
|
||||||
|
use: '@vercel/static-build',
|
||||||
|
src: 'package.json',
|
||||||
|
config: {
|
||||||
|
zeroConfig: true,
|
||||||
|
buildCommand: projectSettings.buildCommand,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
expect(errorRoutes!.length).toBe(1);
|
||||||
|
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Using "Other" framework should autodetect Next.js for old projects', async () => {
|
||||||
|
const pkg = {
|
||||||
|
scripts: {
|
||||||
|
dev: 'next dev',
|
||||||
|
build: 'next build',
|
||||||
|
},
|
||||||
|
dependencies: {
|
||||||
|
next: '9.3.5',
|
||||||
|
react: '16.13.1',
|
||||||
|
'react-dom': '16.13.1',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const files = ['package.json', 'pages/api/foo.js', 'index.html'];
|
||||||
|
const projectSettings = {
|
||||||
|
framework: null, // Selected "Other" framework
|
||||||
|
createdAt: Date.parse('2020-02-01'),
|
||||||
|
};
|
||||||
|
|
||||||
|
const { builders, errorRoutes } = await detectBuilders(files, pkg, {
|
||||||
|
projectSettings,
|
||||||
|
featHandleMiss,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(builders).toEqual([
|
||||||
|
{
|
||||||
|
use: '@vercel/next',
|
||||||
|
src: 'package.json',
|
||||||
|
config: {
|
||||||
|
zeroConfig: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
expect(errorRoutes).toStrictEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
it('api + raw static', async () => {
|
it('api + raw static', async () => {
|
||||||
const files = ['api/endpoint.js', 'index.html', 'favicon.ico'];
|
const files = ['api/endpoint.js', 'index.html', 'favicon.ico'];
|
||||||
|
|
||||||
@@ -1808,23 +1929,38 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
|||||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('RedwoodJS should only use redwood builder', async () => {
|
const redwoodFiles = [
|
||||||
const files = [
|
'package.json',
|
||||||
'package.json',
|
'web/package.json',
|
||||||
'web/index.html',
|
'web/public/robots.txt',
|
||||||
'api/one.js',
|
'web/src/index.html',
|
||||||
'api/two.js',
|
'web/src/index.css',
|
||||||
];
|
'web/src/index.js',
|
||||||
|
'api/package.json',
|
||||||
|
'api/prisma/seeds.js',
|
||||||
|
'api/src/functions/graphql.js',
|
||||||
|
'api/src/graphql/.keep',
|
||||||
|
'api/src/services/.keep',
|
||||||
|
'api/src/lib/db.js',
|
||||||
|
];
|
||||||
|
|
||||||
|
it('RedwoodJS should only use Redwood builder and not Node builder', async () => {
|
||||||
|
const files = [...redwoodFiles].sort();
|
||||||
const projectSettings = {
|
const projectSettings = {
|
||||||
framework: 'redwoodjs',
|
framework: 'redwoodjs',
|
||||||
};
|
};
|
||||||
|
|
||||||
const { builders, errorRoutes } = await detectBuilders(files, null, {
|
const {
|
||||||
|
builders,
|
||||||
|
defaultRoutes,
|
||||||
|
rewriteRoutes,
|
||||||
|
errorRoutes,
|
||||||
|
} = await detectBuilders(files, null, {
|
||||||
projectSettings,
|
projectSettings,
|
||||||
featHandleMiss,
|
featHandleMiss,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(builders).toEqual([
|
expect(builders).toStrictEqual([
|
||||||
{
|
{
|
||||||
use: '@vercel/redwood',
|
use: '@vercel/redwood',
|
||||||
src: 'package.json',
|
src: 'package.json',
|
||||||
@@ -1834,8 +1970,73 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
expect(errorRoutes!.length).toBe(1);
|
expect(defaultRoutes).toStrictEqual([]);
|
||||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
expect(rewriteRoutes).toStrictEqual([]);
|
||||||
|
expect(errorRoutes).toStrictEqual([
|
||||||
|
{
|
||||||
|
status: 404,
|
||||||
|
src: '^/(?!.*api).*$',
|
||||||
|
dest: '/404.html',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('RedwoodJS should allow usage of non-js API and not add 404 api route', async () => {
|
||||||
|
const files = [...redwoodFiles, 'api/golang.go', 'api/python.py'].sort();
|
||||||
|
const projectSettings = {
|
||||||
|
framework: 'redwoodjs',
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
builders,
|
||||||
|
defaultRoutes,
|
||||||
|
rewriteRoutes,
|
||||||
|
errorRoutes,
|
||||||
|
} = await detectBuilders(files, null, {
|
||||||
|
projectSettings,
|
||||||
|
featHandleMiss,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(builders).toStrictEqual([
|
||||||
|
{
|
||||||
|
use: '@vercel/go',
|
||||||
|
src: 'api/golang.go',
|
||||||
|
config: {
|
||||||
|
zeroConfig: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
use: '@vercel/python',
|
||||||
|
src: 'api/python.py',
|
||||||
|
config: {
|
||||||
|
zeroConfig: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
use: '@vercel/redwood',
|
||||||
|
src: 'package.json',
|
||||||
|
config: {
|
||||||
|
zeroConfig: true,
|
||||||
|
framework: 'redwoodjs',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
expect(defaultRoutes).toStrictEqual([
|
||||||
|
{ handle: 'miss' },
|
||||||
|
{
|
||||||
|
src: '^/api/(.+)(?:\\.(?:go|py))$',
|
||||||
|
dest: '/api/$1',
|
||||||
|
check: true,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
expect(rewriteRoutes).toStrictEqual([]);
|
||||||
|
expect(errorRoutes).toStrictEqual([
|
||||||
|
{
|
||||||
|
status: 404,
|
||||||
|
src: '^/(?!.*api).*$',
|
||||||
|
dest: '/404.html',
|
||||||
|
},
|
||||||
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('No framework, only package.json', async () => {
|
it('No framework, only package.json', async () => {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"types": ["node", "jest"],
|
"types": ["node", "jest"],
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"target": "esnext"
|
"target": "es2019"
|
||||||
},
|
},
|
||||||
"include": ["src/**/*"],
|
"include": ["src/**/*"],
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"]
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
declare module 'which-promise' {
|
|
||||||
export default function (name: string): Promise<string>;
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vercel",
|
"name": "vercel",
|
||||||
"version": "20.0.0-canary.4",
|
"version": "20.1.2-canary.5",
|
||||||
"preferGlobal": true,
|
"preferGlobal": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"description": "The command-line interface for Vercel",
|
"description": "The command-line interface for Vercel",
|
||||||
@@ -14,7 +14,6 @@
|
|||||||
"preinstall": "node ./scripts/preinstall.js",
|
"preinstall": "node ./scripts/preinstall.js",
|
||||||
"test-unit": "nyc ava test/unit.js test/dev-builder.unit.js test/dev-router.unit.js test/dev-server.unit.js test/dev-validate.unit.js --serial --fail-fast --verbose",
|
"test-unit": "nyc ava test/unit.js test/dev-builder.unit.js test/dev-router.unit.js test/dev-server.unit.js test/dev-validate.unit.js --serial --fail-fast --verbose",
|
||||||
"test-integration-cli": "ava test/integration.js --serial --fail-fast --verbose",
|
"test-integration-cli": "ava test/integration.js --serial --fail-fast --verbose",
|
||||||
"test-integration-v1": "ava test/integration-v1.js --serial --fail-fast",
|
|
||||||
"test-integration-dev": "ava test/dev/integration.js --serial --fail-fast --verbose",
|
"test-integration-dev": "ava test/dev/integration.js --serial --fail-fast --verbose",
|
||||||
"prepublishOnly": "yarn build",
|
"prepublishOnly": "yarn build",
|
||||||
"coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov",
|
"coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov",
|
||||||
@@ -62,14 +61,11 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/build-utils": "2.4.3-canary.2",
|
"@vercel/build-utils": "2.5.4-canary.0",
|
||||||
"@vercel/go": "1.1.5-canary.0",
|
"@vercel/go": "1.1.6",
|
||||||
"@vercel/next": "2.6.14-canary.1",
|
"@vercel/node": "1.8.4-canary.0",
|
||||||
"@vercel/node": "1.7.4-canary.0",
|
"@vercel/python": "1.2.3",
|
||||||
"@vercel/python": "1.2.2",
|
"@vercel/ruby": "1.2.4",
|
||||||
"@vercel/redwood": "0.0.2-canary.1",
|
|
||||||
"@vercel/ruby": "1.2.3",
|
|
||||||
"@vercel/static-build": "0.17.7-canary.1",
|
|
||||||
"update-notifier": "4.1.0"
|
"update-notifier": "4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -104,9 +100,9 @@
|
|||||||
"@types/universal-analytics": "0.4.2",
|
"@types/universal-analytics": "0.4.2",
|
||||||
"@types/which": "1.3.2",
|
"@types/which": "1.3.2",
|
||||||
"@types/write-json-file": "2.2.1",
|
"@types/write-json-file": "2.2.1",
|
||||||
"@zeit/dockerignore": "0.0.5",
|
"@vercel/frameworks": "0.1.1",
|
||||||
|
"@vercel/ncc": "0.24.0",
|
||||||
"@zeit/fun": "0.11.2",
|
"@zeit/fun": "0.11.2",
|
||||||
"@zeit/ncc": "0.18.5",
|
|
||||||
"@zeit/source-map-support": "0.6.2",
|
"@zeit/source-map-support": "0.6.2",
|
||||||
"ajv": "6.12.2",
|
"ajv": "6.12.2",
|
||||||
"alpha-sort": "2.0.1",
|
"alpha-sort": "2.0.1",
|
||||||
@@ -125,13 +121,9 @@
|
|||||||
"cpy": "7.2.0",
|
"cpy": "7.2.0",
|
||||||
"credit-card": "3.0.1",
|
"credit-card": "3.0.1",
|
||||||
"date-fns": "1.29.0",
|
"date-fns": "1.29.0",
|
||||||
"death": "1.1.0",
|
|
||||||
"debug": "3.1.0",
|
"debug": "3.1.0",
|
||||||
"deployment-type": "1.0.1",
|
|
||||||
"docker-file-parser": "1.0.2",
|
|
||||||
"dot": "1.1.3",
|
"dot": "1.1.3",
|
||||||
"dotenv": "4.0.0",
|
"dotenv": "4.0.0",
|
||||||
"download": "6.2.5",
|
|
||||||
"email-prompt": "0.3.2",
|
"email-prompt": "0.3.2",
|
||||||
"email-validator": "1.1.1",
|
"email-validator": "1.1.1",
|
||||||
"epipebomb": "1.0.0",
|
"epipebomb": "1.0.0",
|
||||||
@@ -142,9 +134,7 @@
|
|||||||
"fs-extra": "7.0.1",
|
"fs-extra": "7.0.1",
|
||||||
"get-port": "5.1.1",
|
"get-port": "5.1.1",
|
||||||
"glob": "7.1.2",
|
"glob": "7.1.2",
|
||||||
"http-proxy": "1.17.0",
|
"http-proxy": "1.18.1",
|
||||||
"ignore": "4.0.6",
|
|
||||||
"ini": "1.3.4",
|
|
||||||
"inquirer": "7.0.4",
|
"inquirer": "7.0.4",
|
||||||
"is-port-reachable": "3.0.0",
|
"is-port-reachable": "3.0.0",
|
||||||
"is-url": "1.2.2",
|
"is-url": "1.2.2",
|
||||||
@@ -157,20 +147,17 @@
|
|||||||
"mri": "1.1.5",
|
"mri": "1.1.5",
|
||||||
"ms": "2.1.2",
|
"ms": "2.1.2",
|
||||||
"nanoid": "3.0.2",
|
"nanoid": "3.0.2",
|
||||||
"node-fetch": "2.6.0",
|
"node-fetch": "2.6.1",
|
||||||
"npm-package-arg": "6.1.0",
|
"npm-package-arg": "6.1.0",
|
||||||
"nyc": "13.2.0",
|
"nyc": "13.2.0",
|
||||||
"ora": "3.4.0",
|
"ora": "3.4.0",
|
||||||
"pcre-to-regexp": "1.0.0",
|
"pcre-to-regexp": "1.0.0",
|
||||||
"pluralize": "7.0.0",
|
"pluralize": "7.0.0",
|
||||||
"printf": "0.2.5",
|
|
||||||
"progress": "2.0.3",
|
"progress": "2.0.3",
|
||||||
"promisepipe": "3.0.0",
|
"promisepipe": "3.0.0",
|
||||||
"psl": "1.1.31",
|
"psl": "1.1.31",
|
||||||
"qr-image": "3.2.0",
|
"qr-image": "3.2.0",
|
||||||
"raw-body": "2.4.1",
|
"raw-body": "2.4.1",
|
||||||
"read-pkg": "2.0.0",
|
|
||||||
"rx-lite-aggregates": "4.0.8",
|
|
||||||
"semver": "5.5.0",
|
"semver": "5.5.0",
|
||||||
"serve-handler": "6.1.1",
|
"serve-handler": "6.1.1",
|
||||||
"sinon": "4.4.2",
|
"sinon": "4.4.2",
|
||||||
@@ -179,17 +166,14 @@
|
|||||||
"tar-fs": "1.16.3",
|
"tar-fs": "1.16.3",
|
||||||
"test-listen": "1.1.0",
|
"test-listen": "1.1.0",
|
||||||
"text-table": "0.2.0",
|
"text-table": "0.2.0",
|
||||||
"then-sleep": "1.0.1",
|
|
||||||
"through2": "2.0.3",
|
|
||||||
"title": "3.4.1",
|
"title": "3.4.1",
|
||||||
"tmp-promise": "1.0.3",
|
"tmp-promise": "1.0.3",
|
||||||
"tree-kill": "1.2.1",
|
"tree-kill": "1.2.2",
|
||||||
"ts-node": "8.3.0",
|
"ts-node": "8.3.0",
|
||||||
"typescript": "3.9.3",
|
"typescript": "3.9.3",
|
||||||
"universal-analytics": "0.4.20",
|
"universal-analytics": "0.4.20",
|
||||||
"utility-types": "2.1.0",
|
"utility-types": "2.1.0",
|
||||||
"which": "2.0.2",
|
"which": "2.0.2",
|
||||||
"which-promise": "1.0.0",
|
|
||||||
"write-json-file": "2.2.0",
|
"write-json-file": "2.2.0",
|
||||||
"xdg-app-paths": "5.1.0"
|
"xdg-app-paths": "5.1.0"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,18 +49,12 @@ async function main() {
|
|||||||
// Do the initial `ncc` build
|
// Do the initial `ncc` build
|
||||||
console.log();
|
console.log();
|
||||||
const src = join(dirRoot, 'src');
|
const src = join(dirRoot, 'src');
|
||||||
const args = [
|
const args = ['ncc', 'build', '--external', 'update-notifier'];
|
||||||
'@zeit/ncc',
|
if (isDev) {
|
||||||
'build',
|
args.push('--source-map');
|
||||||
'--source-map',
|
|
||||||
'--external',
|
|
||||||
'update-notifier',
|
|
||||||
];
|
|
||||||
if (!isDev) {
|
|
||||||
args.push('--minify');
|
|
||||||
}
|
}
|
||||||
args.push(src);
|
args.push(src);
|
||||||
await execa('npx', args, { stdio: 'inherit' });
|
await execa('yarn', args, { stdio: 'inherit' });
|
||||||
|
|
||||||
// `ncc` has some issues with `@zeit/fun`'s runtime files:
|
// `ncc` has some issues with `@zeit/fun`'s runtime files:
|
||||||
// - Executable bits on the `bootstrap` files appear to be lost:
|
// - Executable bits on the `bootstrap` files appear to be lost:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
//
|
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
|
|
||||||
import { handleError } from '../../util/error';
|
import { handleError } from '../../util/error';
|
||||||
@@ -19,7 +18,7 @@ const help = () => {
|
|||||||
|
|
||||||
${chalk.dim('Commands:')}
|
${chalk.dim('Commands:')}
|
||||||
|
|
||||||
ls [app] Show all aliases (or per app name)
|
ls Show all aliases
|
||||||
set <deployment> <alias> Create a new alias
|
set <deployment> <alias> Create a new alias
|
||||||
rm <alias> Remove an alias using its hostname
|
rm <alias> Remove an alias using its hostname
|
||||||
|
|
||||||
@@ -32,31 +31,27 @@ const help = () => {
|
|||||||
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
|
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
|
||||||
'DIR'
|
'DIR'
|
||||||
)} Path to the global ${'`.vercel`'} directory
|
)} Path to the global ${'`.vercel`'} directory
|
||||||
-r ${chalk.bold.underline('RULES_FILE')}, --rules=${chalk.bold.underline(
|
|
||||||
'RULES_FILE'
|
|
||||||
)} Rules file
|
|
||||||
-d, --debug Debug mode [off]
|
-d, --debug Debug mode [off]
|
||||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||||
'TOKEN'
|
'TOKEN'
|
||||||
)} Login token
|
)} Login token
|
||||||
-S, --scope Set a custom scope
|
-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
|
-N, --next Show next page of results
|
||||||
${chalk.dim('Examples:')}
|
${chalk.dim('Examples:')}
|
||||||
|
|
||||||
${chalk.gray('–')} Add a new alias to ${chalk.underline('my-api.now.sh')}
|
${chalk.gray('–')} Add a new alias to ${chalk.underline('my-api.vercel.app')}
|
||||||
|
|
||||||
${chalk.cyan(
|
${chalk.cyan(
|
||||||
`$ ${getPkgName()} alias set ${chalk.underline(
|
`$ ${getPkgName()} alias set ${chalk.underline(
|
||||||
'api-ownv3nc9f8.now.sh'
|
'api-ownv3nc9f8.vercel.app'
|
||||||
)} ${chalk.underline('my-api.now.sh')}`
|
)} ${chalk.underline('my-api.vercel.app')}`
|
||||||
)}
|
)}
|
||||||
|
|
||||||
Custom domains work as alias targets
|
Custom domains work as alias targets
|
||||||
|
|
||||||
${chalk.cyan(
|
${chalk.cyan(
|
||||||
`$ ${getPkgName()} alias set ${chalk.underline(
|
`$ ${getPkgName()} alias set ${chalk.underline(
|
||||||
'api-ownv3nc9f8.now.sh'
|
'api-ownv3nc9f8.vercel.app'
|
||||||
)} ${chalk.underline('my-api.com')}`
|
)} ${chalk.underline('my-api.com')}`
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -66,30 +61,6 @@ const help = () => {
|
|||||||
${chalk.dim('–')} ${chalk.dim(
|
${chalk.dim('–')} ${chalk.dim(
|
||||||
'Protocols'
|
'Protocols'
|
||||||
)} in the URLs are unneeded and ignored.
|
)} in the URLs are unneeded and ignored.
|
||||||
|
|
||||||
${chalk.gray('–')} Add and modify path based aliases for ${chalk.underline(
|
|
||||||
'example.com'
|
|
||||||
)}
|
|
||||||
|
|
||||||
${chalk.cyan(
|
|
||||||
`$ ${getPkgName()} alias ${chalk.underline(
|
|
||||||
'example.com'
|
|
||||||
)} -r ${chalk.underline('rules.json')}`
|
|
||||||
)}
|
|
||||||
|
|
||||||
Export effective routing rules
|
|
||||||
|
|
||||||
${chalk.cyan(
|
|
||||||
`$ ${getPkgName()} 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(`$ ${getPkgName()} alias ls --next 1584722256178`)}
|
|
||||||
`);
|
`);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -106,12 +77,8 @@ export default async function main(ctx) {
|
|||||||
try {
|
try {
|
||||||
argv = getArgs(ctx.argv.slice(2), {
|
argv = getArgs(ctx.argv.slice(2), {
|
||||||
'--json': Boolean,
|
'--json': Boolean,
|
||||||
'--no-verify': Boolean,
|
|
||||||
'--rules': String,
|
|
||||||
'--yes': Boolean,
|
'--yes': Boolean,
|
||||||
'--next': Number,
|
'--next': Number,
|
||||||
'-n': '--no-verify',
|
|
||||||
'-r': '--rules',
|
|
||||||
'-y': '--yes',
|
'-y': '--yes',
|
||||||
'-N': '--next',
|
'-N': '--next',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import ms from 'ms';
|
import ms from 'ms';
|
||||||
import plural from 'pluralize';
|
|
||||||
import table from 'text-table';
|
import table from 'text-table';
|
||||||
import Now from '../../util';
|
import Now from '../../util';
|
||||||
import Client from '../../util/client.ts';
|
import Client from '../../util/client.ts';
|
||||||
@@ -52,21 +51,17 @@ export default async function ls(ctx, opts, args, output) {
|
|||||||
const lsStamp = stamp();
|
const lsStamp = stamp();
|
||||||
let cancelWait;
|
let cancelWait;
|
||||||
|
|
||||||
if (args.length > 1) {
|
if (args.length > 0) {
|
||||||
output.error(
|
output.error(
|
||||||
`Invalid number of arguments. Usage: ${chalk.cyan(
|
`Invalid number of arguments. Usage: ${chalk.cyan(
|
||||||
`${getCommandName('alias ls [alias]')}`
|
`${getCommandName('alias ls')}`
|
||||||
)}`
|
)}`
|
||||||
);
|
);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cancelWait = output.spinner(
|
cancelWait = output.spinner(
|
||||||
args[0]
|
`Fetching aliases under ${chalk.bold(contextName)}`
|
||||||
? `Fetching alias details for "${args[0]}" under ${chalk.bold(
|
|
||||||
contextName
|
|
||||||
)}`
|
|
||||||
: `Fetching aliases under ${chalk.bold(contextName)}`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const { aliases, pagination } = await getAliases(
|
const { aliases, pagination } = await getAliases(
|
||||||
@@ -76,32 +71,8 @@ export default async function ls(ctx, opts, args, output) {
|
|||||||
);
|
);
|
||||||
if (cancelWait) cancelWait();
|
if (cancelWait) cancelWait();
|
||||||
|
|
||||||
if (args[0]) {
|
output.log(`aliases found under ${chalk.bold(contextName)} ${lsStamp()}`);
|
||||||
const alias = aliases.find(
|
console.log(printAliasTable(aliases));
|
||||||
item => item.uid === args[0] || item.alias === args[0]
|
|
||||||
);
|
|
||||||
if (!alias) {
|
|
||||||
output.error(`Could not match path alias for: ${args[0]}`);
|
|
||||||
now.close();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts['--json']) {
|
|
||||||
console.log(JSON.stringify({ rules: alias.rules }, null, 2));
|
|
||||||
} else {
|
|
||||||
const rules = alias.rules || [];
|
|
||||||
output.log(
|
|
||||||
`${rules.length} path alias ${plural(
|
|
||||||
'rule',
|
|
||||||
rules.length
|
|
||||||
)} found under ${chalk.bold(contextName)} ${lsStamp()}`
|
|
||||||
);
|
|
||||||
output.print(`${printPathAliasTable(rules)}\n`);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
output.log(`aliases found under ${chalk.bold(contextName)} ${lsStamp()}`);
|
|
||||||
console.log(printAliasTable(aliases));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pagination && pagination.count === 20) {
|
if (pagination && pagination.count === 20) {
|
||||||
const flags = getCommandFlags(opts, ['_', '--next']);
|
const flags = getCommandFlags(opts, ['_', '--next']);
|
||||||
@@ -121,14 +92,10 @@ function printAliasTable(aliases) {
|
|||||||
[
|
[
|
||||||
['source', 'url', 'age'].map(h => chalk.gray(h)),
|
['source', 'url', 'age'].map(h => chalk.gray(h)),
|
||||||
...aliases.map(a => [
|
...aliases.map(a => [
|
||||||
a.rules && a.rules.length
|
// for legacy reasons, we might have situations
|
||||||
? chalk.cyan(`[${plural('rule', a.rules.length, true)}]`)
|
// where the deployment was deleted and the alias
|
||||||
: // for legacy reasons, we might have situations
|
// not collected appropriately, and we need to handle it
|
||||||
// where the deployment was deleted and the alias
|
a.deployment && a.deployment.url ? a.deployment.url : chalk.gray('–'),
|
||||||
// not collected appropriately, and we need to handle it
|
|
||||||
a.deployment && a.deployment.url
|
|
||||||
? a.deployment.url
|
|
||||||
: chalk.gray('–'),
|
|
||||||
a.alias,
|
a.alias,
|
||||||
ms(Date.now() - new Date(a.createdAt)),
|
ms(Date.now() - new Date(a.createdAt)),
|
||||||
]),
|
]),
|
||||||
@@ -140,21 +107,3 @@ function printAliasTable(aliases) {
|
|||||||
}
|
}
|
||||||
).replace(/^/gm, ' ')}\n\n`;
|
).replace(/^/gm, ' ')}\n\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function printPathAliasTable(rules) {
|
|
||||||
const header = [['pathname', 'method', 'dest'].map(s => chalk.gray(s))];
|
|
||||||
return `${table(
|
|
||||||
header.concat(
|
|
||||||
rules.map(rule => [
|
|
||||||
rule.pathname ? rule.pathname : chalk.cyan('[fallthrough]'),
|
|
||||||
rule.method ? rule.method : '*',
|
|
||||||
rule.dest,
|
|
||||||
])
|
|
||||||
),
|
|
||||||
{
|
|
||||||
align: ['l', 'l', 'l', 'l'],
|
|
||||||
hsep: ' '.repeat(6),
|
|
||||||
stringLength: strlen,
|
|
||||||
}
|
|
||||||
).replace(/^(.*)/gm, ' $1')}\n`;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import ms from 'ms';
|
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import { SetDifference } from 'utility-types';
|
import { SetDifference } from 'utility-types';
|
||||||
import { AliasRecord } from '../../util/alias/create-alias';
|
import { AliasRecord } from '../../util/alias/create-alias';
|
||||||
@@ -7,28 +6,24 @@ import { Output } from '../../util/output';
|
|||||||
import * as ERRORS from '../../util/errors-ts';
|
import * as ERRORS from '../../util/errors-ts';
|
||||||
import assignAlias from '../../util/alias/assign-alias';
|
import assignAlias from '../../util/alias/assign-alias';
|
||||||
import Client from '../../util/client';
|
import Client from '../../util/client';
|
||||||
import formatDnsTable from '../../util/format-dns-table';
|
|
||||||
import formatNSTable from '../../util/format-ns-table';
|
import formatNSTable from '../../util/format-ns-table';
|
||||||
import getDeploymentForAlias from '../../util/alias/get-deployment-for-alias';
|
import getDeploymentByIdOrHost from '../../util/deploy/get-deployment-by-id-or-host';
|
||||||
import getRulesFromFile from '../../util/alias/get-rules-from-file';
|
import { getDeploymentForAlias } from '../../util/alias/get-deployment-by-alias';
|
||||||
import getScope from '../../util/get-scope';
|
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 setupDomain from '../../util/domains/setup-domain';
|
||||||
import stamp from '../../util/output/stamp';
|
import stamp from '../../util/output/stamp';
|
||||||
import { isValidName } from '../../util/is-valid-name';
|
import { isValidName } from '../../util/is-valid-name';
|
||||||
import upsertPathAlias from '../../util/alias/upsert-path-alias';
|
|
||||||
import handleCertError from '../../util/certs/handle-cert-error';
|
import handleCertError from '../../util/certs/handle-cert-error';
|
||||||
import isWildcardAlias from '../../util/alias/is-wildcard-alias';
|
import isWildcardAlias from '../../util/alias/is-wildcard-alias';
|
||||||
import link from '../../util/output/link';
|
import link from '../../util/output/link';
|
||||||
import { User } from '../../types';
|
import { User } from '../../types';
|
||||||
import { getCommandName } from '../../util/pkg-name';
|
import { getCommandName } from '../../util/pkg-name';
|
||||||
|
import toHost from '../../util/to-host';
|
||||||
|
import { NowConfig } from '../../util/dev/types';
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
'--debug': boolean;
|
'--debug': boolean;
|
||||||
'--local-config': string;
|
'--local-config': string;
|
||||||
'--no-verify': boolean;
|
|
||||||
'--rules': string;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async function set(
|
export default async function set(
|
||||||
@@ -47,11 +42,7 @@ export default async function set(
|
|||||||
const { apiUrl } = ctx;
|
const { apiUrl } = ctx;
|
||||||
const setStamp = stamp();
|
const setStamp = stamp();
|
||||||
|
|
||||||
const {
|
const { '--debug': debugEnabled } = opts;
|
||||||
'--debug': debugEnabled,
|
|
||||||
'--no-verify': noVerify,
|
|
||||||
'--rules': rulesPath,
|
|
||||||
} = opts;
|
|
||||||
|
|
||||||
const client = new Client({
|
const client = new Client({
|
||||||
apiUrl,
|
apiUrl,
|
||||||
@@ -96,35 +87,7 @@ export default async function set(
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the path alias rules in case there is is given
|
if (args.length === 0) {
|
||||||
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(
|
output.error(
|
||||||
`To ship to production, optionally configure your domains (${link(
|
`To ship to production, optionally configure your domains (${link(
|
||||||
'https://vercel.com/docs/v2/custom-domains'
|
'https://vercel.com/docs/v2/custom-domains'
|
||||||
@@ -133,62 +96,79 @@ export default async function set(
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the targets to perform the alias
|
// For `vercel alias set <argument>`
|
||||||
const targets = getTargetsForAlias(args, localConfig);
|
if (args.length === 1) {
|
||||||
|
const deployment = handleCertError(
|
||||||
if (targets instanceof ERRORS.NoAliasInConfig) {
|
output,
|
||||||
output.error(`Couldn't find an alias in config`);
|
await getDeploymentForAlias(
|
||||||
return 1;
|
client,
|
||||||
}
|
output,
|
||||||
|
args,
|
||||||
if (targets instanceof ERRORS.InvalidAliasInConfig) {
|
opts['--local-config'],
|
||||||
output.error(
|
user,
|
||||||
`Wrong value for alias found in config. It must be a string or array of string.`
|
contextName,
|
||||||
|
localConfig
|
||||||
|
)
|
||||||
);
|
);
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rules) {
|
if (deployment === 1) {
|
||||||
// If we have rules for path alias we assign them to the domain
|
return deployment;
|
||||||
for (const target of targets) {
|
}
|
||||||
output.log(
|
|
||||||
`Assigning path alias rules from ${humanizePath(
|
if (deployment instanceof Error) {
|
||||||
rulesPath
|
output.error(deployment.message);
|
||||||
)} to ${target}`
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!deployment) {
|
||||||
|
output.error(
|
||||||
|
`Couldn't find a deployment to alias. Please provide one as an argument.`
|
||||||
);
|
);
|
||||||
const pathAlias = await upsertPathAlias(
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the targets to perform the alias
|
||||||
|
const targets = getTargetsForAlias(args, localConfig);
|
||||||
|
|
||||||
|
if (targets instanceof Error) {
|
||||||
|
output.prettyError(targets);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const target of targets) {
|
||||||
|
output.log(`Assigning alias ${target} to deployment ${deployment.url}`);
|
||||||
|
|
||||||
|
const record = await assignAlias(
|
||||||
output,
|
output,
|
||||||
client,
|
client,
|
||||||
rules,
|
deployment,
|
||||||
target,
|
target,
|
||||||
contextName
|
contextName
|
||||||
);
|
);
|
||||||
const remaining = handleCreateAliasError(output, pathAlias);
|
|
||||||
if (handleSetupDomainError(output, remaining) !== 1) {
|
const handleResult = handleSetupDomainError(
|
||||||
console.log(
|
output,
|
||||||
`${chalk.cyan('> Success!')} ${
|
handleCreateAliasError(output, record)
|
||||||
rules.length
|
);
|
||||||
} rules configured for ${chalk.underline(target)} ${setStamp()}`
|
|
||||||
);
|
if (handleResult === 1) {
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`${chalk.cyan('> Success!')} ${chalk.bold(
|
||||||
|
`${isWildcardAlias(target) ? '' : 'https://'}${handleResult.alias}`
|
||||||
|
)} now points to https://${deployment.url} ${setStamp()}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there are no rules for path alias we should find out a deployment and perform the alias
|
const [deploymentIdOrHost, aliasTarget] = args;
|
||||||
|
|
||||||
const deployment = handleCertError(
|
const deployment = handleCertError(
|
||||||
output,
|
output,
|
||||||
await getDeploymentForAlias(
|
await getDeploymentByIdOrHost(client, contextName, deploymentIdOrHost)
|
||||||
client,
|
|
||||||
output,
|
|
||||||
args,
|
|
||||||
opts['--local-config'],
|
|
||||||
user,
|
|
||||||
contextName,
|
|
||||||
localConfig
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (deployment === 1) {
|
if (deployment === 1) {
|
||||||
@@ -225,37 +205,32 @@ export default async function set(
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign the alias for each of the targets in the array
|
output.log(`Assigning alias ${aliasTarget} to deployment ${deployment.url}`);
|
||||||
for (const target of targets) {
|
|
||||||
output.log(`Assigning alias ${target} to deployment ${deployment.url}`);
|
|
||||||
|
|
||||||
const isWildcard = isWildcardAlias(target);
|
const isWildcard = isWildcardAlias(aliasTarget);
|
||||||
const record = await assignAlias(
|
const record = await assignAlias(
|
||||||
output,
|
output,
|
||||||
client,
|
client,
|
||||||
deployment,
|
deployment,
|
||||||
target,
|
aliasTarget,
|
||||||
contextName,
|
contextName
|
||||||
noVerify
|
);
|
||||||
);
|
const handleResult = handleSetupDomainError(
|
||||||
const handleResult = handleSetupDomainError(
|
output,
|
||||||
output,
|
handleCreateAliasError(output, record)
|
||||||
handleCreateAliasError(output, record),
|
);
|
||||||
isWildcard
|
if (handleResult === 1) {
|
||||||
);
|
return 1;
|
||||||
if (handleResult === 1) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const prefix = isWildcard ? '' : 'https://';
|
|
||||||
|
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,8 +240,7 @@ type SetupDomainError = Exclude<SetupDomainResolve, Domain>;
|
|||||||
|
|
||||||
function handleSetupDomainError<T>(
|
function handleSetupDomainError<T>(
|
||||||
output: Output,
|
output: Output,
|
||||||
error: SetupDomainError | T,
|
error: SetupDomainError | T
|
||||||
isWildcard: boolean = false
|
|
||||||
): T | 1 {
|
): T | 1 {
|
||||||
if (
|
if (
|
||||||
error instanceof ERRORS.DomainVerificationFailed ||
|
error instanceof ERRORS.DomainVerificationFailed ||
|
||||||
@@ -278,9 +252,7 @@ function handleSetupDomainError<T>(
|
|||||||
`We could not alias since the domain ${domain} could not be verified due to the following reasons:\n`
|
`We could not alias since the domain ${domain} could not be verified due to the following reasons:\n`
|
||||||
);
|
);
|
||||||
output.print(
|
output.print(
|
||||||
` ${chalk.gray(
|
`Nameservers verification failed since we see a different set than the intended set:`
|
||||||
'a)'
|
|
||||||
)} Nameservers verification failed since we see a different set than the intended set:`
|
|
||||||
);
|
);
|
||||||
output.print(
|
output.print(
|
||||||
`\n${formatNSTable(
|
`\n${formatNSTable(
|
||||||
@@ -289,35 +261,7 @@ function handleSetupDomainError<T>(
|
|||||||
{ extraSpace: ' ' }
|
{ extraSpace: ' ' }
|
||||||
)}\n\n`
|
)}\n\n`
|
||||||
);
|
);
|
||||||
if (error instanceof ERRORS.DomainVerificationFailed && !isWildcard) {
|
output.print(' Read more: https://err.sh/vercel/domain-verification\n');
|
||||||
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 ${getCommandName(
|
|
||||||
'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 ${getCommandName(
|
|
||||||
'domains verify <domain>'
|
|
||||||
)}.\n`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
output.print(' Read more: https://err.sh/now/domain-verification\n');
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +388,7 @@ function handleCreateAliasError<T>(
|
|||||||
}
|
}
|
||||||
if (error instanceof ERRORS.InvalidAlias) {
|
if (error instanceof ERRORS.InvalidAlias) {
|
||||||
output.error(
|
output.error(
|
||||||
`Invalid alias. Please confirm that the alias you provided is a valid hostname. Note: For \`now.sh\`, only sub and sub-sub domains are supported.`
|
`Invalid alias. Please confirm that the alias you provided is a valid hostname. Note: For \`vercel.app\`, only sub and sub-sub domains are supported.`
|
||||||
);
|
);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -457,66 +401,6 @@ function handleCreateAliasError<T>(
|
|||||||
return 1;
|
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 ${getCommandName('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 ${getCommandName('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 ${getCommandName('scale')} and try again`
|
|
||||||
);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error instanceof ERRORS.CertMissing) {
|
if (error instanceof ERRORS.CertMissing) {
|
||||||
output.error(
|
output.error(
|
||||||
`There is no certificate for the domain ${error.meta.domain} and it could not be created.`
|
`There is no certificate for the domain ${error.meta.domain} and it could not be created.`
|
||||||
@@ -552,3 +436,22 @@ function handleCreateAliasError<T>(
|
|||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTargetsForAlias(args: string[], { alias }: NowConfig) {
|
||||||
|
if (args.length) {
|
||||||
|
return [args[args.length - 1]]
|
||||||
|
.map(target => (target.indexOf('.') !== -1 ? toHost(target) : target))
|
||||||
|
.filter((x): x is string => !!x && typeof x === 'string');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!alias) {
|
||||||
|
return new ERRORS.NoAliasInConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the type for the option aliases
|
||||||
|
if (typeof alias !== 'string' && !Array.isArray(alias)) {
|
||||||
|
return new ERRORS.InvalidAliasInConfig(alias);
|
||||||
|
}
|
||||||
|
|
||||||
|
return typeof alias === 'string' ? [alias] : alias;
|
||||||
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ export default async function issue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (crtPath || keyPath || caPath) {
|
if (crtPath || keyPath || caPath) {
|
||||||
if (args.length !== 0 || (!crtPath || !keyPath || !caPath)) {
|
if (args.length !== 0 || !crtPath || !keyPath || !caPath) {
|
||||||
output.error(
|
output.error(
|
||||||
`Invalid number of arguments to create a custom certificate entry. Usage:`
|
`Invalid number of arguments to create a custom certificate entry. Usage:`
|
||||||
);
|
);
|
||||||
@@ -230,6 +230,8 @@ async function runStartOrder(
|
|||||||
output.print(
|
output.print(
|
||||||
` ${chalk.cyan(getCommandName(`certs issue ${cns.join(' ')}`))}\n`
|
` ${chalk.cyan(getCommandName(`certs issue ${cns.join(' ')}`))}\n`
|
||||||
);
|
);
|
||||||
output.print(' Read more: https://err.sh/now/solve-challenges-manually\n');
|
output.print(
|
||||||
|
' Read more: https://err.sh/vercel/solve-challenges-manually\n'
|
||||||
|
);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import * as ERRORS from '../../util/errors-ts';
|
|||||||
import { Output } from '../../util/output';
|
import { Output } from '../../util/output';
|
||||||
import deleteCertById from '../../util/certs/delete-cert-by-id';
|
import deleteCertById from '../../util/certs/delete-cert-by-id';
|
||||||
import getCertById from '../../util/certs/get-cert-by-id';
|
import getCertById from '../../util/certs/get-cert-by-id';
|
||||||
import getCertsForDomain from '../../util/certs/get-certs-for-domain';
|
import { getCustomCertsForDomain } from '../../util/certs/get-custom-certs-for-domain';
|
||||||
import Client from '../../util/client';
|
import Client from '../../util/client';
|
||||||
import getScope from '../../util/get-scope';
|
import getScope from '../../util/get-scope';
|
||||||
import stamp from '../../util/output/stamp';
|
import stamp from '../../util/output/stamp';
|
||||||
@@ -66,9 +66,17 @@ async function rm(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (certs.length === 0) {
|
if (certs.length === 0) {
|
||||||
output.error(
|
if (id.includes('.')) {
|
||||||
`No certificates found by id "${id}" under ${chalk.bold(contextName)}`
|
output.error(
|
||||||
);
|
`No custom certificates found for "${id}" under ${chalk.bold(
|
||||||
|
contextName
|
||||||
|
)}`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
output.error(
|
||||||
|
`No certificates found by id "${id}" under ${chalk.bold(contextName)}`
|
||||||
|
);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,7 +109,7 @@ async function getCertsToDelete(
|
|||||||
) {
|
) {
|
||||||
const cert = await getCertById(client, id);
|
const cert = await getCertById(client, id);
|
||||||
if (cert instanceof ERRORS.CertNotFound) {
|
if (cert instanceof ERRORS.CertNotFound) {
|
||||||
const certs = await getCertsForDomain(output, client, contextName, id);
|
const certs = await getCustomCertsForDomain(client, contextName, id);
|
||||||
if (certs instanceof ERRORS.CertsPermissionDenied) {
|
if (certs instanceof ERRORS.CertsPermissionDenied) {
|
||||||
return certs;
|
return certs;
|
||||||
}
|
}
|
||||||
@@ -125,12 +133,7 @@ function readConfirmation(output: Output, msg: string, certs: Cert[]) {
|
|||||||
process.stdin
|
process.stdin
|
||||||
.on('data', d => {
|
.on('data', d => {
|
||||||
process.stdin.pause();
|
process.stdin.pause();
|
||||||
resolve(
|
resolve(d.toString().trim().toLowerCase() === 'y');
|
||||||
d
|
|
||||||
.toString()
|
|
||||||
.trim()
|
|
||||||
.toLowerCase() === 'y'
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
.resume();
|
.resume();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,8 @@
|
|||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import logo from '../../util/output/logo';
|
import logo from '../../util/output/logo';
|
||||||
import code from '../../util/output/code';
|
|
||||||
import note from '../../util/output/note';
|
|
||||||
import { getPkgName } from '../../util/pkg-name.ts';
|
import { getPkgName } from '../../util/pkg-name.ts';
|
||||||
|
|
||||||
export const latestHelp = () => `
|
export const help = () => `
|
||||||
${chalk.bold(`${logo} ${getPkgName()}`)} [options] <command | path>
|
${chalk.bold(`${logo} ${getPkgName()}`)} [options] <command | path>
|
||||||
|
|
||||||
${chalk.dim('Commands:')}
|
${chalk.dim('Commands:')}
|
||||||
@@ -70,12 +68,6 @@ export const latestHelp = () => `
|
|||||||
--prod Create a production deployment
|
--prod Create a production deployment
|
||||||
-c, --confirm Confirm default options and skip questions
|
-c, --confirm Confirm default options and skip questions
|
||||||
|
|
||||||
${note(
|
|
||||||
`To view the usage information for Now 1.0, run ${code(
|
|
||||||
`${getPkgName()} help deploy-v1`
|
|
||||||
)}`
|
|
||||||
)}
|
|
||||||
|
|
||||||
${chalk.dim('Examples:')}
|
${chalk.dim('Examples:')}
|
||||||
|
|
||||||
${chalk.gray('–')} Deploy the current directory
|
${chalk.gray('–')} Deploy the current directory
|
||||||
@@ -100,7 +92,7 @@ export const latestHelp = () => `
|
|||||||
|
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const latestArgs = {
|
export const args = {
|
||||||
'--force': Boolean,
|
'--force': Boolean,
|
||||||
'--with-cache': Boolean,
|
'--with-cache': Boolean,
|
||||||
'--public': Boolean,
|
'--public': Boolean,
|
||||||
@@ -108,7 +100,6 @@ export const latestArgs = {
|
|||||||
'--env': [String],
|
'--env': [String],
|
||||||
'--build-env': [String],
|
'--build-env': [String],
|
||||||
'--meta': [String],
|
'--meta': [String],
|
||||||
'--no-scale': Boolean,
|
|
||||||
// This is not an array in favor of matching
|
// This is not an array in favor of matching
|
||||||
// the config property name.
|
// the config property name.
|
||||||
'--regions': String,
|
'--regions': String,
|
||||||
@@ -127,180 +118,3 @@ export const latestArgs = {
|
|||||||
'-n': '--name',
|
'-n': '--name',
|
||||||
'--target': String,
|
'--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 ${'`vercel.json`'} file
|
|
||||||
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
|
|
||||||
'DIR'
|
|
||||||
)} Path to the global ${'`.vercel`'} 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')}
|
|
||||||
|
|
||||||
`;
|
|
||||||
|
|||||||
@@ -1,22 +1,16 @@
|
|||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import { resolve, basename, parse, join } from 'path';
|
import { resolve, basename } from 'path';
|
||||||
import { fileNameSymbol } from '@vercel/client';
|
import { fileNameSymbol } from '@vercel/client';
|
||||||
import Client from '../../util/client.ts';
|
import Client from '../../util/client.ts';
|
||||||
import getScope from '../../util/get-scope.ts';
|
import getScope from '../../util/get-scope.ts';
|
||||||
import createOutput from '../../util/output';
|
import createOutput from '../../util/output';
|
||||||
import code from '../../util/output/code';
|
import code from '../../util/output/code';
|
||||||
import highlight from '../../util/output/highlight';
|
import highlight from '../../util/output/highlight';
|
||||||
import param from '../../util/output/param.ts';
|
|
||||||
import { readLocalConfig } from '../../util/config/files';
|
import { readLocalConfig } from '../../util/config/files';
|
||||||
import getArgs from '../../util/get-args';
|
import getArgs from '../../util/get-args';
|
||||||
import * as parts from './args';
|
|
||||||
import { handleError } from '../../util/error';
|
import { handleError } from '../../util/error';
|
||||||
import readPackage from '../../util/read-package';
|
import { help, args } from './args';
|
||||||
import preferV2Deployment, {
|
import deploy from './latest';
|
||||||
hasDockerfile,
|
|
||||||
hasServerfile,
|
|
||||||
} from '../../util/prefer-v2-deployment';
|
|
||||||
import getProjectName from '../../util/get-project-name';
|
|
||||||
|
|
||||||
export default async ctx => {
|
export default async ctx => {
|
||||||
const {
|
const {
|
||||||
@@ -24,14 +18,12 @@ export default async ctx => {
|
|||||||
config: { currentTeam },
|
config: { currentTeam },
|
||||||
apiUrl,
|
apiUrl,
|
||||||
} = ctx;
|
} = ctx;
|
||||||
const combinedArgs = Object.assign({}, parts.legacyArgs, parts.latestArgs);
|
|
||||||
|
|
||||||
let platformVersion = null;
|
|
||||||
let contextName = currentTeam || 'current user';
|
let contextName = currentTeam || 'current user';
|
||||||
let argv = null;
|
let argv = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
argv = getArgs(ctx.argv.slice(2), combinedArgs);
|
argv = getArgs(ctx.argv.slice(2), args);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error);
|
handleError(error);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -58,12 +50,8 @@ export default async ctx => {
|
|||||||
const debugEnabled = argv['--debug'];
|
const debugEnabled = argv['--debug'];
|
||||||
const output = createOutput({ debug: debugEnabled });
|
const output = createOutput({ debug: debugEnabled });
|
||||||
const stats = {};
|
const stats = {};
|
||||||
const versionFlag = argv['--platform-version'];
|
|
||||||
|
|
||||||
if (argv['--help']) {
|
if (argv['--help']) {
|
||||||
const lastArg = argv._[argv._.length - 1];
|
|
||||||
const help = lastArg === 'deploy-v1' ? parts.legacyHelp : parts.latestHelp;
|
|
||||||
|
|
||||||
output.print(help());
|
output.print(help());
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
@@ -72,28 +60,15 @@ export default async ctx => {
|
|||||||
try {
|
try {
|
||||||
stats[path] = await fs.lstat(path);
|
stats[path] = await fs.lstat(path);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const { ext } = parse(path);
|
output.error(
|
||||||
|
`The specified file or directory "${basename(path)}" does not exist.`
|
||||||
if (versionFlag === 1 && !ext) {
|
);
|
||||||
// This will ensure `-V 1 zeit/serve` (GitHub deployments) work. Since
|
return 1;
|
||||||
// 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;
|
let client = null;
|
||||||
|
|
||||||
const isFile = Object.keys(stats).length === 1 && stats[paths[0]].isFile();
|
|
||||||
|
|
||||||
if (authConfig && authConfig.token) {
|
if (authConfig && authConfig.token) {
|
||||||
client = new Client({
|
client = new Client({
|
||||||
apiUrl,
|
apiUrl,
|
||||||
@@ -102,7 +77,7 @@ export default async ctx => {
|
|||||||
debug: debugEnabled,
|
debug: debugEnabled,
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
({ contextName, platformVersion } = await getScope(client));
|
({ contextName } = await getScope(client));
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
|
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
|
||||||
output.error(err.message);
|
output.error(err.message);
|
||||||
@@ -120,17 +95,14 @@ export default async ctx => {
|
|||||||
|
|
||||||
if (version) {
|
if (version) {
|
||||||
if (typeof version === 'number') {
|
if (typeof version === 'number') {
|
||||||
if (version !== 1 && version !== 2) {
|
if (version !== 2) {
|
||||||
const first = code(1);
|
const two = code(2);
|
||||||
const second = code(2);
|
|
||||||
|
|
||||||
output.error(
|
output.error(
|
||||||
`The value of the ${prop} property within ${file} can only be ${first} or ${second}.`
|
`The value of the ${prop} property within ${file} can only be ${two}.`
|
||||||
);
|
);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
platformVersion = version;
|
|
||||||
} else {
|
} else {
|
||||||
output.error(
|
output.error(
|
||||||
`The ${prop} property inside your ${file} file must be a number.`
|
`The ${prop} property inside your ${file} file must be a number.`
|
||||||
@@ -140,61 +112,5 @@ export default async ctx => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (versionFlag) {
|
return deploy(ctx, contextName, output, stats, localConfig, args);
|
||||||
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
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ const printDeploymentStatus = async (
|
|||||||
|
|
||||||
if (readyState !== 'READY') {
|
if (readyState !== 'READY') {
|
||||||
output.error(
|
output.error(
|
||||||
`Your deployment failed. Please retry later. More: https://err.sh/now/deployment-error`
|
`Your deployment failed. Please retry later. More: https://err.sh/vercel/deployment-error`
|
||||||
);
|
);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -157,13 +157,21 @@ const printDeploymentStatus = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (indications) {
|
if (indications) {
|
||||||
|
const indent = process.stdout.isTTY ? ' ' : ''; // if using emojis
|
||||||
|
const newline = '\n';
|
||||||
for (let indication of indications) {
|
for (let indication of indications) {
|
||||||
output.print(
|
const message =
|
||||||
prependEmoji(
|
prependEmoji(chalk.dim(indication.payload), emoji(indication.type)) +
|
||||||
`${chalk.dim(indication.payload)}`,
|
newline;
|
||||||
emoji(indication.type)
|
let link = '';
|
||||||
) + `\n`
|
if (indication.link)
|
||||||
);
|
link =
|
||||||
|
indent +
|
||||||
|
chalk.dim(
|
||||||
|
`${indication.action || 'Learn More'}: ${indication.link}`
|
||||||
|
) +
|
||||||
|
newline;
|
||||||
|
output.print(message + link);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -239,11 +247,6 @@ export default async function main(
|
|||||||
const { isFile, path } = pathValidation;
|
const { isFile, path } = pathValidation;
|
||||||
const autoConfirm = argv['--confirm'] || isFile;
|
const autoConfirm = argv['--confirm'] || isFile;
|
||||||
|
|
||||||
// --no-scale
|
|
||||||
if (argv['--no-scale']) {
|
|
||||||
warn(`The option --no-scale is only supported on Now 1.0 deployments`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// deprecate --name
|
// deprecate --name
|
||||||
if (argv['--name']) {
|
if (argv['--name']) {
|
||||||
output.print(
|
output.print(
|
||||||
@@ -272,6 +275,7 @@ export default async function main(
|
|||||||
let { org, project, status } = link;
|
let { org, project, status } = link;
|
||||||
let newProjectName = null;
|
let newProjectName = null;
|
||||||
let rootDirectory = project ? project.rootDirectory : null;
|
let rootDirectory = project ? project.rootDirectory : null;
|
||||||
|
let sourceFilesOutsideRootDirectory = true;
|
||||||
|
|
||||||
if (status === 'not_linked') {
|
if (status === 'not_linked') {
|
||||||
const shouldStartSetup =
|
const shouldStartSetup =
|
||||||
@@ -329,6 +333,7 @@ export default async function main(
|
|||||||
} else {
|
} else {
|
||||||
project = projectOrNewProjectName;
|
project = projectOrNewProjectName;
|
||||||
rootDirectory = project.rootDirectory;
|
rootDirectory = project.rootDirectory;
|
||||||
|
sourceFilesOutsideRootDirectory = project.sourceFilesOutsideRootDirectory;
|
||||||
|
|
||||||
// we can already link the project
|
// we can already link the project
|
||||||
await linkFolderToProject(
|
await linkFolderToProject(
|
||||||
@@ -345,7 +350,12 @@ export default async function main(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const sourcePath = rootDirectory ? join(path, rootDirectory) : path;
|
// if we have `sourceFilesOutsideRootDirectory` set to `true`, we use the current path
|
||||||
|
// and upload the entire directory.
|
||||||
|
const sourcePath =
|
||||||
|
rootDirectory && !sourceFilesOutsideRootDirectory
|
||||||
|
? join(path, rootDirectory)
|
||||||
|
: path;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
rootDirectory &&
|
rootDirectory &&
|
||||||
@@ -364,7 +374,7 @@ export default async function main(
|
|||||||
// If Root Directory is used we'll try to read the config
|
// If Root Directory is used we'll try to read the config
|
||||||
// from there instead and use it if it exists.
|
// from there instead and use it if it exists.
|
||||||
if (rootDirectory) {
|
if (rootDirectory) {
|
||||||
const rootDirectoryConfig = readLocalConfig(sourcePath);
|
const rootDirectoryConfig = readLocalConfig(join(path, rootDirectory));
|
||||||
|
|
||||||
if (rootDirectoryConfig) {
|
if (rootDirectoryConfig) {
|
||||||
debug(`Read local config from root directory (${rootDirectory})`);
|
debug(`Read local config from root directory (${rootDirectory})`);
|
||||||
@@ -521,6 +531,11 @@ export default async function main(
|
|||||||
skipAutoDetectionConfirmation: autoConfirm,
|
skipAutoDetectionConfirmation: autoConfirm,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (!localConfig.builds || localConfig.builds.length === 0) {
|
||||||
|
// Only add projectSettings for zero config deployments
|
||||||
|
createArgs.projectSettings = { sourceFilesOutsideRootDirectory };
|
||||||
|
}
|
||||||
|
|
||||||
deployment = await createDeploy(
|
deployment = await createDeploy(
|
||||||
output,
|
output,
|
||||||
now,
|
now,
|
||||||
@@ -542,6 +557,10 @@ export default async function main(
|
|||||||
projectSettings.rootDirectory = rootDirectory;
|
projectSettings.rootDirectory = rootDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (typeof sourceFilesOutsideRootDirectory !== 'undefined') {
|
||||||
|
projectSettings.sourceFilesOutsideRootDirectory = sourceFilesOutsideRootDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
const settings = await editProjectSettings(
|
const settings = await editProjectSettings(
|
||||||
output,
|
output,
|
||||||
projectSettings,
|
projectSettings,
|
||||||
@@ -669,7 +688,7 @@ export default async function main(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (err instanceof BuildError) {
|
if (err instanceof BuildError) {
|
||||||
output.error('Build failed');
|
output.error(err.message || 'Build failed');
|
||||||
output.error(
|
output.error(
|
||||||
`Check your logs at https://${now.url}/_logs or run ${getCommandName(
|
`Check your logs at https://${now.url}/_logs or run ${getCommandName(
|
||||||
`logs ${now.url}`,
|
`logs ${now.url}`,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -99,7 +99,7 @@ export default async function main(ctx: NowContext) {
|
|||||||
'package.json'
|
'package.json'
|
||||||
)} must not contain ${cmd('now dev')}`
|
)} must not contain ${cmd('now dev')}`
|
||||||
);
|
);
|
||||||
output.error(`Learn More: http://err.sh/now/now-dev-as-dev-script`);
|
output.error(`Learn More: http://err.sh/vercel/now-dev-as-dev-script`);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (scripts && scripts.dev && /\bvercel\b\W+\bdev\b/.test(scripts.dev)) {
|
if (scripts && scripts.dev && /\bvercel\b\W+\bdev\b/.test(scripts.dev)) {
|
||||||
@@ -108,7 +108,7 @@ export default async function main(ctx: NowContext) {
|
|||||||
'package.json'
|
'package.json'
|
||||||
)} must not contain ${cmd('vercel dev')}`
|
)} must not contain ${cmd('vercel dev')}`
|
||||||
);
|
);
|
||||||
output.error(`Learn More: http://err.sh/now/now-dev-as-dev-script`);
|
output.error(`Learn More: http://err.sh/vercel/now-dev-as-dev-script`);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ export default async function add(
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const domainConfig = await getDomainConfig(client, contextName, domainName);
|
const domainConfig = await getDomainConfig(client, domainName);
|
||||||
|
|
||||||
if (domainConfig.misconfigured) {
|
if (domainConfig.misconfigured) {
|
||||||
output.warn(
|
output.warn(
|
||||||
@@ -142,7 +142,7 @@ export default async function add(
|
|||||||
);
|
);
|
||||||
output.print(
|
output.print(
|
||||||
` ${chalk.grey('b)')} ` +
|
` ${chalk.grey('b)')} ` +
|
||||||
`Change your domain nameservers to the intended set`
|
`Change your Domains's nameservers to the intended set`
|
||||||
);
|
);
|
||||||
output.print(
|
output.print(
|
||||||
`\n${formatNSTable(
|
`\n${formatNSTable(
|
||||||
|
|||||||
@@ -71,8 +71,9 @@ export default async function buy(
|
|||||||
|
|
||||||
const availableStamp = stamp();
|
const availableStamp = stamp();
|
||||||
const domainPrice = await getDomainPrice(client, domainName);
|
const domainPrice = await getDomainPrice(client, domainName);
|
||||||
if (domainPrice instanceof ERRORS.UnsupportedTLD) {
|
|
||||||
output.error(`The TLD for ${param(domainName)} is not supported.`);
|
if (domainPrice instanceof Error) {
|
||||||
|
output.prettyError(domainPrice);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import inspect from './inspect';
|
|||||||
import ls from './ls';
|
import ls from './ls';
|
||||||
import rm from './rm';
|
import rm from './rm';
|
||||||
import move from './move';
|
import move from './move';
|
||||||
|
import verify from './verify';
|
||||||
import { getPkgName } from '../../util/pkg-name';
|
import { getPkgName } from '../../util/pkg-name';
|
||||||
|
|
||||||
const help = () => {
|
const help = () => {
|
||||||
@@ -81,6 +82,7 @@ const COMMAND_CONFIG = {
|
|||||||
move: ['move'],
|
move: ['move'],
|
||||||
rm: ['rm', 'remove'],
|
rm: ['rm', 'remove'],
|
||||||
transferIn: ['transfer-in'],
|
transferIn: ['transfer-in'],
|
||||||
|
verify: ['verify'],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async function main(ctx: NowContext) {
|
export default async function main(ctx: NowContext) {
|
||||||
@@ -119,6 +121,8 @@ export default async function main(ctx: NowContext) {
|
|||||||
return rm(ctx, argv, args, output);
|
return rm(ctx, argv, args, output);
|
||||||
case 'transferIn':
|
case 'transferIn':
|
||||||
return transferIn(ctx, argv, args, output);
|
return transferIn(ctx, argv, args, output);
|
||||||
|
case 'verify':
|
||||||
|
return verify(ctx, argv, args, output);
|
||||||
default:
|
default:
|
||||||
return ls(ctx, argv, args, output);
|
return ls(ctx, argv, args, output);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import getDomainPrice from '../../util/domains/get-domain-price';
|
|||||||
import { getCommandName } from '../../util/pkg-name';
|
import { getCommandName } from '../../util/pkg-name';
|
||||||
import { getDomainConfig } from '../../util/domains/get-domain-config';
|
import { getDomainConfig } from '../../util/domains/get-domain-config';
|
||||||
import code from '../../util/output/code';
|
import code from '../../util/output/code';
|
||||||
|
import wait from '../../util/output/wait';
|
||||||
|
import { getDomainRegistrar } from '../../util/domains/get-domain-registrar';
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
'--debug': boolean;
|
'--debug': boolean;
|
||||||
@@ -67,38 +69,26 @@ export default async function inspect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
output.debug(`Fetching domain info`);
|
output.debug(`Fetching domain info`);
|
||||||
const [domain, renewalPrice] = await Promise.all([
|
|
||||||
getDomainByName(client, contextName, domainName),
|
const cancelWait = wait(
|
||||||
getDomainPrice(client, domainName, 'renewal')
|
`Fetching Domain ${domainName} under ${chalk.bold(contextName)}`
|
||||||
.then(res => (res instanceof Error ? null : res.price))
|
);
|
||||||
.catch(() => null),
|
|
||||||
]);
|
const information = await fetchInformation({
|
||||||
if (!domain || domain instanceof DomainNotFound) {
|
output,
|
||||||
output.error(
|
client,
|
||||||
`Domain not found by "${domainName}" under ${chalk.bold(contextName)}`
|
contextName,
|
||||||
);
|
domainName,
|
||||||
output.log(`Run ${getCommandName(`domains ls`)} to see your domains.`);
|
cancelWait,
|
||||||
return 1;
|
}).finally(() => {
|
||||||
|
cancelWait();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof information === 'number') {
|
||||||
|
return information;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (domain instanceof DomainPermissionDenied) {
|
const { domain, projects, renewalPrice, domainConfig } = information;
|
||||||
output.error(
|
|
||||||
`You don't have access to the domain ${domainName} under ${chalk.bold(
|
|
||||||
contextName
|
|
||||||
)}`
|
|
||||||
);
|
|
||||||
output.log(`Run ${getCommandName(`domains ls`)} to see your domains.`);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const projects = await findProjectsForDomain(client, domainName);
|
|
||||||
|
|
||||||
if (projects instanceof Error) {
|
|
||||||
output.prettyError(projects);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
const domainConfig = await getDomainConfig(client, contextName, domainName);
|
|
||||||
|
|
||||||
output.log(
|
output.log(
|
||||||
`Domain ${domainName} found under ${chalk.bold(contextName)} ${chalk.gray(
|
`Domain ${domainName} found under ${chalk.bold(contextName)} ${chalk.gray(
|
||||||
@@ -108,46 +98,25 @@ export default async function inspect(
|
|||||||
output.print('\n');
|
output.print('\n');
|
||||||
output.print(chalk.bold(' General\n\n'));
|
output.print(chalk.bold(' General\n\n'));
|
||||||
output.print(` ${chalk.cyan('Name')}\t\t\t${domain.name}\n`);
|
output.print(` ${chalk.cyan('Name')}\t\t\t${domain.name}\n`);
|
||||||
output.print(` ${chalk.cyan('Service Type')}\t\t${domain.serviceType}\n`);
|
|
||||||
output.print(
|
output.print(
|
||||||
` ${chalk.cyan('Ordered At')}\t\t\t${formatDate(domain.orderedAt)}\n`
|
` ${chalk.cyan('Registrar')}\t\t\t${getDomainRegistrar(domain)}\n`
|
||||||
);
|
);
|
||||||
output.print(
|
output.print(
|
||||||
` ${chalk.cyan('Transfer Started At')}\t\t${formatDate(
|
` ${chalk.cyan('Expiration Date')}\t\t${formatDate(domain.expiresAt)}\n`
|
||||||
domain.transferStartedAt
|
);
|
||||||
)}\n`
|
output.print(
|
||||||
|
` ${chalk.cyan('Creator')}\t\t\t${domain.creator.username}\n`
|
||||||
);
|
);
|
||||||
output.print(
|
output.print(
|
||||||
` ${chalk.cyan('Created At')}\t\t\t${formatDate(domain.createdAt)}\n`
|
` ${chalk.cyan('Created At')}\t\t\t${formatDate(domain.createdAt)}\n`
|
||||||
);
|
);
|
||||||
|
output.print(` ${chalk.cyan('Edge Network')}\t\tyes\n`);
|
||||||
output.print(
|
output.print(
|
||||||
` ${chalk.cyan('Bought At')}\t\t\t${formatDate(domain.boughtAt)}\n`
|
` ${chalk.cyan('Renewal Price')}\t\t${
|
||||||
);
|
domain.boughtAt && renewalPrice ? `$${renewalPrice} USD` : chalk.gray('-')
|
||||||
output.print(
|
}\n`
|
||||||
` ${chalk.cyan('Transferred At')}\t\t${formatDate(
|
|
||||||
domain.transferredAt
|
|
||||||
)}\n`
|
|
||||||
);
|
|
||||||
output.print(
|
|
||||||
` ${chalk.cyan('Expires At')}\t\t\t${formatDate(domain.expiresAt)}\n`
|
|
||||||
);
|
|
||||||
output.print(
|
|
||||||
` ${chalk.cyan('NS Verified At')}\t\t${formatDate(
|
|
||||||
domain.nsVerifiedAt
|
|
||||||
)}\n`
|
|
||||||
);
|
|
||||||
output.print(
|
|
||||||
` ${chalk.cyan('TXT Verified At')}\t\t${formatDate(
|
|
||||||
domain.txtVerifiedAt
|
|
||||||
)}\n`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (renewalPrice && domain.boughtAt) {
|
|
||||||
output.print(
|
|
||||||
` ${chalk.cyan('Renewal Price')}\t\t$${renewalPrice} USD\n`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
output.print(` ${chalk.cyan('CDN Enabled')}\t\t\t${true}\n`);
|
|
||||||
output.print('\n');
|
output.print('\n');
|
||||||
|
|
||||||
output.print(chalk.bold(' Nameservers\n\n'));
|
output.print(chalk.bold(' Nameservers\n\n'));
|
||||||
@@ -158,26 +127,6 @@ export default async function inspect(
|
|||||||
);
|
);
|
||||||
output.print('\n');
|
output.print('\n');
|
||||||
|
|
||||||
if (domainConfig.misconfigured) {
|
|
||||||
output.warn(
|
|
||||||
`This domain is not configured properly. To configure it you should either:`
|
|
||||||
);
|
|
||||||
output.print(
|
|
||||||
` ${chalk.grey('a)')} ` +
|
|
||||||
`Set the following record on your DNS provider to continue: ` +
|
|
||||||
`${code(`A ${domainName} 76.76.21.21`)} ` +
|
|
||||||
`${chalk.grey('[recommended]')}\n`
|
|
||||||
);
|
|
||||||
output.print(
|
|
||||||
` ${chalk.grey('b)')} ` +
|
|
||||||
`Change your domain nameservers to the intended set detailed above.\n\n`
|
|
||||||
);
|
|
||||||
output.print(
|
|
||||||
` We will run a verification for you and you will receive an email upon completion.\n`
|
|
||||||
);
|
|
||||||
output.print(' Read more: https://vercel.link/domain-configuration\n\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(projects) && projects.length > 0) {
|
if (Array.isArray(projects) && projects.length > 0) {
|
||||||
output.print(chalk.bold(' Projects\n'));
|
output.print(chalk.bold(' Projects\n'));
|
||||||
|
|
||||||
@@ -208,8 +157,109 @@ export default async function inspect(
|
|||||||
.join('\n')
|
.join('\n')
|
||||||
);
|
);
|
||||||
|
|
||||||
output.print('\n\n');
|
output.print('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domainConfig.misconfigured) {
|
||||||
|
output.warn(
|
||||||
|
`This Domain is not configured properly. To configure it you should either:`,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
boxen: {
|
||||||
|
margin: {
|
||||||
|
left: 2,
|
||||||
|
right: 0,
|
||||||
|
bottom: 0,
|
||||||
|
top: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
output.print(
|
||||||
|
` ${chalk.grey('a)')} ` +
|
||||||
|
`Set the following record on your DNS provider to continue: ` +
|
||||||
|
`${code(`A ${domainName} 76.76.21.21`)} ` +
|
||||||
|
`${chalk.grey('[recommended]')}\n`
|
||||||
|
);
|
||||||
|
output.print(
|
||||||
|
` ${chalk.grey('b)')} ` +
|
||||||
|
`Change your Domains's nameservers to the intended set detailed above.\n\n`
|
||||||
|
);
|
||||||
|
output.print(
|
||||||
|
` We will run a verification for you and you will receive an email upon completion.\n`
|
||||||
|
);
|
||||||
|
|
||||||
|
const contextNameConst = contextName;
|
||||||
|
const projectNames = Array.from(
|
||||||
|
new Set(projects.map(project => project.name))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (projectNames.length) {
|
||||||
|
projectNames.forEach((name, index) => {
|
||||||
|
const prefix = index === 0 ? ' Read more:' : ' '.repeat(12);
|
||||||
|
output.print(
|
||||||
|
`${prefix} https://vercel.com/${contextNameConst}/${name}/settings/domains\n`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
output.print(` Read more: https://vercel.link/domain-configuration\n`);
|
||||||
|
}
|
||||||
|
|
||||||
|
output.print('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchInformation({
|
||||||
|
output,
|
||||||
|
client,
|
||||||
|
contextName,
|
||||||
|
domainName,
|
||||||
|
cancelWait,
|
||||||
|
}: {
|
||||||
|
output: Output;
|
||||||
|
client: Client;
|
||||||
|
contextName: string;
|
||||||
|
domainName: string;
|
||||||
|
cancelWait: () => void;
|
||||||
|
}) {
|
||||||
|
const [domain, renewalPrice] = await Promise.all([
|
||||||
|
getDomainByName(client, contextName, domainName, { ignoreWait: true }),
|
||||||
|
getDomainPrice(client, domainName, 'renewal')
|
||||||
|
.then(res => (res instanceof Error ? null : res.price))
|
||||||
|
.catch(() => null),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (domain instanceof DomainNotFound) {
|
||||||
|
cancelWait();
|
||||||
|
output.prettyError(domain);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (domain instanceof DomainPermissionDenied) {
|
||||||
|
cancelWait();
|
||||||
|
output.prettyError(domain);
|
||||||
|
output.log(`Run ${getCommandName(`domains ls`)} to see your domains.`);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const projects = await findProjectsForDomain(client, domainName);
|
||||||
|
|
||||||
|
if (projects instanceof Error) {
|
||||||
|
cancelWait();
|
||||||
|
output.prettyError(projects);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const domainConfig = await getDomainConfig(client, domainName);
|
||||||
|
|
||||||
|
return {
|
||||||
|
domain,
|
||||||
|
projects,
|
||||||
|
renewalPrice,
|
||||||
|
domainConfig,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import ms from 'ms';
|
import ms from 'ms';
|
||||||
import psl from 'psl';
|
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import plural from 'pluralize';
|
import plural from 'pluralize';
|
||||||
|
|
||||||
|
import wait from '../../util/output/wait';
|
||||||
import Client from '../../util/client';
|
import Client from '../../util/client';
|
||||||
import getDomains from '../../util/domains/get-domains';
|
import getDomains from '../../util/domains/get-domains';
|
||||||
import getScope from '../../util/get-scope';
|
import getScope from '../../util/get-scope';
|
||||||
@@ -10,28 +10,17 @@ import stamp from '../../util/output/stamp';
|
|||||||
import { Output } from '../../util/output';
|
import { Output } from '../../util/output';
|
||||||
import formatTable from '../../util/format-table';
|
import formatTable from '../../util/format-table';
|
||||||
import { formatDateWithoutTime } from '../../util/format-date';
|
import { formatDateWithoutTime } from '../../util/format-date';
|
||||||
import { Domain, Project, NowContext } from '../../types';
|
import { Domain, NowContext } from '../../types';
|
||||||
import { getProjectsWithDomains } from '../../util/projects/get-projects-with-domains';
|
|
||||||
import getCommandFlags from '../../util/get-command-flags';
|
import getCommandFlags from '../../util/get-command-flags';
|
||||||
import { getCommandName } from '../../util/pkg-name';
|
import { getCommandName } from '../../util/pkg-name';
|
||||||
import isDomainExternal from '../../util/domains/is-domain-external';
|
import isDomainExternal from '../../util/domains/is-domain-external';
|
||||||
import { isPublicSuffix } from '../../util/domains/is-public-suffix';
|
import { getDomainRegistrar } from '../../util/domains/get-domain-registrar';
|
||||||
|
|
||||||
type Options = {
|
type Options = {
|
||||||
'--debug': boolean;
|
'--debug': boolean;
|
||||||
'--next': number;
|
'--next': number;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface DomainInfo {
|
|
||||||
domain: string;
|
|
||||||
apexDomain: string;
|
|
||||||
projectName: string | null;
|
|
||||||
dns: 'Vercel' | 'External';
|
|
||||||
configured: boolean;
|
|
||||||
expiresAt: number | null;
|
|
||||||
createdAt: number | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function ls(
|
export default async function ls(
|
||||||
ctx: NowContext,
|
ctx: NowContext,
|
||||||
opts: Options,
|
opts: Options,
|
||||||
@@ -75,29 +64,24 @@ export default async function ls(
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const [{ domains, pagination }, projects] = await Promise.all([
|
const cancelWait = wait(`Fetching Domains under ${chalk.bold(contextName)}`);
|
||||||
getDomains(client, contextName),
|
|
||||||
getProjectsWithDomains(client),
|
|
||||||
] as const);
|
|
||||||
|
|
||||||
if (projects instanceof Error) {
|
const { domains, pagination } = await getDomains(
|
||||||
output.prettyError(projects);
|
client,
|
||||||
return 1;
|
nextTimestamp
|
||||||
}
|
).finally(() => {
|
||||||
|
cancelWait();
|
||||||
const domainsInfo = createDomainsInfo(domains, projects);
|
});
|
||||||
|
|
||||||
output.log(
|
output.log(
|
||||||
`${plural(
|
`${plural('Domain', domains.length, true)} found under ${chalk.bold(
|
||||||
'project domain',
|
contextName
|
||||||
domainsInfo.length,
|
)} ${chalk.gray(lsStamp())}`
|
||||||
true
|
|
||||||
)} found under ${chalk.bold(contextName)} ${chalk.gray(lsStamp())}`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (domainsInfo.length > 0) {
|
if (domains.length > 0) {
|
||||||
output.print(
|
output.print(
|
||||||
formatDomainsTable(domainsInfo).replace(/^(.*)/gm, `${' '.repeat(3)}$1`)
|
formatDomainsTable(domains).replace(/^(.*)/gm, `${' '.repeat(1)}$1`)
|
||||||
);
|
);
|
||||||
output.print('\n\n');
|
output.print('\n\n');
|
||||||
}
|
}
|
||||||
@@ -105,7 +89,7 @@ export default async function ls(
|
|||||||
if (pagination && pagination.count === 20) {
|
if (pagination && pagination.count === 20) {
|
||||||
const flags = getCommandFlags(opts, ['_', '--next']);
|
const flags = getCommandFlags(opts, ['_', '--next']);
|
||||||
output.log(
|
output.log(
|
||||||
`To display the next page run ${getCommandName(
|
`To display the next page, run ${getCommandName(
|
||||||
`domains ls${flags} --next ${pagination.next}`
|
`domains ls${flags} --next ${pagination.next}`
|
||||||
)}`
|
)}`
|
||||||
);
|
);
|
||||||
@@ -114,92 +98,26 @@ export default async function ls(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDomainsInfo(domains: Domain[], projects: Project[]) {
|
function formatDomainsTable(domains: Domain[]) {
|
||||||
const info = new Map<string, DomainInfo>();
|
|
||||||
|
|
||||||
domains.forEach(domain => {
|
|
||||||
info.set(domain.name, {
|
|
||||||
domain: domain.name,
|
|
||||||
apexDomain: domain.name,
|
|
||||||
projectName: null,
|
|
||||||
expiresAt: domain.expiresAt || null,
|
|
||||||
createdAt: domain.createdAt,
|
|
||||||
configured: Boolean(domain.verified),
|
|
||||||
dns: isDomainExternal(domain) ? 'External' : 'Vercel',
|
|
||||||
});
|
|
||||||
|
|
||||||
projects.forEach(project => {
|
|
||||||
(project.alias || []).forEach(target => {
|
|
||||||
if (!target.domain.endsWith(domain.name)) return;
|
|
||||||
|
|
||||||
info.set(target.domain, {
|
|
||||||
domain: target.domain,
|
|
||||||
apexDomain: domain.name,
|
|
||||||
projectName: project.name,
|
|
||||||
expiresAt: domain.expiresAt || null,
|
|
||||||
createdAt: domain.createdAt || target.createdAt || null,
|
|
||||||
configured: Boolean(domain.verified),
|
|
||||||
dns: isDomainExternal(domain) ? 'External' : 'Vercel',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
projects.forEach(project => {
|
|
||||||
(project.alias || []).forEach(target => {
|
|
||||||
if (info.has(target.domain)) return;
|
|
||||||
|
|
||||||
const { domain: apexDomain } = psl.parse(
|
|
||||||
target.domain
|
|
||||||
) as psl.ParsedDomain;
|
|
||||||
|
|
||||||
info.set(target.domain, {
|
|
||||||
domain: target.domain,
|
|
||||||
apexDomain: apexDomain || target.domain,
|
|
||||||
projectName: project.name,
|
|
||||||
expiresAt: null,
|
|
||||||
createdAt: target.createdAt || null,
|
|
||||||
configured: isPublicSuffix(target.domain),
|
|
||||||
dns: isPublicSuffix(target.domain) ? 'Vercel' : 'External',
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
const list = Array.from(info.values());
|
|
||||||
|
|
||||||
return list.sort((a, b) => {
|
|
||||||
if (a.apexDomain === b.apexDomain) {
|
|
||||||
if (a.apexDomain === a.domain) return -1;
|
|
||||||
if (b.apexDomain === b.domain) return 1;
|
|
||||||
return a.domain.localeCompare(b.domain);
|
|
||||||
}
|
|
||||||
|
|
||||||
return a.apexDomain.localeCompare(b.apexDomain);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatDomainsTable(domainsInfo: DomainInfo[]) {
|
|
||||||
const current = Date.now();
|
const current = Date.now();
|
||||||
|
|
||||||
const rows: string[][] = domainsInfo.map(info => {
|
const rows: string[][] = domains.map(domain => {
|
||||||
const expiration = formatDateWithoutTime(info.expiresAt);
|
const expiration = formatDateWithoutTime(domain.expiresAt);
|
||||||
const age = info.createdAt ? ms(current - info.createdAt) : '-';
|
const age = domain.createdAt ? ms(current - domain.createdAt) : '-';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
info.domain,
|
domain.name,
|
||||||
info.projectName || '-',
|
getDomainRegistrar(domain),
|
||||||
info.dns,
|
isDomainExternal(domain) ? 'Third Party' : 'Vercel',
|
||||||
expiration,
|
expiration,
|
||||||
info.configured.toString(),
|
domain.creator.username,
|
||||||
chalk.gray(age),
|
chalk.gray(age),
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
const table = formatTable(
|
return formatTable(
|
||||||
['domain', 'project', 'dns', 'expiration', 'configured', 'age'],
|
['Domain', 'Registrar', 'Nameservers', 'Expiration Date', 'Creator', 'Age'],
|
||||||
['l', 'l', 'l', 'l', 'l', 'l'],
|
['l', 'l', 'l', 'l', 'l', 'l'],
|
||||||
[{ rows }]
|
[{ rows }]
|
||||||
);
|
);
|
||||||
|
|
||||||
return table;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ export default async function transferIn(
|
|||||||
checkTransfer(client, domainName),
|
checkTransfer(client, domainName),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (domainPrice instanceof ERRORS.UnsupportedTLD) {
|
if (domainPrice instanceof Error) {
|
||||||
output.error(`The TLD for ${param(domainName)} is not supported.`);
|
output.prettyError(domainPrice);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
33
packages/now-cli/src/commands/domains/verify.ts
Normal file
33
packages/now-cli/src/commands/domains/verify.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { NowContext } from '../../types';
|
||||||
|
import { Output } from '../../util/output';
|
||||||
|
import { NowBuildError } from '@vercel/build-utils';
|
||||||
|
import { getCommandName } from '../../util/pkg-name';
|
||||||
|
|
||||||
|
export default async function verify(
|
||||||
|
_ctx: NowContext,
|
||||||
|
_opts: {},
|
||||||
|
args: string[],
|
||||||
|
output: Output
|
||||||
|
) {
|
||||||
|
const [domainName] = args;
|
||||||
|
|
||||||
|
if (!domainName) {
|
||||||
|
output.error(
|
||||||
|
`${getCommandName(`domains verify <domain>`)} expects one argument`
|
||||||
|
);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const error = new NowBuildError({
|
||||||
|
code: 'domains_verify_command_deprecated',
|
||||||
|
message: `It's not necessary to verify Domains anymore. Instead, you can run ${getCommandName(
|
||||||
|
`domains inspect ${domainName}`
|
||||||
|
)} to see what you need to do in order to configure it properly.`,
|
||||||
|
link: 'https://vercel.link/domain-verification-via-cli',
|
||||||
|
});
|
||||||
|
|
||||||
|
output.prettyError(error);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -6,8 +6,6 @@ export default new Map([
|
|||||||
['cert', 'certs'],
|
['cert', 'certs'],
|
||||||
['certs', 'certs'],
|
['certs', 'certs'],
|
||||||
['deploy', 'deploy'],
|
['deploy', 'deploy'],
|
||||||
['deploy-v1', 'deploy'],
|
|
||||||
['deploy-v2', 'deploy'],
|
|
||||||
['dev', 'dev'],
|
['dev', 'dev'],
|
||||||
['dns', 'dns'],
|
['dns', 'dns'],
|
||||||
['domain', 'domains'],
|
['domain', 'domains'],
|
||||||
@@ -29,7 +27,6 @@ export default new Map([
|
|||||||
['projects', 'projects'],
|
['projects', 'projects'],
|
||||||
['remove', 'remove'],
|
['remove', 'remove'],
|
||||||
['rm', 'remove'],
|
['rm', 'remove'],
|
||||||
['scale', 'scale'],
|
|
||||||
['secret', 'secrets'],
|
['secret', 'secrets'],
|
||||||
['secrets', 'secrets'],
|
['secrets', 'secrets'],
|
||||||
['switch', 'teams'],
|
['switch', 'teams'],
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user