1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
import * as fs from "fs-extra"
import * as pathlib from "path"
import fetch from "node-fetch-commonjs"
import { matchAll, replaceAll } from "./generate"
const CONFIG = {
destination: pathlib.resolve(process.env.DESTINATION || "./examples/imports"),
URLs: process.argv.slice(2),
}
const IMPORT_FROM_RE = /from\s*"([^"]+)"/g
const IMPORT_EXPRESSION_RE = /import\s*\("([^"]+)"\)/g
async function main() {
const { destination } = CONFIG
const queue = Array.from(CONFIG.URLs)
const queued = new Set(queue)
function enqueue(url: string, baseUrl: string) {
const absoluteUrl = new URL(url, baseUrl).toString()
if (!queued.has(absoluteUrl)) {
console.log("enqueue", absoluteUrl)
queue.push(absoluteUrl)
queued.add(absoluteUrl)
}
}
function nameFile(args: { target: string; baseUrl: string }) {
const { target, baseUrl } = args
const url = new URL(target, baseUrl)
return pathlib.join(destination, url.hostname, url.pathname)
}
function renameImport(args: { target: string; baseUrl: string; fileName: string }) {
const targetFile = nameFile(args)
return pathlib.relative(pathlib.dirname(args.fileName), targetFile)
}
async function process(url: string) {
const log = (...args: any[]) => console.log(`${url}`, ...args)
log("download")
const filename = nameFile({ target: url, baseUrl: url })
const text = await (await fetch(url)).text()
const importFrom = matchAll(IMPORT_FROM_RE, text).map((match) => match[0])
const importExpression = matchAll(IMPORT_EXPRESSION_RE, text).map((match) => match[0])
log("parsed", { filename, importFrom, importExpression })
let replaced = replaceAll(IMPORT_FROM_RE, text, (match) => {
const importTarget = match[1]
enqueue(importTarget, url)
const renamed = renameImport({
target: importTarget,
baseUrl: url,
fileName: filename,
})
log("replaced", importTarget, "->", renamed)
return `from "${renamed}"`
})
replaced = replaceAll(IMPORT_EXPRESSION_RE, replaced, (match) => {
const importTarget = match[1]
enqueue(importTarget, url)
const renamed = renameImport({
target: importTarget,
baseUrl: url,
fileName: filename,
})
log("replaced", importTarget, "->", renamed)
return `import("${renamed}")`
})
await fs.mkdirp(pathlib.dirname(filename))
await fs.writeFile(filename, replaced)
}
while (queue.length > 0) {
const url = queue.shift()!
await process(url)
}
}
main()
|