/** * Simple tool for extracting source code from sourcemaps. * Puts extracted files in ./_extracted/ * Puts files from `../` (for example, webpack puts there node_modules) dir to _extracted/__/, * and files from `./` to _extracted/ * * (c) tggdesu 2019. Licensed under GPLv3. */ import * as fs from 'node:fs/promises' import * as path from 'node:path' import { question } from 'zx' interface SourceMap { sources: string[] sourcesContent: string[] } const input = await question('URL or path to file > ') const outDirDefault = `./assets/${input.split('/').pop()?.split('?')[0]}_extracted` const outDir = await question(`Output directory [${outDirDefault}]> `) let content: SourceMap if (/^https?:\/\//i.test(input)) { console.log('[+] Fetching sourcemap') const response = await fetch(input) content = await response.json() as SourceMap } else { const data = await fs.readFile(input, 'utf-8') content = JSON.parse(data) as SourceMap } if (!content.sources || !content.sourcesContent || content.sources.length !== content.sourcesContent.length) { console.error('[!] Sourcemap is either invalid or does not contain source code') process.exit(1) } for (let i = 0; i < content.sources.length; i++) { const fname = content.sources[i] .replace(/[\\/]\.[\\/]/g, '/_/') .replace(/[\\/]\.\.[\\/]/g, '/__/') .replace(/[:*?'"<>|&]/g, '') process.stdout.write(`[~] ${fname}\r`) await fs.mkdir(path.join(outDir, path.dirname(fname)), { recursive: true }) await fs.writeFile(path.join(outDir, fname), content.sourcesContent[i]) } console.log('\n[v] Finished!')