-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathconfig.mjs
More file actions
108 lines (96 loc) · 3.76 KB
/
config.mjs
File metadata and controls
108 lines (96 loc) · 3.76 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
104
105
106
107
108
'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 { 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} config
* @param {string} pageURLBase
* @returns {Array<{url: string, label: string, major: number}>}
*/
export function buildVersionEntries(config, pageURLBase) {
return config.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, string?]>}
*/
export function buildPageList(input) {
const headNodes = getSortedHeadNodes(input.map(({ data }) => data));
return headNodes.map(({ path, category, heading }) => [
heading.data.name,
path,
category,
]);
}
/**
* 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 config = getConfig('web');
const currentVersion = `v${config.version.version}`;
const templateVars = { ...config, version: currentVersion };
// Partially populate URL templates: resolve config-level placeholders,
// leave {path} for per-page resolution by components
const editURL = populate(config.editURL, templateVars);
// Resolve the pageURL template once with config-level values, leaving
// {version} and {path} as the only remaining placeholders
// eslint-disable-next-line no-unused-vars
const { version, ...configWithoutVersion } = config;
const pageURLBase = populate(config.pageURL, configWithoutVersion);
const versions = buildVersionEntries(config, pageURLBase);
const pages = buildPageList(input);
const shikiDisplayNameMap = buildLanguageDisplayNameMap();
return [
`export const title = ${JSON.stringify(config.title)};`,
`export const repository = ${JSON.stringify(config.repository)};`,
`export const version = ${JSON.stringify(currentVersion)};`,
`export const versions = ${JSON.stringify(versions)};`,
`export const editURL = ${JSON.stringify(editURL)};`,
`export const pages = ${JSON.stringify(pages)};`,
`export const languageDisplayNameMap = new Map(${JSON.stringify(shikiDisplayNameMap)});`,
].join('\n');
}