George Kalpakas 2076bde100 build(docs-infra): take disambiguated doc paths into account when generating the sitemap (#41842)
In ##41788, the `disambiguateDocsPathsProcessor` was introduced to fix
an issue with case-insensitively equal paths. This processor may alter
the paths of some docs and thus their final URL in the app.

Previously, both the `disambiguateDocPathsProcessor` and the
`createSitemap` processor (which relies on the docs' computed paths to
generate the sitemap file) were configured to run before the
"rendering-docs" phase. However, this resulted in the
`disambiguateDocPathsProcessor`'s running after `createSitemap`, which
meant that the sitemap did not include the updated doc paths.

This commit fixes it by ensuring that the
`disambiguateDocPathsProcessor` is explicitly run before the
`createSitemap` processor, so that the latter will be able to take into
account any changes made by the former.

PR Close #41842
2021-04-27 14:05:23 -07:00

69 lines
2.3 KiB
JavaScript

/**
* @dgProcessor disambiguateDocPathsProcessor
* @description
*
* Ensures that docs that have the same path, other than case changes,
* are disambiguated.
*
* For example in Angular there is the `ROUTES` const and a `Routes` type.
* In a case-sensitive file-system these would both be stored at the paths
*
* ```
* aio/src/generated/router/Routes.json
* aio/src/generated/router/ROUTES.json
* ```
*
* but in a case-insensitive file-system these two paths point to the same file!
*/
module.exports = function disambiguateDocPathsProcessor(log) {
return {
$runAfter: ['paths-computed'],
$runBefore: ['rendering-docs', 'createSitemap'],
$process(docs) {
// Collect all the ambiguous docs, whose outputPath is are only different by casing.
const ambiguousDocMap = new Map();
for (const doc of docs) {
if (!doc.outputPath) {
continue;
}
const outputPath = doc.outputPath.toLowerCase();
if (!ambiguousDocMap.has(outputPath)) {
ambiguousDocMap.set(outputPath, []);
}
const ambiguousDocs = ambiguousDocMap.get(outputPath);
ambiguousDocs.push(doc);
}
// Create a disambiguator doc for each set of such ambiguous docs,
// and update the ambiguous docs to have unique `path` and `outputPath` properties.
for (const [outputPath, ambiguousDocs] of ambiguousDocMap) {
if (ambiguousDocs.length === 1) {
continue;
}
log.debug('Docs with ambiguous outputPath:' + ambiguousDocs.map((d, i) => `\n - ${d.id}: "${d.outputPath}" replaced with "${convertPath(d.outputPath, i)}".`));
const doc = ambiguousDocs[0];
const path = doc.path;
const id = `${doc.id.toLowerCase()}-disambiguator`;
const title = `${doc.id.toLowerCase()} (disambiguation)`;
const aliases = [id];
docs.push({ docType: 'disambiguator', id, title, aliases, path, outputPath, docs: ambiguousDocs });
// Update the paths
let count = 0;
for (const doc of ambiguousDocs) {
doc.path = convertPath(doc.path, count);
doc.outputPath = convertPath(doc.outputPath, count);
count += 1;
}
}
}
};
};
function convertPath(path, count) {
// Add the counter before any extension
return path.replace(/(\.[^.]*)?$/, `-${count}$1`);
}