import { mkdir, writeFile } from 'node:fs/promises'; import path from 'node:path'; import { createRequire } from 'node:module'; import { fileURLToPath } from 'node:url'; const require = createRequire(import.meta.url); const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); const OUTPUT_DIR = path.resolve(__dirname, '../public/vendor'); interface LibraryDefinition { packageName: string; globalName: string; outputFile: string; } interface WriteShimOptions { outputDir: string; silent: boolean; } type ShimSource = Pick; const libraries: LibraryDefinition[] = [ { packageName: 'vue', globalName: 'Vue', outputFile: 'vue.mjs' }, { packageName: 'vue-router', globalName: 'VueRouter', outputFile: 'vue-router.mjs' }, { packageName: 'pinia', globalName: 'Pinia', outputFile: 'pinia.mjs' }, ]; const formatLines = (globalName: string, exports: readonly string[]): string => { const lines: string[] = []; lines.push(`const ${globalName} = window.${globalName};`); lines.push(`if (!${globalName}) {`); lines.push(` throw new Error('${globalName} runtime is not available on window.');`); lines.push('}'); lines.push(`export default ${globalName};`); for (const name of exports) { lines.push(`export const ${name} = ${globalName}.${name};`); } lines.push(''); return lines.join('\n'); }; const generateShim = ({ packageName, globalName }: ShimSource): string => { const mod = require(packageName) as Record; const exportNames = Object.keys(mod) .filter((key) => key !== 'default') .sort(); return formatLines(globalName, exportNames); }; const writeShim = async ( { packageName, globalName, outputFile }: LibraryDefinition, { outputDir, silent }: WriteShimOptions, ): Promise => { const content = generateShim({ packageName, globalName }); await writeFile(path.join(outputDir, outputFile), content, 'utf8'); if (!silent) { console.log(`Generated ${outputFile}`); } }; export interface GenerateVendorShimsOptions { outputDir?: string; silent?: boolean; } export type GenerateVendorShims = (options?: GenerateVendorShimsOptions) => Promise; export const generateVendorShims: GenerateVendorShims = async (options = {}) => { const { outputDir = OUTPUT_DIR, silent = false } = options; await mkdir(outputDir, { recursive: true }); await Promise.all(libraries.map((library) => writeShim(library, { outputDir, silent }))); if (!silent) { console.log(`[generate-vendor-shims] Vendor shims updated in ${outputDir}`); } }; const isCliExecution = Boolean(process.argv[1] && path.resolve(process.argv[1]) === __filename); if (isCliExecution) { void generateVendorShims().catch((error) => { console.error('[generate-vendor-shims] Failed to generate shims', error); process.exitCode = 1; }); }