/ download-extensions.js
download-extensions.js
 1  #!/usr/bin/env node
 2  
 3  import { fileURLToPath } from 'node:url'
 4  import path from 'node:path'
 5  import { readFile, mkdir, access } from 'node:fs/promises'
 6  import { createWriteStream } from 'node:fs'
 7  import { Readable } from 'stream'
 8  import { pipeline } from 'stream/promises'
 9  
10  const __dirname = fileURLToPath(new URL('./', import.meta.url))
11  
12  const EXTENSION_FOLDER = path.join(__dirname, 'app/extensions')
13  const EXTENSIONS_LIST_FILE = path.join(EXTENSION_FOLDER, 'builtins.json')
14  const EXTENSIONS_BUILTINS_FOLDER = path.join(EXTENSION_FOLDER, 'builtins/')
15  
16  console.log('Loading extension list')
17  
18  const extensionsJSON = await readFile(EXTENSIONS_LIST_FILE, 'utf8')
19  
20  try {
21    await access(EXTENSIONS_BUILTINS_FOLDER)
22  } catch {
23    console.log(`Creating destination folder:\n${EXTENSIONS_BUILTINS_FOLDER}`)
24    await mkdir(EXTENSIONS_BUILTINS_FOLDER)
25  }
26  
27  const extensions = JSON.parse(extensionsJSON)
28  
29  console.log('Downloading extensions')
30  
31  for (const [name, options] of Object.entries(extensions)) {
32    downloadExtension(name, options)
33  }
34  
35  async function downloadExtension (name, { version, url, subfolder }) {
36    const finalURL = url.replaceAll('{version}', version)
37    const destination = path.join(EXTENSIONS_BUILTINS_FOLDER, `${name}.zip`)
38  
39    console.log(`Downloading: ${name}`)
40    console.log(`URL: ${finalURL}`)
41    console.log(`Destination: ${destination}`)
42  
43    const response = await fetch(finalURL)
44  
45    if (!response.ok) {
46      throw new Error(`Could not download ${name} at ${version} from ${finalURL}\n${await response.text()}`)
47    }
48  
49    // Based on this Stack Overflow question: https://stackoverflow.com/questions/37614649/how-can-i-download-and-save-a-file-using-the-fetch-api-node-js
50    const fileSourceStream = Readable.fromWeb(response.body)
51    const fileDestinationStream = createWriteStream(destination)
52  
53    await pipeline(fileSourceStream, fileDestinationStream)
54    console.log(`Finished downloading ${name}`)
55  }