Compare commits

...

16 Commits

Author SHA1 Message Date
Steven
4ccdcde463 Publish Stable
- @vercel/build-utils@5.9.0
 - vercel@28.12.6
 - @vercel/client@12.3.1
 - @vercel/fs-detectors@3.7.5
 - @vercel/go@2.2.30
 - @vercel/hydrogen@0.0.44
 - @vercel/next@3.3.15
 - @vercel/node@2.8.13
 - @vercel/python@3.1.40
 - @vercel/redwood@1.0.51
 - @vercel/remix@1.2.5
 - @vercel/ruby@1.3.56
 - @vercel/static-build@1.1.7
2023-01-17 19:25:26 -05:00
Nathan Rajlich
22d3ee160b [build-utils] Add includeDirectories option to glob() (#9245)
Instead of always including empty directories in `glob()`, make it an
opt-in behavior because technically it's a breaking change to include
them by default.
2023-01-17 19:21:40 -05:00
Sean Massa
6d97e1673e Publish Stable
- vercel@28.12.5
 - @vercel/client@12.3.0
 - @vercel/node-bridge@3.1.9
 - @vercel/node@2.8.12
2023-01-17 13:46:58 -06:00
Nathan Rajlich
522565f6e5 [node-bridge] Add missing lazy dependencies (#9231)
These were missing from the compiled ncc build of `helpers.ts`, and thus causing an error at runtime because the deps are not available within the Serverless Function.
2023-01-14 01:41:50 +00:00
Steven
07bf81ab10 [client] Add sliding window delay when polling deployment complete (#9222)
The previous delay of 1500ms was causing some users to hit the API rate limits. This doesn't normally happen with a single deployment, but it can happen with several concurrent deployments (for example a monorepo with many projects).

We don't need to be polling so often, so this PR changed the polling delay to the following:

- During 0s-15s: check every 1 second
- During 15s-60s: check every 5 seconds
- During 1m-5m: check every 15 seconds
- During 5m-10m: check every 30 seconds
2023-01-14 00:27:14 +00:00
Steven
35024a4e3a [tests] Split up dev tests to increase concurrency (#9228)
This will speed up CI because we can run more tests concurrently.

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
2023-01-13 18:53:57 -05:00
Sean Massa
c1df9bca19 [tests] skip private packages (#9229) 2023-01-13 17:24:50 -06:00
Nathan Rajlich
4c1cdd1f0f [client] Send empty directory entries to POST create deployment (#9118)
Update `@vercel/client` to send empty directory entries to the `POST` create deployment endpoint. This makes it so that CLI deployments will have empty directories re-populated in the build-container when doing `vc deploy`.

Follow-up to #9103.
2023-01-13 22:24:31 +00:00
Sean Massa
b5cdc82a1c Publish Stable
- @vercel/build-utils@5.8.3
 - vercel@28.12.4
 - @vercel/client@12.2.31
 - @vercel/edge@0.2.6
 - @vercel/error-utils@1.0.8
 - @vercel/frameworks@1.2.4
 - @vercel/fs-detectors@3.7.4
 - @vercel/gatsby-plugin-vercel-analytics@1.0.6
 - @vercel/go@2.2.29
 - @vercel/hydrogen@0.0.43
 - @vercel/next@3.3.14
 - @vercel/node-bridge@3.1.8
 - @vercel/node@2.8.11
 - @vercel/python@3.1.39
 - @vercel/redwood@1.0.50
 - @vercel/remix@1.2.4
 - @vercel/routing-utils@2.1.8
 - @vercel/ruby@1.3.55
 - @vercel/static-build@1.1.6
 - @vercel/static-config@2.0.11
2023-01-13 15:45:03 -06:00
Nathan Rajlich
c7851404b3 [*] Remove "workspace:" (#9225) 2023-01-13 15:42:29 -06:00
Sean Massa
e54da8a2e5 Publish Stable
- @vercel/build-utils@5.8.2
 - vercel@28.12.3
 - @vercel/client@12.2.30
 - @vercel/edge@0.2.5
 - @vercel/error-utils@1.0.7
 - @vercel/frameworks@1.2.3
 - @vercel/fs-detectors@3.7.3
 - @vercel/gatsby-plugin-vercel-analytics@1.0.5
 - @vercel/go@2.2.28
 - @vercel/hydrogen@0.0.42
 - @vercel/next@3.3.13
 - @vercel/node-bridge@3.1.7
 - @vercel/node@2.8.10
 - @vercel/python@3.1.38
 - @vercel/redwood@1.0.49
 - @vercel/remix@1.2.3
 - @vercel/routing-utils@2.1.7
 - @vercel/ruby@1.3.54
 - @vercel/static-build@1.1.5
 - @vercel/static-config@2.0.10
2023-01-13 15:06:45 -06:00
Sean Massa
a066bedf95 add the lockfile before commit 2023-01-13 15:06:16 -06:00
Sean Massa
09b23e53ba update lockfile because lerna did not do its job 2023-01-13 15:05:29 -06:00
Sean Massa
b793a67588 Publish Stable
- @vercel/build-utils@5.8.1
 - vercel@28.12.2
 - @vercel/client@12.2.29
 - @vercel/edge@0.2.4
 - @vercel/error-utils@1.0.6
 - @vercel/frameworks@1.2.2
 - @vercel/fs-detectors@3.7.2
 - @vercel/gatsby-plugin-vercel-analytics@1.0.4
 - @vercel/go@2.2.27
 - @vercel/hydrogen@0.0.41
 - @vercel/next@3.3.12
 - @vercel/node-bridge@3.1.6
 - @vercel/node@2.8.9
 - @vercel/python@3.1.37
 - @vercel/redwood@1.0.48
 - @vercel/remix@1.2.2
 - @vercel/routing-utils@2.1.6
 - @vercel/ruby@1.3.53
 - @vercel/static-build@1.1.4
 - @vercel/static-config@2.0.9
2023-01-13 15:01:55 -06:00
Sean Massa
31dd354b3a remove unnecessary checkout 2023-01-13 15:00:52 -06:00
Sean Massa
529ff3b2d7 add "version" lifecycle hook for lerna to update lockfile before commit 2023-01-13 14:59:49 -06:00
39 changed files with 540 additions and 422 deletions

View File

@@ -16,7 +16,7 @@
"devDependencies": { "devDependencies": {
"@types/node": "16.18.11", "@types/node": "16.18.11",
"@types/node-fetch": "2.5.4", "@types/node-fetch": "2.5.4",
"@vercel/node": "workspace:*", "@vercel/node": "*",
"typescript": "4.3.4" "typescript": "4.3.4"
} }
} }

View File

@@ -11,9 +11,9 @@
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@typescript-eslint/eslint-plugin": "5.21.0", "@typescript-eslint/eslint-plugin": "5.21.0",
"@typescript-eslint/parser": "5.21.0", "@typescript-eslint/parser": "5.21.0",
"@vercel/build-utils": "workspace:*", "@vercel/build-utils": "*",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"@vercel/next": "workspace:*", "@vercel/next": "*",
"async-retry": "1.2.3", "async-retry": "1.2.3",
"buffer-replace": "1.0.0", "buffer-replace": "1.0.0",
"create-svelte": "2.0.1", "create-svelte": "2.0.1",
@@ -37,6 +37,7 @@
}, },
"scripts": { "scripts": {
"lerna": "lerna", "lerna": "lerna",
"version": "pnpm install && git add pnpm-lock.yaml",
"bootstrap": "lerna bootstrap", "bootstrap": "lerna bootstrap",
"publish-stable": "echo 'Run `pnpm changelog` for instructions'", "publish-stable": "echo 'Run `pnpm changelog` for instructions'",
"publish-canary": "git checkout main && git pull && lerna version prerelease --preid canary --message \"Publish Canary\" --exact", "publish-canary": "git checkout main && git pull && lerna version prerelease --preid canary --message \"Publish Canary\" --exact",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/build-utils", "name": "@vercel/build-utils",
"version": "5.8.0", "version": "5.9.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

@@ -6,7 +6,9 @@ import { lstat, Stats } from 'fs-extra';
import { normalizePath } from './normalize-path'; import { normalizePath } from './normalize-path';
import FileFsRef from '../file-fs-ref'; import FileFsRef from '../file-fs-ref';
export type GlobOptions = vanillaGlob_.IOptions; export interface GlobOptions extends vanillaGlob_.IOptions {
includeDirectories?: boolean;
}
const vanillaGlob = promisify(vanillaGlob_); const vanillaGlob = promisify(vanillaGlob_);
@@ -73,18 +75,20 @@ export default async function glob(
} }
// Add empty directory entries // Add empty directory entries
for (const relativePath of dirs) { if (options.includeDirectories) {
if (dirsWithEntries.has(relativePath)) continue; for (const relativePath of dirs) {
if (dirsWithEntries.has(relativePath)) continue;
let finalPath = relativePath; let finalPath = relativePath;
if (mountpoint) { if (mountpoint) {
finalPath = path.join(mountpoint, finalPath); finalPath = path.join(mountpoint, finalPath);
}
const fsPath = normalizePath(path.join(options.cwd, relativePath));
const stat = statCache[fsPath];
results[finalPath] = new FileFsRef({ mode: stat.mode, fsPath });
} }
const fsPath = normalizePath(path.join(options.cwd, relativePath));
const stat = statCache[fsPath];
results[finalPath] = new FileFsRef({ mode: stat.mode, fsPath });
} }
return results; return results;

View File

@@ -4,7 +4,7 @@ import { tmpdir } from 'os';
import { glob, isDirectory } from '../src'; import { glob, isDirectory } from '../src';
describe('glob()', () => { describe('glob()', () => {
it('should return entries for empty directories', async () => { it('should not return entries for empty directories by default', async () => {
const dir = await fs.mkdtemp(join(tmpdir(), 'build-utils-test')); const dir = await fs.mkdtemp(join(tmpdir(), 'build-utils-test'));
try { try {
await Promise.all([ await Promise.all([
@@ -19,6 +19,33 @@ describe('glob()', () => {
]); ]);
const files = await glob('**', dir); const files = await glob('**', dir);
const fileNames = Object.keys(files).sort(); const fileNames = Object.keys(files).sort();
expect(fileNames).toHaveLength(2);
expect(fileNames).toEqual(['dir-with-file/data.json', 'root.txt']);
expect(isDirectory(files['dir-with-file/data.json'].mode)).toEqual(false);
expect(isDirectory(files['root.txt'].mode)).toEqual(false);
expect(files['dir-with-file']).toBeUndefined();
expect(files['another/subdir']).toBeUndefined();
expect(files['empty-dir']).toBeUndefined();
} finally {
await fs.remove(dir);
}
});
it('should return entries for empty directories with `includeDirectories: true`', async () => {
const dir = await fs.mkdtemp(join(tmpdir(), 'build-utils-test'));
try {
await Promise.all([
fs.writeFile(join(dir, 'root.txt'), 'file at the root'),
fs.mkdirp(join(dir, 'empty-dir')),
fs
.mkdirp(join(dir, 'dir-with-file'))
.then(() =>
fs.writeFile(join(dir, 'dir-with-file/data.json'), '{"a":"b"}')
),
fs.mkdirp(join(dir, 'another/subdir')),
]);
const files = await glob('**', { cwd: dir, includeDirectories: true });
const fileNames = Object.keys(files).sort();
expect(fileNames).toHaveLength(4); expect(fileNames).toHaveLength(4);
expect(fileNames).toEqual([ expect(fileNames).toEqual([
'another/subdir', 'another/subdir',

View File

@@ -1,6 +1,6 @@
{ {
"name": "vercel", "name": "vercel",
"version": "28.12.1", "version": "28.12.6",
"preferGlobal": true, "preferGlobal": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "The command-line interface for Vercel", "description": "The command-line interface for Vercel",
@@ -41,16 +41,16 @@
"node": ">= 14" "node": ">= 14"
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "workspace:5.8.0", "@vercel/build-utils": "5.9.0",
"@vercel/go": "workspace:2.2.26", "@vercel/go": "2.2.30",
"@vercel/hydrogen": "workspace:0.0.40", "@vercel/hydrogen": "0.0.44",
"@vercel/next": "workspace:3.3.11", "@vercel/next": "3.3.15",
"@vercel/node": "workspace:2.8.8", "@vercel/node": "2.8.13",
"@vercel/python": "workspace:3.1.36", "@vercel/python": "3.1.40",
"@vercel/redwood": "workspace:1.0.47", "@vercel/redwood": "1.0.51",
"@vercel/remix": "workspace:1.2.1", "@vercel/remix": "1.2.5",
"@vercel/ruby": "workspace:1.3.52", "@vercel/ruby": "1.3.56",
"@vercel/static-build": "workspace:1.1.3" "@vercel/static-build": "1.1.7"
}, },
"devDependencies": { "devDependencies": {
"@alex_neo/jest-expect-message": "1.0.5", "@alex_neo/jest-expect-message": "1.0.5",
@@ -93,13 +93,13 @@
"@types/which": "1.3.2", "@types/which": "1.3.2",
"@types/write-json-file": "2.2.1", "@types/write-json-file": "2.2.1",
"@types/yauzl-promise": "2.1.0", "@types/yauzl-promise": "2.1.0",
"@vercel/client": "workspace:12.2.28", "@vercel/client": "12.3.1",
"@vercel/error-utils": "workspace:1.0.5", "@vercel/error-utils": "1.0.8",
"@vercel/frameworks": "workspace:1.2.1", "@vercel/frameworks": "1.2.4",
"@vercel/fs-detectors": "workspace:3.7.1", "@vercel/fs-detectors": "3.7.5",
"@vercel/fun": "1.0.4", "@vercel/fun": "1.0.4",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "workspace:2.1.5", "@vercel/routing-utils": "2.1.8",
"@zeit/source-map-support": "0.6.2", "@zeit/source-map-support": "0.6.2",
"ajv": "6.12.2", "ajv": "6.12.2",
"alpha-sort": "2.0.1", "alpha-sort": "2.0.1",

View File

@@ -1,16 +1,4 @@
import { join } from 'path'; const { exec, fixture, testFixture, testFixtureStdio } = require('./utils.js');
import ms from 'ms';
import fs, { mkdirp } from 'fs-extra';
const {
exec,
fetch,
fixture,
sleep,
testFixture,
testFixtureStdio,
validateResponseHeaders,
} = require('./utils.js');
test('[vercel dev] validate redirects', async () => { test('[vercel dev] validate redirects', async () => {
const directory = fixture('invalid-redirects'); const directory = fixture('invalid-redirects');
@@ -122,262 +110,3 @@ test(
}); });
}) })
); );
test(
'[vercel dev] test cleanUrls serve correct content',
testFixtureStdio('test-clean-urls', async (testPath: any) => {
await testPath(200, '/', 'Index Page');
await testPath(200, '/about', 'About Page');
await testPath(200, '/sub', 'Sub Index Page');
await testPath(200, '/sub/another', 'Sub Another Page');
await testPath(200, '/style.css', 'body { color: green }');
await testPath(308, '/index.html', 'Redirecting to / (308)', {
Location: '/',
});
await testPath(308, '/about.html', 'Redirecting to /about (308)', {
Location: '/about',
});
await testPath(308, '/sub/index.html', 'Redirecting to /sub (308)', {
Location: '/sub',
});
await testPath(
308,
'/sub/another.html',
'Redirecting to /sub/another (308)',
{ Location: '/sub/another' }
);
})
);
test(
'[vercel dev] test cleanUrls serve correct content when using `outputDirectory`',
testFixtureStdio(
'test-clean-urls-with-output-directory',
async (testPath: any) => {
await testPath(200, '/', 'Index Page');
await testPath(200, '/about', 'About Page');
await testPath(200, '/sub', 'Sub Index Page');
await testPath(200, '/sub/another', 'Sub Another Page');
await testPath(200, '/style.css', 'body { color: green }');
await testPath(308, '/index.html', 'Redirecting to / (308)', {
Location: '/',
});
await testPath(308, '/about.html', 'Redirecting to /about (308)', {
Location: '/about',
});
await testPath(308, '/sub/index.html', 'Redirecting to /sub (308)', {
Location: '/sub',
});
await testPath(
308,
'/sub/another.html',
'Redirecting to /sub/another (308)',
{ Location: '/sub/another' }
);
}
)
);
test(
'[vercel dev] should serve custom 404 when `cleanUrls: true`',
testFixtureStdio('test-clean-urls-custom-404', async (testPath: any) => {
await testPath(200, '/', 'This is the home page');
await testPath(200, '/about', 'The about page');
await testPath(200, '/contact/me', 'Contact Me Subdirectory');
await testPath(404, '/nothing', 'Custom 404 Page');
await testPath(404, '/nothing/', 'Custom 404 Page');
})
);
test(
'[vercel dev] test cleanUrls and trailingSlash serve correct content',
testFixtureStdio('test-clean-urls-trailing-slash', async (testPath: any) => {
await testPath(200, '/', 'Index Page');
await testPath(200, '/about/', 'About Page');
await testPath(200, '/sub/', 'Sub Index Page');
await testPath(200, '/sub/another/', 'Sub Another Page');
await testPath(200, '/style.css', 'body { color: green }');
//TODO: fix this test so that location is `/` instead of `//`
//await testPath(308, '/index.html', 'Redirecting to / (308)', { Location: '/' });
await testPath(308, '/about.html', 'Redirecting to /about/ (308)', {
Location: '/about/',
});
await testPath(308, '/sub/index.html', 'Redirecting to /sub/ (308)', {
Location: '/sub/',
});
await testPath(
308,
'/sub/another.html',
'Redirecting to /sub/another/ (308)',
{
Location: '/sub/another/',
}
);
})
);
test(
'[vercel dev] test cors headers work with OPTIONS',
testFixtureStdio('test-cors-routes', async (testPath: any) => {
const headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers':
'Content-Type, Authorization, Accept, Content-Length, Origin, User-Agent',
'Access-Control-Allow-Methods':
'GET, POST, OPTIONS, HEAD, PATCH, PUT, DELETE',
};
await testPath(200, '/', 'status api', headers, { method: 'GET' });
await testPath(200, '/', 'status api', headers, { method: 'POST' });
await testPath(200, '/api/status.js', 'status api', headers, {
method: 'GET',
});
await testPath(200, '/api/status.js', 'status api', headers, {
method: 'POST',
});
await testPath(204, '/', '', headers, { method: 'OPTIONS' });
await testPath(204, '/api/status.js', '', headers, { method: 'OPTIONS' });
})
);
test(
'[vercel dev] test trailingSlash true serve correct content',
testFixtureStdio('test-trailing-slash', async (testPath: any) => {
await testPath(200, '/', 'Index Page');
await testPath(200, '/index.html', 'Index Page');
await testPath(200, '/about.html', 'About Page');
await testPath(200, '/sub/', 'Sub Index Page');
await testPath(200, '/sub/index.html', 'Sub Index Page');
await testPath(200, '/sub/another.html', 'Sub Another Page');
await testPath(200, '/style.css', 'body { color: green }');
await testPath(308, '/about.html/', 'Redirecting to /about.html (308)', {
Location: '/about.html',
});
await testPath(308, '/style.css/', 'Redirecting to /style.css (308)', {
Location: '/style.css',
});
await testPath(308, '/sub', 'Redirecting to /sub/ (308)', {
Location: '/sub/',
});
})
);
test(
'[vercel dev] should serve custom 404 when `trailingSlash: true`',
testFixtureStdio('test-trailing-slash-custom-404', async (testPath: any) => {
await testPath(200, '/', 'This is the home page');
await testPath(200, '/about.html', 'The about page');
await testPath(200, '/contact/', 'Contact Subdirectory');
await testPath(404, '/nothing/', 'Custom 404 Page');
})
);
test(
'[vercel dev] test trailingSlash false serve correct content',
testFixtureStdio('test-trailing-slash-false', async (testPath: any) => {
await testPath(200, '/', 'Index Page');
await testPath(200, '/index.html', 'Index Page');
await testPath(200, '/about.html', 'About Page');
await testPath(200, '/sub', 'Sub Index Page');
await testPath(200, '/sub/index.html', 'Sub Index Page');
await testPath(200, '/sub/another.html', 'Sub Another Page');
await testPath(200, '/style.css', 'body { color: green }');
await testPath(308, '/about.html/', 'Redirecting to /about.html (308)', {
Location: '/about.html',
});
await testPath(308, '/sub/', 'Redirecting to /sub (308)', {
Location: '/sub',
});
await testPath(
308,
'/sub/another.html/',
'Redirecting to /sub/another.html (308)',
{
Location: '/sub/another.html',
}
);
})
);
test(
'[vercel dev] throw when invalid builder routes detected',
testFixtureStdio(
'invalid-builder-routes',
async (testPath: any) => {
await testPath(
500,
'/',
/Route at index 0 has invalid `src` regular expression/m
);
},
{ skipDeploy: true }
)
);
test(
'[vercel dev] support legacy `@now` scope runtimes',
testFixtureStdio('legacy-now-runtime', async (testPath: any) => {
await testPath(200, '/', /A simple deployment with the Vercel API!/m);
})
);
test(
'[vercel dev] 00-list-directory',
testFixtureStdio(
'00-list-directory',
async (testPath: any) => {
await testPath(200, '/', /Files within/m);
await testPath(200, '/', /test[0-3]\.txt/m);
await testPath(200, '/', /\.well-known/m);
await testPath(200, '/.well-known/keybase.txt', 'proof goes here');
},
{ projectSettings: { directoryListing: true } }
)
);
test(
'[vercel dev] 01-node',
testFixtureStdio('01-node', async (testPath: any) => {
await testPath(200, '/', /A simple deployment with the Vercel API!/m);
})
);
test(
'[vercel dev] add a `api/fn.ts` when `api` does not exist at startup`',
testFixtureStdio('no-api', async (_testPath: any, port: any) => {
const directory = fixture('no-api');
const apiDir = join(directory, 'api');
try {
{
const response = await fetch(`http://localhost:${port}/api/new-file`);
validateResponseHeaders(response);
expect(response.status).toBe(404);
}
const fileContents = `
export const config = {
runtime: 'edge'
}
export default async function edge(request, event) {
return new Response('from new file');
}
`;
await mkdirp(apiDir);
await fs.writeFile(join(apiDir, 'new-file.js'), fileContents);
// Wait until file events have been processed
await sleep(ms('1s'));
{
const response = await fetch(`http://localhost:${port}/api/new-file`);
validateResponseHeaders(response);
const body = await response.text();
expect(body.trim()).toBe('from new file');
}
} finally {
await fs.remove(apiDir);
}
})
);

View File

@@ -0,0 +1,270 @@
import { join } from 'path';
import ms from 'ms';
import fs, { mkdirp } from 'fs-extra';
const {
fetch,
fixture,
sleep,
testFixtureStdio,
validateResponseHeaders,
} = require('./utils.js');
test(
'[vercel dev] test cleanUrls serve correct content',
testFixtureStdio('test-clean-urls', async (testPath: any) => {
await testPath(200, '/', 'Index Page');
await testPath(200, '/about', 'About Page');
await testPath(200, '/sub', 'Sub Index Page');
await testPath(200, '/sub/another', 'Sub Another Page');
await testPath(200, '/style.css', 'body { color: green }');
await testPath(308, '/index.html', 'Redirecting to / (308)', {
Location: '/',
});
await testPath(308, '/about.html', 'Redirecting to /about (308)', {
Location: '/about',
});
await testPath(308, '/sub/index.html', 'Redirecting to /sub (308)', {
Location: '/sub',
});
await testPath(
308,
'/sub/another.html',
'Redirecting to /sub/another (308)',
{ Location: '/sub/another' }
);
})
);
test(
'[vercel dev] test cleanUrls serve correct content when using `outputDirectory`',
testFixtureStdio(
'test-clean-urls-with-output-directory',
async (testPath: any) => {
await testPath(200, '/', 'Index Page');
await testPath(200, '/about', 'About Page');
await testPath(200, '/sub', 'Sub Index Page');
await testPath(200, '/sub/another', 'Sub Another Page');
await testPath(200, '/style.css', 'body { color: green }');
await testPath(308, '/index.html', 'Redirecting to / (308)', {
Location: '/',
});
await testPath(308, '/about.html', 'Redirecting to /about (308)', {
Location: '/about',
});
await testPath(308, '/sub/index.html', 'Redirecting to /sub (308)', {
Location: '/sub',
});
await testPath(
308,
'/sub/another.html',
'Redirecting to /sub/another (308)',
{ Location: '/sub/another' }
);
}
)
);
test(
'[vercel dev] should serve custom 404 when `cleanUrls: true`',
testFixtureStdio('test-clean-urls-custom-404', async (testPath: any) => {
await testPath(200, '/', 'This is the home page');
await testPath(200, '/about', 'The about page');
await testPath(200, '/contact/me', 'Contact Me Subdirectory');
await testPath(404, '/nothing', 'Custom 404 Page');
await testPath(404, '/nothing/', 'Custom 404 Page');
})
);
test(
'[vercel dev] test cleanUrls and trailingSlash serve correct content',
testFixtureStdio('test-clean-urls-trailing-slash', async (testPath: any) => {
await testPath(200, '/', 'Index Page');
await testPath(200, '/about/', 'About Page');
await testPath(200, '/sub/', 'Sub Index Page');
await testPath(200, '/sub/another/', 'Sub Another Page');
await testPath(200, '/style.css', 'body { color: green }');
//TODO: fix this test so that location is `/` instead of `//`
//await testPath(308, '/index.html', 'Redirecting to / (308)', { Location: '/' });
await testPath(308, '/about.html', 'Redirecting to /about/ (308)', {
Location: '/about/',
});
await testPath(308, '/sub/index.html', 'Redirecting to /sub/ (308)', {
Location: '/sub/',
});
await testPath(
308,
'/sub/another.html',
'Redirecting to /sub/another/ (308)',
{
Location: '/sub/another/',
}
);
})
);
test(
'[vercel dev] test cors headers work with OPTIONS',
testFixtureStdio('test-cors-routes', async (testPath: any) => {
const headers = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Headers':
'Content-Type, Authorization, Accept, Content-Length, Origin, User-Agent',
'Access-Control-Allow-Methods':
'GET, POST, OPTIONS, HEAD, PATCH, PUT, DELETE',
};
await testPath(200, '/', 'status api', headers, { method: 'GET' });
await testPath(200, '/', 'status api', headers, { method: 'POST' });
await testPath(200, '/api/status.js', 'status api', headers, {
method: 'GET',
});
await testPath(200, '/api/status.js', 'status api', headers, {
method: 'POST',
});
await testPath(204, '/', '', headers, { method: 'OPTIONS' });
await testPath(204, '/api/status.js', '', headers, { method: 'OPTIONS' });
})
);
test(
'[vercel dev] test trailingSlash true serve correct content',
testFixtureStdio('test-trailing-slash', async (testPath: any) => {
await testPath(200, '/', 'Index Page');
await testPath(200, '/index.html', 'Index Page');
await testPath(200, '/about.html', 'About Page');
await testPath(200, '/sub/', 'Sub Index Page');
await testPath(200, '/sub/index.html', 'Sub Index Page');
await testPath(200, '/sub/another.html', 'Sub Another Page');
await testPath(200, '/style.css', 'body { color: green }');
await testPath(308, '/about.html/', 'Redirecting to /about.html (308)', {
Location: '/about.html',
});
await testPath(308, '/style.css/', 'Redirecting to /style.css (308)', {
Location: '/style.css',
});
await testPath(308, '/sub', 'Redirecting to /sub/ (308)', {
Location: '/sub/',
});
})
);
test(
'[vercel dev] should serve custom 404 when `trailingSlash: true`',
testFixtureStdio('test-trailing-slash-custom-404', async (testPath: any) => {
await testPath(200, '/', 'This is the home page');
await testPath(200, '/about.html', 'The about page');
await testPath(200, '/contact/', 'Contact Subdirectory');
await testPath(404, '/nothing/', 'Custom 404 Page');
})
);
test(
'[vercel dev] test trailingSlash false serve correct content',
testFixtureStdio('test-trailing-slash-false', async (testPath: any) => {
await testPath(200, '/', 'Index Page');
await testPath(200, '/index.html', 'Index Page');
await testPath(200, '/about.html', 'About Page');
await testPath(200, '/sub', 'Sub Index Page');
await testPath(200, '/sub/index.html', 'Sub Index Page');
await testPath(200, '/sub/another.html', 'Sub Another Page');
await testPath(200, '/style.css', 'body { color: green }');
await testPath(308, '/about.html/', 'Redirecting to /about.html (308)', {
Location: '/about.html',
});
await testPath(308, '/sub/', 'Redirecting to /sub (308)', {
Location: '/sub',
});
await testPath(
308,
'/sub/another.html/',
'Redirecting to /sub/another.html (308)',
{
Location: '/sub/another.html',
}
);
})
);
test(
'[vercel dev] throw when invalid builder routes detected',
testFixtureStdio(
'invalid-builder-routes',
async (testPath: any) => {
await testPath(
500,
'/',
/Route at index 0 has invalid `src` regular expression/m
);
},
{ skipDeploy: true }
)
);
test(
'[vercel dev] support legacy `@now` scope runtimes',
testFixtureStdio('legacy-now-runtime', async (testPath: any) => {
await testPath(200, '/', /A simple deployment with the Vercel API!/m);
})
);
test(
'[vercel dev] 00-list-directory',
testFixtureStdio(
'00-list-directory',
async (testPath: any) => {
await testPath(200, '/', /Files within/m);
await testPath(200, '/', /test[0-3]\.txt/m);
await testPath(200, '/', /\.well-known/m);
await testPath(200, '/.well-known/keybase.txt', 'proof goes here');
},
{ projectSettings: { directoryListing: true } }
)
);
test(
'[vercel dev] 01-node',
testFixtureStdio('01-node', async (testPath: any) => {
await testPath(200, '/', /A simple deployment with the Vercel API!/m);
})
);
test(
'[vercel dev] add a `api/fn.ts` when `api` does not exist at startup`',
testFixtureStdio('no-api', async (_testPath: any, port: any) => {
const directory = fixture('no-api');
const apiDir = join(directory, 'api');
try {
{
const response = await fetch(`http://localhost:${port}/api/new-file`);
validateResponseHeaders(response);
expect(response.status).toBe(404);
}
const fileContents = `
export const config = {
runtime: 'edge'
}
export default async function edge(request, event) {
return new Response('from new file');
}
`;
await mkdirp(apiDir);
await fs.writeFile(join(apiDir, 'new-file.js'), fileContents);
// Wait until file events have been processed
await sleep(ms('1s'));
{
const response = await fetch(`http://localhost:${port}/api/new-file`);
validateResponseHeaders(response);
const body = await response.text();
expect(body.trim()).toBe('from new file');
}
} finally {
await fs.remove(apiDir);
}
})
);

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/client", "name": "@vercel/client",
"version": "12.2.28", "version": "12.3.1",
"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",
@@ -43,8 +43,8 @@
] ]
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "workspace:5.8.0", "@vercel/build-utils": "5.9.0",
"@vercel/routing-utils": "workspace:2.1.5", "@vercel/routing-utils": "2.1.8",
"@zeit/fetch": "5.2.0", "@zeit/fetch": "5.2.0",
"async-retry": "1.2.3", "async-retry": "1.2.3",
"async-sema": "3.0.0", "async-sema": "3.0.0",

View File

@@ -1,6 +1,6 @@
import sleep from 'sleep-promise'; import sleep from 'sleep-promise';
import ms from 'ms';
import { fetch, getApiDeploymentsUrl } from './utils'; import { fetch, getApiDeploymentsUrl } from './utils';
import { getPollingDelay } from './utils/get-polling-delay';
import { import {
isDone, isDone,
isReady, isReady,
@@ -47,6 +47,7 @@ export async function* checkDeploymentStatus(
// Build polling // Build polling
debug('Waiting for builds and the deployment to complete...'); debug('Waiting for builds and the deployment to complete...');
const finishedEvents = new Set(); const finishedEvents = new Set();
const startTime = Date.now();
while (true) { while (true) {
// Deployment polling // Deployment polling
@@ -155,6 +156,8 @@ export async function* checkDeploymentStatus(
}; };
} }
await sleep(ms('1.5s')); const elapsed = Date.now() - startTime;
const duration = getPollingDelay(elapsed);
await sleep(duration);
} }
} }

View File

@@ -73,7 +73,7 @@ export default function buildCreateDeployment() {
debug(`Provided 'path' is a single file`); debug(`Provided 'path' is a single file`);
} }
let { fileList } = await buildFileTree(path, clientOptions, debug); const { fileList } = await buildFileTree(path, clientOptions, debug);
// This is a useful warning because it prevents people // This is a useful warning because it prevents people
// from getting confused about a deployment that renders 404. // from getting confused about a deployment that renders 404.

View File

@@ -1,4 +1,4 @@
import { DeploymentFile } from './utils/hashes'; import { FilesMap } from './utils/hashes';
import { generateQueryString } from './utils/query-string'; import { generateQueryString } from './utils/query-string';
import { isReady, isAliasAssigned } from './utils/ready-state'; import { isReady, isAliasAssigned } from './utils/ready-state';
import { checkDeploymentStatus } from './check-deployment-status'; import { checkDeploymentStatus } from './check-deployment-status';
@@ -16,7 +16,7 @@ import {
} from './types'; } from './types';
async function* postDeployment( async function* postDeployment(
files: Map<string, DeploymentFile>, files: FilesMap,
clientOptions: VercelClientOptions, clientOptions: VercelClientOptions,
deploymentOptions: DeploymentOptions deploymentOptions: DeploymentOptions
): AsyncIterableIterator<{ ): AsyncIterableIterator<{
@@ -90,7 +90,7 @@ async function* postDeployment(
} }
function getDefaultName( function getDefaultName(
files: Map<string, DeploymentFile>, files: FilesMap,
clientOptions: VercelClientOptions clientOptions: VercelClientOptions
): string { ): string {
const debug = createDebug(clientOptions.debug); const debug = createDebug(clientOptions.debug);
@@ -109,7 +109,7 @@ function getDefaultName(
} }
export async function* deploy( export async function* deploy(
files: Map<string, DeploymentFile>, files: FilesMap,
clientOptions: VercelClientOptions, clientOptions: VercelClientOptions,
deploymentOptions: DeploymentOptions deploymentOptions: DeploymentOptions
): AsyncIterableIterator<{ type: string; payload: any }> { ): AsyncIterableIterator<{ type: string; payload: any }> {

View File

@@ -5,7 +5,7 @@ import { EventEmitter } from 'events';
import retry from 'async-retry'; import retry from 'async-retry';
import { Sema } from 'async-sema'; import { Sema } from 'async-sema';
import { DeploymentFile } from './utils/hashes'; import { DeploymentFile, FilesMap } from './utils/hashes';
import { fetch, API_FILES, createDebug } from './utils'; import { fetch, API_FILES, createDebug } from './utils';
import { DeploymentError } from './errors'; import { DeploymentError } from './errors';
import { deploy } from './deploy'; import { deploy } from './deploy';
@@ -29,7 +29,7 @@ const isClientNetworkError = (err: Error) => {
}; };
export async function* upload( export async function* upload(
files: Map<string, DeploymentFile>, files: FilesMap,
clientOptions: VercelClientOptions, clientOptions: VercelClientOptions,
deploymentOptions: DeploymentOptions deploymentOptions: DeploymentOptions
): AsyncIterableIterator<any> { ): AsyncIterableIterator<any> {
@@ -98,6 +98,10 @@ export async function* upload(
await semaphore.acquire(); await semaphore.acquire();
const { data } = file; const { data } = file;
if (typeof data === 'undefined') {
// Directories don't need to be uploaded
return;
}
uploadProgress.bytesUploaded = 0; uploadProgress.bytesUploaded = 0;

View File

@@ -0,0 +1,14 @@
import ms from 'ms';
export function getPollingDelay(elapsed: number): number {
if (elapsed <= ms('15s')) {
return ms('1s');
}
if (elapsed <= ms('1m')) {
return ms('5s');
}
if (elapsed <= ms('5m')) {
return ms('15s');
}
return ms('30s');
}

View File

@@ -4,10 +4,12 @@ import { Sema } from 'async-sema';
export interface DeploymentFile { export interface DeploymentFile {
names: string[]; names: string[];
data: Buffer; data?: Buffer;
mode: number; mode: number;
} }
export type FilesMap = Map<string | undefined, DeploymentFile>;
/** /**
* Computes a hash for the given buf. * Computes a hash for the given buf.
* *
@@ -23,14 +25,12 @@ export function hash(buf: Buffer): string {
* @param map with hashed files * @param map with hashed files
* @return {object} * @return {object}
*/ */
export const mapToObject = ( export const mapToObject = (map: FilesMap): Record<string, DeploymentFile> => {
map: Map<string, DeploymentFile>
): { [key: string]: DeploymentFile } => {
const obj: { [key: string]: DeploymentFile } = {}; const obj: { [key: string]: DeploymentFile } = {};
for (const [key, value] of map) { for (const [key, value] of map) {
if (typeof key === 'undefined') continue;
obj[key] = value; obj[key] = value;
} }
return obj; return obj;
}; };
@@ -43,8 +43,8 @@ export const mapToObject = (
*/ */
export async function hashes( export async function hashes(
files: string[], files: string[],
map = new Map<string, DeploymentFile>() map = new Map<string | undefined, DeploymentFile>()
): Promise<Map<string, DeploymentFile>> { ): Promise<FilesMap> {
const semaphore = new Sema(100); const semaphore = new Sema(100);
await Promise.all( await Promise.all(
@@ -54,15 +54,21 @@ export async function hashes(
const stat = await fs.lstat(name); const stat = await fs.lstat(name);
const mode = stat.mode; const mode = stat.mode;
let data: Buffer | null = null; let data: Buffer | undefined;
if (stat.isSymbolicLink()) { const isDirectory = stat.isDirectory();
const link = await fs.readlink(name);
data = Buffer.from(link, 'utf8'); let h: string | undefined;
} else {
data = await fs.readFile(name); if (!isDirectory) {
if (stat.isSymbolicLink()) {
const link = await fs.readlink(name);
data = Buffer.from(link, 'utf8');
} else {
data = await fs.readFile(name);
}
h = hash(data);
} }
const h = hash(data);
const entry = map.get(h); const entry = map.get(h);
if (entry) { if (entry) {

View File

@@ -1,4 +1,4 @@
import { DeploymentFile } from './hashes'; import { FilesMap } from './hashes';
import { FetchOptions } from '@zeit/fetch'; import { FetchOptions } from '@zeit/fetch';
import { nodeFetch, zeitFetch } from './fetch'; import { nodeFetch, zeitFetch } from './fetch';
import { join, sep, relative } from 'path'; import { join, sep, relative } from 'path';
@@ -256,15 +256,15 @@ export const fetch = async (
export interface PreparedFile { export interface PreparedFile {
file: string; file: string;
sha: string; sha?: string;
size: number; size?: number;
mode: number; mode: number;
} }
const isWin = process.platform.includes('win'); const isWin = process.platform.includes('win');
export const prepareFiles = ( export const prepareFiles = (
files: Map<string, DeploymentFile>, files: FilesMap,
clientOptions: VercelClientOptions clientOptions: VercelClientOptions
): PreparedFile[] => { ): PreparedFile[] => {
const preparedFiles: PreparedFile[] = []; const preparedFiles: PreparedFile[] = [];
@@ -286,9 +286,9 @@ export const prepareFiles = (
preparedFiles.push({ preparedFiles.push({
file: isWin ? fileName.replace(/\\/g, '/') : fileName, file: isWin ? fileName.replace(/\\/g, '/') : fileName,
size: file.data.byteLength || file.data.length, size: file.data?.byteLength || file.data?.length,
mode: file.mode, mode: file.mode,
sha, sha: sha || undefined,
}); });
} }
} }

View File

@@ -87,6 +87,10 @@ export default function readdir(
if (stats.isDirectory()) { if (stats.isDirectory()) {
readdir(filePath, ignores) readdir(filePath, ignores)
.then(function (res) { .then(function (res) {
if (res.length === 0) {
// Empty directories get returned
list.push(filePath);
}
list = list.concat(res); list = list.concat(res);
pending -= 1; pending -= 1;
if (!pending) { if (!pending) {

View File

@@ -0,0 +1,41 @@
import { getPollingDelay } from '../src/utils/get-polling-delay';
describe('getPollingDelay()', () => {
it('should return 1 second', async () => {
expect(getPollingDelay(0)).toBe(1000);
expect(getPollingDelay(1000)).toBe(1000);
expect(getPollingDelay(3000)).toBe(1000);
expect(getPollingDelay(5000)).toBe(1000);
expect(getPollingDelay(8000)).toBe(1000);
expect(getPollingDelay(9000)).toBe(1000);
expect(getPollingDelay(10000)).toBe(1000);
expect(getPollingDelay(13000)).toBe(1000);
expect(getPollingDelay(15000)).toBe(1000);
});
it('should return 5 second', async () => {
expect(getPollingDelay(15001)).toBe(5000);
expect(getPollingDelay(16000)).toBe(5000);
expect(getPollingDelay(23000)).toBe(5000);
expect(getPollingDelay(36000)).toBe(5000);
expect(getPollingDelay(59000)).toBe(5000);
expect(getPollingDelay(60000)).toBe(5000);
});
it('should return 15 second', async () => {
expect(getPollingDelay(60001)).toBe(15000);
expect(getPollingDelay(80000)).toBe(15000);
expect(getPollingDelay(100000)).toBe(15000);
expect(getPollingDelay(200000)).toBe(15000);
expect(getPollingDelay(250000)).toBe(15000);
expect(getPollingDelay(300000)).toBe(15000);
});
it('should return 30 second', async () => {
expect(getPollingDelay(300001)).toBe(30000);
expect(getPollingDelay(400000)).toBe(30000);
expect(getPollingDelay(1400000)).toBe(30000);
expect(getPollingDelay(9400000)).toBe(30000);
expect(getPollingDelay(99400000)).toBe(30000);
});
});

View File

@@ -24,7 +24,11 @@ describe('buildFileTree()', () => {
noop noop
); );
const expectedFileList = toAbsolutePaths(cwd, ['.nowignore', 'index.txt']); const expectedFileList = toAbsolutePaths(cwd, [
'.nowignore',
'folder',
'index.txt',
]);
expect(normalizeWindowsPaths(expectedFileList).sort()).toEqual( expect(normalizeWindowsPaths(expectedFileList).sort()).toEqual(
normalizeWindowsPaths(fileList).sort() normalizeWindowsPaths(fileList).sort()
); );
@@ -41,9 +45,14 @@ describe('buildFileTree()', () => {
it('should include symlinked files and directories', async () => { it('should include symlinked files and directories', async () => {
const cwd = fixture('symlinks'); const cwd = fixture('symlinks');
// Also add an empty directory to make sure it's included
await fs.mkdirp(join(cwd, 'empty'));
const { fileList } = await buildFileTree(cwd, { isDirectory: true }, noop); const { fileList } = await buildFileTree(cwd, { isDirectory: true }, noop);
const expectedFileList = toAbsolutePaths(cwd, [ const expectedFileList = toAbsolutePaths(cwd, [
'empty',
'folder-link', 'folder-link',
'folder/text.txt', 'folder/text.txt',
'index.txt', 'index.txt',

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/edge", "name": "@vercel/edge",
"version": "0.2.3", "version": "0.2.6",
"license": "MIT", "license": "MIT",
"main": "dist/index.js", "main": "dist/index.js",
"module": "dist/index.mjs", "module": "dist/index.mjs",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/error-utils", "name": "@vercel/error-utils",
"version": "1.0.5", "version": "1.0.8",
"description": "A collection of error utilities for vercel/vercel", "description": "A collection of error utilities for vercel/vercel",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/frameworks", "name": "@vercel/frameworks",
"version": "1.2.1", "version": "1.2.4",
"main": "./dist/frameworks.js", "main": "./dist/frameworks.js",
"types": "./dist/frameworks.d.ts", "types": "./dist/frameworks.d.ts",
"files": [ "files": [
@@ -21,7 +21,7 @@
"@types/js-yaml": "3.12.1", "@types/js-yaml": "3.12.1",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@types/node-fetch": "2.5.8", "@types/node-fetch": "2.5.8",
"@vercel/routing-utils": "workspace:2.1.5", "@vercel/routing-utils": "2.1.8",
"ajv": "6.12.2", "ajv": "6.12.2",
"typescript": "4.3.4" "typescript": "4.3.4"
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/fs-detectors", "name": "@vercel/fs-detectors",
"version": "3.7.1", "version": "3.7.5",
"description": "Vercel filesystem detectors", "description": "Vercel filesystem detectors",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -19,9 +19,9 @@
"test-unit": "pnpm test" "test-unit": "pnpm test"
}, },
"dependencies": { "dependencies": {
"@vercel/error-utils": "workspace:1.0.5", "@vercel/error-utils": "1.0.8",
"@vercel/frameworks": "workspace:1.2.1", "@vercel/frameworks": "1.2.4",
"@vercel/routing-utils": "workspace:2.1.5", "@vercel/routing-utils": "2.1.8",
"glob": "8.0.3", "glob": "8.0.3",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
"json5": "2.2.2", "json5": "2.2.2",
@@ -35,7 +35,7 @@
"@types/minimatch": "3.0.5", "@types/minimatch": "3.0.5",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@types/semver": "7.3.10", "@types/semver": "7.3.10",
"@vercel/build-utils": "workspace:5.8.0", "@vercel/build-utils": "5.9.0",
"typescript": "4.3.4" "typescript": "4.3.4"
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/gatsby-plugin-vercel-analytics", "name": "@vercel/gatsby-plugin-vercel-analytics",
"version": "1.0.3", "version": "1.0.6",
"description": "Track Core Web Vitals in Gatsby projects with Vercel Analytics.", "description": "Track Core Web Vitals in Gatsby projects with Vercel Analytics.",
"main": "index.js", "main": "index.js",
"files": [ "files": [

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/go", "name": "@vercel/go",
"version": "2.2.26", "version": "2.2.30",
"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",
@@ -36,7 +36,7 @@
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@types/node-fetch": "^2.3.0", "@types/node-fetch": "^2.3.0",
"@types/tar": "^4.0.0", "@types/tar": "^4.0.0",
"@vercel/build-utils": "workspace:5.8.0", "@vercel/build-utils": "5.9.0",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"async-retry": "1.3.1", "async-retry": "1.3.1",
"execa": "^1.0.0", "execa": "^1.0.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/hydrogen", "name": "@vercel/hydrogen",
"version": "0.0.40", "version": "0.0.44",
"license": "MIT", "license": "MIT",
"main": "./dist/index.js", "main": "./dist/index.js",
"homepage": "https://vercel.com/docs", "homepage": "https://vercel.com/docs",
@@ -21,8 +21,8 @@
"devDependencies": { "devDependencies": {
"@types/jest": "27.5.1", "@types/jest": "27.5.1",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@vercel/build-utils": "workspace:5.8.0", "@vercel/build-utils": "5.9.0",
"@vercel/static-config": "workspace:2.0.8", "@vercel/static-config": "2.0.11",
"execa": "3.2.0", "execa": "3.2.0",
"fs-extra": "11.1.0", "fs-extra": "11.1.0",
"ts-morph": "12.0.0", "ts-morph": "12.0.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/next", "name": "@vercel/next",
"version": "3.3.11", "version": "3.3.15",
"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",
@@ -45,9 +45,9 @@
"@types/semver": "6.0.0", "@types/semver": "6.0.0",
"@types/text-table": "0.2.1", "@types/text-table": "0.2.1",
"@types/webpack-sources": "3.2.0", "@types/webpack-sources": "3.2.0",
"@vercel/build-utils": "workspace:5.8.0", "@vercel/build-utils": "5.9.0",
"@vercel/nft": "0.22.5", "@vercel/nft": "0.22.5",
"@vercel/routing-utils": "workspace:2.1.5", "@vercel/routing-utils": "2.1.8",
"async-sema": "3.0.1", "async-sema": "3.0.1",
"buffer-crc32": "0.2.13", "buffer-crc32": "0.2.13",
"bytes": "3.1.2", "bytes": "3.1.2",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/node-bridge", "name": "@vercel/node-bridge",
"version": "3.1.5", "version": "3.1.9",
"license": "MIT", "license": "MIT",
"main": "./index.js", "main": "./index.js",
"repository": { "repository": {
@@ -23,6 +23,9 @@
"devDependencies": { "devDependencies": {
"@types/aws-lambda": "8.10.19", "@types/aws-lambda": "8.10.19",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"content-type": "1.0.4",
"cookie": "0.4.0",
"etag": "1.8.1",
"execa": "3.2.0", "execa": "3.2.0",
"fs-extra": "10.0.0", "fs-extra": "10.0.0",
"jsonlines": "0.1.1", "jsonlines": "0.1.1",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/node", "name": "@vercel/node",
"version": "2.8.8", "version": "2.8.13",
"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",
@@ -31,9 +31,9 @@
"dependencies": { "dependencies": {
"@edge-runtime/vm": "2.0.0", "@edge-runtime/vm": "2.0.0",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@vercel/build-utils": "workspace:5.8.0", "@vercel/build-utils": "5.9.0",
"@vercel/node-bridge": "workspace:3.1.5", "@vercel/node-bridge": "3.1.9",
"@vercel/static-config": "workspace:2.0.8", "@vercel/static-config": "2.0.11",
"edge-runtime": "2.0.0", "edge-runtime": "2.0.0",
"esbuild": "0.14.47", "esbuild": "0.14.47",
"exit-hook": "2.2.1", "exit-hook": "2.2.1",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/python", "name": "@vercel/python",
"version": "3.1.36", "version": "3.1.40",
"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",
@@ -23,7 +23,7 @@
"@types/execa": "^0.9.0", "@types/execa": "^0.9.0",
"@types/jest": "27.4.1", "@types/jest": "27.4.1",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@vercel/build-utils": "workspace:5.8.0", "@vercel/build-utils": "5.9.0",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"execa": "^1.0.0", "execa": "^1.0.0",
"typescript": "4.3.4" "typescript": "4.3.4"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/redwood", "name": "@vercel/redwood",
"version": "1.0.47", "version": "1.0.51",
"main": "./dist/index.js", "main": "./dist/index.js",
"license": "MIT", "license": "MIT",
"homepage": "https://vercel.com/docs", "homepage": "https://vercel.com/docs",
@@ -20,14 +20,14 @@
}, },
"dependencies": { "dependencies": {
"@vercel/nft": "0.22.5", "@vercel/nft": "0.22.5",
"@vercel/routing-utils": "workspace:2.1.5", "@vercel/routing-utils": "2.1.8",
"semver": "6.1.1" "semver": "6.1.1"
}, },
"devDependencies": { "devDependencies": {
"@types/aws-lambda": "8.10.19", "@types/aws-lambda": "8.10.19",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@types/semver": "6.0.0", "@types/semver": "6.0.0",
"@vercel/build-utils": "workspace:5.8.0", "@vercel/build-utils": "5.9.0",
"execa": "3.2.0", "execa": "3.2.0",
"fs-extra": "11.1.0", "fs-extra": "11.1.0",
"typescript": "4.3.4" "typescript": "4.3.4"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/remix", "name": "@vercel/remix",
"version": "1.2.1", "version": "1.2.5",
"license": "MIT", "license": "MIT",
"main": "./dist/index.js", "main": "./dist/index.js",
"homepage": "https://vercel.com/docs", "homepage": "https://vercel.com/docs",
@@ -25,7 +25,7 @@
"devDependencies": { "devDependencies": {
"@types/jest": "27.5.1", "@types/jest": "27.5.1",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@vercel/build-utils": "workspace:5.8.0", "@vercel/build-utils": "5.9.0",
"typescript": "4.6.4" "typescript": "4.6.4"
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/routing-utils", "name": "@vercel/routing-utils",
"version": "2.1.5", "version": "2.1.8",
"description": "Vercel routing utilities", "description": "Vercel routing utilities",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",

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.3.52", "version": "1.3.56",
"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",
@@ -22,7 +22,7 @@
"devDependencies": { "devDependencies": {
"@types/fs-extra": "8.0.0", "@types/fs-extra": "8.0.0",
"@types/semver": "6.0.0", "@types/semver": "6.0.0",
"@vercel/build-utils": "workspace:5.8.0", "@vercel/build-utils": "5.9.0",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"execa": "2.0.4", "execa": "2.0.4",
"fs-extra": "^7.0.1", "fs-extra": "^7.0.1",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/static-build", "name": "@vercel/static-build",
"version": "1.1.3", "version": "1.1.7",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/build-step", "homepage": "https://vercel.com/docs/build-step",
@@ -37,11 +37,11 @@
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@types/node-fetch": "2.5.4", "@types/node-fetch": "2.5.4",
"@types/promise-timeout": "1.3.0", "@types/promise-timeout": "1.3.0",
"@vercel/build-utils": "workspace:5.8.0", "@vercel/build-utils": "5.9.0",
"@vercel/frameworks": "workspace:1.2.1", "@vercel/frameworks": "1.2.4",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "workspace:2.1.5", "@vercel/routing-utils": "2.1.8",
"@vercel/static-config": "workspace:2.0.8", "@vercel/static-config": "2.0.11",
"execa": "3.2.0", "execa": "3.2.0",
"fs-extra": "10.0.0", "fs-extra": "10.0.0",
"get-port": "5.0.0", "get-port": "5.0.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/static-config", "name": "@vercel/static-config",
"version": "2.0.8", "version": "2.0.11",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"repository": { "repository": {

90
pnpm-lock.yaml generated
View File

@@ -7,9 +7,9 @@ importers:
'@types/node': 14.18.33 '@types/node': 14.18.33
'@typescript-eslint/eslint-plugin': 5.21.0 '@typescript-eslint/eslint-plugin': 5.21.0
'@typescript-eslint/parser': 5.21.0 '@typescript-eslint/parser': 5.21.0
'@vercel/build-utils': workspace:* '@vercel/build-utils': '*'
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
'@vercel/next': workspace:* '@vercel/next': '*'
async-retry: 1.2.3 async-retry: 1.2.3
buffer-replace: 1.0.0 buffer-replace: 1.0.0
create-svelte: 2.0.1 create-svelte: 2.0.1
@@ -66,7 +66,7 @@ importers:
'@sentry/node': 5.11.1 '@sentry/node': 5.11.1
'@types/node': 16.18.11 '@types/node': 16.18.11
'@types/node-fetch': 2.5.4 '@types/node-fetch': 2.5.4
'@vercel/node': workspace:* '@vercel/node': '*'
got: 10.2.1 got: 10.2.1
node-fetch: 2.6.7 node-fetch: 2.6.7
parse-github-url: 1.0.2 parse-github-url: 1.0.2
@@ -198,23 +198,23 @@ importers:
'@types/which': 1.3.2 '@types/which': 1.3.2
'@types/write-json-file': 2.2.1 '@types/write-json-file': 2.2.1
'@types/yauzl-promise': 2.1.0 '@types/yauzl-promise': 2.1.0
'@vercel/build-utils': workspace:5.7.6 '@vercel/build-utils': 5.9.0
'@vercel/client': workspace:12.2.27 '@vercel/client': 12.3.1
'@vercel/error-utils': workspace:1.0.4 '@vercel/error-utils': 1.0.8
'@vercel/frameworks': workspace:1.2.0 '@vercel/frameworks': 1.2.4
'@vercel/fs-detectors': workspace:3.7.0 '@vercel/fs-detectors': 3.7.5
'@vercel/fun': 1.0.4 '@vercel/fun': 1.0.4
'@vercel/go': workspace:2.2.25 '@vercel/go': 2.2.30
'@vercel/hydrogen': workspace:0.0.39 '@vercel/hydrogen': 0.0.44
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
'@vercel/next': workspace:3.3.10 '@vercel/next': 3.3.15
'@vercel/node': workspace:2.8.7 '@vercel/node': 2.8.13
'@vercel/python': workspace:3.1.35 '@vercel/python': 3.1.40
'@vercel/redwood': workspace:1.0.46 '@vercel/redwood': 1.0.51
'@vercel/remix': workspace:1.2.0 '@vercel/remix': 1.2.5
'@vercel/routing-utils': workspace:2.1.4 '@vercel/routing-utils': 2.1.8
'@vercel/ruby': workspace:1.3.51 '@vercel/ruby': 1.3.56
'@vercel/static-build': workspace:1.1.2 '@vercel/static-build': 1.1.7
'@zeit/source-map-support': 0.6.2 '@zeit/source-map-support': 0.6.2
ajv: 6.12.2 ajv: 6.12.2
alpha-sort: 2.0.1 alpha-sort: 2.0.1
@@ -440,8 +440,8 @@ importers:
'@types/node-fetch': 2.5.4 '@types/node-fetch': 2.5.4
'@types/recursive-readdir': 2.2.0 '@types/recursive-readdir': 2.2.0
'@types/tar-fs': 1.16.1 '@types/tar-fs': 1.16.1
'@vercel/build-utils': workspace:5.7.6 '@vercel/build-utils': 5.9.0
'@vercel/routing-utils': workspace:2.1.4 '@vercel/routing-utils': 2.1.8
'@zeit/fetch': 5.2.0 '@zeit/fetch': 5.2.0
async-retry: 1.2.3 async-retry: 1.2.3
async-sema: 3.0.0 async-sema: 3.0.0
@@ -521,7 +521,7 @@ importers:
'@types/js-yaml': 3.12.1 '@types/js-yaml': 3.12.1
'@types/node': 14.18.33 '@types/node': 14.18.33
'@types/node-fetch': 2.5.8 '@types/node-fetch': 2.5.8
'@vercel/routing-utils': workspace:2.1.4 '@vercel/routing-utils': 2.1.8
ajv: 6.12.2 ajv: 6.12.2
js-yaml: 3.13.1 js-yaml: 3.13.1
typescript: 4.3.4 typescript: 4.3.4
@@ -545,10 +545,10 @@ importers:
'@types/minimatch': 3.0.5 '@types/minimatch': 3.0.5
'@types/node': 14.18.33 '@types/node': 14.18.33
'@types/semver': 7.3.10 '@types/semver': 7.3.10
'@vercel/build-utils': workspace:5.7.6 '@vercel/build-utils': 5.9.0
'@vercel/error-utils': workspace:1.0.4 '@vercel/error-utils': 1.0.8
'@vercel/frameworks': workspace:1.2.0 '@vercel/frameworks': 1.2.4
'@vercel/routing-utils': workspace:2.1.4 '@vercel/routing-utils': 2.1.8
glob: 8.0.3 glob: 8.0.3
js-yaml: 4.1.0 js-yaml: 4.1.0
json5: 2.2.2 json5: 2.2.2
@@ -592,7 +592,7 @@ importers:
'@types/node': 14.18.33 '@types/node': 14.18.33
'@types/node-fetch': ^2.3.0 '@types/node-fetch': ^2.3.0
'@types/tar': ^4.0.0 '@types/tar': ^4.0.0
'@vercel/build-utils': workspace:5.7.6 '@vercel/build-utils': 5.9.0
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
async-retry: 1.3.1 async-retry: 1.3.1
execa: ^1.0.0 execa: ^1.0.0
@@ -624,8 +624,8 @@ importers:
specifiers: specifiers:
'@types/jest': 27.5.1 '@types/jest': 27.5.1
'@types/node': 14.18.33 '@types/node': 14.18.33
'@vercel/build-utils': workspace:5.7.6 '@vercel/build-utils': 5.9.0
'@vercel/static-config': workspace:2.0.7 '@vercel/static-config': 2.0.11
execa: 3.2.0 execa: 3.2.0
fs-extra: 11.1.0 fs-extra: 11.1.0
ts-morph: 12.0.0 ts-morph: 12.0.0
@@ -655,9 +655,9 @@ importers:
'@types/semver': 6.0.0 '@types/semver': 6.0.0
'@types/text-table': 0.2.1 '@types/text-table': 0.2.1
'@types/webpack-sources': 3.2.0 '@types/webpack-sources': 3.2.0
'@vercel/build-utils': workspace:5.7.6 '@vercel/build-utils': 5.9.0
'@vercel/nft': 0.22.5 '@vercel/nft': 0.22.5
'@vercel/routing-utils': workspace:2.1.4 '@vercel/routing-utils': 2.1.8
async-sema: 3.0.1 async-sema: 3.0.1
buffer-crc32: 0.2.13 buffer-crc32: 0.2.13
bytes: 3.1.2 bytes: 3.1.2
@@ -734,11 +734,11 @@ importers:
'@types/node': 14.18.33 '@types/node': 14.18.33
'@types/node-fetch': ^2.6.1 '@types/node-fetch': ^2.6.1
'@types/test-listen': 1.1.0 '@types/test-listen': 1.1.0
'@vercel/build-utils': workspace:5.7.6 '@vercel/build-utils': 5.9.0
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
'@vercel/nft': 0.22.5 '@vercel/nft': 0.22.5
'@vercel/node-bridge': workspace:3.1.4 '@vercel/node-bridge': 3.1.9
'@vercel/static-config': workspace:2.0.7 '@vercel/static-config': 2.0.11
content-type: 1.0.4 content-type: 1.0.4
cookie: 0.4.0 cookie: 0.4.0
edge-runtime: 2.0.0 edge-runtime: 2.0.0
@@ -793,6 +793,9 @@ importers:
specifiers: specifiers:
'@types/aws-lambda': 8.10.19 '@types/aws-lambda': 8.10.19
'@types/node': 14.18.33 '@types/node': 14.18.33
content-type: 1.0.4
cookie: 0.4.0
etag: 1.8.1
execa: 3.2.0 execa: 3.2.0
fs-extra: 10.0.0 fs-extra: 10.0.0
jsonlines: 0.1.1 jsonlines: 0.1.1
@@ -801,6 +804,9 @@ importers:
devDependencies: devDependencies:
'@types/aws-lambda': 8.10.19 '@types/aws-lambda': 8.10.19
'@types/node': 14.18.33 '@types/node': 14.18.33
content-type: 1.0.4
cookie: 0.4.0
etag: 1.8.1
execa: 3.2.0 execa: 3.2.0
fs-extra: 10.0.0 fs-extra: 10.0.0
jsonlines: 0.1.1 jsonlines: 0.1.1
@@ -812,7 +818,7 @@ importers:
'@types/execa': ^0.9.0 '@types/execa': ^0.9.0
'@types/jest': 27.4.1 '@types/jest': 27.4.1
'@types/node': 14.18.33 '@types/node': 14.18.33
'@vercel/build-utils': workspace:5.7.6 '@vercel/build-utils': 5.9.0
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
execa: ^1.0.0 execa: ^1.0.0
typescript: 4.3.4 typescript: 4.3.4
@@ -830,9 +836,9 @@ importers:
'@types/aws-lambda': 8.10.19 '@types/aws-lambda': 8.10.19
'@types/node': 14.18.33 '@types/node': 14.18.33
'@types/semver': 6.0.0 '@types/semver': 6.0.0
'@vercel/build-utils': workspace:5.7.6 '@vercel/build-utils': 5.9.0
'@vercel/nft': 0.22.5 '@vercel/nft': 0.22.5
'@vercel/routing-utils': workspace:2.1.4 '@vercel/routing-utils': 2.1.8
execa: 3.2.0 execa: 3.2.0
fs-extra: 11.1.0 fs-extra: 11.1.0
semver: 6.1.1 semver: 6.1.1
@@ -854,7 +860,7 @@ importers:
specifiers: specifiers:
'@types/jest': 27.5.1 '@types/jest': 27.5.1
'@types/node': 14.18.33 '@types/node': 14.18.33
'@vercel/build-utils': workspace:5.7.6 '@vercel/build-utils': 5.9.0
'@vercel/nft': 0.22.5 '@vercel/nft': 0.22.5
typescript: 4.6.4 typescript: 4.6.4
dependencies: dependencies:
@@ -885,7 +891,7 @@ importers:
specifiers: specifiers:
'@types/fs-extra': 8.0.0 '@types/fs-extra': 8.0.0
'@types/semver': 6.0.0 '@types/semver': 6.0.0
'@vercel/build-utils': workspace:5.7.6 '@vercel/build-utils': 5.9.0
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
execa: 2.0.4 execa: 2.0.4
fs-extra: ^7.0.1 fs-extra: ^7.0.1
@@ -911,11 +917,11 @@ importers:
'@types/node': 14.18.33 '@types/node': 14.18.33
'@types/node-fetch': 2.5.4 '@types/node-fetch': 2.5.4
'@types/promise-timeout': 1.3.0 '@types/promise-timeout': 1.3.0
'@vercel/build-utils': workspace:5.7.6 '@vercel/build-utils': 5.9.0
'@vercel/frameworks': workspace:1.2.0 '@vercel/frameworks': 1.2.4
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
'@vercel/routing-utils': workspace:2.1.4 '@vercel/routing-utils': 2.1.8
'@vercel/static-config': workspace:2.0.7 '@vercel/static-config': 2.0.11
execa: 3.2.0 execa: 3.2.0
fs-extra: 10.0.0 fs-extra: 10.0.0
get-port: 5.0.0 get-port: 5.0.0

2
utils/changelog.js vendored
View File

@@ -105,7 +105,7 @@ async function main() {
const pub = Array.from(pkgs).join(','); const pub = Array.from(pkgs).join(',');
console.log('To publish a stable release, execute the following:'); console.log('To publish a stable release, execute the following:');
console.log( console.log(
`\nnpx lerna version --message "Publish Stable" --exact --force-publish=${pub}\n` `\npnpx lerna version --message "Publish Stable" --exact --no-private --force-publish=${pub}\n`
); );
} }

3
utils/publish.sh vendored
View File

@@ -29,9 +29,6 @@ else
echo "Publishing stable release" echo "Publishing stable release"
fi fi
# Sometimes this is a false alarm and blocks publish
git checkout pnpm-lock.yaml
pnpm run lerna publish from-git $dist_tag --no-verify-access --yes pnpm run lerna publish from-git $dist_tag --no-verify-access --yes
# always update canary dist-tag as we no longer publish canary versions separate # always update canary dist-tag as we no longer publish canary versions separate