Compare commits

..

4 Commits

Author SHA1 Message Date
Steven
f3b286ecf3 Publish Canary
- now@17.0.2-canary.0
 - @now/routing-utils@1.5.3-canary.0
2020-02-06 09:12:19 -05:00
Steven
adf31c3fcc [now-routing-utils] Change behavior of trailingSlash: true redirects (#3745)
This PR changes the behavior of `trailingSlash: true` after we received feedback that files should not be redirected with a trailing slash. This matches the behavior of `serve` and `serve-handler`.

### Examples 
* `/index.html` => serve
* `/assets/style.css` => serve
* `/assets` => redirect to `/assets/`
* `/assets/style` => redirect to `/assets/style/` 

### Additional

In order to avoid duplicate content, this PR also adds redirects to files without a trailing slash.

* `/about.html/` => redirect to `/about.html`
* `/assets/style.css/` => redirect to `/assets/style.css`


Fixes #3731
2020-02-06 09:07:46 -05:00
luc
deacdfc47c Publish Stable
- now@17.0.1
2020-02-06 01:07:15 +01:00
Luc
ac9badbe9e [now-cli] Always output deployment url in stdout (#3753) 2020-02-06 00:58:24 +01:00
7 changed files with 49 additions and 23 deletions

View File

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

View File

@@ -94,7 +94,6 @@ const printDeploymentStatus = async (
},
deployStamp,
isClipboardEnabled,
quiet,
isFile
) => {
const isProdDeployment = target === 'production';
@@ -144,11 +143,6 @@ const printDeploymentStatus = async (
.catch(error => output.debug(`Error copying to clipboard: ${error}`));
}
// write to stdout
if (quiet) {
process.stdout.write(`https://${deploymentUrl}`);
}
output.print(
prependEmoji(
`${isProdDeployment ? 'Production' : 'Preview'}: ${chalk.bold(
@@ -659,7 +653,6 @@ export default async function main(
deployment,
deployStamp,
!argv['--no-clipboard'],
quiet,
isFile
);
}

View File

@@ -83,6 +83,7 @@ export default async function processDeployment({
deployStamp,
force,
nowConfig,
quiet,
} = args;
const { debug } = output;
@@ -179,6 +180,10 @@ export default async function processDeployment({
printInspectUrl(output, event.payload.url, deployStamp, org.slug);
if (quiet) {
process.stdout.write(`https://${event.payload.url}`);
}
if (queuedSpinner === null) {
queuedSpinner =
event.payload.readyState === 'QUEUED'

View File

@@ -638,7 +638,7 @@ test(
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(200, '/style.css', 'body { color: green }');
await testPath(308, '/index.html', '', { Location: '/' });
await testPath(308, '/about.html', '', { Location: '/about/' });
await testPath(308, '/sub/index.html', '', { Location: '/sub/' });
@@ -653,17 +653,15 @@ test(
'[now dev] test trailingSlash true serve correct content',
testFixtureStdio('test-trailing-slash', async (t, port, testPath) => {
await testPath(200, '/', 'Index Page');
await testPath(200, '/index.html/', 'Index Page');
await testPath(200, '/about.html/', 'About 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', '', { Location: '/about.html/' });
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/', '', { Location: '/about.html' });
await testPath(308, '/style.css/', '', { Location: '/style.css' });
await testPath(308, '/sub', '', { Location: '/sub/' });
await testPath(308, '/sub/another.html', '', {
Location: '/sub/another.html/',
});
})
);

View File

@@ -1,6 +1,6 @@
{
"name": "@now/routing-utils",
"version": "1.5.2",
"version": "1.5.3-canary.0",
"description": "ZEIT Now routing utilities",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",

View File

@@ -105,10 +105,15 @@ export function convertTrailingSlash(enable: boolean, status = 308): Route[] {
const routes: Route[] = [];
if (enable) {
routes.push({
src: '^/(.*[^\\/])$',
src: '^/((?:[^/]+/)*[^/\\.]+)$',
headers: { Location: '/$1/' },
status,
});
routes.push({
src: '^/((?:[^/]+/)*[^/]+\\.\\w+)/$',
headers: { Location: '/$1' },
status,
});
} else {
routes.push({
src: '^/(.*)\\/$',

View File

@@ -503,16 +503,41 @@ test('convertTrailingSlash enabled', () => {
const actual = convertTrailingSlash(true);
const expected = [
{
src: '^/(.*[^\\/])$',
src: '^/((?:[^/]+/)*[^/\\.]+)$',
headers: { Location: '/$1/' },
status: 308,
},
{
src: '^/((?:[^/]+/)*[^/]+\\.\\w+)/$',
headers: { Location: '/$1' },
status: 308,
},
];
deepEqual(actual, expected);
const mustMatch = [['/index.html', '/dir', '/dir/index.html', '/foo/bar']];
const mustMatch = [
['/dir', '/dir/foo', '/dir/foo/bar'],
['/foo.html/', '/dir/foo.html/', '/dir/foo/bar.css/', '/dir/about.map.js/'],
];
const mustNotMatch = [['/', '/dir/', '/dir/foo/', '/next.php?page=/']];
const mustNotMatch = [
[
'/',
'/index.html',
'/asset/style.css',
'/asset/about.map.js',
'/dir/',
'/dir/foo/',
'/next.php?page=/',
],
[
'/',
'/foo.html',
'/dir/foo.html',
'/dir/foo/bar.css',
'/dir/about.map.js',
],
];
assertRegexMatches(actual, mustMatch, mustNotMatch);
});