-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Expand file tree
/
Copy pathmdn-content-inventory.js
More file actions
94 lines (81 loc) · 2.89 KB
/
mdn-content-inventory.js
File metadata and controls
94 lines (81 loc) · 2.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/* This file is a part of @mdn/browser-compat-data
* See LICENSE file for more information. */
import mdnContentInventory from '@ddbeck/mdn-content-inventory';
/** @type {Map<string, string>} lowercase slug → canonical slug */
const slugs = (() => {
/** @type {Map<string, string>} */
const result = new Map();
for (const item of mdnContentInventory.inventory) {
result.set(item.frontmatter.slug.toLowerCase(), item.frontmatter.slug);
}
return result;
})();
// Page types that are overview/landing pages rather than specific reference pages.
// When a BCD key appears on both one of these and a reference page, the reference page wins.
const OVERVIEW_PAGE_TYPES = new Set([
'web-api-overview',
'guide',
'landing-page',
]);
/**
* Build a map from BCD path to MDN slug, preferring specific reference pages.
* @param {typeof mdnContentInventory.inventory} inventory The MDN content inventory to process
* @returns {Map<string, string>} Map from BCD path to MDN slug
*/
export const buildSlugByPath = (inventory) => {
/**
* @typedef {{ slug: string, isSoleKey: boolean }} SlugEntry
* @type {Map<string, SlugEntry[]>}
*/
const slugsByPath = new Map();
for (const item of inventory) {
if (!('browser-compat' in item.frontmatter)) {
continue;
}
if (OVERVIEW_PAGE_TYPES.has(item.frontmatter['page-type'])) {
// Skip overview/landing pages; a reference page for the same BCD key is preferred.
continue;
}
const value = item.frontmatter['browser-compat'];
const paths = Array.isArray(value) ? value : [value];
const isSoleKey = paths.length === 1;
const slug = item.frontmatter.slug;
for (const path of paths) {
const slugTail = slug.split('/').at(-1);
const pathTail = path.split('.').at(-1);
if (!slugTail.includes(pathTail) && !pathTail?.includes(slugTail)) {
// Ignore unrelated pages/features.
continue;
}
if (!slugsByPath.has(path)) {
slugsByPath.set(path, []);
}
slugsByPath.get(path)?.push({ slug, isSoleKey });
}
}
/** @type {Map<string, string>} */
const result = new Map();
slugsByPath.forEach((entries, key) => {
if (entries.length === 1) {
result.set(key, entries[0].slug);
} else {
// When multiple pages list this key, prefer the one where it's the only key.
const soleKeyEntries = entries.filter((e) => e.isSoleKey);
if (soleKeyEntries.length === 1) {
result.set(key, soleKeyEntries[0].slug);
}
}
});
return result;
};
/** @type {Map<string, string>} BCD path → MDN slug (only unambiguous mappings) */
const slugByPath = buildSlugByPath(mdnContentInventory.inventory);
/**
* Mutable inventory data derived from `@ddbeck/mdn-content-inventory`.
* Properties can be reassigned in tests to inject mock data.
*/
export const inventory = {
slugs,
slugByPath,
redirects: mdnContentInventory.redirects,
};