webapps/packages/layers/content/app/utils/content-files.ts
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

91 lines
2.7 KiB
TypeScript

import { getLayerDirectories } from '@nuxt/kit'
import { existsSync, lstatSync } from 'fs'
import { readFile } from 'fs/promises'
import { join } from 'path'
import { parse } from 'yaml'
import { fromInputJson, merge, type CanonicalValue } from './content-canonical'
import { type Plugin, build } from 'esbuild'
export function getLayerFiles(slug: string): string[] {
return getLayerDirectories().flatMap((d) =>
['mts', 'yaml'].map((e) => join(d.app, `${slug}.${e}`))
)
}
export async function getLayerContent(files: string[]): Promise<CanonicalValue | undefined> {
const ts = await mergeTsFiles(
files.filter((f) => f.endsWith('.mts') && existsSync(f) && lstatSync(f).isFile())
)
const yaml = await mergeYamlFiles(
files.filter((f) => f.endsWith('.yaml') && existsSync(f) && lstatSync(f).isFile())
)
const merged = merge([ts, yaml].filter((c) => c !== undefined))
return merged?.dropTags(['de', 'en', 'summer', 'winter']) // TODO
}
async function mergeTsFiles(files: string[]): Promise<CanonicalValue | undefined> {
if (!files.length) return undefined
try {
const loader: Plugin = {
name: 'file-loader',
setup(build) {
build.onLoad({ filter: /\.mts$/ }, async (args) => {
let code = await readFile(args.path, 'utf-8')
const index = files.indexOf(args.path)
if (index < files.length - 1) {
code = `
export * from '${files[index + 1]}';
import * as parent from '${files[index + 1]}';
${code}
`
}
return { contents: code, loader: 'ts' }
})
},
}
const bundle = await build({
entryPoints: [files[0]!],
bundle: true,
format: 'esm',
platform: 'node',
target: 'node22',
write: false,
sourcemap: 'inline',
plugins: [loader],
})
const url =
'data:text/javascript;base64,' + Buffer.from(bundle.outputFiles[0]!.text).toString('base64')
const module = await import(url)
return fromInputJson([], module.default)
} catch (e) {
const message = e instanceof Error ? e.message : String(e)
console.error(`Unable to load merged ts: ${message}`)
return undefined
}
}
async function mergeYamlFiles(files: string[]): Promise<CanonicalValue | undefined> {
const objects = await Promise.all(
files.map(async (f) => {
try {
return fromInputJson([], parse(await readFile(f, 'utf-8')))
} catch (e) {
const message = e instanceof Error ? e.message : String(e)
console.error(`Unable to load content file ${f}: ${message}`)
return undefined
}
})
)
return merge(objects.filter((o) => !!o))
}