96 lines
2.7 KiB
JavaScript
96 lines
2.7 KiB
JavaScript
import { readFileSync, readdirSync, existsSync } from 'fs'
|
|
import { join, resolve, extname, basename } from 'path'
|
|
import matter from 'gray-matter'
|
|
import { marked } from 'marked'
|
|
import yaml from 'js-yaml'
|
|
|
|
const CONTENT_DIR = resolve(process.cwd(), 'content')
|
|
const VIRTUAL_MODULE_ID = 'virtual:content'
|
|
const RESOLVED_VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID
|
|
|
|
function readContentDir(subdir) {
|
|
const dir = join(CONTENT_DIR, subdir)
|
|
if (!existsSync(dir)) return []
|
|
|
|
return readdirSync(dir)
|
|
.filter(f => !f.startsWith('.'))
|
|
.map(filename => {
|
|
const filepath = join(dir, filename)
|
|
const ext = extname(filename)
|
|
const slug = basename(filename, ext)
|
|
|
|
if (ext === '.md') {
|
|
const raw = readFileSync(filepath, 'utf-8')
|
|
const { data, content } = matter(raw)
|
|
return {
|
|
...data,
|
|
slug,
|
|
body: marked(content),
|
|
_source: `${subdir}/${filename}`
|
|
}
|
|
}
|
|
|
|
if (ext === '.yaml' || ext === '.yml') {
|
|
const raw = readFileSync(filepath, 'utf-8')
|
|
const data = yaml.load(raw)
|
|
return { ...data, slug, _source: `${subdir}/${filename}` }
|
|
}
|
|
|
|
return null
|
|
})
|
|
.filter(Boolean)
|
|
}
|
|
|
|
function readMetaFile(filename) {
|
|
const filepath = join(CONTENT_DIR, 'meta', filename)
|
|
if (!existsSync(filepath)) return null
|
|
const raw = readFileSync(filepath, 'utf-8')
|
|
return yaml.load(raw)
|
|
}
|
|
|
|
function loadAllContent() {
|
|
return {
|
|
posts: readContentDir('posts'),
|
|
kniepunkt: readContentDir('kniepunkt'),
|
|
podcast: readContentDir('podcast'),
|
|
talks: readContentDir('talks'),
|
|
consulting: readContentDir('consulting'),
|
|
resources: readContentDir('resources'),
|
|
events: readContentDir('events'),
|
|
meta: {
|
|
profile: readMetaFile('profile.yaml'),
|
|
stats: readMetaFile('stats.yaml'),
|
|
testimonials: readMetaFile('testimonials.yaml'),
|
|
logos: readMetaFile('logos.yaml'),
|
|
services: readMetaFile('services.yaml'),
|
|
about: readMetaFile('about.yaml'),
|
|
speaking: readMetaFile('speaking.yaml'),
|
|
newsletter: readMetaFile('newsletter.yaml'),
|
|
}
|
|
}
|
|
}
|
|
|
|
export default function contentPlugin() {
|
|
return {
|
|
name: 'vite-plugin-content',
|
|
resolveId(id) {
|
|
if (id === VIRTUAL_MODULE_ID) return RESOLVED_VIRTUAL_MODULE_ID
|
|
},
|
|
load(id) {
|
|
if (id === RESOLVED_VIRTUAL_MODULE_ID) {
|
|
const content = loadAllContent()
|
|
return `export default ${JSON.stringify(content)}`
|
|
}
|
|
},
|
|
handleHotUpdate({ file, server }) {
|
|
if (file.includes('content')) {
|
|
const mod = server.moduleGraph.getModuleById(RESOLVED_VIRTUAL_MODULE_ID)
|
|
if (mod) {
|
|
server.moduleGraph.invalidateModule(mod)
|
|
return [mod]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|