| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 | 
							- const pickle = require('chromium-pickle-js')
 
- const path = require('path')
 
- const UINT64 = require('cuint').UINT64
 
- const fs = require('fs')
 
- /**
 
-  * Based of express-serve-asar (https://github.com/toyobayashi/express-serve-asar)
 
-  * by Fenglin Li (https://github.com/toyobayashi)
 
-  */
 
- const packages = {
 
-   'twemoji': path.join(WIKI.ROOTPATH, `assets-legacy/svg/twemoji.asar`)
 
- }
 
- module.exports = {
 
-   fdCache: {},
 
-   async serve (pkgName, req, res, next) {
 
-     const file = this.readFilesystemSync(packages[pkgName])
 
-     const { filesystem, fd } = file
 
-     const info = filesystem.getFile(req.path.substring(1))
 
-     if (info) {
 
-       res.set({
 
-         'Content-Type': 'image/svg+xml',
 
-         'Content-Length': info.size
 
-       })
 
-       fs.createReadStream('', {
 
-         fd,
 
-         autoClose: false,
 
-         start: 8 + filesystem.headerSize + parseInt(info.offset, 10),
 
-         end: 8 + filesystem.headerSize + parseInt(info.offset, 10) + info.size - 1
 
-       }).on('error', (err) => {
 
-         WIKI.logger.warn(err)
 
-         res.sendStatus(404)
 
-       }).pipe(res.status(200))
 
-     } else {
 
-       res.sendStatus(404)
 
-     }
 
-   },
 
-   async unload () {
 
-     const fds = Object.values(this.fdCache)
 
-     if (fds.length > 0) {
 
-       WIKI.logger.info('Closing ASAR file descriptors...')
 
-       const closeAsync = require('util').promisify(fs.close)
 
-       await Promise.all(fds.map(x => closeAsync(x.fd)))
 
-       this.fdCache = {}
 
-     }
 
-   },
 
-   readArchiveHeaderSync (fd) {
 
-     let size
 
-     let headerBuf
 
-     const sizeBuf = Buffer.alloc(8)
 
-     if (fs.readSync(fd, sizeBuf, 0, 8, null) !== 8) {
 
-       throw new Error('Unable to read header size')
 
-     }
 
-     const sizePickle = pickle.createFromBuffer(sizeBuf)
 
-     size = sizePickle.createIterator().readUInt32()
 
-     headerBuf = Buffer.alloc(size)
 
-     if (fs.readSync(fd, headerBuf, 0, size, null) !== size) {
 
-       throw new Error('Unable to read header')
 
-     }
 
-     const headerPickle = pickle.createFromBuffer(headerBuf)
 
-     const header = headerPickle.createIterator().readString()
 
-     return { header: JSON.parse(header), headerSize: size }
 
-   },
 
-   readFilesystemSync (archive) {
 
-     if (!this.fdCache[archive]) {
 
-       const fd = fs.openSync(archive, 'r')
 
-       const header = this.readArchiveHeaderSync(fd)
 
-       const filesystem = new Filesystem(archive)
 
-       filesystem.header = header.header
 
-       filesystem.headerSize = header.headerSize
 
-       this.fdCache[archive] = {
 
-         fd,
 
-         filesystem: filesystem
 
-       }
 
-     }
 
-     return this.fdCache[archive]
 
-   }
 
- }
 
- class Filesystem {
 
-   constructor (src) {
 
-     this.src = path.resolve(src)
 
-     this.header = { files: {} }
 
-     this.offset = UINT64(0)
 
-   }
 
-   searchNodeFromDirectory (p) {
 
-     let json = this.header
 
-     const dirs = p.split(path.sep)
 
-     for (const dir of dirs) {
 
-       if (dir !== '.') {
 
-         json = json.files[dir]
 
-       }
 
-     }
 
-     return json
 
-   }
 
-   getNode (p) {
 
-     const node = this.searchNodeFromDirectory(path.dirname(p))
 
-     const name = path.basename(p)
 
-     if (name) {
 
-       return node.files[name]
 
-     } else {
 
-       return node
 
-     }
 
-   }
 
-   getFile (p, followLinks) {
 
-     followLinks = typeof followLinks === 'undefined' ? true : followLinks
 
-     const info = this.getNode(p)
 
-     if (!info) {
 
-       return false
 
-     }
 
-     if (info.link && followLinks) {
 
-       return this.getFile(info.link)
 
-     } else {
 
-       return info
 
-     }
 
-   }
 
- }
 
 
  |