Spaces:
Sleeping
Sleeping
| import fs from 'fs'; | |
| import path from 'path'; | |
| import {promisify} from 'util'; | |
| import fetch from 'cross-fetch'; | |
| import {name} from '../../../package.json'; | |
| import defaultIcon from '../images/default-icon.png'; | |
| import Image from './image'; | |
| const readFile = promisify(fs.readFile); | |
| const writeFile = promisify(fs.writeFile); | |
| const mkdir = promisify(fs.mkdir); | |
| const safeJoin = (root, file) => { | |
| root = path.join(root, '/'); | |
| const joined = path.join(root, file); | |
| if (joined.startsWith(root)) { | |
| return joined; | |
| } | |
| return null; | |
| }; | |
| const cacheDirectory = path.join(__dirname, '..', '.packager-cache'); | |
| const getCachePath = async (asset) => { | |
| if (!asset.sha256) return null; | |
| const path = safeJoin(cacheDirectory, asset.sha256); | |
| if (path) { | |
| await mkdir(cacheDirectory, { | |
| recursive: true | |
| }); | |
| return path; | |
| } | |
| return null; | |
| }; | |
| const nodeBufferToArrayBuffer = (buffer) => buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); | |
| const arrayBufferToNodeBuffer = (buffer) => Buffer.from(buffer); | |
| class NodeAdapter { | |
| async getCachedAsset (asset) { | |
| const urls = asset.src; | |
| const src = Array.isArray(urls) ? urls[0] : urls; | |
| if (src.startsWith('scaffolding/')) { | |
| const file = safeJoin(__dirname, src); | |
| if (file) { | |
| return readFile(file, 'utf-8'); | |
| } | |
| } | |
| if (src.startsWith('https:')) { | |
| const cachePath = await getCachePath(asset); | |
| if (cachePath) { | |
| try { | |
| return nodeBufferToArrayBuffer(await readFile(cachePath)); | |
| } catch (e) { | |
| // ignore | |
| } | |
| } | |
| console.log(`[${name}]: downloading large asset ${src}; this may take a while`); | |
| const res = await fetch(src); | |
| if (!res.ok) { | |
| throw new Error(`Unexpected status code: ${res.status}`); | |
| } | |
| const arrayBuffer = await res.arrayBuffer(); | |
| if (cachePath) { | |
| await writeFile(cachePath, arrayBufferToNodeBuffer(arrayBuffer)); | |
| } | |
| return arrayBuffer; | |
| } | |
| } | |
| async cacheAsset (asset, result) { | |
| // all of our caching logic lives in getCachedAsset | |
| } | |
| async getAppIcon (file) { | |
| if (!file) { | |
| // Use the default icon when no icon is given | |
| const buffer = await readFile(path.join(__dirname, defaultIcon)); | |
| return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength); | |
| } | |
| if (file instanceof Image) { | |
| if (file.mimeType === 'image/png') { | |
| return file.readAsBuffer(); | |
| } | |
| throw new Error('icon must be of type image/png but found ' + file.mimeType + ' instead.'); | |
| } | |
| throw new Error('file must be an instance of Packager.Image or null but found ' + file + ' instead.'); | |
| } | |
| readAsURL (file) { | |
| if (!(file instanceof Image)) { | |
| throw new Error('file must be an instance of Packager.Image but found ' + file + ' instead.'); | |
| } | |
| return file.readAsURL(); | |
| } | |
| fetchExtensionScript (url) { | |
| return fetch(url) | |
| .then(res => { | |
| if (res.ok) { | |
| return res.text(); | |
| } | |
| throw new Error(`Unexpected status code: ${res.status}`); | |
| }); | |
| } | |
| } | |
| export default NodeAdapter; | |