import { readFileSync, writeFileSync, readdirSync } from 'node:fs' import { fileURLToPath } from 'node:url' import { dirname, join, relative } from 'node:path' const __filename = fileURLToPath(import.meta.url) const __dirname = dirname(__filename) const buildDir = join(__dirname, '..', 'build') const files = (await readdirSync(buildDir, { recursive: true })) .filter(file => file.endsWith('.js')) .map(file => join(buildDir, file)) for (const file of files) { reflectType(file, { debug: true }) } function reflectType(srcFile, options = { debug: false }) { log(`Reflecting file "${relative(__dirname, srcFile)}"`) const defFile = srcFile.replace(/.js$/, '.d.ts') const src = String(readFileSync(srcFile)) const defs = String(readFileSync(defFile)) if (src.includes('.reflectedType5')) { log(' Source file already contains reflected types and will be ignored') return } const matches = Array.from(src.matchAll(/[^\n](export +)?const +([\w$]+) += +implementations\b/g)) if (matches.length === 0) { log(` No implementations found`) return } for (const match of matches) { const name = match[2] log(` Found an implementations definition: "${name}"`) const def = new RegExp(`export declare const ${name}: {(?:(?!\n}).)+\n}`, 's').exec(defs) if (def) { log(` Injected type definitions for "${name}"`) const srcReflected = `${src}\n${name}.reflectedType5 = \`${def}\`\n` writeFileSync(srcFile, srcReflected) } else { log(` No type definitions found for "${name}"`) } } function log(...args) { if (options.debug) { console.log(...args) } } }