返回 slidev
monacoWrite.ts
根目录 / packages / slidev / node / vite / monacoWrite.ts
1 import type { ResolvedSlidevOptions } from '@slidev/types'
2 import type { Plugin } from 'vite'
3 import fs from 'node:fs/promises'
4 import path from 'pathe'
5
6 export const monacoWriterWhitelist = new Set<string>()
7
8 export function createMonacoWriterPlugin({ userRoot }: ResolvedSlidevOptions): Plugin {
9 return {
10 name: 'slidev:monaco-write',
11 apply: 'serve',
12
13 configureServer(server) {
14 server.ws.on('connection', (socket) => {
15 socket.on('message', async (data) => {
16 let json
17 try {
18 json = JSON.parse(data.toString())
19 }
20 catch {
21 return
22 }
23 if (json.type === 'custom' && json.event === 'slidev:monaco-write') {
24 const { file, content } = json.data
25 if (!monacoWriterWhitelist.has(file)) {
26 console.error(`[Slidev] Unauthorized file write: ${file}`)
27 return
28 }
29 const filepath = path.resolve(userRoot, file)
30 const rel = path.relative(userRoot, filepath)
31 if (rel.startsWith('..') || path.isAbsolute(rel)) {
32 console.error(`[slidev] Refusing monaco write outside project root: ${file}`)
33 return
34 }
35 // eslint-disable-next-line no-console
36 console.log('[Slidev] Writing file:', filepath)
37 await fs.writeFile(filepath, content, 'utf-8')
38 }
39 })
40 })
41 },
42 }
43 }
44
44 lines TYPESCRIPT