valaxy 0.3.11 → 0.6.0

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.
Files changed (150) hide show
  1. package/README.md +0 -4
  2. package/{src/client → client}/App.vue +0 -0
  3. package/{src/client/composables/search/index.ts → client/app/data.ts} +0 -0
  4. package/{src/client → client}/components/AppLink.vue +0 -0
  5. package/client/components/PostCard.vue +84 -0
  6. package/{src/client → client}/components/PostList.vue +0 -0
  7. package/{src/client → client}/components/README.md +0 -0
  8. package/{src/client → client}/components/ValaxyBg.vue +0 -0
  9. package/{src/client → client}/components/ValaxyCopyright.vue +0 -0
  10. package/{src/client → client}/components/ValaxyFooter.vue +1 -1
  11. package/{src/client → client}/components/ValaxyHamburger.vue +0 -0
  12. package/{src/client → client}/components/ValaxyMd.vue +1 -5
  13. package/{src/client → client}/components/ValaxyOverlay.vue +0 -0
  14. package/{src/client → client}/components/ValaxyPagination.vue +0 -0
  15. package/{src/client → client}/components/ValaxyRightSidebar.vue +0 -0
  16. package/{src/client → client}/components/ValaxySidebar.vue +0 -0
  17. package/{src/client → client}/components/ValaxyToc.vue +3 -3
  18. package/{src/client → client}/composables/category.ts +0 -0
  19. package/{src/client → client}/composables/comments/index.ts +0 -0
  20. package/{src/client → client}/composables/comments/twikoo.ts +0 -0
  21. package/{src/client → client}/composables/comments/waline.ts +0 -0
  22. package/{src/client → client}/composables/common.ts +0 -0
  23. package/{src/client → client}/composables/dark.ts +0 -0
  24. package/client/composables/features/index.ts +0 -0
  25. package/{src/client → client}/composables/helper.ts +0 -0
  26. package/{src/client → client}/composables/index.ts +1 -1
  27. package/{src/client → client}/composables/layout.ts +0 -0
  28. package/client/composables/outline.ts +181 -0
  29. package/{src/client → client}/composables/post.ts +0 -0
  30. package/client/composables/search/index.ts +0 -0
  31. package/{src/client → client}/composables/sidebar.ts +68 -9
  32. package/{src/client → client}/composables/tag.ts +0 -0
  33. package/{src/client → client}/composables/widgets/aplayer.ts +0 -0
  34. package/{src/client → client}/composables/widgets/backToTop.ts +0 -0
  35. package/{src/client → client}/composables/widgets/codepen.ts +0 -0
  36. package/{src/client → client}/composables/widgets/index.ts +0 -0
  37. package/client/config.ts +75 -0
  38. package/{src/client → client}/index.html +0 -0
  39. package/{src/client → client}/index.ts +0 -0
  40. package/{src/client → client}/layouts/404.vue +0 -0
  41. package/{src/client → client}/layouts/README.md +0 -0
  42. package/{src/client → client}/locales/README.md +0 -0
  43. package/{src/client → client}/locales/en.yml +1 -0
  44. package/{src/client → client}/locales/zh-CN.yml +4 -3
  45. package/{src/client → client}/main.ts +8 -1
  46. package/{src/client → client}/modules/README.md +0 -0
  47. package/{src/client → client}/modules/nprogress.ts +0 -0
  48. package/{src/client → client}/modules/pinia.ts +0 -0
  49. package/{src/client → client}/modules/valaxy.ts +34 -9
  50. package/{src/client → client}/pages/README.md +0 -0
  51. package/{src/client → client}/pages/[...all].vue +0 -0
  52. package/{src/client → client}/pages/hi/[name].vue +0 -0
  53. package/{src/client → client}/pages/index.vue +0 -0
  54. package/{src/client → client}/pages/page/[page].vue +0 -0
  55. package/{src/client → client}/shims.d.ts +7 -1
  56. package/{src/client → client}/stores/app.ts +0 -0
  57. package/{src/client → client}/stores/user.ts +0 -0
  58. package/{src/client → client}/styles/common/button.scss +0 -0
  59. package/{src/client → client}/styles/common/code.scss +0 -0
  60. package/{src/client → client}/styles/common/custom-blocks.scss +0 -0
  61. package/{src/client → client}/styles/common/hamburger.scss +0 -0
  62. package/{src/client → client}/styles/common/markdown.scss +5 -1
  63. package/client/styles/common/scrollbar.scss +28 -0
  64. package/{src/client → client}/styles/common/sidebar.scss +0 -0
  65. package/{src/client → client}/styles/common/transition.scss +0 -0
  66. package/{src/client → client}/styles/css-vars.scss +0 -0
  67. package/{src/client → client}/styles/global/helper.scss +0 -0
  68. package/{src/client → client}/styles/global/i18n.scss +0 -0
  69. package/{src/client → client}/styles/global/index.scss +0 -0
  70. package/{src/client → client}/styles/global/nprogress.scss +0 -0
  71. package/{src/client → client}/styles/global/reset.scss +0 -0
  72. package/{src/client → client}/styles/index.scss +0 -0
  73. package/{src/client → client}/styles/mixins/config.scss +0 -0
  74. package/{src/client → client}/styles/mixins/index.scss +0 -0
  75. package/{src/client → client}/styles/mixins/size.scss +0 -0
  76. package/{src/client → client}/styles/mixins/variable.scss +0 -0
  77. package/{src/client → client}/styles/palette.scss +6 -2
  78. package/client/styles/third/katex.scss +3 -0
  79. package/{src/client → client}/styles/vars.scss +0 -0
  80. package/{src/client → client}/styles/widgets/banner.scss +0 -0
  81. package/{src/client → client}/types.ts +0 -0
  82. package/{src/client → client}/utils/helper.ts +22 -0
  83. package/{src/client → client}/utils/index.ts +0 -0
  84. package/client/utils/sidebar.ts +26 -0
  85. package/{src/client → client}/utils/time.ts +0 -0
  86. package/config/index.ts +18 -0
  87. package/dist/chunk-CP3UCJ2D.js +34 -0
  88. package/dist/chunk-EAN2KU6W.mjs +1 -0
  89. package/dist/chunk-HCVZ2UUO.mjs +34 -0
  90. package/dist/chunk-U5OMNIOK.js +1 -0
  91. package/dist/{config-de04677b.d.ts → config-ad23e743.d.ts} +28 -14
  92. package/dist/index.d.ts +67 -111
  93. package/dist/index.js +1 -1
  94. package/dist/index.mjs +1 -1
  95. package/dist/node/cli.js +7 -11
  96. package/dist/node/cli.mjs +7 -11
  97. package/dist/node/index.d.ts +2 -2
  98. package/dist/node/index.js +1 -1
  99. package/dist/node/index.mjs +1 -1
  100. package/{src/index.ts → index.ts} +1 -0
  101. package/{src/node → node}/build.ts +0 -0
  102. package/{src/node → node}/cli.ts +3 -2
  103. package/node/config.ts +156 -0
  104. package/{src/node → node}/index.ts +0 -0
  105. package/{src/node → node}/markdown/check.ts +0 -0
  106. package/{src/node → node}/markdown/highlight.ts +0 -0
  107. package/{src/node → node}/markdown/index.ts +21 -13
  108. package/{src/node → node}/markdown/markdown-it/container.ts +0 -0
  109. package/{src/node → node}/markdown/markdown-it/headings.ts +0 -0
  110. package/{src/node → node}/markdown/markdown-it/highlightLines.ts +0 -0
  111. package/{src/node → node}/markdown/markdown-it/katex.ts +0 -0
  112. package/{src/node → node}/markdown/markdown-it/parseHeader.ts +0 -0
  113. package/node/markdown/markdownToVue.ts +253 -0
  114. package/{src/node → node}/markdown/slugify.ts +0 -0
  115. package/{src/node → node}/options.ts +18 -2
  116. package/{src/node → node}/plugins/extendConfig.ts +6 -3
  117. package/node/plugins/index.ts +224 -0
  118. package/{src/node → node}/plugins/preset.ts +6 -36
  119. package/{src/node → node}/plugins/unocss.ts +0 -0
  120. package/{src/node → node}/plugins/valaxy.ts +0 -0
  121. package/{src/node → node}/rss.ts +1 -1
  122. package/{src/node → node}/server.ts +6 -4
  123. package/{src/node → node}/shims.d.ts +0 -0
  124. package/{src/node → node}/utils/cli.ts +1 -1
  125. package/node/utils/getGitTimestamp.ts +13 -0
  126. package/node/utils/index.ts +59 -0
  127. package/node/utils/net.ts +20 -0
  128. package/{src/node → node}/vite.ts +5 -1
  129. package/package.json +33 -13
  130. package/shared/index.ts +1 -0
  131. package/tsup.config.ts +7 -4
  132. package/{src/types → types}/config.ts +31 -108
  133. package/types/data.ts +31 -0
  134. package/{src/types → types}/index.ts +1 -0
  135. package/{src/types → types}/posts.ts +6 -1
  136. package/dist/chunk-6LIOFBAA.mjs +0 -1
  137. package/dist/chunk-ABPVSNYI.js +0 -83
  138. package/dist/chunk-QOANGHSR.mjs +0 -83
  139. package/dist/chunk-V3BMKLEW.js +0 -1
  140. package/src/client/components/PostCard.vue +0 -68
  141. package/src/client/composables/features/index.ts +0 -1
  142. package/src/client/composables/features/katex.ts +0 -15
  143. package/src/client/composables/search/algolia.ts +0 -115
  144. package/src/client/config.ts +0 -51
  145. package/src/client/modules/pwa.ts +0 -12
  146. package/src/client/styles/common/scrollbar.scss +0 -34
  147. package/src/node/config.ts +0 -52
  148. package/src/node/plugins/index.ts +0 -120
  149. package/src/node/plugins/markdown.ts +0 -57
  150. package/src/node/utils/index.ts +0 -26
