@vuepress/core 2.0.0-rc.3 → 2.0.0-rc.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,1017 +1,1027 @@
1
- // src/app/prepare/prepareClientConfigs.ts
2
- var prepareClientConfigs = async (app) => {
3
- const clientConfigFiles = await app.pluginApi.hooks.clientConfigFile.process(app);
4
- const content = `${clientConfigFiles.map((filePath, index) => `import clientConfig${index} from '${filePath}'`).join("\n")}
1
+ import { createRequire } from "node:module";
2
+ import { ensureLeadingSlash, formatDateString, inferRoutePath, isFunction, isString, normalizeRoutePath, omit, removeLeadingSlash, resolveLocalePath } from "@vuepress/shared";
3
+ import { colors, debug, fs, hash, logger, path, sanitizeFileName, templateRenderer, tinyglobby, transformPathToFileName, warn } from "@vuepress/utils";
4
+ import { createMarkdown } from "@vuepress/markdown";
5
+ //#region src/app/prepare/prepareClientConfigs.ts
6
+ /**
7
+ * Generate client configs temp file
8
+ *
9
+ * @internal
10
+ */
11
+ const prepareClientConfigs = async (app) => {
12
+ const clientConfigFiles = await app.pluginApi.hooks.clientConfigFile.process(app);
13
+ const content = `\
14
+ ${clientConfigFiles.map((filePath, index) => `import * as clientConfig${index} from '${filePath}'`).join("\n")}
5
15
 
6
16
  export const clientConfigs = [
7
17
  ${clientConfigFiles.map((_, index) => ` clientConfig${index},`).join("\n")}
8
- ]
18
+ ].map((m) => m.default).filter(Boolean)
9
19
  `;
10
- await app.writeTemp("internal/clientConfigs.js", content);
20
+ await app.writeTemp("internal/clientConfigs.js", content);
11
21
  };
12
-
13
- // src/app/prepare/preparePageChunk.ts
14
- var HMR_CODE = `
22
+ //#endregion
23
+ //#region src/page/inferPagePath.ts
24
+ /**
25
+ * Infer page path according to file path
26
+ *
27
+ * @internal
28
+ */
29
+ const inferPagePath = ({ app, filePathRelative, options }) => {
30
+ if (options.path) {
31
+ const pathLocale = resolveLocalePath(app.siteData.locales, options.path);
32
+ return {
33
+ pathInferred: filePathRelative ? inferRoutePath(ensureLeadingSlash(filePathRelative)) : null,
34
+ pathLocale
35
+ };
36
+ }
37
+ if (!filePathRelative) return {
38
+ pathInferred: null,
39
+ pathLocale: "/"
40
+ };
41
+ const pathInferred = inferRoutePath(ensureLeadingSlash(filePathRelative));
42
+ return {
43
+ pathInferred,
44
+ pathLocale: resolveLocalePath(app.siteData.locales, pathInferred)
45
+ };
46
+ };
47
+ //#endregion
48
+ //#region src/page/parsePageContent.ts
49
+ /**
50
+ * Render page content and extract related info
51
+ *
52
+ * @internal
53
+ */
54
+ const parsePageContent = ({ app, content, filePath, filePathRelative, options }) => {
55
+ const markdownEnv = {
56
+ base: app.options.base,
57
+ filePath,
58
+ filePathRelative,
59
+ frontmatter: { ...options.frontmatter }
60
+ };
61
+ const contentRendered = app.markdown.render(content, markdownEnv);
62
+ /* istanbul ignore next */
63
+ const { frontmatter = {}, headers = [], importedFiles = [], links = [], sfcBlocks = {
64
+ template: null,
65
+ script: null,
66
+ scriptSetup: null,
67
+ scripts: [],
68
+ styles: [],
69
+ customBlocks: []
70
+ }, title = "", ...extraMarkdownEnv } = markdownEnv;
71
+ return {
72
+ contentRendered,
73
+ deps: importedFiles,
74
+ frontmatter,
75
+ headers,
76
+ links,
77
+ markdownEnv: omit(extraMarkdownEnv, "base", "content", "filePath", "filePathRelative", "frontmatter"),
78
+ sfcBlocks,
79
+ title: frontmatter.title ? `${frontmatter.title}` : title
80
+ };
81
+ };
82
+ //#endregion
83
+ //#region src/page/resolvePageChunkInfo.ts
84
+ /**
85
+ * Resolve page chunk file related info
86
+ *
87
+ * @internal
88
+ */
89
+ const resolvePageChunkInfo = ({ app, filePath, filePathRelative, htmlFilePathRelative }) => {
90
+ const chunkName = transformPathToFileName(htmlFilePathRelative);
91
+ if (filePath && filePathRelative) return {
92
+ chunkFilePath: filePath,
93
+ chunkFilePathRelative: filePathRelative,
94
+ chunkName
95
+ };
96
+ const chunkFilePathRelative = path.join("pages", `${htmlFilePathRelative}.vue`);
97
+ return {
98
+ chunkFilePath: app.dir.temp(chunkFilePathRelative),
99
+ chunkFilePathRelative,
100
+ chunkName
101
+ };
102
+ };
103
+ //#endregion
104
+ //#region src/page/resolvePageContent.ts
105
+ const log$5 = debug("vuepress:core/page");
106
+ const FALLBACK_CONTENT = "";
107
+ /**
108
+ * Resolve page content according to `content` or `filePath`
109
+ *
110
+ * @internal
111
+ */
112
+ const resolvePageContent = async ({ filePath, options }) => {
113
+ if (isString(options.content)) return options.content;
114
+ if (filePath) try {
115
+ return await fs.readFile(filePath, "utf-8");
116
+ } catch (e) {
117
+ log$5(e instanceof Error ? e.message : e);
118
+ }
119
+ return FALLBACK_CONTENT;
120
+ };
121
+ //#endregion
122
+ //#region src/page/resolvePageDate.ts
123
+ const FILENAME_DATE_RE = /^(\d{4})-(\d{1,2})(?:-(\d{1,2}))?-(.*)$/;
124
+ const DIRNAME_DATE_RE = /(\d{4})\/(\d{1,2})(?:\/(\d{1,2}))?(\/|$)/;
125
+ const DEFAULT_DATE = "0000-00-00";
126
+ /**
127
+ * Resolve page date according to frontmatter or file path
128
+ *
129
+ * It will be resolved as 'yyyy-MM-dd' format
130
+ *
131
+ * @internal
132
+ */
133
+ const resolvePageDate = ({ frontmatter, filePathRelative }) => {
134
+ if (frontmatter.date instanceof Date) return formatDateString([
135
+ frontmatter.date.getUTCFullYear(),
136
+ frontmatter.date.getUTCMonth() + 1,
137
+ frontmatter.date.getUTCDate()
138
+ ].join("-"), DEFAULT_DATE);
139
+ if (isString(frontmatter.date)) return formatDateString(frontmatter.date, DEFAULT_DATE);
140
+ if (filePathRelative === null) return DEFAULT_DATE;
141
+ const filename = path.parse(filePathRelative).name;
142
+ if (filename) {
143
+ const matches = filename.match(FILENAME_DATE_RE);
144
+ if (matches) return formatDateString(`${matches[1]}-${matches[2]}-${matches[3] ?? "01"}`, DEFAULT_DATE);
145
+ }
146
+ const dirname = path.dirname(filePathRelative);
147
+ if (dirname !== ".") {
148
+ const matches = dirname.match(DIRNAME_DATE_RE);
149
+ if (matches) return formatDateString(`${matches[1]}-${matches[2]}-${matches[3] ?? "01"}`, DEFAULT_DATE);
150
+ }
151
+ return DEFAULT_DATE;
152
+ };
153
+ //#endregion
154
+ //#region src/page/resolvePageFilePath.ts
155
+ /**
156
+ * Resolve absolute and relative path of page file
157
+ *
158
+ * @internal
159
+ */
160
+ const resolvePageFilePath = ({ app, options }) => {
161
+ if (!options.filePath) return {
162
+ filePath: null,
163
+ filePathRelative: null
164
+ };
165
+ if (!path.isAbsolute(options.filePath)) throw logger.createError(`filePath is not absolute file path: ${options.filePath}}`);
166
+ return {
167
+ filePath: options.filePath,
168
+ filePathRelative: path.relative(app.dir.source(), options.filePath)
169
+ };
170
+ };
171
+ //#endregion
172
+ //#region src/page/resolvePageHtmlInfo.ts
173
+ /**
174
+ * Resolve page rendered html file path
175
+ *
176
+ * @internal
177
+ */
178
+ const resolvePageHtmlInfo = ({ app, path: pagePath }) => {
179
+ const path = decodeURI(pagePath);
180
+ const htmlFilePathRelative = removeLeadingSlash(path.endsWith("/") ? `${path}index.html` : path.endsWith(".html") ? path : `${path}.html`);
181
+ return {
182
+ htmlFilePath: app.dir.dest(htmlFilePathRelative),
183
+ htmlFilePathRelative
184
+ };
185
+ };
186
+ //#endregion
187
+ //#region src/page/resolvePageLang.ts
188
+ /**
189
+ * Resolve language of page
190
+ *
191
+ * @internal
192
+ */
193
+ const resolvePageLang = ({ app, frontmatter, pathLocale }) => {
194
+ if (isString(frontmatter.lang) && frontmatter.lang) return frontmatter.lang;
195
+ return app.siteData.locales[pathLocale]?.lang ?? app.siteData.lang;
196
+ };
197
+ //#endregion
198
+ //#region src/page/resolvePagePath.ts
199
+ /**
200
+ * Resolve the final route path of a page
201
+ *
202
+ * @internal
203
+ */
204
+ const resolvePagePath = ({ permalink, pathInferred, options }) => {
205
+ const pagePath = options.path || permalink || pathInferred;
206
+ if (!pagePath) throw logger.createError(`page path is empty, page options: ${JSON.stringify(options, null, 2)}`);
207
+ return encodeURI(pagePath.split("/").map(sanitizeFileName).join("/"));
208
+ };
209
+ //#endregion
210
+ //#region src/page/resolvePagePermalink.ts
211
+ /**
212
+ * Resolve page permalink from frontmatter / options / pattern
213
+ *
214
+ * @internal
215
+ */
216
+ const resolvePagePermalink = ({ app, frontmatter, slug, date, pathInferred, pathLocale }) => {
217
+ if (frontmatter.permalink === null) return null;
218
+ if (isString(frontmatter.permalink)) return frontmatter.permalink;
219
+ if (frontmatter.permalinkPattern === null) return null;
220
+ const permalinkPattern = frontmatter.permalinkPattern || app.options.permalinkPattern;
221
+ if (!isString(permalinkPattern)) return null;
222
+ const [year, month, day] = date.split("-");
223
+ return ensureLeadingSlash(path.join(pathLocale, permalinkPattern.replace(/:year/, year).replace(/:month/, month).replace(/:day/, day).replace(/:slug/, slug).replace(/:raw/, pathInferred?.replace(/^\//, "") ?? "")));
224
+ };
225
+ //#endregion
226
+ //#region src/page/resolvePageRouteMeta.ts
227
+ /**
228
+ * Resolve page route meta
229
+ *
230
+ * @internal
231
+ */
232
+ const resolvePageRouteMeta = ({ frontmatter }) => frontmatter.routeMeta ?? {};
233
+ //#endregion
234
+ //#region src/page/resolvePageSlug.ts
235
+ const DATE_RE = /(\d{4}-\d{1,2}(-\d{1,2})?)-(.*)/;
236
+ /**
237
+ * Resolve page slug from filename
238
+ *
239
+ * @internal
240
+ */
241
+ const resolvePageSlug = ({ filePathRelative }) => {
242
+ if (!filePathRelative) return "";
243
+ const filename = path.parse(filePathRelative).name;
244
+ const match = filename.match(DATE_RE);
245
+ return match ? match[3] : filename;
246
+ };
247
+ //#endregion
248
+ //#region src/page/createPage.ts
249
+ /**
250
+ * Create vuepress page object
251
+ */
252
+ const createPage = async (app, options) => {
253
+ await app.pluginApi.hooks.extendsPageOptions.process(options, app);
254
+ const { filePath, filePathRelative } = resolvePageFilePath({
255
+ app,
256
+ options
257
+ });
258
+ const content = await resolvePageContent({
259
+ filePath,
260
+ options
261
+ });
262
+ const { contentRendered, deps, frontmatter, headers, links, markdownEnv, sfcBlocks, title } = parsePageContent({
263
+ app,
264
+ content,
265
+ filePath,
266
+ filePathRelative,
267
+ options
268
+ });
269
+ const routeMeta = resolvePageRouteMeta({ frontmatter });
270
+ const slug = resolvePageSlug({ filePathRelative });
271
+ const date = resolvePageDate({
272
+ frontmatter,
273
+ filePathRelative
274
+ });
275
+ const { pathInferred, pathLocale } = inferPagePath({
276
+ app,
277
+ filePathRelative,
278
+ options
279
+ });
280
+ const lang = resolvePageLang({
281
+ app,
282
+ frontmatter,
283
+ pathLocale
284
+ });
285
+ const permalink = resolvePagePermalink({
286
+ app,
287
+ frontmatter,
288
+ slug,
289
+ date,
290
+ pathInferred,
291
+ pathLocale
292
+ });
293
+ const path = resolvePagePath({
294
+ permalink,
295
+ pathInferred,
296
+ options
297
+ });
298
+ const { htmlFilePath, htmlFilePathRelative } = resolvePageHtmlInfo({
299
+ app,
300
+ path
301
+ });
302
+ const { chunkFilePath, chunkFilePathRelative, chunkName } = resolvePageChunkInfo({
303
+ app,
304
+ filePath,
305
+ filePathRelative,
306
+ htmlFilePathRelative
307
+ });
308
+ const page = {
309
+ data: {
310
+ path,
311
+ title,
312
+ lang,
313
+ frontmatter
314
+ },
315
+ path,
316
+ title,
317
+ lang,
318
+ frontmatter,
319
+ headers,
320
+ content,
321
+ contentRendered,
322
+ date,
323
+ deps,
324
+ links,
325
+ markdownEnv,
326
+ pathInferred,
327
+ pathLocale,
328
+ permalink,
329
+ routeMeta,
330
+ sfcBlocks,
331
+ slug,
332
+ filePath,
333
+ filePathRelative,
334
+ chunkFilePath,
335
+ chunkFilePathRelative,
336
+ chunkName,
337
+ htmlFilePath,
338
+ htmlFilePathRelative
339
+ };
340
+ await app.pluginApi.hooks.extendsPage.process(page, app);
341
+ return page;
342
+ };
343
+ //#endregion
344
+ //#region src/page/renderPageToVue.ts
345
+ const TEMPLATE_WRAPPER_TAG_OPEN = "<div>";
346
+ const TEMPLATE_WRAPPER_TAG_CLOSE = "</div>";
347
+ const SCRIPT_TAG_OPEN = "<script>";
348
+ const SCRIPT_TAG_CLOSE = "<\/script>";
349
+ const SCRIPT_TAG_OPEN_LANG_TS_REGEX = /<\s*script[^>]*\blang=['"]ts['"][^>]*/;
350
+ const SCRIPT_TAG_OPEN_LANG_TS = "<script lang=\"ts\">";
351
+ const SCRIPT_DEFAULT_EXPORT_REGEX = /((?:^|\n|;)\s*)export(\s*)default/;
352
+ const SCRIPT_DEFAULT_NAMED_EXPORT_REGEX = /((?:^|\n|;)\s*)export(.+)as(\s*)default/;
353
+ const SCRIPT_DEFAULT_EXPORT_CODE_TEMPLATE_OUTLET = "__SCRIPT_DEFAULT_EXPORT__";
354
+ const SCRIPT_DEFAULT_EXPORT_CODE_TEMPLATE = `export default { name: ${SCRIPT_DEFAULT_EXPORT_CODE_TEMPLATE_OUTLET} }`;
355
+ const PAGE_DATA_CODE_VAR_NAME = "_pageData";
356
+ const PAGE_DATA_CODE_TEMPLATE_OUTLET = "__PAGE_DATA__";
357
+ const PAGE_DATA_CODE_TEMPLATE = `export const ${PAGE_DATA_CODE_VAR_NAME} = JSON.parse(${PAGE_DATA_CODE_TEMPLATE_OUTLET})`;
358
+ const HMR_CODE$2 = `
15
359
  if (import.meta.webpackHot) {
16
360
  import.meta.webpackHot.accept()
17
- if (__VUE_HMR_RUNTIME__.updatePageData) {
18
- __VUE_HMR_RUNTIME__.updatePageData(data)
19
- }
361
+ __VUE_HMR_RUNTIME__.updatePageData?.(${PAGE_DATA_CODE_VAR_NAME})
20
362
  }
21
363
 
22
364
  if (import.meta.hot) {
23
- import.meta.hot.accept(({ data }) => {
24
- __VUE_HMR_RUNTIME__.updatePageData(data)
365
+ import.meta.hot.accept((m) => {
366
+ __VUE_HMR_RUNTIME__.updatePageData?.(m.${PAGE_DATA_CODE_VAR_NAME})
25
367
  })
26
368
  }
27
369
  `;
28
- var preparePageChunk = async (app, page) => {
29
- let content = `import comp from ${JSON.stringify(page.componentFilePath)}
30
- const data = JSON.parse(${JSON.stringify(JSON.stringify(page.data))})
31
- export { comp, data }
32
- `;
33
- if (app.env.isDev) {
34
- content += HMR_CODE;
35
- }
36
- await app.writeTemp(page.chunkFilePathRelative, content);
370
+ /**
371
+ * Util to resolve the open tag of script block
372
+ */
373
+ const resolveScriptTagOpen = (page) => {
374
+ if (page.sfcBlocks.script?.tagOpen) return page.sfcBlocks.script.tagOpen;
375
+ return page.sfcBlocks.scriptSetup?.tagOpen.match(SCRIPT_TAG_OPEN_LANG_TS_REGEX) ? SCRIPT_TAG_OPEN_LANG_TS : SCRIPT_TAG_OPEN;
37
376
  };
38
-
39
- // src/app/prepare/preparePageComponent.ts
40
- var preparePageComponent = async (app, page) => {
41
- await app.writeTemp(
42
- page.componentFilePathRelative,
43
- [
44
- // #688: wrap the content of `<template>` with a `<div>` to avoid some potential issues of fragment component
45
- `${page.sfcBlocks.template?.tagOpen}<div>${page.sfcBlocks.template?.contentStripped}</div>${page.sfcBlocks.template?.tagClose}
46
- `,
47
- // hoist `<script>`, `<style>` and other custom blocks
48
- page.sfcBlocks.script?.content,
49
- page.sfcBlocks.scriptSetup?.content,
50
- ...page.sfcBlocks.styles.map((item) => item.content),
51
- ...page.sfcBlocks.customBlocks.map((item) => item.content)
52
- ].join("\n")
53
- );
377
+ /**
378
+ * Util to resolve the default export code
379
+ */
380
+ const resolveDefaultExportCode = (page) => SCRIPT_DEFAULT_EXPORT_CODE_TEMPLATE.replace(SCRIPT_DEFAULT_EXPORT_CODE_TEMPLATE_OUTLET, JSON.stringify(path.basename(page.chunkFilePath)));
381
+ /**
382
+ * Util to resolve the page data code
383
+ */
384
+ const resolvePageDataCode = (page) => PAGE_DATA_CODE_TEMPLATE.replace(PAGE_DATA_CODE_TEMPLATE_OUTLET, JSON.stringify(JSON.stringify(page.data)));
385
+ /**
386
+ * Resolve the stripped content of script block
387
+ */
388
+ const resolveScriptContentStripped = (app, page) => {
389
+ const rawContentStripped = page.sfcBlocks.script?.contentStripped;
390
+ const hasDefaultExport = rawContentStripped ? SCRIPT_DEFAULT_EXPORT_REGEX.test(rawContentStripped) || SCRIPT_DEFAULT_NAMED_EXPORT_REGEX.test(rawContentStripped) : false;
391
+ return [
392
+ rawContentStripped,
393
+ resolvePageDataCode(page),
394
+ !hasDefaultExport && resolveDefaultExportCode(page),
395
+ app.env.isDev && HMR_CODE$2
396
+ ].filter(isString).join("\n");
54
397
  };
55
-
56
- // src/app/prepare/prepareRoutes.ts
57
- import { ensureLeadingSlash, normalizeRoutePath } from "@vuepress/shared";
58
- var HMR_CODE2 = `
398
+ /**
399
+ * Render page to vue component
400
+ */
401
+ const renderPageToVue = (app, page) => {
402
+ const { sfcBlocks } = page;
403
+ return [
404
+ sfcBlocks.template && [
405
+ sfcBlocks.template.tagOpen,
406
+ TEMPLATE_WRAPPER_TAG_OPEN,
407
+ sfcBlocks.template.contentStripped,
408
+ TEMPLATE_WRAPPER_TAG_CLOSE,
409
+ sfcBlocks.template.tagClose
410
+ ].join(""),
411
+ [
412
+ resolveScriptTagOpen(page),
413
+ resolveScriptContentStripped(app, page),
414
+ sfcBlocks.script?.tagClose ?? SCRIPT_TAG_CLOSE
415
+ ].filter(isString).join("\n"),
416
+ sfcBlocks.scriptSetup?.content,
417
+ ...sfcBlocks.styles.map((item) => item.content),
418
+ ...sfcBlocks.customBlocks.map((item) => item.content)
419
+ ].filter(isString).join("\n");
420
+ };
421
+ //#endregion
422
+ //#region src/app/prepare/preparePageChunk.ts
423
+ /**
424
+ * Generate temp file if the page does not have a source file
425
+ */
426
+ const preparePageChunk = async (app, page) => {
427
+ if (page.filePath === null) await app.writeTemp(page.chunkFilePathRelative, renderPageToVue(app, page));
428
+ };
429
+ //#endregion
430
+ //#region src/app/prepare/prepareRoutes.ts
431
+ const ROUTES_VAR_NAME = "routes";
432
+ const REDIRECTS_VAR_NAME = "redirects";
433
+ const HMR_CODE$1 = `
59
434
  if (import.meta.webpackHot) {
60
435
  import.meta.webpackHot.accept()
61
- if (__VUE_HMR_RUNTIME__.updateRoutes) {
62
- __VUE_HMR_RUNTIME__.updateRoutes(routes)
63
- }
64
- if (__VUE_HMR_RUNTIME__.updateRedirects) {
65
- __VUE_HMR_RUNTIME__.updateRedirects(redirects)
66
- }
436
+ __VUE_HMR_RUNTIME__.updateRoutes?.(${ROUTES_VAR_NAME})
437
+ __VUE_HMR_RUNTIME__.updateRedirects?.(${REDIRECTS_VAR_NAME})
67
438
  }
68
439
 
69
440
  if (import.meta.hot) {
70
- import.meta.hot.accept(({ routes, redirects }) => {
71
- __VUE_HMR_RUNTIME__.updateRoutes(routes)
72
- __VUE_HMR_RUNTIME__.updateRedirects(redirects)
441
+ import.meta.hot.accept((m) => {
442
+ __VUE_HMR_RUNTIME__.updateRoutes?.(m.${ROUTES_VAR_NAME})
443
+ __VUE_HMR_RUNTIME__.updateRedirects?.(m.${REDIRECTS_VAR_NAME})
73
444
  })
74
445
  }
75
446
  `;
76
- var resolvePageRedirects = ({
77
- path: path9,
78
- pathInferred,
79
- filePathRelative
80
- }) => {
81
- const redirectsSet = /* @__PURE__ */ new Set();
82
- const addRedirect = (redirect) => {
83
- const normalizedPath = normalizeRoutePath(redirect);
84
- if (normalizedPath === path9)
85
- return;
86
- const encodedPath = encodeURI(normalizedPath);
87
- if (encodedPath === path9)
88
- return;
89
- redirectsSet.add(redirect);
90
- };
91
- if (pathInferred !== null) {
92
- addRedirect(pathInferred);
93
- }
94
- if (filePathRelative !== null) {
95
- addRedirect(ensureLeadingSlash(filePathRelative));
96
- }
97
- return Array.from(redirectsSet);
98
- };
99
- var prepareRoutes = async (app) => {
100
- let content = `export const redirects = JSON.parse(${JSON.stringify(
101
- JSON.stringify(
102
- Object.fromEntries(
103
- app.pages.flatMap(
104
- (page) => resolvePageRedirects(page).map((redirect) => [redirect, page.path])
105
- )
106
- )
107
- )
108
- )})
447
+ /**
448
+ * Resolve page redirects
449
+ *
450
+ * @internal
451
+ */
452
+ const resolvePageRedirects = ({ path, pathInferred }) => {
453
+ const redirectsSet = /* @__PURE__ */ new Set();
454
+ if (pathInferred !== null) {
455
+ const normalizedPathInferred = normalizeRoutePath(pathInferred);
456
+ const encodedPathInferred = encodeURI(normalizedPathInferred);
457
+ if (normalizedPathInferred !== path && encodedPathInferred !== path) redirectsSet.add(encodedPathInferred);
458
+ }
459
+ return Array.from(redirectsSet);
460
+ };
461
+ /**
462
+ * Generate routes temp file
463
+ */
464
+ const prepareRoutes = async (app) => {
465
+ let content = `\
466
+ export const ${REDIRECTS_VAR_NAME} = JSON.parse(${JSON.stringify(JSON.stringify(Object.fromEntries(app.pages.flatMap((page) => resolvePageRedirects(page).map((redirect) => [redirect, page.path])))))})
109
467
 
110
- export const routes = Object.fromEntries([
111
- ${app.pages.map(
112
- ({ chunkFilePath, chunkName, path: path9, routeMeta }) => ` [${JSON.stringify(path9)}, { loader: () => import(${chunkName ? `/* webpackChunkName: "${chunkName}" */` : ""}${JSON.stringify(chunkFilePath)}), meta: ${JSON.stringify(routeMeta)} }],`
113
- ).join("\n")}
468
+ export const ${ROUTES_VAR_NAME} = Object.fromEntries([
469
+ ${app.pages.map(({ chunkFilePath, chunkName, path, routeMeta }) => ` [${JSON.stringify(path)}, { loader: () => import(${chunkName ? `/* webpackChunkName: "${chunkName}" */` : ""}${JSON.stringify(chunkFilePath)}), meta: ${JSON.stringify(routeMeta)} }],`).join("\n")}
114
470
  ]);
115
471
  `;
116
- if (app.env.isDev) {
117
- content += HMR_CODE2;
118
- }
119
- await app.writeTemp("internal/routes.js", content);
472
+ if (app.env.isDev) content += HMR_CODE$1;
473
+ await app.writeTemp("internal/routes.js", content);
120
474
  };
121
-
122
- // src/app/prepare/prepareSiteData.ts
123
- var HMR_CODE3 = `
475
+ //#endregion
476
+ //#region src/app/prepare/prepareSiteData.ts
477
+ const SITE_DATA_VAR_NAME = "siteData";
478
+ const HMR_CODE = `
124
479
  if (import.meta.webpackHot) {
125
480
  import.meta.webpackHot.accept()
126
- if (__VUE_HMR_RUNTIME__.updateSiteData) {
127
- __VUE_HMR_RUNTIME__.updateSiteData(siteData)
128
- }
481
+ __VUE_HMR_RUNTIME__.updateSiteData?.(${SITE_DATA_VAR_NAME})
129
482
  }
130
483
 
131
484
  if (import.meta.hot) {
132
- import.meta.hot.accept(({ siteData }) => {
133
- __VUE_HMR_RUNTIME__.updateSiteData(siteData)
485
+ import.meta.hot.accept((m) => {
486
+ __VUE_HMR_RUNTIME__.updateSiteData?.(m.${SITE_DATA_VAR_NAME})
134
487
  })
135
488
  }
136
489
  `;
137
- var prepareSiteData = async (app) => {
138
- let content = `export const siteData = JSON.parse(${JSON.stringify(
139
- JSON.stringify(app.siteData)
140
- )})
490
+ /**
491
+ * Generate site data temp file
492
+ *
493
+ * @internal
494
+ */
495
+ const prepareSiteData = async (app) => {
496
+ let content = `\
497
+ export const ${SITE_DATA_VAR_NAME} = JSON.parse(${JSON.stringify(JSON.stringify(app.siteData))})
141
498
  `;
142
- if (app.env.isDev) {
143
- content += HMR_CODE3;
144
- }
145
- await app.writeTemp("internal/siteData.js", content);
146
- };
147
-
148
- // src/app/appInit.ts
149
- import { debug as debug3 } from "@vuepress/utils";
150
-
151
- // src/app/resolveAppMarkdown.ts
152
- import { createMarkdown } from "@vuepress/markdown";
153
- var resolveAppMarkdown = async (app) => {
154
- await app.pluginApi.hooks.extendsMarkdownOptions.process(
155
- app.options.markdown,
156
- app
157
- );
158
- const markdown = createMarkdown(app.options.markdown);
159
- await app.pluginApi.hooks.extendsMarkdown.process(markdown, app);
160
- return markdown;
161
- };
162
-
163
- // src/app/resolveAppPages.ts
164
- import { debug as debug2, globby } from "@vuepress/utils";
165
-
166
- // src/page/inferPagePath.ts
167
- import { ensureLeadingSlash as ensureLeadingSlash2, resolveLocalePath } from "@vuepress/shared";
168
- var inferPagePath = ({
169
- app,
170
- filePathRelative
171
- }) => {
172
- if (!filePathRelative) {
173
- return {
174
- pathInferred: null,
175
- pathLocale: "/"
176
- };
177
- }
178
- const pathInferred = ensureLeadingSlash2(filePathRelative).replace(/\.md$/, ".html").replace(/\/(README|index).html$/i, "/");
179
- const pathLocale = resolveLocalePath(app.siteData.locales, pathInferred);
180
- return {
181
- pathInferred,
182
- pathLocale
183
- };
184
- };
185
-
186
- // src/page/renderPageContent.ts
187
- import { omit } from "@vuepress/shared";
188
- var renderPageContent = ({
189
- app,
190
- content,
191
- filePath,
192
- filePathRelative,
193
- options
194
- }) => {
195
- const markdownEnv = {
196
- base: app.options.base,
197
- filePath,
198
- filePathRelative,
199
- frontmatter: { ...options.frontmatter }
200
- };
201
- const contentRendered = app.markdown.render(content, markdownEnv);
202
- const {
203
- frontmatter = {},
204
- headers = [],
205
- importedFiles = [],
206
- links = [],
207
- sfcBlocks = {
208
- template: null,
209
- script: null,
210
- scriptSetup: null,
211
- scripts: [],
212
- styles: [],
213
- customBlocks: []
214
- },
215
- title = "",
216
- ...extraMarkdownEnv
217
- } = markdownEnv;
218
- return {
219
- contentRendered,
220
- deps: importedFiles,
221
- frontmatter,
222
- headers,
223
- links,
224
- markdownEnv: omit(
225
- extraMarkdownEnv,
226
- "base",
227
- "content",
228
- "filePath",
229
- "filePathRelative",
230
- "frontmatter"
231
- ),
232
- sfcBlocks,
233
- title: frontmatter.title ? `${frontmatter.title}` : title
234
- };
235
- };
236
-
237
- // src/page/resolvePageChunkInfo.ts
238
- import { hash, path } from "@vuepress/utils";
239
- var resolvePageChunkInfo = ({
240
- app,
241
- htmlFilePathRelative
242
- }) => {
243
- const chunkFilePathRelative = path.join("pages", `${htmlFilePathRelative}.js`);
244
- const chunkFilePath = app.dir.temp(chunkFilePathRelative);
245
- const chunkName = `v-${hash(htmlFilePathRelative)}`;
246
- return {
247
- chunkFilePath,
248
- chunkFilePathRelative,
249
- chunkName
250
- };
251
- };
252
-
253
- // src/page/resolvePageComponentInfo.ts
254
- import { path as path2 } from "@vuepress/utils";
255
- var resolvePageComponentInfo = async ({
256
- app,
257
- htmlFilePathRelative
258
- }) => {
259
- const componentFilePathRelative = path2.join(
260
- "pages",
261
- `${htmlFilePathRelative}.vue`
262
- );
263
- const componentFilePath = app.dir.temp(componentFilePathRelative);
264
- return {
265
- componentFilePath,
266
- componentFilePathRelative
267
- };
268
- };
269
-
270
- // src/page/resolvePageDate.ts
271
- import { formatDateString, isString } from "@vuepress/shared";
272
- import { path as path3 } from "@vuepress/utils";
273
- var FILENAME_DATE_RE = /^(\d{4})-(\d{1,2})(?:-(\d{1,2}))?-(.*)$/;
274
- var DIRNAME_DATE_RE = /(\d{4})\/(\d{1,2})(?:\/(\d{1,2}))?(\/|$)/;
275
- var DEFAULT_DATE = "0000-00-00";
276
- var resolvePageDate = ({
277
- frontmatter,
278
- filePathRelative
279
- }) => {
280
- if (frontmatter.date instanceof Date) {
281
- return formatDateString(
282
- [
283
- frontmatter.date.getUTCFullYear(),
284
- frontmatter.date.getUTCMonth() + 1,
285
- frontmatter.date.getUTCDate()
286
- ].join("-"),
287
- DEFAULT_DATE
288
- );
289
- }
290
- if (isString(frontmatter.date)) {
291
- return formatDateString(frontmatter.date, DEFAULT_DATE);
292
- }
293
- if (filePathRelative === null) {
294
- return DEFAULT_DATE;
295
- }
296
- const filename = path3.parse(filePathRelative).name;
297
- if (filename) {
298
- const matches = filename.match(FILENAME_DATE_RE);
299
- if (matches) {
300
- return formatDateString(
301
- `${matches[1]}-${matches[2]}-${matches[3] ?? "01"}`,
302
- DEFAULT_DATE
303
- );
304
- }
305
- }
306
- const dirname = path3.dirname(filePathRelative);
307
- if (dirname !== ".") {
308
- const matches = dirname.match(DIRNAME_DATE_RE);
309
- if (matches) {
310
- return formatDateString(
311
- `${matches[1]}-${matches[2]}-${matches[3] ?? "01"}`,
312
- DEFAULT_DATE
313
- );
314
- }
315
- }
316
- return DEFAULT_DATE;
317
- };
318
-
319
- // src/page/resolvePageFileContent.ts
320
- import { debug, fs } from "@vuepress/utils";
321
- var log = debug("vuepress:core/page");
322
- var resolvePageFileContent = async ({
323
- filePath,
324
- options
325
- }) => {
326
- if (filePath) {
327
- try {
328
- const content = await fs.readFile(filePath, "utf-8");
329
- return content;
330
- } catch (e) {
331
- log(e instanceof Error ? e.message : e);
332
- }
333
- }
334
- return options.content ?? "";
499
+ if (app.env.isDev) content += HMR_CODE;
500
+ await app.writeTemp("internal/siteData.js", content);
335
501
  };
336
-
337
- // src/page/resolvePageFilePath.ts
338
- import { logger, path as path4 } from "@vuepress/utils";
339
- var resolvePageFilePath = ({
340
- app,
341
- options
342
- }) => {
343
- if (!options.filePath) {
344
- return {
345
- filePath: null,
346
- filePathRelative: null
347
- };
348
- }
349
- if (!path4.isAbsolute(options.filePath)) {
350
- throw logger.createError(
351
- `filePath is not absolute file path: ${options.filePath}}`
352
- );
353
- }
354
- return {
355
- filePath: options.filePath,
356
- filePathRelative: path4.relative(app.dir.source(), options.filePath)
357
- };
358
- };
359
-
360
- // src/page/resolvePageHtmlInfo.ts
361
- import { removeLeadingSlash } from "@vuepress/shared";
362
- var resolvePageHtmlInfo = ({
363
- app,
364
- path: pagePath
365
- }) => {
366
- const path9 = decodeURI(pagePath);
367
- const htmlFilePathRelative = removeLeadingSlash(
368
- path9.endsWith("/") ? path9 + "index.html" : path9.endsWith(".html") ? path9 : path9 + ".html"
369
- );
370
- const htmlFilePath = app.dir.dest(htmlFilePathRelative);
371
- return {
372
- htmlFilePath,
373
- htmlFilePathRelative
374
- };
375
- };
376
-
377
- // src/page/resolvePageLang.ts
378
- import { isString as isString2 } from "@vuepress/shared";
379
- var resolvePageLang = ({
380
- app,
381
- frontmatter,
382
- pathLocale
383
- }) => {
384
- if (isString2(frontmatter.lang) && frontmatter.lang) {
385
- return frontmatter.lang;
386
- }
387
- return app.siteData.locales[pathLocale]?.lang ?? app.siteData.lang;
502
+ //#endregion
503
+ //#region src/app/prepare/prepareUserStyle.ts
504
+ /**
505
+ * Generate user style temp file
506
+ *
507
+ * @internal
508
+ */
509
+ const prepareUserStyle = async (app, fileExists = null) => {
510
+ let content = "";
511
+ const { userStyle } = app.options;
512
+ if (userStyle) {
513
+ const userStylePath = app.dir.source(userStyle);
514
+ if (fileExists ?? await fs.pathExists(userStylePath)) content += `import ${JSON.stringify(userStylePath)}\n`;
515
+ }
516
+ await app.writeTemp("internal/userStyle.js", content);
388
517
  };
389
-
390
- // src/page/resolvePagePath.ts
391
- import { logger as logger2, sanitizeFileName } from "@vuepress/utils";
392
- var resolvePagePath = ({
393
- permalink,
394
- pathInferred,
395
- options
396
- }) => {
397
- const pagePath = options.path || permalink || pathInferred;
398
- if (!pagePath) {
399
- throw logger2.createError(
400
- `page path is empty, page options: ${JSON.stringify(options, null, 2)}`
401
- );
402
- }
403
- return encodeURI(pagePath.split("/").map(sanitizeFileName).join("/"));
518
+ //#endregion
519
+ //#region src/app/resolveAppMarkdown.ts
520
+ /**
521
+ * Resolve markdown-it instance for vuepress app
522
+ *
523
+ * @internal
524
+ */
525
+ const resolveAppMarkdown = async (app) => {
526
+ await app.pluginApi.hooks.extendsMarkdownOptions.process(app.options.markdown, app);
527
+ if (app.options.markdown.assets !== false) {
528
+ app.options.markdown.assets ??= {};
529
+ app.options.markdown.assets.absolutePathPrependBase ??= app.options.bundler.type === "webpack";
530
+ }
531
+ const markdown = createMarkdown(app.options.markdown);
532
+ await app.pluginApi.hooks.extendsMarkdown.process(markdown, app);
533
+ return markdown;
404
534
  };
405
-
406
- // src/page/resolvePagePermalink.ts
407
- import { ensureLeadingSlash as ensureLeadingSlash3, isString as isString3 } from "@vuepress/shared";
408
- import { path as path5 } from "@vuepress/utils";
409
- var resolvePagePermalink = ({
410
- app,
411
- frontmatter,
412
- slug,
413
- date,
414
- pathInferred,
415
- pathLocale
416
- }) => {
417
- if (isString3(frontmatter.permalink)) {
418
- return frontmatter.permalink;
419
- }
420
- const permalinkPattern = getPermalinkPattern({ app, frontmatter });
421
- if (permalinkPattern === null) {
422
- return null;
423
- }
424
- const [year, month, day] = date.split("-");
425
- const link = path5.join(
426
- pathLocale,
427
- permalinkPattern.replace(/:year/, year).replace(/:month/, month).replace(/:day/, day).replace(/:slug/, slug).replace(/:raw/, pathInferred?.replace(/^\//, "") ?? "")
428
- );
429
- return ensureLeadingSlash3(link);
430
- };
431
- var getPermalinkPattern = ({
432
- app,
433
- frontmatter
434
- }) => {
435
- if (frontmatter.permalinkPattern === null) {
436
- return null;
437
- }
438
- if (isString3(frontmatter.permalinkPattern)) {
439
- return frontmatter.permalinkPattern;
440
- }
441
- return app.options.permalinkPattern;
535
+ //#endregion
536
+ //#region src/constants.ts
537
+ const DEFAULT_IGNORE_PATTERNS = [
538
+ "**/node_modules",
539
+ "**/.yarn",
540
+ "**/.git",
541
+ "**/.svn",
542
+ "**/.hg"
543
+ ];
544
+ //#endregion
545
+ //#region src/app/resolveAppPages.ts
546
+ const log$4 = debug("vuepress:core/app");
547
+ /**
548
+ * Resolve pages for vuepress app
549
+ *
550
+ * @internal
551
+ */
552
+ const resolveAppPages = async (app) => {
553
+ log$4("resolveAppPages start");
554
+ const pageFilePaths = await tinyglobby.glob(app.options.pagePatterns, {
555
+ absolute: true,
556
+ cwd: app.dir.source(),
557
+ ignore: DEFAULT_IGNORE_PATTERNS
558
+ });
559
+ let hasNotFoundPage = false;
560
+ const pagesMap = {};
561
+ const pages = await Promise.all(pageFilePaths.map(async (filePath) => {
562
+ const page = await createPage(app, { filePath });
563
+ if (page.filePath) pagesMap[page.filePath] = page;
564
+ if (page.path === "/404.html") {
565
+ page.frontmatter.layout ??= "NotFound";
566
+ hasNotFoundPage = true;
567
+ }
568
+ return page;
569
+ }));
570
+ if (!hasNotFoundPage) pages.push(await createPage(app, {
571
+ path: "/404.html",
572
+ frontmatter: { layout: "NotFound" },
573
+ content: "404 Not Found"
574
+ }));
575
+ log$4("resolveAppPages finish");
576
+ return {
577
+ pages,
578
+ pagesMap
579
+ };
442
580
  };
443
-
444
- // src/page/resolvePageRouteMeta.ts
445
- var resolvePageRouteMeta = ({
446
- frontmatter
447
- }) => frontmatter.routeMeta ?? {};
448
-
449
- // src/page/resolvePageSlug.ts
450
- import { path as path6 } from "@vuepress/utils";
451
- var DATE_RE = /(\d{4}-\d{1,2}(-\d{1,2})?)-(.*)/;
452
- var resolvePageSlug = ({
453
- filePathRelative
454
- }) => {
455
- if (!filePathRelative) {
456
- return "";
457
- }
458
- const filename = path6.parse(filePathRelative).name;
459
- const match = filename.match(DATE_RE);
460
- return match ? match[3] : filename;
581
+ //#endregion
582
+ //#region src/app/appInit.ts
583
+ const log$3 = debug("vuepress:core/app");
584
+ /**
585
+ * Initialize a vuepress app
586
+ *
587
+ * Plugins should be used before initialization.
588
+ *
589
+ * @internal
590
+ */
591
+ const appInit = async (app) => {
592
+ log$3("init start");
593
+ app.pluginApi.registerHooks();
594
+ app.markdown = await resolveAppMarkdown(app);
595
+ const { pages, pagesMap } = await resolveAppPages(app);
596
+ app.pages = pages;
597
+ app.pagesMap = pagesMap;
598
+ await app.pluginApi.hooks.onInitialized.process(app);
599
+ log$3("init finish");
461
600
  };
462
-
463
- // src/page/createPage.ts
464
- var createPage = async (app, options) => {
465
- await app.pluginApi.hooks.extendsPageOptions.process(options, app);
466
- const { filePath, filePathRelative } = resolvePageFilePath({
467
- app,
468
- options
469
- });
470
- const content = await resolvePageFileContent({ filePath, options });
471
- const {
472
- contentRendered,
473
- deps,
474
- frontmatter,
475
- headers,
476
- links,
477
- markdownEnv,
478
- sfcBlocks,
479
- title
480
- } = renderPageContent({
481
- app,
482
- content,
483
- filePath,
484
- filePathRelative,
485
- options
486
- });
487
- const routeMeta = resolvePageRouteMeta({ frontmatter });
488
- const slug = resolvePageSlug({ filePathRelative });
489
- const date = resolvePageDate({ frontmatter, filePathRelative });
490
- const { pathInferred, pathLocale } = inferPagePath({ app, filePathRelative });
491
- const lang = resolvePageLang({ app, frontmatter, pathLocale });
492
- const permalink = resolvePagePermalink({
493
- app,
494
- frontmatter,
495
- slug,
496
- date,
497
- pathInferred,
498
- pathLocale
499
- });
500
- const path9 = resolvePagePath({ permalink, pathInferred, options });
501
- const { htmlFilePath, htmlFilePathRelative } = resolvePageHtmlInfo({
502
- app,
503
- path: path9
504
- });
505
- const { componentFilePath, componentFilePathRelative } = await resolvePageComponentInfo({
506
- app,
507
- htmlFilePathRelative
508
- });
509
- const { chunkFilePath, chunkFilePathRelative, chunkName } = resolvePageChunkInfo({ app, htmlFilePathRelative });
510
- const page = {
511
- // page data
512
- data: {
513
- path: path9,
514
- title,
515
- lang,
516
- frontmatter,
517
- headers
518
- },
519
- // base fields
520
- path: path9,
521
- title,
522
- lang,
523
- frontmatter,
524
- headers,
525
- // extra fields
526
- content,
527
- contentRendered,
528
- date,
529
- deps,
530
- links,
531
- markdownEnv,
532
- pathInferred,
533
- pathLocale,
534
- permalink,
535
- routeMeta,
536
- sfcBlocks,
537
- slug,
538
- // file info
539
- filePath,
540
- filePathRelative,
541
- componentFilePath,
542
- componentFilePathRelative,
543
- chunkFilePath,
544
- chunkFilePathRelative,
545
- chunkName,
546
- htmlFilePath,
547
- htmlFilePathRelative
548
- };
549
- await app.pluginApi.hooks.extendsPage.process(page, app);
550
- return page;
601
+ //#endregion
602
+ //#region src/app/appPrepare.ts
603
+ const log$2 = debug("vuepress:core/app");
604
+ /**
605
+ * Prepare files for development or build
606
+ *
607
+ * - page chunks
608
+ * - routes
609
+ * - site data
610
+ * - other files that generated by plugins
611
+ *
612
+ * @internal
613
+ */
614
+ const appPrepare = async (app) => {
615
+ log$2("prepare start");
616
+ await Promise.all([
617
+ ...app.pages.map(async (page) => preparePageChunk(app, page)),
618
+ prepareRoutes(app),
619
+ prepareSiteData(app),
620
+ prepareClientConfigs(app),
621
+ prepareUserStyle(app)
622
+ ]);
623
+ await app.pluginApi.hooks.onPrepared.process(app);
624
+ log$2("prepare finish");
551
625
  };
552
-
553
- // src/app/resolveAppPages.ts
554
- var log2 = debug2("vuepress:core/app");
555
- var resolveAppPages = async (app) => {
556
- log2("resolveAppPages start");
557
- const pageFilePaths = await globby(app.options.pagePatterns, {
558
- absolute: true,
559
- cwd: app.dir.source()
560
- });
561
- const pages = await Promise.all(
562
- pageFilePaths.map((filePath) => createPage(app, { filePath }))
563
- );
564
- const notFoundPage = pages.find((page) => page.path === "/404.html");
565
- if (notFoundPage) {
566
- notFoundPage.frontmatter.layout ??= "NotFound";
567
- } else {
568
- pages.push(
569
- await createPage(app, {
570
- path: "/404.html",
571
- frontmatter: { layout: "NotFound" },
572
- content: "404 Not Found"
573
- })
574
- );
575
- }
576
- log2("resolveAppPages finish");
577
- return pages;
578
- };
579
-
580
- // src/app/appInit.ts
581
- var log3 = debug3("vuepress:core/app");
582
- var appInit = async (app) => {
583
- log3("init start");
584
- app.pluginApi.registerHooks();
585
- app.markdown = await resolveAppMarkdown(app);
586
- app.pages = await resolveAppPages(app);
587
- await app.pluginApi.hooks.onInitialized.process(app);
588
- log3("init finish");
589
- };
590
-
591
- // src/app/appPrepare.ts
592
- import { debug as debug4 } from "@vuepress/utils";
593
- var log4 = debug4("vuepress:core/app");
594
- var appPrepare = async (app) => {
595
- log4("prepare start");
596
- for (const page of app.pages) {
597
- await preparePageComponent(app, page);
598
- }
599
- for (const page of app.pages) {
600
- await preparePageChunk(app, page);
601
- }
602
- await prepareRoutes(app);
603
- await prepareSiteData(app);
604
- await prepareClientConfigs(app);
605
- await app.pluginApi.hooks.onPrepared.process(app);
606
- log4("prepare finish");
607
- };
608
-
609
- // src/app/appUse.ts
610
- import { colors, debug as debug5, warn } from "@vuepress/utils";
611
-
612
- // src/app/resolvePluginObject.ts
613
- import { isFunction } from "@vuepress/shared";
614
- var resolvePluginObject = (app, plugin) => isFunction(plugin) ? plugin(app) : plugin;
615
-
616
- // src/app/appUse.ts
617
- var log5 = debug5("vuepress:core/app");
618
- var appUse = (app, rawPlugin) => {
619
- const pluginObject = resolvePluginObject(app, rawPlugin);
620
- if (!pluginObject.name) {
621
- warn(`an anonymous plugin or theme was detected and ignored`);
622
- return app;
623
- }
624
- log5(`use plugin ${colors.magenta(pluginObject.name)}`);
625
- if (pluginObject.multiple !== true) {
626
- const duplicateIndex = app.pluginApi.plugins.findIndex(
627
- ({ name }) => name === pluginObject.name
628
- );
629
- if (duplicateIndex !== -1) {
630
- app.pluginApi.plugins.splice(duplicateIndex, 1);
631
- warn(
632
- `plugin ${colors.magenta(
633
- pluginObject.name
634
- )} has been used multiple times, only the last one will take effect`
635
- );
636
- }
637
- }
638
- app.pluginApi.plugins.push(pluginObject);
639
- return app;
626
+ //#endregion
627
+ //#region src/app/resolvePluginObject.ts
628
+ /**
629
+ * Resolve a plugin object according to name / path / module and config
630
+ *
631
+ * @internal
632
+ */
633
+ const resolvePluginObject = (app, plugin) => isFunction(plugin) ? plugin(app) : plugin;
634
+ //#endregion
635
+ //#region src/app/appUse.ts
636
+ const log$1 = debug("vuepress:core/app");
637
+ /**
638
+ * Use a plugin in vuepress app.
639
+ *
640
+ * Should be called before initialization.
641
+ *
642
+ * @internal
643
+ */
644
+ const appUse = (app, rawPlugin) => {
645
+ const pluginObject = resolvePluginObject(app, rawPlugin);
646
+ if (!pluginObject.name) {
647
+ warn(`an anonymous plugin or theme was detected and ignored`);
648
+ return app;
649
+ }
650
+ log$1(`use plugin ${colors.magenta(pluginObject.name)}`);
651
+ if (pluginObject.multiple !== true) {
652
+ const duplicateIndex = app.pluginApi.plugins.findIndex(({ name }) => name === pluginObject.name);
653
+ if (duplicateIndex !== -1) {
654
+ app.pluginApi.plugins.splice(duplicateIndex, 1);
655
+ warn(`plugin ${colors.magenta(pluginObject.name)} has been used multiple times, only the last one will take effect`);
656
+ }
657
+ }
658
+ app.pluginApi.plugins.push(pluginObject);
659
+ return app;
640
660
  };
641
-
642
- // src/pluginApi/createHookQueue.ts
643
- import { colors as colors2, debug as debug6, logger as logger3 } from "@vuepress/utils";
644
- var log6 = debug6("vuepress:core/plugin-api");
645
- var createHookQueue = (name) => {
646
- const items = [];
647
- const hookQueue = {
648
- name,
649
- items,
650
- add: (item) => {
651
- items.push(item);
652
- },
653
- process: async (...args) => {
654
- const results = [];
655
- for (const item of items) {
656
- log6(
657
- `process ${colors2.magenta(name)} from ${colors2.magenta(
658
- item.pluginName
659
- )}`
660
- );
661
- try {
662
- const result = await item.hook(...args);
663
- if (result !== void 0) {
664
- results.push(result);
665
- }
666
- } catch (e) {
667
- logger3.error(
668
- `error in hook ${colors2.magenta(name)} from ${colors2.magenta(
669
- item.pluginName
670
- )}`
671
- );
672
- throw e;
673
- }
674
- }
675
- return results;
676
- }
677
- };
678
- return hookQueue;
661
+ //#endregion
662
+ //#region src/pluginApi/createHookQueue.ts
663
+ const log = debug("vuepress:core/plugin-api");
664
+ /**
665
+ * Create hook queue for plugin system
666
+ *
667
+ * @internal
668
+ */
669
+ const createHookQueue = (name) => {
670
+ const items = [];
671
+ return {
672
+ name,
673
+ items,
674
+ add: (item) => {
675
+ items.push(item);
676
+ },
677
+ process: async (...args) => {
678
+ const results = [];
679
+ for (const item of items) {
680
+ log(`process ${colors.magenta(name)} from ${colors.magenta(item.pluginName)}`);
681
+ try {
682
+ const result = await item.hook(...args);
683
+ if (result !== void 0) results.push(result);
684
+ } catch (e) {
685
+ logger.error(`error in hook ${colors.magenta(name)} from ${colors.magenta(item.pluginName)}`);
686
+ throw e;
687
+ }
688
+ }
689
+ return results;
690
+ }
691
+ };
679
692
  };
680
-
681
- // src/pluginApi/createPluginApiHooks.ts
682
- var createPluginApiHooks = () => ({
683
- // life cycle hooks
684
- onInitialized: createHookQueue("onInitialized"),
685
- onPrepared: createHookQueue("onPrepared"),
686
- onWatched: createHookQueue("onWatched"),
687
- onGenerated: createHookQueue("onGenerated"),
688
- // extends hooks
689
- extendsMarkdownOptions: createHookQueue("extendsMarkdownOptions"),
690
- extendsMarkdown: createHookQueue("extendsMarkdown"),
691
- extendsPageOptions: createHookQueue("extendsPageOptions"),
692
- extendsPage: createHookQueue("extendsPage"),
693
- extendsBundlerOptions: createHookQueue("extendsBundlerOptions"),
694
- // client config file hooks
695
- clientConfigFile: createHookQueue("clientConfigFile"),
696
- // bundler hooks
697
- alias: createHookQueue("alias"),
698
- define: createHookQueue("define")
693
+ //#endregion
694
+ //#region src/pluginApi/createPluginApiHooks.ts
695
+ /**
696
+ * Create hooks for plugin api
697
+ *
698
+ * @internal
699
+ */
700
+ const createPluginApiHooks = () => ({
701
+ onInitialized: createHookQueue("onInitialized"),
702
+ onPrepared: createHookQueue("onPrepared"),
703
+ onWatched: createHookQueue("onWatched"),
704
+ onPageUpdated: createHookQueue("onPageUpdated"),
705
+ onGenerated: createHookQueue("onGenerated"),
706
+ extendsMarkdownOptions: createHookQueue("extendsMarkdownOptions"),
707
+ extendsMarkdown: createHookQueue("extendsMarkdown"),
708
+ extendsPageOptions: createHookQueue("extendsPageOptions"),
709
+ extendsPage: createHookQueue("extendsPage"),
710
+ extendsBundlerOptions: createHookQueue("extendsBundlerOptions"),
711
+ clientConfigFile: createHookQueue("clientConfigFile"),
712
+ alias: createHookQueue("alias"),
713
+ define: createHookQueue("define")
699
714
  });
700
-
701
- // src/pluginApi/normalizeAliasDefineHook.ts
702
- import { isFunction as isFunction2 } from "@vuepress/shared";
703
- var normalizeAliasDefineHook = (hook) => async (app, isServer) => isFunction2(hook) ? hook(app, isServer) : hook;
704
-
705
- // src/pluginApi/normalizeClientConfigFileHook.ts
706
- import { isFunction as isFunction3 } from "@vuepress/shared";
707
- import { fs as fs2, logger as logger4 } from "@vuepress/utils";
708
- var normalizeClientConfigFileHook = (hook) => async (app) => {
709
- const clientConfigFileResult = isFunction3(hook) ? await hook(app) : hook;
710
- const isExisted = await fs2.pathExists(clientConfigFileResult);
711
- if (!isExisted) {
712
- throw logger4.createError(
713
- `client config file does not exist: ${clientConfigFileResult}`
714
- );
715
- }
716
- return clientConfigFileResult;
715
+ //#endregion
716
+ //#region src/pluginApi/normalizeAliasDefineHook.ts
717
+ /**
718
+ * Normalize alias and define hook
719
+ *
720
+ * @internal
721
+ */
722
+ const normalizeAliasDefineHook = (hook) => async (app, isServer) => isFunction(hook) ? hook(app, isServer) : hook;
723
+ //#endregion
724
+ //#region src/pluginApi/normalizeClientConfigFileHook.ts
725
+ /**
726
+ * Normalize hook for client config file
727
+ *
728
+ * @internal
729
+ */
730
+ const normalizeClientConfigFileHook = (hook) => async (app) => {
731
+ const clientConfigFileResult = isFunction(hook) ? await hook(app) : hook;
732
+ if (!await fs.pathExists(clientConfigFileResult)) throw logger.createError(`client config file does not exist: ${clientConfigFileResult}`);
733
+ return clientConfigFileResult;
717
734
  };
718
-
719
- // src/pluginApi/createPluginApiRegisterHooks.ts
720
- var createPluginApiRegisterHooks = (plugins, hooks) => () => {
721
- plugins.forEach(
722
- ({
723
- name: pluginName,
724
- multiple,
725
- alias,
726
- define,
727
- clientConfigFile,
728
- ...commonHooks
729
- }) => {
730
- if (alias) {
731
- hooks.alias.add({
732
- pluginName,
733
- hook: normalizeAliasDefineHook(alias)
734
- });
735
- }
736
- if (define) {
737
- hooks.define.add({
738
- pluginName,
739
- hook: normalizeAliasDefineHook(define)
740
- });
741
- }
742
- if (clientConfigFile) {
743
- hooks.clientConfigFile.add({
744
- pluginName,
745
- hook: normalizeClientConfigFileHook(clientConfigFile)
746
- });
747
- }
748
- Object.keys(commonHooks).forEach((key) => {
749
- if (hooks[key] && commonHooks[key]) {
750
- hooks[key].add({
751
- pluginName,
752
- hook: commonHooks[key]
753
- });
754
- }
755
- });
756
- }
757
- );
735
+ //#endregion
736
+ //#region src/pluginApi/createPluginApiRegisterHooks.ts
737
+ /**
738
+ * Create registerHooks method for plugin api
739
+ *
740
+ * @internal
741
+ */
742
+ const createPluginApiRegisterHooks = (plugins, hooks) => () => {
743
+ plugins.forEach(({ name: pluginName, multiple, alias, define, clientConfigFile, ...commonHooks }) => {
744
+ /**
745
+ * hooks that need to be normalized
746
+ */
747
+ if (alias) hooks.alias.add({
748
+ pluginName,
749
+ hook: normalizeAliasDefineHook(alias)
750
+ });
751
+ if (define) hooks.define.add({
752
+ pluginName,
753
+ hook: normalizeAliasDefineHook(define)
754
+ });
755
+ if (clientConfigFile) hooks.clientConfigFile.add({
756
+ pluginName,
757
+ hook: normalizeClientConfigFileHook(clientConfigFile)
758
+ });
759
+ /**
760
+ * common hooks
761
+ */
762
+ Object.keys(commonHooks).forEach((key) => {
763
+ if (hooks[key] && commonHooks[key]) hooks[key].add({
764
+ pluginName,
765
+ hook: commonHooks[key]
766
+ });
767
+ });
768
+ });
758
769
  };
759
-
760
- // src/pluginApi/createPluginApi.ts
761
- var createPluginApi = () => {
762
- const plugins = [];
763
- const hooks = createPluginApiHooks();
764
- const registerHooks = createPluginApiRegisterHooks(plugins, hooks);
765
- return {
766
- plugins,
767
- hooks,
768
- registerHooks
769
- };
770
+ //#endregion
771
+ //#region src/pluginApi/createPluginApi.ts
772
+ /**
773
+ * Create vuepress plugin api
774
+ *
775
+ * @internal
776
+ */
777
+ const createPluginApi = () => {
778
+ const plugins = [];
779
+ const hooks = createPluginApiHooks();
780
+ return {
781
+ plugins,
782
+ hooks,
783
+ registerHooks: createPluginApiRegisterHooks(plugins, hooks)
784
+ };
770
785
  };
771
-
772
- // src/app/resolveAppDir.ts
773
- import { createRequire } from "module";
774
- import { path as path7 } from "@vuepress/utils";
775
- var require2 = createRequire(import.meta.url);
776
- var createAppDirFunction = (baseDir) => {
777
- return (...args) => path7.resolve(baseDir, ...args);
778
- };
779
- var resolveAppDir = (options) => {
780
- const cache = createAppDirFunction(options.cache);
781
- const temp = createAppDirFunction(options.temp);
782
- const source = createAppDirFunction(options.source);
783
- const dest = createAppDirFunction(options.dest);
784
- const publicDir = createAppDirFunction(options.public);
785
- const client = createAppDirFunction(
786
- path7.resolve(require2.resolve("@vuepress/client/package.json"), "..")
787
- );
788
- return {
789
- cache,
790
- temp,
791
- source,
792
- dest,
793
- client,
794
- public: publicDir
795
- };
786
+ //#endregion
787
+ //#region src/app/resolveAppDir.ts
788
+ const require$2 = createRequire(import.meta.url);
789
+ /**
790
+ * Create directory util function
791
+ *
792
+ * @internal
793
+ */
794
+ const createAppDirFunction = (baseDir) => (...args) => path.resolve(baseDir, ...args);
795
+ /**
796
+ * Resolve directory utils for vuepress app
797
+ */
798
+ const resolveAppDir = (options) => {
799
+ const cache = createAppDirFunction(options.cache);
800
+ const temp = createAppDirFunction(options.temp);
801
+ const source = createAppDirFunction(options.source);
802
+ const dest = createAppDirFunction(options.dest);
803
+ const publicDir = createAppDirFunction(options.public);
804
+ return {
805
+ cache,
806
+ temp,
807
+ source,
808
+ dest,
809
+ client: createAppDirFunction(path.resolve(require$2.resolve("@vuepress/client/package.json"), "..")),
810
+ public: publicDir
811
+ };
796
812
  };
797
-
798
- // src/app/resolveAppEnv.ts
799
- var resolveAppEnv = (options, isBuild) => ({
800
- isBuild,
801
- isDev: !isBuild,
802
- isDebug: options.debug
803
- });
804
-
805
- // src/app/resolveAppOptions.ts
806
- import { createRequire as createRequire2 } from "module";
807
- import { path as path8, templateRenderer } from "@vuepress/utils";
808
- var require3 = createRequire2(import.meta.url);
809
- var resolveAppOptions = ({
810
- // site config
811
- base = "/",
812
- lang = "en-US",
813
- title = "",
814
- description = "",
815
- head = [],
816
- locales = {},
817
- // directory config
818
- source,
819
- dest = path8.resolve(source, ".vuepress/dist"),
820
- temp = path8.resolve(source, ".vuepress/.temp"),
821
- cache = path8.resolve(source, ".vuepress/.cache"),
822
- public: publicDir = path8.resolve(source, ".vuepress/public"),
823
- // dev config
824
- host = "0.0.0.0",
825
- port = 8080,
826
- open = false,
827
- templateDev = path8.normalize(
828
- require3.resolve("@vuepress/client/templates/dev.html")
829
- ),
830
- // build config
831
- shouldPreload = true,
832
- shouldPrefetch = true,
833
- templateBuild = path8.normalize(
834
- require3.resolve("@vuepress/client/templates/build.html")
835
- ),
836
- // common config
837
- bundler,
838
- debug: debug7 = false,
839
- markdown = {},
840
- pagePatterns = ["**/*.md", "!.vuepress", "!node_modules"],
841
- permalinkPattern = null,
842
- plugins = [],
843
- theme
844
- }) => ({
845
- base,
846
- lang,
847
- title,
848
- description,
849
- head,
850
- locales,
851
- source,
852
- dest,
853
- temp,
854
- cache,
855
- public: publicDir,
856
- host,
857
- port,
858
- open,
859
- templateDev,
860
- shouldPreload,
861
- shouldPrefetch,
862
- templateBuild,
863
- templateBuildRenderer: templateRenderer,
864
- bundler,
865
- debug: debug7,
866
- markdown,
867
- pagePatterns,
868
- permalinkPattern,
869
- plugins,
870
- theme
813
+ //#endregion
814
+ //#region src/app/resolveAppEnv.ts
815
+ /**
816
+ * Resolve environment flags for vuepress app
817
+ *
818
+ * @internal
819
+ */
820
+ const resolveAppEnv = (options) => ({
821
+ isBuild: false,
822
+ isDev: false,
823
+ isDebug: options.debug
871
824
  });
872
-
873
- // src/app/resolveAppSiteData.ts
874
- var resolveAppSiteData = (options) => ({
875
- base: options.base,
876
- lang: options.lang,
877
- title: options.title,
878
- description: options.description,
879
- head: options.head,
880
- locales: options.locales
825
+ //#endregion
826
+ //#region src/app/resolveAppOptions.ts
827
+ const require$1 = createRequire(import.meta.url);
828
+ /**
829
+ * Create app options with default values
830
+ *
831
+ * @internal
832
+ */
833
+ const resolveAppOptions = ({ base = "/", lang = "en-US", title = "", description = "", head = [], locales = {}, source, dest = path.resolve(source, ".vuepress/dist"), temp = path.resolve(source, ".vuepress/.temp"), cache = path.resolve(source, ".vuepress/.cache"), public: publicDir = path.resolve(source, ".vuepress/public"), host = "0.0.0.0", port = 8080, open = false, templateDev = path.normalize(require$1.resolve("@vuepress/client/templates/dev.html")), shouldPreload = true, shouldPrefetch = "as-needed", templateBuild = path.normalize(require$1.resolve("@vuepress/client/templates/build.html")), templateBuildRenderer = templateRenderer, bundler, debug = false, markdown = {}, pagePatterns = ["**/*.md", "!.vuepress"], permalinkPattern = null, userStyle = null, plugins = [], theme }) => {
834
+ locales["/"] ??= {
835
+ lang,
836
+ title,
837
+ description
838
+ };
839
+ return {
840
+ base,
841
+ lang,
842
+ title,
843
+ description,
844
+ head,
845
+ locales,
846
+ source,
847
+ dest,
848
+ temp,
849
+ cache,
850
+ public: publicDir,
851
+ host,
852
+ port,
853
+ open,
854
+ templateDev,
855
+ shouldPreload,
856
+ shouldPrefetch,
857
+ templateBuild,
858
+ templateBuildRenderer,
859
+ bundler,
860
+ debug,
861
+ markdown,
862
+ pagePatterns,
863
+ permalinkPattern,
864
+ userStyle,
865
+ plugins,
866
+ theme
867
+ };
868
+ };
869
+ //#endregion
870
+ //#region src/app/resolveAppSiteData.ts
871
+ /**
872
+ * Resolve site data for vuepress app
873
+ *
874
+ * Site data will also be used in client
875
+ *
876
+ * @internal
877
+ */
878
+ const resolveAppSiteData = (options) => ({
879
+ base: options.base,
880
+ lang: options.lang,
881
+ title: options.title,
882
+ description: options.description,
883
+ head: options.head,
884
+ locales: options.locales
881
885
  });
882
-
883
- // src/app/resolveAppVersion.ts
884
- import { createRequire as createRequire3 } from "module";
885
- import { fs as fs3 } from "@vuepress/utils";
886
- var require4 = createRequire3(import.meta.url);
887
- var resolveAppVersion = () => {
888
- const pkgJson = fs3.readJsonSync(
889
- require4.resolve("@vuepress/core/package.json")
890
- );
891
- return pkgJson.version;
886
+ //#endregion
887
+ //#region src/app/resolveAppVersion.ts
888
+ const require = createRequire(import.meta.url);
889
+ /**
890
+ * Resolve version of vuepress app
891
+ *
892
+ * @internal
893
+ */
894
+ const resolveAppVersion = () => {
895
+ return fs.readJsonSync(require.resolve("@vuepress/core/package.json")).version;
892
896
  };
893
-
894
- // src/app/resolveAppWriteTemp.ts
895
- import { fs as fs4 } from "@vuepress/utils";
896
- var resolveAppWriteTemp = (dir) => {
897
- const writeTemp = async (file, content) => {
898
- const filePath = dir.temp(file);
899
- await fs4.outputFile(filePath, content);
900
- return filePath;
901
- };
902
- return writeTemp;
897
+ //#endregion
898
+ //#region src/app/resolveAppWriteTemp.ts
899
+ /**
900
+ * Resolve write temp file util for vuepress app
901
+ *
902
+ * @internal
903
+ */
904
+ const resolveAppWriteTemp = (dir) => {
905
+ const cache = /* @__PURE__ */ new Map();
906
+ const writeTemp = (async (file, content) => {
907
+ const filePath = dir.temp(file);
908
+ const contentHash = hash(content);
909
+ let item = cache.get(filePath);
910
+ if (!item) cache.set(filePath, item = {});
911
+ if (item.hash === contentHash) return filePath;
912
+ item.hash = contentHash;
913
+ if (!item.current) item.current = (async () => {
914
+ await fs.outputFile(filePath, content);
915
+ item.current = item.next?.();
916
+ return item.current;
917
+ })();
918
+ else item.next = async () => {
919
+ await fs.outputFile(filePath, content);
920
+ item.next = void 0;
921
+ item.current = void 0;
922
+ };
923
+ await item.current;
924
+ return filePath;
925
+ });
926
+ writeTemp.cleanup = () => {
927
+ cache.clear();
928
+ };
929
+ return writeTemp;
903
930
  };
904
-
905
- // src/app/resolveThemeInfo.ts
906
- var resolveThemeInfo = (app, theme) => {
907
- const themeObject = resolvePluginObject(app, theme);
908
- const themeInfo = {
909
- plugins: [...themeObject.plugins ?? [], themeObject],
910
- templateBuild: themeObject.templateBuild,
911
- templateBuildRenderer: themeObject.templateBuildRenderer,
912
- templateDev: themeObject.templateDev
913
- };
914
- if (!themeObject.extends) {
915
- return themeInfo;
916
- }
917
- const parentThemeInfo = resolveThemeInfo(app, themeObject.extends);
918
- return {
919
- plugins: [...parentThemeInfo.plugins, ...themeInfo.plugins],
920
- templateBuild: themeObject.templateBuild ?? parentThemeInfo.templateBuild,
921
- templateBuildRenderer: themeObject.templateBuildRenderer ?? parentThemeInfo.templateBuildRenderer,
922
- templateDev: themeObject.templateDev ?? parentThemeInfo.templateDev
923
- };
931
+ //#endregion
932
+ //#region src/app/createBaseApp.ts
933
+ /**
934
+ * Create base vuepress app.
935
+ *
936
+ * Notice that the base app could not be used for dev nor build.
937
+ *
938
+ * It would be used for creating dev app or build app internally.
939
+ *
940
+ * @internal
941
+ */
942
+ const createBaseApp = (config) => {
943
+ const options = resolveAppOptions(config);
944
+ const dir = resolveAppDir(options);
945
+ const env = resolveAppEnv(options);
946
+ const pluginApi = createPluginApi();
947
+ const app = {
948
+ options,
949
+ siteData: resolveAppSiteData(options),
950
+ version: resolveAppVersion(),
951
+ dir,
952
+ env,
953
+ pluginApi,
954
+ writeTemp: resolveAppWriteTemp(dir),
955
+ use: (plugin) => appUse(app, plugin),
956
+ init: async () => appInit(app),
957
+ prepare: async () => appPrepare(app)
958
+ };
959
+ return app;
924
960
  };
925
-
926
- // src/app/setupAppThemeAndPlugins.ts
927
- var setupAppThemeAndPlugins = (app, config) => {
928
- const themeInfo = resolveThemeInfo(app, app.options.theme);
929
- app.options.templateDev = config.templateDev ?? themeInfo.templateDev ?? app.options.templateDev;
930
- app.options.templateBuild = config.templateBuild ?? themeInfo.templateBuild ?? app.options.templateBuild;
931
- app.options.templateBuildRenderer = config.templateBuildRenderer ?? themeInfo.templateBuildRenderer ?? app.options.templateBuildRenderer;
932
- [...themeInfo.plugins, ...app.options.plugins].flat().forEach((plugin) => app.use(plugin));
961
+ //#endregion
962
+ //#region src/app/resolveThemeInfo.ts
963
+ /**
964
+ * Resolve theme info and its parent theme info
965
+ *
966
+ * @internal
967
+ */
968
+ const resolveThemeInfo = (app, theme) => {
969
+ const themeObject = resolvePluginObject(app, theme);
970
+ const themeInfo = {
971
+ plugins: [...themeObject.plugins ?? [], themeObject],
972
+ templateBuild: themeObject.templateBuild,
973
+ templateBuildRenderer: themeObject.templateBuildRenderer,
974
+ templateDev: themeObject.templateDev,
975
+ userStyle: themeObject.userStyle
976
+ };
977
+ if (!themeObject.extends) return themeInfo;
978
+ const parentThemeInfo = resolveThemeInfo(app, themeObject.extends);
979
+ return {
980
+ plugins: [...parentThemeInfo.plugins, ...themeInfo.plugins],
981
+ templateBuild: themeObject.templateBuild ?? parentThemeInfo.templateBuild,
982
+ templateBuildRenderer: themeObject.templateBuildRenderer ?? parentThemeInfo.templateBuildRenderer,
983
+ templateDev: themeObject.templateDev ?? parentThemeInfo.templateDev,
984
+ userStyle: themeObject.userStyle ?? parentThemeInfo.userStyle
985
+ };
933
986
  };
934
-
935
- // src/app/createBaseApp.ts
936
- var createBaseApp = (config, isBuild = false) => {
937
- const options = resolveAppOptions(config);
938
- const dir = resolveAppDir(options);
939
- const env = resolveAppEnv(options, isBuild);
940
- const pluginApi = createPluginApi();
941
- const siteData = resolveAppSiteData(options);
942
- const version = resolveAppVersion();
943
- const writeTemp = resolveAppWriteTemp(dir);
944
- const app = {
945
- options,
946
- siteData,
947
- version,
948
- // utils
949
- dir,
950
- env,
951
- pluginApi,
952
- writeTemp,
953
- // methods
954
- use: (plugin) => appUse(app, plugin),
955
- init: () => appInit(app),
956
- prepare: () => appPrepare(app)
957
- };
958
- setupAppThemeAndPlugins(app, config);
959
- return app;
987
+ //#endregion
988
+ //#region src/app/setupAppThemeAndPlugins.ts
989
+ /**
990
+ * Setup theme and plugins for vuepress app
991
+ *
992
+ * @internal
993
+ */
994
+ const setupAppThemeAndPlugins = (app, config) => {
995
+ const themeInfo = resolveThemeInfo(app, app.options.theme);
996
+ app.options.templateDev = config.templateDev ?? themeInfo.templateDev ?? app.options.templateDev;
997
+ app.options.templateBuild = config.templateBuild ?? themeInfo.templateBuild ?? app.options.templateBuild;
998
+ app.options.templateBuildRenderer = config.templateBuildRenderer ?? themeInfo.templateBuildRenderer ?? app.options.templateBuildRenderer;
999
+ app.options.userStyle = config.userStyle ?? themeInfo.userStyle ?? app.options.userStyle;
1000
+ [...themeInfo.plugins, ...app.options.plugins].flat().forEach((plugin) => app.use(plugin));
960
1001
  };
961
-
962
- // src/app/createBuildApp.ts
963
- var createBuildApp = (config) => {
964
- const app = createBaseApp(config, true);
965
- app.build = () => app.options.bundler.build(app);
966
- return app;
1002
+ //#endregion
1003
+ //#region src/app/createBuildApp.ts
1004
+ /**
1005
+ * Create vuepress build app.
1006
+ */
1007
+ const createBuildApp = (config) => {
1008
+ const app = createBaseApp(config);
1009
+ app.env.isBuild = true;
1010
+ app.build = async () => app.options.bundler.build(app);
1011
+ setupAppThemeAndPlugins(app, config);
1012
+ return app;
967
1013
  };
968
-
969
- // src/app/createDevApp.ts
970
- var createDevApp = (config) => {
971
- const app = createBaseApp(config, false);
972
- app.dev = () => app.options.bundler.dev(app);
973
- return app;
974
- };
975
- export {
976
- appInit,
977
- appPrepare,
978
- appUse,
979
- createAppDirFunction,
980
- createBaseApp,
981
- createBuildApp,
982
- createDevApp,
983
- createHookQueue,
984
- createPage,
985
- createPluginApi,
986
- createPluginApiHooks,
987
- createPluginApiRegisterHooks,
988
- inferPagePath,
989
- normalizeAliasDefineHook,
990
- normalizeClientConfigFileHook,
991
- prepareClientConfigs,
992
- preparePageChunk,
993
- preparePageComponent,
994
- prepareRoutes,
995
- prepareSiteData,
996
- renderPageContent,
997
- resolveAppDir,
998
- resolveAppEnv,
999
- resolveAppOptions,
1000
- resolveAppPages,
1001
- resolveAppSiteData,
1002
- resolveAppVersion,
1003
- resolveAppWriteTemp,
1004
- resolvePageChunkInfo,
1005
- resolvePageComponentInfo,
1006
- resolvePageDate,
1007
- resolvePageFileContent,
1008
- resolvePageFilePath,
1009
- resolvePageHtmlInfo,
1010
- resolvePageLang,
1011
- resolvePagePath,
1012
- resolvePagePermalink,
1013
- resolvePageRouteMeta,
1014
- resolvePageSlug,
1015
- resolvePluginObject,
1016
- resolveThemeInfo
1014
+ //#endregion
1015
+ //#region src/app/createDevApp.ts
1016
+ /**
1017
+ * Create vuepress dev app.
1018
+ */
1019
+ const createDevApp = (config) => {
1020
+ const app = createBaseApp(config);
1021
+ app.env.isDev = true;
1022
+ app.dev = async () => app.options.bundler.dev(app);
1023
+ setupAppThemeAndPlugins(app, config);
1024
+ return app;
1017
1025
  };
1026
+ //#endregion
1027
+ export { DEFAULT_IGNORE_PATTERNS, appInit, appPrepare, appUse, createAppDirFunction, createBaseApp, createBuildApp, createDevApp, createHookQueue, createPage, createPluginApi, createPluginApiHooks, createPluginApiRegisterHooks, inferPagePath, normalizeAliasDefineHook, normalizeClientConfigFileHook, parsePageContent, prepareClientConfigs, preparePageChunk, prepareRoutes, prepareSiteData, prepareUserStyle, renderPageToVue, resolveAppDir, resolveAppEnv, resolveAppOptions, resolveAppPages, resolveAppSiteData, resolveAppVersion, resolveAppWriteTemp, resolvePageChunkInfo, resolvePageContent, resolvePageDate, resolvePageFilePath, resolvePageHtmlInfo, resolvePageLang, resolvePagePath, resolvePagePermalink, resolvePageRedirects, resolvePageRouteMeta, resolvePageSlug, resolvePluginObject, resolveThemeInfo };