@yuebai008/cli
Version:
Command line interface for rapid qg-minigame development
163 lines (131 loc) • 10.1 kB
JavaScript
;var _typeof = require("@babel/runtime-corejs2/helpers/typeof");var _WeakMap = require("@babel/runtime-corejs2/core-js/weak-map");var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");_Object$defineProperty(exports, "__esModule", { value: true });exports["default"] = rpk;var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));var _stringify = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/json/stringify"));var _promise = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/promise"));var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));var _path = _interopRequireDefault(require("path"));
var _jszip = _interopRequireDefault(require("jszip"));
var _crypto = _interopRequireDefault(require("crypto"));
var _index = require("../../cli-shared-utils/index.js");
var _bundle = require("./bundle.js");
var _constanst = require("./constanst.js");
var fflate = _interopRequireWildcard(require("fflate"));function _getRequireWildcardCache(e) {if ("function" != typeof _WeakMap) return null;var r = new _WeakMap(),t = new _WeakMap();return (_getRequireWildcardCache = function _getRequireWildcardCache(e) {return e ? t : r;})(e);}function _interopRequireWildcard(e, r) {if (!r && e && e.__esModule) return e;if (null === e || "object" != _typeof(e) && "function" != typeof e) return { "default": e };var t = _getRequireWildcardCache(r);if (t && t.has(e)) return t.get(e);var n = { __proto__: null },a = _Object$defineProperty && _Object$getOwnPropertyDescriptor;for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) {var i = a ? _Object$getOwnPropertyDescriptor(e, u) : null;i && (i.get || i.set) ? _Object$defineProperty(n, u, i) : n[u] = e[u];}return n["default"] = e, t && t.set(e, n), n;}
// 文件摘要包(zip 文件)
var DIGEST_ZIP_PATH = 'META-INF/CERT';
// 压缩参数,设置输出 buffer,以便对 buffer 进行操作
var COMPRESS_OPTS = {
type: 'nodebuffer',
compression: 'DEFLATE',
compressionOptions: {
level: 9
}
};
// 获取buf的hash
function getBufferDigest(buf) {
var signer = _crypto["default"].createHash('SHA256');
signer.update(buf);
return signer.digest();
}
/**
* 返回摘要文件签名buff d
* @param {} fileHashObj - 文件资源列表和对应hash
* @param {Buffer} privatekey - 私钥文件 buffer
* @param {Buffer} certificate - 证书文件 buffer
* @returns {Object} signedDigestBuf - 摘要文件签名buff
*/function
signZipResourcesMeta(_x, _x2, _x3, _x4) {return _signZipResourcesMeta.apply(this, arguments);}
/**
* 对文件进行重新 排序
* 第一位 入口文件 第二位 js文件 第三位 manifest(读取到这个文件引擎会执行js)
* 第四位 icon和防沉迷页面图片 第五位 游戏的资源文件
* @param {Array(String)} res 文件路径数组
* @param {Object} manifest 小游戏配置文件
*/function _signZipResourcesMeta() {_signZipResourcesMeta = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee(fileHashObj, privatekey, certificate, pathTo) {var metaZipFile, content, digestHash;return _regenerator["default"].wrap(function _callee$(_context) {while (1) switch (_context.prev = _context.next) {case 0: // ZIP元文件
metaZipFile = new _jszip["default"]();metaZipFile.file('hash.json', (0, _stringify["default"])({ algorithm: 'SHA-256', digests: fileHashObj }));_context.next = 4;return metaZipFile.generateAsync(COMPRESS_OPTS);case 4:content = _context.sent;digestHash = { name: 'hash.json', hash: getBufferDigest(content) };return _context.abrupt("return", (0, _bundle.signZip)(content, [digestHash], privatekey, certificate));case 7:case "end":return _context.stop();}}, _callee);}));return _signZipResourcesMeta.apply(this, arguments);}function sortAgain(res, manifest) {
var firstFileArr = ['main.js', 'game.js'];
var firstFile = [];
var secondFile = [];
var imageFileArr = [manifest && manifest.icon.substr(1), manifest && manifest.homePage && manifest.homePage.substr(1)];
var imageFile = [];
var manifestFileArr = ['manifest.json'];
var manifestFile = [];
var lastFile = [];
if (!res) {return [];}
// 将输入数组深拷贝,避免源数据被修改,执行后续操作时出问题
var newRes = JSON.parse((0, _stringify["default"])(res));
for (var index = newRes.length - 1; index >= 0; index--) {
var element = newRes[index];
var extname = _path["default"].extname(element);
if (firstFileArr.indexOf(element) > -1) {
// 入口文件
firstFile.push(element);
newRes.splice(index, 1);
// 其次是icon和首页图片
} else if (extname === '.js') {
// js文件
secondFile.push(element);
newRes.splice(index, 1);
} else if (manifestFileArr.indexOf(element) > -1) {
// 配置文件 manifest.json
manifestFile.push(element);
newRes.splice(index, 1);
} else if (imageFileArr.indexOf(element) > -1) {
// icon和防沉迷页面图片
imageFile.push(element);
newRes.splice(index, 1);
} else {
lastFile.push(element);
}
}
return firstFile.concat(secondFile, manifestFile, imageFile, lastFile);
}
/**
* 打rpk包
* @param {String} name rpk包的文件名
* @param {Array(String)} buildReses rpk对应的资源路径
* @param {String} pathFrom 打包rpk到何处
* @param {String} pathTo 打包rpk到何处
* @param {Object} signFile 签名文件信息
* @param {Object} manifest 小游戏配置文件
*/function
rpk(_x5, _x6, _x7, _x8, _x9, _x10) {return _rpk.apply(this, arguments);}function _rpk() {_rpk = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2(name, buildReses, pathFrom, pathTo, signFile, manifest) {return _regenerator["default"].wrap(function _callee2$(_context2) {while (1) switch (_context2.prev = _context2.next) {case 0:_context2.next = 2;return (
fflateRpk(name, buildReses, pathFrom, pathTo, signFile, manifest));case 2:case "end":return _context2.stop();}}, _callee2);}));return _rpk.apply(this, arguments);}function
fflateRpk(_x11, _x12, _x13, _x14, _x15, _x16) {return _fflateRpk.apply(this, arguments);}function _fflateRpk() {_fflateRpk = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee4(name, buildReses, pathFrom, pathTo, signFile, manifest) {var rpkStartTime, fileHashObj, zipFileHashs, fileContents, privatekey, certificate, newBuildRess, fflateZip, content, size;return _regenerator["default"].wrap(function _callee4$(_context4) {while (1) switch (_context4.prev = _context4.next) {case 0:
// 保证打包路径存在,不存在就创建
rpkStartTime = new Date().valueOf();
_index.fs.ensureDirSync(pathTo);
(0, _index.info)("".concat(_constanst.LOG_TITLE, "\u5F00\u59CBfflate\u538B\u7F29:").concat(name, " from:").concat(pathFrom));
fileHashObj = {}; // 文件hash列表 缓存
zipFileHashs = []; // 文件hash列表打包使用
fileContents = {}; // fflate压缩的文件列表
privatekey = _index.fs.readFileSync(signFile.privatekey);
certificate = _index.fs.readFileSync(signFile.certificate);
// 对打包的文件 进行排序
newBuildRess = sortAgain(buildReses, manifest);
newBuildRess.forEach(function (name) {
var file = _path["default"].join(pathFrom, name);
var buf = _index.fs.readFileSync(file);
var fileHash = getBufferDigest(buf);
fileHashObj[name] = fileHash.toString('hex');
zipFileHashs.push({
name: name,
hash: fileHash
});
// 添加文件到压缩文件列表
fileContents[name] = new Uint8Array(buf);
});
fflateZip = /*#__PURE__*/function () {var _ref = (0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee3(
files,
compressOptions) {var options, zippedContent;return _regenerator["default"].wrap(function _callee3$(_context3) {while (1) switch (_context3.prev = _context3.next) {case 0:_context3.prev = 0;
options = compressOptions || {};_context3.next = 4;return (
new _promise["default"](function (resolve, reject) {
fflate.zip(files, options, function (err, data) {
if (err) {
reject(err);
}
resolve(data);
});
}));case 4:zippedContent = _context3.sent;return _context3.abrupt("return",
Buffer.from(zippedContent));case 8:_context3.prev = 8;_context3.t0 = _context3["catch"](0);return _context3.abrupt("return",
_promise["default"].reject(new Error("compress failed: ".concat(_context3.t0))));case 11:case "end":return _context3.stop();}}, _callee3, null, [[0, 8]]);}));return function fflateZip(_x17, _x18) {return _ref.apply(this, arguments);};}();
// fflate 打包zip包
_context4.next = 13;return fflateZip(fileContents, { level: 9 });case 13:content = _context4.sent;
size = Number(content.length / 1024).toFixed(2);
// 对压缩包进行签名
(0, _bundle.signZip)(content, zipFileHashs, privatekey, certificate, _path["default"].join(pathTo, "".concat(name)));
(0, _index.info)("".concat(_constanst.LOG_TITLE, "\u538B\u7F29fflate\u5B8C\u6210:").concat(name, " \u8017\u65F6\uFF1A").concat((new Date().valueOf() - rpkStartTime) / 1000, "s \u5927\u5C0F\uFF1A").concat(size, "Kb"));case 17:case "end":return _context4.stop();}}, _callee4);}));return _fflateRpk.apply(this, arguments);}