Skip to content

Instantly share code, notes, and snippets.

@teidesu
Last active September 23, 2022 12:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save teidesu/a189d2325a31ccf138617c5c5ef3a937 to your computer and use it in GitHub Desktop.
Save teidesu/a189d2325a31ccf138617c5c5ef3a937 to your computer and use it in GitHub Desktop.
Simple tool for extracting source code from sourcemaps.
/**
* Simple tool for extracting source code from sourcemaps.
* Requires axios for automatic fetching.
* Puts extracted files in ./<sourcemap_file_name>_extracted/
* Puts files from `../` (for example, webpack puts there node_modules) dir to _extracted/__/,
* and files from `./` to _extracted/
*
* (c) teidesu 2019. Licensed under GPLv3.
*/
const fs = require('fs')
const { promisify } = require('util')
const readline = require('readline')
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
})
const path = require('path')
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const mkdir = (path, options) => new Promise((resolve, reject) => {
fs.mkdir(path, options, (err) => {
if (err && err.code !== 'EEXIST') {
reject(err)
} else {
resolve()
}
})
})
const mkdirs = async (p) => {
const sep = path.sep
const stack = []
for (let it of p.split(sep)) {
stack.push(it)
await mkdir(stack.join(sep))
}
}
rl.question('URL or path to file > ', async (it) => {
let content
if (it.match(/^https?:\/\//i)) {
console.log('[+] Fetching sourcemap')
const axios = require('axios')
const { data } = await axios.get(it)
content = data
} else {
content = await readFile(it)
}
it = it.split('/').pop().split('?')[0] + '_extracted'
try {
if (typeof content !== 'object') {
content = JSON.parse(content)
}
if (!content.sources || !content.sourcesContent || content.sources.length !== content.sourcesContent.length) {
throw 1
}
} catch (e) {
console.error('[!] Sourcemap is either invalid or does not contain source code')
console.log(e)
process.exit(1)
return
}
for (let i = 0; i < content.sources.length; i++) {
let fname = content.sources[i].replace(/\.\./g, '__').replace(/[:*?'"<>|&]/gi, '')
process.stdout.write('[~] ' + fname + '\r')
await mkdirs(path.join(it, path.dirname(fname)))
await writeFile(path.join(it, fname), content.sourcesContent[i])
}
console.log('\n[v] Finished!')
process.exit(0)
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment