Dominik Milacher 0dc24c4db7
Some checks failed
Build and deploy updated apps / Build & deploy (push) Failing after 50s
Extend ux layer and overhaul panoramablick-saalbach.at
2025-11-21 21:17:52 +01:00

106 lines
3.4 KiB
TypeScript

import { addVitePlugin, defineNuxtModule, getLayerDirectories } from '@nuxt/kit'
import { getLayerFiles, getLayerContent } from '../app/utils/content-files'
import {
getRoutes,
getExpandedRoutes,
getRouteShortcuts,
getConfig,
} from '../app/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.app, '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.app)
.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.app)) {
if (id.startsWith(root)) {
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}
`
},
}))
},
})