Skip to content

Commit

Permalink
wip: refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
OzakIOne committed Dec 28, 2023
1 parent 66ccc3b commit 660a527
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 78 deletions.
28 changes: 14 additions & 14 deletions packages/docusaurus/src/server/__tests__/brokenLinks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ describe('handleBrokenLinks NEW TESTS', () => {
Exhaustive list of all broken anchors found:
- Broken anchor on source page path = /page1:
-> linking to /page2#brokenAnchor
-> linking to /page2#brokenAnchor (resolved as: /page2)
"
`);
});
Expand All @@ -241,7 +241,7 @@ describe('handleBrokenLinks NEW TESTS', () => {
Exhaustive list of all broken anchors found:
- Broken anchor on source page path = /page1:
-> linking to /page2#
-> linking to /page2# (resolved as: /page2)
"
`);
});
Expand All @@ -266,7 +266,7 @@ describe('handleBrokenLinks NEW TESTS', () => {
Exhaustive list of all broken anchors found:
- Broken anchor on source page path = /page1:
-> linking to /page2#brokenAnchor (resolved as: /page2?age=42&theme=dark#brokenAnchor)
-> linking to /page2?age=42&theme=dark#brokenAnchor (resolved as: /page2)
"
`);
});
Expand All @@ -278,17 +278,17 @@ describe('handleBrokenLinks NEW TESTS', () => {
allCollectedLinks: {
'/page1': {
links: [
'/page1',
'',
// '#goodAnchor1', // TODO brokenLink
// '/page1',
// '',
'#goodAnchor1', // TODO brokenLink
'/page1#goodAnchor2',
'/page1?age=42#goodAnchor3',
// '#badAnchor1', // TODO brokenLink
'/page1#badAnchor2',
'/page1?age=42#badAnchor3',
// '/page1?age=42#goodAnchor3',
'#badAnchor1', // TODO brokenLink
// '/page1#badAnchor2',
// '/page1?age=42#badAnchor3',
],

anchors: ['goodAnchor1', 'goodAnchor2', 'goodAnchor3'],
anchors: ['goodAnchor1'],
},
},
}),
Expand Down Expand Up @@ -323,7 +323,7 @@ describe('handleBrokenLinks NEW TESTS', () => {
Exhaustive list of all broken anchors found:
- Broken anchor on source page path = /page1:
-> linking to /page2#brokenAnchor
-> linking to /page2#brokenAnchor (resolved as: /page2)
"
`);
});
Expand All @@ -348,7 +348,7 @@ describe('handleBrokenLinks NEW TESTS', () => {
Exhaustive list of all broken anchors found:
- Broken anchor on source page path = /page1:
-> linking to /page2#brokenAnchor (resolved as: /page2?age=42&theme=dark#brokenAnchor)
-> linking to /page2?age=42&theme=dark#brokenAnchor (resolved as: /page2)
"
`);
});
Expand Down Expand Up @@ -437,7 +437,7 @@ describe('handleBrokenLinks NEW TESTS', () => {
Exhaustive list of all broken anchors found:
- Broken anchor on source page path = /page1:
-> linking to /page1#brokenAnchor
-> linking to /page1#brokenAnchor (resolved as: /page1)
",
],
]
Expand Down
150 changes: 86 additions & 64 deletions packages/docusaurus/src/server/brokenLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,61 +58,64 @@ function getRouteAndAnchor(link: string, fromPath: string) {
return {route, anchor};
}

function checkAnchorsInOtherRoutes(allCollectedCorrectLinks: CollectedLinks): {
[location: string]: BrokenLink[];
} {
const brokenLinksByLocation: BrokenLinksByLocation = {};

const linkCollection = Object.entries(allCollectedCorrectLinks);

linkCollection.forEach(([path, collection]) => {
const brokenLinks = collection.links.flatMap((link) => {
const {route, anchor} = getRouteAndAnchor(link, path);
if (anchor !== undefined) {
const targetRoute = allCollectedCorrectLinks[route];

if (targetRoute) {
// means we have a link to an internal or external page that exists
if (!targetRoute.anchors.includes(anchor)) {
return [
{
link: `${route}#${anchor}`,
resolvedLink: link,
anchor: true,
},
];
}
} else {
// means we have link to an EXTERNAL not collected
// (means no anchor or link)
// but we have a link to this page with an anchor
return [
{
link: `${route}#${anchor}`,
resolvedLink: link,
anchor: true,
},
];
}
}

return [];
});

if (brokenLinks.length > 0) {
brokenLinksByLocation[path] = brokenLinks;
}
});

return brokenLinksByLocation;
}
// function checkAnchorsInOtherRoutes(allCollectedCorrectLinks:CollectedLinks):{
// [location: string]: BrokenLink[];
// } {
// const brokenLinksByLocation: BrokenLinksByLocation = {};