@@ -1,12 +1,11 @@
1
1
  import * as vite from 'vite';
2
2
  import { InlineConfig } from 'vite';
3
- import { V as ValaxyConfig } from '../config-de04677b.js';
3
+ import { V as ValaxyConfig } from '../config-ad23e743.js';
4
4
  import 'type-fest';
5
5
  import 'unocss/vite';
6
6
  import 'markdown-it';
7
7
  import 'markdown-it-anchor';
8
8
  import 'katex';
9
- import 'vite-plugin-md';
10
9
 
11
10
  interface ResolvedValaxyOptions {
12
11
  mode: 'dev' | 'build';
@@ -36,6 +35,7 @@ interface ResolvedValaxyOptions {
36
35
  * config file path
37
36
  */
38
37
  configFile: string;
38
+ pages: string[];
39
39
  }
40
40
  interface ValaxyServerOptions {
41
41
  onConfigReload?: (newConfig: ValaxyConfig, config: ValaxyConfig) => void;
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkABPVSNYIjs = require('../chunk-ABPVSNYI.js');require('../chunk-V3BMKLEW.js');exports.createServer = _chunkABPVSNYIjs.g;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkCP3UCJ2Djs = require('../chunk-CP3UCJ2D.js');require('../chunk-U5OMNIOK.js');exports.createServer = _chunkCP3UCJ2Djs.f;
@@ -1 +1 @@
1
- import{g as o}from"../chunk-QOANGHSR.mjs";import"../chunk-6LIOFBAA.mjs";export{o as createServer};
1
+ import{f as o}from"../chunk-HCVZ2UUO.mjs";import"../chunk-EAN2KU6W.mjs";export{o as createServer};
@@ -1,2 +1,3 @@
1
1
  export * from './client'
2
2
  export * from './types'
3
+ export * from './config'
File without changes
@@ -9,7 +9,8 @@ import openBrowser from 'open'
9
9
  import consola from 'consola'
10
10
 
11
11
  import { yellow } from 'kolorist'
12
- import { version } from '../../package.json'
12
+ import { version } from '../package.json'
13
+ import { findFreePort } from './utils/net'
13
14
  import { resolveOptions } from './options'
14
15
  import { bindShortcut, initServer, printInfo } from './utils/cli'
15
16
 
@@ -59,7 +60,7 @@ cli.command(
59
60
  if (!fs.existsSync(path.resolve(root, 'pages')))
60
61
  process.exit(0)
61
62
 
62
- const port = userPort || 4859
63
+ const port = await findFreePort(userPort || 4859)
63
64
  const options = await resolveOptions({ userRoot: root })
64
65
 
65
66
  const viteConfig: InlineConfig = {
package/node/config.ts ADDED
@@ -0,0 +1,156 @@
1
+ // import { loadConfig } from 'c12'
2
+ import fs from 'fs'
3
+ import { loadConfig } from 'unconfig'
4
+ import defu from 'defu'
5
+ import type { ValaxyConfig } from '../types'
6
+ import type { ValaxyEntryOptions } from './options'
7
+
8
+ const defaultValaxyConfig: ValaxyConfig = {
9
+ url: '/',
10
+ lang: 'en',
11
+ title: 'Valaxy Blog',
12
+ description: 'A blog generated by Valaxy.',
13
+ subtitle: 'Next Generation Static Blog Framework.',
14
+ author: {
15
+ avatar: 'https://cdn.jsdelivr.net/gh/YunYouJun/yun/images/meme/yun-good-with-bg.jpg',
16
+ email: 'me@yunyoujun.cn',
17
+ link: 'https://www.yunyoujun.cn',
18
+ name: 'YunYouJun',
19
+ status: {
20
+ emoji: '😊',
21
+ message: 'All at sea.',
22
+ },
23
+ },
24
+ favicon: '/favicon.svg',
25
+ feed: {
26
+ name: '',
27
+ favicon: 'favicon.svg',
28
+ },
29
+ social: [],
30
+
31
+ lastUpdated: true,
32
+
33
+ license: {
34
+ enabled: true,
35
+ language: '',
36
+ type: 'by-nc-sa',
37
+ },
38
+
39
+ sponsor: {
40
+ enable: true,
41
+ title: '我很可爱,请给我钱',
42
+ methods: [
43
+ {
44
+ name: '支付宝',
45
+ url: 'https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/donate/alipay-qrcode.jpg',
46
+ color: '#00A3EE',
47
+ icon: 'i-ri-alipay-line',
48
+ },
49
+ {
50
+ name: 'QQ 支付',
51
+ url: 'https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/donate/qqpay-qrcode.png',
52
+ color: '#12B7F5',
53
+ icon: 'i-ri-qq-line',
54
+ },
55
+ {
56
+ name: '微信支付',
57
+ url: 'https://cdn.jsdelivr.net/gh/YunYouJun/cdn/img/donate/wechatpay-qrcode.jpg',
58
+ color: '#2DC100',
59
+ icon: 'i-ri-wechat-pay-line',
60
+ },
61
+
62
+ ],
63
+ },
64
+
65
+ search: {
66
+ enable: true,
67
+ algolia: {
68
+ enable: false,
69
+ appId: '',
70
+ apiKey: '',
71
+ indexName: '',
72
+ },
73
+ },
74
+
75
+ comment: {
76
+ waline: {
77
+ enable: false,
78
+ serverURL: '',
79
+ },
80
+ twikoo: {
81
+ enable: false,
82
+ envId: 'https://twikoo.vercel.app',
83
+ },
84
+ },
85
+
86
+ features: {
87
+ katex: true,
88
+ },
89
+
90
+ theme: 'yun',
91
+ themeConfig: {
92
+ pkg: {
93
+ name: '',
94
+ version: '',
95
+ },
96
+ },
97
+
98
+ unocss: {},
99
+
100
+ // markdown: {
101
+ // excerpt: '<!-- more -->',
102
+ // },
103
+
104
+ markdownIt: {
105
+ toc: {
106
+ includeLevel: [1, 2, 3, 4],
107
+ listType: 'ol',
108
+ },
109
+ katex: {},
110
+ },
111
+ }
112
+
113
+ // for user config
114
+ export async function resolveConfig(options: ValaxyEntryOptions = {}) {
115
+ // c12 merge array twice, so i deprecated it
116
+ // const { config, configFile } = await loadConfig<ValaxyConfig>({
117
+ // name: 'valaxy',
118
+ // defaults: defaultValaxyConfig,
119
+ // })
120
+
121
+ const { config: userConfig, sources } = await loadConfig<ValaxyConfig>({
122
+ sources: [
123
+ {
124
+ files: 'valaxy.config',
125
+ extensions: ['ts', 'js', 'mjs', 'cjs', 'json'],
126
+ },
127
+ ],
128
+ merge: false,
129
+ })
130
+ const configFile = sources[0]
131
+ const config = defu(userConfig, defaultValaxyConfig)
132
+
133
+ const theme = options.theme || config.theme || 'yun'
134
+
135
+ try {
136
+ const { defaultThemeConfig } = await import(`valaxy-theme-${theme}`)
137
+ config.themeConfig = defu(config.themeConfig, defaultThemeConfig)
138
+ }
139
+ catch (e) {
140
+ console.error(`valaxy-theme-${theme} doesn't have default config`)
141
+ }
142
+
143
+ try {
144
+ const pkg = fs.readFileSync(require.resolve(`valaxy-theme-${theme}/package.json`), 'utf-8')
145
+ config.themeConfig.pkg = JSON.parse(pkg)
146
+ }
147
+ catch (e) {
148
+ console.error(`valaxy-theme-${theme} doesn't have package.json`)
149
+ }
150
+
151
+ return {
152
+ config,
153
+ configFile,
154
+ theme,
155
+ }
156
+ }
File without changes
File without changes
File without changes
@@ -1,4 +1,4 @@
1
- import type MarkdownIt from 'markdown-it'
1
+ import MarkdownIt from 'markdown-it'
2
2
 
3
3
  import Anchor from 'markdown-it-anchor'
4
4
  import Emoji from 'markdown-it-emoji'
@@ -8,30 +8,23 @@ import TaskLists from 'markdown-it-task-lists'
8
8
  import attrs from 'markdown-it-attrs'
9
9
 
10
10
  import type { KatexOptions } from 'katex'
11
+ import type { Header } from '../../types'
11
12
  import Katex from './markdown-it/katex'
12
13
  import { containerPlugin } from './markdown-it/container'
13
- // import { headingPlugin } from './markdown-it/headings'
14
+ import { headingPlugin } from './markdown-it/headings'
14
15
  import { slugify } from './slugify'
15
16
  import { parseHeader } from './markdown-it/parseHeader'
16
17
  import { highlight } from './highlight'
17
18
  import { highlightLinePlugin, preWrapperPlugin } from './markdown-it/highlightLines'
18
19
 
19
- export interface Header {
20
- level: number
21
- title: string
22
- slug: string
23
- /**
24
- * i18n
25
- */
26
- lang?: string
27
- }
28
-
29
20
  export interface MarkdownParsedData {
30
21
  hoistedTags?: string[]
31
22
  links?: string[]
32
23
  headers?: Header[]
33
24
  }
34
25
  export interface MarkdownRenderer extends MarkdownIt {
26
+ __path: string
27
+ __relativePath: string
35
28
  __data: MarkdownParsedData
36
29
  }
37
30
 
@@ -59,7 +52,7 @@ export function setupMarkdownPlugins(md: MarkdownIt, mdOptions: MarkdownOptions
59
52
  // conflict with {% %}
60
53
  .use(attrs)
61
54
  // generate toc in client
62
- // .use(headingPlugin, mdOptions?.toc?.includeLevel)
55
+ .use(headingPlugin, mdOptions?.toc?.includeLevel)
63
56
  // .use(lineNumberPlugin)
64
57
  // https://github.com/arve0/markdown-it-attrs
65
58
  // add classes
@@ -93,3 +86,18 @@ export function setupMarkdownPlugins(md: MarkdownIt, mdOptions: MarkdownOptions
93
86
 
94
87
  return md as MarkdownRenderer
95
88
  }
89
+
90
+ export const createMarkdownRenderer = async (
91
+ srcDir: string,
92
+ options: MarkdownOptions = {},
93
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
94
+ base = '/',
95
+ ): Promise<MarkdownRenderer> => {
96
+ const md = MarkdownIt({
97
+ html: true,
98
+ linkify: true,
99
+ ...options,
100
+ }) as MarkdownRenderer
101
+ setupMarkdownPlugins(md)
102
+ return md
103
+ }
File without changes
@@ -0,0 +1,253 @@
1
+ // copy from vitepress
2
+ import fs from 'fs'
3
+ import path from 'path'
4
+ import c from 'picocolors'
5
+ import matter from 'gray-matter'
6
+ import LRUCache from 'lru-cache'
7
+ import _debug from 'debug'
8
+ import { getGitTimestamp, slash, transformObject } from '../utils'
9
+ import { EXTERNAL_URL_RE } from '../../shared'
10
+ import type { HeadConfig, PageData } from '../../types'
11
+ import { deeplyParseHeader } from './markdown-it/parseHeader'
12
+ import { createMarkdownRenderer } from '.'
13
+ import type { MarkdownOptions } from '.'
14
+
15
+ const debug = _debug('vitepress:md')
16
+ const cache = new LRUCache<string, MarkdownCompileResult>({ max: 1024 })
17
+ const includesRE = /<!--\s*@include:\s*(.*?)\s*-->/g
18
+
19
+ export interface MarkdownCompileResult {
20
+ vueSrc: string
21
+ pageData: PageData
22
+ deadLinks: string[]
23
+ includes: string[]
24
+ }
25
+
26
+ const inferTitle = (frontmatter: Record<string, any>, content: string) => {
27
+ if (frontmatter.title)
28
+ return deeplyParseHeader(frontmatter.title)
29
+
30
+ const match = content.match(/^\s*#+\s+(.*)/m)
31
+
32
+ if (match)
33
+ return deeplyParseHeader(match[1].trim())
34
+
35
+ return ''
36
+ }
37
+
38
+ const getHeadMetaContent = (
39
+ head: HeadConfig[],
40
+ name: string,
41
+ ): string | undefined => {
42
+ if (!head || !head.length)
43
+ return undefined
44
+
45
+ const meta = head.find(([tag, attrs = {}]) => {
46
+ return tag === 'meta' && attrs.name === name && attrs.content
47
+ })
48
+
49
+ return meta && meta[1].content
50
+ }
51
+
52
+ const inferDescription = (frontmatter: Record<string, any>) => {
53
+ const { description, head } = frontmatter
54
+
55
+ if (description !== undefined)
56
+ return description
57
+
58
+ return (head && getHeadMetaContent(head, 'description')) || ''
59
+ }
60
+
61
+ export async function createMarkdownToVueRenderFn(
62
+ srcDir: string,
63
+ options: MarkdownOptions = {},
64
+ pages: string[],
65
+ userDefines: Record<string, any> | undefined,
66
+ isBuild = false,
67
+ base = '/',
68
+ includeLastUpdatedData = false,
69
+ ) {
70
+ const md = await createMarkdownRenderer(srcDir, options, base)
71
+
72
+ pages = pages.map(p => slash(p.replace(/\.md$/, '')))
73
+
74
+ const userDefineRegex = userDefines
75
+ ? new RegExp(
76
+ `\\b(${Object.keys(userDefines)
77
+ .map(key => key.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&'))
78
+ .join('|')})`,
79
+ 'g',
80
+ )
81
+ : null
82
+
83
+ return async (
84
+ src: string,
85
+ file: string,
86
+ publicDir: string,
87
+ ): Promise<MarkdownCompileResult> => {
88
+ const relativePath = slash(path.relative(srcDir, file))
89
+ const dir = path.dirname(file)
90
+
91
+ const cached = cache.get(src)
92
+ if (cached) {
93
+ debug(`[cache hit] ${relativePath}`)
94
+ return cached
95
+ }
96
+
97
+ const start = Date.now()
98
+
99
+ // resolve includes
100
+ const includes: string[] = []
101
+ src = src.replace(includesRE, (_, m1) => {
102
+ const includePath = path.join(dir, m1)
103
+ const content = fs.readFileSync(includePath, 'utf-8')
104
+ includes.push(slash(includePath))
105
+ return content
106
+ })
107
+
108
+ const { content, data: frontmatter } = matter(src)
109
+
110
+ // reset state before render
111
+ md.__path = file
112
+ md.__relativePath = relativePath
113
+
114
+ let html = md.render(content)
115
+ const data = md.__data
116
+
117
+ if (isBuild) {
118
+ // avoid env variables being replaced by vite
119
+ html = html
120
+ .replace(/\bimport\.meta/g, 'import.<wbr/>meta')
121
+ .replace(/\bprocess\.env/g, 'process.<wbr/>env')
122
+
123
+ // also avoid replacing vite user defines
124
+ if (userDefineRegex) {
125
+ html = html.replace(
126
+ userDefineRegex,
127
+ _ => `${_[0]}<wbr/>${_.slice(1)}`,
128
+ )
129
+ }
130
+ }
131
+
132
+ // validate data.links
133
+ const deadLinks: string[] = []
134
+ const recordDeadLink = (url: string) => {
135
+ console.warn(
136
+ c.yellow(
137
+ `\n(!) Found dead link ${c.cyan(url)} in file ${c.white(c.dim(file))}`,
138
+ ),
139
+ )
140
+ deadLinks.push(url)
141
+ }
142
+
143
+ if (data.links) {
144
+ const dir = path.dirname(file)
145
+ for (let url of data.links) {
146
+ if (/\.(?!html|md)\w+($|\?)/i.test(url))
147
+ continue
148
+
149
+ if (url.replace(EXTERNAL_URL_RE, '').startsWith('//localhost:')) {
150
+ recordDeadLink(url)
151
+ continue
152
+ }
153
+
154
+ url = url.replace(/[?#].*$/, '').replace(/\.(html|md)$/, '')
155
+ if (url.endsWith('/'))
156
+ url += 'index'
157
+ const resolved = decodeURIComponent(
158
+ slash(
159
+ url.startsWith('/')
160
+ ? url.slice(1)
161
+ : path.relative(srcDir, path.resolve(dir, url)),
162
+ ),
163
+ )
164
+ if (
165
+ !pages.includes(resolved)
166
+ && !fs.existsSync(path.resolve(dir, publicDir, `${resolved}.html`))
167
+ )
168
+ recordDeadLink(url)
169
+ }
170
+ }
171
+
172
+ const pageData: PageData = {
173
+ title: inferTitle(frontmatter, content),
174
+ titleTemplate: frontmatter.titleTemplate,
175
+ description: inferDescription(frontmatter),
176
+ frontmatter,
177
+ headers: data.headers || [],
178
+ relativePath,
179
+ path: path.join(srcDir, relativePath),
180
+ }
181
+
182
+ if (includeLastUpdatedData)
183
+ pageData.lastUpdated = await getGitTimestamp(file)
184
+
185
+ const valaxyMd = 'ValaxyMd'
186
+ const vueSrc
187
+ = `${genPageDataCode(data.hoistedTags || [], pageData).join('\n')
188
+ }\n<template><${valaxyMd} :frontmatter="frontmatter">${html}</${valaxyMd}></template>`
189
+
190
+ debug(`[render] ${file} in ${Date.now() - start}ms.`)
191
+
192
+ const result = {
193
+ vueSrc,
194
+ pageData,
195
+ deadLinks,
196
+ includes,
197
+ }
198
+ cache.set(src, result)
199
+ return result
200
+ }
201
+ }
202
+
203
+ const scriptRE = /<\/script>/
204
+ const scriptLangTsRE = /<\s*script[^>]*\blang=['"]ts['"][^>]*/
205
+ const scriptSetupRE = /<\s*script[^>]*\bsetup\b[^>]*/
206
+ const scriptClientRE = /<\s*script[^>]*\bclient\b[^>]*/
207
+ const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/
208
+ const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/
209
+
210
+ function genPageDataCode(tags: string[], data: PageData) {
211
+ const code = `\nexport const __pageData = ${transformObject(data)}`
212
+
213
+ const existingScriptIndex = tags.findIndex((tag) => {
214
+ return (
215
+ scriptRE.test(tag)
216
+ && !scriptSetupRE.test(tag)
217
+ && !scriptClientRE.test(tag)
218
+ )
219
+ })
220
+
221
+ const isUsingTS = tags.findIndex(tag => scriptLangTsRE.test(tag)) > -1
222
+
223
+ const exportScript = `
224
+ export default {
225
+ name:'${data.relativePath}',
226
+ data() {
227
+ return {frontmatter:${transformObject(data.frontmatter)}}
228
+ }
229
+ }`
230
+
231
+ if (existingScriptIndex > -1) {
232
+ const tagSrc = tags[existingScriptIndex]
233
+ // user has <script> tag inside markdown
234
+ // if it doesn't have export default it will error out on build
235
+ const hasDefaultExport
236
+ = defaultExportRE.test(tagSrc) || namedDefaultExportRE.test(tagSrc)
237
+ tags[existingScriptIndex] = tagSrc.replace(
238
+ scriptRE,
239
+ `${code
240
+ + (hasDefaultExport
241
+ ? ''
242
+ : `\n${exportScript}`)
243
+ }</script>`,
244
+ )
245
+ }
246
+ else {
247
+ tags.unshift(
248
+ `<script ${isUsingTS ? 'lang="ts"' : ''}>${code}\n${exportScript}</script>`,
249
+ )
250
+ }
251
+
252
+ return tags
253
+ }
File without changes
@@ -1,5 +1,6 @@
1
1
  import { dirname, resolve } from 'path'
2
2
  import _debug from 'debug'
3
+ import fg from 'fast-glob'
3
4
  import type { ValaxyConfig } from '../types'
4
5
  import { resolveConfig } from './config'
5
6
  import { resolveImportPath } from './utils'
@@ -43,6 +44,7 @@ export interface ResolvedValaxyOptions {
43
44
  * config file path
44
45
  */
45
46
  configFile: string
47
+ pages: string[]
46
48
  }
47
49
 
48
50
  export interface ValaxyServerOptions {
@@ -66,17 +68,30 @@ export function getThemeRoot(name: string, entry: string) {
66
68
  if (isPath(name))
67
69
  return resolve(dirname(entry), name)
68
70
  else
69
- return resolveImportPath(`valaxy-theme-${name}/package.json`)
71
+ return dirname(resolveImportPath(`valaxy-theme-${name}/package.json`) || '')
70
72
  }
71
73
 
72
74
  // for cli options
73
75
  export async function resolveOptions(options: ValaxyEntryOptions, mode: ResolvedValaxyOptions['mode'] = 'dev') {
74
- const clientRoot = resolve(resolveImportPath('valaxy/package.json'), 'src/client')
76
+ const clientRoot = resolve(dirname(resolveImportPath('valaxy/package.json', true)), 'client')
75
77
  const userRoot = resolve(options.userRoot || process.cwd())
76
78
 
77
79
  const { config: valaxyConfig, configFile, theme } = await resolveConfig(options)
78
80
  const themeRoot = getThemeRoot(theme, userRoot)
79
81
 
82
+ // Important: fast-glob doesn't guarantee order of the returned files.
83
+ // We must sort the pages so the input list to rollup is stable across
84
+ // builds - otherwise different input order could result in different exports
85
+ // order in shared chunks which in turns invalidates the hash of every chunk!
86
+ // JavaScript built-in sort() is mandated to be stable as of ES2019 and
87
+ // supported in Node 12+, which is required by Vite.
88
+ const pages = (
89
+ await fg(['**.md'], {
90
+ cwd: userRoot,
91
+ ignore: ['**/node_modules'],
92
+ })
93
+ ).sort()
94
+
80
95
  const valaxyOptions: ResolvedValaxyOptions = {
81
96
  mode,
82
97
  clientRoot,
@@ -85,6 +100,7 @@ export async function resolveOptions(options: ValaxyEntryOptions, mode: Resolved
85
100
  theme,
86
101
  config: valaxyConfig,
87
102
  configFile: configFile || '',
103
+ pages,
88
104
  }
89
105
  debug(valaxyOptions)
90
106
 
@@ -13,13 +13,14 @@ export function createConfigPlugin(options: ResolvedValaxyOptions): Plugin {
13
13
  alias: {
14
14
  '@/': `${toAtFS(options.userRoot)}/`,
15
15
  '~/': `${toAtFS(options.clientRoot)}/`,
16
+ 'valaxy/client': `${toAtFS(options.clientRoot)}/`,
17
+ 'valaxy': toAtFS(resolve(options.clientRoot, 'index.ts')),
16
18
  '@valaxyjs/client': `${toAtFS(options.clientRoot)}/`,
17
19
  '@valaxyjs/config': '/@valaxyjs/config',
20
+ '@valaxyjs/context': '/@valaxyjs/context',
18
21
  'valaxy/package.json': toAtFS(resolve(options.clientRoot, '../../package.json')),
19
- 'valaxy/': `${toAtFS(resolve(options.clientRoot, '../..'))}/`,
20
- 'valaxy': toAtFS(resolve(options.clientRoot, '../index.ts')),
21
22
  [`valaxy-theme-${options.theme}/`]: `${toAtFS(resolve(options.themeRoot))}/`,
22
- [`valaxy-theme-${options.theme}`]: `${toAtFS(resolve(options.themeRoot))}`,
23
+ [`valaxy-theme-${options.theme}`]: `${toAtFS(resolve(options.themeRoot))}/index.ts`,
23
24
  },
24
25
  },
25
26
 
@@ -35,6 +36,8 @@ export function createConfigPlugin(options: ResolvedValaxyOptions): Plugin {
35
36
  'dayjs',
36
37
  'nprogress',
37
38
  ],
39
+
40
+ exclude: ['@docsearch/js'],
38
41
  },
39
42
  }
40
43
  return mergeConfig(config, injection)