fix(v2): doc path special char (space or other) should lead to a valid slug (#3262)

* doc path special char (space or other) should lead to a valid slug

* doc path special char (space or other) should lead to a valid slug

* improve doc bad slug message
This commit is contained in:
Sébastien Lorber 2020-08-11 17:20:51 +02:00 committed by GitHub
parent b75a7150b2
commit dd3f3f1093
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 3 deletions

View file

@ -15,6 +15,13 @@ describe('getSlug', () => {
); );
}); });
// See https://github.com/facebook/docusaurus/issues/3223
test('should handle special chars in doc path', () => {
expect(
getSlug({baseID: 'my dôc', dirName: '/dir with spâce/hey $hello'}),
).toEqual('/dir with spâce/hey $hello/my dôc');
});
test('should handle current dir', () => { test('should handle current dir', () => {
expect(getSlug({baseID: 'doc', dirName: '.'})).toEqual('/doc'); expect(getSlug({baseID: 'doc', dirName: '.'})).toEqual('/doc');
expect(getSlug({baseID: 'doc', dirName: '/'})).toEqual('/doc'); expect(getSlug({baseID: 'doc', dirName: '/'})).toEqual('/doc');

View file

@ -33,7 +33,16 @@ export default function getSlug({
if (!isValidPathname(slug)) { if (!isValidPathname(slug)) {
throw new Error( throw new Error(
`Unable to resolve valid document slug. Maybe your slug frontmatter is incorrect? Doc id=${baseID} / dirName=${dirName} / frontmatterSlug=${frontmatterSlug} => bad result slug=${slug}`, `We couldn't compute a valid slug for document with id=${baseID} in folder=${dirName}
The slug we computed looks invalid: ${slug}
Maybe your slug frontmatter is incorrect or you use weird chars in the file path?
By using the slug frontmatter, you should be able to fix this error, by using the slug of your choice:
Example =>
---
slug: /my/customDocPath
---
`,
); );
} }

View file

@ -394,10 +394,11 @@ describe('load utils', () => {
expect(isValidPathname('/hey/ho/')).toBe(true); expect(isValidPathname('/hey/ho/')).toBe(true);
expect(isValidPathname('/hey/h%C3%B4/')).toBe(true); expect(isValidPathname('/hey/h%C3%B4/')).toBe(true);
expect(isValidPathname('/hey///ho///')).toBe(true); // Unexpected but valid expect(isValidPathname('/hey///ho///')).toBe(true); // Unexpected but valid
expect(isValidPathname('/hey/héllô you')).toBe(true);
// //
expect(isValidPathname('')).toBe(false); expect(isValidPathname('')).toBe(false);
expect(isValidPathname('hey')).toBe(false); expect(isValidPathname('hey')).toBe(false);
expect(isValidPathname('/hey/hô')).toBe(false);
expect(isValidPathname('/hey?qs=ho')).toBe(false); expect(isValidPathname('/hey?qs=ho')).toBe(false);
expect(isValidPathname('https://fb.com/hey')).toBe(false); expect(isValidPathname('https://fb.com/hey')).toBe(false);
expect(isValidPathname('//hey')).toBe(false); expect(isValidPathname('//hey')).toBe(false);

View file

@ -365,7 +365,8 @@ export function isValidPathname(str: string): boolean {
} }
try { try {
// weird, but is there a better way? // weird, but is there a better way?
return new URL(str, 'https://domain.com').pathname === str; const parsedPathname = new URL(str, 'https://domain.com').pathname;
return parsedPathname === str || parsedPathname === encodeURI(str);
} catch (e) { } catch (e) {
return false; return false;
} }