Compare commits

..

24 Commits

Author SHA1 Message Date
Steven
0d4be3f5f2 Publish Canary
- @vercel/build-utils@2.5.2-canary.2
 - vercel@20.1.1-canary.3
 - @vercel/client@9.0.2-canary.2
 - @vercel/next@2.6.25-canary.2
 - @vercel/node@1.8.2-canary.2
2020-09-05 15:16:56 -04:00
Steven
a971c2aa3a [tests] Delay deprecation message (#5158)
This PR is a follow up to #5157 which was unable to deprecate a package immediately after publishing and failed with E405. So this PR adds a delay between publish and deprecate. It also uses the `-f` flag suggested in the error message. https://github.com/vercel/vercel/runs/1076007594#step:6:649
2020-09-05 15:13:48 -04:00
Steven
66414bd65a Publish Canary
- @vercel/build-utils@2.5.2-canary.1
 - vercel@20.1.1-canary.2
 - @vercel/client@9.0.2-canary.1
 - @vercel/next@2.6.25-canary.1
 - @vercel/node@1.8.2-canary.1
2020-09-05 13:54:34 -04:00
Steven
3b021993b5 [tests] Fix deprecation message (#5157)
This PR is a follow up to #5119 which had the names backwards.

I fixed the variable names to avoid the confusion since "new" and "old" were ambiguous.

I also removed the incorrect deprecation message from packages published during commit c9597dc199.
2020-09-05 13:49:20 -04:00
JJ Kasper
c9597dc199 Publish Canary
- @vercel/build-utils@2.5.2-canary.0
 - vercel@20.1.1-canary.1
 - @vercel/client@9.0.2-canary.0
 - @vercel/next@2.6.25-canary.0
 - @vercel/node@1.8.2-canary.0
2020-09-05 00:16:18 -05:00
Steven
1b5c94b392 [node][next] Fix nft tracing for monorepos (#5143)
Co-authored-by: Joe Haddad <joe.haddad@zeit.co>
Co-authored-by: JJ Kasper <jj@jjsweb.site>
2020-09-05 01:13:54 -04:00
dav-is
bd1393a9d6 Publish Canary
- vercel@20.1.1-canary.0
2020-09-04 18:40:25 -04:00
dependabot[bot]
47ddd36fec [cli] Update http-proxy to v1.18.1 (#5152)
Bumps [http-proxy](https://github.com/http-party/node-http-proxy) from 1.17.0 to 1.18.1.
- [Release notes](https://github.com/http-party/node-http-proxy/releases)
- [Changelog](https://github.com/http-party/node-http-proxy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/http-party/node-http-proxy/compare/1.17.0...1.18.1)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-09-04 14:33:56 -07:00
dependabot[bot]
bd047cdc6a Update tree-kill to v1.2.2 (#5151)
Bumps [tree-kill](https://github.com/pkrumins/node-tree-kill) from 1.2.1 to 1.2.2.
- [Release notes](https://github.com/pkrumins/node-tree-kill/releases)
- [Commits](https://github.com/pkrumins/node-tree-kill/compare/v1.2.1...v1.2.2)

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

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2020-09-04 14:33:32 -07:00
Connor Davis
477f9e8753 [cli] Fix color and indention in learn more link (#5148)
CH-568

Before:
![image](https://user-images.githubusercontent.com/11590024/92258007-2883e080-eea4-11ea-8c14-af0f3c9e27a6.png)

After:
![Screenshot-2020-09-04-11:44](https://user-images.githubusercontent.com/11590024/92258023-3174b200-eea4-11ea-9170-0acd4d6f883b.png)
2020-09-04 21:25:52 +00:00
Mike Hartington
183ea42f94 [examples] chore(ionic-angular): remove Google Maps API key (#5130) 2020-08-31 11:58:52 -07:00
Steven
57a17eb416 [tests] Deprecate "now" npm package in favor of "vercel" (#5119)
We deprecated all the `now` scoped packages in favor of the `vercel` equivalents, however the deprecation message disappears after each publish, so we must to run `npm deprecate` after `npm publish` for legacy packages.
2020-08-28 15:39:06 -04:00
Steven
be24510f16 Publish Stable
- @vercel/frameworks@0.1.1
 - @vercel/build-utils@2.5.1
 - vercel@20.1.0
 - @vercel/client@9.0.1
 - @vercel/go@1.1.6
 - @vercel/next@2.6.24
 - @vercel/node@1.8.1
 - @vercel/python@1.2.3
 - @vercel/ruby@1.2.4
 - @vercel/static-build@0.17.8
 - @vercel/redwood@0.1.1
2020-08-27 20:01:15 -04:00
Steven
05c534d855 Publish Canary
- @vercel/frameworks@0.1.1-canary.0
 - @vercel/build-utils@2.5.1-canary.1
 - vercel@20.0.1-canary.2
 - @vercel/client@9.0.1-canary.1
 - @vercel/go@1.1.6-canary.0
 - @vercel/node@1.8.1-canary.0
 - @vercel/python@1.2.3-canary.0
 - @vercel/ruby@1.2.4-canary.0
 - @vercel/static-build@0.17.8-canary.0
 - @vercel/redwood@0.1.1-canary.0
2020-08-27 19:39:21 -04:00
Shu Ding
910169dba7 [cli] Add support for the sourceFilesOutsideRootDirectory option (#5113)
If the value is set to `true` in the project settings, we don't cd into `rootDirectory`. 
We default it to `true` for new projects.
2020-08-27 23:37:50 +00:00
Steven
0fc74feddc [all] Bump ncc to 0.24.0 (#5103)
- Bump ncc to [0.24.0](https://github.com/vercel/ncc/releases/tag/0.24.0)
- Install ncc in each package that depends on it
2020-08-26 11:03:34 -04:00
Naoyuki Kanezawa
a9ea294514 fix framework names (#5104) 2020-08-26 22:14:39 +09:00
Steven
42e0450d87 Publish Canary
- vercel@20.0.1-canary.1
 - @vercel/next@2.6.24-canary.0
2020-08-25 22:13:26 -04:00
Guy Bedford
08c0feb58a [cli] Improve startup perf - disable source maps and minification (#5100)
Currently on my machine, vercel --version takes 850ms to run. With this change, that execution time is reduced to ~550ms.

The reason is that source maps seem to significantly slow down Node.js execution, compounded by the size of the source map, even if it is not used.

I believe the benefits of this perf improvement outweigh the direct source maps and minification benefits.

If it is felt that direct per-file source maps are necessary for internal errors, then reducing the source map size should be investigated further to improve the runtime performance here.
2020-08-25 22:12:25 -04:00
Mark Glagola
60aaf76ed2 [cli] Fix vc domains ls pagination (#5099)
Fixes pagination for vercel cli `domains ls --next <timestamp>`
2020-08-25 19:39:34 -04:00
Matthew Sweeney
bd706beba5 [examples] Update README Files (#5092)
This PR updates the `README.md` files with the following changes:

- Removal of CLI deployment.
- Amends Blitz.js to be in line with other `README.md` formats.
2020-08-25 14:51:46 -04:00
JJ Kasper
b85a0a349a [next] Add test case for root optional revalidate params (#5072)
This adds test cases from https://github.com/vercel/next.js/pull/16451 which are currently failing and will pass after a new canary of Next.js has been published
2020-08-24 16:32:30 +00:00
Steven
a97bc2af6d Publish Canary
- @vercel/build-utils@2.5.1-canary.0
 - vercel@20.0.1-canary.0
 - @vercel/client@9.0.1-canary.0
2020-08-24 11:19:44 -04:00
Steven
a5dc90c8cd Revert "[build-utils] Use handle: error for api 404" (#5088)
* Revert "[build-utils] Use `handle: error` for api 404 (#5064)"

This reverts commit 02e1c921ac.

* Re-enable cli changes

* Re-enable redwood changes

* Minor cleanup
2020-08-24 11:16:32 -04:00
65 changed files with 521 additions and 814 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -1,21 +1,19 @@
![Blitz Logo](https://github.com/vercel/vercel/blob/master/packages/frameworks/logos/blitz.svg)
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)
[![Deploy with Vercel](https://vercel.com/button)](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)

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -27,7 +27,7 @@ export class MapPage implements AfterViewInit {
}
const googleMaps = await getGoogleMaps(
'AIzaSyB8pf6ZdFQj5qw7rc_HSGrhUwQKfIe9ICw'
'YOUR_API_KEY_HERE'
);
let map;

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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
```

View File

@@ -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",

View File

@@ -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",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/frameworks",
"version": "0.1.0",
"version": "0.1.1",
"main": "frameworks.json",
"license": "UNLICENSED",
"scripts": {

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/build-utils",
"version": "2.5.0",
"version": "2.5.2-canary.2",
"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",

View File

@@ -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 {

View File

@@ -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`.

View File

@@ -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,
},
]);
}

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "20.0.0",
"version": "20.1.1-canary.3",
"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.2-canary.2",
"@vercel/go": "1.1.6",
"@vercel/node": "1.8.2-canary.2",
"@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",
@@ -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",

View File

@@ -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:

View File

@@ -157,17 +157,22 @@ 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 +
newline;
output.print(message + link);
}
}
};
@@ -276,6 +281,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 +339,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 +356,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 +380,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 +537,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 +563,10 @@ export default async function main(
projectSettings.rootDirectory = rootDirectory;
}
if (typeof sourceFilesOutsideRootDirectory !== 'undefined') {
projectSettings.sourceFilesOutsideRootDirectory = sourceFilesOutsideRootDirectory;
}
const settings = await editProjectSettings(
output,
projectSettings,

View File

@@ -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();
});

View File

@@ -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,

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/client",
"version": "9.0.0",
"version": "9.0.2-canary.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,7 +37,7 @@
]
},
"dependencies": {
"@vercel/build-utils": "2.5.0",
"@vercel/build-utils": "2.5.2-canary.2",
"@zeit/fetch": "5.2.0",
"async-retry": "1.2.3",
"async-sema": "3.0.0",

View File

@@ -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",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/next",
"version": "2.6.23",
"version": "2.6.25-canary.2",
"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",

View File

@@ -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;
@@ -756,7 +758,10 @@ export const build = async ({
};
const lambdaOptions = await getLambdaOptionsFromFunction({
sourceFile: await getSourceFilePathFromPage({ workPath, page }),
sourceFile: await getSourceFilePathFromPage({
workPath: entryPath,
page,
}),
config,
});
@@ -939,12 +944,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 +973,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 +984,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 +1169,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 +1209,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 +1243,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 +1262,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,
@@ -1372,10 +1403,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 +1434,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 +1449,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,
});
}

View File

@@ -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';

View File

@@ -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';

View 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);
});
};

View File

@@ -0,0 +1,15 @@
{
"version": 2,
"builds": [
{
"src": "package.json",
"use": "@vercel/next"
}
],
"probes": [
{
"path": "/non-existent",
"status": 404
}
]
}

View File

@@ -0,0 +1,7 @@
{
"dependencies": {
"next": "canary",
"react": "^16.8.6",
"react-dom": "^16.8.6"
}
}

View 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,
};
}

View File

@@ -40,6 +40,6 @@ declare namespace ncc {
}
}
declare module '@zeit/ncc' {
declare module '@vercel/ncc' {
export = ncc;
}

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/node",
"version": "1.8.0",
"version": "1.8.2-canary.2",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -32,8 +32,8 @@
"@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",

View File

@@ -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}`,

View File

@@ -3,6 +3,7 @@
"strict": true,
"esModuleInterop": true,
"sourceMap": true,
"jsx": "react",
"lib": ["esnext"],
"target": "esnext",
"module": "commonjs"

View File

@@ -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"
}

View File

@@ -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",

View File

@@ -1,9 +1,9 @@
{
"name": "@vercel/static-build",
"version": "0.17.7",
"version": "0.17.8",
"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,6 +23,7 @@
"@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",

View File

@@ -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",

View File

@@ -14,7 +14,15 @@ commit="$(git log --format="%H" -n 1)"
tags="$(git show-ref --tags -d | grep ^"$commit" | sed -e 's,.* refs/tags/,,' -e 's/\^{}//')"
for tag in $tags; do
package_dir="$(node "${__dirname}/update-legacy-name.js" "$tag")"
str="$(node "${__dirname}/update-legacy-name.js" "$tag")"
IFS='|' # set delimiter
read -ra ADDR <<< "$str" # str is read into an array as tokens separated by IFS
package_dir="${ADDR[0]}"
vc_name="${ADDR[1]}"
now_name="${ADDR[2]}"
version="${ADDR[3]}"
IFS=' ' # reset to default after usage
cd "${__dirname}/../packages/${package_dir}"
@@ -25,4 +33,7 @@ for tag in $tags; do
echo "Running \`npm publish $npm_tag\` in \"$(pwd)\""
npm publish $npm_tag
sleep 5 # Wait after publish before deprecate to avoid E405. https://github.com/vercel/vercel/runs/1076007594#step:6:649
echo "Running \`npm deprecate -f $now_name@$version\` in favor of $vc_name"
npm deprecate -f "$now_name@$version" "\"$now_name\" is deprecated and will stop receiving updates on December 31, 2020. Please use \"$vc_name\" instead."
done

View File

@@ -29,7 +29,8 @@ if (!packageDir) {
const pkgJsonPath = join(packagesDir, packageDir, 'package.json');
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
const originalName = pkg.name;
const vcName = pkg.name;
const version = pkg.version;
if (pkg.name === '@vercel/client') {
// The legacy name for `@vercel/client` is `now-client` (global scope)
@@ -42,10 +43,12 @@ if (pkg.name === '@vercel/client') {
}
}
console.error(`Updated package name: "${originalName}" -> "${pkg.name}"`);
const nowName = pkg.name;
console.error(`Updated package name: "${vcName}" -> "${nowName}"`);
fs.writeFileSync(pkgJsonPath, `${JSON.stringify(pkg, null, 2)}\n`);
// Log the directory name to stdout for the `publish-legacy.sh`
// script to consume for the `npm publish` that happens next.
console.log(packageDir);
const IFS = '|';
console.log([packageDir, vcName, nowName, version].join(IFS));

123
yarn.lock
View File

@@ -2216,6 +2216,33 @@
semver "^7.3.2"
tsutils "^3.17.1"
"@vercel/ncc@0.24.0":
version "0.24.0"
resolved "https://registry.yarnpkg.com/@vercel/ncc/-/ncc-0.24.0.tgz#a2e8783a185caa99b5d8961a57dfc9665de16296"
integrity sha512-crqItMcIwCkvdXY/V3/TzrHJQx6nbIaRqE1cOopJhgGX6izvNov40SmD//nS5flfEvdK54YGjwVVq+zG6crjOg==
"@vercel/nft@0.9.2":
version "0.9.2"
resolved "https://registry.yarnpkg.com/@vercel/nft/-/nft-0.9.2.tgz#677ecefb0bd618143281c62c719baca57a36ac4d"
integrity sha512-Dr2yJlCnfkQEt4QHKcPJKTxCyoBX0YCzHDzozd8upBFm8kKbh2yMSu5wp+1btevQXOMkOUtxntovwwPHDIU51w==
dependencies:
acorn "^7.1.1"
acorn-class-fields "^0.3.2"
acorn-export-ns-from "^0.1.0"
acorn-import-meta "^1.1.0"
acorn-numeric-separator "^0.3.0"
acorn-static-class-features "^0.2.1"
bindings "^1.4.0"
estree-walker "^0.6.1"
glob "^7.1.3"
graceful-fs "^4.1.15"
micromatch "^4.0.2"
mkdirp "^0.5.1"
node-gyp-build "^4.2.2"
node-pre-gyp "^0.13.0"
resolve-from "^5.0.0"
rollup-pluginutils "^2.8.2"
"@zeit/dns-cached-resolve@2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@zeit/dns-cached-resolve/-/dns-cached-resolve-2.1.0.tgz#78583010df1683fdb7b05949b75593c9a8641bc1"
@@ -2277,38 +2304,6 @@
xdg-app-paths "5.1.0"
yauzl-promise "2.1.3"
"@zeit/ncc@0.18.5":
version "0.18.5"
resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.18.5.tgz#5687df6c32f1a2e2486aa110b3454ccebda4fb9c"
integrity sha512-F+SbvEAh8rchiRXqQbmD1UmbePY7dCOKTbvfFtbVbK2xMH/tyri5YKfNxXKK7eL9EWkkbqB3NTVQO6nokApeBA==
"@zeit/ncc@0.20.4":
version "0.20.4"
resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.20.4.tgz#00f0a25a88cac3712af4ba66561d9e281c6f05c9"
integrity sha512-fmq+F/QxPec+k/zvT7HiVpk7oiGFseS6brfT/AYqmCUp6QFRK7vZf2Ref46MImsg/g2W3g5X6SRvGRmOAvEfdA==
"@zeit/node-file-trace@0.8.2":
version "0.8.2"
resolved "https://registry.yarnpkg.com/@zeit/node-file-trace/-/node-file-trace-0.8.2.tgz#a00d21a98015c4ea18c8b1104ad60ea91b42dcca"
integrity sha512-M6KR95Xz9af8kB8X7e4inhoIjVoKNT6WxjLQwPByAAdCP6JdCg3Fb0dbTh2WelKlAibUpfS9nANU/HUDcfedSA==
dependencies:
acorn "^7.1.1"
acorn-class-fields "^0.3.2"
acorn-export-ns-from "^0.1.0"
acorn-import-meta "^1.1.0"
acorn-numeric-separator "^0.3.0"
acorn-static-class-features "^0.2.1"
bindings "^1.4.0"
estree-walker "^0.6.1"
glob "^7.1.3"
graceful-fs "^4.1.15"
micromatch "^4.0.2"
mkdirp "^0.5.1"
node-gyp-build "^4.2.2"
node-pre-gyp "^0.13.0"
resolve-from "^5.0.0"
rollup-pluginutils "^2.8.2"
"@zeit/source-map-support@0.6.2":
version "0.6.2"
resolved "https://registry.yarnpkg.com/@zeit/source-map-support/-/source-map-support-0.6.2.tgz#0efd478f24a606726948165e53a8efe89e24036f"
@@ -2344,11 +2339,11 @@ abbrev@1:
integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==
acorn-class-fields@^0.3.2:
version "0.3.4"
resolved "https://registry.yarnpkg.com/acorn-class-fields/-/acorn-class-fields-0.3.4.tgz#4144289bdf9d8b2bb9d274b794dd72d7f8e4a815"
integrity sha512-yqUCIu0UJHFmCVhH3Cq29UR+3OJo1CtNWf1ncxTf3KfdEDt7aD0iVYmX7UN+RvIHyOsgukzplQhNkgePtASLUw==
version "0.3.7"
resolved "https://registry.yarnpkg.com/acorn-class-fields/-/acorn-class-fields-0.3.7.tgz#a35122f3cc6ad2bb33b1857e79215677fcfdd720"
integrity sha512-jdUWSFce0fuADUljmExz4TWpPkxmRW/ZCPRqeeUzbGf0vFUcpQYbyq52l75qGd0oSwwtAepeL6hgb/naRgvcKQ==
dependencies:
acorn-private-class-elements "^0.2.5"
acorn-private-class-elements "^0.2.7"
acorn-export-ns-from@^0.1.0:
version "0.1.0"
@@ -2374,21 +2369,21 @@ acorn-jsx@^5.2.0:
integrity sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==
acorn-numeric-separator@^0.3.0:
version "0.3.2"
resolved "https://registry.yarnpkg.com/acorn-numeric-separator/-/acorn-numeric-separator-0.3.2.tgz#5f849ae00d11e0bf1f8092e0eca7e0917436ae9f"
integrity sha512-ZNN1qnKvjWycDSQBfuD1TCiB81ItjjeGUPLHuqfP8X8HXwAodGTWsAaqSOQ1Nc9t+Wlb3tcEFdBrwUFUIzDiiA==
version "0.3.6"
resolved "https://registry.yarnpkg.com/acorn-numeric-separator/-/acorn-numeric-separator-0.3.6.tgz#af7f0abaf8e74bd9ca1117602954d0a3b75804f3"
integrity sha512-jUr5esgChu4k7VzesH/Nww3EysuyGJJcTEEiXqILUFKpO96PNyEXmK21M6nE0TSqGA1PeEg1MzgqJaoFsn9JMw==
acorn-private-class-elements@^0.2.3, acorn-private-class-elements@^0.2.5:
version "0.2.5"
resolved "https://registry.yarnpkg.com/acorn-private-class-elements/-/acorn-private-class-elements-0.2.5.tgz#5082582395d2dabbbb1ddf6397244fdaa61cded6"
integrity sha512-3eApRrJmPjaxWB3XidP8YMeVq9pcswPFE0KsSWVuhceCU68ZS8fkcf0fTXGhCmnNd7n48NWWV27EKMFPeCoJLg==
acorn-private-class-elements@^0.2.7:
version "0.2.7"
resolved "https://registry.yarnpkg.com/acorn-private-class-elements/-/acorn-private-class-elements-0.2.7.tgz#b14902c705bcff267adede1c9f61c1a317ef95d2"
integrity sha512-+GZH2wOKNZOBI4OOPmzpo4cs6mW297sn6fgIk1dUI08jGjhAaEwvC39mN2gJAg2lmAQJ1rBkFqKWonL3Zz6PVA==
acorn-static-class-features@^0.2.1:
version "0.2.2"
resolved "https://registry.yarnpkg.com/acorn-static-class-features/-/acorn-static-class-features-0.2.2.tgz#3f8e5b97e5b969d544cf4b2fe51c0d4c396d7a5b"
integrity sha512-B7aWeS7MXqdgP3RnettN/CFz7HevAlQWfh5zkc3LJzeCQoF1InTzYBCfkkbmit1p0pmCEB8IG05gB62pOm5lvA==
version "0.2.4"
resolved "https://registry.yarnpkg.com/acorn-static-class-features/-/acorn-static-class-features-0.2.4.tgz#a0f5261dd483f25196716854f2d7652a1deb39ee"
integrity sha512-5X4mpYq5J3pdndLmIB0+WtFd/mKWnNYpuTlTzj32wUu/PMmEGOiayQ5UrqgwdBNiaZBtDDh5kddpP7Yg2QaQYA==
dependencies:
acorn-private-class-elements "^0.2.3"
acorn-private-class-elements "^0.2.7"
acorn-walk@^6.0.1:
version "6.2.0"
@@ -4997,11 +4992,16 @@ etag@1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
eventemitter3@^3.0.0, eventemitter3@^3.1.0:
eventemitter3@^3.1.0:
version "3.1.2"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==
eventemitter3@^4.0.0:
version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
events-intercept@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/events-intercept/-/events-intercept-2.0.0.tgz#adbf38681c5a4b2011c41ee41f61a34cba448897"
@@ -6051,12 +6051,12 @@ http-proxy-agent@^4.0.0:
agent-base "6"
debug "4"
http-proxy@1.17.0:
version "1.17.0"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.17.0.tgz#7ad38494658f84605e2f6db4436df410f4e5be9a"
integrity sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==
http-proxy@1.18.1:
version "1.18.1"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
dependencies:
eventemitter3 "^3.0.0"
eventemitter3 "^4.0.0"
follow-redirects "^1.0.0"
requires-port "^1.0.0"
@@ -8285,9 +8285,9 @@ natural-compare@^1.4.0:
integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=
needle@^2.2.1:
version "2.5.0"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.0.tgz#e6fc4b3cc6c25caed7554bd613a5cf0bac8c31c0"
integrity sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==
version "2.5.2"
resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.2.tgz#cf1a8fce382b5a280108bba90a14993c00e4010a"
integrity sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ==
dependencies:
debug "^3.2.6"
iconv-lite "^0.4.4"
@@ -8339,9 +8339,9 @@ node-fetch@2.6.0, node-fetch@^2.2.0, node-fetch@^2.2.1, node-fetch@^2.3.0, node-
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
node-gyp-build@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.2.tgz#3f44b65adaafd42fb6c3d81afd630e45c847eb66"
integrity sha512-Lqh7mrByWCM8Cf9UPqpeoVBBo5Ugx+RKu885GAzmLBVYjeywScxHXPGLa4JfYNZmcNGwzR0Glu5/9GaQZMFqyA==
version "4.2.3"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739"
integrity sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==
node-gyp@^5.0.2:
version "5.1.1"
@@ -11092,6 +11092,11 @@ tree-kill@1.2.1:
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.1.tgz#5398f374e2f292b9dcc7b2e71e30a5c3bb6c743a"
integrity sha512-4hjqbObwlh2dLyW4tcz0Ymw0ggoaVDMveUB9w8kFSQScdRLo0gxO9J7WFcUBo+W3C1TLdFIEwNOWebgZZ0RH9Q==
tree-kill@1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc"
integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==
trim-newlines@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"