-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathconfig.mjs
More file actions
103 lines (92 loc) · 3.29 KB
/
config.mjs
File metadata and controls
103 lines (92 loc) · 3.29 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
95
96
97
98
99
100
101
102
103
'use strict';
import { LANGS } from '@node-core/rehype-shiki';
import getConfig from '../../../utils/configuration/index.mjs';
import { populate } from '../../../utils/configuration/templates.mjs';
import { getVersionFromSemVer } from '../../../utils/generators.mjs';
import { omitKeys } from '../../../utils/misc.mjs';
import { getSortedHeadNodes } from '../../jsx-ast/utils/getSortedHeadNodes.mjs';
/**
* Pre-compute version entries with labels and URL templates.
* Each entry's `url` still contains `{path}` for per-page resolution.
*
* @param {object} changelog
* @param {string} pageURLBase
* @returns {Array<{url: string, label: string, major: number}>}
*/
export function buildVersionEntries(changelog, pageURLBase) {
return changelog.map(({ version, isLts, isCurrent }) => {
let label = `v${getVersionFromSemVer(version)}`;
const url = pageURLBase.replace('{version}', label);
if (isLts) {
label += ' (LTS)';
}
if (isCurrent) {
label += ' (Current)';
}
return { url, label, major: version.major };
});
}
/**
* Pre-compute sorted page list for sidebar navigation.
*
* @param {Array<import('../../jsx-ast/utils/buildContent.mjs').JSXContent>} input
* @returns {Array<[string, string]>}
*/
export function buildPageList(input) {
const headNodes = getSortedHeadNodes(input.map(e => e.data));
return headNodes.map(node => [node.heading.data.name, node.path]);
}
/**
* Pre-compute Shiki language display name map entries.
*
* @returns {Array<[string[], string]>}
*/
export function buildLanguageDisplayNameMap() {
return [
...new Map(
LANGS.map(({ name, aliases = [], displayName }) => [
name,
[[...aliases, name], displayName],
])
).values(),
];
}
/**
* Generates the JavaScript source code for the `#theme/config` virtual module.
*
* This module exposes web configuration and pre-computed build-time data as
* named exports so that UI components can import only what they need, and
* tree-shaking removes the rest.
*
* Values are pre-populated as much as possible at build time to minimize
* client-side computation. For example, version entries include their
* display labels and URL templates (with only `{path}` remaining for
* per-page resolution by components).
*
* @param {Array<import('../../jsx-ast/utils/buildContent.mjs').JSXContent>} input - JSX AST entries with .data metadata
* @returns {string} JavaScript source code string with named exports
*/
export default function createConfigSource(input) {
const { version: configVersion, ...config } = getConfig('web');
const version = `v${configVersion.version}`;
const editURL = populate(config.editURL, { ...config, version });
const pageURL = populate(config.pageURL, config);
const exports = {
...omitKeys(
config,
// These are keys that are large, and not needed by components, so we ignore them
['changelog', 'index', 'imports', 'virtualImports']
),
version,
versions: buildVersionEntries(config.changelog, pageURL),
editURL,
pages: buildPageList(input),
};
const lines = Object.entries(exports).map(
([k, v]) => `export const ${k} = ${JSON.stringify(v)};`
);
lines.push(
`export const languageDisplayNameMap = new Map(${JSON.stringify(buildLanguageDisplayNameMap())});`
);
return lines.join('\n');
}