valaxy 0.6.2 → 0.7.1

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 (70) hide show
  1. package/client/components/PostCard.vue +26 -29
  2. package/client/config.ts +1 -1
  3. package/client/index.ts +5 -0
  4. package/client/locales/en.yml +18 -17
  5. package/client/locales/zh-CN.yml +5 -4
  6. package/client/main.ts +3 -0
  7. package/client/setup/main.ts +11 -0
  8. package/client/setups.ts +16 -0
  9. package/client/styles/common/custom-blocks.scss +7 -0
  10. package/client/styles/common/markdown.scss +0 -4
  11. package/dist/chunk-35O5DRGK.mjs +2270 -0
  12. package/dist/chunk-4VSND5ZW.mjs +1 -0
  13. package/dist/chunk-CDIW2WTI.js +1 -0
  14. package/dist/chunk-RGBLPQZ2.js +2270 -0
  15. package/dist/{index.d.ts → client/index.d.ts} +16 -160
  16. package/dist/client/index.js +1 -0
  17. package/dist/client/index.mjs +1 -0
  18. package/dist/index-a6b0a69b.d.ts +16 -0
  19. package/dist/{config-112ac884.d.ts → index-afca77df.d.ts} +223 -6
  20. package/dist/node/cli.js +13 -8
  21. package/dist/node/cli.mjs +13 -8
  22. package/dist/node/index.d.ts +13 -35
  23. package/dist/node/index.js +1 -1
  24. package/dist/node/index.mjs +1 -1
  25. package/dist/types/index.d.ts +10 -0
  26. package/dist/types/index.js +1 -0
  27. package/dist/types/index.mjs +0 -0
  28. package/package.json +27 -22
  29. package/shared/index.ts +19 -0
  30. package/config/index.ts +0 -18
  31. package/dist/chunk-23IW567G.mjs +0 -40
  32. package/dist/chunk-EAN2KU6W.mjs +0 -1
  33. package/dist/chunk-U5OMNIOK.js +0 -1
  34. package/dist/chunk-YUC5WP5Y.js +0 -40
  35. package/dist/index.js +0 -1
  36. package/dist/index.mjs +0 -1
  37. package/index.ts +0 -3
  38. package/node/build.ts +0 -31
  39. package/node/cli.ts +0 -192
  40. package/node/config.ts +0 -156
  41. package/node/index.ts +0 -1
  42. package/node/markdown/check.ts +0 -14
  43. package/node/markdown/highlight.ts +0 -38
  44. package/node/markdown/index.ts +0 -109
  45. package/node/markdown/markdown-it/container.ts +0 -61
  46. package/node/markdown/markdown-it/headings.ts +0 -32
  47. package/node/markdown/markdown-it/highlightLines.ts +0 -96
  48. package/node/markdown/markdown-it/katex.ts +0 -210
  49. package/node/markdown/markdown-it/parseHeader.ts +0 -72
  50. package/node/markdown/markdownToVue.ts +0 -275
  51. package/node/markdown/slugify.ts +0 -24
  52. package/node/options.ts +0 -108
  53. package/node/plugins/extendConfig.ts +0 -46
  54. package/node/plugins/index.ts +0 -224
  55. package/node/plugins/preset.ts +0 -186
  56. package/node/plugins/unocss.ts +0 -110
  57. package/node/plugins/valaxy.ts +0 -1
  58. package/node/rss.ts +0 -127
  59. package/node/server.ts +0 -23
  60. package/node/shims.d.ts +0 -33
  61. package/node/utils/cli.ts +0 -103
  62. package/node/utils/getGitTimestamp.ts +0 -13
  63. package/node/utils/index.ts +0 -59
  64. package/node/utils/net.ts +0 -20
  65. package/node/vite.ts +0 -52
  66. package/tsup.config.ts +0 -25
  67. package/types/config.ts +0 -217
  68. package/types/data.ts +0 -31
  69. package/types/index.ts +0 -3
  70. package/types/posts.ts +0 -122
