UNPKG

@equicord/unzip-crx

Version:
69 lines (65 loc) 2.66 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// src/index.ts var _promises = require('fs/promises'); var _promises2 = _interopRequireDefault(_promises); var _path = require('path'); var _path2 = _interopRequireDefault(_path); var _jszip = require('jszip'); var _jszip2 = _interopRequireDefault(_jszip); function mkdirp(path2) { return _promises2.default.mkdir(path2, { recursive: true }); } function crxToZip(buf) { function calcLength(a, b, c, d) { let length = 0; length += a << 0; length += b << 8; length += c << 16; length += d << 24 >>> 0; return length; } if (buf[0] === 80 && buf[1] === 75 && buf[2] === 3 && buf[3] === 4) { return buf; } if (buf[0] !== 67 || buf[1] !== 114 || buf[2] !== 50 || buf[3] !== 52) { throw new Error("Invalid header: Does not start with Cr24"); } const isV3 = buf[4] === 3; const isV2 = buf[4] === 2; if (!isV2 && !isV3 || buf[5] || buf[6] || buf[7]) { throw new Error("Unexpected crx format version number."); } if (isV2) { const publicKeyLength = calcLength(buf[8], buf[9], buf[10], buf[11]); const signatureLength = calcLength(buf[12], buf[13], buf[14], buf[15]); const zipStartOffset2 = 16 + publicKeyLength + signatureLength; return buf.slice(zipStartOffset2, buf.length); } const headerSize = calcLength(buf[8], buf[9], buf[10], buf[11]); const zipStartOffset = 12 + headerSize; return buf.slice(zipStartOffset, buf.length); } async function unzip(crxFilePath, destination) { const filePath = _path2.default.resolve(crxFilePath); let dest; if (destination) { dest = destination; } else { const extname = _path2.default.extname(crxFilePath); const basename = _path2.default.basename(crxFilePath, extname); const dirname = _path2.default.dirname(crxFilePath); dest = _path2.default.resolve(dirname, basename); } const buf = await _promises2.default.readFile(filePath); const { files } = await _jszip2.default.loadAsync(crxToZip(buf)); return Promise.all( Object.keys(files).map(async (filename) => { const isFile = !files[filename].dir; const fullPath = _path2.default.join(dest, filename); const directory = isFile && _path2.default.dirname(fullPath) || fullPath; await mkdirp(directory); if (isFile) { const content = await files[filename].async("nodebuffer"); await _promises2.default.writeFile(fullPath, content); } }) ); } var src_default = unzip; exports.default = src_default; exports.unzip = unzip;