mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-27 03:39:11 +00:00
Compare commits
45 Commits
@vercel/ro
...
@vercel/cl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
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.
|
||||
|
||||
### @zeit/node-file-trace
|
||||
### @vercel/nft
|
||||
|
||||
Some of the Builders use `@zeit/node-file-trace` to tree-shake files before deployment. If you suspect an error with this tree-shaking mechanism, you can create the following script in your project:
|
||||
Some of the Builders use `@vercel/nft` to tree-shake files before deployment. If you suspect an error with this tree-shaking mechanism, you can create the following script in your project:
|
||||
|
||||
```js
|
||||
const trace = require('@zeit/node-file-trace');
|
||||
const trace = require('@vercel/nft');
|
||||
trace(['path/to/entrypoint.js'], {
|
||||
ts: true,
|
||||
mixedModules: true,
|
||||
@@ -82,7 +82,7 @@ trace(['path/to/entrypoint.js'], {
|
||||
.then(e => console.error(e));
|
||||
```
|
||||
|
||||
When you run this script, you'll see all imported files. If anything file is missing, the bug is in [@zeit/node-file-trace](https://github.com/vercel/node-file-trace) and not the Builder.
|
||||
When you run this script, you'll see all imported files. If anything file is missing, the bug is in [@vercel/nft](https://github.com/vercel/nft) and not the Builder.
|
||||
|
||||
## Deploy a Builder with existing project
|
||||
|
||||
|
||||
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: 10
|
||||
node-version: 12
|
||||
- name: Install
|
||||
run: yarn install --check-files --frozen-lockfile
|
||||
- name: Build
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
#### Why This Error Occurred
|
||||
|
||||
When supplying `regions` or `scale` settings, you
|
||||
used an unknown or invalid dc identifier.
|
||||
When supplying `regions` configuration, you
|
||||
used an unknown or invalid DC identifier.
|
||||
|
||||
#### Possible Ways to Fix It
|
||||
|
||||
@@ -19,7 +19,7 @@ and DCs have to be in _lowercase_.
|
||||
- `gru`
|
||||
- `iad`
|
||||
|
||||
In `now-cli`, they currently are transformed to
|
||||
In Vercel CLI, they currently are transformed to
|
||||
DC identifiers before being sent to our APIs.
|
||||
|
||||
**Valid DC identifiers**:
|
||||
|
||||
@@ -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
|
||||
|
||||
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
|
||||
|
||||
|
||||
@@ -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
|
||||
$ 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
|
||||
$ 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
|
||||
npx blitz start
|
||||
Deploy your own Blitz.js project with Vercel by viewing the [documentation on deploying to Vercel](https://blitzjs.com/docs/deploy-vercel)
|
||||
|
||||
[](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
|
||||
$ 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
|
||||
$ 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
|
||||
$ 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
|
||||
$ 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
|
||||
$ 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
|
||||
$ 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
|
||||
$ 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
|
||||
.env
|
||||
.env.build
|
||||
|
||||
# Vercel
|
||||
.vercel
|
||||
|
||||
@@ -19,11 +19,3 @@ To get started with Ember for deployment with Vercel, you can use the [Ember CLI
|
||||
```shell
|
||||
$ npx ember-cli new ember-project
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Ember project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
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
|
||||
$ 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
|
||||
```
|
||||
|
||||
@@ -19,11 +19,3 @@ To get started with Gridsome for deployment with Vercel, you can use the [Gridso
|
||||
```shell
|
||||
$ gridsome create my-website
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Gridsome project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -19,11 +19,3 @@ To get started with Hexo for deployment with Vercel, you can use the [Hexo CLI](
|
||||
```shell
|
||||
$ hexo init project-name
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Hexo project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -17,11 +17,3 @@ To get started with Hugo for deployment with Vercel, you can use the [Hugo CLI](
|
||||
```shell
|
||||
$ hugo new site project-name
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Hugo project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -17,11 +17,3 @@ To get started with Ionic Angular deployed with Vercel, you can use the [Ionic C
|
||||
```shell
|
||||
$ npx @ionic/cli start [project-name] conference --type angular && cd [project-name]
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Ionic Angular project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -27,7 +27,7 @@ export class MapPage implements AfterViewInit {
|
||||
}
|
||||
|
||||
const googleMaps = await getGoogleMaps(
|
||||
'AIzaSyB8pf6ZdFQj5qw7rc_HSGrhUwQKfIe9ICw'
|
||||
'YOUR_API_KEY_HERE'
|
||||
);
|
||||
|
||||
let map;
|
||||
|
||||
@@ -17,11 +17,3 @@ To get started with Ionic React deployed with Vercel, you can use the [Ionic CLI
|
||||
```shell
|
||||
$ npx ionic start [project-name] conference --type react && cd [project-name]
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Ionic React project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -17,11 +17,3 @@ To get started with Jekyll for deployment with Vercel, you can use the [Jekyll C
|
||||
```shell
|
||||
$ jekyll new my-blog
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Jekyll project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -17,11 +17,3 @@ To get started with Middleman for deployment with Vercel, you can use the [Middl
|
||||
```shell
|
||||
$ middleman init project-name
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Middleman project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -19,11 +19,3 @@ $ npx create-nuxt-app my-app
|
||||
```
|
||||
|
||||
> The only change made is to amend the output directory in `nuxt.config.js` to `"/public"`.
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Nuxt.js project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -19,11 +19,3 @@ To get started with Polymer deployed with Vercel, you can use the [Polymer CLI](
|
||||
```shell
|
||||
$ polymer init
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Polymer project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -19,11 +19,3 @@ To get started with Preact for deployment with Vercel, you can use the [Preact C
|
||||
```shell
|
||||
$ preact create default my-project
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Preact project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -19,11 +19,3 @@ To get started with RedwoodJS on Vercel, you can [use Yarn to initialize](https:
|
||||
```shell
|
||||
$ yarn create redwood-app ./my-redwood-app
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new RedwoodJS project, along with [Serverless Functions](https://vercel.com/docs/v2/serverless-functions/introduction), with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -19,11 +19,3 @@ To get started with Saber on Vercel, you can use [`npm init`](https://docs.npmjs
|
||||
```shell
|
||||
$ npm init site my-saber-site
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Saber project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -19,11 +19,3 @@ $ npx degit "sveltejs/sapper-template#webpack" my-sapper-app
|
||||
```
|
||||
|
||||
> The only change made is to change the build script in `package.json` to be `"sapper export"`.
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Sapper project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -19,11 +19,3 @@ To get started deploying Scully with Vercel, you can use the [Vercel CLI](https:
|
||||
```shell
|
||||
$ vercel init scully
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Scully project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -17,11 +17,3 @@ To get started with Stencil deployed with Vercel, you can use the [Stencil proje
|
||||
```shell
|
||||
$ npm init stencil
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Stencil project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -17,11 +17,3 @@ To get started with Svelte, along with [Serverless Functions](https://vercel.com
|
||||
```shell
|
||||
$ npx degit sveltejs/template my-svelte-project
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new Svelte project, along with [Serverless Functions](https://vercel.com/docs/v2/serverless-functions/introduction), with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -19,11 +19,3 @@ To get started with UmiJS deployed with Vercel, you can use the [Umi CLI](https:
|
||||
```shell
|
||||
$ yarn create umi app-name
|
||||
```
|
||||
|
||||
### Deploying From Your Terminal
|
||||
|
||||
You can deploy your new UmiJS project with a single command from your terminal using [Vercel CLI](https://vercel.com/download):
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "2.0.0",
|
||||
"@typescript-eslint/parser": "2.0.0",
|
||||
"@zeit/ncc": "0.20.4",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"async-retry": "1.2.3",
|
||||
"buffer-replace": "1.0.0",
|
||||
"cheerio": "1.0.0-rc.3",
|
||||
@@ -27,7 +27,7 @@
|
||||
"husky": "3.0.4",
|
||||
"json5": "2.1.1",
|
||||
"lint-staged": "9.2.5",
|
||||
"node-fetch": "2.6.0",
|
||||
"node-fetch": "2.6.1",
|
||||
"npm-package-arg": "6.1.0",
|
||||
"prettier": "2.0.5"
|
||||
},
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Gatsby",
|
||||
"name": "Gatsby.js",
|
||||
"slug": "gatsby",
|
||||
"demo": "https://gatsby.now-examples.now.sh",
|
||||
"logo": "https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/gatsby.svg",
|
||||
@@ -261,7 +261,7 @@
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Ember",
|
||||
"name": "Ember.js",
|
||||
"slug": "ember",
|
||||
"demo": "https://ember.now-examples.now.sh",
|
||||
"logo": "https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/ember.svg",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/frameworks",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"main": "frameworks.json",
|
||||
"license": "UNLICENSED",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "2.5.0",
|
||||
"version": "2.5.3",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
@@ -29,7 +29,8 @@
|
||||
"@types/node-fetch": "^2.1.6",
|
||||
"@types/semver": "6.0.0",
|
||||
"@types/yazl": "^2.4.1",
|
||||
"@vercel/frameworks": "0.1.0",
|
||||
"@vercel/frameworks": "0.1.1",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"aggregate-error": "3.0.1",
|
||||
"async-retry": "1.2.3",
|
||||
"async-sema": "2.1.4",
|
||||
@@ -43,7 +44,7 @@
|
||||
"js-yaml": "3.13.1",
|
||||
"minimatch": "3.0.4",
|
||||
"multistream": "2.1.1",
|
||||
"node-fetch": "2.2.0",
|
||||
"node-fetch": "2.6.1",
|
||||
"semver": "6.1.1",
|
||||
"ts-jest": "24.1.0",
|
||||
"typescript": "3.9.3",
|
||||
|
||||
@@ -978,9 +978,10 @@ function getRouteResult(
|
||||
// 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.
|
||||
errorRoutes.push({
|
||||
status: 404,
|
||||
rewriteRoutes.push({
|
||||
src: '^/api(/.*)?$',
|
||||
status: 404,
|
||||
continue: true,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -107,6 +107,13 @@ export interface BuildOptions {
|
||||
*/
|
||||
workPath: string;
|
||||
|
||||
/**
|
||||
* The "Root Directory" is assigned to the `workPath` so the `repoRootPath`
|
||||
* is the Git Repository Root. This is only relevant for Monorepos.
|
||||
* See https://vercel.com/blog/monorepos
|
||||
*/
|
||||
repoRootPath?: string;
|
||||
|
||||
/**
|
||||
* An arbitrary object passed by the user in the build definition defined
|
||||
* in `vercel.json`.
|
||||
|
||||
@@ -947,18 +947,10 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
|
||||
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
|
||||
expect(redirectRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
expect(rewriteRoutes!.length).toBe(1);
|
||||
expect((rewriteRoutes![0] as Source).status).toBe(404);
|
||||
expect(errorRoutes!.length).toBe(1);
|
||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||
});
|
||||
|
||||
it('no package.json + no build + raw static + api', async () => {
|
||||
@@ -982,18 +974,10 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
|
||||
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
|
||||
expect(redirectRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
expect(rewriteRoutes!.length).toBe(1);
|
||||
expect((rewriteRoutes![0] as Source).status).toBe(404);
|
||||
expect(errorRoutes!.length).toBe(1);
|
||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||
});
|
||||
|
||||
it('package.json + no build + root + api', async () => {
|
||||
@@ -1031,19 +1015,11 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
|
||||
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
|
||||
expect(redirectRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes!.length).toBe(1);
|
||||
expect(rewriteRoutes!.length).toBe(2);
|
||||
expect((rewriteRoutes![0] as Source).src).toBe('^/api/([^/]+)/([^/]+)$');
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
expect((rewriteRoutes![1] as Source).status).toBe(404);
|
||||
expect(errorRoutes!.length).toBe(1);
|
||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||
});
|
||||
|
||||
it('api + next + public', async () => {
|
||||
@@ -1070,13 +1046,9 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
|
||||
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
|
||||
expect(redirectRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
]);
|
||||
expect(rewriteRoutes!.length).toBe(1);
|
||||
expect((rewriteRoutes![0] as Source).status).toBe(404);
|
||||
expect(errorRoutes).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('api + next + raw static', async () => {
|
||||
@@ -1103,13 +1075,9 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
|
||||
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
|
||||
expect(redirectRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
]);
|
||||
expect(rewriteRoutes!.length).toBe(1);
|
||||
expect((rewriteRoutes![0] as Source).status).toBe(404);
|
||||
expect(errorRoutes).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('Using "Other" framework with Storybook should NOT autodetect Next.js for new projects', async () => {
|
||||
@@ -1154,13 +1122,8 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
},
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
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 () => {
|
||||
@@ -1218,18 +1181,10 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
|
||||
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
|
||||
expect(redirectRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
expect(rewriteRoutes!.length).toBe(1);
|
||||
expect((rewriteRoutes![0] as Source).status).toBe(404);
|
||||
expect(errorRoutes!.length).toBe(1);
|
||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||
});
|
||||
|
||||
it('api + raw static + package.json no build script', async () => {
|
||||
@@ -1256,18 +1211,10 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
|
||||
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
|
||||
expect(redirectRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
expect(rewriteRoutes!.length).toBe(1);
|
||||
expect((rewriteRoutes![0] as Source).status).toBe(404);
|
||||
expect(errorRoutes!.length).toBe(1);
|
||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||
});
|
||||
|
||||
it('api + public', async () => {
|
||||
@@ -1286,17 +1233,8 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
expect(builders![1].use).toBe('@vercel/static');
|
||||
expect(builders![1].src).toBe('public/**/*');
|
||||
expect(builders!.length).toBe(2);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes!.length).toBe(1);
|
||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||
});
|
||||
|
||||
it('api go with test files', async () => {
|
||||
@@ -1315,27 +1253,13 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
'api/src/controllers/user.module_test.go',
|
||||
];
|
||||
|
||||
const { builders, rewriteRoutes, errorRoutes } = await detectBuilders(
|
||||
files,
|
||||
undefined,
|
||||
{
|
||||
featHandleMiss,
|
||||
}
|
||||
);
|
||||
const { builders, errorRoutes } = await detectBuilders(files, undefined, {
|
||||
featHandleMiss,
|
||||
});
|
||||
expect(builders!.length).toBe(7);
|
||||
expect(builders!.some(b => b.src.endsWith('_test.go'))).toBe(false);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes!.length).toBe(1);
|
||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||
});
|
||||
|
||||
it('just public', async () => {
|
||||
@@ -1412,17 +1336,8 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
expect(builders![0].use).toBe('@vercel/node');
|
||||
expect(builders![0].src).toBe('api/[endpoint].js');
|
||||
expect(builders!.length).toBe(1);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes!.length).toBe(1);
|
||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||
});
|
||||
|
||||
it('package.json with no build + public directory', async () => {
|
||||
@@ -1541,31 +1456,17 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
it('many static files + one api file', async () => {
|
||||
const files = Array.from({ length: 5000 }).map((_, i) => `file${i}.html`);
|
||||
files.push('api/index.ts');
|
||||
const { builders, rewriteRoutes, errorRoutes } = await detectBuilders(
|
||||
files,
|
||||
undefined,
|
||||
{
|
||||
featHandleMiss,
|
||||
}
|
||||
);
|
||||
const { builders, errorRoutes } = await detectBuilders(files, undefined, {
|
||||
featHandleMiss,
|
||||
});
|
||||
|
||||
expect(builders!.length).toBe(2);
|
||||
expect(builders![0].use).toBe('@vercel/node');
|
||||
expect(builders![0].src).toBe('api/index.ts');
|
||||
expect(builders![1].use).toBe('@vercel/static');
|
||||
expect(builders![1].src).toBe('!{api/**,package.json}');
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes!.length).toBe(1);
|
||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||
});
|
||||
|
||||
it('functions with nextjs', async () => {
|
||||
@@ -1957,18 +1858,10 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
expect((defaultRoutes![0] as Handler).handle).toBe('miss');
|
||||
expect((defaultRoutes![1] as Source).dest).toBe('/api/$1');
|
||||
expect(redirectRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
expect(rewriteRoutes!.length).toBe(1);
|
||||
expect((rewriteRoutes![0] as Source).status).toBe(404);
|
||||
expect(errorRoutes!.length).toBe(1);
|
||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||
});
|
||||
|
||||
it('Framework with non-package.json entrypoint', async () => {
|
||||
@@ -2135,14 +2028,10 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
const files = ['config.rb', 'api/date.rb'];
|
||||
const projectSettings = { framework: 'middleman' };
|
||||
|
||||
const { builders, rewriteRoutes, errorRoutes } = await detectBuilders(
|
||||
files,
|
||||
null,
|
||||
{
|
||||
projectSettings,
|
||||
featHandleMiss,
|
||||
}
|
||||
);
|
||||
const { builders, errorRoutes } = await detectBuilders(files, null, {
|
||||
projectSettings,
|
||||
featHandleMiss,
|
||||
});
|
||||
|
||||
expect(builders).toEqual([
|
||||
{
|
||||
@@ -2161,18 +2050,8 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
|
||||
},
|
||||
},
|
||||
]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes!.length).toBe(1);
|
||||
expect((errorRoutes![0] as Source).status).toBe(404);
|
||||
});
|
||||
|
||||
it('Error for non-api functions', async () => {
|
||||
@@ -2426,12 +2305,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
@@ -2439,8 +2320,7 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
},
|
||||
]);
|
||||
|
||||
const apiPattern = new RegExp(errorRoutes![0].src!);
|
||||
const customPattern = new RegExp(errorRoutes![1].src!);
|
||||
const pattern = new RegExp(errorRoutes![0].src!);
|
||||
|
||||
[
|
||||
'/',
|
||||
@@ -2454,8 +2334,7 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
'/another/sub/page.html',
|
||||
'/another/sub/page',
|
||||
].forEach(file => {
|
||||
expect(file).not.toMatch(apiPattern);
|
||||
expect(file).toMatch(customPattern);
|
||||
expect(file).toMatch(pattern);
|
||||
});
|
||||
|
||||
[
|
||||
@@ -2469,8 +2348,7 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
'/api/sub/page.html',
|
||||
'/api/sub/page',
|
||||
].forEach(file => {
|
||||
expect(file).toMatch(apiPattern);
|
||||
expect(file).not.toMatch(customPattern);
|
||||
expect(file).not.toMatch(pattern);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -2508,13 +2386,9 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
{
|
||||
const files = ['api/[endpoint].js', 'api/[endpoint]/[id].js'];
|
||||
|
||||
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
|
||||
files,
|
||||
null,
|
||||
{
|
||||
featHandleMiss,
|
||||
}
|
||||
);
|
||||
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, null, {
|
||||
featHandleMiss,
|
||||
});
|
||||
expect(defaultRoutes).toStrictEqual([
|
||||
{ handle: 'miss' },
|
||||
{
|
||||
@@ -2534,16 +2408,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
dest: '/api/[endpoint]?endpoint=$1',
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -2555,13 +2423,9 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
'api/[endpoint]/[id].js',
|
||||
];
|
||||
|
||||
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
|
||||
files,
|
||||
null,
|
||||
{
|
||||
featHandleMiss,
|
||||
}
|
||||
);
|
||||
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, null, {
|
||||
featHandleMiss,
|
||||
});
|
||||
expect(defaultRoutes).toStrictEqual([
|
||||
{ handle: 'miss' },
|
||||
{
|
||||
@@ -2582,16 +2446,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
dest: '/api/[endpoint]?endpoint=$1',
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -2609,13 +2467,9 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
|
||||
const files = ['public/index.html', 'api/[endpoint].js'];
|
||||
|
||||
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
|
||||
files,
|
||||
pkg,
|
||||
{
|
||||
featHandleMiss,
|
||||
}
|
||||
);
|
||||
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, pkg, {
|
||||
featHandleMiss,
|
||||
});
|
||||
expect(defaultRoutes).toStrictEqual([
|
||||
{ handle: 'miss' },
|
||||
{
|
||||
@@ -2630,16 +2484,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
dest: '/api/[endpoint]?endpoint=$1',
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -2656,13 +2504,9 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
{
|
||||
const files = ['api/date/index.js', 'api/date.js'];
|
||||
|
||||
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
|
||||
files,
|
||||
null,
|
||||
{
|
||||
featHandleMiss,
|
||||
}
|
||||
);
|
||||
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, null, {
|
||||
featHandleMiss,
|
||||
});
|
||||
expect(defaultRoutes).toStrictEqual([
|
||||
{ handle: 'miss' },
|
||||
{
|
||||
@@ -2671,16 +2515,12 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -2688,13 +2528,9 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
{
|
||||
const files = ['api/date.js', 'api/[date]/index.js'];
|
||||
|
||||
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
|
||||
files,
|
||||
null,
|
||||
{
|
||||
featHandleMiss,
|
||||
}
|
||||
);
|
||||
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, null, {
|
||||
featHandleMiss,
|
||||
});
|
||||
expect(defaultRoutes).toStrictEqual([
|
||||
{ handle: 'miss' },
|
||||
{
|
||||
@@ -2709,16 +2545,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
dest: '/api/[date]/index?date=$1',
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -2732,13 +2562,9 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
'api/food.ts',
|
||||
'api/ts/gold.ts',
|
||||
];
|
||||
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
|
||||
files,
|
||||
null,
|
||||
{
|
||||
featHandleMiss,
|
||||
}
|
||||
);
|
||||
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, null, {
|
||||
featHandleMiss,
|
||||
});
|
||||
|
||||
expect(defaultRoutes).toStrictEqual([
|
||||
{ handle: 'miss' },
|
||||
@@ -2748,16 +2574,12 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -2767,14 +2589,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
const functions = { 'api/user.php': { runtime: 'vercel-php@0.1.0' } };
|
||||
const files = ['api/user.php'];
|
||||
|
||||
const { defaultRoutes, rewriteRoutes, errorRoutes } = await detectBuilders(
|
||||
files,
|
||||
null,
|
||||
{
|
||||
functions,
|
||||
featHandleMiss,
|
||||
}
|
||||
);
|
||||
const { defaultRoutes, rewriteRoutes } = await detectBuilders(files, null, {
|
||||
functions,
|
||||
featHandleMiss,
|
||||
});
|
||||
expect(defaultRoutes).toStrictEqual([
|
||||
{ handle: 'miss' },
|
||||
{
|
||||
@@ -2783,16 +2601,12 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404.html',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -2823,12 +2637,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
} = await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
@@ -2903,7 +2719,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
@@ -2918,16 +2733,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
dest: '/api/[endpoint]?endpoint=$1',
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -2943,7 +2752,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
@@ -2958,16 +2766,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
dest: '/api/[endpoint]?endpoint=$1',
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -2989,7 +2791,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, pkg, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
@@ -2999,16 +2800,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
dest: '/api/[endpoint]?endpoint=$1',
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -3027,20 +2822,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -3052,7 +2841,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
@@ -3062,16 +2850,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
dest: '/api/[date]/index?date=$1',
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -3089,20 +2871,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -3116,20 +2892,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`', async ()
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, { functions, ...options });
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -3157,20 +2927,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -3211,7 +2975,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
@@ -3226,16 +2989,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
dest: '/api/[endpoint]?endpoint=$1',
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -3251,7 +3008,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
@@ -3266,16 +3022,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
dest: '/api/[endpoint]?endpoint=$1',
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -3297,7 +3047,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, pkg, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
@@ -3307,16 +3056,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
dest: '/api/[endpoint]?endpoint=$1',
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -3328,20 +3071,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -3353,7 +3090,6 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
@@ -3363,16 +3099,10 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
dest: '/api/[date]/index?date=$1',
|
||||
check: true,
|
||||
},
|
||||
]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -3390,20 +3120,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, options);
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
@@ -3417,20 +3141,14 @@ it('Test `detectRoutes` with `featHandleMiss=true`, `cleanUrls=true`, `trailingS
|
||||
defaultRoutes,
|
||||
redirectRoutes,
|
||||
rewriteRoutes,
|
||||
errorRoutes,
|
||||
} = await detectBuilders(files, null, { functions, ...options });
|
||||
testHeaders(redirectRoutes);
|
||||
expect(defaultRoutes).toStrictEqual([]);
|
||||
expect(rewriteRoutes).toStrictEqual([]);
|
||||
expect(errorRoutes).toStrictEqual([
|
||||
expect(rewriteRoutes).toStrictEqual([
|
||||
{
|
||||
status: 404,
|
||||
src: '^/api(/.*)?$',
|
||||
},
|
||||
{
|
||||
status: 404,
|
||||
src: '^/(?!.*api).*$',
|
||||
dest: '/404',
|
||||
continue: true,
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "20.0.0",
|
||||
"version": "20.1.1",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -61,11 +61,11 @@
|
||||
"node": ">= 10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "2.5.0",
|
||||
"@vercel/go": "1.1.5",
|
||||
"@vercel/node": "1.8.0",
|
||||
"@vercel/python": "1.2.2",
|
||||
"@vercel/ruby": "1.2.3",
|
||||
"@vercel/build-utils": "2.5.3",
|
||||
"@vercel/go": "1.1.6",
|
||||
"@vercel/node": "1.8.3",
|
||||
"@vercel/python": "1.2.3",
|
||||
"@vercel/ruby": "1.2.4",
|
||||
"update-notifier": "4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -100,9 +100,9 @@
|
||||
"@types/universal-analytics": "0.4.2",
|
||||
"@types/which": "1.3.2",
|
||||
"@types/write-json-file": "2.2.1",
|
||||
"@vercel/frameworks": "0.1.0",
|
||||
"@vercel/frameworks": "0.1.1",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@zeit/fun": "0.11.2",
|
||||
"@zeit/ncc": "0.18.5",
|
||||
"@zeit/source-map-support": "0.6.2",
|
||||
"ajv": "6.12.2",
|
||||
"alpha-sort": "2.0.1",
|
||||
@@ -134,7 +134,7 @@
|
||||
"fs-extra": "7.0.1",
|
||||
"get-port": "5.1.1",
|
||||
"glob": "7.1.2",
|
||||
"http-proxy": "1.17.0",
|
||||
"http-proxy": "1.18.1",
|
||||
"inquirer": "7.0.4",
|
||||
"is-port-reachable": "3.0.0",
|
||||
"is-url": "1.2.2",
|
||||
@@ -147,7 +147,7 @@
|
||||
"mri": "1.1.5",
|
||||
"ms": "2.1.2",
|
||||
"nanoid": "3.0.2",
|
||||
"node-fetch": "2.6.0",
|
||||
"node-fetch": "2.6.1",
|
||||
"npm-package-arg": "6.1.0",
|
||||
"nyc": "13.2.0",
|
||||
"ora": "3.4.0",
|
||||
@@ -168,7 +168,7 @@
|
||||
"text-table": "0.2.0",
|
||||
"title": "3.4.1",
|
||||
"tmp-promise": "1.0.3",
|
||||
"tree-kill": "1.2.1",
|
||||
"tree-kill": "1.2.2",
|
||||
"ts-node": "8.3.0",
|
||||
"typescript": "3.9.3",
|
||||
"universal-analytics": "0.4.20",
|
||||
|
||||
@@ -49,18 +49,12 @@ async function main() {
|
||||
// Do the initial `ncc` build
|
||||
console.log();
|
||||
const src = join(dirRoot, 'src');
|
||||
const args = [
|
||||
'@zeit/ncc',
|
||||
'build',
|
||||
'--source-map',
|
||||
'--external',
|
||||
'update-notifier',
|
||||
];
|
||||
if (!isDev) {
|
||||
args.push('--minify');
|
||||
const args = ['ncc', 'build', '--external', 'update-notifier'];
|
||||
if (isDev) {
|
||||
args.push('--source-map');
|
||||
}
|
||||
args.push(src);
|
||||
await execa('npx', args, { stdio: 'inherit' });
|
||||
await execa('yarn', args, { stdio: 'inherit' });
|
||||
|
||||
// `ncc` has some issues with `@zeit/fun`'s runtime files:
|
||||
// - Executable bits on the `bootstrap` files appear to be lost:
|
||||
|
||||
@@ -96,7 +96,7 @@ export default async function set(
|
||||
return 1;
|
||||
}
|
||||
|
||||
// For `now alias set <argument>`
|
||||
// For `vercel alias set <argument>`
|
||||
if (args.length === 1) {
|
||||
const deployment = handleCertError(
|
||||
output,
|
||||
@@ -261,7 +261,7 @@ function handleSetupDomainError<T>(
|
||||
{ extraSpace: ' ' }
|
||||
)}\n\n`
|
||||
);
|
||||
output.print(' Read more: https://err.sh/now/domain-verification\n');
|
||||
output.print(' Read more: https://err.sh/vercel/domain-verification\n');
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ export default async function issue(
|
||||
}
|
||||
|
||||
if (crtPath || keyPath || caPath) {
|
||||
if (args.length !== 0 || (!crtPath || !keyPath || !caPath)) {
|
||||
if (args.length !== 0 || !crtPath || !keyPath || !caPath) {
|
||||
output.error(
|
||||
`Invalid number of arguments to create a custom certificate entry. Usage:`
|
||||
);
|
||||
@@ -230,6 +230,8 @@ async function runStartOrder(
|
||||
output.print(
|
||||
` ${chalk.cyan(getCommandName(`certs issue ${cns.join(' ')}`))}\n`
|
||||
);
|
||||
output.print(' Read more: https://err.sh/now/solve-challenges-manually\n');
|
||||
output.print(
|
||||
' Read more: https://err.sh/vercel/solve-challenges-manually\n'
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
import chalk from 'chalk';
|
||||
import logo from '../../util/output/logo';
|
||||
import code from '../../util/output/code';
|
||||
import note from '../../util/output/note';
|
||||
import { getPkgName } from '../../util/pkg-name.ts';
|
||||
|
||||
export const help = () => `
|
||||
@@ -70,12 +68,6 @@ export const help = () => `
|
||||
--prod Create a production deployment
|
||||
-c, --confirm Confirm default options and skip questions
|
||||
|
||||
${note(
|
||||
`To view the usage information for Now 1.0, run ${code(
|
||||
`${getPkgName()} help deploy-v1`
|
||||
)}`
|
||||
)}
|
||||
|
||||
${chalk.dim('Examples:')}
|
||||
|
||||
${chalk.gray('–')} Deploy the current directory
|
||||
|
||||
@@ -104,7 +104,7 @@ const printDeploymentStatus = async (
|
||||
|
||||
if (readyState !== 'READY') {
|
||||
output.error(
|
||||
`Your deployment failed. Please retry later. More: https://err.sh/now/deployment-error`
|
||||
`Your deployment failed. Please retry later. More: https://err.sh/vercel/deployment-error`
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
@@ -157,17 +157,21 @@ const printDeploymentStatus = async (
|
||||
}
|
||||
|
||||
if (indications) {
|
||||
const indent = process.stdout.isTTY ? ' ' : ''; // if using emojis
|
||||
const newline = '\n';
|
||||
for (let indication of indications) {
|
||||
output.print(
|
||||
prependEmoji(
|
||||
`${chalk.dim(indication.payload)}`,
|
||||
emoji(indication.type)
|
||||
) +
|
||||
`\n` +
|
||||
(indication.link
|
||||
? `${indication.action || 'Learn More'}: ${indication.link}\n\n`
|
||||
: '')
|
||||
);
|
||||
const message =
|
||||
prependEmoji(chalk.dim(indication.payload), emoji(indication.type)) +
|
||||
newline;
|
||||
let link = '';
|
||||
if (indication.link)
|
||||
link =
|
||||
indent +
|
||||
chalk.dim(
|
||||
`${indication.action || 'Learn More'}: ${indication.link}`
|
||||
) +
|
||||
newline;
|
||||
output.print(message + link);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -243,11 +247,6 @@ export default async function main(
|
||||
const { isFile, path } = pathValidation;
|
||||
const autoConfirm = argv['--confirm'] || isFile;
|
||||
|
||||
// --no-scale
|
||||
if (argv['--no-scale']) {
|
||||
warn(`The option --no-scale is only supported on Now 1.0 deployments`);
|
||||
}
|
||||
|
||||
// deprecate --name
|
||||
if (argv['--name']) {
|
||||
output.print(
|
||||
@@ -276,6 +275,7 @@ export default async function main(
|
||||
let { org, project, status } = link;
|
||||
let newProjectName = null;
|
||||
let rootDirectory = project ? project.rootDirectory : null;
|
||||
let sourceFilesOutsideRootDirectory = true;
|
||||
|
||||
if (status === 'not_linked') {
|
||||
const shouldStartSetup =
|
||||
@@ -333,6 +333,7 @@ export default async function main(
|
||||
} else {
|
||||
project = projectOrNewProjectName;
|
||||
rootDirectory = project.rootDirectory;
|
||||
sourceFilesOutsideRootDirectory = project.sourceFilesOutsideRootDirectory;
|
||||
|
||||
// we can already link the project
|
||||
await linkFolderToProject(
|
||||
@@ -349,7 +350,12 @@ export default async function main(
|
||||
}
|
||||
}
|
||||
|
||||
const sourcePath = rootDirectory ? join(path, rootDirectory) : path;
|
||||
// if we have `sourceFilesOutsideRootDirectory` set to `true`, we use the current path
|
||||
// and upload the entire directory.
|
||||
const sourcePath =
|
||||
rootDirectory && !sourceFilesOutsideRootDirectory
|
||||
? join(path, rootDirectory)
|
||||
: path;
|
||||
|
||||
if (
|
||||
rootDirectory &&
|
||||
@@ -368,7 +374,7 @@ export default async function main(
|
||||
// If Root Directory is used we'll try to read the config
|
||||
// from there instead and use it if it exists.
|
||||
if (rootDirectory) {
|
||||
const rootDirectoryConfig = readLocalConfig(sourcePath);
|
||||
const rootDirectoryConfig = readLocalConfig(join(path, rootDirectory));
|
||||
|
||||
if (rootDirectoryConfig) {
|
||||
debug(`Read local config from root directory (${rootDirectory})`);
|
||||
@@ -525,6 +531,11 @@ export default async function main(
|
||||
skipAutoDetectionConfirmation: autoConfirm,
|
||||
};
|
||||
|
||||
if (!localConfig.builds || localConfig.builds.length === 0) {
|
||||
// Only add projectSettings for zero config deployments
|
||||
createArgs.projectSettings = { sourceFilesOutsideRootDirectory };
|
||||
}
|
||||
|
||||
deployment = await createDeploy(
|
||||
output,
|
||||
now,
|
||||
@@ -546,6 +557,10 @@ export default async function main(
|
||||
projectSettings.rootDirectory = rootDirectory;
|
||||
}
|
||||
|
||||
if (typeof sourceFilesOutsideRootDirectory !== 'undefined') {
|
||||
projectSettings.sourceFilesOutsideRootDirectory = sourceFilesOutsideRootDirectory;
|
||||
}
|
||||
|
||||
const settings = await editProjectSettings(
|
||||
output,
|
||||
projectSettings,
|
||||
|
||||
@@ -99,7 +99,7 @@ export default async function main(ctx: NowContext) {
|
||||
'package.json'
|
||||
)} must not contain ${cmd('now dev')}`
|
||||
);
|
||||
output.error(`Learn More: http://err.sh/now/now-dev-as-dev-script`);
|
||||
output.error(`Learn More: http://err.sh/vercel/now-dev-as-dev-script`);
|
||||
return 1;
|
||||
}
|
||||
if (scripts && scripts.dev && /\bvercel\b\W+\bdev\b/.test(scripts.dev)) {
|
||||
@@ -108,7 +108,7 @@ export default async function main(ctx: NowContext) {
|
||||
'package.json'
|
||||
)} must not contain ${cmd('vercel dev')}`
|
||||
);
|
||||
output.error(`Learn More: http://err.sh/now/now-dev-as-dev-script`);
|
||||
output.error(`Learn More: http://err.sh/vercel/now-dev-as-dev-script`);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,10 @@ export default async function ls(
|
||||
|
||||
const cancelWait = wait(`Fetching Domains under ${chalk.bold(contextName)}`);
|
||||
|
||||
const { domains, pagination } = await getDomains(client).finally(() => {
|
||||
const { domains, pagination } = await getDomains(
|
||||
client,
|
||||
nextTimestamp
|
||||
).finally(() => {
|
||||
cancelWait();
|
||||
});
|
||||
|
||||
|
||||
@@ -67,13 +67,15 @@ export default function handleCertError<T>(
|
||||
output.print(
|
||||
` ${getCommandName(`certs issue --challenge-only <cns>`)}\n`
|
||||
);
|
||||
output.print(' Read more: https://err.sh/now/dns-configuration-error\n');
|
||||
output.print(
|
||||
' Read more: https://err.sh/vercel/dns-configuration-error\n'
|
||||
);
|
||||
} else {
|
||||
output.print(
|
||||
` We configured them for you, but the propagation may take a few minutes. Please try again later.\n`
|
||||
);
|
||||
output.print(
|
||||
' Read more: https://err.sh/now/dns-configuration-error\n\n'
|
||||
' Read more: https://err.sh/vercel/dns-configuration-error\n\n'
|
||||
);
|
||||
}
|
||||
return 1;
|
||||
|
||||
@@ -999,7 +999,7 @@ export class MissingDotenvVarsError extends NowError<
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
message += '\nRead more: https://err.sh/now/missing-env-file';
|
||||
message += '\nRead more: https://err.sh/vercel/missing-env-file';
|
||||
|
||||
super({
|
||||
code: 'MISSING_DOTENV_VARS',
|
||||
|
||||
@@ -186,7 +186,7 @@ export default class Now extends EventEmitter {
|
||||
const { key } = error;
|
||||
err.message =
|
||||
`The env key ${key} has an invalid type: ${typeof env[key]}. ` +
|
||||
'Please supply a String or a Number (https://err.sh/now-cli/env-value-invalid-type)';
|
||||
'Please supply a String or a Number (https://err.sh/vercel-cli/env-value-invalid-type)';
|
||||
} else if (code === 'unreferenced_build_specifications') {
|
||||
const count = unreferencedBuildSpecs.length;
|
||||
const prefix = count === 1 ? 'build' : 'builds';
|
||||
|
||||
@@ -59,6 +59,7 @@ export default async function setupAndLink(
|
||||
const isTTY = process.stdout.isTTY;
|
||||
const quiet = !isTTY;
|
||||
let rootDirectory: string | null = null;
|
||||
let sourceFilesOutsideRootDirectory = true;
|
||||
let newProjectName: string;
|
||||
let org;
|
||||
|
||||
@@ -129,7 +130,13 @@ export default async function setupAndLink(
|
||||
);
|
||||
return { status: 'linked', org, project };
|
||||
}
|
||||
const sourcePath = rootDirectory ? join(path, rootDirectory) : path;
|
||||
|
||||
// if we have `sourceFilesOutsideRootDirectory` set to `true`, we use the current path
|
||||
// and upload the entire directory.
|
||||
const sourcePath =
|
||||
rootDirectory && !sourceFilesOutsideRootDirectory
|
||||
? join(path, rootDirectory)
|
||||
: path;
|
||||
|
||||
if (
|
||||
rootDirectory &&
|
||||
@@ -174,6 +181,11 @@ export default async function setupAndLink(
|
||||
skipAutoDetectionConfirmation: false,
|
||||
};
|
||||
|
||||
if (!localConfig.builds || localConfig.builds.length === 0) {
|
||||
// Only add projectSettings for zero config deployments
|
||||
createArgs.projectSettings = { sourceFilesOutsideRootDirectory };
|
||||
}
|
||||
|
||||
const deployment = await createDeploy(
|
||||
output,
|
||||
now,
|
||||
|
||||
@@ -33,7 +33,7 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
|
||||
boxen?: boxen.Options;
|
||||
}
|
||||
) {
|
||||
const details = slug ? `https://err.sh/now/${slug}` : link;
|
||||
const details = slug ? `https://err.sh/vercel/${slug}` : link;
|
||||
|
||||
print(
|
||||
boxen(
|
||||
@@ -66,7 +66,7 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
|
||||
action = 'Learn More'
|
||||
) {
|
||||
print(`${chalk.red(`Error!`)} ${str}\n`);
|
||||
const details = slug ? `https://err.sh/now/${slug}` : link;
|
||||
const details = slug ? `https://err.sh/vercel/${slug}` : link;
|
||||
if (details) {
|
||||
print(`${chalk.bold(action)}: ${renderLink(details)}\n`);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export default function error(...input: string[] | [APIError]) {
|
||||
if (typeof input[0] === 'object') {
|
||||
const { slug, message, link, action = 'Learn More' } = input[0];
|
||||
messages = [message];
|
||||
const details = slug ? `https://err.sh/now/${slug}` : link;
|
||||
const details = slug ? `https://err.sh/vercel/${slug}` : link;
|
||||
if (details) {
|
||||
messages.push(`${chalk.bold(action)}: ${renderLink(details)}`);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,68 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "CommonJS"
|
||||
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
||||
|
||||
/* Basic Options */
|
||||
// "incremental": true, /* Enable incremental compilation */
|
||||
"module": "CommonJS",
|
||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
// "declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
// "outDir": "./", /* Redirect output structure to the directory. */
|
||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true /* Enable all strict type-checking options. */,
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
||||
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
|
||||
/* Advanced Options */
|
||||
"skipLibCheck": true /* Skip type checking of declaration files. */,
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import retry from 'async-retry';
|
||||
import { satisfies } from 'semver';
|
||||
import { getDistTag } from '../../src/util/get-dist-tag';
|
||||
import { version as cliVersion } from '../../package.json';
|
||||
import { fetchTokenWithRetry } from '../../../../test/lib/deployment/now-deploy';
|
||||
import { fetchCachedToken } from '../../../../test/lib/deployment/now-deploy';
|
||||
|
||||
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
|
||||
const isCanary = () => getDistTag(cliVersion) === 'canary';
|
||||
@@ -245,7 +245,7 @@ function testFixtureStdio(
|
||||
const cwd = isExample
|
||||
? exampleAbsolute(directory)
|
||||
: fixtureAbsolute(directory);
|
||||
const token = await fetchTokenWithRetry();
|
||||
const token = await fetchCachedToken();
|
||||
let deploymentUrl;
|
||||
|
||||
// Deploy fixture and link project
|
||||
|
||||
@@ -90,7 +90,7 @@ module.exports = async function prepare(session) {
|
||||
}),
|
||||
'now-build.js': `
|
||||
const fs = require('fs');
|
||||
fs.writeFileSync(
|
||||
fs.writeFileSync(
|
||||
'index.js',
|
||||
fs.readFileSync('index.js', 'utf8')
|
||||
.replace('BUILD_ENV_DEBUG', process.env.NOW_BUILDER_DEBUG ? 'on' : 'off'),
|
||||
|
||||
4
packages/now-cli/test/integration.js
vendored
4
packages/now-cli/test/integration.js
vendored
@@ -2365,7 +2365,6 @@ test('invalid `--token`', async t => {
|
||||
);
|
||||
});
|
||||
|
||||
// We need to skip this test until `now-php` supports Runtime version 3
|
||||
test('deploy a Lambda with a specific runtime', async t => {
|
||||
const directory = fixture('lambda-with-php-runtime');
|
||||
const output = await execute([directory, '--public', '--confirm']);
|
||||
@@ -2374,7 +2373,8 @@ test('deploy a Lambda with a specific runtime', async t => {
|
||||
|
||||
const { host: url } = new URL(output.stdout);
|
||||
|
||||
const [build] = await getDeploymentBuildsByUrl(url);
|
||||
const builds = await getDeploymentBuildsByUrl(url);
|
||||
const build = builds.find(b => b.use && b.use.includes('php')) || builds[0];
|
||||
t.is(build.use, 'vercel-php@0.1.0', JSON.stringify(build, null, 2));
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/client",
|
||||
"version": "9.0.0",
|
||||
"version": "9.0.2",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"homepage": "https://vercel.com",
|
||||
@@ -26,7 +26,6 @@
|
||||
"@types/node": "12.0.4",
|
||||
"@types/node-fetch": "2.5.4",
|
||||
"@types/recursive-readdir": "2.2.0",
|
||||
"@zeit/ncc": "0.18.5",
|
||||
"typescript": "3.9.3"
|
||||
},
|
||||
"jest": {
|
||||
@@ -38,14 +37,14 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "2.5.0",
|
||||
"@vercel/build-utils": "2.5.3",
|
||||
"@zeit/fetch": "5.2.0",
|
||||
"async-retry": "1.2.3",
|
||||
"async-sema": "3.0.0",
|
||||
"fs-extra": "8.0.1",
|
||||
"ignore": "4.0.6",
|
||||
"ms": "2.1.2",
|
||||
"node-fetch": "2.6.0",
|
||||
"node-fetch": "2.6.1",
|
||||
"querystring": "^0.2.0",
|
||||
"recursive-readdir": "2.2.2",
|
||||
"sleep-promise": "8.0.1"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
const {
|
||||
fetchTokenWithRetry,
|
||||
fetchCachedToken,
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
} = require('../../../test/lib/deployment/now-deploy.js');
|
||||
|
||||
export async function generateNewToken(): Promise<string> {
|
||||
const token = await fetchTokenWithRetry();
|
||||
const token = await fetchCachedToken();
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/go",
|
||||
"version": "1.1.5",
|
||||
"version": "1.1.6",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
||||
@@ -25,6 +25,7 @@
|
||||
"@types/fs-extra": "^5.0.5",
|
||||
"@types/node-fetch": "^2.3.0",
|
||||
"@types/tar": "^4.0.0",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"async-retry": "1.3.1",
|
||||
"execa": "^1.0.0",
|
||||
"fs-extra": "^7.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/next",
|
||||
"version": "2.6.23",
|
||||
"version": "2.6.26",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
||||
@@ -26,7 +26,7 @@
|
||||
"@types/resolve-from": "5.0.1",
|
||||
"@types/semver": "6.0.0",
|
||||
"@types/yazl": "2.4.1",
|
||||
"@zeit/node-file-trace": "0.8.2",
|
||||
"@vercel/nft": "0.9.2",
|
||||
"async-sema": "3.0.1",
|
||||
"buffer-crc32": "0.2.13",
|
||||
"escape-string-regexp": "3.0.0",
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
convertRedirects,
|
||||
convertRewrites,
|
||||
} from '@vercel/routing-utils/dist/superstatic';
|
||||
import { nodeFileTrace, NodeFileTraceReasons } from '@zeit/node-file-trace';
|
||||
import { nodeFileTrace, NodeFileTraceReasons } from '@vercel/nft';
|
||||
import { Sema } from 'async-sema';
|
||||
import { ChildProcess, fork } from 'child_process';
|
||||
import escapeStringRegexp from 'escape-string-regexp';
|
||||
@@ -213,6 +213,7 @@ function startDevServer(entryPath: string, runtimeEnv: EnvConfig) {
|
||||
export const build = async ({
|
||||
files,
|
||||
workPath,
|
||||
repoRootPath,
|
||||
entrypoint,
|
||||
config = {} as Config,
|
||||
meta = {} as BuildParamsMeta,
|
||||
@@ -231,6 +232,7 @@ export const build = async ({
|
||||
const entryPath = path.join(workPath, entryDirectory);
|
||||
const outputDirectory = config.outputDirectory || '.next';
|
||||
const dotNextStatic = path.join(entryPath, outputDirectory, 'static');
|
||||
const baseDir = repoRootPath || workPath;
|
||||
|
||||
await download(files, workPath, meta);
|
||||
|
||||
@@ -240,7 +242,7 @@ export const build = async ({
|
||||
const spawnOpts = getSpawnOptions(meta, nodeVersion);
|
||||
|
||||
const nowJsonPath = await findUp(['now.json', 'vercel.json'], {
|
||||
cwd: path.join(workPath, path.dirname(entrypoint)),
|
||||
cwd: entryPath,
|
||||
});
|
||||
|
||||
let hasLegacyRoutes = false;
|
||||
@@ -755,10 +757,16 @@ export const build = async ({
|
||||
],
|
||||
};
|
||||
|
||||
const lambdaOptions = await getLambdaOptionsFromFunction({
|
||||
sourceFile: await getSourceFilePathFromPage({ workPath, page }),
|
||||
config,
|
||||
});
|
||||
let lambdaOptions = {};
|
||||
if (config && config.functions) {
|
||||
lambdaOptions = await getLambdaOptionsFromFunction({
|
||||
sourceFile: await getSourceFilePathFromPage({
|
||||
workPath: entryPath,
|
||||
page,
|
||||
}),
|
||||
config,
|
||||
});
|
||||
}
|
||||
|
||||
debug(`Creating serverless function for page: "${page}"...`);
|
||||
lambdas[path.join(entryDirectory, pathname)] = await createLambda({
|
||||
@@ -864,7 +872,7 @@ export const build = async ({
|
||||
};
|
||||
|
||||
const isApiPage = (page: string) =>
|
||||
page.replace(/\\/g, '/').match(/serverless\/pages\/api/);
|
||||
page.replace(/\\/g, '/').match(/serverless\/pages\/api(\/|\.js$)/);
|
||||
|
||||
const canUsePreviewMode = Object.keys(pages).some(page =>
|
||||
isApiPage(pages[page].fsPath)
|
||||
@@ -939,12 +947,18 @@ export const build = async ({
|
||||
const {
|
||||
fileList: apiFileList,
|
||||
reasons: apiReasons,
|
||||
} = await nodeFileTrace(apiPages, { base: workPath });
|
||||
} = await nodeFileTrace(apiPages, {
|
||||
base: baseDir,
|
||||
processCwd: entryPath,
|
||||
});
|
||||
|
||||
const {
|
||||
fileList,
|
||||
reasons: nonApiReasons,
|
||||
} = await nodeFileTrace(nonApiPages, { base: workPath });
|
||||
const { fileList, reasons: nonApiReasons } = await nodeFileTrace(
|
||||
nonApiPages,
|
||||
{
|
||||
base: baseDir,
|
||||
processCwd: entryPath,
|
||||
}
|
||||
);
|
||||
|
||||
debug(`node-file-trace result for pages: ${fileList}`);
|
||||
|
||||
@@ -962,7 +976,7 @@ export const build = async ({
|
||||
// Initial files are manually added to the lambda later
|
||||
return;
|
||||
}
|
||||
const filePath = path.join(workPath, file);
|
||||
const filePath = path.join(baseDir, file);
|
||||
|
||||
if (!lstatResults[filePath]) {
|
||||
lstatResults[filePath] = lstatSema
|
||||
@@ -973,7 +987,7 @@ export const build = async ({
|
||||
const { mode } = await lstatResults[filePath];
|
||||
|
||||
files[file] = new FileFsRef({
|
||||
fsPath: path.join(workPath, file),
|
||||
fsPath: path.join(baseDir, file),
|
||||
mode,
|
||||
});
|
||||
};
|
||||
@@ -1158,7 +1172,11 @@ export const build = async ({
|
||||
const {
|
||||
pseudoLayer: pageLayer,
|
||||
pseudoLayerBytes: pageLayerBytes,
|
||||
} = await createPseudoLayer({ [pageFileName]: pages[page] });
|
||||
} = await createPseudoLayer({
|
||||
[path.join(path.relative(baseDir, entryPath), pageFileName)]: pages[
|
||||
page
|
||||
],
|
||||
});
|
||||
|
||||
currentLambdaGroup.pages[outputName] = {
|
||||
pageLayer,
|
||||
@@ -1194,21 +1212,31 @@ export const build = async ({
|
||||
}
|
||||
|
||||
const pageFileName = path.normalize(
|
||||
path.relative(workPath, pages[page].fsPath)
|
||||
path.relative(entryPath, pages[page].fsPath)
|
||||
);
|
||||
|
||||
const launcher = launcherData.replace(
|
||||
/__LAUNCHER_PAGE_PATH__/g,
|
||||
JSON.stringify(requiresTracing ? `./${pageFileName}` : './page')
|
||||
);
|
||||
const launcherFiles: { [name: string]: FileFsRef | FileBlob } = {
|
||||
'now__bridge.js': new FileFsRef({
|
||||
[path.join(
|
||||
path.relative(baseDir, entryPath),
|
||||
'now__bridge.js'
|
||||
)]: new FileFsRef({
|
||||
fsPath: path.join(__dirname, 'now__bridge.js'),
|
||||
}),
|
||||
'now__launcher.js': new FileBlob({ data: launcher }),
|
||||
[path.join(
|
||||
path.relative(baseDir, entryPath),
|
||||
'now__launcher.js'
|
||||
)]: new FileBlob({ data: launcher }),
|
||||
};
|
||||
|
||||
const lambdaOptions = await getLambdaOptionsFromFunction({
|
||||
sourceFile: await getSourceFilePathFromPage({ workPath, page }),
|
||||
sourceFile: await getSourceFilePathFromPage({
|
||||
workPath: entryPath,
|
||||
page,
|
||||
}),
|
||||
config,
|
||||
});
|
||||
|
||||
@@ -1218,10 +1246,16 @@ export const build = async ({
|
||||
lambdas[outputName] = await createLambdaFromPseudoLayers({
|
||||
files: {
|
||||
...launcherFiles,
|
||||
[requiresTracing ? pageFileName : 'page.js']: pages[page],
|
||||
[path.join(
|
||||
path.relative(baseDir, entryPath),
|
||||
pageFileName
|
||||
)]: pages[page],
|
||||
},
|
||||
layers: isApiPage(pageFileName) ? apiPseudoLayers : pseudoLayers,
|
||||
handler: 'now__launcher.launcher',
|
||||
handler: path.join(
|
||||
path.relative(baseDir, entryPath),
|
||||
'now__launcher.launcher'
|
||||
),
|
||||
runtime: nodeVersion.runtime,
|
||||
...lambdaOptions,
|
||||
});
|
||||
@@ -1231,7 +1265,7 @@ export const build = async ({
|
||||
...launcherFiles,
|
||||
...assets,
|
||||
...tracedFiles,
|
||||
[requiresTracing ? pageFileName : 'page.js']: pages[page],
|
||||
['page.js']: pages[page],
|
||||
},
|
||||
handler: 'now__launcher.launcher',
|
||||
runtime: nodeVersion.runtime,
|
||||
@@ -1293,7 +1327,7 @@ export const build = async ({
|
||||
${groupPageKeys
|
||||
.map(
|
||||
page =>
|
||||
`'${page}': require('./${path.join(
|
||||
`'${page}': () => require('./${path.join(
|
||||
'./',
|
||||
group.pages[page].pageFileName
|
||||
)}')`
|
||||
@@ -1302,7 +1336,7 @@ export const build = async ({
|
||||
${
|
||||
'' /*
|
||||
creates a mapping of the page and the page's module e.g.
|
||||
'/about': require('./.next/serverless/pages/about.js')
|
||||
'/about': () => require('./.next/serverless/pages/about.js')
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -1362,7 +1396,10 @@ export const build = async ({
|
||||
res.statusCode = 500
|
||||
return res.end('internal server error')
|
||||
}
|
||||
const method = currentPage.render || currentPage.default || currentPage
|
||||
|
||||
const mod = currentPage()
|
||||
const method = mod.render || mod.default || mod
|
||||
|
||||
return method(req, res)
|
||||
} catch (err) {
|
||||
console.error('Unhandled error during request:', err)
|
||||
@@ -1372,10 +1409,16 @@ export const build = async ({
|
||||
`
|
||||
);
|
||||
const launcherFiles: { [name: string]: FileFsRef | FileBlob } = {
|
||||
'now__bridge.js': new FileFsRef({
|
||||
[path.join(
|
||||
path.relative(baseDir, entryPath),
|
||||
'now__bridge.js'
|
||||
)]: new FileFsRef({
|
||||
fsPath: path.join(__dirname, 'now__bridge.js'),
|
||||
}),
|
||||
'now__launcher.js': new FileBlob({ data: launcher }),
|
||||
[path.join(
|
||||
path.relative(baseDir, entryPath),
|
||||
'now__launcher.js'
|
||||
)]: new FileBlob({ data: launcher }),
|
||||
};
|
||||
|
||||
const pageLayers: PseudoLayer[] = [];
|
||||
@@ -1397,7 +1440,10 @@ export const build = async ({
|
||||
...(group.isApiLambda ? apiPseudoLayers : pseudoLayers),
|
||||
...pageLayers,
|
||||
],
|
||||
handler: 'now__launcher.launcher',
|
||||
handler: path.join(
|
||||
path.relative(baseDir, entryPath),
|
||||
'now__launcher.launcher'
|
||||
),
|
||||
runtime: nodeVersion.runtime,
|
||||
});
|
||||
} else {
|
||||
@@ -1409,7 +1455,10 @@ export const build = async ({
|
||||
...assets,
|
||||
},
|
||||
layers: pageLayers,
|
||||
handler: 'now__launcher.launcher',
|
||||
handler: path.join(
|
||||
path.relative(baseDir, entryPath),
|
||||
'now__launcher.launcher'
|
||||
),
|
||||
runtime: nodeVersion.runtime,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
// The Next.js builder can emit the project in a subdirectory depending on how
|
||||
// many folder levels of `node_modules` are traced. To ensure `process.cwd()`
|
||||
// returns the proper path, we change the directory to the folder with the
|
||||
// launcher. This mimics `yarn workspace run` behavior.
|
||||
process.chdir(__dirname);
|
||||
|
||||
if (!process.env.NODE_ENV) {
|
||||
const region = process.env.VERCEL_REGION || process.env.NOW_REGION;
|
||||
process.env.NODE_ENV = region === 'dev1' ? 'development' : 'production';
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
// The Next.js builder can emit the project in a subdirectory depending on how
|
||||
// many folder levels of `node_modules` are traced. To ensure `process.cwd()`
|
||||
// returns the proper path, we change the directory to the folder with the
|
||||
// launcher. This mimics `yarn workspace run` behavior.
|
||||
process.chdir(__dirname);
|
||||
|
||||
if (!process.env.NODE_ENV) {
|
||||
const region = process.env.VERCEL_REGION || process.env.NOW_REGION;
|
||||
process.env.NODE_ENV = region === 'dev1' ? 'development' : 'production';
|
||||
|
||||
@@ -1000,11 +1000,38 @@ async function getSourceFilePathFromPage({
|
||||
workPath: string;
|
||||
page: string;
|
||||
}) {
|
||||
let fsPath = path.join(workPath, 'pages', page);
|
||||
if (await usesSrcDirectory(workPath)) {
|
||||
return path.join('src', 'pages', page);
|
||||
fsPath = path.join(workPath, 'src', 'pages', page);
|
||||
}
|
||||
|
||||
return path.join('pages', page);
|
||||
if (fs.existsSync(fsPath)) {
|
||||
return path.relative(workPath, fsPath);
|
||||
}
|
||||
|
||||
const extensionless = fsPath.slice(0, -3); // remove ".js"
|
||||
fsPath = extensionless + '.ts';
|
||||
if (fs.existsSync(fsPath)) {
|
||||
return path.relative(workPath, fsPath);
|
||||
}
|
||||
|
||||
if (isDirectory(extensionless)) {
|
||||
fsPath = path.join(extensionless, 'index.js');
|
||||
if (fs.existsSync(fsPath)) {
|
||||
return path.relative(workPath, fsPath);
|
||||
}
|
||||
fsPath = path.join(extensionless, 'index.ts');
|
||||
if (fs.existsSync(fsPath)) {
|
||||
return path.relative(workPath, fsPath);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`WARNING: Unable to find source file for page ${page}`);
|
||||
return '';
|
||||
}
|
||||
|
||||
function isDirectory(path: string) {
|
||||
return fs.existsSync(path) && fs.lstatSync(path).isDirectory();
|
||||
}
|
||||
|
||||
export {
|
||||
|
||||
52
packages/now-next/test/fixtures/00-root-optional-revalidate/additional.js
vendored
Normal file
52
packages/now-next/test/fixtures/00-root-optional-revalidate/additional.js
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/* eslint-env jest */
|
||||
const fetch = require('node-fetch');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
const waitFor = ms => new Promise(resolve => setTimeout(resolve, ms));
|
||||
|
||||
module.exports = function (ctx) {
|
||||
const getProps = async path => {
|
||||
const html = await fetch(`${ctx.deploymentUrl}/${path}`).then(res =>
|
||||
res.text()
|
||||
);
|
||||
|
||||
const $ = cheerio.load(html);
|
||||
return JSON.parse($('#props').text());
|
||||
};
|
||||
|
||||
it('should render / correctly', async () => {
|
||||
const props = await getProps('/', { params: {} });
|
||||
expect(props.params).toEqual({});
|
||||
|
||||
await waitFor(2000);
|
||||
await getProps('/');
|
||||
|
||||
const newProps = await getProps('/', { params: {} });
|
||||
expect(newProps.params).toEqual({});
|
||||
expect(props.random).not.toBe(newProps.random);
|
||||
});
|
||||
|
||||
it('should render /a correctly', async () => {
|
||||
const props = await getProps('/a');
|
||||
expect(props.params).toEqual({ slug: ['a'] });
|
||||
|
||||
await waitFor(2000);
|
||||
await getProps('/a');
|
||||
|
||||
const newProps = await getProps('/a');
|
||||
expect(newProps.params).toEqual({ slug: ['a'] });
|
||||
expect(props.random).not.toBe(newProps.random);
|
||||
});
|
||||
|
||||
it('should render /hello/world correctly', async () => {
|
||||
const props = await getProps('/hello/world');
|
||||
expect(props.params).toEqual({ slug: ['hello', 'world'] });
|
||||
|
||||
await waitFor(2000);
|
||||
await getProps('/hello/world');
|
||||
|
||||
const newProps = await getProps('/hello/world');
|
||||
expect(newProps.params).toEqual({ slug: ['hello', 'world'] });
|
||||
expect(props.random).not.toBe(newProps.random);
|
||||
});
|
||||
};
|
||||
15
packages/now-next/test/fixtures/00-root-optional-revalidate/now.json
vendored
Normal file
15
packages/now-next/test/fixtures/00-root-optional-revalidate/now.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{
|
||||
"src": "package.json",
|
||||
"use": "@vercel/next"
|
||||
}
|
||||
],
|
||||
"probes": [
|
||||
{
|
||||
"path": "/non-existent",
|
||||
"status": 404
|
||||
}
|
||||
]
|
||||
}
|
||||
7
packages/now-next/test/fixtures/00-root-optional-revalidate/package.json
vendored
Normal file
7
packages/now-next/test/fixtures/00-root-optional-revalidate/package.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"next": "canary",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6"
|
||||
}
|
||||
}
|
||||
24
packages/now-next/test/fixtures/00-root-optional-revalidate/pages/[[...slug]].js
vendored
Normal file
24
packages/now-next/test/fixtures/00-root-optional-revalidate/pages/[[...slug]].js
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
export default function Home(props) {
|
||||
return <pre id="props">{JSON.stringify(props)}</pre>;
|
||||
}
|
||||
|
||||
export async function getStaticPaths() {
|
||||
return {
|
||||
paths: [
|
||||
{ params: { slug: false } },
|
||||
{ params: { slug: ['a'] } },
|
||||
{ params: { slug: ['hello', 'world'] } },
|
||||
],
|
||||
fallback: false,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getStaticProps({ params }) {
|
||||
return {
|
||||
props: {
|
||||
params,
|
||||
random: Math.random(),
|
||||
},
|
||||
revalidate: 1,
|
||||
};
|
||||
}
|
||||
@@ -7,6 +7,15 @@
|
||||
"functions": {
|
||||
"src/pages/api/memory.js": {
|
||||
"memory": 128
|
||||
},
|
||||
"src/pages/api/index.js": {
|
||||
"memory": 192
|
||||
},
|
||||
"src/pages/api/sub/index.ts": {
|
||||
"memory": 128
|
||||
},
|
||||
"src/pages/api/sub/another.ts": {
|
||||
"memory": 192
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +27,21 @@
|
||||
"status": 200,
|
||||
"mustContain": "128"
|
||||
},
|
||||
{
|
||||
"path": "/api",
|
||||
"status": 200,
|
||||
"mustContain": "192"
|
||||
},
|
||||
{
|
||||
"path": "/api/sub",
|
||||
"status": 200,
|
||||
"mustContain": "128"
|
||||
},
|
||||
{
|
||||
"path": "/api/sub/another",
|
||||
"status": 200,
|
||||
"mustContain": "192"
|
||||
},
|
||||
{
|
||||
"logMustContain": "WARNING: Your application is being opted out of \"@vercel/next\" optimized lambdas mode due to `functions` config"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
{
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@types/node": "^12.12.56",
|
||||
"@types/react": "^16.9.49",
|
||||
"next": "canary",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6"
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1",
|
||||
"typescript": "^4.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
3
packages/now-next/test/fixtures/06-lambda-with-memory/src/pages/api/index.js
vendored
Normal file
3
packages/now-next/test/fixtures/06-lambda-with-memory/src/pages/api/index.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function (req, res) {
|
||||
res.end(`${process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE}`);
|
||||
}
|
||||
3
packages/now-next/test/fixtures/06-lambda-with-memory/src/pages/api/sub/another.ts
vendored
Normal file
3
packages/now-next/test/fixtures/06-lambda-with-memory/src/pages/api/sub/another.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function (req: any, res: any) {
|
||||
res.end(`${process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE}`);
|
||||
}
|
||||
3
packages/now-next/test/fixtures/06-lambda-with-memory/src/pages/api/sub/index.ts
vendored
Normal file
3
packages/now-next/test/fixtures/06-lambda-with-memory/src/pages/api/sub/index.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function (req: any, res: any) {
|
||||
res.end(`${process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE}`);
|
||||
}
|
||||
@@ -135,6 +135,27 @@
|
||||
"path": "/_next/data/testing-build-id/nofallback/nope.json",
|
||||
"status": 404
|
||||
},
|
||||
{
|
||||
"path": "/api-docs/first",
|
||||
"status": 200,
|
||||
"mustContain": "API Docs"
|
||||
},
|
||||
{
|
||||
"path": "/api-docs/second",
|
||||
"status": 200,
|
||||
"mustContain": "Loading..."
|
||||
},
|
||||
{
|
||||
"path": "/_next/data/testing-build-id/api-docs/first.json",
|
||||
"status": 200,
|
||||
"responseHeaders": {
|
||||
"x-vercel-cache": "/HIT|STALE|PRERENDER/"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "/_next/data/testing-build-id/api-docs/second.json",
|
||||
"status": 200
|
||||
},
|
||||
{
|
||||
"logMustNotContain": "WARNING: your application is being opted out of @vercel/next's optimized lambdas mode due to legacy routes"
|
||||
},
|
||||
|
||||
27
packages/now-next/test/fixtures/22-ssg-v2/pages/api-docs/[...slug].js
vendored
Normal file
27
packages/now-next/test/fixtures/22-ssg-v2/pages/api-docs/[...slug].js
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
export const getStaticProps = () => {
|
||||
return {
|
||||
props: {
|
||||
hello: 'world',
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const getStaticPaths = () => {
|
||||
return {
|
||||
paths: ['/api-docs/first'],
|
||||
fallback: true,
|
||||
};
|
||||
};
|
||||
|
||||
export default function Slug(props) {
|
||||
if (useRouter().isFallback) return 'Loading...';
|
||||
|
||||
return (
|
||||
<>
|
||||
<p id="api-docs">API Docs</p>
|
||||
<p id="props">{JSON.stringify(props)}</p>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -40,6 +40,6 @@ declare namespace ncc {
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@zeit/ncc' {
|
||||
declare module '@vercel/ncc' {
|
||||
export = ncc;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node",
|
||||
"version": "1.8.0",
|
||||
"version": "1.8.3",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
||||
@@ -32,13 +32,13 @@
|
||||
"@types/cookie": "0.3.3",
|
||||
"@types/etag": "1.8.0",
|
||||
"@types/test-listen": "1.1.0",
|
||||
"@zeit/ncc": "0.20.4",
|
||||
"@zeit/node-file-trace": "0.8.2",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/nft": "0.9.2",
|
||||
"content-type": "1.0.4",
|
||||
"cookie": "0.4.0",
|
||||
"etag": "1.8.1",
|
||||
"mkdirp-promise": "5.0.1",
|
||||
"node-fetch": "2.6.0",
|
||||
"node-fetch": "2.6.1",
|
||||
"source-map-support": "0.5.12",
|
||||
"test-listen": "1.1.0"
|
||||
}
|
||||
|
||||
@@ -8,11 +8,10 @@ if (!entrypoint) {
|
||||
throw new Error('`VERCEL_DEV_ENTRYPOINT` must be defined');
|
||||
}
|
||||
|
||||
import fs from 'fs';
|
||||
import { register } from 'ts-node';
|
||||
|
||||
// Use the project's version of TypeScript if available,
|
||||
// otherwise fall back to using the copy that `@now/node` uses.
|
||||
// otherwise fall back to using the copy that `@vercel/node` uses.
|
||||
let compiler: string;
|
||||
try {
|
||||
compiler = require.resolve('typescript', {
|
||||
@@ -34,12 +33,11 @@ if (nodeMajor >= 14) {
|
||||
|
||||
if (tsconfig) {
|
||||
try {
|
||||
const tsconfigParsed = JSON.parse(fs.readFileSync(tsconfig, 'utf8'));
|
||||
if (
|
||||
tsconfigParsed.compilerOptions &&
|
||||
tsconfigParsed.compilerOptions.target
|
||||
) {
|
||||
target = tsconfigParsed.compilerOptions.target;
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const ts: typeof import('typescript') = require(compiler);
|
||||
const { config } = ts.readConfigFile(tsconfig, ts.sys.readFile);
|
||||
if (config?.compilerOptions?.target) {
|
||||
target = config.compilerOptions.target;
|
||||
}
|
||||
} catch (err) {
|
||||
if (err.code !== 'ENOENT') {
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
// @ts-ignore - `@types/mkdirp-promise` is broken
|
||||
import mkdirp from 'mkdirp-promise';
|
||||
import once from '@tootallnate/once';
|
||||
import { nodeFileTrace } from '@zeit/node-file-trace';
|
||||
import { nodeFileTrace } from '@vercel/nft';
|
||||
import buildUtils from './build-utils';
|
||||
import {
|
||||
File,
|
||||
@@ -52,12 +52,6 @@ import { Register, register } from './typescript';
|
||||
export { shouldServe };
|
||||
export { NowRequest, NowResponse } from './types';
|
||||
|
||||
interface CompilerConfig {
|
||||
debug?: boolean;
|
||||
includeFiles?: string | string[];
|
||||
excludeFiles?: string | string[];
|
||||
}
|
||||
|
||||
interface DownloadOptions {
|
||||
files: Files;
|
||||
entrypoint: string;
|
||||
@@ -125,9 +119,10 @@ async function downloadInstallAndBundle({
|
||||
|
||||
async function compile(
|
||||
workPath: string,
|
||||
baseDir: string,
|
||||
entrypointPath: string,
|
||||
entrypoint: string,
|
||||
config: CompilerConfig
|
||||
config: Config
|
||||
): Promise<{
|
||||
preparedFiles: Files;
|
||||
shouldAddSourcemapSupport: boolean;
|
||||
@@ -150,20 +145,21 @@ async function compile(
|
||||
for (const pattern of includeFiles) {
|
||||
const files = await glob(pattern, workPath);
|
||||
await Promise.all(
|
||||
Object.keys(files).map(async file => {
|
||||
const entry = files[file];
|
||||
fsCache.set(file, entry);
|
||||
Object.values(files).map(async entry => {
|
||||
const { fsPath } = entry;
|
||||
const relPath = relative(baseDir, fsPath);
|
||||
fsCache.set(relPath, entry);
|
||||
const stream = entry.toStream();
|
||||
const { data } = await FileBlob.fromStream({ stream });
|
||||
if (file.endsWith('.ts') || file.endsWith('.tsx')) {
|
||||
if (relPath.endsWith('.ts') || relPath.endsWith('.tsx')) {
|
||||
sourceCache.set(
|
||||
file,
|
||||
compileTypeScript(resolve(workPath, file), data.toString())
|
||||
relPath,
|
||||
compileTypeScript(fsPath, data.toString())
|
||||
);
|
||||
} else {
|
||||
sourceCache.set(file, data);
|
||||
sourceCache.set(relPath, data);
|
||||
}
|
||||
inputFiles.add(resolve(workPath, file));
|
||||
inputFiles.add(fsPath);
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -178,7 +174,7 @@ async function compile(
|
||||
|
||||
let tsCompile: Register;
|
||||
function compileTypeScript(path: string, source: string): string {
|
||||
const relPath = relative(workPath, path);
|
||||
const relPath = relative(baseDir, path);
|
||||
if (!tsCompile) {
|
||||
tsCompile = register({
|
||||
basePath: workPath, // The base is the same as root now.json dir
|
||||
@@ -201,12 +197,13 @@ async function compile(
|
||||
const { fileList, esmFileList, warnings } = await nodeFileTrace(
|
||||
[...inputFiles],
|
||||
{
|
||||
base: workPath,
|
||||
base: baseDir,
|
||||
processCwd: workPath,
|
||||
ts: true,
|
||||
mixedModules: true,
|
||||
ignore: config.excludeFiles,
|
||||
readFile(fsPath: string): Buffer | string | null {
|
||||
const relPath = relative(workPath, fsPath);
|
||||
const relPath = relative(baseDir, fsPath);
|
||||
const cached = sourceCache.get(relPath);
|
||||
if (cached) return cached.toString();
|
||||
// null represents a not found
|
||||
@@ -246,7 +243,7 @@ async function compile(
|
||||
for (const path of fileList) {
|
||||
let entry = fsCache.get(path);
|
||||
if (!entry) {
|
||||
const fsPath = resolve(workPath, path);
|
||||
const fsPath = resolve(baseDir, path);
|
||||
const { mode } = lstatSync(fsPath);
|
||||
if (isSymbolicLink(mode)) {
|
||||
entry = new FileFsRef({ fsPath, mode });
|
||||
@@ -258,14 +255,14 @@ async function compile(
|
||||
if (isSymbolicLink(entry.mode) && entry.fsPath) {
|
||||
// ensure the symlink target is added to the file list
|
||||
const symlinkTarget = relative(
|
||||
workPath,
|
||||
baseDir,
|
||||
resolve(dirname(entry.fsPath), readlinkSync(entry.fsPath))
|
||||
);
|
||||
if (
|
||||
!symlinkTarget.startsWith('..' + sep) &&
|
||||
fileList.indexOf(symlinkTarget) === -1
|
||||
) {
|
||||
const stats = statSync(resolve(workPath, symlinkTarget));
|
||||
const stats = statSync(resolve(baseDir, symlinkTarget));
|
||||
if (stats.isFile()) {
|
||||
fileList.push(symlinkTarget);
|
||||
}
|
||||
@@ -275,7 +272,7 @@ async function compile(
|
||||
// There is a bug on Windows where entrypoint uses forward slashes
|
||||
// and workPath uses backslashes so we use resolve before comparing.
|
||||
if (
|
||||
resolve(workPath, path) !== resolve(workPath, entrypoint) &&
|
||||
resolve(baseDir, path) !== resolve(workPath, entrypoint) &&
|
||||
tsCompiled.has(path)
|
||||
) {
|
||||
preparedFiles[
|
||||
@@ -339,6 +336,7 @@ export async function build({
|
||||
files,
|
||||
entrypoint,
|
||||
workPath,
|
||||
repoRootPath,
|
||||
config = {},
|
||||
meta = {},
|
||||
}: BuildOptions) {
|
||||
@@ -346,6 +344,7 @@ export async function build({
|
||||
config.helpers === false || process.env.NODEJS_HELPERS === '0'
|
||||
);
|
||||
|
||||
const baseDir = repoRootPath || workPath;
|
||||
const awsLambdaHandler = getAWSLambdaHandler(entrypoint, config);
|
||||
|
||||
const {
|
||||
@@ -372,6 +371,7 @@ export async function build({
|
||||
const traceTime = Date.now();
|
||||
const { preparedFiles, shouldAddSourcemapSupport, watch } = await compile(
|
||||
workPath,
|
||||
baseDir,
|
||||
entrypointPath,
|
||||
entrypoint,
|
||||
config
|
||||
@@ -383,7 +383,7 @@ export async function build({
|
||||
const launcherFiles: Files = {
|
||||
[`${LAUNCHER_FILENAME}.js`]: new FileBlob({
|
||||
data: makeLauncher({
|
||||
entrypointPath: `./${entrypoint}`,
|
||||
entrypointPath: `./${relative(baseDir, entrypointPath)}`,
|
||||
bridgePath: `./${BRIDGE_FILENAME}`,
|
||||
helpersPath: `./${HELPERS_FILENAME}`,
|
||||
sourcemapSupportPath: `./${SOURCEMAP_SUPPORT_FILENAME}`,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"sourceMap": true,
|
||||
"jsx": "react",
|
||||
"lib": ["esnext"],
|
||||
"target": "esnext",
|
||||
"module": "commonjs"
|
||||
|
||||
18
packages/now-node/test/integration.test.js
vendored
18
packages/now-node/test/integration.test.js
vendored
@@ -28,26 +28,32 @@ beforeAll(async () => {
|
||||
|
||||
const fixturesPath = path.resolve(__dirname, 'fixtures');
|
||||
|
||||
const testsThatFailToBuild = new Set(['45-noEmitOnError-true']);
|
||||
const testsThatFailToBuild = new Map([
|
||||
[
|
||||
'45-noEmitOnError-true',
|
||||
`index.ts(3,19): error TS2339: Property 'thisDoesNotExist' does not exist on type 'IncomingMessage'.\n`,
|
||||
],
|
||||
]);
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const fixture of fs.readdirSync(fixturesPath)) {
|
||||
if (testsThatFailToBuild.has(fixture)) {
|
||||
const errMsg = testsThatFailToBuild.get(fixture);
|
||||
if (errMsg) {
|
||||
// eslint-disable-next-line no-loop-func
|
||||
it(`should not build ${fixture}`, async () => {
|
||||
it(`should fail to build ${fixture}`, async () => {
|
||||
try {
|
||||
await testDeployment(
|
||||
{ builderUrl, buildUtilsUrl },
|
||||
path.join(fixturesPath, fixture)
|
||||
);
|
||||
} catch (err) {
|
||||
expect(err.message).toMatch(/is ERROR/);
|
||||
expect(err).toBeTruthy();
|
||||
expect(err.deployment).toBeTruthy();
|
||||
expect(err.deployment.errorMessage).toBe(errMsg);
|
||||
}
|
||||
});
|
||||
continue; //eslint-disable-line
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-loop-func
|
||||
it(`should build ${fixture}`, async () => {
|
||||
await expect(
|
||||
testDeployment(
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": ["esnext"],
|
||||
"target": "esnext",
|
||||
"target": "es2018",
|
||||
"module": "commonjs",
|
||||
"outDir": "dist",
|
||||
"sourceMap": false,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/python",
|
||||
"version": "1.2.2",
|
||||
"version": "1.2.3",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
||||
@@ -20,6 +20,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/execa": "^0.9.0",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"execa": "^1.0.0",
|
||||
"typescript": "3.9.3"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@vercel/ruby",
|
||||
"author": "Nathan Cahill <nathan@nathancahill.com>",
|
||||
"version": "1.2.3",
|
||||
"version": "1.2.4",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby",
|
||||
@@ -22,6 +22,7 @@
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "8.0.0",
|
||||
"@types/semver": "6.0.0",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"execa": "2.0.4",
|
||||
"fs-extra": "^7.0.1",
|
||||
"semver": "6.1.1",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "@vercel/static-build",
|
||||
"version": "0.17.7",
|
||||
"version": "0.17.9",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/static-builds",
|
||||
"homepage": "https://vercel.com/docs/build-step",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
@@ -23,10 +23,11 @@
|
||||
"@types/ms": "0.7.31",
|
||||
"@types/node-fetch": "2.5.4",
|
||||
"@types/promise-timeout": "1.3.0",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"get-port": "5.0.0",
|
||||
"is-port-reachable": "2.0.1",
|
||||
"ms": "2.1.2",
|
||||
"node-fetch": "2.6.0",
|
||||
"node-fetch": "2.6.1",
|
||||
"typescript": "3.9.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ const frameworkList: Framework[] = [
|
||||
continue: true,
|
||||
},
|
||||
{
|
||||
src: '^/(img|js|css|fonts|media)/.*',
|
||||
src: '^/(img|js|css|fonts|media)/[^/]+\\.[0-9a-f]{8}\\.*',
|
||||
headers: { 'cache-control': 'max-age=31536000, immutable' },
|
||||
continue: true,
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/redwood",
|
||||
"version": "0.1.0",
|
||||
"version": "0.1.1",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"homepage": "https://vercel.com/docs",
|
||||
@@ -19,7 +19,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@netlify/zip-it-and-ship-it": "1.2.0",
|
||||
"@vercel/frameworks": "0.1.0"
|
||||
"@vercel/frameworks": "0.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/aws-lambda": "8.10.19",
|
||||
|
||||
@@ -154,23 +154,21 @@ async function fetchWithAuth(url, opts = {}) {
|
||||
if (!opts.headers) opts.headers = {};
|
||||
|
||||
if (!opts.headers.Authorization) {
|
||||
currentCount += 1;
|
||||
if (!token || currentCount === MAX_COUNT) {
|
||||
currentCount = 0;
|
||||
// used for health checks
|
||||
token = process.env.VERCEL_TOKEN || process.env.NOW_TOKEN;
|
||||
if (!token) {
|
||||
// used by GH Actions
|
||||
token = await fetchTokenWithRetry();
|
||||
}
|
||||
}
|
||||
|
||||
opts.headers.Authorization = `Bearer ${token}`;
|
||||
opts.headers.Authorization = `Bearer ${await fetchCachedToken()}`;
|
||||
}
|
||||
|
||||
return await fetchApi(url, opts);
|
||||
}
|
||||
|
||||
async function fetchCachedToken() {
|
||||
currentCount += 1;
|
||||
if (!token || currentCount === MAX_COUNT) {
|
||||
currentCount = 0;
|
||||
token = await fetchTokenWithRetry();
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
async function fetchTokenWithRetry(retries = 5) {
|
||||
const {
|
||||
NOW_TOKEN,
|
||||
@@ -248,5 +246,6 @@ module.exports = {
|
||||
fetchWithAuth,
|
||||
nowDeploy,
|
||||
fetchTokenWithRetry,
|
||||
fetchCachedToken,
|
||||
fileModeSymbol,
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user