Compare commits

...

10 Commits

Author SHA1 Message Date
Nathan Rajlich
76f544cbea Publish Canary
- @vercel/build-utils@2.3.1-canary.0
 - vercel@19.0.1-canary.0
 - @vercel/client@8.0.1-canary.0
 - @vercel/go@1.1.1-canary.0
 - @vercel/next@2.6.1-canary.0
 - @vercel/node@1.6.1-canary.0
 - @vercel/python@1.2.1-canary.0
 - @vercel/ruby@1.2.1-canary.0
 - @vercel/static-build@0.17.1-canary.0
2020-05-09 13:54:05 -07:00
Nathan Rajlich
e246d2ed71 [client] Throw an error if both .vercelignore and .nowignore exist (#4311)
* [client] Throw an error if both `.vercelignore` and `.nowignore` exist

* Remove `.`

* Add tests

* Update test

* [cli] Properly clear spinner if `createDeployment()` async generator throws an error

* Update packages/now-client/src/utils/index.ts

Co-authored-by: Steven <steven@ceriously.com>

* Update packages/now-client/tests/vercelignore.test.ts

Co-authored-by: Steven <steven@ceriously.com>

Co-authored-by: Steven <steven@ceriously.com>
2020-05-09 03:02:16 -07:00
Steven
ed4c759c49 [all] Fix runtimes to work with old versions of CLI (#4317)
This PR fixes an issue where old versions of the CLI would update to the latest builder, but not have a copy of `@vercel/build-utils` because they only shipped with `@now/build-utils`. So in this case, we can fallback to the other package. We must be careful to only import types from `@vercel/build-utils` and anything needed at runtime must be imported from `./build-utils` wrapper.
2020-05-09 04:00:01 +00:00
Steven
2656647891 [cli] Fix error message to display correct config name (#4309)
This PR fixes an issue when the error message assumed the config was `vercel.json` even when the user had `now.json`.

### Before

```
Error! The property `foo` is not allowed in vercel.json – please remove it.
```

### After

```
 Error! The property `foo` is not allowed in now.json – please remove it.
```

Co-authored-by: Nathan Rajlich <n@n8.io>
2020-05-08 19:45:53 -04:00
Steven
3b3c468f3a [cli] Fix deploying v1 with secrets (#4315)
This PR fixes a regression from PR #4084 where secrets were paginated so some v1 deployments that had more than 20 secrets were unable to deploy since CLI version 19.
2020-05-08 23:08:05 +00:00
Nathan Rajlich
4214de2ce0 [built-utils] Make getPlatformEnv() throw if both NOW_ and VERCEL_ are defined (#4313)
Also adds unit tests.
2020-05-08 15:17:29 -07:00
Nathan Rajlich
40b7af4349 [cli] Fix now dev infinite loop for yarn workspaces (#4310)
A couple quick fixes to `now dev` to land on stable, before #4254 gets merged for canary.
2020-05-08 20:37:20 +00:00
Steven
f4d86cb9df [now-cli] Update now env add to skip value if system var (#4306)
This PR updates the CLI to work the same as the dashboard and skip the env var value if the name indicates that it is a [System Environment Variables](https://vercel.com/docs/v2/build-step#system-environment-variables).

Co-authored-by: Luc <luc.leray@gmail.com>
2020-05-08 11:41:41 -04:00
Nathan Rajlich
0492fcb0fc [now-cli] Fix update Changelog URL (#4302)
Incorrect URL: https://github.com/zeit/now/releases/tag/now@19.0.0

Correct URL: https://github.com/zeit/now/releases/tag/vercel@19.0.0
2020-05-08 01:47:36 +00:00
Nathan Rajlich
3a217dc750 [now-build-utils] Use @vercel runtimes for zero-config (#4300)
This reverts commit 8a9b67a3f3 (#4284),
now that `@vercel` runtimes work in production.
2020-05-08 00:02:30 +00:00
64 changed files with 690 additions and 445 deletions

View File

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

View File

@@ -391,11 +391,11 @@ function getApiMatches({ tag }: Options = {}) {
const config = { zeroConfig: true }; const config = { zeroConfig: true };
return [ return [
{ src: 'api/**/*.js', use: `@now/node${withTag}`, config }, { src: 'api/**/*.js', use: `@vercel/node${withTag}`, config },
{ src: 'api/**/*.ts', use: `@now/node${withTag}`, config }, { src: 'api/**/*.ts', use: `@vercel/node${withTag}`, config },
{ src: 'api/**/!(*_test).go', use: `@now/go${withTag}`, config }, { src: 'api/**/!(*_test).go', use: `@vercel/go${withTag}`, config },
{ src: 'api/**/*.py', use: `@now/python${withTag}`, config }, { src: 'api/**/*.py', use: `@vercel/python${withTag}`, config },
{ src: 'api/**/*.rb', use: `@now/ruby${withTag}`, config }, { src: 'api/**/*.rb', use: `@vercel/ruby${withTag}`, config },
]; ];
} }
@@ -457,7 +457,7 @@ function detectFrontBuilder(
} }
if (framework === 'nextjs') { if (framework === 'nextjs') {
return { src: 'package.json', use: `@now/next${withTag}`, config }; return { src: 'package.json', use: `@vercel/next${withTag}`, config };
} }
// Entrypoints for other frameworks // Entrypoints for other frameworks
@@ -480,7 +480,7 @@ function detectFrontBuilder(
return { return {
src: source || 'package.json', src: source || 'package.json',
use: `@now/static-build${withTag}`, use: `@vercel/static-build${withTag}`,
config, config,
}; };
} }

View File

@@ -102,7 +102,20 @@ export const isStaticRuntime = (name?: string): boolean => {
/** /**
* Helper function to support both `VERCEL_` and legacy `NOW_` env vars. * Helper function to support both `VERCEL_` and legacy `NOW_` env vars.
* Throws an error if *both* env vars are defined.
*/ */
export const getPlatformEnv = (name: string): string | undefined => { export const getPlatformEnv = (name: string): string | undefined => {
return process.env[`VERCEL_${name}`] || process.env[`NOW_${name}`]; const vName = `VERCEL_${name}`;
const nName = `NOW_${name}`;
const v = process.env[vName];
const n = process.env[nName];
if (typeof v === 'string') {
if (typeof n === 'string') {
throw new Error(
`Both "${vName}" and "${nName}" env vars are defined. Please only define the "${vName}" env var`
);
}
return v;
}
return n;
}; };

View File

@@ -119,7 +119,10 @@ it('Test `detectBuilders` and `detectRoutes`', async () => {
JSON.stringify(nowConfig, null, 2) JSON.stringify(nowConfig, null, 2)
); );
const deployment = await testDeployment({ builderUrl }, fixture); const deployment = await testDeployment(
{ builderUrl, buildUtilsUrl },
fixture
);
expect(deployment).toBeDefined(); expect(deployment).toBeDefined();
}); });
@@ -197,6 +200,9 @@ it('Test `detectBuilders` with `index` files', async () => {
JSON.stringify(nowConfig, null, 2) JSON.stringify(nowConfig, null, 2)
); );
const deployment = await testDeployment({ builderUrl }, fixture); const deployment = await testDeployment(
{ builderUrl, buildUtilsUrl },
fixture
);
expect(deployment).toBeDefined(); expect(deployment).toBeDefined();
}); });

View File

@@ -35,7 +35,7 @@ describe('Test `detectBuilders`', () => {
}; };
const files = ['package.json', 'pages/index.js']; const files = ['package.json', 'pages/index.js'];
const { builders, errors } = await detectBuilders(files, pkg); const { builders, errors } = await detectBuilders(files, pkg);
expect(builders![0].use).toBe('@now/next'); expect(builders![0].use).toBe('@vercel/next');
expect(errors).toBe(null); expect(errors).toBe(null);
}); });
@@ -46,7 +46,7 @@ describe('Test `detectBuilders`', () => {
}; };
const files = ['package.json', 'pages/index.js']; const files = ['package.json', 'pages/index.js'];
const { builders, errors } = await detectBuilders(files, pkg); const { builders, errors } = await detectBuilders(files, pkg);
expect(builders![0].use).toBe('@now/next'); expect(builders![0].use).toBe('@vercel/next');
expect(errors).toBe(null); expect(errors).toBe(null);
}); });
@@ -75,7 +75,7 @@ describe('Test `detectBuilders`', () => {
it('no package.json + no build + raw static + api', async () => { it('no package.json + no build + raw static + api', async () => {
const files = ['api/users.js', 'index.html']; const files = ['api/users.js', 'index.html'];
const { builders, errors } = await detectBuilders(files); const { builders, errors } = await detectBuilders(files);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/users.js'); expect(builders![0].src).toBe('api/users.js');
expect(builders![1].use).toBe('@now/static'); expect(builders![1].use).toBe('@now/static');
expect(builders![1].src).toBe('!{api/**,package.json}'); expect(builders![1].src).toBe('!{api/**,package.json}');
@@ -86,7 +86,7 @@ describe('Test `detectBuilders`', () => {
it('package.json + no build + root + api', async () => { it('package.json + no build + root + api', async () => {
const files = ['index.html', 'api/[endpoint].js', 'static/image.png']; const files = ['index.html', 'api/[endpoint].js', 'static/image.png'];
const { builders, errors } = await detectBuilders(files); const { builders, errors } = await detectBuilders(files);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/[endpoint].js'); expect(builders![0].src).toBe('api/[endpoint].js');
expect(builders![1].use).toBe('@now/static'); expect(builders![1].use).toBe('@now/static');
expect(builders![1].src).toBe('!{api/**,package.json}'); expect(builders![1].src).toBe('!{api/**,package.json}');
@@ -102,7 +102,7 @@ describe('Test `detectBuilders`', () => {
]; ];
const { builders } = await detectBuilders(files); const { builders } = await detectBuilders(files);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/[endpoint]/[id].js'); expect(builders![0].src).toBe('api/[endpoint]/[id].js');
expect(builders!.length).toBe(1); expect(builders!.length).toBe(1);
}); });
@@ -115,9 +115,9 @@ describe('Test `detectBuilders`', () => {
const files = ['package.json', 'api/endpoint.js', 'public/index.html']; const files = ['package.json', 'api/endpoint.js', 'public/index.html'];
const { builders } = await detectBuilders(files, pkg); const { builders } = await detectBuilders(files, pkg);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/endpoint.js'); expect(builders![0].src).toBe('api/endpoint.js');
expect(builders![1].use).toBe('@now/next'); expect(builders![1].use).toBe('@vercel/next');
expect(builders![1].src).toBe('package.json'); expect(builders![1].src).toBe('package.json');
expect(builders!.length).toBe(2); expect(builders!.length).toBe(2);
}); });
@@ -130,9 +130,9 @@ describe('Test `detectBuilders`', () => {
const files = ['package.json', 'api/endpoint.js', 'index.html']; const files = ['package.json', 'api/endpoint.js', 'index.html'];
const { builders } = await detectBuilders(files, pkg); const { builders } = await detectBuilders(files, pkg);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/endpoint.js'); expect(builders![0].src).toBe('api/endpoint.js');
expect(builders![1].use).toBe('@now/next'); expect(builders![1].use).toBe('@vercel/next');
expect(builders![1].src).toBe('package.json'); expect(builders![1].src).toBe('package.json');
expect(builders!.length).toBe(2); expect(builders!.length).toBe(2);
}); });
@@ -141,7 +141,7 @@ describe('Test `detectBuilders`', () => {
const files = ['api/endpoint.js', 'index.html', 'favicon.ico']; const files = ['api/endpoint.js', 'index.html', 'favicon.ico'];
const { builders } = await detectBuilders(files); const { builders } = await detectBuilders(files);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/endpoint.js'); expect(builders![0].src).toBe('api/endpoint.js');
expect(builders![1].use).toBe('@now/static'); expect(builders![1].use).toBe('@now/static');
expect(builders![1].src).toBe('!{api/**,package.json}'); expect(builders![1].src).toBe('!{api/**,package.json}');
@@ -157,7 +157,7 @@ describe('Test `detectBuilders`', () => {
]; ];
const { builders } = await detectBuilders(files); const { builders } = await detectBuilders(files);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/endpoint.js'); expect(builders![0].src).toBe('api/endpoint.js');
expect(builders![1].use).toBe('@now/static'); expect(builders![1].use).toBe('@now/static');
expect(builders![1].src).toBe('public/**/*'); expect(builders![1].src).toBe('public/**/*');
@@ -201,7 +201,7 @@ describe('Test `detectBuilders`', () => {
const files = ['package.json', 'public/index.html', 'README.md']; const files = ['package.json', 'public/index.html', 'README.md'];
const { builders } = await detectBuilders(files, pkg); const { builders } = await detectBuilders(files, pkg);
expect(builders![0].use).toBe('@now/next'); expect(builders![0].use).toBe('@vercel/next');
expect(builders![0].src).toBe('package.json'); expect(builders![0].src).toBe('package.json');
expect(builders!.length).toBe(1); expect(builders!.length).toBe(1);
}); });
@@ -214,7 +214,7 @@ describe('Test `detectBuilders`', () => {
const files = ['package.json', 'pages/index.js']; const files = ['package.json', 'pages/index.js'];
const { builders } = await detectBuilders(files, pkg); const { builders } = await detectBuilders(files, pkg);
expect(builders![0].use).toBe('@now/static-build'); expect(builders![0].use).toBe('@vercel/static-build');
expect(builders![0].src).toBe('package.json'); expect(builders![0].src).toBe('package.json');
expect(builders!.length).toBe(1); expect(builders!.length).toBe(1);
}); });
@@ -227,7 +227,7 @@ describe('Test `detectBuilders`', () => {
const files = ['package.json', 'pages/index.js']; const files = ['package.json', 'pages/index.js'];
const { builders } = await detectBuilders(files, pkg, { tag: 'canary' }); const { builders } = await detectBuilders(files, pkg, { tag: 'canary' });
expect(builders![0].use).toBe('@now/static-build@canary'); expect(builders![0].use).toBe('@vercel/static-build@canary');
expect(builders![0].src).toBe('package.json'); expect(builders![0].src).toBe('package.json');
expect(builders!.length).toBe(1); expect(builders!.length).toBe(1);
}); });
@@ -237,7 +237,7 @@ describe('Test `detectBuilders`', () => {
const files = ['package.json', 'api/[endpoint].js']; const files = ['package.json', 'api/[endpoint].js'];
const { builders } = await detectBuilders(files, pkg); const { builders } = await detectBuilders(files, pkg);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/[endpoint].js'); expect(builders![0].src).toBe('api/[endpoint].js');
expect(builders!.length).toBe(1); expect(builders!.length).toBe(1);
}); });
@@ -278,9 +278,9 @@ describe('Test `detectBuilders`', () => {
]; ];
const { builders } = await detectBuilders(files, pkg, { tag: 'canary' }); const { builders } = await detectBuilders(files, pkg, { tag: 'canary' });
expect(builders![0].use).toBe('@now/node@canary'); expect(builders![0].use).toBe('@vercel/node@canary');
expect(builders![1].use).toBe('@now/node@canary'); expect(builders![1].use).toBe('@vercel/node@canary');
expect(builders![2].use).toBe('@now/next@canary'); expect(builders![2].use).toBe('@vercel/next@canary');
expect(builders!.length).toBe(3); expect(builders!.length).toBe(3);
}); });
@@ -296,9 +296,9 @@ describe('Test `detectBuilders`', () => {
]; ];
const { builders } = await detectBuilders(files, pkg, { tag: 'latest' }); const { builders } = await detectBuilders(files, pkg, { tag: 'latest' });
expect(builders![0].use).toBe('@now/node@latest'); expect(builders![0].use).toBe('@vercel/node@latest');
expect(builders![1].use).toBe('@now/node@latest'); expect(builders![1].use).toBe('@vercel/node@latest');
expect(builders![2].use).toBe('@now/next@latest'); expect(builders![2].use).toBe('@vercel/next@latest');
expect(builders!.length).toBe(3); expect(builders!.length).toBe(3);
}); });
@@ -314,9 +314,9 @@ describe('Test `detectBuilders`', () => {
]; ];
const { builders } = await detectBuilders(files, pkg, { tag: 'haha' }); const { builders } = await detectBuilders(files, pkg, { tag: 'haha' });
expect(builders![0].use).toBe('@now/node@haha'); expect(builders![0].use).toBe('@vercel/node@haha');
expect(builders![1].use).toBe('@now/node@haha'); expect(builders![1].use).toBe('@vercel/node@haha');
expect(builders![2].use).toBe('@now/next@haha'); expect(builders![2].use).toBe('@vercel/next@haha');
expect(builders!.length).toBe(3); expect(builders!.length).toBe(3);
}); });
@@ -334,8 +334,8 @@ describe('Test `detectBuilders`', () => {
expect(warnings[0].code).toBe('conflicting_files'); expect(warnings[0].code).toBe('conflicting_files');
expect(builders).toBeDefined(); expect(builders).toBeDefined();
expect(builders!.length).toBe(2); expect(builders!.length).toBe(2);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![1].use).toBe('@now/next'); expect(builders![1].use).toBe('@vercel/next');
}); });
it('many static files + one api file', async () => { it('many static files + one api file', async () => {
@@ -344,7 +344,7 @@ describe('Test `detectBuilders`', () => {
const { builders } = await detectBuilders(files); const { builders } = await detectBuilders(files);
expect(builders!.length).toBe(2); expect(builders!.length).toBe(2);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/index.ts'); expect(builders![0].src).toBe('api/index.ts');
expect(builders![1].use).toBe('@now/static'); expect(builders![1].use).toBe('@now/static');
expect(builders![1].src).toBe('!{api/**,package.json}'); expect(builders![1].src).toBe('!{api/**,package.json}');
@@ -374,7 +374,7 @@ describe('Test `detectBuilders`', () => {
expect(builders!.length).toBe(1); expect(builders!.length).toBe(1);
expect(builders![0]).toEqual({ expect(builders![0]).toEqual({
src: 'package.json', src: 'package.json',
use: '@now/next', use: '@vercel/next',
config: { config: {
zeroConfig: true, zeroConfig: true,
functions: { functions: {
@@ -412,7 +412,7 @@ describe('Test `detectBuilders`', () => {
expect(builders!.length).toBe(3); expect(builders!.length).toBe(3);
expect(builders![0]).toEqual({ expect(builders![0]).toEqual({
src: 'api/teams/members.ts', src: 'api/teams/members.ts',
use: '@now/node', use: '@vercel/node',
config: { config: {
zeroConfig: true, zeroConfig: true,
functions: { functions: {
@@ -437,7 +437,7 @@ describe('Test `detectBuilders`', () => {
}); });
expect(builders![2]).toEqual({ expect(builders![2]).toEqual({
src: 'package.json', src: 'package.json',
use: '@now/next', use: '@vercel/next',
config: { config: {
zeroConfig: true, zeroConfig: true,
}, },
@@ -538,7 +538,7 @@ describe('Test `detectBuilders`', () => {
expect(errors![0].code).toBe('invalid_function'); expect(errors![0].code).toBe('invalid_function');
}); });
it('Do not allow functions that are not used by @now/next', async () => { it('Do not allow functions that are not used by @vercel/next', async () => {
const pkg = { const pkg = {
scripts: { build: 'next build' }, scripts: { build: 'next build' },
dependencies: { next: '9.0.0' }, dependencies: { next: '9.0.0' },
@@ -564,7 +564,7 @@ describe('Test `detectBuilders`', () => {
expect(errors).toBe(null); expect(errors).toBe(null);
expect(builders).not.toBe(null); expect(builders).not.toBe(null);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].config).toMatchObject({ expect(builders![0].config).toMatchObject({
functions, functions,
zeroConfig: true, zeroConfig: true,
@@ -584,7 +584,7 @@ describe('Test `detectBuilders`', () => {
expect(errors).toBe(null); expect(errors).toBe(null);
expect(builders).not.toBe(null); expect(builders).not.toBe(null);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].config).toMatchObject({ expect(builders![0].config).toMatchObject({
functions, functions,
zeroConfig: true, zeroConfig: true,
@@ -607,7 +607,7 @@ describe('Test `detectBuilders`', () => {
expect(errors).toBe(null); expect(errors).toBe(null);
expect(builders).not.toBe(null); expect(builders).not.toBe(null);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].config).toMatchObject({ expect(builders![0].config).toMatchObject({
functions, functions,
zeroConfig: true, zeroConfig: true,
@@ -705,7 +705,7 @@ describe('Test `detectBuilders`', () => {
expect(builders).toEqual([ expect(builders).toEqual([
{ {
use: '@now/static-build', use: '@vercel/static-build',
src: 'config.yaml', src: 'config.yaml',
config: { config: {
zeroConfig: true, zeroConfig: true,
@@ -727,7 +727,7 @@ describe('Test `detectBuilders`', () => {
expect(builders).toEqual([ expect(builders).toEqual([
{ {
use: '@now/static-build', use: '@vercel/static-build',
src: 'package.json', src: 'package.json',
config: { config: {
zeroConfig: true, zeroConfig: true,
@@ -744,14 +744,14 @@ describe('Test `detectBuilders`', () => {
expect(builders).toEqual([ expect(builders).toEqual([
{ {
use: '@now/ruby', use: '@vercel/ruby',
src: 'api/date.rb', src: 'api/date.rb',
config: { config: {
zeroConfig: true, zeroConfig: true,
}, },
}, },
{ {
use: '@now/static-build', use: '@vercel/static-build',
src: 'config.rb', src: 'config.rb',
config: { config: {
zeroConfig: true, zeroConfig: true,
@@ -765,7 +765,7 @@ describe('Test `detectBuilders`', () => {
const files = ['server/hello.ts', 'public/index.html']; const files = ['server/hello.ts', 'public/index.html'];
const functions = { const functions = {
'server/**/*.ts': { 'server/**/*.ts': {
runtime: '@now/node@1.3.1', runtime: '@vercel/node@1.3.1',
}, },
}; };
@@ -868,7 +868,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
redirectRoutes, redirectRoutes,
rewriteRoutes, rewriteRoutes,
} = await detectBuilders(files, pkg, { featHandleMiss }); } = await detectBuilders(files, pkg, { featHandleMiss });
expect(builders![0].use).toBe('@now/next'); expect(builders![0].use).toBe('@vercel/next');
expect(errors).toBe(null); expect(errors).toBe(null);
expect(defaultRoutes).toStrictEqual([]); expect(defaultRoutes).toStrictEqual([]);
expect(redirectRoutes).toStrictEqual([]); expect(redirectRoutes).toStrictEqual([]);
@@ -888,7 +888,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
redirectRoutes, redirectRoutes,
rewriteRoutes, rewriteRoutes,
} = await detectBuilders(files, pkg, { featHandleMiss }); } = await detectBuilders(files, pkg, { featHandleMiss });
expect(builders![0].use).toBe('@now/next'); expect(builders![0].use).toBe('@vercel/next');
expect(errors).toBe(null); expect(errors).toBe(null);
expect(defaultRoutes).toStrictEqual([]); expect(defaultRoutes).toStrictEqual([]);
expect(redirectRoutes).toStrictEqual([]); expect(redirectRoutes).toStrictEqual([]);
@@ -950,7 +950,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
redirectRoutes, redirectRoutes,
rewriteRoutes, rewriteRoutes,
} = await detectBuilders(files, null, { featHandleMiss }); } = await detectBuilders(files, null, { featHandleMiss });
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/users.js'); expect(builders![0].src).toBe('api/users.js');
expect(builders![1].use).toBe('@now/static'); expect(builders![1].use).toBe('@now/static');
expect(builders![1].src).toBe('!{api/**,package.json}'); expect(builders![1].src).toBe('!{api/**,package.json}');
@@ -970,7 +970,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
const { builders, errors } = await detectBuilders(files, null, { const { builders, errors } = await detectBuilders(files, null, {
featHandleMiss, featHandleMiss,
}); });
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/[endpoint].js'); expect(builders![0].src).toBe('api/[endpoint].js');
expect(builders![1].use).toBe('@now/static'); expect(builders![1].use).toBe('@now/static');
expect(builders![1].src).toBe('!{api/**,package.json}'); expect(builders![1].src).toBe('!{api/**,package.json}');
@@ -991,7 +991,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
redirectRoutes, redirectRoutes,
rewriteRoutes, rewriteRoutes,
} = await detectBuilders(files, undefined, { featHandleMiss }); } = await detectBuilders(files, undefined, { featHandleMiss });
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/[endpoint]/[id].js'); expect(builders![0].src).toBe('api/[endpoint]/[id].js');
expect(builders!.length).toBe(1); expect(builders!.length).toBe(1);
@@ -1017,9 +1017,9 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
redirectRoutes, redirectRoutes,
rewriteRoutes, rewriteRoutes,
} = await detectBuilders(files, pkg, { featHandleMiss }); } = await detectBuilders(files, pkg, { featHandleMiss });
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/endpoint.js'); expect(builders![0].src).toBe('api/endpoint.js');
expect(builders![1].use).toBe('@now/next'); expect(builders![1].use).toBe('@vercel/next');
expect(builders![1].src).toBe('package.json'); expect(builders![1].src).toBe('package.json');
expect(builders!.length).toBe(2); expect(builders!.length).toBe(2);
@@ -1044,9 +1044,9 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
redirectRoutes, redirectRoutes,
rewriteRoutes, rewriteRoutes,
} = await detectBuilders(files, pkg, { featHandleMiss }); } = await detectBuilders(files, pkg, { featHandleMiss });
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/endpoint.js'); expect(builders![0].src).toBe('api/endpoint.js');
expect(builders![1].use).toBe('@now/next'); expect(builders![1].use).toBe('@vercel/next');
expect(builders![1].src).toBe('package.json'); expect(builders![1].src).toBe('package.json');
expect(builders!.length).toBe(2); expect(builders!.length).toBe(2);
@@ -1067,7 +1067,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
redirectRoutes, redirectRoutes,
rewriteRoutes, rewriteRoutes,
} = await detectBuilders(files, null, { featHandleMiss }); } = await detectBuilders(files, null, { featHandleMiss });
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/endpoint.js'); expect(builders![0].src).toBe('api/endpoint.js');
expect(builders![1].use).toBe('@now/static'); expect(builders![1].use).toBe('@now/static');
expect(builders![1].src).toBe('!{api/**,package.json}'); expect(builders![1].src).toBe('!{api/**,package.json}');
@@ -1094,7 +1094,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
redirectRoutes, redirectRoutes,
rewriteRoutes, rewriteRoutes,
} = await detectBuilders(files, pkg, { featHandleMiss }); } = await detectBuilders(files, pkg, { featHandleMiss });
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/version.js'); expect(builders![0].src).toBe('api/version.js');
expect(builders![1].use).toBe('@now/static'); expect(builders![1].use).toBe('@now/static');
expect(builders![1].src).toBe('!{api/**,package.json}'); expect(builders![1].src).toBe('!{api/**,package.json}');
@@ -1119,7 +1119,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
const { builders } = await detectBuilders(files, undefined, { const { builders } = await detectBuilders(files, undefined, {
featHandleMiss, featHandleMiss,
}); });
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/endpoint.js'); expect(builders![0].src).toBe('api/endpoint.js');
expect(builders![1].use).toBe('@now/static'); expect(builders![1].use).toBe('@now/static');
expect(builders![1].src).toBe('public/**/*'); expect(builders![1].src).toBe('public/**/*');
@@ -1167,7 +1167,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
const files = ['package.json', 'public/index.html', 'README.md']; const files = ['package.json', 'public/index.html', 'README.md'];
const { builders } = await detectBuilders(files, pkg, { featHandleMiss }); const { builders } = await detectBuilders(files, pkg, { featHandleMiss });
expect(builders![0].use).toBe('@now/next'); expect(builders![0].use).toBe('@vercel/next');
expect(builders![0].src).toBe('package.json'); expect(builders![0].src).toBe('package.json');
expect(builders!.length).toBe(1); expect(builders!.length).toBe(1);
}); });
@@ -1180,7 +1180,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
const files = ['package.json', 'pages/index.js']; const files = ['package.json', 'pages/index.js'];
const { builders } = await detectBuilders(files, pkg, { featHandleMiss }); const { builders } = await detectBuilders(files, pkg, { featHandleMiss });
expect(builders![0].use).toBe('@now/static-build'); expect(builders![0].use).toBe('@vercel/static-build');
expect(builders![0].src).toBe('package.json'); expect(builders![0].src).toBe('package.json');
expect(builders!.length).toBe(1); expect(builders!.length).toBe(1);
}); });
@@ -1196,7 +1196,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
tag: 'canary', tag: 'canary',
featHandleMiss, featHandleMiss,
}); });
expect(builders![0].use).toBe('@now/static-build@canary'); expect(builders![0].use).toBe('@vercel/static-build@canary');
expect(builders![0].src).toBe('package.json'); expect(builders![0].src).toBe('package.json');
expect(builders!.length).toBe(1); expect(builders!.length).toBe(1);
}); });
@@ -1206,7 +1206,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
const files = ['package.json', 'api/[endpoint].js']; const files = ['package.json', 'api/[endpoint].js'];
const { builders } = await detectBuilders(files, pkg, { featHandleMiss }); const { builders } = await detectBuilders(files, pkg, { featHandleMiss });
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/[endpoint].js'); expect(builders![0].src).toBe('api/[endpoint].js');
expect(builders!.length).toBe(1); expect(builders!.length).toBe(1);
}); });
@@ -1256,9 +1256,9 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
tag: 'canary', tag: 'canary',
featHandleMiss, featHandleMiss,
}); });
expect(builders![0].use).toBe('@now/node@canary'); expect(builders![0].use).toBe('@vercel/node@canary');
expect(builders![1].use).toBe('@now/node@canary'); expect(builders![1].use).toBe('@vercel/node@canary');
expect(builders![2].use).toBe('@now/next@canary'); expect(builders![2].use).toBe('@vercel/next@canary');
expect(builders!.length).toBe(3); expect(builders!.length).toBe(3);
}); });
@@ -1277,9 +1277,9 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
tag: 'latest', tag: 'latest',
featHandleMiss, featHandleMiss,
}); });
expect(builders![0].use).toBe('@now/node@latest'); expect(builders![0].use).toBe('@vercel/node@latest');
expect(builders![1].use).toBe('@now/node@latest'); expect(builders![1].use).toBe('@vercel/node@latest');
expect(builders![2].use).toBe('@now/next@latest'); expect(builders![2].use).toBe('@vercel/next@latest');
expect(builders!.length).toBe(3); expect(builders!.length).toBe(3);
}); });
@@ -1298,9 +1298,9 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
tag: 'haha', tag: 'haha',
featHandleMiss, featHandleMiss,
}); });
expect(builders![0].use).toBe('@now/node@haha'); expect(builders![0].use).toBe('@vercel/node@haha');
expect(builders![1].use).toBe('@now/node@haha'); expect(builders![1].use).toBe('@vercel/node@haha');
expect(builders![2].use).toBe('@now/next@haha'); expect(builders![2].use).toBe('@vercel/next@haha');
expect(builders!.length).toBe(3); expect(builders!.length).toBe(3);
}); });
@@ -1320,8 +1320,8 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(warnings[0].code).toBe('conflicting_files'); expect(warnings[0].code).toBe('conflicting_files');
expect(builders).toBeDefined(); expect(builders).toBeDefined();
expect(builders!.length).toBe(2); expect(builders!.length).toBe(2);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![1].use).toBe('@now/next'); expect(builders![1].use).toBe('@vercel/next');
}); });
it('many static files + one api file', async () => { it('many static files + one api file', async () => {
@@ -1332,7 +1332,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
}); });
expect(builders!.length).toBe(2); expect(builders!.length).toBe(2);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].src).toBe('api/index.ts'); expect(builders![0].src).toBe('api/index.ts');
expect(builders![1].use).toBe('@now/static'); expect(builders![1].use).toBe('@now/static');
expect(builders![1].src).toBe('!{api/**,package.json}'); expect(builders![1].src).toBe('!{api/**,package.json}');
@@ -1363,7 +1363,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(builders!.length).toBe(1); expect(builders!.length).toBe(1);
expect(builders![0]).toEqual({ expect(builders![0]).toEqual({
src: 'package.json', src: 'package.json',
use: '@now/next', use: '@vercel/next',
config: { config: {
zeroConfig: true, zeroConfig: true,
functions: { functions: {
@@ -1404,7 +1404,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(builders!.length).toBe(3); expect(builders!.length).toBe(3);
expect(builders![0]).toEqual({ expect(builders![0]).toEqual({
src: 'api/teams/members.ts', src: 'api/teams/members.ts',
use: '@now/node', use: '@vercel/node',
config: { config: {
zeroConfig: true, zeroConfig: true,
functions: { functions: {
@@ -1429,7 +1429,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
}); });
expect(builders![2]).toEqual({ expect(builders![2]).toEqual({
src: 'package.json', src: 'package.json',
use: '@now/next', use: '@vercel/next',
config: { config: {
zeroConfig: true, zeroConfig: true,
}, },
@@ -1538,7 +1538,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(errors![0].code).toBe('invalid_function'); expect(errors![0].code).toBe('invalid_function');
}); });
it('Do not allow functions that are not used by @now/next', async () => { it('Do not allow functions that are not used by @vercel/next', async () => {
const pkg = { const pkg = {
scripts: { build: 'next build' }, scripts: { build: 'next build' },
dependencies: { next: '9.0.0' }, dependencies: { next: '9.0.0' },
@@ -1568,7 +1568,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(errors).toBe(null); expect(errors).toBe(null);
expect(builders).not.toBe(null); expect(builders).not.toBe(null);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].config).toMatchObject({ expect(builders![0].config).toMatchObject({
functions, functions,
zeroConfig: true, zeroConfig: true,
@@ -1589,7 +1589,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(errors).toBe(null); expect(errors).toBe(null);
expect(builders).not.toBe(null); expect(builders).not.toBe(null);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].config).toMatchObject({ expect(builders![0].config).toMatchObject({
functions, functions,
zeroConfig: true, zeroConfig: true,
@@ -1613,7 +1613,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(errors).toBe(null); expect(errors).toBe(null);
expect(builders).not.toBe(null); expect(builders).not.toBe(null);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![0].config).toMatchObject({ expect(builders![0].config).toMatchObject({
functions, functions,
zeroConfig: true, zeroConfig: true,
@@ -1737,7 +1737,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(builders).toEqual([ expect(builders).toEqual([
{ {
use: '@now/static-build', use: '@vercel/static-build',
src: 'config.yaml', src: 'config.yaml',
config: { config: {
zeroConfig: true, zeroConfig: true,
@@ -1759,7 +1759,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(builders).toEqual([ expect(builders).toEqual([
{ {
use: '@now/static-build', use: '@vercel/static-build',
src: 'package.json', src: 'package.json',
config: { config: {
zeroConfig: true, zeroConfig: true,
@@ -1779,14 +1779,14 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
expect(builders).toEqual([ expect(builders).toEqual([
{ {
use: '@now/ruby', use: '@vercel/ruby',
src: 'api/date.rb', src: 'api/date.rb',
config: { config: {
zeroConfig: true, zeroConfig: true,
}, },
}, },
{ {
use: '@now/static-build', use: '@vercel/static-build',
src: 'config.rb', src: 'config.rb',
config: { config: {
zeroConfig: true, zeroConfig: true,
@@ -1800,7 +1800,7 @@ describe('Test `detectBuilders` with `featHandleMiss=true`', () => {
const files = ['server/hello.ts', 'public/index.html']; const files = ['server/hello.ts', 'public/index.html'];
const functions = { const functions = {
'server/**/*.ts': { 'server/**/*.ts': {
runtime: '@now/node@1.3.1', runtime: '@vercel/node@1.3.1',
}, },
}; };
@@ -2000,10 +2000,10 @@ it('Test `detectRoutes`', async () => {
const { builders, defaultRoutes } = await detectBuilders(files); const { builders, defaultRoutes } = await detectBuilders(files);
expect(builders!.length).toBe(4); expect(builders!.length).toBe(4);
expect(builders![0].use).toBe('@now/node'); expect(builders![0].use).toBe('@vercel/node');
expect(builders![1].use).toBe('@now/node'); expect(builders![1].use).toBe('@vercel/node');
expect(builders![2].use).toBe('@now/node'); expect(builders![2].use).toBe('@vercel/node');
expect(builders![3].use).toBe('@now/node'); expect(builders![3].use).toBe('@vercel/node');
expect(defaultRoutes!.length).toBe(5); expect(defaultRoutes!.length).toBe(5);
} }
@@ -2883,7 +2883,7 @@ describe('Test `detectOutputDirectory`', () => {
config: { zeroConfig: true }, config: { zeroConfig: true },
}, },
{ {
use: '@now/node', use: '@vercel/node',
src: 'api/index.js', src: 'api/index.js',
}, },
]; ];
@@ -2896,7 +2896,7 @@ describe('Test `detectApiDirectory`', () => {
it('should be `null` with no config', async () => { it('should be `null` with no config', async () => {
const builders = [ const builders = [
{ {
use: '@now/node', use: '@vercel/node',
src: 'api/**/*.js', src: 'api/**/*.js',
}, },
]; ];
@@ -2907,7 +2907,7 @@ describe('Test `detectApiDirectory`', () => {
it('should be `null` with no zero config builds', async () => { it('should be `null` with no zero config builds', async () => {
const builders = [ const builders = [
{ {
use: '@now/node', use: '@vercel/node',
src: 'api/**/*.js', src: 'api/**/*.js',
config: {}, config: {},
}, },
@@ -2919,7 +2919,7 @@ describe('Test `detectApiDirectory`', () => {
it('should be `api` with one zero config', async () => { it('should be `api` with one zero config', async () => {
const builders = [ const builders = [
{ {
use: '@now/node', use: '@vercel/node',
src: 'api/**/*.js', src: 'api/**/*.js',
config: { zeroConfig: true }, config: { zeroConfig: true },
}, },
@@ -2931,12 +2931,12 @@ describe('Test `detectApiDirectory`', () => {
it('should be `api` with one zero config and one without config', async () => { it('should be `api` with one zero config and one without config', async () => {
const builders = [ const builders = [
{ {
use: '@now/node', use: '@vercel/node',
src: 'api/**/*.js', src: 'api/**/*.js',
config: { zeroConfig: true }, config: { zeroConfig: true },
}, },
{ {
use: '@now/php', use: '@vercel/php',
src: 'api/**/*.php', src: 'api/**/*.php',
}, },
]; ];
@@ -2947,7 +2947,7 @@ describe('Test `detectApiDirectory`', () => {
it('should be `null` with zero config but without api directory', async () => { it('should be `null` with zero config but without api directory', async () => {
const builders = [ const builders = [
{ {
use: '@now/next', use: '@vercel/next',
src: 'package.json', src: 'package.json',
config: { zeroConfig: true }, config: { zeroConfig: true },
}, },
@@ -2961,28 +2961,28 @@ describe('Test `detectApiExtensions`', () => {
it('should have correct extensions', async () => { it('should have correct extensions', async () => {
const builders = [ const builders = [
{ {
use: '@now/node', use: '@vercel/node',
src: 'api/**/*.js', src: 'api/**/*.js',
config: { config: {
zeroConfig: true, zeroConfig: true,
}, },
}, },
{ {
use: '@now/python', use: '@vercel/python',
src: 'api/**/*.py', src: 'api/**/*.py',
config: { config: {
zeroConfig: true, zeroConfig: true,
}, },
}, },
{ {
use: '@now/go', use: '@vercel/go',
src: 'api/**/*.go', src: 'api/**/*.go',
config: { config: {
zeroConfig: true, zeroConfig: true,
}, },
}, },
{ {
use: '@now/ruby', use: '@vercel/ruby',
src: 'api/**/*.rb', src: 'api/**/*.rb',
config: { config: {
zeroConfig: true, zeroConfig: true,
@@ -3002,7 +3002,7 @@ describe('Test `detectApiExtensions`', () => {
}, },
}, },
{ {
use: '@now/next', use: '@vercel/next',
src: 'package.json', src: 'package.json',
// No api directory should not be added // No api directory should not be added
config: { config: {

View File

@@ -0,0 +1,45 @@
import assert from 'assert';
import { getPlatformEnv } from '../src';
describe('Test `getPlatformEnv()`', () => {
it('should support `VERCEL_` prefix', () => {
try {
assert.equal(undefined, getPlatformEnv('FOO'));
process.env.VERCEL_FOO = 'bar';
assert.equal('bar', getPlatformEnv('FOO'));
} finally {
delete process.env.VERCEL_FOO;
}
});
it('should support `NOW_` prefix', () => {
try {
assert.equal(undefined, getPlatformEnv('FOO'));
process.env.NOW_FOO = 'bar';
assert.equal('bar', getPlatformEnv('FOO'));
} finally {
delete process.env.NOW_FOO;
}
});
it('should throw an error if both env vars exist', () => {
let err: Error | null = null;
try {
process.env.NOW_FOO = 'bar';
process.env.VERCEL_FOO = 'baz';
getPlatformEnv('FOO');
} catch (_err) {
err = _err;
} finally {
delete process.env.NOW_FOO;
delete process.env.VERCEL_FOO;
}
assert(err);
assert.equal(
err!.message,
'Both "VERCEL_FOO" and "NOW_FOO" env vars are defined. Please only define the "VERCEL_FOO" env var'
);
});
});

View File

@@ -1,6 +1,6 @@
{ {
"name": "vercel", "name": "vercel",
"version": "19.0.0", "version": "19.0.1-canary.0",
"preferGlobal": true, "preferGlobal": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "The command-line interface for Now", "description": "The command-line interface for Now",

View File

@@ -1,5 +1,6 @@
import fs from 'fs-extra'; import fs from 'fs-extra';
import { resolve, basename, parse, join } from 'path'; import { resolve, basename, parse, join } from 'path';
import { fileNameSymbol } from '@vercel/client';
import Client from '../../util/client.ts'; import Client from '../../util/client.ts';
import getScope from '../../util/get-scope.ts'; import getScope from '../../util/get-scope.ts';
import createOutput from '../../util/output'; import createOutput from '../../util/output';
@@ -112,11 +113,10 @@ export default async ctx => {
} }
} }
const file = highlight('vercel.json');
const prop = code('version');
if (localConfig) { if (localConfig) {
const { version } = localConfig; const { version } = localConfig;
const file = highlight(localConfig[fileNameSymbol]);
const prop = code('version');
if (version) { if (version) {
if (typeof version === 'number') { if (typeof version === 'number') {

View File

@@ -4,6 +4,7 @@ import { join } from 'path';
import { write as copy } from 'clipboardy'; import { write as copy } from 'clipboardy';
import chalk from 'chalk'; import chalk from 'chalk';
import title from 'title'; import title from 'title';
import { fileNameSymbol } from '@vercel/client';
import Client from '../../util/client'; import Client from '../../util/client';
import { handleError } from '../../util/error'; import { handleError } from '../../util/error';
import getArgs from '../../util/get-args'; import getArgs from '../../util/get-args';
@@ -373,7 +374,7 @@ export default async function main(
output.print( output.print(
`${prependEmoji( `${prependEmoji(
`The ${highlight( `The ${highlight(
'vercel.json' localConfig[fileNameSymbol]
)} file should be inside of the provided root directory.`, )} file should be inside of the provided root directory.`,
emoji('warning') emoji('warning')
)}\n` )}\n`
@@ -387,7 +388,7 @@ export default async function main(
output.print( output.print(
`${prependEmoji( `${prependEmoji(
`The ${code('name')} property in ${highlight( `The ${code('name')} property in ${highlight(
'vercel.json' localConfig[fileNameSymbol]
)} is deprecated (https://zeit.ink/5F)`, )} is deprecated (https://zeit.ink/5F)`,
emoji('warning') emoji('warning')
)}\n` )}\n`
@@ -404,7 +405,7 @@ export default async function main(
if (typeof localConfig.env !== 'undefined' && !isObject(localConfig.env)) { if (typeof localConfig.env !== 'undefined' && !isObject(localConfig.env)) {
error( error(
`The ${code('env')} property in ${highlight( `The ${code('env')} property in ${highlight(
'vercel.json' localConfig[fileNameSymbol]
)} needs to be an object` )} needs to be an object`
); );
return 1; return 1;
@@ -414,7 +415,7 @@ export default async function main(
if (!isObject(localConfig.build)) { if (!isObject(localConfig.build)) {
error( error(
`The ${code('build')} property in ${highlight( `The ${code('build')} property in ${highlight(
'vercel.json' localConfig[fileNameSymbol]
)} needs to be an object` )} needs to be an object`
); );
return 1; return 1;
@@ -426,7 +427,7 @@ export default async function main(
) { ) {
error( error(
`The ${code('build.env')} property in ${highlight( `The ${code('build.env')} property in ${highlight(
'vercel.json' localConfig[fileNameSymbol]
)} needs to be an object` )} needs to be an object`
); );
return 1; return 1;
@@ -637,11 +638,11 @@ export default async function main(
} }
if (purchase === false || purchase instanceof UserAborted) { if (purchase === false || purchase instanceof UserAborted) {
handleCreateDeployError(output, deployment); handleCreateDeployError(output, deployment, localConfig);
return 1; return 1;
} }
handleCreateDeployError(output, purchase); handleCreateDeployError(output, purchase, localConfig);
return 1; return 1;
} }
@@ -661,7 +662,7 @@ export default async function main(
err instanceof ConflictingFilePath || err instanceof ConflictingFilePath ||
err instanceof ConflictingPathSegment err instanceof ConflictingPathSegment
) { ) {
handleCreateDeployError(output, err); handleCreateDeployError(output, err, localConfig);
return 1; return 1;
} }
@@ -707,7 +708,7 @@ export default async function main(
); );
} }
function handleCreateDeployError(output, error) { function handleCreateDeployError(output, error, localConfig) {
if (error instanceof InvalidDomain) { if (error instanceof InvalidDomain) {
output.error(`The domain ${error.meta.domain} is not valid`); output.error(`The domain ${error.meta.domain} is not valid`);
return 1; return 1;
@@ -736,7 +737,7 @@ function handleCreateDeployError(output, error) {
output.error( output.error(
`The property ${code(prop)} is not allowed in ${highlight( `The property ${code(prop)} is not allowed in ${highlight(
'vercel.json' localConfig[fileNameSymbol]
)} please remove it.` )} please remove it.`
); );
@@ -761,7 +762,7 @@ function handleCreateDeployError(output, error) {
output.error( output.error(
`The property ${code(prop)} in ${highlight( `The property ${code(prop)} in ${highlight(
'vercel.json' localConfig[fileNameSymbol]
)} can only be of type ${code(title(params.type))}.` )} can only be of type ${code(title(params.type))}.`
); );
@@ -772,7 +773,7 @@ function handleCreateDeployError(output, error) {
output.error( output.error(
`Failed to validate ${highlight( `Failed to validate ${highlight(
'vercel.json' localConfig[fileNameSymbol]
)}: ${message}\nDocumentation: ${link}` )}: ${message}\nDocumentation: ${link}`
); );

View File

@@ -25,6 +25,8 @@ import link from '../../util/output/link';
import exit from '../../util/exit'; import exit from '../../util/exit';
// @ts-ignore // @ts-ignore
import Now from '../../util'; import Now from '../../util';
// @ts-ignore
import NowSecrets from '../../util/secrets';
import uniq from '../../util/unique-strings'; import uniq from '../../util/unique-strings';
import promptBool from '../../util/input/prompt-bool'; import promptBool from '../../util/input/prompt-bool';
// @ts-ignore // @ts-ignore
@@ -633,20 +635,7 @@ async function sync({
nowConfig.build.env = deploymentBuildEnv; nowConfig.build.env = deploymentBuildEnv;
} }
const hasSecrets = Object.keys(deploymentEnv).some(key => const nowSecrets = new NowSecrets({ apiUrl, token, debug, currentTeam });
(deploymentEnv[key] || '').startsWith('@')
);
const secretsPromise = hasSecrets ? now.listSecrets() : null;
const findSecret = async (uidOrName: string) => {
const secrets = await Promise.resolve(secretsPromise);
return secrets.filter(
(secret: { name: string; uid: string }) =>
secret.name === uidOrName || secret.uid === uidOrName
);
};
const env_ = await Promise.all( const env_ = await Promise.all(
Object.keys(deploymentEnv).map(async (key: string) => { Object.keys(deploymentEnv).map(async (key: string) => {
@@ -673,36 +662,17 @@ async function sync({
if (val[0] === '@') { if (val[0] === '@') {
const uidOrName = val.substr(1); const uidOrName = val.substr(1);
const _secrets = await findSecret(uidOrName); const secret = await nowSecrets.getSecretByNameOrId(uidOrName);
if (_secrets.length === 0) { if (!secret) {
if (uidOrName === '') {
error( error(
`Empty reference provided for env key ${chalk.bold( `No secret found by uid or name ${chalk.bold(`"${uidOrName}"`)}`,
`"${chalk.bold(key)}"`
)}`
);
} else {
error(
`No secret found by uid or name ${chalk.bold(
`"${uidOrName}"`
)}`,
'env-no-secret' 'env-no-secret'
); );
}
await exit(1);
} else if (_secrets.length > 1) {
error(
`Ambiguous secret ${chalk.bold(
`"${uidOrName}"`
)} (matches ${chalk.bold(_secrets.length)} secrets)`
);
await exit(1); await exit(1);
} }
val = { uid: _secrets[0].uid }; val = { uid: secret.uid };
} }
return [key, typeof val === 'string' ? val.replace(/^\\@/, '@') : val]; return [key, typeof val === 'string' ? val.replace(/^\\@/, '@') : val];

View File

@@ -98,6 +98,8 @@ export default async function add(
if (stdInput) { if (stdInput) {
envValue = stdInput; envValue = stdInput;
} else if (isSystemEnvVariable(envName)) {
envValue = '';
} else { } else {
const { inputValue } = await inquirer.prompt({ const { inputValue } = await inquirer.prompt({
type: 'password', type: 'password',
@@ -146,3 +148,7 @@ export default async function add(
return 0; return 0;
} }
function isSystemEnvVariable(envName: string) {
return envName.startsWith('VERCEL_');
}

View File

@@ -157,7 +157,7 @@ const main = async argv_ => {
console.log( console.log(
info( info(
`Changelog: https://github.com/zeit/now/releases/tag/now@${update.latest}` `Changelog: https://github.com/zeit/now/releases/tag/vercel@${update.latest}`
) )
); );
} }

View File

@@ -2,8 +2,6 @@ import { NowConfig } from './util/dev/types';
export type ThenArg<T> = T extends Promise<infer U> ? U : T; export type ThenArg<T> = T extends Promise<infer U> ? U : T;
export type Config = NowConfig;
export interface NowContext { export interface NowContext {
argv: string[]; argv: string[];
apiUrl: string; apiUrl: string;
@@ -14,7 +12,7 @@ export interface NowContext {
currentTeam: string; currentTeam: string;
updateChannel: string; updateChannel: string;
}; };
localConfig: Config; localConfig: NowConfig;
} }
type Billing = { type Billing = {

View File

@@ -2,7 +2,8 @@ import path from 'path';
import chalk from 'chalk'; import chalk from 'chalk';
import Client from '../client'; import Client from '../client';
import { Output } from '../output'; import { Output } from '../output';
import { User, Config } from '../../types'; import { User } from '../../types';
import { NowConfig } from '../dev/types';
import getDeploymentsByAppName from '../deploy/get-deployments-by-appname'; import getDeploymentsByAppName from '../deploy/get-deployments-by-appname';
import getDeploymentByIdOrHost from '../deploy/get-deployment-by-id-or-host'; import getDeploymentByIdOrHost from '../deploy/get-deployment-by-id-or-host';
@@ -34,7 +35,7 @@ export async function getDeploymentForAlias(
localConfigPath: string | undefined, localConfigPath: string | undefined,
user: User, user: User,
contextName: string, contextName: string,
localConfig: Config localConfig: NowConfig
) { ) {
const cancelWait = output.spinner( const cancelWait = output.spinner(
`Fetching deployment to alias in ${chalk.bold(contextName)}` `Fetching deployment to alias in ${chalk.bold(contextName)}`

View File

@@ -5,7 +5,8 @@ import getAppName from '../deploy/get-app-name';
import fetchDeploymentByIdOrHost from '../deploy/get-deployment-by-id-or-host'; import fetchDeploymentByIdOrHost from '../deploy/get-deployment-by-id-or-host';
import Client from '../client'; import Client from '../client';
import { Output } from '../output'; import { Output } from '../output';
import { User, Config } from '../../types'; import { User } from '../../types';
import { NowConfig } from '../dev/types';
export default async function getDeploymentForAlias( export default async function getDeploymentForAlias(
client: Client, client: Client,
@@ -14,7 +15,7 @@ export default async function getDeploymentForAlias(
localConfigPath: string | undefined, localConfigPath: string | undefined,
user: User, user: User,
contextName: string, contextName: string,
localConfig: Config localConfig: NowConfig
) { ) {
const cancelWait = output.spinner( const cancelWait = output.spinner(
`Fetching deployment to alias in ${chalk.bold(contextName)}` `Fetching deployment to alias in ${chalk.bold(contextName)}`

View File

@@ -1,8 +1,8 @@
import toHost from '../to-host'; import toHost from '../to-host';
import { Config } from '../../types'; import { NowConfig } from '../dev/types';
import * as ERRORS from '../errors-ts'; import * as ERRORS from '../errors-ts';
export function getTargetsForAlias(args: string[], { alias }: Config) { export function getTargetsForAlias(args: string[], { alias }: NowConfig) {
if (args.length) { if (args.length) {
return targetsToHosts([args[args.length - 1]]); return targetsToHosts([args[args.length - 1]]);
} }

View File

@@ -1,16 +1,18 @@
import { join as joinPath } from 'path'; import { join, basename } from 'path';
import loadJSON from 'load-json-file'; import loadJSON from 'load-json-file';
import writeJSON from 'write-json-file'; import writeJSON from 'write-json-file';
import { existsSync } from 'fs'; import { existsSync } from 'fs';
import { fileNameSymbol } from '@vercel/client';
import getGlobalPathConfig from './global-path'; import getGlobalPathConfig from './global-path';
import getLocalPathConfig from './local-path'; import getLocalPathConfig from './local-path';
import { NowError } from '../now-error'; import { NowError } from '../now-error';
import error from '../output/error'; import error from '../output/error';
import highlight from '../output/highlight'; import highlight from '../output/highlight';
import { NowConfig } from '../dev/types';
const VERCEL_DIR = getGlobalPathConfig(); const VERCEL_DIR = getGlobalPathConfig();
const CONFIG_FILE_PATH = joinPath(VERCEL_DIR, 'config.json'); const CONFIG_FILE_PATH = join(VERCEL_DIR, 'config.json');
const AUTH_CONFIG_FILE_PATH = joinPath(VERCEL_DIR, 'auth.json'); const AUTH_CONFIG_FILE_PATH = join(VERCEL_DIR, 'auth.json');
// reads `CONFIG_FILE_PATH` atomically // reads `CONFIG_FILE_PATH` atomically
export const readConfigFile = () => loadJSON.sync(CONFIG_FILE_PATH); export const readConfigFile = () => loadJSON.sync(CONFIG_FILE_PATH);
@@ -87,7 +89,10 @@ export function getAuthConfigFilePath() {
return AUTH_CONFIG_FILE_PATH; return AUTH_CONFIG_FILE_PATH;
} }
export function readLocalConfig(prefix: string = process.cwd()) { export function readLocalConfig(
prefix: string = process.cwd()
): NowConfig | null {
let config: NowConfig | null = null;
let target = ''; let target = '';
try { try {
@@ -105,29 +110,24 @@ export function readLocalConfig(prefix: string = process.cwd()) {
return null; return null;
} }
let localConfigExists;
try { try {
localConfigExists = existsSync(target); if (existsSync(target)) {
} catch (err) { config = loadJSON.sync(target);
console.error(error(`Config file does not exist: ${target}`));
process.exit(1);
} }
if (localConfigExists) {
try {
return loadJSON.sync(target);
} catch (err) { } catch (err) {
if (err.name === 'JSONError') { if (err.name === 'JSONError') {
console.log(error(err.message)); console.error(error(err.message));
} else { } else {
const code = err.code ? ` (${err.code})` : ''; const code = err.code ? ` (${err.code})` : '';
console.error(error(`Failed to read config file: ${target} (${code})`)); console.error(error(`Failed to read config file: ${target}${code}`));
} }
process.exit(1); process.exit(1);
} }
}
if (!config) {
return null; return null;
} }
config[fileNameSymbol] = basename(target);
return config;
}

View File

@@ -1,7 +1,7 @@
import { join } from 'path'; import { join } from 'path';
import { CantParseJSONFile } from '../errors-ts'; import { CantParseJSONFile } from '../errors-ts';
import readJSONFile from '../read-json-file'; import readJSONFile from '../read-json-file';
import { Config } from '../../types'; import { NowConfig } from '../dev/types';
import getLocalConfigPath from './local-path'; import getLocalConfigPath from './local-path';
export default async function readConfig(dir: string) { export default async function readConfig(dir: string) {
@@ -13,7 +13,7 @@ export default async function readConfig(dir: string) {
} }
if (result) { if (result) {
return result as Config; return result as NowConfig;
} }
return null; return null;

View File

@@ -1,12 +1,12 @@
import path from 'path'; import path from 'path';
import { NowError } from '../now-error'; import { NowError } from '../now-error';
import { Output } from '../output'; import { Output } from '../output';
import { Config } from '../../types'; import { NowConfig } from '../dev/types';
import readPackage from '../read-package'; import readPackage from '../read-package';
export default async function getAppName( export default async function getAppName(
output: Output, output: Output,
config: Config, config: NowConfig,
localConfigPath?: string localConfigPath?: string
) { ) {
// If the name is in the configuration, return it // If the name is in the configuration, return it

View File

@@ -109,7 +109,7 @@ export default async function processDeployment({
let buildSpinner = null; let buildSpinner = null;
let deploySpinner = null; let deploySpinner = null;
let deployingSpinner = output.spinner( const deployingSpinner = output.spinner(
isSettingUpProject isSettingUpProject
? 'Setting up project' ? 'Setting up project'
: `Deploying ${chalk.bold(`${org.slug}/${projectName}`)}`, : `Deploying ${chalk.bold(`${org.slug}/${projectName}`)}`,
@@ -120,6 +120,7 @@ export default async function processDeployment({
// the deployment is done // the deployment is done
const indications = []; const indications = [];
try {
for await (const event of createDeployment( for await (const event of createDeployment(
nowClientOptions, nowClientOptions,
requestBody, requestBody,
@@ -151,9 +152,7 @@ export default async function processDeployment({
if (deploySpinner) { if (deploySpinner) {
deploySpinner(); deploySpinner();
} }
if (deployingSpinner) {
deployingSpinner(); deployingSpinner();
}
bar = new Progress(`${chalk.gray('>')} Upload [:bar] :percent :etas`, { bar = new Progress(`${chalk.gray('>')} Upload [:bar] :percent :etas`, {
width: 20, width: 20,
complete: '=', complete: '=',
@@ -176,9 +175,7 @@ export default async function processDeployment({
} }
if (event.type === 'created') { if (event.type === 'created') {
if (deployingSpinner) {
deployingSpinner(); deployingSpinner();
}
now._host = event.payload.url; now._host = event.payload.url;
@@ -251,9 +248,7 @@ export default async function processDeployment({
if (deploySpinner) { if (deploySpinner) {
deploySpinner(); deploySpinner();
} }
if (deployingSpinner) {
deployingSpinner(); deployingSpinner();
}
const error = await now.handleDeploymentError(event.payload, { const error = await now.handleDeploymentError(event.payload, {
hashes, hashes,
@@ -278,12 +273,23 @@ export default async function processDeployment({
if (deploySpinner) { if (deploySpinner) {
deploySpinner(); deploySpinner();
} }
if (deployingSpinner) {
deployingSpinner(); deployingSpinner();
}
event.payload.indications = indications; event.payload.indications = indications;
return event.payload; return event.payload;
} }
} }
} catch (err) {
if (queuedSpinner) {
queuedSpinner();
}
if (buildSpinner) {
buildSpinner();
}
if (deploySpinner) {
deploySpinner();
}
deployingSpinner();
throw err;
}
} }

View File

@@ -268,6 +268,7 @@ export async function installBuilders(
'--exact', '--exact',
'--no-lockfile', '--no-lockfile',
'--non-interactive', '--non-interactive',
'--ignore-workspace-root-check',
...packagesToInstall, ...packagesToInstall,
], ],
{ {
@@ -322,6 +323,7 @@ export async function updateBuilders(
'--exact', '--exact',
'--no-lockfile', '--no-lockfile',
'--non-interactive', '--non-interactive',
'--ignore-workspace-root-check',
...packages.filter(p => !isStaticRuntime(p)), ...packages.filter(p => !isStaticRuntime(p)),
], ],
{ {
@@ -352,7 +354,8 @@ export async function getBuilder(
builderPkg: string, builderPkg: string,
yarnDir: string, yarnDir: string,
output: Output, output: Output,
builderDir?: string builderDir?: string,
isRetry = false
): Promise<BuilderWithPackage> { ): Promise<BuilderWithPackage> {
let builderWithPkg: BuilderWithPackage = localBuilders[builderPkg]; let builderWithPkg: BuilderWithPackage = localBuilders[builderPkg];
if (!builderWithPkg) { if (!builderWithPkg) {
@@ -371,7 +374,7 @@ export async function getBuilder(
package: Object.freeze(pkg), package: Object.freeze(pkg),
}; };
} catch (err) { } catch (err) {
if (err.code === 'MODULE_NOT_FOUND') { if (err.code === 'MODULE_NOT_FOUND' && !isRetry) {
output.debug( output.debug(
`Attempted to require ${builderPkg}, but it is not installed` `Attempted to require ${builderPkg}, but it is not installed`
); );
@@ -379,7 +382,7 @@ export async function getBuilder(
await installBuilders(pkgSet, yarnDir, output, builderDir); await installBuilders(pkgSet, yarnDir, output, builderDir);
// Run `getBuilder()` again now that the builder has been installed // Run `getBuilder()` again now that the builder has been installed
return getBuilder(builderPkg, yarnDir, output, builderDir); return getBuilder(builderPkg, yarnDir, output, builderDir, true);
} }
throw err; throw err;
} }

View File

@@ -18,7 +18,7 @@ import { ChildProcess } from 'child_process';
import isPortReachable from 'is-port-reachable'; import isPortReachable from 'is-port-reachable';
import which from 'which'; import which from 'which';
import { getVercelIgnore } from '@vercel/client'; import { getVercelIgnore, fileNameSymbol } from '@vercel/client';
import { import {
getTransformedRoutes, getTransformedRoutes,
appendRoutesToPhase, appendRoutesToPhase,
@@ -495,7 +495,11 @@ export default class DevServer {
// The default empty `vercel.json` is used to serve all files as static // The default empty `vercel.json` is used to serve all files as static
// when no `vercel.json` is present // when no `vercel.json` is present
let config: NowConfig = this.cachedNowConfig || { version: 2 }; let configPath = 'vercel.json';
let config: NowConfig = this.cachedNowConfig || {
version: 2,
[fileNameSymbol]: configPath,
};
// We need to delete these properties for zero config to work // We need to delete these properties for zero config to work
// with file changes // with file changes
@@ -504,11 +508,11 @@ export default class DevServer {
delete this.cachedNowConfig.routes; delete this.cachedNowConfig.routes;
} }
let configPath = 'vercel.json';
try { try {
configPath = getNowConfigPath(this.cwd); configPath = getNowConfigPath(this.cwd);
this.output.debug(`Reading ${configPath}`); this.output.debug(`Reading ${configPath}`);
config = JSON.parse(await fs.readFile(configPath, 'utf8')); config = JSON.parse(await fs.readFile(configPath, 'utf8'));
config[fileNameSymbol] = configPath;
} catch (err) { } catch (err) {
if (err.code === 'ENOENT') { if (err.code === 'ENOENT') {
this.output.debug(err.toString()); this.output.debug(err.toString());

View File

@@ -70,7 +70,9 @@ function validateKey(
const error = validate.errors[0]; const error = validate.errors[0];
return `Invalid \`${key}\` property: ${error.dataPath} ${error.message}`; return `Invalid \`${String(key)}\` property: ${error.dataPath} ${
error.message
}`;
} }
return null; return null;

View File

@@ -1,4 +1,5 @@
import path from 'path'; import path from 'path';
import { fileNameSymbol } from '@vercel/client';
import { import {
CantParseJSONFile, CantParseJSONFile,
CantFindConfig, CantFindConfig,
@@ -7,15 +8,15 @@ import {
import humanizePath from './humanize-path'; import humanizePath from './humanize-path';
import readJSONFile from './read-json-file'; import readJSONFile from './read-json-file';
import readPackage from './read-package'; import readPackage from './read-package';
import { Config } from '../types'; import { NowConfig } from './dev/types';
import { Output } from './output'; import { Output } from './output';
let config: Config; let config: NowConfig;
export default async function getConfig( export default async function getConfig(
output: Output, output: Output,
configFile?: string configFile?: string
): Promise<Config | Error> { ): Promise<NowConfig | Error> {
// If config was already read, just return it // If config was already read, just return it
if (config) { if (config) {
return config; return config;
@@ -42,7 +43,8 @@ export default async function getConfig(
return localConfig; return localConfig;
} }
if (localConfig !== null) { if (localConfig !== null) {
config = localConfig; config = localConfig as NowConfig;
config[fileNameSymbol] = configFile;
return config; return config;
} }
} }
@@ -55,7 +57,8 @@ export default async function getConfig(
} }
if (vercelConfig !== null) { if (vercelConfig !== null) {
output.debug(`Found config in file ${vercelFilePath}`); output.debug(`Found config in file ${vercelFilePath}`);
config = vercelConfig; config = vercelConfig as NowConfig;
config[fileNameSymbol] = 'vercel.json';
return config; return config;
} }
@@ -67,7 +70,8 @@ export default async function getConfig(
} }
if (mainConfig !== null) { if (mainConfig !== null) {
output.debug(`Found config in file ${nowFilePath}`); output.debug(`Found config in file ${nowFilePath}`);
config = mainConfig; config = mainConfig as NowConfig;
config[fileNameSymbol] = 'now.json';
return config; return config;
} }
@@ -78,13 +82,16 @@ export default async function getConfig(
return pkgConfig; return pkgConfig;
} }
if (pkgConfig) { if (pkgConfig) {
output.debug(`Found config in package ${nowFilePath}`); output.debug(`Found config in package ${pkgFilePath}`);
config = pkgConfig; config = pkgConfig as NowConfig;
config[fileNameSymbol] = 'package.json';
return config; return config;
} }
// If we couldn't find the config anywhere return error // If we couldn't find the config anywhere return error
return new CantFindConfig([nowFilePath, pkgFilePath].map(humanizePath)); return new CantFindConfig(
[vercelFilePath, nowFilePath, pkgFilePath].map(humanizePath)
);
} }
async function readConfigFromPackage(file: string) { async function readConfigFromPackage(file: string) {

View File

@@ -3,7 +3,7 @@ import { exists } from 'fs-extra';
import { PackageJson } from '@vercel/build-utils'; import { PackageJson } from '@vercel/build-utils';
import Client from './client'; import Client from './client';
import { Config } from '../types'; import { NowConfig } from './dev/types';
import { CantParseJSONFile, ProjectNotFound } from './errors-ts'; import { CantParseJSONFile, ProjectNotFound } from './errors-ts';
import getProjectByIdOrName from './projects/get-project-by-id-or-name'; import getProjectByIdOrName from './projects/get-project-by-id-or-name';
@@ -33,7 +33,7 @@ export default async function preferV2Deployment({
hasDockerfile: boolean; hasDockerfile: boolean;
hasServerfile: boolean; hasServerfile: boolean;
pkg: PackageJson | CantParseJSONFile | null; pkg: PackageJson | CantParseJSONFile | null;
localConfig: Config | undefined; localConfig: NowConfig | undefined;
projectName?: string; projectName?: string;
}): Promise<null | string> { }): Promise<null | string> {
if (localConfig && localConfig.version) { if (localConfig && localConfig.version) {

View File

@@ -1,11 +1,11 @@
import path from 'path'; import path from 'path';
import { CantParseJSONFile } from './errors-ts'; import { CantParseJSONFile } from './errors-ts';
import readJSONFile from './read-json-file'; import readJSONFile from './read-json-file';
import { Config } from '../types'; import { NowConfig } from './dev/types';
import { PackageJson } from '@vercel/build-utils'; import { PackageJson } from '@vercel/build-utils';
interface CustomPackage extends PackageJson { interface CustomPackage extends PackageJson {
now?: Config; now?: NowConfig;
} }
export default async function readPackage(file?: string) { export default async function readPackage(file?: string) {

View File

@@ -134,6 +134,10 @@ module.exports = async session => {
'now.json': '{"builder": 1, "type": "static"}', 'now.json': '{"builder": 1, "type": "static"}',
'index.html': '<span>test</span', 'index.html': '<span>test</span',
}, },
'builds-wrong-vercel': {
'vercel.json': '{"fake": 1}',
'index.html': '<h1>Fake</h1>',
},
'builds-no-list': { 'builds-no-list': {
'now.json': `{ 'now.json': `{
"version": 2, "version": 2,

View File

@@ -25,7 +25,7 @@ import { fetchTokenWithRetry } from '../../../test/lib/deployment/now-deploy';
// log command when running `execa` // log command when running `execa`
function execa(file, args, options) { function execa(file, args, options) {
console.log(`$ now ${args.join(' ')}`); console.log(`$ vercel ${args.join(' ')}`);
return _execa(file, args, options); return _execa(file, args, options);
} }
@@ -410,6 +410,28 @@ test('Deploy `api-env` fixture and test `now env` command', async t => {
t.is(exitCode, 0, formatOutput({ stderr, stdout })); t.is(exitCode, 0, formatOutput({ stderr, stdout }));
} }
async function nowEnvAddSystemEnv() {
const now = execa(
binaryPath,
['env', 'add', 'VERCEL_URL', ...defaultArgs],
{
reject: false,
cwd: target,
}
);
await waitForPrompt(
now,
chunk =>
chunk.includes('which Environments') && chunk.includes('VERCEL_URL')
);
now.stdin.write('a\n'); // select all
const { exitCode, stderr, stdout } = await now;
t.is(exitCode, 0, formatOutput({ stderr, stdout }));
}
async function nowEnvLsIncludesVar() { async function nowEnvLsIncludesVar() {
const { exitCode, stderr, stdout } = await execa( const { exitCode, stderr, stdout } = await execa(
binaryPath, binaryPath,
@@ -434,6 +456,12 @@ test('Deploy `api-env` fixture and test `now env` command', async t => {
const myStdinVars = lines.filter(line => line.includes('MY_STDIN_VAR')); const myStdinVars = lines.filter(line => line.includes('MY_STDIN_VAR'));
t.is(myStdinVars.length, 1); t.is(myStdinVars.length, 1);
t.regex(myStdinVars.join('\n'), /preview/gm); t.regex(myStdinVars.join('\n'), /preview/gm);
const vercelVars = lines.filter(line => line.includes('VERCEL_URL'));
t.is(vercelVars.length, 3);
t.regex(vercelVars.join('\n'), /development/gm);
t.regex(vercelVars.join('\n'), /preview/gm);
t.regex(vercelVars.join('\n'), /production/gm);
} }
async function nowEnvPull() { async function nowEnvPull() {
@@ -450,7 +478,9 @@ test('Deploy `api-env` fixture and test `now env` command', async t => {
t.regex(stderr, /Created .env file/gm); t.regex(stderr, /Created .env file/gm);
const contents = fs.readFileSync(path.join(target, '.env'), 'utf8'); const contents = fs.readFileSync(path.join(target, '.env'), 'utf8');
t.is(contents, 'MY_ENV_VAR="MY_VALUE"\n'); const lines = new Set(contents.split('\n'));
t.true(lines.has('MY_ENV_VAR="MY_VALUE"'));
t.true(lines.has('VERCEL_URL=""'));
} }
async function nowDeployWithVar() { async function nowDeployWithVar() {
@@ -472,6 +502,7 @@ test('Deploy `api-env` fixture and test `now env` command', async t => {
const apiJson = await apiRes.json(); const apiJson = await apiRes.json();
t.is(apiJson['MY_ENV_VAR'], 'MY_VALUE'); t.is(apiJson['MY_ENV_VAR'], 'MY_VALUE');
t.is(apiJson['MY_STDIN_VAR'], 'MY_STDIN_VALUE'); t.is(apiJson['MY_STDIN_VAR'], 'MY_STDIN_VALUE');
t.is(apiJson['VERCEL_URL'], host);
const homeUrl = `https://${host}`; const homeUrl = `https://${host}`;
console.log({ homeUrl }); console.log({ homeUrl });
@@ -480,6 +511,7 @@ test('Deploy `api-env` fixture and test `now env` command', async t => {
const homeJson = await homeRes.json(); const homeJson = await homeRes.json();
t.is(homeJson['MY_ENV_VAR'], 'MY_VALUE'); t.is(homeJson['MY_ENV_VAR'], 'MY_VALUE');
t.is(homeJson['MY_STDIN_VAR'], 'MY_STDIN_VALUE'); t.is(homeJson['MY_STDIN_VAR'], 'MY_STDIN_VALUE');
t.is(apiJson['VERCEL_URL'], host);
} }
async function nowEnvRemove() { async function nowEnvRemove() {
@@ -517,15 +549,38 @@ test('Deploy `api-env` fixture and test `now env` command', async t => {
t.is(exitCode, 0, formatOutput({ stderr, stdout })); t.is(exitCode, 0, formatOutput({ stderr, stdout }));
} }
async function nowEnvRemoveWithNameOnly() {
const vc = execa(
binaryPath,
['env', 'rm', 'VERCEL_URL', '-y', ...defaultArgs],
{
reject: false,
cwd: target,
}
);
await waitForPrompt(
vc,
chunk =>
chunk.includes('which Environments') && chunk.includes('VERCEL_URL')
);
vc.stdin.write('a\n'); // select all
const { exitCode, stderr, stdout } = await vc;
t.is(exitCode, 0, formatOutput({ stderr, stdout }));
}
await nowDeploy(); await nowDeploy();
await nowEnvLsIsEmpty(); await nowEnvLsIsEmpty();
await nowEnvAdd(); await nowEnvAdd();
await nowEnvAddFromStdin(); await nowEnvAddFromStdin();
await nowEnvAddSystemEnv();
await nowEnvLsIncludesVar(); await nowEnvLsIncludesVar();
await nowEnvPull(); await nowEnvPull();
await nowDeployWithVar(); await nowDeployWithVar();
await nowEnvRemove(); await nowEnvRemove();
await nowEnvRemoveWithArgs(); await nowEnvRemoveWithArgs();
await nowEnvRemoveWithNameOnly();
await nowEnvLsIsEmpty(); await nowEnvLsIsEmpty();
}); });
@@ -1366,20 +1421,12 @@ test('ensure the `scope` property works with username', async t => {
t.is(contentType, 'text/html; charset=utf-8'); t.is(contentType, 'text/html; charset=utf-8');
}); });
test('try to create a builds deployments with wrong config', async t => { test('try to create a builds deployments with wrong now.json', async t => {
const directory = fixture('builds-wrong'); const directory = fixture('builds-wrong');
const { stderr, stdout, exitCode } = await execa( const { stderr, stdout, exitCode } = await execa(
binaryPath, binaryPath,
[ [directory, '--public', ...defaultArgs, '--confirm'],
directory,
'--public',
'--name',
session,
...defaultArgs,
'--force',
'--confirm',
],
{ {
reject: false, reject: false,
} }
@@ -1393,7 +1440,30 @@ test('try to create a builds deployments with wrong config', async t => {
t.is(exitCode, 1); t.is(exitCode, 1);
t.true( t.true(
stderr.includes( stderr.includes(
'Error! The property `builder` is not allowed in vercel.json please remove it.' 'Error! The property `builder` is not allowed in now.json please remove it.'
)
);
});
test('try to create a builds deployments with wrong vercel.json', async t => {
const directory = fixture('builds-wrong-vercel');
const { stderr, stdout, exitCode } = await execa(
binaryPath,
[directory, '--public', ...defaultArgs, '--confirm'],
{
reject: false,
}
);
console.log(stderr);
console.log(stdout);
console.log(exitCode);
t.is(exitCode, 1);
t.true(
stderr.includes(
'Error! The property `fake` is not allowed in vercel.json please remove it.'
) )
); );
}); });

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/client", "name": "@vercel/client",
"version": "8.0.0", "version": "8.0.1-canary.0",
"main": "dist/index.js", "main": "dist/index.js",
"typings": "dist/index.d.ts", "typings": "dist/index.d.ts",
"homepage": "https://vercel.com", "homepage": "https://vercel.com",

View File

@@ -111,9 +111,10 @@ export default function buildCreateDeployment(version: number) {
debug(`Deploying the provided path as single file`); debug(`Deploying the provided path as single file`);
} }
let configPath: string | undefined;
if (!nowConfig) { if (!nowConfig) {
// If the user did not provide a config file, use the one in the root directory. // If the user did not provide a config file, use the one in the root directory.
const configPath = fileList configPath = fileList
.map(f => relative(cwd, f)) .map(f => relative(cwd, f))
.find(f => f === 'vercel.json' || f === 'now.json'); .find(f => f === 'vercel.json' || f === 'now.json');
nowConfig = await parseNowJSON(configPath); nowConfig = await parseNowJSON(configPath);
@@ -126,7 +127,7 @@ export default function buildCreateDeployment(version: number) {
nowConfig.files.length > 0 nowConfig.files.length > 0
) { ) {
// See the docs: https://vercel.com/docs/v1/features/configuration/#files-(array) // See the docs: https://vercel.com/docs/v1/features/configuration/#files-(array)
debug('Filtering file list based on `files` key in vercel.json'); debug(`Filtering file list based on \`files\` key in "${configPath}"`);
const allowedFiles = new Set<string>(['Dockerfile']); const allowedFiles = new Set<string>(['Dockerfile']);
const allowedDirs = new Set<string>(); const allowedDirs = new Set<string>();
nowConfig.files.forEach(relPath => { nowConfig.files.forEach(relPath => {

View File

@@ -106,7 +106,10 @@ interface LegacyNowConfig {
aliases?: string | string[]; aliases?: string | string[];
} }
export const fileNameSymbol = Symbol('fileName');
export interface NowConfig extends LegacyNowConfig { export interface NowConfig extends LegacyNowConfig {
[fileNameSymbol]?: string;
name?: string; name?: string;
version?: number; version?: number;
env?: Dictionary<string>; env?: Dictionary<string>;

View File

@@ -109,11 +109,16 @@ export async function getVercelIgnore(
const files = await Promise.all( const files = await Promise.all(
cwds.map(async cwd => { cwds.map(async cwd => {
let str = await maybeRead(join(cwd, '.vercelignore'), ''); const [vercelignore, nowignore] = await Promise.all([
if (!str) { maybeRead(join(cwd, '.vercelignore'), ''),
str = await maybeRead(join(cwd, '.nowignore'), ''); maybeRead(join(cwd, '.nowignore'), ''),
]);
if (vercelignore && nowignore) {
throw new Error(
'Cannot use both a `.vercelignore` and `.nowignore` file. Please delete the `.nowignore` file.'
);
} }
return str; return vercelignore || nowignore;
}) })
); );

View File

@@ -0,0 +1 @@
bar

View File

@@ -0,0 +1 @@
foo

View File

@@ -0,0 +1,27 @@
import assert from 'assert';
import { join } from 'path';
import { getVercelIgnore } from '../src';
describe('Test `getVercelIgnore()`', () => {
it('Should read `.nowignore`', async () => {
const fixture = join(__dirname, 'fixtures', 'nowignore');
const { ig } = await getVercelIgnore(fixture);
assert.equal(ig.ignores('ignore.txt'), true);
assert.equal(ig.ignores('keep.txt'), false);
});
it('Should throw an error if `.vercelignore` and `.nowignore` exist', async () => {
let err: Error | null = null;
const fixture = join(__dirname, 'fixtures', 'vercelignore-and-nowignore');
try {
await getVercelIgnore(fixture);
} catch (_err) {
err = _err;
}
assert(err);
assert.equal(
err!.message,
'Cannot use both a `.vercelignore` and `.nowignore` file. Please delete the `.nowignore` file.'
);
});
});

View File

@@ -0,0 +1,10 @@
let buildUtils: typeof import('@vercel/build-utils');
try {
buildUtils = require('@vercel/build-utils');
} catch (e) {
// Fallback for older CLI versions
buildUtils = require('@now/build-utils');
}
export default buildUtils;

View File

@@ -1,4 +1,4 @@
ncc build index.ts -e @vercel/build-utils -o dist ncc build index.ts -e @vercel/build-utils -e @now/build-utils -o dist
ncc build install.ts -e @vercel/build-utils -o dist/install ncc build install.ts -e @vercel/build-utils -e @now/build-utils -o dist/install
mv dist/install/index.js dist/install.js mv dist/install/index.js dist/install.js
rm -rf dist/install rm -rf dist/install

View File

@@ -4,9 +4,9 @@ import fetch from 'node-fetch';
import { mkdirp, pathExists } from 'fs-extra'; import { mkdirp, pathExists } from 'fs-extra';
import { dirname, join } from 'path'; import { dirname, join } from 'path';
import { homedir } from 'os'; import { homedir } from 'os';
import { debug } from '@vercel/build-utils'; import buildUtils from './build-utils';
import stringArgv from 'string-argv'; import stringArgv from 'string-argv';
const { debug } = buildUtils;
const archMap = new Map([['x64', 'amd64'], ['x86', '386']]); const archMap = new Map([['x64', 'amd64'], ['x86', '386']]);
const platformMap = new Map([['win32', 'windows']]); const platformMap = new Map([['win32', 'windows']]);

View File

@@ -2,18 +2,17 @@ import { join, sep, dirname, basename, normalize } from 'path';
import { readFile, writeFile, pathExists, move } from 'fs-extra'; import { readFile, writeFile, pathExists, move } from 'fs-extra';
import { homedir } from 'os'; import { homedir } from 'os';
import execa from 'execa'; import execa from 'execa';
import { BuildOptions, Meta, Files } from '@vercel/build-utils';
import buildUtils from './build-utils';
import { const {
glob, glob,
download, download,
createLambda, createLambda,
getWriteableDirectory, getWriteableDirectory,
BuildOptions,
Meta,
shouldServe, shouldServe,
Files,
debug, debug,
} from '@vercel/build-utils'; } = buildUtils;
import { createGo, getAnalyzedEntrypoint, OUT_EXTENSION } from './go-helpers'; import { createGo, getAnalyzedEntrypoint, OUT_EXTENSION } from './go-helpers';
const handlerFileName = `handler${OUT_EXTENSION}`; const handlerFileName = `handler${OUT_EXTENSION}`;

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/go", "name": "@vercel/go",
"version": "1.1.0", "version": "1.1.1-canary.0",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",

View File

@@ -7,10 +7,10 @@ cp -v "$bridge_defs" src/now__bridge.ts
tsc tsc
ncc build src/dev-server.ts -e @vercel/build-utils -o dist/dev ncc build src/dev-server.ts -e @vercel/build-utils -e @now/build-utils -o dist/dev
mv dist/dev/index.js dist/dev-server.js mv dist/dev/index.js dist/dev-server.js
rm -rf dist/dev rm -rf dist/dev
ncc build src/index.ts -e @vercel/build-utils -o dist/main ncc build src/index.ts -e @vercel/build-utils -e @now/build-utils -o dist/main
mv dist/main/index.js dist/index.js mv dist/main/index.js dist/index.js
rm -rf dist/main rm -rf dist/main

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/next", "name": "@vercel/next",
"version": "2.6.0", "version": "2.6.1-canary.0",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",

View File

@@ -0,0 +1,10 @@
let buildUtils: typeof import('@vercel/build-utils');
try {
buildUtils = require('@vercel/build-utils');
} catch (e) {
// Fallback for older CLI versions
buildUtils = require('@now/build-utils');
}
export default buildUtils;

View File

@@ -1,24 +1,28 @@
import { import buildUtils from './build-utils';
BuildOptions, const {
Config,
createLambda, createLambda,
debug, debug,
download, download,
FileBlob,
FileFsRef,
Files,
getLambdaOptionsFromFunction, getLambdaOptionsFromFunction,
getNodeVersion, getNodeVersion,
getSpawnOptions, getSpawnOptions,
glob, glob,
Lambda,
PackageJson,
PrepareCacheOptions,
Prerender,
runNpmInstall, runNpmInstall,
runPackageJsonScript, runPackageJsonScript,
execCommand, execCommand,
getNodeBinPath, getNodeBinPath,
} = buildUtils;
import {
Lambda,
BuildOptions,
Config,
FileBlob,
FileFsRef,
Files,
PackageJson,
PrepareCacheOptions,
Prerender,
NowBuildError, NowBuildError,
} from '@vercel/build-utils'; } from '@vercel/build-utils';
import { Route, Handler } from '@vercel/routing-utils'; import { Route, Handler } from '@vercel/routing-utils';

View File

@@ -6,14 +6,9 @@ import { ZipFile } from 'yazl';
import crc32 from 'buffer-crc32'; import crc32 from 'buffer-crc32';
import { Sema } from 'async-sema'; import { Sema } from 'async-sema';
import resolveFrom from 'resolve-from'; import resolveFrom from 'resolve-from';
import { import buildUtils from './build-utils';
Files, const { streamToBuffer, Lambda, NowBuildError, isSymbolicLink } = buildUtils;
FileFsRef, import { Files, FileFsRef } from '@vercel/build-utils';
streamToBuffer,
Lambda,
NowBuildError,
isSymbolicLink,
} from '@vercel/build-utils';
import { Route, Source, NowHeader, NowRewrite } from '@vercel/routing-utils'; import { Route, Source, NowHeader, NowRewrite } from '@vercel/routing-utils';
type stringMap = { [key: string]: string }; type stringMap = { [key: string]: string };

View File

@@ -21,23 +21,23 @@ mv dist/types dist/index.d.ts
# bundle helpers.ts with ncc # bundle helpers.ts with ncc
rm dist/helpers.js rm dist/helpers.js
ncc build src/helpers.ts -e @vercel/build-utils -o dist/helpers ncc build src/helpers.ts -e @vercel/build-utils -e @now/build-utils -o dist/helpers
mv dist/helpers/index.js dist/helpers.js mv dist/helpers/index.js dist/helpers.js
rm -rf dist/helpers rm -rf dist/helpers
# build source-map-support/register for source maps # build source-map-support/register for source maps
ncc build ../../node_modules/source-map-support/register -e @vercel/build-utils -o dist/source-map-support ncc build ../../node_modules/source-map-support/register -e @vercel/build-utils -e @now/build-utils -o dist/source-map-support
mv dist/source-map-support/index.js dist/source-map-support.js mv dist/source-map-support/index.js dist/source-map-support.js
rm -rf dist/source-map-support rm -rf dist/source-map-support
# build typescript # build typescript
ncc build ../../node_modules/typescript/lib/typescript -e @vercel/build-utils -o dist/typescript ncc build ../../node_modules/typescript/lib/typescript -e @vercel/build-utils -e @now/build-utils -o dist/typescript
mv dist/typescript/index.js dist/typescript.js mv dist/typescript/index.js dist/typescript.js
mkdir -p dist/typescript/lib mkdir -p dist/typescript/lib
mv dist/typescript/typescript/lib/*.js dist/typescript/lib/ mv dist/typescript/typescript/lib/*.js dist/typescript/lib/
mv dist/typescript/typescript/lib/*.d.ts dist/typescript/lib/ mv dist/typescript/typescript/lib/*.d.ts dist/typescript/lib/
rm -r dist/typescript/typescript rm -r dist/typescript/typescript
ncc build src/index.ts -e @vercel/build-utils -o dist/main ncc build src/index.ts -e @vercel/build-utils -e @now/build-utils -o dist/main
mv dist/main/index.js dist/index.js mv dist/main/index.js dist/index.js
rm -rf dist/main rm -rf dist/main

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/node", "name": "@vercel/node",
"version": "1.6.0", "version": "1.6.1-canary.0",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",

View File

@@ -0,0 +1,10 @@
let buildUtils: typeof import('@vercel/build-utils');
try {
buildUtils = require('@vercel/build-utils');
} catch (e) {
// Fallback for older CLI versions
buildUtils = require('@now/build-utils');
}
export default buildUtils;

View File

@@ -8,26 +8,29 @@ import {
parse as parsePath, parse as parsePath,
} from 'path'; } from 'path';
import nodeFileTrace from '@zeit/node-file-trace'; import nodeFileTrace from '@zeit/node-file-trace';
import buildUtils from './build-utils';
import { import {
glob,
download,
File, File,
FileBlob,
FileFsRef,
Files, Files,
Meta, Meta,
PrepareCacheOptions,
BuildOptions,
Config,
} from '@vercel/build-utils';
const {
glob,
download,
FileBlob,
FileFsRef,
createLambda, createLambda,
runNpmInstall, runNpmInstall,
runPackageJsonScript, runPackageJsonScript,
getNodeVersion, getNodeVersion,
getSpawnOptions, getSpawnOptions,
PrepareCacheOptions,
BuildOptions,
shouldServe, shouldServe,
Config,
debug, debug,
isSymbolicLink, isSymbolicLink,
} from '@vercel/build-utils'; } = buildUtils;
export { shouldServe }; export { shouldServe };
export { NowRequest, NowResponse } from './types'; export { NowRequest, NowResponse } from './types';
import { makeNowLauncher, makeAwsLauncher } from './launcher'; import { makeNowLauncher, makeAwsLauncher } from './launcher';
@@ -120,7 +123,7 @@ async function compile(
const files = await glob(pattern, workPath); const files = await glob(pattern, workPath);
await Promise.all( await Promise.all(
Object.keys(files).map(async file => { Object.keys(files).map(async file => {
const entry: FileFsRef = files[file]; const entry = files[file];
fsCache.set(file, entry); fsCache.set(file, entry);
const stream = entry.toStream(); const stream = entry.toStream();
const { data } = await FileBlob.fromStream({ stream }); const { data } = await FileBlob.fromStream({ stream });

View File

@@ -1,6 +1,7 @@
import { relative, basename, resolve, dirname } from 'path'; import { relative, basename, resolve, dirname } from 'path';
import _ts from 'typescript'; import _ts from 'typescript';
import { NowBuildError } from '@vercel/build-utils'; import buildUtils from './build-utils';
const { NowBuildError } = buildUtils;
/* /*
* Fork of TS-Node - https://github.com/TypeStrong/ts-node * Fork of TS-Node - https://github.com/TypeStrong/ts-node

View File

@@ -1 +1 @@
ncc build src/index.ts -e @vercel/build-utils -o dist ncc build src/index.ts -e @vercel/build-utils -e @now/build-utils -o dist

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/python", "name": "@vercel/python",
"version": "1.2.0", "version": "1.2.1-canary.0",
"main": "./dist/index.js", "main": "./dist/index.js",
"license": "MIT", "license": "MIT",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",

View File

@@ -0,0 +1,10 @@
let buildUtils: typeof import('@vercel/build-utils');
try {
buildUtils = require('@vercel/build-utils');
} catch (e) {
// Fallback for older CLI versions
buildUtils = require('@now/build-utils');
}
export default buildUtils;

View File

@@ -4,16 +4,16 @@ import fs from 'fs';
import { promisify } from 'util'; import { promisify } from 'util';
const readFile = promisify(fs.readFile); const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile); const writeFile = promisify(fs.writeFile);
import { import buildUtils from './build-utils';
import { GlobOptions, BuildOptions } from '@vercel/build-utils';
const {
getWriteableDirectory, getWriteableDirectory,
download, download,
glob, glob,
GlobOptions,
createLambda, createLambda,
shouldServe, shouldServe,
BuildOptions,
debug, debug,
} from '@vercel/build-utils'; } = buildUtils;
import { installRequirement, installRequirementsFile } from './install'; import { installRequirement, installRequirementsFile } from './install';
async function pipenvConvert(cmd: string, srcDir: string) { async function pipenvConvert(cmd: string, srcDir: string) {

View File

@@ -1,5 +1,7 @@
import execa from 'execa'; import execa from 'execa';
import { debug, Meta } from '@vercel/build-utils'; import { Meta } from '@vercel/build-utils';
import buildUtils from './build-utils';
const { debug } = buildUtils;
const pipPath = 'pip3'; const pipPath = 'pip3';
const makeDependencyCheckCode = (dependency: string) => ` const makeDependencyCheckCode = (dependency: string) => `

View File

@@ -0,0 +1,10 @@
let buildUtils: typeof import('@vercel/build-utils');
try {
buildUtils = require('@vercel/build-utils');
} catch (e) {
// Fallback for older CLI versions
buildUtils = require('@now/build-utils');
}
export default buildUtils;

View File

@@ -1 +1 @@
ncc build index.ts -e @vercel/build-utils -o dist ncc build index.ts -e @vercel/build-utils -e @now/build-utils -o dist

View File

@@ -8,15 +8,16 @@ import {
readFile, readFile,
writeFile, writeFile,
} from 'fs-extra'; } from 'fs-extra';
import { import buildUtils from './build-utils';
import { BuildOptions } from '@vercel/build-utils';
const {
download, download,
getWriteableDirectory, getWriteableDirectory,
glob, glob,
createLambda, createLambda,
BuildOptions,
debug, debug,
walkParentDirs, walkParentDirs,
} from '@vercel/build-utils'; } = buildUtils;
import { installBundler } from './install-ruby'; import { installBundler } from './install-ruby';
async function matchPaths( async function matchPaths(

View File

@@ -1,7 +1,9 @@
import { join } from 'path'; import { join } from 'path';
import { intersects } from 'semver'; import { intersects } from 'semver';
import execa from 'execa'; import execa from 'execa';
import { debug, Meta, NowBuildError, NodeVersion } from '@vercel/build-utils'; import buildUtils from './build-utils';
import { Meta, NodeVersion } from '@vercel/build-utils';
const { debug, NowBuildError } = buildUtils;
interface RubyVersion extends NodeVersion { interface RubyVersion extends NodeVersion {
minor: number; minor: number;

View File

@@ -1,7 +1,7 @@
{ {
"name": "@vercel/ruby", "name": "@vercel/ruby",
"author": "Nathan Cahill <nathan@nathancahill.com>", "author": "Nathan Cahill <nathan@nathancahill.com>",
"version": "1.2.0", "version": "1.2.1-canary.0",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby",

View File

@@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
set -euo pipefail set -euo pipefail
ncc build src/index.ts -e @vercel/build-utils -o dist ncc build src/index.ts -e @vercel/build-utils -e @now/build-utils -o dist

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/static-build", "name": "@vercel/static-build",
"version": "0.17.0", "version": "0.17.1-canary.0",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/static-builds", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/static-builds",

View File

@@ -0,0 +1,10 @@
let buildUtils: typeof import('@vercel/build-utils');
try {
buildUtils = require('@vercel/build-utils');
} catch (e) {
// Fallback for older CLI versions
buildUtils = require('@now/build-utils');
}
export default buildUtils;

View File

@@ -6,7 +6,16 @@ import isPortReachable from 'is-port-reachable';
import { ChildProcess, SpawnOptions } from 'child_process'; import { ChildProcess, SpawnOptions } from 'child_process';
import { existsSync, readFileSync, statSync, readdirSync } from 'fs'; import { existsSync, readFileSync, statSync, readdirSync } from 'fs';
import { frameworks, Framework } from './frameworks'; import { frameworks, Framework } from './frameworks';
import buildUtils from './build-utils';
import { import {
Files,
FileFsRef,
BuildOptions,
Config,
PackageJson,
PrepareCacheOptions,
} from '@vercel/build-utils';
const {
glob, glob,
download, download,
spawnAsync, spawnAsync,
@@ -20,15 +29,9 @@ import {
runShellScript, runShellScript,
getNodeVersion, getNodeVersion,
getSpawnOptions, getSpawnOptions,
Files,
FileFsRef,
BuildOptions,
Config,
debug, debug,
PackageJson,
PrepareCacheOptions,
NowBuildError, NowBuildError,
} from '@vercel/build-utils'; } = buildUtils;
import { Route, Source } from '@vercel/routing-utils'; import { Route, Source } from '@vercel/routing-utils';
import { getVercelIgnore } from '@vercel/client'; import { getVercelIgnore } from '@vercel/client';