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.root, `${slug}.${e}`))) } export async function getLayerContent(files: string[]): Promise { 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 { 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 { 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)) }