Compare commits

..

21 Commits

Author SHA1 Message Date
Steven
94ab2512e9 Publish Canary
- vercel@19.1.2-canary.2
 - @vercel/ruby@1.2.3-canary.0
2020-06-18 17:19:29 -04:00
Jared White
da3207278e [ruby] Fix for UTF-8 responses in Ruby functions (#4593)
There's an unexpected string encoding issue with `Net::HTTP`, so this is a workaround. Further details:
https://bugs.ruby-lang.org/issues/15517

Co-authored-by: Steven <steven@ceriously.com>
2020-06-18 17:12:28 -04:00
nkzawa
8e10a82b43 Publish Canary
- vercel@19.1.2-canary.1
2020-06-18 20:24:49 +09:00
Naoyuki Kanezawa
d7731d191b Fix to not render no token error, prompt login instead (#4659)
When `auth.json` exists but no `token` property exists in it, we currently render error like the following screenshot.
<img width="488" alt="Screen Shot 2020-06-15 at 21 32 55" src="https://user-images.githubusercontent.com/775227/84657782-cd4eeb80-af4f-11ea-901d-2ad4b52b6667.png">

This PR fixes to prompt login instead.
<img width="994" alt="Screen Shot 2020-06-15 at 21 28 09" src="https://user-images.githubusercontent.com/775227/84657706-aa243c00-af4f-11ea-915e-4ada7de9c467.png">
2020-06-17 17:20:08 +00:00
Steven
0f5f99e667 Publish Canary
- vercel@19.1.2-canary.0
 - @vercel/next@2.6.8-canary.0
 - @vercel/node@1.7.2-canary.0
2020-06-16 17:41:45 -04:00
Steven
93a7831943 [node][next] Bump node-file-trace to 0.6.5 (#4667)
Bump `node-file-trace` to version [0.6.5](https://github.com/vercel/node-file-trace/releases/tag/0.6.5) to fix a webpack wrappers bug
2020-06-16 21:41:13 +00:00
Steven
0eacbeae11 Publish Stable
- vercel@19.1.1
 - @vercel/next@2.6.7
 - @vercel/node@1.7.1
 - @vercel/static-build@0.17.3
2020-06-16 13:09:42 -04:00
Steven
e50417dc47 Publish Canary
- vercel@19.1.1-canary.4
 - @vercel/static-build@0.17.3-canary.0
2020-06-16 08:55:29 -04:00
Paco
4840a25d30 [static-build] Apply Gatsby default caching routes automatically (#4645)
CH-702
Fixes #3331

If the file generated by `gatsby-plugin-now` does not exist, we'll set up these routes automatically.
2020-06-15 22:15:14 +00:00
Steven
785e91979d Publish Canary
- vercel@19.1.1-canary.3
 - @vercel/next@2.6.7-canary.1
 - @vercel/node@1.7.1-canary.1
2020-06-15 16:46:03 -04:00
Steven
7a776c54b8 [node][next] Bump node-file-trace to 0.6.4 (#4617)
Bump node-file-trace to fix a webpack tracing bug that looks like the following:


```
TypeError: Cannot read property 'type' of null
    at handleWrappers (/vercel/e77875438c1cd74b/.build-utils/.builder/node_modules/@vercel/next/dist/index.js:12763:58)
    at module.exports.447.module.exports (/vercel/e77875438c1cd74b/.build-utils/.builder/node_modules/@vercel/next/dist/index.js:14674:3)
    at Job.emitDependency (/vercel/e77875438c1cd74b/.build-utils/.builder/node_modules/@vercel/next/dist/index.js:11730:40)
    at /vercel/e77875438c1cd74b/.build-utils/.builder/node_modules/@vercel/next/dist/index.js:11755:20
    at async Promise.all (index 9)
    at async Job.emitDependency (/vercel/e77875438c1cd74b/.build-utils/.builder/node_modules/@vercel/next/dist/index.js:11736:5)
    at async Promise.all (index 1)
    at async Object.module.exports.328.module.exports [as default] (/vercel/e77875438c1cd74b/.build-utils/.builder/node_modules/@vercel/next/dist/index.js:11514:3)
    at async Object.module.exports.178.exports.build (/vercel/e77875438c1cd74b/.build-utils/.builder/node_modules/@vercel/next/dist/index.js:6076:69)
    at async buildStep (/var/task/sandbox-worker.js:20407:20)
```

- [0.6.2](https://github.com/vercel/node-file-trace/releases/tag/0.6.2)
- [0.6.3](https://github.com/vercel/node-file-trace/releases/tag/0.6.3) 
- [0.6.4](https://github.com/vercel/node-file-trace/releases/tag/0.6.4)

Depends on #4355
2020-06-15 20:45:15 +00:00
JJ Kasper
997031c53b [next] Update handling experimental basePath (#3791)
As mentioned by @dav-is we can prefix the outputs with the `basePath` instead of using a rewrite so that we make sure to 404 when the basePath isn't prefixed on the output. This behavior is also matched in Next.js with [this PR](https://github.com/zeit/next.js/pull/9988). 

x-ref: https://github.com/zeit/now/pull/3478
2020-06-15 17:43:37 +00:00
Steven
fdee03a599 Publish Canary
- vercel@19.1.1-canary.2
2020-06-15 12:38:11 -04:00
Steven
c5a93ecdad [cli] Fix vc dev proxy to upstream frontend dev server (#4644)
This PR fixes a longstanding issue introduced in #3673 that prevents routing properties from applying to the framework's upstream dev server.

This mimic's the older proxy logic used in build matches here: 5035fa537f/packages/now-cli/src/util/dev/server.ts (L1535-L1539)

- Related to #3777
- Related to #4510
2020-06-15 16:37:08 +00:00
JJ Kasper
5a9391b7ce Publish Canary
- vercel@19.1.1-canary.1
 - @vercel/next@2.6.7-canary.0
2020-06-15 10:20:38 -05:00
JJ Kasper
99e49473b8 [next] Update dynamic route named regexes and route keys (#4355)
This updates to leverage changes from https://github.com/zeit/next.js/pull/12801 which resolves invalid named regexes being used when the segments contain non-word characters e.g. `/[hello-world]`. 

Failing page names have also been added to the `23-custom-routes-verbose` fixture. Since the routeKeys aren't applied for dynamic routes in this PR until the routes-manifest version is bumped in the latest canary of Next.js the added test cases will be passing now and should be re-run to ensure passing after a new canary of Next.js is released with the routes-manifest version bump
2020-06-15 15:15:38 +00:00
Nathan Rajlich
de1cc6f9a7 [cli] Add a test case for resolving default "typescript" version in @vercel/node (#4656)
Adds a test case for #4655 (it got auto-merged too quickly).
2020-06-14 21:52:33 +00:00
Nathan Rajlich
08eedd8f34 Publish Canary
- vercel@19.1.1-canary.0
 - @vercel/node@1.7.1-canary.0
2020-06-14 14:00:04 -07:00
Nathan Rajlich
5021a71a8e [node] Don't resolve "typescript" from the dist dir (#4655)
On Node 10, the `require.resolve()` with "paths" does not return the
proper value relative to the `node_modules` directory. To wit:

```
$ node -v
v10.16.3

$ node -p "require.resolve('typescript', { paths: [process.cwd()] })"
/Users/nrajlich/Code/vercel/vercel/packages/now-node/dist/typescript.js

$ node -v
v14.4.0

$ node -p "require.resolve('typescript', { paths: [process.cwd()] })"
/Users/nrajlich/Code/vercel/vercel/node_modules/typescript/lib/typescript.js
```

(**Note:** cwd when running these commands is the `dist` dir of `@vercel/node`)

So the solution is to just let `require.resolve()` throw an error so the
default string "typescript" is used instead of a resolved absolute path.
2020-06-14 20:47:23 +00:00
Max Leiter
56671d7c2f [tests] Don't revoke VERCEL_TOKEN after tests run (#4643)
`VERCEL_TOKEN` will no longer be invalidated during tests

Story: https://app.clubhouse.io/vercel/story/2281
2020-06-12 22:49:37 +00:00
Steven
5035fa537f [cli] Add test for gatsby cache (#4447)
This PR adds a E2E CLI test to ensure that the Gatsby example deploys correctly and that the second deployment has the proper cached directories.

Co-authored-by: Nathan Rajlich <n@n8.io>
Co-authored-by: Andy <AndyBitz@users.noreply.github.com>
2020-06-12 16:51:55 -04:00
31 changed files with 350 additions and 72 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "19.1.0",
"version": "19.1.2-canary.2",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Now",
@@ -64,11 +64,11 @@
"dependencies": {
"@vercel/build-utils": "2.4.0",
"@vercel/go": "1.1.2",
"@vercel/next": "2.6.6",
"@vercel/node": "1.7.0",
"@vercel/next": "2.6.8-canary.0",
"@vercel/node": "1.7.2-canary.0",
"@vercel/python": "1.2.2",
"@vercel/ruby": "1.2.2",
"@vercel/static-build": "0.17.2"
"@vercel/ruby": "1.2.3-canary.0",
"@vercel/static-build": "0.17.3"
},
"devDependencies": {
"@sentry/node": "5.5.0",

View File

@@ -314,21 +314,6 @@ const main = async argv_ => {
// need to migrate.
if (authConfig.credentials) {
authConfigExists = false;
} else if (
!authConfig.token &&
!subcommandsWithoutToken.includes(targetOrSubcommand) &&
!argv['--help'] &&
!argv['--token']
) {
console.error(
error(
`The content of "${hp(VERCEL_AUTH_CONFIG_PATH)}" is invalid. ` +
`No \`token\` property found inside. Run ${getCommandName(
'login'
)} to authorize.`
)
);
return 1;
}
} else {
const results = await getDefaultAuthConfig(authConfig);

View File

@@ -1503,16 +1503,15 @@ export default class DevServer {
if (!match) {
// If the dev command is started, then proxy to it
if (this.devProcessPort) {
debug('Proxying to frontend dev server');
const upstream = `http://localhost:${this.devProcessPort}`;
debug(`Proxying to frontend dev server: ${upstream}`);
this.setResponseHeaders(res, nowRequestId);
return proxyPass(
req,
res,
`http://localhost:${this.devProcessPort}`,
this,
nowRequestId,
false
);
const origUrl = url.parse(req.url || '/', true);
delete origUrl.search;
origUrl.pathname = dest;
Object.assign(origUrl.query, uri_args);
req.url = url.format(origUrl);
return proxyPass(req, res, upstream, this, nowRequestId, false);
}
if (

View File

@@ -3,7 +3,7 @@
"private": true,
"scripts": {
"build": "gridsome build",
"develop": "gridsome develop",
"dev": "gridsome develop -p $PORT",
"explore": "gridsome explore"
},
"dependencies": {

View File

@@ -0,0 +1,14 @@
<template>
<Layout>
<h1>Not Found</h1>
<p>This is a Custom Gridsome 404.</p>
</Layout>
</template>
<script>
export default {
metaInfo: {
title: 'Not Found'
}
}
</script>

View File

@@ -1,11 +1,11 @@
<template>
<Layout>
<!-- Learn how to use images here: https://gridsome.org/docs/images -->
<g-image alt="Example image" src="~/favicon.png" width="135" />
<h1>Hello, world!</h1>
<h1>Gridsome on Vercel</h1>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Pariatur excepturi labore tempore expedita, et iste tenetur suscipit explicabo! Dolores, aperiam non officia eos quod asperiores
</p>

View File

@@ -0,0 +1,3 @@
{
"redirects": [{ "source": "/support", "destination": "/about?ref=support" }]
}

View File

@@ -0,0 +1 @@
<h1>Contact Us</h1>

View File

@@ -0,0 +1,3 @@
{
"rewrites": [{ "source": "/support", "destination": "/contact.html" }]
}

View File

@@ -0,0 +1,3 @@
export default function Contact() {
return <h1>Contact Page</h1>;
}

View File

@@ -0,0 +1,3 @@
{
"rewrites": [{ "source": "/support", "destination": "/contact" }]
}

View File

@@ -1,4 +1,5 @@
import ms from 'ms';
import os from 'os';
import fs from 'fs-extra';
import test from 'ava';
import { join, resolve, delimiter } from 'path';
@@ -526,6 +527,35 @@ test('[vercel dev] reflects changes to config and env without restart', async t
}
});
test('[vercel dev] `@vercel/node` TypeScript should be resolved by default', async t => {
// The purpose of this test is to test that `@vercel/node` can properly
// resolve the default "typescript" module when the project doesn't include
// its own version. To properly test for this, a fixture needs to be created
// *outside* of the `vercel` repo, since otherwise the root-level
// "node_modules/typescript" is resolved as relative to the project, and
// not relative to `@vercel/node` which is what we are testing for here.
const dir = join(os.tmpdir(), 'vercel-node-typescript-resolve-test');
const apiDir = join(dir, 'api');
await fs.mkdirp(apiDir);
await fs.writeFile(
join(apiDir, 'hello.js'),
'export default (req, res) => { res.end("world"); }'
);
const { dev, port, readyResolver } = await testFixture(dir);
try {
await readyResolver;
const res = await fetch(`http://localhost:${port}/api/hello`);
const body = await res.text();
t.is(body, 'world');
} finally {
await dev.kill('SIGTERM');
await fs.remove(dir);
}
});
test(
'[vercel dev] validate routes that use `check: true`',
testFixtureStdio('routes-check-true', async testPath => {
@@ -1059,6 +1089,13 @@ test(
'[vercel dev] 06-gridsome',
testFixtureStdio('06-gridsome', async testPath => {
await testPath(200, '/');
await testPath(200, '/about');
await testPath(308, '/support', 'Redirecting to /about?ref=support (308)', {
Location: '/about?ref=support',
});
// Bug with gridsome's dev server: https://github.com/gridsome/gridsome/issues/831
// Works in prod only so leave out for now
// await testPath(404, '/nothing');
})
);
@@ -1066,6 +1103,9 @@ test(
'[vercel dev] 07-hexo-node',
testFixtureStdio('07-hexo-node', async testPath => {
await testPath(200, '/', /Hexo \+ Node.js API/m);
await testPath(200, '/api/date', new RegExp(new Date().getFullYear()));
await testPath(200, '/contact.html', /Contact Us/m);
await testPath(200, '/support', /Contact Us/m);
})
);
@@ -1090,6 +1130,8 @@ test(
testFixtureStdio('10-nextjs-node', async testPath => {
await testPath(200, '/', /Next.js \+ Node.js API/m);
await testPath(200, '/api/date', new RegExp(new Date().getFullYear()));
await testPath(200, '/contact', /Contact Page/);
await testPath(200, '/support', /Contact Page/);
await testPath(404, '/nothing', /Custom Next 404/);
})
);
@@ -1100,6 +1142,7 @@ test(
'12-polymer-node',
async testPath => {
await testPath(200, '/', /Polymer \+ Node.js API/m);
await testPath(200, '/api/date', new RegExp(new Date().getFullYear()));
},
{ skipDeploy: true }
)
@@ -1111,6 +1154,7 @@ test(
'13-preact-node',
async testPath => {
await testPath(200, '/', /Preact/m);
await testPath(200, '/api/date', new RegExp(new Date().getFullYear()));
},
{ skipDeploy: true }
)
@@ -1122,6 +1166,7 @@ test(
'14-svelte-node',
async testPath => {
await testPath(200, '/', /Svelte/m);
await testPath(200, '/api/date', new RegExp(new Date().getFullYear()));
},
{ skipDeploy: true }
)
@@ -1133,6 +1178,7 @@ test(
'16-vue-node',
async testPath => {
await testPath(200, '/', /Vue.js \+ Node.js API/m);
await testPath(200, '/api/date', new RegExp(new Date().getFullYear()));
},
{ skipDeploy: true }
)
@@ -1144,6 +1190,7 @@ test(
'17-vuepress-node',
async testPath => {
await testPath(200, '/', /VuePress \+ Node.js API/m);
await testPath(200, '/api/date', new RegExp(new Date().getFullYear()));
},
{ skipDeploy: true }
)

View File

@@ -31,6 +31,8 @@ function execa(file, args, options) {
const binaryPath = path.resolve(__dirname, `../scripts/start.js`);
const fixture = name => path.join(__dirname, 'fixtures', 'integration', name);
const example = name =>
path.join(__dirname, '..', '..', '..', 'examples', name);
const deployHelpMessage = `${logo} vercel [options] <command | path>`;
let session = 'temp-session';
@@ -243,8 +245,10 @@ test.after.always(async () => {
loginApiServer.close();
}
// Make sure the token gets revoked
await execa(binaryPath, ['logout', ...defaultArgs]);
// Make sure the token gets revoked unless it's passed in via environment
if (!process.env.VERCEL_TOKEN) {
await execa(binaryPath, ['logout', ...defaultArgs]);
}
if (tmpDir) {
// Remove config directory entirely
@@ -252,6 +256,20 @@ test.after.always(async () => {
}
});
test('default command should prompt login with empty auth.json', async t => {
await fs.writeFile(getConfigAuthPath(), JSON.stringify({}));
try {
await execa(binaryPath, [...defaultArgs]);
t.fail();
} catch (err) {
t.true(
err.stderr.includes(
'Error! No existing credentials found. Please run `vercel login` or pass "--token"'
)
);
}
});
test('login', async t => {
t.timeout(ms('1m'));
@@ -2934,3 +2952,36 @@ test('`vc --debug project ls` should output the projects listing', async t => {
formatOutput({ stderr, stdout })
);
});
test('deploy gatsby twice and print cached directories', async t => {
const directory = example('gatsby');
const packageJsonPath = path.join(directory, 'package.json');
const packageJsonOriginal = await readFile(packageJsonPath, 'utf8');
const pkg = JSON.parse(packageJsonOriginal);
async function tryDeploy(cwd) {
await execa(binaryPath, [...defaultArgs, '--public', '--confirm'], {
cwd,
stdio: 'inherit',
reject: true,
});
t.true(true);
}
// Deploy once to populate the cache
await tryDeploy(directory);
// Wait because the cache is not available right away
// See https://codeburst.io/quick-explanation-of-the-s3-consistency-model-6c9f325e3f82
await sleep(60000);
// Update build script to ensure cached files were restored in the next deploy
pkg.scripts.build = `ls -lA && ls .cache && ls public && ${pkg.scripts.build}`;
await writeFile(packageJsonPath, JSON.stringify(pkg));
try {
await tryDeploy(directory);
} finally {
await writeFile(packageJsonPath, packageJsonOriginal);
}
});

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/next",
"version": "2.6.6",
"version": "2.6.8-canary.0",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
@@ -26,7 +26,7 @@
"@types/resolve-from": "5.0.1",
"@types/semver": "6.0.0",
"@types/yazl": "2.4.1",
"@zeit/node-file-trace": "0.6.1",
"@zeit/node-file-trace": "0.6.5",
"async-sema": "3.0.1",
"buffer-crc32": "0.2.13",
"escape-string-regexp": "3.0.0",

View File

@@ -208,7 +208,7 @@ export const build = async ({
// Limit for max size each lambda can be, 50 MB if no custom limit
const lambdaCompressedByteLimit = config.maxLambdaSize || 50 * 1000 * 1000;
const entryDirectory = path.dirname(entrypoint);
let entryDirectory = path.dirname(entrypoint);
const entryPath = path.join(workPath, entryDirectory);
const outputDirectory = config.outputDirectory || '.next';
const dotNextStatic = path.join(entryPath, outputDirectory, 'static');
@@ -422,17 +422,16 @@ export const build = async ({
const headers: Route[] = [];
const rewrites: Route[] = [];
const redirects: Route[] = [];
const nextBasePathRoute: Route[] = [];
const dataRoutes: Route[] = [];
let dynamicRoutes: Route[] = [];
let nextBasePath: string | undefined;
// whether they have enabled pages/404.js as the custom 404 page
let hasPages404 = false;
if (routesManifest) {
switch (routesManifest.version) {
case 1:
case 2: {
case 2:
case 3: {
redirects.push(...convertRedirects(routesManifest.redirects));
rewrites.push(...convertRewrites(routesManifest.rewrites));
@@ -468,7 +467,14 @@ export const build = async ({
// make sure to route SSG data route to the data prerender
// output, we don't do this for SSP routes since they don't
// have a separate data output
(ssgDataRoute && ssgDataRoute.dataRoute) || dataRoute.page
(ssgDataRoute && ssgDataRoute.dataRoute) || dataRoute.page,
`${
dataRoute.routeKeys
? `?${Object.keys(dataRoute.routeKeys)
.map(key => `${dataRoute.routeKeys![key]}=$${key}`)
.join('&')}`
: ''
}`
),
check: true,
});
@@ -480,7 +486,7 @@ export const build = async ({
}
if (routesManifest.basePath && routesManifest.basePath !== '/') {
nextBasePath = routesManifest.basePath;
const nextBasePath = routesManifest.basePath;
if (!nextBasePath.startsWith('/')) {
throw new NowBuildError({
@@ -497,11 +503,7 @@ export const build = async ({
});
}
nextBasePathRoute.push({
src: `^${nextBasePath}(?:$|/(.*))$`,
dest: `/$1`,
continue: true,
});
entryDirectory = path.join(entryDirectory, nextBasePath);
}
break;
}
@@ -565,9 +567,6 @@ export const build = async ({
routes: [
// TODO: low priority: handle trailingSlash
// Add top level rewrite for basePath if provided
...nextBasePathRoute,
// User headers
...headers,
@@ -1583,9 +1582,6 @@ export const build = async ({
- Builder rewrites
*/
routes: [
// Add top level rewrite for basePath if provided
...nextBasePathRoute,
// headers
...headers,

View File

@@ -312,9 +312,16 @@ export type RoutesManifest = {
dynamicRoutes: {
page: string;
regex: string;
namedRegex?: string;
routeKeys?: { [named: string]: string };
}[];
version: number;
dataRoutes?: Array<{ page: string; dataRouteRegex: string }>;
dataRoutes?: Array<{
page: string;
dataRouteRegex: string;
namedDataRouteRegex?: string;
routeKeys?: { [named: string]: string };
}>;
};
export async function getRoutesManifest(
@@ -352,6 +359,20 @@ export async function getRoutesManifest(
// eslint-disable-next-line @typescript-eslint/no-var-requires
const routesManifest: RoutesManifest = require(pathRoutesManifest);
// massage temporary array based routeKeys from v1/v2 of routes
// manifest into new object based
for (const route of [
...(routesManifest.dataRoutes || []),
...(routesManifest.dynamicRoutes || []),
]) {
if (Array.isArray(route.routeKeys)) {
route.routeKeys = route.routeKeys.reduce((prev, cur) => {
prev[cur] = cur;
return prev;
}, {});
}
}
return routesManifest;
}
@@ -383,6 +404,25 @@ export async function getDynamicRoutes(
};
});
}
case 3: {
return routesManifest.dynamicRoutes
.filter(({ page }) =>
omittedRoutes ? !omittedRoutes.has(page) : true
)
.map(({ page, namedRegex, regex, routeKeys }) => {
return {
src: namedRegex || regex,
dest: `${!isDev ? path.join('/', entryDirectory, page) : page}${
routeKeys
? `?${Object.keys(routeKeys)
.map(key => `${routeKeys[key]}=$${key}`)
.join('&')}`
: ''
}`,
check: true,
};
});
}
default: {
// update MIN_ROUTES_MANIFEST_VERSION
throw new NowBuildError({

View File

@@ -3,7 +3,7 @@
"builds": [{ "src": "package.json", "use": "@vercel/next" }],
"probes": [
{
"path": "/_next/static/testing-build-id/pages/index.js",
"path": "/_next/static/9dc4d2c93491d81eead3/pages/index.js",
"responseHeaders": {
"cache-control": "public,max-age=31536000,immutable"
}

View File

@@ -3,7 +3,7 @@
"builds": [{ "src": "package.json", "use": "@vercel/next" }],
"probes": [
{
"path": "/docs/_next/static/testing-build-id/pages/index.js",
"path": "/docs/_next/static/a7184ed7301386fd6825/pages/index.js",
"responseHeaders": {
"cache-control": "public,max-age=31536000,immutable"
}
@@ -19,6 +19,22 @@
{
"path": "/docs/another",
"mustContain": "hello from another"
},
{
"path": "/",
"mustNotContain": "hello from index"
},
{
"path": "/another",
"mustNotContain": "hello from another"
},
{
"path": "/_next/static/testing-build-id/pages/index.js",
"mustNotContain": "hello from index"
},
{
"path": "/_next/static/testing-build-id/pages/another.js",
"mustNotContain": "hello from another"
}
]
}

View File

@@ -182,7 +182,7 @@
// should match /_next file after rewrite
{
"path": "/hidden/_next/static/testing-build-id/pages/hello.js",
"path": "/hidden/_next/static/b09092d6eebe375caba5/pages/hello.js",
"mustContain": "createElement"
},
@@ -245,6 +245,13 @@
"path": "/hello/post-123.html",
"status": 200,
"mustContain": "123"
},
// should rewrite to catch-all with dash in segment name
{
"path": "/catchall-dash/hello/world",
"status": 200,
"mustContain": "hello/world"
}
]
}

View File

@@ -0,0 +1,17 @@
import { useRouter } from 'next/router'
const Page = () => {
return (
<p>path: {useRouter().query['hello-world']?.join('/')}</p>
)
}
export default Page
export const getServerSideProps = () => {
return {
props: {
hello: 'world'
}
}
}

View File

@@ -0,0 +1 @@
export default () => 'hi'

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/node",
"version": "1.7.0",
"version": "1.7.2-canary.0",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -33,7 +33,7 @@
"@types/etag": "1.8.0",
"@types/test-listen": "1.1.0",
"@zeit/ncc": "0.20.4",
"@zeit/node-file-trace": "0.6.1",
"@zeit/node-file-trace": "0.6.5",
"content-type": "1.0.4",
"cookie": "0.4.0",
"etag": "1.8.1",

View File

@@ -15,7 +15,7 @@ import { register } from 'ts-node';
let compiler: string;
try {
compiler = require.resolve('typescript', {
paths: [process.cwd(), __dirname],
paths: [process.cwd()],
});
} catch (e) {
compiler = 'typescript';

View File

@@ -60,9 +60,19 @@ def webrick_handler(httpMethod, path, body, headers)
server.shutdown
Thread.kill(th)
# Net::HTTP doesnt read the set the encoding so we must set manually.
# Bug: https://bugs.ruby-lang.org/issues/15517
# More: https://yehudakatz.com/2010/05/17/encodings-unabridged/
res_headers = res.each_capitalized.to_h
if res_headers["Content-Type"] && res_headers["Content-Type"].include?("charset=")
res_encoding = res_headers["Content-Type"].match(/charset=([^;]*)/)[1]
res.body.force_encoding(res_encoding)
res.body = res.body.encode(res_encoding)
end
{
:statusCode => res.code.to_i,
:headers => res.each_capitalized.to_h,
:headers => res_headers,
:body => res.body,
}
end

View File

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

View File

@@ -0,0 +1,6 @@
Handler = Proc.new do |req, res|
res.status = 200
res['Content-Type'] = 'text/text; charset=utf-8'
res.body = '🐄RANDOMNESS_PLACEHOLDER'
end

View File

@@ -0,0 +1,5 @@
{
"version": 2,
"builds": [{ "src": "index.rb", "use": "@vercel/ruby" }],
"probes": [{ "path": "/", "mustContain": "🐄RANDOMNESS_PLACEHOLDER" }]
}

View File

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

View File

@@ -43,6 +43,7 @@ const frameworkList: Framework[] = [
buildCommand: 'gatsby build',
getOutputDirName: async () => 'public',
defaultRoutes: async (dirPrefix: string) => {
// This file could be generated by gatsby-plugin-now or gatsby-plugin-zeit-now
try {
const nowRoutesPath = join(
dirPrefix,
@@ -58,8 +59,34 @@ const frameworkList: Framework[] = [
}
return nowRoutes;
} catch (err) {
// if the file doesn't exist, we don't create routes
return [];
// if the file doesn't exist, we implement gatsby's recommendations
// https://www.gatsbyjs.org/docs/caching
return [
{
src: '^/static/(.*)$',
headers: { 'cache-control': 'public,max-age=31536000,immutable' },
continue: true,
},
{
src: '^/.*\\.(js|css)$',
headers: { 'cache-control': 'public,max-age=31536000,immutable' },
continue: true,
},
{
src: '^/(sw\\.js|app-data\\.json|.*\\.html|page-data/.*)$',
headers: { 'cache-control': 'public,max-age=0,must-revalidate' },
continue: true,
},
{
handle: 'filesystem',
},
{
src: '.*',
status: 404,
dest: '404.html',
},
];
}
},
cachePattern: '{.cache,public}/**',

View File

@@ -7,5 +7,49 @@
"config": { "zeroConfig": true }
}
],
"probes": [{ "path": "/", "mustContain": "Welcome to your new Gatsby site" }]
"probes": [
{ "path": "/", "mustContain": "Welcome to your new Gatsby site" },
{
"path": "/static/d/856328897.json",
"responseHeaders": {
"cache-control": "public,max-age=31536000,immutable"
}
},
{
"path": "/app-08a9fb9626777db1bf33.js",
"responseHeaders": {
"cache-control": "public,max-age=31536000,immutable"
}
},
{
"path": "/styles.fc4fa5e094d218207796.css",
"responseHeaders": {
"cache-control": "public,max-age=31536000,immutable"
}
},
{
"path": "/sw.js",
"responseHeaders": { "cache-control": "public,max-age=0,must-revalidate" }
},
{
"path": "/app-data.json",
"responseHeaders": { "cache-control": "public,max-age=0,must-revalidate" }
},
{
"path": "/index.html",
"responseHeaders": { "cache-control": "public,max-age=0,must-revalidate" }
},
{
"path": "/page-data/404/page-data.json",
"responseHeaders": { "cache-control": "public,max-age=0,must-revalidate" }
},
{
"path": "/path-that-does-not-exist",
"mustContain": "You just hit a route that doesn&#x27;t exist..."
},
{
"path": "/path-that-does-not-exist",
"status": 404
}
]
}

View File

@@ -2266,10 +2266,10 @@
resolved "https://registry.yarnpkg.com/@zeit/ncc/-/ncc-0.20.4.tgz#00f0a25a88cac3712af4ba66561d9e281c6f05c9"
integrity sha512-fmq+F/QxPec+k/zvT7HiVpk7oiGFseS6brfT/AYqmCUp6QFRK7vZf2Ref46MImsg/g2W3g5X6SRvGRmOAvEfdA==
"@zeit/node-file-trace@0.6.1":
version "0.6.1"
resolved "https://registry.yarnpkg.com/@zeit/node-file-trace/-/node-file-trace-0.6.1.tgz#44d832c4bf71bc4d142cc5e2ef3e708673cdd2b4"
integrity sha512-rcaY2xxhjBzGJEtpdLFbS87HYx8bVbi/a+0MBVpMVvURrmjVAY58VL+Ynz4QPNs1C6o8e0FB1gVQFtN47ZnkMw==
"@zeit/node-file-trace@0.6.5":
version "0.6.5"
resolved "https://registry.yarnpkg.com/@zeit/node-file-trace/-/node-file-trace-0.6.5.tgz#ffd443e4648eb88591c53b1a871a47bff651b62e"
integrity sha512-PbxtiZBU+axKtR9dU2/iQgK9+aP/ip94SqI/FCMWppmFPGlxGKHf8UnJZskFuqLZeWWzL+L+8SeipsNHATO9nw==
dependencies:
acorn "^7.1.1"
acorn-class-fields "^0.3.2"