-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathconfig.js
238 lines (203 loc) · 10.5 KB
/
config.js
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
// mods
import {existsSync} from 'node:fs';
import {dirname, resolve} from 'node:path';
import {fileURLToPath} from 'node:url';
import isEmpty from 'lodash-es/isEmpty.js';
import merge from 'lodash-es/merge.js';
import Debug from 'debug';
import {defineConfigWithTheme} from 'vitepress';
// utils
import {default as createContainer} from './utils/create-container.js';
import {default as getBaseUrl} from './utils/get-base-url.js';
import {default as getContributors} from './utils/get-contributors.js';
import {default as getGaHeaders} from './utils/get-ga-headers.js';
import {default as getHubspotHeaders} from './utils/get-hubspot-headers.js';
import {default as getTags} from './utils/get-tags.js';
import {default as normalizeMVB} from './utils/normalize-mvb.js';
import {default as parseLayouts} from './utils/parse-layouts.js';
import {default as traverseUp} from './utils/traverse-up.js';
// node/plugins
import {default as addContributors} from './node/add-contributors.js';
import {default as addLayoutsPlugin} from './vite/add-layout-components-plugin.js';
import {default as addMetadata} from './node/add-metadata.js';
import {default as augmentAuthors} from './node/augment-authors.js';
import {default as buildCollections} from './node/build-collections.js';
import {default as normalizeFrontmatter} from './node/normalize-frontmatter.js';
import {default as normalizeLegacyFrontmatter} from './node/normalize-legacy-frontmatter.js';
import {default as parseCollections} from './node/parse-collections.js';
import {default as generateFeeds} from './node/generate-feeds.js';
import {default as generateRobotsTxt} from './node/generate-robots.js';
import {default as linkOverridePlugin} from './markdown/link-override-plugin.js';
import {tabsMarkdownPlugin} from 'vitepress-plugin-tabs';
import {default as tabsMarkdownOverridePlugin} from './markdown/tabs-override-plugin.js';
import {default as urlLoader} from './vite/url-loader.js';
// vitepress patches
import {default as patchVPMenuColumnsPlugin} from './vite/patch-vp-menu-columns-plugin.js';
import {default as patchVPUseSidebarControl} from './vite/patch-vp-use-sidebar-control.js';
// configsets
import {default as baseConfig} from './config/defaults.js';
import {default as lando3BaseConfig} from './config/landov3.js';
import {default as lando4BaseConfig} from './config/landov4.js';
export async function defineConfig(userConfig = {}, defaults = {}) {
const debug = Debug('@lando/vpltheme'); // eslint-disable-line
// theme root
userConfig.themeRoot = dirname(fileURLToPath(import.meta.url));
// prefer landov4 if defaults not set
if (isEmpty(userConfig.defaults) && userConfig.landoDocs === 4) {
debug('no user defaults set, using lando v4 defaults');
defaults = lando4BaseConfig(userConfig);
// ditto but for lando v3
} else if (isEmpty(userConfig.defaults) && userConfig.landoDocs === 3) {
debug('no user defaults set, using lando v3 defaults');
defaults = lando3BaseConfig(userConfig);
// Same as above but for legacy things
} else if (isEmpty(userConfig.defaults) && (userConfig.landoDocs || userConfig.lando)) {
debug('no user defaults set, using lando v3 defaults');
defaults = lando3BaseConfig(userConfig);
// Otherwise if we are empty then just set to defaults
} else if (isEmpty(userConfig.defaults)) {
debug('no user defaults set, using theme defaults');
defaults = baseConfig(userConfig);
}
// merge config sources
const config = merge({}, defaults, userConfig);
// log
debug('incoming vitepress configuration %O', config);
// normalize mvb stuff as needed
if (config?.themeConfig.multiVersionBuild) {
config.themeConfig.multiVersionBuild = normalizeMVB({...config.themeConfig.multiVersionBuild, siteBase: config.base});
debug('normalized mvb config to %o', config.themeConfig.multiVersionBuild);
}
// get git root if its not defined
if (!config.gitRoot) {
const gitDir = traverseUp(['.git'], resolve(config.themeRoot, '..')).find(dir => existsSync(dir));
config.gitRoot = gitDir ? resolve(gitDir, '..') : config.themeRoot;
debug('automatically set gitRoot to %o', config.gitRoot);
}
// If we want to show the shared navbar then lets add it to the begining of the navbar
if (Array.isArray(config?.themeConfig?.sharedNav)) {
config.themeConfig.nav = config.themeConfig.sharedNav.concat(config.themeConfig.nav);
debug('prepended shared navbar to user specified navbar with %o', config.themeConfig.sharedNav);
}
// explode
const {buildEnd, markdown, themeConfig, transformPageData, sitemap, vite} = config;
// normalize id
if (typeof themeConfig.internalDomain === 'string') themeConfig.internalDomain = [themeConfig.internalDomain];
if (typeof themeConfig.internalDomains === 'string') themeConfig.internalDomains = [themeConfig.internalDomains];
themeConfig.internalDomains = [...themeConfig.internalDomain, ...themeConfig.internalDomains];
// normalize contribs
if (themeConfig.contributors === true) themeConfig.contributors = baseConfig.themeConfig.contributors;
// normalize layouts
if (Object.keys(themeConfig.layouts).length > 0) themeConfig.layouts = parseLayouts(themeConfig.layouts);
// normalize sitemap
if (!sitemap.hostname && themeConfig?.autometa?.canonicalUrl) sitemap.hostname = themeConfig.autometa.canonicalUrl;
// attempt to set a baseurl
if (!config.baseUrl) config.baseUrl = getBaseUrl() ?? config.basethemeConfig?.autometa?.canonicalUrl ?? sitemap.hostname;
// extract
const {containers, contributors, ga, hubspot, internalDomains, layouts} = themeConfig;
// debug here so it doesnt print like 10 times
for (const [name, opts] of Object.entries(containers)) {
debug('added custom markdown container %o with config %o', name, opts);
}
// vite aliases
vite.resolve.alias.push(...[
{find: /^.*\/VPAlgoliaSearchBox\.vue$/, replacement: fileURLToPath(new URL('./components/VPLAlgoliaSearchBox.vue', import.meta.url))},
{find: /^.*\/VPDocFooter\.vue$/, replacement: fileURLToPath(new URL('./components/VPLDocFooter.vue', import.meta.url))},
{find: /^.*\/VPLink\.vue$/, replacement: fileURLToPath(new URL('./components/VPLLink.vue', import.meta.url))},
{find: /^.*\/VPMenuGroup\.vue$/, replacement: fileURLToPath(new URL('./components/VPLMenuGroup.vue', import.meta.url))},
{find: /^.*\/VPNavBarMenuGroup\.vue$/, replacement: fileURLToPath(new URL('./components/VPLNavBarMenuGroup.vue', import.meta.url))},
{find: /^.*\/VPTeamMembersItem\.vue$/, replacement: fileURLToPath(new URL('./components/VPLTeamMembersItem.vue', import.meta.url))},
]);
// plguins
vite.plugins.push(...[
addLayoutsPlugin(layouts, {debug: debug.extend('vite-plugin')}),
patchVPMenuColumnsPlugin({debug: debug.extend('vitepress-patcher')}),
patchVPUseSidebarControl({debug: debug.extend('vitepress-patcher')}),
urlLoader({debug: debug.extend('url-loader')}),
]);
// deps
vite.optimizeDeps.exclude.push('fsevents', '@lando/vitepress-theme-default-plus');
// ssr
vite.ssr.noExternal.push('@lando/vitepress-theme-default-plus');
// debug
debug('added vite resolver config %O', vite.resolve);
debug('added vite plugins %O', vite.plugins);
debug('added vite optimizeDeps config %O', vite.optimizeDeps);
debug('added vite ssr config %O', vite.ssr);
// markdown plugins
markdown.config = md => {
// add custom markdown containers, including tabs
for (const [name, opts] of Object.entries(containers)) {
md.use(...createContainer(name, opts, md));
}
// add tabs plugin
md.use(tabsMarkdownPlugin);
// override the tabs container so we can inject styling
md.use(tabsMarkdownOverridePlugin, {debug: debug.extend('markdown-plugin')});
// override the link plugin so it can handle internal domains
md.use(linkOverridePlugin, {
target: '_blank',
rel: 'noreferrer',
...markdown.externalLinks,
},
config.base,
internalDomains,
debug.extend('markdown-plugin'),
);
};
// add google analytics
if (ga !== false && ga.id) {
config.head.push(...getGaHeaders(ga.id));
debug('added google analytics/gtm tracking with %o', ga);
}
// add hubspot
if (hubspot !== false && hubspot.id) {
config.head.push(...getHubspotHeaders(hubspot.id));
debug('added hubspot tracking with %o', hubspot);
}
// get full team info
const copts = {debug: debug.extend('get-contribs'), paths: []};
const team = contributors !== false ? await getContributors(config.gitRoot, contributors, copts) : [];
debug('discovered full team info %o', team);
// get full version alias information but let this fail
try {
const tags = await getTags(config.gitRoot, undefined, {debug: debug.extend('get-tags')});
themeConfig.versions = tags.aliases ?? {};
debug('discovered version aliases %o', config.versions);
} catch (error) {
debug('unable to get version alias information with error %o', error);
}
// build robots.txt and rssfeed
config.buildEnd = async siteConfig => {
// generate robots txt
await generateRobotsTxt(siteConfig, {debug: debug.extend('generate-robots')});
// generate rss feeds
await generateFeeds(siteConfig, {debug: debug.extend('generate-feeds')});
// run any user specified transformPageData if its a function
if (buildEnd && typeof buildEnd === 'function') {
await buildEnd(siteConfig, {debug: debug.extend('user-build-end')});
}
};
// augment pages with additional data
config.transformPageData = async (pageData, {siteConfig}) => {
// make sure siteConfig.collections exists and is populated
await buildCollections(siteConfig, {debug: debug.extend('build-collections')});
// normalize legacy frontmatter
await normalizeLegacyFrontmatter(pageData, {siteConfig, debug: debug.extend('page-data')});
// normalize frontmatter
await normalizeFrontmatter(pageData, {siteConfig, debug: debug.extend('page-data')});
// add contributor information
await addContributors(pageData, {siteConfig, debug: debug.extend('page-data')});
// add metadata information
await addMetadata(pageData, {siteConfig, debug: debug.extend('page-data')});
// parse collections
await parseCollections(pageData, {siteConfig, debug: debug.extend('page-data')});
// normalize authors
await augmentAuthors(pageData, {team, debug: debug.extend('page-data')});
// run any user specified transformPageData if its a function
if (transformPageData && typeof transformPageData === 'function') {
await transformPageData(pageData, {siteConfig, debug: debug.extend('user-transform-page-data')});
}
};
return defineConfigWithTheme(config);
}