@@ -1,210 +0,0 @@
1
- // copy from https://github.com/slidevjs/slidev/blob/main/packages/slidev/node/plugins/markdown-it-katex.ts
2
- // Ported from https://github.com/waylonflinn/markdown-it-katex
3
-
4
- /* Process inline math */
5
- /*
6
- Like markdown-it-simplemath, this is a stripped down, simplified version of:
7
- https://github.com/runarberg/markdown-it-math
8
-
9
- It differs in that it takes (a subset of) LaTeX as input and relies on KaTeX
10
- for rendering output.
11
- */
12
-
13
- import type { KatexOptions } from 'katex'
14
- import katex from 'katex'
15
-
16
- // Test if potential opening or closing delimieter
17
- // Assumes that there is a "$" at state.src[pos]
18
- function isValidDelim(state: any, pos: number) {
19
- const max = state.posMax
20
- let can_open = true
21
- let can_close = true
22
-
23
- const prevChar = pos > 0 ? state.src.charCodeAt(pos - 1) : -1
24
- const nextChar = pos + 1 <= max ? state.src.charCodeAt(pos + 1) : -1
25
-
26
- // Check non-whitespace conditions for opening and closing, and
27
- // check that closing delimeter isn't followed by a number
28
- if (prevChar === 0x20/* " " */ || prevChar === 0x09
29
- ||/* \t */ (nextChar >= 0x30/* "0" */ && nextChar <= 0x39/* "9" */))
30
- can_close = false
31
-
32
- if (nextChar === 0x20/* " " */ || nextChar === 0x09/* \t */)
33
- can_open = false
34
-
35
- return {
36
- can_open,
37
- can_close,
38
- }
39
- }
40
-
41
- function math_inline(state: any, silent: boolean) {
42
- let match, token, res, pos
43
-
44
- if (state.src[state.pos] !== '$')
45
- return false
46
-
47
- res = isValidDelim(state, state.pos)
48
- if (!res.can_open) {
49
- if (!silent)
50
- state.pending += '$'
51
- state.pos += 1
52
- return true
53
- }
54
-
55
- // First check for and bypass all properly escaped delimieters
56
- // This loop will assume that the first leading backtick can not
57
- // be the first character in state.src, which is known since
58
- // we have found an opening delimieter already.
59
- const start = state.pos + 1
60
- match = start
61
- // eslint-disable-next-line no-cond-assign
62
- while ((match = state.src.indexOf('$', match)) !== -1) {
63
- // Found potential $, look for escapes, pos will point to
64
- // first non escape when complete
65
- pos = match - 1
66
- while (state.src[pos] === '\\') pos -= 1
67
-
68
- // Even number of escapes, potential closing delimiter found
69
- if (((match - pos) % 2) === 1)
70
- break
71
- match += 1
72
- }
73
-
74
- // No closing delimter found. Consume $ and continue.
75
- if (match === -1) {
76
- if (!silent)
77
- state.pending += '$'
78
- state.pos = start
79
- return true
80
- }
81
-
82
- // Check if we have empty content, ie: $$. Do not parse.
83
- if (match - start === 0) {
84
- if (!silent)
85
- state.pending += '$$'
86
- state.pos = start + 1
87
- return true
88
- }
89
-
90
- // Check for valid closing delimiter
91
- res = isValidDelim(state, match)
92
- if (!res.can_close) {
93
- if (!silent)
94
- state.pending += '$'
95
- state.pos = start
96
- return true
97
- }
98
-
99
- if (!silent) {
100
- token = state.push('math_inline', 'math', 0)
101
- token.markup = '$'
102
- token.content = state.src.slice(start, match)
103
- }
104
-
105
- state.pos = match + 1
106
- return true
107
- }
108
-
109
- function math_block(state: any, start: number, end: number, silent: boolean) {
110
- let firstLine; let lastLine; let next; let lastPos
111
- let found = false
112
- let pos = state.bMarks[start] + state.tShift[start]
113
- let max = state.eMarks[start]
114
-
115
- if (pos + 2 > max)
116
- return false
117
- if (state.src.slice(pos, pos + 2) !== '$$')
118
- return false
119
-
120
- pos += 2
121
- firstLine = state.src.slice(pos, max)
122
-
123
- if (silent)
124
- return true
125
- if (firstLine.trim().slice(-2) === '$$') {
126
- // Single line expression
127
- firstLine = firstLine.trim().slice(0, -2)
128
- found = true
129
- }
130
-
131
- for (next = start; !found;) {
132
- next++
133
-
134
- if (next >= end)
135
- break
136
-
137
- pos = state.bMarks[next] + state.tShift[next]
138
- max = state.eMarks[next]
139
-
140
- if (pos < max && state.tShift[next] < state.blkIndent) {
141
- // non-empty line with negative indent should stop the list:
142
- break
143
- }
144
-
145
- if (state.src.slice(pos, max).trim().slice(-2) === '$$') {
146
- lastPos = state.src.slice(0, max).lastIndexOf('$$')
147
- lastLine = state.src.slice(pos, lastPos)
148
- found = true
149
- }
150
- }
151
-
152
- state.line = next + 1
153
-
154
- const token = state.push('math_block', 'math', 0)
155
- token.block = true
156
- token.content = (firstLine && firstLine.trim() ? `${firstLine}\n` : '')
157
- + state.getLines(start + 1, next, state.tShift[start], true)
158
- + (lastLine && lastLine.trim() ? lastLine : '')
159
- token.map = [start, state.line]
160
- token.markup = '$$'
161
- return true
162
- }
163
-
164
- export default function math_plugin(md: any, options: KatexOptions) {
165
- // Default options
166
-
167
- options = options || {}
168
-
169
- // set KaTeX as the renderer for markdown-it-simplemath
170
- const katexInline = function (latex: string) {
171
- options.displayMode = false
172
- try {
173
- return katex.renderToString(latex, options)
174
- }
175
- catch (error) {
176
- if (options.throwOnError)
177
-
178
- console.warn(error)
179
- return latex
180
- }
181
- }
182
-
183
- const inlineRenderer = function (tokens: any, idx: number) {
184
- return katexInline(tokens[idx].content)
185
- }
186
-
187
- const katexBlock = function (latex: string) {
188
- options.displayMode = true
189
- try {
190
- return `<p>${katex.renderToString(latex, options)}</p>`
191
- }
192
- catch (error) {
193
- if (options.throwOnError)
194
-
195
- console.warn(error)
196
- return latex
197
- }
198
- }
199
-
200
- const blockRenderer = function (tokens: any, idx: number) {
201
- return `${katexBlock(tokens[idx].content)}\n`
202
- }
203
-
204
- md.inline.ruler.after('escape', 'math_inline', math_inline)
205
- md.block.ruler.after('blockquote', 'math_block', math_block, {
206
- alt: ['paragraph', 'reference', 'blockquote', 'list'],
207
- })
208
- md.renderer.rules.math_inline = inlineRenderer
209
- md.renderer.rules.math_block = blockRenderer
210
- }
@@ -1,72 +0,0 @@
1
- // ref vitepress
2
-
3
- // Since VuePress needs to extract the header from the markdown source
4
- // file and display it in the sidebar or title (#238), this file simply
5
- // removes some unnecessary elements to make header displays well at
6
- // sidebar or title.
7
- //
8
- // But header's parsing in the markdown content is done by the markdown
9
- // loader based on markdown-it. markdown-it parser will will always keep
10
- // HTML in headers, so in VuePress, after being parsed by the markdown
11
- // loader, the raw HTML in headers will finally be parsed by Vue-loader.
12
- // so that we can write HTML/Vue in the header. One exception is the HTML
13
- // wrapped by <code>(markdown token: '`') tag.
14
- import emojiData from 'markdown-it-emoji/lib/data/full.json'
15
-
16
- const parseEmojis = (str: string) => {
17
- return str.replace(
18
- /:(.+?):/g,
19
- (placeholder, key) => (emojiData as any)[key] || placeholder,
20
- )
21
- }
22
-
23
- const unescapeHtml = (html: string) =>
24
- html
25
- .replace(/&quot;/g, '"')
26
- .replace(/&#39;/g, '\'')
27
- .replace(/&#x3A;/g, ':')
28
- .replace(/&lt;/g, '<')
29
- .replace(/&gt;/g, '>')
30
-
31
- const removeMarkdownTokens = (str: string) =>
32
- str
33
- .replace(/(\[(.[^\]]+)\]\((.[^)]+)\))/g, '$2') // []()
34
- .replace(/(`|\*{1,3}|_)(.*?[^\\])\1/g, '$2') // `{t}` | *{t}* | **{t}** | ***{t}*** | _{t}_
35
- .replace(/(\\)(\*|_|`|\!|<|\$)/g, '$2') // remove escape char '\'
36
-
37
- const remvoeCustomAnchor = (str: string) =>
38
- str.replace(/\{#([a-z0-9\-_]+?)\}\s*$/, '') // {#custom-header}
39
-
40
- const trim = (str: string) => str.trim()
41
-
42
- // This method remove the raw HTML but reserve the HTML wrapped by `<code>`.
43
- // e.g.
44
- // Input: "<a> b", Output: "b"
45
- // Input: "`<a>` b", Output: "`<a>` b"
46
- export const removeNonCodeWrappedHTML = (str: string) => {
47
- return String(str).replace(/(^|[^><`\\])<.*>([^><`]|$)/g, '$1$2')
48
- }
49
-
50
- const compose = (...processors: ((str: string) => string)[]) => {
51
- if (processors.length === 0)
52
- return (input: string) => input
53
- if (processors.length === 1)
54
- return processors[0]
55
- return processors.reduce((prev, next) => {
56
- return str => next(prev(str))
57
- })
58
- }
59
-
60
- // Unescape html, parse emojis and remove some md tokens.
61
- export const parseHeader = compose(
62
- unescapeHtml,
63
- parseEmojis,
64
- remvoeCustomAnchor,
65
- removeMarkdownTokens,
66
- trim,
67
- )
68
-
69
- // Also clean the html that isn't wrapped by code.
70
- // Because we want to support using VUE components in headers.
71
- // e.g. https://vuepress.vuejs.org/guide/using-vue.html#badge
72
- export const deeplyParseHeader = compose(removeNonCodeWrappedHTML, parseHeader)
@@ -1,275 +0,0 @@
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 pageComponent = 'ValaxyMain'
186
-
187
- function generateSlots() {
188
- const slots = [
189
- 'main-header',
190
- 'main-header-after',
191
- 'main-nav',
192
- 'main-content',
193
- 'main-content-after',
194
- 'footer',
195
- 'aside',
196
- 'aside-custom',
197
- ]
198
- const slotsText = slots.map(s => `<template #${s}><slot name="${s}" /></template>`).join('')
199
- return slotsText
200
- }
201
- const vueSrc
202
- = `${genPageDataCode(data.hoistedTags || [], pageData).join('\n')
203
- }\n<template><${pageComponent} :frontmatter="frontmatter" :data="data">
204
- <template #main-content-md>${html}</template>
205
- ${generateSlots()}
206
- <slot />
207
- </${pageComponent}></template>`
208
-
209
- debug(`[render] ${file} in ${Date.now() - start}ms.`)
210
-
211
- const result = {
212
- vueSrc,
213
- pageData,
214
- deadLinks,
215
- includes,
216
- }
217
- cache.set(src, result)
218
- return result
219
- }
220
- }
221
-
222
- const scriptRE = /<\/script>/
223
- const scriptLangTsRE = /<\s*script[^>]*\blang=['"]ts['"][^>]*/
224
- const scriptSetupRE = /<\s*script[^>]*\bsetup\b[^>]*/
225
- const scriptClientRE = /<\s*script[^>]*\bclient\b[^>]*/
226
- const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/
227
- const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/
228
-
229
- function genPageDataCode(tags: string[], data: PageData) {
230
- const code = ''
231
-
232
- const existingScriptIndex = tags.findIndex((tag) => {
233
- return (
234
- scriptRE.test(tag)
235
- && !scriptSetupRE.test(tag)
236
- && !scriptClientRE.test(tag)
237
- )
238
- })
239
-
240
- const isUsingTS = tags.findIndex(tag => scriptLangTsRE.test(tag)) > -1
241
-
242
- const exportScript = `
243
- export default {
244
- name:'${data.relativePath}',
245
- data() {
246
- return {
247
- frontmatter:${transformObject(data.frontmatter)},
248
- data: ${transformObject(data)}
249
- }
250
- }
251
- }`
252
-
253
- if (existingScriptIndex > -1) {
254
- const tagSrc = tags[existingScriptIndex]
255
- // user has <script> tag inside markdown
256
- // if it doesn't have export default it will error out on build
257
- const hasDefaultExport
258
- = defaultExportRE.test(tagSrc) || namedDefaultExportRE.test(tagSrc)
259
- tags[existingScriptIndex] = tagSrc.replace(
260
- scriptRE,
261
- `${code
262
- + (hasDefaultExport
263
- ? ''
264
- : `\n${exportScript}`)
265
- }</script>`,
266
- )
267
- }
268
- else {
269
- tags.unshift(
270
- `<script ${isUsingTS ? 'lang="ts"' : ''}>${code}\n${exportScript}</script>`,
271
- )
272
- }
273
-
274
- return tags
275
- }
@@ -1,24 +0,0 @@
1
- // ref vitepress
2
- import { remove as removeDiacritics } from 'diacritics'
3
- // eslint-disable-next-line no-control-regex
4
- const rControl = /[\u0000-\u001F]/g
5
- // add '…'
6
- const rSpecial = /[\s~`!@#$%^&*()\-_+=[\]{}|\\;:"'<>,.…?/]+/g
7
-
8
- export const slugify = (str: string): string => {
9
- return (
10
- removeDiacritics(str)
11
- // Remove control characters
12
- .replace(rControl, '')
13
- // Replace special characters
14
- .replace(rSpecial, '-')
15
- // Remove continuous separators
16
- .replace(/\-{2,}/g, '-')
17
- // Remove prefixing and trailing separators
18
- .replace(/^\-+|\-+$/g, '')
19
- // ensure it doesn't start with a number (#121)
20
- .replace(/^(\d)/, '_$1')
21
- // lowercase
22
- .toLowerCase()
23
- )
24
- }
package/node/options.ts DELETED
@@ -1,108 +0,0 @@
1
- import { dirname, resolve } from 'path'
2
- import _debug from 'debug'
3
- import fg from 'fast-glob'
4
- import type { ValaxyConfig } from '../types'
5
- import { resolveConfig } from './config'
6
- import { resolveImportPath } from './utils'
7
-
8
- const debug = _debug('valaxy:options')
9
-
10
- // for cli entry
11
- export interface ValaxyEntryOptions {
12
- /**
13
- * theme name
14
- */
15
- theme?: string
16
- userRoot?: string
17
- }
18
-
19
- export interface ResolvedValaxyOptions {
20
- mode: 'dev' | 'build'
21
- /**
22
- * Client root path
23
- * @default 'valaxy/src/client'
24
- */
25
- clientRoot: string
26
- /**
27
- * User root path
28
- * @default process.cwd()
29
- */
30
- userRoot: string
31
- /**
32
- * Theme root path
33
- */
34
- themeRoot: string
35
- /**
36
- * Theme name
37
- */
38
- theme: string
39
- /**
40
- * Valaxy Config
41
- */
42
- config: ValaxyConfig
43
- /**
44
- * config file path
45
- */
46
- configFile: string
47
- pages: string[]
48
- }
49
-
50
- export interface ValaxyServerOptions {
51
- onConfigReload?: (newConfig: ValaxyConfig, config: ValaxyConfig) => void
52
- }
53
-
54
- export function isPath(name: string) {
55
- return name.startsWith('/') || /^\.\.?[\/\\]/.test(name)
56
- }
57
-
58
- /**
59
- * get theme roots
60
- * @param name
61
- * @param entry
62
- * @returns
63
- */
64
- export function getThemeRoot(name: string, entry: string) {
65
- if (!name)
66
- return ''
67
-
68
- if (isPath(name))
69
- return resolve(dirname(entry), name)
70
- else
71
- return dirname(resolveImportPath(`valaxy-theme-${name}/package.json`) || '')
72
- }
73
-
74
- // for cli options
75
- export async function resolveOptions(options: ValaxyEntryOptions, mode: ResolvedValaxyOptions['mode'] = 'dev') {
76
- const clientRoot = resolve(dirname(resolveImportPath('valaxy/package.json', true)), 'client')
77
- const userRoot = resolve(options.userRoot || process.cwd())
78
-
79
- const { config: valaxyConfig, configFile, theme } = await resolveConfig(options)
80
- const themeRoot = getThemeRoot(theme, userRoot)
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
-
95
- const valaxyOptions: ResolvedValaxyOptions = {
96
- mode,
97
- clientRoot,
98
- userRoot,
99
- themeRoot,
100
- theme,
101
- config: valaxyConfig,
102
- configFile: configFile || '',
103
- pages,
104
- }
105
- debug(valaxyOptions)
106
-
107
- return valaxyOptions
108
- }