Repository navigation
Expand file tree
/
Copy pathdownloadEcmaScriptModules.ts
More file actions
80 lines (70 loc) · 2.5 KB
/
Copy pathdownloadEcmaScriptModules.ts
File metadata and controls
80 lines (70 loc) · 2.5 KB
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()