UNPKG

@licq/tpkg

Version:

pack or unpack wechatapp and qqminiapp package

166 lines (144 loc) 4.38 kB
const path = require("path"); const fs = require("fs"); /** * pack dir to pkg * @name pack * @param {pathLike} sourceDir [required] The directory to work with * @param {pathLike} targetPath [optional] The target path, The default path is the same as the sourceDir. * @param {string} targetName [optional] The target filename, The default name is the same as the sourceDir. * @since v1.0.0 * @returns pathLike * @example * const tpkg = require('@licq/tpkg') * const res = tpkg.pack('path/to/dir/'); * const res = tpkg.pack('path/to/dir/', 'path/to/dir/demo'); * const res = tpkg.pack('path/to/dir/', 'path/to/dir/demo', 'demo.wxvpkg') // or demo.tqapkg * //==> eg: path/to/dir/demo.wxvpkg */ function pack(sourceDir, targetPath, targetName) { if (!fs.existsSync(sourceDir)) { return console.log(`\nsourceDir ${sourceDir} does not exist.\n`); } if(targetPath){ if(!fs.existsSync(targetPath)){ return console.log(`\ntargetPath ${targetPath} does not exist.\n`); } }else{ targetPath = path.dirname(sourceDir); } if(!targetName){ targetName = `${path.basename(sourceDir)}.wxvpkg` } targetPath = path.join(targetPath, targetName); const fd = fs.openSync(targetPath, "w"); function writeSync(buf, start) { fs.writeSync(fd, buf, 0, buf.length, start); } function writeInt32(number, start) { let buf = Buffer.alloc(4); buf.writeInt32BE(number, 0); writeSync(buf, start); } let files = fs.readdirSync(sourceDir); let totalCount = files.length; let buf = Buffer.alloc(4); buf.writeInt32BE(totalCount, 0); writeSync(buf, 14); let start = 18; // 12 + /name.length let dataOffset = start; for (let file of files) { let name = `/${file}`; let buf = Buffer.from(name, "utf8"); dataOffset = dataOffset + 12 + buf.length; } for (let file of files) { let nb = Buffer.from(`/${file}`, "utf8"); // write filename byte length writeInt32(nb.length, start); start += 4; // write filename writeSync(nb, start); start += nb.length; // write offset writeInt32(dataOffset, start); start += 4; // write length let contentBuf = fs.readFileSync(path.join(sourceDir, file)); writeInt32(contentBuf.length, start); start += 4; // write content writeSync(contentBuf, dataOffset); dataOffset += contentBuf.length; } fs.closeSync(fd); return targetPath; } /** * unpack pkg * @name unpack * @param {pathLike} pkgPath [required] The pkgPath to work with * @param {pathLike} targetPath [optional] The target path, The default is the same as the pkgPath. * @since v1.0.0 * @returns pathLike * @example * const tpkg = require('@licq/tpkg') * const res = tpkg.unpack('path/to/dir/demo.wxvpkg', _dirname) // or demo.tqapkg * //==> eg: ${_dirname}/demo/** */ function unpack(pkgPath, targetPath) { if (!fs.existsSync(pkgPath)) { return console.log(`\npkgPath ${pkgPath} does not exist.\n`); } if (targetPath) { if (!fs.existsSync(targetPath)) { return console.log(`\ntargetPath ${targetPath} does not exist.\n`); } } else { targetPath = path.dirname(pkgPath); } targetPath = path.join( targetPath, path.basename(pkgPath, path.extname(pkgPath)) ); const fd = fs.openSync(pkgPath, "r"); // read buffer function readSync(start, length) { const n = Buffer.alloc(length); fs.readSync(fd, n, 0, length, start); return n; } const totalCount = readSync(14, 4).readInt32BE(0); const map = {}; let n = 18; for (let i = 0; i < totalCount; i++) { const e = {}; // byte length of filename const i = readSync(n, 4).readInt32BE(0); n += 4; e.name = readSync(n, i).toString(); n += i; e.offset = readSync(n, 4).readInt32BE(0); n += 4; e.length = readSync(n, 4).readInt32BE(0); n += 4; map[e.name] = e; } let created = []; for (let item of Object.values(map)) { let dir = path.join(targetPath, path.dirname(item.name)); if (created.indexOf(dir) == -1) { fs.mkdirSync(dir, { recursive: true }); created.push(dir); } let buf = readSync(item.offset, item.length); let filepath = path.join(targetPath, item.name); fs.writeFileSync(filepath, buf.toString("utf8"), "utf8"); } fs.closeSync(fd); return targetPath; } module.exports = { pack, unpack, };