Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(v2): normalizeUrl edge cases #3427

Merged
merged 2 commits into from
Sep 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions packages/docusaurus-utils/src/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,22 @@ describe('load utils', () => {

test('normalizeUrl', () => {
const asserts = [
{
input: ['/', ''],
output: '/',
},
{
input: ['', '/'],
output: '/',
},
{
input: ['/'],
output: '/',
},
{
input: [''],
output: '',
},
{
input: ['/', '/'],
output: '/',
Expand Down Expand Up @@ -306,6 +322,34 @@ describe('load utils', () => {
input: ['http://foobar.com', '', 'test', '/'],
output: 'http://foobar.com/test/',
},
{
input: ['/', '', 'hello', '', '/', '/', '', '/', '/world'],
output: '/hello/world',
},
{
input: ['', '', '/tt', 'ko', 'hello'],
output: '/tt/ko/hello',
},
{
input: ['', '///hello///', '', '///world'],
output: '/hello/world',
},
{
input: ['', '/hello/', ''],
output: '/hello/',
},
{
input: ['', '/', ''],
output: '/',
},
{
input: ['///', '///'],
output: '/',
},
{
input: ['/', '/hello/world/', '///'],
output: '/hello/world/',
},
];
asserts.forEach((testCase) => {
expect(normalizeUrl(testCase.input)).toBe(testCase.output);
Expand Down
28 changes: 21 additions & 7 deletions packages/docusaurus-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,9 @@ export function normalizeUrl(rawUrls: string[]): string {
const urls = rawUrls;
const resultArray = [];

let hasStartingSlash = false;
let hasEndingSlash = false;

// If the first part is a plain protocol, we combine it with the next part.
if (urls[0].match(/^[^/:]+:\/*$/) && urls.length > 1) {
const first = urls.shift();
Expand All @@ -302,19 +305,30 @@ export function normalizeUrl(rawUrls: string[]): string {
}

if (component === '') {
if (i === urls.length - 1 && hasEndingSlash) {
resultArray.push('/');
}
// eslint-disable-next-line
continue;
}

if (i > 0) {
// Removing the starting slashes for each component but the first.
component = component.replace(/^[/]+/, '');
}
if (component !== '/') {
if (i > 0) {
// Removing the starting slashes for each component but the first.
component = component.replace(
/^[/]+/,
// Special case where the first element of rawUrls is empty ["", "/hello"] => /hello
component[0] === '/' && !hasStartingSlash ? '/' : '',
);
}

// Removing the ending slashes for each component but the last.
// For the last component we will combine multiple slashes to a single one.
component = component.replace(/[/]+$/, i < urls.length - 1 ? '' : '/');
hasEndingSlash = component[component.length - 1] === '/';
// Removing the ending slashes for each component but the last.
// For the last component we will combine multiple slashes to a single one.
component = component.replace(/[/]+$/, i < urls.length - 1 ? '' : '/');
}

hasStartingSlash = true;
resultArray.push(component);
}

Expand Down