MCPcopy
hub / github.com/facebook/docusaurus / normalizeUrl

Function normalizeUrl

packages/docusaurus-utils/src/urlUtils.ts:22–106  ·  view source on GitHub ↗
(rawUrls: string[])

Source from the content-addressed store, hash-verified

20 * @throws {TypeError} If any of the URL segment is not a string, this throws.
21 */
22export function normalizeUrl(rawUrls: string[]): string {
23 const urls = [...rawUrls];
24 const resultArray = [];
25
26 let hasStartingSlash = false;
27 let hasEndingSlash = false;
28
29 const isNonEmptyArray = (arr: string[]): arr is [string, ...string[]] =>
30 arr.length > 0;
31
32 if (!isNonEmptyArray(urls)) {
33 return '';
34 }
35
36 // If the first part is a plain protocol, we combine it with the next part.
37 if (urls[0].match(/^[^/:]+:\/*$/) && urls.length > 1) {
38 const first = urls.shift()!;
39 if (first.startsWith('file:') && urls[0].startsWith('/')) {
40 // Force a double slash here, else we lose the information that the next
41 // segment is an absolute path
42 urls[0] = `${first}//${urls[0]}`;
43 } else {
44 urls[0] = first + urls[0];
45 }
46 }
47
48 // There must be two or three slashes in the file protocol,
49 // two slashes in anything else.
50 const replacement = urls[0].match(/^file:\/\/\//) ? '$1:///' : '$1://';
51 urls[0] = urls[0].replace(/^(?<protocol>[^/:]+):\/*/, replacement);
52
53 for (let i = 0; i < urls.length; i += 1) {
54 let component = urls[i];
55
56 if (typeof component !== 'string') {
57 throw new TypeError(`Url must be a string. Received ${typeof component}`);
58 }
59
60 if (component === '') {
61 if (i === urls.length - 1 && hasEndingSlash) {
62 resultArray.push('/');
63 }
64 continue;
65 }
66
67 if (component !== '/') {
68 if (i > 0) {
69 // Removing the starting slashes for each component but the first.
70 component = component.replace(
71 /^\/+/,
72 // Special case where the first element of rawUrls is empty
73 // ["", "/hello"] => /hello
74 component.startsWith('/') && !hasStartingSlash ? '/' : '',
75 );
76 }
77
78 hasEndingSlash = component.endsWith('/');
79 // Removing the ending slashes for each component but the last. For the

Callers 15

injectHtmlTagsFunction · 0.90
generateBlogFeedFunction · 0.90
defaultCreateFeedItemsFunction · 0.90
createFeedHtmlHeadTagsFunction · 0.90
loadContentFunction · 0.90
getAuthorsMapCheckedFunction · 0.90
normalizeImageUrlFunction · 0.90
getAuthorPageFunction · 0.90
buildAllRoutesFunction · 0.90
createArchiveRouteFunction · 0.90
permalinkFunction · 0.90
processBlogSourceFileFunction · 0.90

Calls 1

isNonEmptyArrayFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…