// const linkCollection = Object.entries(allCollectedCorrectLinks);

// linkCollection.forEach(([path, collection]) => {
// const brokenLinks = collection.links.flatMap((link) => {
// const {route, anchor} = getRouteAndAnchor(link, path);
// if (anchor !== undefined) {
// const targetRoute = allCollectedCorrectLinks[route];

// if (targetRoute) {
// // means we have a link to an internal or external page that exists
// // if (!targetRoute.anchors.find((el) => el === anchor)) {
// if (targetRoute.anchors.includes(anchor) === false) {
// return [
// {
// link: `${route}#${anchor}`,
// resolvedLink: link,
// anchor: true,
// },
// ];
// }
// } else {
// // means we have link to an EXTERNAL not collected
// // (means no anchor or link)
// // but we have a link to this page with an anchor
// return [
// {
// link: `${route}#${anchor}`,
// resolvedLink: link,
// anchor: true,
// },
// ];
// }
// }

// return [];
// });

// if (brokenLinks.length > 0) {
// brokenLinksByLocation[path] = brokenLinks;
// }
// });

// return brokenLinksByLocation;
// }

function getPageBrokenLinks({
allCollectedLinks,
pagePath,
pageLinks,
pageAnchors,
routes,
}: {
allCollectedLinks: CollectedLinks;
pagePath: string;
pageLinks: string[];
pageAnchors: string[];
Expand All @@ -126,37 +129,40 @@ function getPageBrokenLinks({
return resolvedLink;
}

// console.log('routes:', routes);
function isPathBrokenLink(link: string) {
const matchedRoutes = [link, decodeURI(link)]
// @ts-expect-error: React router types RouteConfig with an actual React
// component, but we load route components with string paths.
// We don't actually access component here, so it's fine.
.map((l) => matchRoutes(routes, l))
.flat();
console.log('matchedRoutes:', matchedRoutes.length === 0);
return matchedRoutes.length === 0;
}

function isAnchorBrokenLink(link: string) {
const [urlPath, urlHash] = link.split('#');

// ignore anchors that are not on the current page
if (urlHash === undefined || pageAnchors.length === 0 || urlPath !== '') {
function isAnchorBrokenLink(pageLink: string) {
const {route, anchor} = getRouteAndAnchor(pageLink, pagePath);
const targetRoute = allCollectedLinks[route];
// console.log('d:', pagePath, pageLinks, pageLink, pageAnchors, routes);
// console.log('debug2', route, anchor, targetRoute);
console.log(pageAnchors);
if (anchor === undefined) {
return false;
}

const brokenAnchors = pageAnchors.filter((anchor) => anchor !== urlHash);

return brokenAnchors.length > 0;
if (targetRoute) {
// console.log('debug3', targetRoute.anchors, anchor);
// means we have a link to an internal or external page that exists
if (targetRoute.anchors.includes(anchor) === false) {
return true;
}
return false;
}
return !allCollectedLinks[route]?.anchors.includes(anchor);
}

// console.log('routes:', routes);
// console.log('pagePath:', pagePath);
// console.log('pageLinks:', pageLinks);

const brokenLinks = pageLinks.flatMap((pageLink) => {
const resolvedLink = resolveLink(pageLink);
// console.log('resolvedLink:', resolvedLink);
if (isPathBrokenLink(resolvedLink)) {
return [{link: pageLink, resolvedLink, anchor: false}];
}
Expand Down Expand Up @@ -193,17 +199,33 @@ function getAllBrokenLinks({
allCollectedLinks,
(pageCollectedData, pagePath) =>
getPageBrokenLinks({
allCollectedLinks,
pageLinks: pageCollectedData.links,
pageAnchors: pageCollectedData.anchors,
pagePath,
routes: filteredRoutes,
}),
);
// const brokenLinks = Object.fromEntries(
// Object.entries(allBrokenLinks).filter(([, value]) => value.length > 0),
// );

const brokenLinks = Object.fromEntries(
Object.entries(allBrokenLinks).filter(([, value]) => value.length > 0),
Object.entries(allBrokenLinks).filter(
([, value]) => value[0]?.anchor === false,
),
);

const brokenAnchors = checkAnchorsInOtherRoutes(allCollectedLinks);
// split allBrokenLinks object into two separate objects brokenLinks and
// brokenAnchors based on anchor boolean value
const brokenAnchors = Object.fromEntries(
Object.entries(allBrokenLinks).filter(
([, value]) => value[0]?.anchor === true,
),
);
// console.log('allBrokenLinks:', allBrokenLinks);
// console.log('brokenAnchors:', brokenAnchors);
// console.log('brokenLinks:', brokenLinks);

return {brokenLinks, brokenAnchors};
}
Expand Down

0 comments on commit 660a527

Please sign in to comment.