Skip to content

Commit 226e5e6

Browse files
committed
fix: guard mdream dev middleware
1 parent 5f5a782 commit 226e5e6

File tree

3 files changed

+107
-19
lines changed

3 files changed

+107
-19
lines changed

packages/nimiq-css/src/unocss/index.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,8 +273,7 @@ export const presetNimiq = definePreset((options: NimiqPresetOptions = {}) => {
273273
layer: `${prefix}preflight`,
274274
})
275275

276-
// @ts-expect-error This is fine
277-
presets.push(presetLightDark({ colors, prefix, layer: `${prefix}colors` }))
276+
presets.push(presetLightDark({ colors, prefix, layer: `${prefix}colors` }) as Preset)
278277

279278
const colorsWithGradientsRe = 'neutral|blue|green|orange|red|gold'
280279
shortcuts.push(

packages/nimiq-vitepress-theme/src/vite/index.ts

Lines changed: 105 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import type { Plugin } from 'vite'
1+
import type { IncomingMessage } from 'node:http'
2+
import type { Plugin, PreviewServerHook, ServerHook } from 'vite'
23
import { viteHtmlToMarkdownPlugin } from '@mdream/vite'
34
import { GitChangelog } from '@nolebase/vitepress-plugin-git-changelog/vite'
45
import { groupIconVitePlugin } from '../code-groups/vite'
@@ -79,20 +80,109 @@ export function NimiqVitepressVitePlugin({
7980
]
8081

8182
// Add mdream plugin to generate markdown copies of each page
82-
plugins.push(viteHtmlToMarkdownPlugin({
83-
outputDir: 'markdown',
84-
cacheEnabled: true,
85-
exclude: [
86-
'**/node_modules/**',
87-
'**/@vite/**',
88-
'**/@id/**',
89-
'**/@fs/**',
90-
'**/*.js',
91-
'**/*.mjs',
92-
'**/*.ts',
93-
'**/*.tsx',
94-
],
95-
}))
83+
const markdownPlugin = guardMarkdownMiddleware(
84+
viteHtmlToMarkdownPlugin({
85+
outputDir: 'markdown',
86+
cacheEnabled: true,
87+
exclude: [
88+
'**/node_modules/**',
89+
'**/@vite/**',
90+
'**/@id/**',
91+
'**/@fs/**',
92+
'**/*.js',
93+
'**/*.mjs',
94+
'**/*.ts',
95+
'**/*.tsx',
96+
],
97+
}),
98+
)
99+
100+
plugins.push(markdownPlugin)
96101

97102
return plugins
98103
}
104+
105+
function guardMarkdownMiddleware(plugin: Plugin): Plugin {
106+
const shouldServeMarkdown = (req: IncomingMessage | undefined) => {
107+
if (!req?.url) {
108+
return false
109+
}
110+
111+
if (req.url.endsWith('.md')) {
112+
return true
113+
}
114+
115+
const accept = req.headers.accept ?? ''
116+
return accept.includes('text/markdown')
117+
}
118+
interface HookObject<T> {
119+
handler: T
120+
order?: 'pre' | 'post' | null
121+
}
122+
123+
const isHookObject = <T>(value: unknown): value is HookObject<T> => {
124+
return Boolean(value) && typeof value === 'object' && 'handler' in (value as Record<string, unknown>)
125+
}
126+
127+
const wrapHook = <T extends (server: any) => any>(hook?: T | HookObject<T>) => {
128+
if (!hook) {
129+
return hook
130+
}
131+
132+
const original = typeof hook === 'function' ? hook : hook.handler
133+
134+
const wrapped: T = ((server: any) => {
135+
const middlewares = (server as any)?.middlewares
136+
if (!middlewares?.use) {
137+
return original(server)
138+
}
139+
140+
const originalUse = middlewares.use.bind(middlewares)
141+
142+
middlewares.use = (fn: any) => originalUse((req: IncomingMessage, res: any, next: any) => {
143+
if (shouldServeMarkdown(req)) {
144+
return fn(req, res, next)
145+
}
146+
return next()
147+
})
148+
149+
const result = original(server)
150+
151+
const restore = () => {
152+
middlewares.use = originalUse
153+
}
154+
155+
if (typeof result === 'function') {
156+
return (...args: any[]) => {
157+
try {
158+
return result(...args)
159+
}
160+
finally {
161+
restore()
162+
}
163+
}
164+
}
165+
166+
if (result && typeof result.then === 'function') {
167+
return (result.finally(restore))
168+
}
169+
170+
restore()
171+
return result
172+
}) as T
173+
174+
if (!isHookObject<T>(hook)) {
175+
return wrapped
176+
}
177+
178+
return {
179+
...hook,
180+
handler: wrapped,
181+
}
182+
}
183+
184+
plugin.configureServer = wrapHook(plugin.configureServer as ServerHook | HookObject<ServerHook>) as typeof plugin.configureServer
185+
plugin.configurePreviewServer = wrapHook(plugin.configurePreviewServer as PreviewServerHook | HookObject<PreviewServerHook>) as typeof plugin.configurePreviewServer
186+
187+
return plugin
188+
}

packages/nimiq-vitepress-theme/src/vite/inline-actions-plugin.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import type { PluginSimple } from 'markdown-it'
21
import type { MarkdownEnv, MarkdownRenderer } from 'vitepress'
32

4-
export default function inlineActionsPlugin(md: MarkdownRenderer): PluginSimple {
3+
export default function inlineActionsPlugin(md: MarkdownRenderer): void {
54
md.core.ruler.after('block', 'inline-actions', (state) => {
65
const env = state.env as MarkdownEnv
76
const frontmatter = env.frontmatter || {}

0 commit comments

Comments
 (0)