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 { 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)) }