handling files when stages and dirty at once
This commit is contained in:
@@ -202,6 +202,32 @@ export async function readProjectFile(root: string, rel: string): Promise<string
|
||||
return buf.toString('utf8')
|
||||
}
|
||||
|
||||
const IMAGE_MIME: Record<string, string> = {
|
||||
png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg', jfif: 'image/jpeg',
|
||||
gif: 'image/gif', webp: 'image/webp', svg: 'image/svg+xml', bmp: 'image/bmp',
|
||||
ico: 'image/x-icon', avif: 'image/avif', apng: 'image/apng',
|
||||
}
|
||||
const MAX_IMAGE_BYTES = 25_000_000
|
||||
|
||||
/** Read an image file as a `data:` URL for the viewer's <img> — the renderer
|
||||
* can't touch the filesystem, and a data URL sidesteps file:// path/escaping
|
||||
* concerns entirely. Returns '' for a non-image extension, a path escaping the
|
||||
* root, or an oversized/unreadable file. */
|
||||
export async function readImageDataUrl(root: string, rel: string): Promise<string> {
|
||||
const ext = rel.split('.').pop()?.toLowerCase() ?? ''
|
||||
const mime = IMAGE_MIME[ext]
|
||||
if (!mime) return ''
|
||||
const target = join(root, rel)
|
||||
if (relative(root, target).startsWith('..')) return ''
|
||||
try {
|
||||
const buf = await readFile(target)
|
||||
if (buf.length > MAX_IMAGE_BYTES) return ''
|
||||
return `data:${mime};base64,${buf.toString('base64')}`
|
||||
} catch {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
/** Write a text file (relative path). Used by the editable buffer's save. */
|
||||
export async function writeProjectFile(root: string, rel: string, content: string): Promise<void> {
|
||||
await writeFile(join(root, rel), content, 'utf8')
|
||||
|
||||
Reference in New Issue
Block a user