Some checks failed
Build and deploy updated apps / Build & deploy (push) Failing after 1m7s
95 lines
3.3 KiB
TypeScript
95 lines
3.3 KiB
TypeScript
import {addVitePlugin, defineNuxtModule, getLayerDirectories} from '@nuxt/kit'
|
|
import {getLayerFiles, getLayerContent} from '../utils/content-files'
|
|
import {getRoutes, getExpandedRoutes, getRouteShortcuts, getConfig} from '../utils/content-routes'
|
|
import {join, relative, dirname, basename, extname} from 'path'
|
|
import {existsSync} from 'fs'
|
|
|
|
/* Rationale:
|
|
1) Every project file containing useInjectedContent() is transformed and virtual modules are imported
|
|
2) Upon request the virtual modules are compiled from ts/yaml files
|
|
3) If any of the files that back a virtual module change the module is invalidated
|
|
*/
|
|
|
|
export default defineNuxtModule({
|
|
setup() {
|
|
addVitePlugin(() => ({
|
|
name: 'content-import-injector',
|
|
resolveId(id) {
|
|
if (id.startsWith('virtual:content/')) {
|
|
return '\0' + id // convention, hide from further processing
|
|
}
|
|
},
|
|
async load(id) {
|
|
if (id.startsWith('\0' + 'virtual:content/')) {
|
|
const slug = id.slice(17)
|
|
|
|
if (slug === 'shortcuts') {
|
|
const routes = await getRoutes()
|
|
const shortcuts = getRouteShortcuts(routes)
|
|
|
|
return `export default ${JSON.stringify(shortcuts)}`
|
|
} else if (slug === 'content.config') {
|
|
const file = getLayerDirectories().map(d => join(d.root, 'content.config.ts')).find(f => existsSync(f))
|
|
|
|
if (file) {
|
|
this.addWatchFile(file)
|
|
return `export {default} from '${file}'`
|
|
}
|
|
} else {
|
|
const files = getLayerFiles(slug)
|
|
const content = await getLayerContent(files)
|
|
|
|
files.filter(f => existsSync(f)).forEach(f => this.addWatchFile(f))
|
|
|
|
return `export const content = ${JSON.stringify(content)}`
|
|
}
|
|
}
|
|
},
|
|
hotUpdate({file, server}) {
|
|
const root = getLayerDirectories().map(d => d.root).find(r => file.startsWith(r))
|
|
|
|
if (root !== undefined) {
|
|
const path = relative(root, file)
|
|
const slug = join(dirname(path), basename(path, extname(path)))
|
|
|
|
const module = server.moduleGraph.getModuleById('\0' + `virtual:content/${slug}`)
|
|
|
|
if (module) {
|
|
server.moduleGraph.invalidateModule(module)
|
|
this.environment.hot.send({ type: 'full-reload' })
|
|
}
|
|
}
|
|
|
|
return []
|
|
},
|
|
transform(code, id) {
|
|
let slug: string | undefined = undefined
|
|
|
|
for (const root of getLayerDirectories().map(d => d.root)) {
|
|
if (id.startsWith(root) && !id.includes('/node_modules/')) {
|
|
const path = relative(root, id).split('?')[0]!
|
|
slug = join(dirname(path), basename(path, extname(path)))
|
|
break
|
|
}
|
|
}
|
|
|
|
if (slug === undefined) {
|
|
return null
|
|
}
|
|
|
|
const expression = /\buseContentInjected\s*\(\s*\)/g
|
|
if (!expression.test(code)) return null
|
|
|
|
const transformed = code.replace(expression,
|
|
`useContentInjected('${slug}', a23631da455de90c5a945da16897d0bd, d61397115e513f2bb1d8e872b7e7788f)`)
|
|
|
|
return `
|
|
import {content as a23631da455de90c5a945da16897d0bd} from 'virtual:content/content.global';
|
|
import {content as d61397115e513f2bb1d8e872b7e7788f} from 'virtual:content/${slug}';
|
|
${transformed}
|
|
`
|
|
}
|
|
}))
|
|
}
|
|
})
|