ttmg-pack 0.1.5 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -250,19 +250,7 @@ remove useless log
250
250
  ## 0.1.1
251
251
 
252
252
  移除 project.config.json 校验
253
-
254
- ## 0.1.2
255
-
256
- 支持 getPkgs unity br 信息导出
257
-
258
- ## 0.1.3
259
-
260
- 优化 unity br 相关问题,支持 CLI 部分测试
261
-
262
- ## 0.1.4
263
-
264
- 修复 unity br 相关问题,支持 CLI 全部测试,补发版本
265
-
266
- ## 0.1.5
267
-
268
- 调整 unity 包大小问题校验,仅对非 unity 工程生效
253
+ ## 0.1.2-0.1.5
254
+ 开发 unity 相关
255
+ ## 0.1.6
256
+ 修复 esbuild 构建编码问题,导致部分 JS 语法不符合预期
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * ==========================================
3
3
  * @Description: ttmg pack
4
- * @Version: 0.1.5
4
+ * @Version: 0.1.6
5
5
  * @Author: zhanghongyang.mocha
6
- * @Date: 2025-11-12 19:20:02
6
+ * @Date: 2025-11-26 11:02:58
7
7
  * ==========================================
8
8
  */
9
- "use strict";var e=require("fs"),s=require("winston"),t=require("path");require("crypto"),require("zlib");var a=require("fs/promises"),i=require("node-fetch"),n=require("acorn"),c=require("glob"),o=require("magic-string"),r=require("esbuild");function d(e){var s=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var a=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(s,t,a.get?a:{enumerable:!0,get:function(){return e[t]}})}}),s.default=e,Object.freeze(s)}var m=d(e),u=d(t);function b(s){e.existsSync(s)||e.mkdirSync(s,{recursive:!0})}const g=new class{constructor(){this.logger=null}init(e,a=!0){this.enableLog=a,this.logger=s.createLogger({level:"info",format:s.format.combine(s.format.timestamp(),s.format.json()),transports:[new s.transports.File({filename:t.join(e,"pack.log")}),new s.transports.Console]})}info(e){this.enableLog&&this.logger.info(e)}error(e){this.enableLog&&this.logger.error(e)}warn(e){this.enableLog&&this.logger.warn(e)}debug(e){this.enableLog&&this.logger.debug(e)}log(e){this.logger.info(e)}setOutput(e){this.output=e}};function f(s){if(!e.existsSync(s))return!1;if(!e.statSync(s).isDirectory())return!1;let a=!0;const i=e.readdirSync(s);for(const n of i){const i=t.join(s,n);if(e.statSync(i).isDirectory()){f(i)||(a=!1)}else a=!1}return!!a&&(e.rmSync(s,{recursive:!0}),!0)}const l="packageConfig.json",p="game.json",k="__GAME__",h=".txt",y="_code",_="_asset",v=62914560,j=["ttmg_odr_high_channel","ttmg_odr_middle_channel","ttmg_odr_normal_channel"],x="independent_package",S="independent_package",w="main_package";function z({rootDir:s,entryDir:a,filterDirs:i}){let n=0;if(!e.existsSync(a))return 0;const c=e.readdirSync(a,{withFileTypes:!0});for(const o of c){const c=t.join(a,o.name);if(o.isDirectory()){const e=t.relative(s,c).replace(/\\/g,"/");i.includes(e)||(n+=z({entryDir:c,filterDirs:i,rootDir:s}))}else o.isFile()&&(n+=e.statSync(c).size)}return n}function $(s){const a=e.readdirSync(s,{withFileTypes:!0});for(const i of a){const a=t.join(s,i.name);if(i.isDirectory())$(a);else if(i.isFile()&&(a.endsWith(".js")||a.endsWith(".js.map")))try{e.unlinkSync(a)}catch(e){}}}function q(s){const a=e.readdirSync(s,{withFileTypes:!0});for(const i of a){const a=t.join(s,i.name);if(i.isDirectory())q(a);else if(i.isFile()&&!a.endsWith(".js")&&!a.endsWith(".js.map"))try{e.unlinkSync(a)}catch(e){}}}const O=["node_modules","__MACOSX"],D=[".DS_Store","Thumbs.db"];function F(s){var a;try{const i=t.join(s,p),n=JSON.parse(e.readFileSync(i,"utf-8"));return(null===(a=null==n?void 0:n.subpackages)||void 0===a?void 0:a.filter(e=>e.independent))||[]}catch(e){return[]}}function M({entryDir:e}){return z({rootDir:e,entryDir:e,filterDirs:C(e)})}function C(s){var a;const i=t.join(s,p);try{const s=JSON.parse(e.readFileSync(i,"utf8"));return((null===(a=s.subpackages)||void 0===a?void 0:a.map(e=>e.root))||[]).map(e=>e.replace(/^\/|\/$/g,""))}catch(e){return[]}}function P({entryDir:e}){return z({rootDir:e,entryDir:e,filterDirs:[]})}function E(s){const a=t.join(s,p);if(!e.existsSync(a))return"unknown";let i;try{i=JSON.parse(e.readFileSync(a,"utf-8"));const s=null==i?void 0:i.gameEngine;return s||"unknown"}catch(e){return"unknown"}}function N(e){return"unity"===E(e)}async function R(e,s,n=5){const c=[];for(const i of e){const{id:e,packages:n}=i,o=t.join(s,e);await a.mkdir(o,{recursive:!0});for(const e in n){const s=n[e],{code_url:a}=s,i=`${e}.txt`,r=t.join(o,i);c.push({code_url:a,filePath:r,packageName:e})}}await async function(e,s,t){const a=[],i=[];for(const n of s){const c=Promise.resolve().then(()=>t(n));if(a.push(c),e<=s.length){const s=c.then(()=>i.splice(i.indexOf(s),1));i.push(s),i.length>=e&&await Promise.race(i)}}return Promise.all(a)}(n,c,async e=>{const{code_url:s,filePath:t,packageName:n}=e;console.log(`start to download ${n}`);try{const e=await i(s);if(!e.ok)throw new Error(`Failed to fetch ${s}: ${e.statusText}`);const c=Buffer.from(await e.arrayBuffer());await a.writeFile(t,c),console.log(`finish to download ${n}`)}catch(e){console.error(`Error downloading ${n}:`,e)}})}var L={MinisPackagingInfoMap:{sbmg0cldak4bbz86dq:{ClientKey:"sbmg0cldak4bbz86dq",MinisStage:1,MinisURL:"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us",ODRPackages:'{"112":{"asset_md5":"9fe63b5fc31e9b4ccd1ee9fa9ed2913b","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/112_asset/9fe63b5fc31e9b4ccd1ee9fa9ed2913b.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/112_code/ebb1a6d341c0013a445f3dbf2600c9ae.txt","root":"subpackages/112","main":"subpackages/112/game.js"},"116":{"asset_md5":"690814b650564724a235a4f155cfe5e3","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/116_asset/690814b650564724a235a4f155cfe5e3.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/116_code/ddc0d442aef316e3e45cdbac9ccb88eb.txt","root":"subpackages/116","main":"subpackages/116/game.js"},"108":{"asset_md5":"b7b3aeafdd70aed9e77fb2f1554d6675","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/108_asset/b7b3aeafdd70aed9e77fb2f1554d6675.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/108_code/bdac7d266b4a15af9ca109d1673168a6.txt","root":"subpackages/108","main":"subpackages/108/game.js"},"game3":{"asset_md5":"bc4b09b1177a35fd8516b8fd5bb9b4e4","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game3_asset/bc4b09b1177a35fd8516b8fd5bb9b4e4.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game3_code/7f3c18114afd5b3d4fd8c39dd2481cf1.txt","root":"subpackages/game3","main":"subpackages/game3/game.js"},"game5":{"asset_md5":"6a75dd22dcf0d7c117cfcb03185696e6","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game5_asset/6a75dd22dcf0d7c117cfcb03185696e6.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game5_code/ed2c8ca8023418099d1232fdc6ac09ae.txt","root":"subpackages/game5","main":"subpackages/game5/game.js"},"main":{"asset_md5":"ecadb8f2a4138a73459e04a8a0c5f470","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/main_asset/ecadb8f2a4138a73459e04a8a0c5f470.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/main_code/3b7a7f0869e5392f1e244eef40ad8abe.txt","root":"subpackages/main","main":"subpackages/main/game.js"},"103":{"asset_md5":"069620ed43643956f6b6448c5d360471","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/103_asset/069620ed43643956f6b6448c5d360471.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/103_code/64a9caf580b6cd991888751e8ea51222.txt","root":"subpackages/103","main":"subpackages/103/game.js"},"other":{"asset_md5":"473ad574dee1813610988dba22fb0acc","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/other_asset/473ad574dee1813610988dba22fb0acc.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/other_code/003784b887ff99fb82d47899798e1ee0.txt","root":"subpackages/other","main":"subpackages/other/game.js"},"resSps":{"asset_md5":"4e72c930e3c8f77bda25be975e3c8019","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/resSps_asset/4e72c930e3c8f77bda25be975e3c8019.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/resSps_code/c6ac2ebde3c8c421ca75ff649280d90b.txt","root":"subpackages/resSps","main":"subpackages/resSps/game.js"},"111":{"asset_md5":"3452f073e30ecc6b3727f072a856068b","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/111_asset/3452f073e30ecc6b3727f072a856068b.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/111_code/3ca9e57876b82945faedce2ca0ab414e.txt","root":"subpackages/111","main":"subpackages/111/game.js"},"117":{"asset_md5":"60206e41273a6a1f6d21bbf634023962","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/117_asset/60206e41273a6a1f6d21bbf634023962.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/117_code/1a85a85048eca0d650ad4b8b198cefdc.txt","root":"subpackages/117","main":"subpackages/117/game.js"},"__GAME__":{"asset_md5":"dbee9c4f704800eb5bf482be01aecadc","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/__GAME___asset/dbee9c4f704800eb5bf482be01aecadc.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/__GAME___code/b42b2a68ce373eb274eedc22351aac02.txt","root":"","main":"game.js"},"jigsaw":{"asset_md5":"4782715dda5ea0d10897d866a84bca19","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/jigsaw_asset/4782715dda5ea0d10897d866a84bca19.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/jigsaw_code/799004f65797d4620549e0d4b27e3794.txt","root":"subpackages/jigsaw","main":"subpackages/jigsaw/game.js"},"newYear":{"asset_md5":"c2cb90fbaac0b4b86d1afa7caabd2f20","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/newYear_asset/c2cb90fbaac0b4b86d1afa7caabd2f20.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/newYear_code/a7d962b4f7a95e8114fcf00bbe27b8ac.txt","root":"subpackages/newYear","main":"subpackages/newYear/game.js"},"adapter":{"asset_md5":"a44f0cd93ad08da6db427c9dc3ab6fe4","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/adapter_asset/a44f0cd93ad08da6db427c9dc3ab6fe4.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/adapter_code/6c3090ba10c12ad637aefa993fe838fc.txt","root":"subpackages/adapter","main":"subpackages/adapter/game.js"},"101":{"asset_md5":"ad3f476d334e695c01f96eef67308f26","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/101_asset/ad3f476d334e695c01f96eef67308f26.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/101_code/dcb5f8547d5285c5e116a1726dc1ecdb.txt","root":"subpackages/101","main":"subpackages/101/game.js"},"102":{"asset_md5":"8b39712d9f0ae7549382da9041cc5f56","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/102_asset/8b39712d9f0ae7549382da9041cc5f56.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/102_code/b70fb4ea0d05b866a4a32ab4cae418c4.txt","root":"subpackages/102","main":"subpackages/102/game.js"},"110":{"asset_md5":"24da51736441ceb88b3d331775004551","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/110_asset/24da51736441ceb88b3d331775004551.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/110_code/f7c97cb3aed7acb4091feaf613c56dd3.txt","root":"subpackages/110","main":"subpackages/110/game.js"},"114":{"asset_md5":"c2f81aaf93311b9302995dba105d69d0","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/114_asset/c2f81aaf93311b9302995dba105d69d0.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/114_code/7574a218fb4053e2005497d84a56132c.txt","root":"subpackages/114","main":"subpackages/114/game.js"},"practice":{"asset_md5":"01d63b100e2cfb80d2d7568d11f346f8","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/practice_asset/01d63b100e2cfb80d2d7568d11f346f8.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/practice_code/2275ac8e93d1c5dd100427aa948cd23c.txt","root":"subpackages/practice","main":"subpackages/practice/game.js"},"zh_CN":{"asset_md5":"2b1c715a0c624c630acb29b4fdfcb240","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/zh_CN_asset/2b1c715a0c624c630acb29b4fdfcb240.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/zh_CN_code/bb44d46f30e57f29d20bf0678426c7c5.txt","root":"subpackages/zh_CN","main":"subpackages/zh_CN/game.js"},"107":{"asset_md5":"652c5385223642c4a19f823666c8a682","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/107_asset/652c5385223642c4a19f823666c8a682.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/107_code/9e717b17251bdc8eefb7b8135fcb6996.txt","root":"subpackages/107","main":"subpackages/107/game.js"},"113":{"asset_md5":"f53882a23326919614b0e9031d28ed39","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/113_asset/f53882a23326919614b0e9031d28ed39.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/113_code/666bb07aea74f0a408136c0ac16a04b8.txt","root":"subpackages/113","main":"subpackages/113/game.js"},"115":{"asset_md5":"6831f12abfeccc9ff720155d9ece2d53","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/115_asset/6831f12abfeccc9ff720155d9ece2d53.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/115_code/76b85e96a57c33c8ba9ff2f316290416.txt","root":"subpackages/115","main":"subpackages/115/game.js"},"118":{"asset_md5":"f787456ee45eccc4c13f20ee21c61858","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/118_asset/f787456ee45eccc4c13f20ee21c61858.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/118_code/e595f8ed244752fe2ddc72def8452cd5.txt","root":"subpackages/118","main":"subpackages/118/game.js"},"chapter":{"asset_md5":"9c4b6cb8dc0b39bfcb275efa0c6b8493","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/chapter_asset/9c4b6cb8dc0b39bfcb275efa0c6b8493.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/chapter_code/9ee175f09ca69c65b630cfee23c0e42c.txt","root":"subpackages/chapter","main":"subpackages/chapter/game.js"},"sound":{"asset_md5":"65c37817ffc86d942d1942443b5e3fb4","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/sound_asset/65c37817ffc86d942d1942443b5e3fb4.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/sound_code/2662512b5aaa6801b6742eb661c44828.txt","root":"subpackages/sound","main":"subpackages/sound/game.js"},"105":{"asset_md5":"82c8cde04fec4456ac6bab8adaef0028","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/105_asset/82c8cde04fec4456ac6bab8adaef0028.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/105_code/74e319194a7f5a204504fc3d83131112.txt","root":"subpackages/105","main":"subpackages/105/game.js"},"109":{"asset_md5":"926ebc459e3329a4d9cda7ddf9718bf4","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/109_asset/926ebc459e3329a4d9cda7ddf9718bf4.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/109_code/19cbdc3d88a72dbd0c5eb52e89e2635a.txt","root":"subpackages/109","main":"subpackages/109/game.js"},"game2":{"asset_md5":"9f1bb086f7587aada8312315f2dd94fc","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game2_asset/9f1bb086f7587aada8312315f2dd94fc.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game2_code/49d07e848cae8eb08428bfbf225a6f30.txt","root":"subpackages/game2","main":"subpackages/game2/game.js"},"game6":{"asset_md5":"b1407de78d19f60644b53436f1791ee6","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game6_asset/b1407de78d19f60644b53436f1791ee6.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game6_code/155651953a65a663f67b95475cd5c941.txt","root":"subpackages/game6","main":"subpackages/game6/game.js"},"prefab":{"asset_md5":"4c4ba8d442bae683575460e884ddba00","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/prefab_asset/4c4ba8d442bae683575460e884ddba00.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/prefab_code/7f037cd7f3b83e90765e749d28f32e3e.txt","root":"subpackages/prefab","main":"subpackages/prefab/game.js"},"104":{"asset_md5":"160c617e3e3adef19c94f57bc4520dba","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/104_asset/160c617e3e3adef19c94f57bc4520dba.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/104_code/ef86df3a24fca9ecffc55f7c33ff3747.txt","root":"subpackages/104","main":"subpackages/104/game.js"},"106":{"asset_md5":"b22052c8f569db2f00a2ae6fcb8872e6","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/106_asset/b22052c8f569db2f00a2ae6fcb8872e6.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/106_code/f13ed6653a2ebb49703d0bc882255cfd.txt","root":"subpackages/106","main":"subpackages/106/game.js"},"game4":{"asset_md5":"b98a8892ccb76e5999cbf7a8e81c4cb5","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game4_asset/b98a8892ccb76e5999cbf7a8e81c4cb5.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game4_code/ebbcf2b74998d340cb8cf85249748992.txt","root":"subpackages/game4","main":"subpackages/game4/game.js"}}',UpdatedTime:1756716749e3,AssetType:1}}};const T={name:"project",dimension:"project"};function A(s,a){g.info("start check project");const i=function(e,s){g.info("start check project size");const{build:{pkgSizeLimit:t},dev:a}=s,i=null==a?void 0:a.enable,n=P({entryDir:e}),c=(n/1048576).toFixed(2),o=(t/1048576).toFixed(2);if(n>t){const e=`Check project size failed, size: ${c}MB, must not exceed ${o}MB`;if(g.error(e),i)return console.log("%s",e),Object.assign({passed:!1,msg:e,type:"size",size:n},T);throw new Error(e)}{const e=`Check project size successfully, size: ${c}MB`;return g.info(e),Object.assign({passed:!0,msg:e,name:"project",type:"size",size:n},T)}}(s,a),n=function(s,a){var i;g.info("start check config");const n=t.join(s,p);if(e.existsSync(n)){const e="Check game.json config successfully";return g.info(e),Object.assign({passed:!0,msg:e,file:p,type:"config"},T)}{const e="Can not find game.json in game source code, please check it";if(g.error(e),null===(i=null==a?void 0:a.dev)||void 0===i?void 0:i.enable)return console.log("%s",`❗️ ${e}`),Object.assign({passed:!1,msg:e,type:"config",file:p},T);throw new Error(e)}}(s,a),c=[i,n];return c.every(e=>e.passed)&&g.info("check project successfully"),c}const J={name:"main",dimension:"main_package"};function G(e,s){var t;const a=[];return g.info("start check main package"),a.push(function({entryDir:e,config:s}){var t;g.info("start check main package entry");const a=u.join(e,"game.js");if(!m.existsSync(a)){const e="Check main package entry failed, game.js must exist in main package!";if(g.error(e),null===(t=s.dev)||void 0===t?void 0:t.enable)return console.log("%s",e),Object.assign({passed:!1,msg:e,type:"config",file:"game.js"},J)}return g.info("check game.js successfully"),Object.assign({passed:!0,msg:"Check main package entry successfully, game.js must exist in main package!",type:"config",file:"game.js"},J)}({entryDir:e,config:s})),!N(e)&&(null===(t=s.build)||void 0===t?void 0:t.mainPkgSizeLimit)&&a.push(function({entryDir:e,config:s}){g.info("start check main package size");const{build:t,dev:a}=s,i=M({entryDir:e}),n=(i/1048576).toFixed(2),c=(t.mainPkgSizeLimit/1048576).toFixed(2);if(i>t.mainPkgSizeLimit){const e=`Check main package size failed, main package size ${n}MB, must not exceed ${c}MB`;if(g.error(e),null==a?void 0:a.enable)return console.log("%s",`❗️ ${e}`),Object.assign({passed:!1,msg:e,size:i,type:"size"},J);throw new Error(e)}return Object.assign({passed:!0,msg:`Check main package size successfully, size: ${n}MB`,size:i,type:"size"},J)}({entryDir:e,config:s})),a.every(e=>e.passed)&&g.info("Check main package successfully"),a}const W={name:"subpackage",dimension:"subpackage"};function B(s,a){const i=[];g.info("start check subpackages in game.json");const n=function(s){var a;try{const i=t.join(s,p),n=JSON.parse(e.readFileSync(i,"utf-8"));return(null===(a=null==n?void 0:n.subpackages)||void 0===a?void 0:a.filter(e=>!e.independent))||[]}catch(e){return[]}}(s);return n.forEach(n=>{var c,o;if(n.name&&n.root)i.push(Object.assign({passed:!0,msg:`Check subpackage<${n.name}> config successfully`,type:"config",file:p},W));else{const e="Check subpackages config failed, the subpackages configuration in game.json is invalid: the root or name field in one or more subpackages is empty. Please ensure that all subpackages have non-empty root and name values.";if(g.error(e),!(null===(c=null==a?void 0:a.dev)||void 0===c?void 0:c.enable))throw new Error(e);console.log("%s",`❗️ ${e}`),i.push(Object.assign({passed:!1,msg:e,type:"config",file:p},W))}const r=t.join(s,n.root);if(e.existsSync(r))i.push(Object.assign({passed:!0,msg:`Check subpackage<${n.name}> config successfully`,type:"config",file:p},W));else{const e=`Check subpackage<${n.name}> config failed, the subpackages configuration in game.json is invalid: can not find subpackage ${n.name} entry dir, please check it`;if(g.error(e),!(null===(o=null==a?void 0:a.dev)||void 0===o?void 0:o.enable))throw new Error(e);console.log("%s",`❗️ ${e}`),i.push(Object.assign({passed:!1,msg:e,type:"config",file:p},W))}}),i.length&&i.every(e=>e.passed)&&g.info("Check subpackages config successfully"),i}const I={dimension:x};function U(s,a){var i;const n=null===(i=null==a?void 0:a.dev)||void 0===i?void 0:i.enable,c=[];g.info("start check independent subpackages in game.json");return F(s).forEach(i=>{var o;if(i.name&&i.root)c.push(Object.assign(Object.assign({},I),{passed:!0,msg:`Check independent package<${i.name}> config successfully`,type:"config",file:p,name:i.name}));else{const e="Check independent subpackages config failed, the subpackages configuration in game.json is invalid: the root or name field in one or more independent subpackages is empty. Please ensure that all independent subpackages have non-empty root and name values.";if(g.error(e),!n)throw new Error(e);console.log("%s",`❗️${e}`),c.push(Object.assign(Object.assign({},I),{passed:!1,msg:e,type:"config",file:p,name:i.name}))}const r=t.join(s,i.root);if(e.existsSync(r))c.push({passed:!0,msg:`Check independent package<${i.name}> config successfully`,type:"config",file:p,dimension:x,name:i.name});else{const e=`Check independent package<${i.name}> config failed, the subpackages configuration in game.json is invalid: can not find subpackage ${i.name} entry dir, please check it`;if(g.error(e),!n)throw new Error(e);console.log("%s",`❗️ ${e}`),c.push(Object.assign(Object.assign({},I),{passed:!1,msg:e,type:"config",file:p,name:i.name}))}const d=null===(o=null==a?void 0:a.build)||void 0===o?void 0:o.independentSubPkgSizeLimit;if(!N(s)&&d){const e=function({entryDir:e,limit:s,pkgName:t,dimension:a}){const i=z({rootDir:e,entryDir:e,filterDirs:[]}),n=i<=s,c=i/1024/1024,o=s/1024/1024;return{passed:n,msg:n?`Check package ${t} size ${c.toFixed(2)}MB check successfully`:`Check package ${t} size ${c.toFixed(2)}MB exceeds limit ${o.toFixed(2)}MB`,type:"size",size:i,dimension:a,name:t}}({entryDir:r,pkgName:i.name,limit:d,dimension:x});if(c.push(e),g.info(e.msg),!e.passed){if(!n)throw new Error(e.msg);console.log("%s",`❗️ ${e.msg}`)}}}),c.length&&c.every(e=>e.passed)&&g.info("Check independent subpackages config successfully"),c}const Y=[{name:"login",desc:"Login to get open id"},{name:"createRewardedVideoAd",desc:"Integrate rewarded video ads"},{name:"addShortcut",desc:"Add game shortcut to home screen"},{name:"getShortcutMissionReward",desc:"Get shortcut mission reward"},{name:"startEntranceMission",desc:"Jump to TikTok personal sidebar"},{name:"getEntranceMissionReward",desc:"Get entrance mission reward"}];function V(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}async function K({entryDir:s,config:a}){g.info("开始校验项目");const i=A(s,a),n=G(s,a),c=B(s,a),o=U(s,a),r=function({entryDir:s,config:a}){var i;if(!(null===(i=null==a?void 0:a.build)||void 0===i?void 0:i.enableAPICheck))return[];const n=[".js",".ts"],c=new Map(Y.map(({name:e})=>{const s=[`\\b${V(e)}\\b`,`\\.${V(e)}\\s*\\(`,`\\b${V(e)}\\s*:\\s*`,`\\b${V(e)}\\s*=`,`\\b${V(e)}\\s*\\(`].join("|");return[e,new RegExp(s,"m")]})),o=new Map;for(const{name:e}of Y)o.set(e,new Set);const r=[s];for(;r.length;){const s=r.pop();if(e.statSync(s).isDirectory()){const a=t.basename(s);if(["node_modules",".git","dist","build","out",".cache"].includes(a))continue;const i=e.readdirSync(s);for(const e of i)r.push(t.join(s,e));continue}const a=t.extname(s).toLowerCase();if(!n.includes(a))continue;let i="";try{i=e.readFileSync(s,"utf8")}catch(e){continue}if(!(i.length>5e6))for(const{name:e}of Y)c.get(e).test(i)&&o.get(e).add(s)}return Y.map(({name:e})=>{const s=Array.from(o.get(e)||[]);return{name:e,msg:s.length>0?`${e} integrated!`:`${e} not integrated!`,passed:s.length>0,files:s,type:"api",required:!1,dimension:"project"}})}({entryDir:s,config:a});return[...i,...n,...c,...o,...r]}async function X(s,a){g.info("开始基于源代码中的 game.json 生成 packageConfig.json");const i=t.join(s,p),n=JSON.parse(e.readFileSync(i,"utf-8")),c={},o=[{value:k,label:"Main (Main package)",type:w}];c[k]={url:"",md5:"",root:"",main:"game.js",output:`${k}${h}`},function(e){if(!e||0===e.length)return[];function s(e){return String(e).replace(/^\/+|\/+$/g,"")}function a(e){return i(e)?t.join(e,"game.js").replace(/\\/g,"/"):e}function i(e){return e.endsWith("/")||!/\.[a-zA-Z0-9]+$/.test(e)}function n(e){return e.replace(/^\/+|\/+$/g,"")}return e.map(e=>{const t=s(e.name);return{main:a(e.root),root:n(e.root),name:t,independent:e.independent||!1}})}(n.subpackages).forEach(({name:e,root:s,main:t,independent:a})=>{c[e]={url:"",md5:"",root:s,main:t,output:`${e}${h}`,independent:a},a&&o.push({value:e,label:`${e} (Independent package)`,type:S})});const r={packages:c,fyf_packages:o};return e.existsSync(a)&&e.rmSync(a,{recursive:!0}),e.mkdirSync(a),e.writeFileSync(t.join(a,l),JSON.stringify(r,null,2)),g.info("基于源代码中的 game.json 生成 packageConfig.json 成功"),r}function Z(e){const s=[];return Object.values(e).forEach(e=>{Object.values(e).forEach(e=>{s.push(...e)})}),s}function H({entry:s,root:a,exts:i=[".js",".ts",".jsx",".tsx"],excludeDirs:n=[]}){let c=[];if(!e.existsSync(s))return c;const o=e.readdirSync(s,{withFileTypes:!0});for(const e of o){const o=t.join(s,e.name);if(e.isDirectory()){const e=t.relative(a,o).replace(/\\/g,"/");if(n.find(s=>s===e))continue;c=c.concat(H({entry:o,root:a,exts:i,excludeDirs:n}))}else i.some(s=>e.name.endsWith(s))&&c.push(o)}return c}function Q(s,a){const i=function(s){return e.readdirSync(s).filter(a=>{const i=t.join(s,a);return e.statSync(i).isDirectory()&&!["node_modules","dist","build","output"].includes(a)}).map(e=>e+"/")}(s),o=c.sync("**/*.js",{cwd:s,ignore:[]}),r=[];o.forEach(a=>{const c=t.join(s,a),o=e.readFileSync(c,"utf-8");let d;try{d=n.parse(o,{ecmaVersion:"latest",sourceType:"module"})}catch(e){return}ee(d,a=>{if("CallExpression"===a.type&&"Identifier"===a.callee.type&&("require"===a.callee.name||"requireAsync"===a.callee.name)&&a.arguments.length>0&&"Literal"===a.arguments[0].type&&"string"==typeof a.arguments[0].value){const n=a.arguments[0].value;let o=null;if(n.startsWith("."))o=t.resolve(t.dirname(c),n);else if(n.startsWith("/"))o=t.resolve(s,"."+n);else for(const e of i)if(n.startsWith(e)){o=t.resolve(s,n);break}o&&!function(s){if(e.existsSync(s)&&e.statSync(s).isFile())return!0;const t=[".js",".ts",".jsx",".tsx"];for(const a of t)if(e.existsSync(s+a)&&e.statSync(s+a).isFile())return!0;return!1}(o)&&(o=null),r.push({file:t.relative(s,c),callee:a.callee.name,requirePath:n,resolvedPath:o?t.relative(s,o):""})}})});const d=r.map(e=>{let s="";Object.keys(a).forEach(t=>{e.resolvedPath&&e.resolvedPath.startsWith(a[t].root)&&(s=t)});let t="";return Object.keys(a).forEach(s=>{e.file.startsWith(a[s].root)&&(t=s)}),Object.assign(Object.assign({},e),{curModule:t,depModule:s})}),m=[".js",".ts",".jsx",".tsx"];return d.reduce((e,s)=>{return e[s.curModule]||(e[s.curModule]={}),s.curModule===s.depModule||s.resolvedPath&&(t=s.resolvedPath,m.some(e=>t.endsWith(e)))&&(e[s.curModule]=Object.assign(Object.assign({},e[s.curModule]),{[s.resolvedPath]:s.depModule})),e;var t},{})}function ee(e,s){s(e);for(let t in e)if(e.hasOwnProperty(t)){const a=e[t];Array.isArray(a)?a.forEach(e=>e&&"string"==typeof e.type&&ee(e,s)):a&&"string"==typeof a.type&&ee(a,s)}}async function se({pkgRoot:s,destRoot:a,packedFiles:i,gameEntry:n,gameOutput:c,skipDirs:o=[],isRoot:r=!0}){if(!e.existsSync(s))return;const d=e.readdirSync(s,{withFileTypes:!0});for(const r of d){const d=t.join(s,r.name),m=t.join(a,r.name),u=t.join(s,r.name);if(r.isDirectory()){const e=t.relative(n,u).replace(/\\/g,"/");if(o.find(s=>s===e))continue}r.isDirectory()?se({pkgRoot:d,destRoot:m,gameOutput:c,packedFiles:i,gameEntry:n,skipDirs:o,isRoot:!1}):(b(t.dirname(m)),i.includes(t.relative(n,d).replace(/\\/g,"/"))||e.copyFileSync(d,m))}}function te(e){const s=[];return e&&s.push(...Object.values(e).map(e=>e.root)),s}async function ae({gameEntry:s,gameOutput:a,config:i}){let n=Date.now();!function(s){!function s(a){let i;try{i=e.readdirSync(a)}catch(e){return void g.warn(`无法访问目录: ${a}, ${e.message}`)}i.forEach(i=>{const n=t.join(a,i);try{const t=e.statSync(n);t.isDirectory()?O.includes(i)?(e.rmSync(n,{recursive:!0,force:!0}),g.info(`已删除无用目录: ${n}`)):s(n):t.isFile()&&D.includes(i)&&(e.rmSync(n,{force:!0}),g.info(`已删除无用文件: ${n}`))}catch(e){g.warn(`无法处理: ${n}, ${e.message}`)}})}(s)}(s),g.info(`pack start,startTime:${n}`);const{packages:c}=await X(s,a),d=Q(s,c),m=function(e,s){g.info("开始基于游戏源代码收集分包中的 JS 文件");const a={},i=Object.values(s).filter(e=>e.root&&""!==e.root).map(e=>e.root).filter(Boolean),n=Array.from(new Set(i));for(const i in s){const c=s[i];let o,r;"__GAME__"===i?(r=H({entry:e,root:e,exts:[".js",".ts",".jsx",".tsx"],excludeDirs:n}),o=e):(o=t.join(e,c.root),r=H({entry:o,root:o,exts:[".js",".ts",".jsx",".tsx"],excludeDirs:[]}));const d=[];r.forEach(s=>{d.push(t.relative(e,s).replace(/\\/g,"/"))});const m=s[i].root;a[i]={[m?`${m}/game.pack.js`:"game.pack.js"]:d}}return g.info("基于游戏源代码收集分包中的 JS 文件完成"),a}(s,c);return await async function(e,s,t){const a=[],i=[];for(const n of s){const c=Promise.resolve().then(()=>t(n));if(a.push(c),e<=s.length){const s=c.then(()=>{i.splice(i.indexOf(s),1)});i.push(s),i.length>=e&&await Promise.race(i)}}return Promise.all(a)}(10,Object.keys(m),async n=>{g.info(`开始基于游戏源代码打包,包名:${n}`);let u=Date.now();const l=c[n],p=t.join(s,l.root),k=t.join(a,n,l.root);await function({gameEntry:s,pkgName:a,allDeps:i,allMaps:n,pkgConfig:c,destRoot:d,config:m}){var u,f,l,p;let k=Date.now();g.info(`pack start,startTime:${k}`);const h=n[a],y={main:c.main,deps:i[a]||{},map:n[a]};b(d),e.writeFileSync(t.join(d,"moduleConfig.json"),JSON.stringify(y));for(const i in h){const n=h[i];if(!Array.isArray(n)||0===n.length)continue;const c=new o.Bundle({separator:"\n"});for(const a of n){const n=t.join(s,a);if(e.existsSync(n)&&t.basename(n)!==i&&/\.js$/i.test(a))try{const{code:s}=r.transformSync(e.readFileSync(n,"utf-8"),{loader:"js",format:"cjs",target:"es2015"}),t=a.replace(/\\/g,"/"),i=`define("game:${t}", ["require", "requireAsync", "module", "exports", "sandboxGlobal"], function(require, requireAsync, module, exports, sandboxGlobal){\nwith(sandboxGlobal){\n`,d="\n}\n});\n",m=new o(s,{filename:t});m.prepend(i),m.append(d),c.addSource({content:m,filename:t})}catch(e){g.error(`pack error, relPath:${a},e:${e}`)}}const b=t.join(d,t.basename(i)),k=c.toString();if(null===(u=null==m?void 0:m.dev)||void 0===u?void 0:u.enableSourcemap){const s=c.generateMap({hires:!0,includeContent:!0,file:t.basename(i)});if(null===(f=null==m?void 0:m.dev)||void 0===f?void 0:f.inlineSourcemap){const t=k+`\n//# sourceMappingURL=data:application/json;base64,${Buffer.from(s.toString()).toString("base64")}`+`\n//# sourceURL=${i}`;e.writeFileSync(b,t,"utf-8")}else{const a=`http://${null===(l=null==m?void 0:m.dev)||void 0===l?void 0:l.host}:${null===(p=null==m?void 0:m.dev)||void 0===p?void 0:p.port}/game/files`,n=t.basename(i)+".map",c=t.join(d,n);e.writeFileSync(c,s.toString(),"utf-8");const o=k+`\n//# sourceMappingURL=${a}/${i}.map`+`\n//# sourceURL=${i}`;e.writeFileSync(b,o,"utf-8")}}else{const s=k+`\n//# sourceURL=${i}`;e.writeFileSync(b,s,"utf-8")}g.info(`pack end,packName:${a}`)}}({gameEntry:s,allDeps:d,allMaps:m,pkgName:n,pkgConfig:l,destRoot:k,config:i}),await se({gameEntry:s,gameOutput:a,pkgRoot:p,destRoot:k,packedFiles:Z(m),skipDirs:te(c)});f(t.join(a,n)),g.info(`基于游戏源代码打包分包完成,包名:${n}`),g.info(`基于游戏源代码打包分包耗时,包名:${n},耗时:${Date.now()-u}ms`)}),g.info(`pack end,duration:${Date.now()-n}ms`),{}}exports.buildOdrPkgs=async function({tempDir:s}){e.existsSync(s)&&e.rmSync(s,{recursive:!0}),e.mkdirSync(s);const a=function(){const{MinisPackagingInfoMap:e}=L;return Object.keys(e).map(s=>({id:s,packages:JSON.parse(e[s].ODRPackages)}))}();g.info("odr_games"),await R(a,s);const i={};for(const e of a){const{id:a}=e,n=t.join(s,a);i[a]=z({rootDir:s,entryDir:n,filterDirs:[]})}const n={};j.forEach(e=>{n[e]=[]});const c={};for(const o of a){const{id:a,packages:r}=o,d=i[a];if(d>v)continue;let m=null;for(const c of j){const o=t.join(s,c);e.existsSync(o)||e.mkdirSync(o);if(n[c].reduce((e,s)=>e+i[s],0)+d<=v){const i=t.join(s,a),r=t.join(o,a);e.cpSync(i,r,{recursive:!0}),n[c].push(a),m=c;break}}if(m){c[a]={tag:m,packages:{}};for(const e in r){const s=r[e];g.info(`TTMGODRConfig[gameId].packages, ${s}, ${e}`),c[a].packages[e]={root:s.root,main:s.main,asset_md5:s.asset_md5,asset_url:s.asset_url}}console.log(`finish to build ${a}`),e.rmSync(t.join(s,a),{recursive:!0})}}const o=t.join(s,"TTMG_ODR_CONFIG.json");e.writeFileSync(o,JSON.stringify(c,null,2),"utf-8"),g.info(`TTMG_ODR_CONFIG.json 已生成: ${o}`)},exports.buildPkgs=async function(s){const{entry:a,output:i,build:n}=s;let c=Date.now();g.init(i,!0),g.info("TTMG_PACK_VERSION: 0.1.5"),g.info(`pack start, startTime:${c}`);const o=function(e,s){var t,a;const i=N(e);return Object.assign(Object.assign({},s),{build:Object.assign(Object.assign({},s.build),{mainPkgSizeLimit:i?null:null===(t=s.build)||void 0===t?void 0:t.mainPkgSizeLimit,independentSubPkgSizeLimit:i?null:null===(a=s.build)||void 0===a?void 0:a.independentSubPkgSizeLimit})})}(a,s);await K({entryDir:a,config:o}),await ae({config:o,gameEntry:a,gameOutput:i}),(null==n?void 0:n.enableOdr)&&await async function(s){let a=Date.now();g.info(`makeOdrPkgs start, ${a}`);const i=t.join(s,l),n=JSON.parse(e.readFileSync(i,"utf-8")),c=n.packages;for(const a in c){const i=t.join(s,a),n=t.join(s,`${a}${y}`),o=t.join(s,`${a}${_}`);b(n),b(o),e.cpSync(i,n,{recursive:!0}),e.cpSync(i,o,{recursive:!0}),q(n),$(o),c[`${a}${y}`]=Object.assign(Object.assign({},c[a]),{code_url:"",code_md5:"",output:`${a}${y}${h}`}),c[`${a}${_}`]=Object.assign(Object.assign({},c[a]),{asset_url:"",asset_md5:"",output:`${a}${_}${h}`})}e.writeFileSync(i,JSON.stringify(n,null,2)),g.info(`makeOdrPkgs end, ${Date.now()-a}ms`)}(i),g.info(`pack end:${Date.now()-c}ms`)},exports.checkPkgs=K,exports.debugPkgs=async function(s){const{entry:a,output:i,dev:{enableLog:n}}=s;g.init(i,n);try{const n=await K({entryDir:a,config:s});await ae({gameEntry:a,gameOutput:i,config:s}),await async function(s){g.info("mergePkgs start");const a=t.join(s,l);let i;try{i=JSON.parse(e.readFileSync(a,"utf-8"))}catch(e){return void g.error(`读取配置文件失败: ${a}, err: ${e.message}`)}const n=i.packages;if(n&&"object"==typeof n){for(const a of Object.keys(n)){const i=t.join(s,a);if(!e.existsSync(i)){g.warn(`package 目录不存在: ${i}`);continue}const n=await e.promises.readdir(i);for(const a of n){const n=t.join(i,a),c=t.join(s,a);try{const s=await e.promises.stat(n);if(s.isFile())await e.promises.copyFile(n,c),await e.promises.rm(n,{recursive:!0,force:!0});else if(s.isDirectory())await e.promises.cp(n,c,{recursive:!0}),await e.promises.rm(n,{recursive:!0,force:!0});else if(s.isSymbolicLink()){const t=e.readlinkSync(n);e.existsSync(c)&&await e.promises.rm(c,{force:!0}),await e.promises.symlink(t,c,s.isDirectory()?"dir":"file")}g.info(`合并文件/目录: ${n} -> ${c}`)}catch(e){g.error(`处理文件失败: ${n}, err: ${e.message}`)}}0===e.readdirSync(i).length&&(e.rmSync(i,{recursive:!0,force:!0}),g.info(`已删除 package 目录: ${i}`))}g.info("mergePkgs 完成")}else g.error("配置文件中 packages 字段无效, 请检查配置")}(i);const c=e.readFileSync(t.join(i,l),"utf-8");return{isSuccess:!0,packages:JSON.parse(c).packages,checkResults:n}}catch(e){return{isSuccess:!1,errorMsg:e.message}}},exports.getPkgs=async function({entryDir:s}){const a=F(s),i=[{type:"main",size:M({entryDir:s}),name:k,root:""},...a.map(e=>({type:"independent",size:z({rootDir:s,entryDir:t.join(s,e.root),filterDirs:[]}),name:e.name,root:e.root}))],n=function({entryDir:s}){if(N(s)){const a=t.join(s,"wasmcode");if(!e.existsSync(a))return"";const i=e.readdirSync(a).filter(e=>e.endsWith(".webgl.wasm.code.unityweb.wasm.br"));return 0===i.length?"":t.relative(s,t.join(a,i[0]))}return""}({entryDir:s});return n&&i.push({type:"wasmcode",name:"wasmcode",root:n}),{size:P({entryDir:s}),engine:E(s),packages:i}},exports.writeOdrConfig=async function(e){g.info("writeOdrPackagesConfig start");const s=u.join(e,l),t=JSON.parse(m.readFileSync(s,"utf-8")),a=t.packages,i=t.odr_packages||{};for(const e in a){if(e.endsWith(y)){const s=a[e],t=e.split(y)[0];i[t]||(i[t]={}),i[t]=Object.assign(Object.assign({},i[t]),{root:s.root,code_output:s.output,code_md5:s.md5,main:s.main}),delete a[e]}if(e.endsWith(_)){const s=e.split(_)[0],t=a[e];i[s]=Object.assign(Object.assign({},i[s]),{root:t.root,asset_output:t.output,asset_md5:t.md5}),delete a[e]}}t.odr_packages=i,m.writeFileSync(s,JSON.stringify(t,null,2)),g.info("writeOdrPackagesConfig end")};
9
+ "use strict";var e=require("fs"),s=require("winston"),t=require("path");require("crypto"),require("zlib");var a=require("fs/promises"),i=require("node-fetch"),n=require("acorn"),c=require("glob"),o=require("magic-string"),r=require("esbuild");function d(e){var s=Object.create(null);return e&&Object.keys(e).forEach(function(t){if("default"!==t){var a=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(s,t,a.get?a:{enumerable:!0,get:function(){return e[t]}})}}),s.default=e,Object.freeze(s)}var m=d(e),u=d(t);function b(s){e.existsSync(s)||e.mkdirSync(s,{recursive:!0})}const g=new class{constructor(){this.logger=null}init(e,a=!0){this.enableLog=a,this.logger=s.createLogger({level:"info",format:s.format.combine(s.format.timestamp(),s.format.json()),transports:[new s.transports.File({filename:t.join(e,"pack.log")}),new s.transports.Console]})}info(e){this.enableLog&&this.logger.info(e)}error(e){this.enableLog&&this.logger.error(e)}warn(e){this.enableLog&&this.logger.warn(e)}debug(e){this.enableLog&&this.logger.debug(e)}log(e){this.logger.info(e)}setOutput(e){this.output=e}};function f(s){if(!e.existsSync(s))return!1;if(!e.statSync(s).isDirectory())return!1;let a=!0;const i=e.readdirSync(s);for(const n of i){const i=t.join(s,n);if(e.statSync(i).isDirectory()){f(i)||(a=!1)}else a=!1}return!!a&&(e.rmSync(s,{recursive:!0}),!0)}const l="packageConfig.json",p="game.json",k="__GAME__",h=".txt",y="_code",_="_asset",v=62914560,j=["ttmg_odr_high_channel","ttmg_odr_middle_channel","ttmg_odr_normal_channel"],x="independent_package",S="independent_package",z="main_package",w="unity";function $({rootDir:s,entryDir:a,filterDirs:i}){let n=0;if(!e.existsSync(a))return 0;const c=e.readdirSync(a,{withFileTypes:!0});for(const o of c){const c=t.join(a,o.name);if(o.isDirectory()){const e=t.relative(s,c).replace(/\\/g,"/");i.includes(e)||(n+=$({entryDir:c,filterDirs:i,rootDir:s}))}else o.isFile()&&(n+=e.statSync(c).size)}return n}function q(s){const a=e.readdirSync(s,{withFileTypes:!0});for(const i of a){const a=t.join(s,i.name);if(i.isDirectory())q(a);else if(i.isFile()&&(a.endsWith(".js")||a.endsWith(".js.map")))try{e.unlinkSync(a)}catch(e){}}}function O(s){const a=e.readdirSync(s,{withFileTypes:!0});for(const i of a){const a=t.join(s,i.name);if(i.isDirectory())O(a);else if(i.isFile()&&!a.endsWith(".js")&&!a.endsWith(".js.map"))try{e.unlinkSync(a)}catch(e){}}}const D=["node_modules","__MACOSX"],F=[".DS_Store","Thumbs.db"];function M(s){var a;try{const i=t.join(s,p),n=JSON.parse(e.readFileSync(i,"utf-8"));return(null===(a=null==n?void 0:n.subpackages)||void 0===a?void 0:a.filter(e=>e.independent))||[]}catch(e){return[]}}function C({entryDir:e}){return $({rootDir:e,entryDir:e,filterDirs:P(e)})}function P(s){var a;const i=t.join(s,p);try{const s=JSON.parse(e.readFileSync(i,"utf8"));return((null===(a=s.subpackages)||void 0===a?void 0:a.map(e=>e.root))||[]).map(e=>e.replace(/^\/|\/$/g,""))}catch(e){return[]}}function E({entryDir:e}){return $({rootDir:e,entryDir:e,filterDirs:[]})}function N(s,a){var i,n;const c=function(s){const a=t.join(s,p);if(!e.existsSync(a))return"";let i;try{i=JSON.parse(e.readFileSync(a,"utf-8"));return(null==i?void 0:i.gameEngine)||""}catch(e){return""}}(s)===w;return Object.assign(Object.assign({},a),{build:Object.assign(Object.assign({},a.build),{mainPkgSizeLimit:c?null:null===(i=a.build)||void 0===i?void 0:i.mainPkgSizeLimit,independentSubPkgSizeLimit:c?null:null===(n=a.build)||void 0===n?void 0:n.independentSubPkgSizeLimit})})}async function R(e,s,n=5){const c=[];for(const i of e){const{id:e,packages:n}=i,o=t.join(s,e);await a.mkdir(o,{recursive:!0});for(const e in n){const s=n[e],{code_url:a}=s,i=`${e}.txt`,r=t.join(o,i);c.push({code_url:a,filePath:r,packageName:e})}}await async function(e,s,t){const a=[],i=[];for(const n of s){const c=Promise.resolve().then(()=>t(n));if(a.push(c),e<=s.length){const s=c.then(()=>i.splice(i.indexOf(s),1));i.push(s),i.length>=e&&await Promise.race(i)}}return Promise.all(a)}(n,c,async e=>{const{code_url:s,filePath:t,packageName:n}=e;console.log(`start to download ${n}`);try{const e=await i(s);if(!e.ok)throw new Error(`Failed to fetch ${s}: ${e.statusText}`);const c=Buffer.from(await e.arrayBuffer());await a.writeFile(t,c),console.log(`finish to download ${n}`)}catch(e){console.error(`Error downloading ${n}:`,e)}})}var L={MinisPackagingInfoMap:{sbmg0cldak4bbz86dq:{ClientKey:"sbmg0cldak4bbz86dq",MinisStage:1,MinisURL:"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us",ODRPackages:'{"112":{"asset_md5":"9fe63b5fc31e9b4ccd1ee9fa9ed2913b","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/112_asset/9fe63b5fc31e9b4ccd1ee9fa9ed2913b.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/112_code/ebb1a6d341c0013a445f3dbf2600c9ae.txt","root":"subpackages/112","main":"subpackages/112/game.js"},"116":{"asset_md5":"690814b650564724a235a4f155cfe5e3","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/116_asset/690814b650564724a235a4f155cfe5e3.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/116_code/ddc0d442aef316e3e45cdbac9ccb88eb.txt","root":"subpackages/116","main":"subpackages/116/game.js"},"108":{"asset_md5":"b7b3aeafdd70aed9e77fb2f1554d6675","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/108_asset/b7b3aeafdd70aed9e77fb2f1554d6675.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/108_code/bdac7d266b4a15af9ca109d1673168a6.txt","root":"subpackages/108","main":"subpackages/108/game.js"},"game3":{"asset_md5":"bc4b09b1177a35fd8516b8fd5bb9b4e4","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game3_asset/bc4b09b1177a35fd8516b8fd5bb9b4e4.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game3_code/7f3c18114afd5b3d4fd8c39dd2481cf1.txt","root":"subpackages/game3","main":"subpackages/game3/game.js"},"game5":{"asset_md5":"6a75dd22dcf0d7c117cfcb03185696e6","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game5_asset/6a75dd22dcf0d7c117cfcb03185696e6.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game5_code/ed2c8ca8023418099d1232fdc6ac09ae.txt","root":"subpackages/game5","main":"subpackages/game5/game.js"},"main":{"asset_md5":"ecadb8f2a4138a73459e04a8a0c5f470","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/main_asset/ecadb8f2a4138a73459e04a8a0c5f470.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/main_code/3b7a7f0869e5392f1e244eef40ad8abe.txt","root":"subpackages/main","main":"subpackages/main/game.js"},"103":{"asset_md5":"069620ed43643956f6b6448c5d360471","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/103_asset/069620ed43643956f6b6448c5d360471.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/103_code/64a9caf580b6cd991888751e8ea51222.txt","root":"subpackages/103","main":"subpackages/103/game.js"},"other":{"asset_md5":"473ad574dee1813610988dba22fb0acc","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/other_asset/473ad574dee1813610988dba22fb0acc.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/other_code/003784b887ff99fb82d47899798e1ee0.txt","root":"subpackages/other","main":"subpackages/other/game.js"},"resSps":{"asset_md5":"4e72c930e3c8f77bda25be975e3c8019","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/resSps_asset/4e72c930e3c8f77bda25be975e3c8019.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/resSps_code/c6ac2ebde3c8c421ca75ff649280d90b.txt","root":"subpackages/resSps","main":"subpackages/resSps/game.js"},"111":{"asset_md5":"3452f073e30ecc6b3727f072a856068b","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/111_asset/3452f073e30ecc6b3727f072a856068b.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/111_code/3ca9e57876b82945faedce2ca0ab414e.txt","root":"subpackages/111","main":"subpackages/111/game.js"},"117":{"asset_md5":"60206e41273a6a1f6d21bbf634023962","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/117_asset/60206e41273a6a1f6d21bbf634023962.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/117_code/1a85a85048eca0d650ad4b8b198cefdc.txt","root":"subpackages/117","main":"subpackages/117/game.js"},"__GAME__":{"asset_md5":"dbee9c4f704800eb5bf482be01aecadc","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/__GAME___asset/dbee9c4f704800eb5bf482be01aecadc.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/__GAME___code/b42b2a68ce373eb274eedc22351aac02.txt","root":"","main":"game.js"},"jigsaw":{"asset_md5":"4782715dda5ea0d10897d866a84bca19","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/jigsaw_asset/4782715dda5ea0d10897d866a84bca19.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/jigsaw_code/799004f65797d4620549e0d4b27e3794.txt","root":"subpackages/jigsaw","main":"subpackages/jigsaw/game.js"},"newYear":{"asset_md5":"c2cb90fbaac0b4b86d1afa7caabd2f20","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/newYear_asset/c2cb90fbaac0b4b86d1afa7caabd2f20.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/newYear_code/a7d962b4f7a95e8114fcf00bbe27b8ac.txt","root":"subpackages/newYear","main":"subpackages/newYear/game.js"},"adapter":{"asset_md5":"a44f0cd93ad08da6db427c9dc3ab6fe4","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/adapter_asset/a44f0cd93ad08da6db427c9dc3ab6fe4.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/adapter_code/6c3090ba10c12ad637aefa993fe838fc.txt","root":"subpackages/adapter","main":"subpackages/adapter/game.js"},"101":{"asset_md5":"ad3f476d334e695c01f96eef67308f26","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/101_asset/ad3f476d334e695c01f96eef67308f26.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/101_code/dcb5f8547d5285c5e116a1726dc1ecdb.txt","root":"subpackages/101","main":"subpackages/101/game.js"},"102":{"asset_md5":"8b39712d9f0ae7549382da9041cc5f56","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/102_asset/8b39712d9f0ae7549382da9041cc5f56.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/102_code/b70fb4ea0d05b866a4a32ab4cae418c4.txt","root":"subpackages/102","main":"subpackages/102/game.js"},"110":{"asset_md5":"24da51736441ceb88b3d331775004551","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/110_asset/24da51736441ceb88b3d331775004551.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/110_code/f7c97cb3aed7acb4091feaf613c56dd3.txt","root":"subpackages/110","main":"subpackages/110/game.js"},"114":{"asset_md5":"c2f81aaf93311b9302995dba105d69d0","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/114_asset/c2f81aaf93311b9302995dba105d69d0.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/114_code/7574a218fb4053e2005497d84a56132c.txt","root":"subpackages/114","main":"subpackages/114/game.js"},"practice":{"asset_md5":"01d63b100e2cfb80d2d7568d11f346f8","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/practice_asset/01d63b100e2cfb80d2d7568d11f346f8.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/practice_code/2275ac8e93d1c5dd100427aa948cd23c.txt","root":"subpackages/practice","main":"subpackages/practice/game.js"},"zh_CN":{"asset_md5":"2b1c715a0c624c630acb29b4fdfcb240","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/zh_CN_asset/2b1c715a0c624c630acb29b4fdfcb240.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/zh_CN_code/bb44d46f30e57f29d20bf0678426c7c5.txt","root":"subpackages/zh_CN","main":"subpackages/zh_CN/game.js"},"107":{"asset_md5":"652c5385223642c4a19f823666c8a682","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/107_asset/652c5385223642c4a19f823666c8a682.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/107_code/9e717b17251bdc8eefb7b8135fcb6996.txt","root":"subpackages/107","main":"subpackages/107/game.js"},"113":{"asset_md5":"f53882a23326919614b0e9031d28ed39","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/113_asset/f53882a23326919614b0e9031d28ed39.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/113_code/666bb07aea74f0a408136c0ac16a04b8.txt","root":"subpackages/113","main":"subpackages/113/game.js"},"115":{"asset_md5":"6831f12abfeccc9ff720155d9ece2d53","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/115_asset/6831f12abfeccc9ff720155d9ece2d53.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/115_code/76b85e96a57c33c8ba9ff2f316290416.txt","root":"subpackages/115","main":"subpackages/115/game.js"},"118":{"asset_md5":"f787456ee45eccc4c13f20ee21c61858","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/118_asset/f787456ee45eccc4c13f20ee21c61858.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/118_code/e595f8ed244752fe2ddc72def8452cd5.txt","root":"subpackages/118","main":"subpackages/118/game.js"},"chapter":{"asset_md5":"9c4b6cb8dc0b39bfcb275efa0c6b8493","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/chapter_asset/9c4b6cb8dc0b39bfcb275efa0c6b8493.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/chapter_code/9ee175f09ca69c65b630cfee23c0e42c.txt","root":"subpackages/chapter","main":"subpackages/chapter/game.js"},"sound":{"asset_md5":"65c37817ffc86d942d1942443b5e3fb4","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/sound_asset/65c37817ffc86d942d1942443b5e3fb4.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/sound_code/2662512b5aaa6801b6742eb661c44828.txt","root":"subpackages/sound","main":"subpackages/sound/game.js"},"105":{"asset_md5":"82c8cde04fec4456ac6bab8adaef0028","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/105_asset/82c8cde04fec4456ac6bab8adaef0028.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/105_code/74e319194a7f5a204504fc3d83131112.txt","root":"subpackages/105","main":"subpackages/105/game.js"},"109":{"asset_md5":"926ebc459e3329a4d9cda7ddf9718bf4","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/109_asset/926ebc459e3329a4d9cda7ddf9718bf4.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/109_code/19cbdc3d88a72dbd0c5eb52e89e2635a.txt","root":"subpackages/109","main":"subpackages/109/game.js"},"game2":{"asset_md5":"9f1bb086f7587aada8312315f2dd94fc","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game2_asset/9f1bb086f7587aada8312315f2dd94fc.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game2_code/49d07e848cae8eb08428bfbf225a6f30.txt","root":"subpackages/game2","main":"subpackages/game2/game.js"},"game6":{"asset_md5":"b1407de78d19f60644b53436f1791ee6","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game6_asset/b1407de78d19f60644b53436f1791ee6.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game6_code/155651953a65a663f67b95475cd5c941.txt","root":"subpackages/game6","main":"subpackages/game6/game.js"},"prefab":{"asset_md5":"4c4ba8d442bae683575460e884ddba00","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/prefab_asset/4c4ba8d442bae683575460e884ddba00.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/prefab_code/7f037cd7f3b83e90765e749d28f32e3e.txt","root":"subpackages/prefab","main":"subpackages/prefab/game.js"},"104":{"asset_md5":"160c617e3e3adef19c94f57bc4520dba","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/104_asset/160c617e3e3adef19c94f57bc4520dba.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/104_code/ef86df3a24fca9ecffc55f7c33ff3747.txt","root":"subpackages/104","main":"subpackages/104/game.js"},"106":{"asset_md5":"b22052c8f569db2f00a2ae6fcb8872e6","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/106_asset/b22052c8f569db2f00a2ae6fcb8872e6.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/106_code/f13ed6653a2ebb49703d0bc882255cfd.txt","root":"subpackages/106","main":"subpackages/106/game.js"},"game4":{"asset_md5":"b98a8892ccb76e5999cbf7a8e81c4cb5","asset_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game4_asset/b98a8892ccb76e5999cbf7a8e81c4cb5.txt","code_url":"https://minis-sbmg0cldak4bbz86dq-vpkg-1.tiktok-minis.us/game4_code/ebbcf2b74998d340cb8cf85249748992.txt","root":"subpackages/game4","main":"subpackages/game4/game.js"}}',UpdatedTime:1756716749e3,AssetType:1}}};const T={name:"project",dimension:"project"};function A(s,a){g.info("start check project");const i=function(e,s){g.info("start check project size");const{build:{pkgSizeLimit:t},dev:a}=s,i=null==a?void 0:a.enable,n=E({entryDir:e}),c=(n/1048576).toFixed(2),o=(t/1048576).toFixed(2);if(n>t){const e=`Check project size failed, size: ${c}MB, must not exceed ${o}MB`;if(g.error(e),i)return console.log("%s",e),Object.assign({passed:!1,msg:e,type:"size",size:n},T);throw new Error(e)}{const e=`Check project size successfully, size: ${c}MB`;return g.info(e),Object.assign({passed:!0,msg:e,name:"project",type:"size",size:n},T)}}(s,a),n=function(s,a){var i;g.info("start check config");const n=t.join(s,p);if(e.existsSync(n)){const e="Check game.json config successfully";return g.info(e),Object.assign({passed:!0,msg:e,file:p,type:"config"},T)}{const e="Can not find game.json in game source code, please check it";if(g.error(e),null===(i=null==a?void 0:a.dev)||void 0===i?void 0:i.enable)return console.log("%s",`❗️ ${e}`),Object.assign({passed:!1,msg:e,type:"config",file:p},T);throw new Error(e)}}(s,a),c=[i,n];return c.every(e=>e.passed)&&g.info("check project successfully"),c}const J={name:"main",dimension:"main_package"};function G(e,s){var t;const a=[];return g.info("start check main package"),a.push(function({entryDir:e,config:s}){var t;g.info("start check main package entry");const a=u.join(e,"game.js");if(!m.existsSync(a)){const e="Check main package entry failed, game.js must exist in main package!";if(g.error(e),null===(t=s.dev)||void 0===t?void 0:t.enable)return console.log("%s",e),Object.assign({passed:!1,msg:e,type:"config",file:"game.js"},J)}return g.info("check game.js successfully"),Object.assign({passed:!0,msg:"Check main package entry successfully, game.js must exist in main package!",type:"config",file:"game.js"},J)}({entryDir:e,config:s})),(null===(t=s.build)||void 0===t?void 0:t.mainPkgSizeLimit)&&a.push(function({entryDir:e,config:s}){g.info("start check main package size");const{build:t,dev:a}=s,i=C({entryDir:e}),n=(i/1048576).toFixed(2),c=(t.mainPkgSizeLimit/1048576).toFixed(2);if(i>t.mainPkgSizeLimit){const e=`Check main package size failed, main package size ${n}MB, must not exceed ${c}MB`;if(g.error(e),null==a?void 0:a.enable)return console.log("%s",`❗️ ${e}`),Object.assign({passed:!1,msg:e,size:i,type:"size"},J);throw new Error(e)}return Object.assign({passed:!0,msg:`Check main package size successfully, size: ${n}MB`,size:i,type:"size"},J)}({entryDir:e,config:s})),a.every(e=>e.passed)&&g.info("Check main package successfully"),a}const B={name:"subpackage",dimension:"subpackage"};function W(s,a){const i=[];g.info("start check subpackages in game.json");const n=function(s){var a;try{const i=t.join(s,p),n=JSON.parse(e.readFileSync(i,"utf-8"));return(null===(a=null==n?void 0:n.subpackages)||void 0===a?void 0:a.filter(e=>!e.independent))||[]}catch(e){return[]}}(s);return n.forEach(n=>{var c,o;if(n.name&&n.root)i.push(Object.assign({passed:!0,msg:`Check subpackage<${n.name}> config successfully`,type:"config",file:p},B));else{const e="Check subpackages config failed, the subpackages configuration in game.json is invalid: the root or name field in one or more subpackages is empty. Please ensure that all subpackages have non-empty root and name values.";if(g.error(e),!(null===(c=null==a?void 0:a.dev)||void 0===c?void 0:c.enable))throw new Error(e);console.log("%s",`❗️ ${e}`),i.push(Object.assign({passed:!1,msg:e,type:"config",file:p},B))}const r=t.join(s,n.root);if(e.existsSync(r))i.push(Object.assign({passed:!0,msg:`Check subpackage<${n.name}> config successfully`,type:"config",file:p},B));else{const e=`Check subpackage<${n.name}> config failed, the subpackages configuration in game.json is invalid: can not find subpackage ${n.name} entry dir, please check it`;if(g.error(e),!(null===(o=null==a?void 0:a.dev)||void 0===o?void 0:o.enable))throw new Error(e);console.log("%s",`❗️ ${e}`),i.push(Object.assign({passed:!1,msg:e,type:"config",file:p},B))}}),i.length&&i.every(e=>e.passed)&&g.info("Check subpackages config successfully"),i}const I={dimension:x};function U(s,a){var i;const n=null===(i=null==a?void 0:a.dev)||void 0===i?void 0:i.enable,c=[];g.info("start check independent subpackages in game.json");return M(s).forEach(i=>{var o;if(i.name&&i.root)c.push(Object.assign(Object.assign({},I),{passed:!0,msg:`Check independent package<${i.name}> config successfully`,type:"config",file:p,name:i.name}));else{const e="Check independent subpackages config failed, the subpackages configuration in game.json is invalid: the root or name field in one or more independent subpackages is empty. Please ensure that all independent subpackages have non-empty root and name values.";if(g.error(e),!n)throw new Error(e);console.log("%s",`❗️${e}`),c.push(Object.assign(Object.assign({},I),{passed:!1,msg:e,type:"config",file:p,name:i.name}))}const r=t.join(s,i.root);if(e.existsSync(r))c.push({passed:!0,msg:`Check independent package<${i.name}> config successfully`,type:"config",file:p,dimension:x,name:i.name});else{const e=`Check independent package<${i.name}> config failed, the subpackages configuration in game.json is invalid: can not find subpackage ${i.name} entry dir, please check it`;if(g.error(e),!n)throw new Error(e);console.log("%s",`❗️ ${e}`),c.push(Object.assign(Object.assign({},I),{passed:!1,msg:e,type:"config",file:p,name:i.name}))}const d=null===(o=null==a?void 0:a.build)||void 0===o?void 0:o.independentSubPkgSizeLimit;if(d){const e=function({entryDir:e,limit:s,pkgName:t,dimension:a}){const i=$({rootDir:e,entryDir:e,filterDirs:[]}),n=i<=s,c=i/1024/1024,o=s/1024/1024;return{passed:n,msg:n?`Check package ${t} size ${c.toFixed(2)}MB check successfully`:`Check package ${t} size ${c.toFixed(2)}MB exceeds limit ${o.toFixed(2)}MB`,type:"size",size:i,dimension:a,name:t}}({entryDir:r,pkgName:i.name,limit:d,dimension:x});if(c.push(e),g.info(e.msg),!e.passed){if(!n)throw new Error(e.msg);console.log("%s",`❗️ ${e.msg}`)}}}),c.length&&c.every(e=>e.passed)&&g.info("Check independent subpackages config successfully"),c}const Y=[{name:"login",desc:"Login to get open id"},{name:"createRewardedVideoAd",desc:"Integrate rewarded video ads"},{name:"addShortcut",desc:"Add game shortcut to home screen"},{name:"getShortcutMissionReward",desc:"Get shortcut mission reward"},{name:"startEntranceMission",desc:"Jump to TikTok personal sidebar"},{name:"getEntranceMissionReward",desc:"Get entrance mission reward"}];function V(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}async function K({entryDir:s,config:a}){g.info("开始校验项目");const i=A(s,a),n=G(s,a),c=W(s,a),o=U(s,a),r=function({entryDir:s,config:a}){var i;if(!(null===(i=null==a?void 0:a.build)||void 0===i?void 0:i.enableAPICheck))return[];const n=[".js",".ts"],c=new Map(Y.map(({name:e})=>{const s=[`\\b${V(e)}\\b`,`\\.${V(e)}\\s*\\(`,`\\b${V(e)}\\s*:\\s*`,`\\b${V(e)}\\s*=`,`\\b${V(e)}\\s*\\(`].join("|");return[e,new RegExp(s,"m")]})),o=new Map;for(const{name:e}of Y)o.set(e,new Set);const r=[s];for(;r.length;){const s=r.pop();if(e.statSync(s).isDirectory()){const a=t.basename(s);if(["node_modules",".git","dist","build","out",".cache"].includes(a))continue;const i=e.readdirSync(s);for(const e of i)r.push(t.join(s,e));continue}const a=t.extname(s).toLowerCase();if(!n.includes(a))continue;let i="";try{i=e.readFileSync(s,"utf8")}catch(e){continue}if(!(i.length>5e6))for(const{name:e}of Y)c.get(e).test(i)&&o.get(e).add(s)}return Y.map(({name:e})=>{const s=Array.from(o.get(e)||[]);return{name:e,msg:s.length>0?`${e} integrated!`:`${e} not integrated!`,passed:s.length>0,files:s,type:"api",required:!1,dimension:"project"}})}({entryDir:s,config:a});return[...i,...n,...c,...o,...r]}async function X(s,a){g.info("开始基于源代码中的 game.json 生成 packageConfig.json");const i=t.join(s,p),n=JSON.parse(e.readFileSync(i,"utf-8")),c={},o=[{value:k,label:"Main (Main package)",type:z}];c[k]={url:"",md5:"",root:"",main:"game.js",output:`${k}${h}`},function(e){if(!e||0===e.length)return[];function s(e){return String(e).replace(/^\/+|\/+$/g,"")}function a(e){return i(e)?t.join(e,"game.js").replace(/\\/g,"/"):e}function i(e){return e.endsWith("/")||!/\.[a-zA-Z0-9]+$/.test(e)}function n(e){return e.replace(/^\/+|\/+$/g,"")}return e.map(e=>{const t=s(e.name);return{main:a(e.root),root:n(e.root),name:t,independent:e.independent||!1}})}(n.subpackages).forEach(({name:e,root:s,main:t,independent:a})=>{c[e]={url:"",md5:"",root:s,main:t,output:`${e}${h}`,independent:a},a&&o.push({value:e,label:`${e} (Independent package)`,type:S})});const r={packages:c,fyf_packages:o};return e.existsSync(a)&&e.rmSync(a,{recursive:!0}),e.mkdirSync(a),e.writeFileSync(t.join(a,l),JSON.stringify(r,null,2)),g.info("基于源代码中的 game.json 生成 packageConfig.json 成功"),r}function Z(e){const s=[];return Object.values(e).forEach(e=>{Object.values(e).forEach(e=>{s.push(...e)})}),s}function H({entry:s,root:a,exts:i=[".js",".ts",".jsx",".tsx"],excludeDirs:n=[]}){let c=[];if(!e.existsSync(s))return c;const o=e.readdirSync(s,{withFileTypes:!0});for(const e of o){const o=t.join(s,e.name);if(e.isDirectory()){const e=t.relative(a,o).replace(/\\/g,"/");if(n.find(s=>s===e))continue;c=c.concat(H({entry:o,root:a,exts:i,excludeDirs:n}))}else i.some(s=>e.name.endsWith(s))&&c.push(o)}return c}function Q(s,a){const i=function(s){return e.readdirSync(s).filter(a=>{const i=t.join(s,a);return e.statSync(i).isDirectory()&&!["node_modules","dist","build","output"].includes(a)}).map(e=>e+"/")}(s),o=c.sync("**/*.js",{cwd:s,ignore:[]}),r=[];o.forEach(a=>{const c=t.join(s,a),o=e.readFileSync(c,"utf-8");let d;try{d=n.parse(o,{ecmaVersion:"latest",sourceType:"module"})}catch(e){return}ee(d,a=>{if("CallExpression"===a.type&&"Identifier"===a.callee.type&&("require"===a.callee.name||"requireAsync"===a.callee.name)&&a.arguments.length>0&&"Literal"===a.arguments[0].type&&"string"==typeof a.arguments[0].value){const n=a.arguments[0].value;let o=null;if(n.startsWith("."))o=t.resolve(t.dirname(c),n);else if(n.startsWith("/"))o=t.resolve(s,"."+n);else for(const e of i)if(n.startsWith(e)){o=t.resolve(s,n);break}o&&!function(s){if(e.existsSync(s)&&e.statSync(s).isFile())return!0;const t=[".js",".ts",".jsx",".tsx"];for(const a of t)if(e.existsSync(s+a)&&e.statSync(s+a).isFile())return!0;return!1}(o)&&(o=null),r.push({file:t.relative(s,c),callee:a.callee.name,requirePath:n,resolvedPath:o?t.relative(s,o):""})}})});const d=r.map(e=>{let s="";Object.keys(a).forEach(t=>{e.resolvedPath&&e.resolvedPath.startsWith(a[t].root)&&(s=t)});let t="";return Object.keys(a).forEach(s=>{e.file.startsWith(a[s].root)&&(t=s)}),Object.assign(Object.assign({},e),{curModule:t,depModule:s})}),m=[".js",".ts",".jsx",".tsx"];return d.reduce((e,s)=>{return e[s.curModule]||(e[s.curModule]={}),s.curModule===s.depModule||s.resolvedPath&&(t=s.resolvedPath,m.some(e=>t.endsWith(e)))&&(e[s.curModule]=Object.assign(Object.assign({},e[s.curModule]),{[s.resolvedPath]:s.depModule})),e;var t},{})}function ee(e,s){s(e);for(let t in e)if(e.hasOwnProperty(t)){const a=e[t];Array.isArray(a)?a.forEach(e=>e&&"string"==typeof e.type&&ee(e,s)):a&&"string"==typeof a.type&&ee(a,s)}}async function se({pkgRoot:s,destRoot:a,packedFiles:i,gameEntry:n,gameOutput:c,skipDirs:o=[],isRoot:r=!0}){if(!e.existsSync(s))return;const d=e.readdirSync(s,{withFileTypes:!0});for(const r of d){const d=t.join(s,r.name),m=t.join(a,r.name),u=t.join(s,r.name);if(r.isDirectory()){const e=t.relative(n,u).replace(/\\/g,"/");if(o.find(s=>s===e))continue}r.isDirectory()?se({pkgRoot:d,destRoot:m,gameOutput:c,packedFiles:i,gameEntry:n,skipDirs:o,isRoot:!1}):(b(t.dirname(m)),i.includes(t.relative(n,d).replace(/\\/g,"/"))||e.copyFileSync(d,m))}}function te(e){const s=[];return e&&s.push(...Object.values(e).map(e=>e.root)),s}async function ae({gameEntry:s,gameOutput:a,config:i}){let n=Date.now();!function(s){!function s(a){let i;try{i=e.readdirSync(a)}catch(e){return void g.warn(`无法访问目录: ${a}, ${e.message}`)}i.forEach(i=>{const n=t.join(a,i);try{const t=e.statSync(n);t.isDirectory()?D.includes(i)?(e.rmSync(n,{recursive:!0,force:!0}),g.info(`已删除无用目录: ${n}`)):s(n):t.isFile()&&F.includes(i)&&(e.rmSync(n,{force:!0}),g.info(`已删除无用文件: ${n}`))}catch(e){g.warn(`无法处理: ${n}, ${e.message}`)}})}(s)}(s),g.info(`pack start,startTime:${n}`);const{packages:c}=await X(s,a),d=Q(s,c),m=function(e,s){g.info("开始基于游戏源代码收集分包中的 JS 文件");const a={},i=Object.values(s).filter(e=>e.root&&""!==e.root).map(e=>e.root).filter(Boolean),n=Array.from(new Set(i));for(const i in s){const c=s[i];let o,r;"__GAME__"===i?(r=H({entry:e,root:e,exts:[".js",".ts",".jsx",".tsx"],excludeDirs:n}),o=e):(o=t.join(e,c.root),r=H({entry:o,root:o,exts:[".js",".ts",".jsx",".tsx"],excludeDirs:[]}));const d=[];r.forEach(s=>{d.push(t.relative(e,s).replace(/\\/g,"/"))});const m=s[i].root;a[i]={[m?`${m}/game.pack.js`:"game.pack.js"]:d}}return g.info("基于游戏源代码收集分包中的 JS 文件完成"),a}(s,c);return await async function(e,s,t){const a=[],i=[];for(const n of s){const c=Promise.resolve().then(()=>t(n));if(a.push(c),e<=s.length){const s=c.then(()=>{i.splice(i.indexOf(s),1)});i.push(s),i.length>=e&&await Promise.race(i)}}return Promise.all(a)}(10,Object.keys(m),async n=>{g.info(`开始基于游戏源代码打包,包名:${n}`);let u=Date.now();const l=c[n],p=t.join(s,l.root),k=t.join(a,n,l.root);await function({gameEntry:s,pkgName:a,allDeps:i,allMaps:n,pkgConfig:c,destRoot:d,config:m}){var u,f,l,p;let k=Date.now();g.info(`pack start,startTime:${k}`);const h=n[a],y={main:c.main,deps:i[a]||{},map:n[a]};b(d),e.writeFileSync(t.join(d,"moduleConfig.json"),JSON.stringify(y));for(const i in h){const n=h[i];if(!Array.isArray(n)||0===n.length)continue;const c=new o.Bundle({separator:"\n"});for(const a of n){const n=t.join(s,a);if(e.existsSync(n)&&t.basename(n)!==i&&/\.js$/i.test(a))try{const{code:s}=r.transformSync(e.readFileSync(n,"utf-8"),{loader:"js",format:"cjs",target:"es2015",minify:!1,charset:"utf8",keepNames:!0}),t=a.replace(/\\/g,"/"),i=`define("game:${t}", ["require", "requireAsync", "module", "exports", "sandboxGlobal"], function(require, requireAsync, module, exports, sandboxGlobal){\nwith(sandboxGlobal){\n`,d="\n}\n});\n",m=new o(s,{filename:t});m.prepend(i),m.append(d),c.addSource({content:m,filename:t})}catch(e){g.error(`pack error, relPath:${a},e:${e}`)}}const b=t.join(d,t.basename(i)),k=c.toString();if(null===(u=null==m?void 0:m.dev)||void 0===u?void 0:u.enableSourcemap){const s=c.generateMap({hires:!0,includeContent:!0,file:t.basename(i)});if(null===(f=null==m?void 0:m.dev)||void 0===f?void 0:f.inlineSourcemap){const t=k+`\n//# sourceMappingURL=data:application/json;base64,${Buffer.from(s.toString()).toString("base64")}`+`\n//# sourceURL=${i}`;e.writeFileSync(b,t,"utf-8")}else{const a=`http://${null===(l=null==m?void 0:m.dev)||void 0===l?void 0:l.host}:${null===(p=null==m?void 0:m.dev)||void 0===p?void 0:p.port}/game/files`,n=t.basename(i)+".map",c=t.join(d,n);e.writeFileSync(c,s.toString(),"utf-8");const o=k+`\n//# sourceMappingURL=${a}/${i}.map`+`\n//# sourceURL=${i}`;e.writeFileSync(b,o,"utf-8")}}else{const s=k+`\n//# sourceURL=${i}`;e.writeFileSync(b,s,"utf-8")}g.info(`pack end,packName:${a}`)}}({gameEntry:s,allDeps:d,allMaps:m,pkgName:n,pkgConfig:l,destRoot:k,config:i}),await se({gameEntry:s,gameOutput:a,pkgRoot:p,destRoot:k,packedFiles:Z(m),skipDirs:te(c)});f(t.join(a,n)),g.info(`基于游戏源代码打包分包完成,包名:${n}`),g.info(`基于游戏源代码打包分包耗时,包名:${n},耗时:${Date.now()-u}ms`)}),g.info(`pack end,duration:${Date.now()-n}ms`),{}}exports.buildOdrPkgs=async function({tempDir:s}){e.existsSync(s)&&e.rmSync(s,{recursive:!0}),e.mkdirSync(s);const a=function(){const{MinisPackagingInfoMap:e}=L;return Object.keys(e).map(s=>({id:s,packages:JSON.parse(e[s].ODRPackages)}))}();g.info("odr_games"),await R(a,s);const i={};for(const e of a){const{id:a}=e,n=t.join(s,a);i[a]=$({rootDir:s,entryDir:n,filterDirs:[]})}const n={};j.forEach(e=>{n[e]=[]});const c={};for(const o of a){const{id:a,packages:r}=o,d=i[a];if(d>v)continue;let m=null;for(const c of j){const o=t.join(s,c);e.existsSync(o)||e.mkdirSync(o);if(n[c].reduce((e,s)=>e+i[s],0)+d<=v){const i=t.join(s,a),r=t.join(o,a);e.cpSync(i,r,{recursive:!0}),n[c].push(a),m=c;break}}if(m){c[a]={tag:m,packages:{}};for(const e in r){const s=r[e];g.info(`TTMGODRConfig[gameId].packages, ${s}, ${e}`),c[a].packages[e]={root:s.root,main:s.main,asset_md5:s.asset_md5,asset_url:s.asset_url}}console.log(`finish to build ${a}`),e.rmSync(t.join(s,a),{recursive:!0})}}const o=t.join(s,"TTMG_ODR_CONFIG.json");e.writeFileSync(o,JSON.stringify(c,null,2),"utf-8"),g.info(`TTMG_ODR_CONFIG.json 已生成: ${o}`)},exports.buildPkgs=async function(s){const{entry:a,output:i,build:n}=s;let c=Date.now();g.init(i,!0),g.info("TTMG_PACK_VERSION: 0.1.6"),g.info(`pack start, startTime:${c}`);const o=N(a,s);await K({entryDir:a,config:o}),await ae({config:o,gameEntry:a,gameOutput:i}),(null==n?void 0:n.enableOdr)&&await async function(s){let a=Date.now();g.info(`makeOdrPkgs start, ${a}`);const i=t.join(s,l),n=JSON.parse(e.readFileSync(i,"utf-8")),c=n.packages;for(const a in c){const i=t.join(s,a),n=t.join(s,`${a}${y}`),o=t.join(s,`${a}${_}`);b(n),b(o),e.cpSync(i,n,{recursive:!0}),e.cpSync(i,o,{recursive:!0}),O(n),q(o),c[`${a}${y}`]=Object.assign(Object.assign({},c[a]),{code_url:"",code_md5:"",output:`${a}${y}${h}`}),c[`${a}${_}`]=Object.assign(Object.assign({},c[a]),{asset_url:"",asset_md5:"",output:`${a}${_}${h}`})}e.writeFileSync(i,JSON.stringify(n,null,2)),g.info(`makeOdrPkgs end, ${Date.now()-a}ms`)}(i),g.info(`pack end:${Date.now()-c}ms`)},exports.checkPkgs=K,exports.debugPkgs=async function(s){const{entry:a,output:i,dev:{enableLog:n}}=s;g.init(i,n);const c=N(a,s);try{const s=await K({entryDir:a,config:c});await ae({gameEntry:a,gameOutput:i,config:c}),await async function(s){g.info("mergePkgs start");const a=t.join(s,l);let i;try{i=JSON.parse(e.readFileSync(a,"utf-8"))}catch(e){return void g.error(`读取配置文件失败: ${a}, err: ${e.message}`)}const n=i.packages;if(n&&"object"==typeof n){for(const a of Object.keys(n)){const i=t.join(s,a);if(!e.existsSync(i)){g.warn(`package 目录不存在: ${i}`);continue}const n=await e.promises.readdir(i);for(const a of n){const n=t.join(i,a),c=t.join(s,a);try{const s=await e.promises.stat(n);if(s.isFile())await e.promises.copyFile(n,c),await e.promises.rm(n,{recursive:!0,force:!0});else if(s.isDirectory())await e.promises.cp(n,c,{recursive:!0}),await e.promises.rm(n,{recursive:!0,force:!0});else if(s.isSymbolicLink()){const t=e.readlinkSync(n);e.existsSync(c)&&await e.promises.rm(c,{force:!0}),await e.promises.symlink(t,c,s.isDirectory()?"dir":"file")}g.info(`合并文件/目录: ${n} -> ${c}`)}catch(e){g.error(`处理文件失败: ${n}, err: ${e.message}`)}}0===e.readdirSync(i).length&&(e.rmSync(i,{recursive:!0,force:!0}),g.info(`已删除 package 目录: ${i}`))}g.info("mergePkgs 完成")}else g.error("配置文件中 packages 字段无效, 请检查配置")}(i);const n=e.readFileSync(t.join(i,l),"utf-8");return{isSuccess:!0,packages:JSON.parse(n).packages,checkResults:s}}catch(e){return{isSuccess:!1,errorMsg:e.message}}},exports.getPkgs=async function({entryDir:e}){const s=M(e);return{size:E({entryDir:e}),packages:[{type:"main",size:C({entryDir:e}),name:k,root:""},...s.map(s=>({type:"independent",size:$({rootDir:e,entryDir:t.join(e,s.root),filterDirs:[]}),name:s.name,root:s.root}))]}},exports.writeOdrConfig=async function(e){g.info("writeOdrPackagesConfig start");const s=u.join(e,l),t=JSON.parse(m.readFileSync(s,"utf-8")),a=t.packages,i=t.odr_packages||{};for(const e in a){if(e.endsWith(y)){const s=a[e],t=e.split(y)[0];i[t]||(i[t]={}),i[t]=Object.assign(Object.assign({},i[t]),{root:s.root,code_output:s.output,code_md5:s.md5,main:s.main}),delete a[e]}if(e.endsWith(_)){const s=e.split(_)[0],t=a[e];i[s]=Object.assign(Object.assign({},i[s]),{root:t.root,asset_output:t.output,asset_md5:t.md5}),delete a[e]}}t.odr_packages=i,m.writeFileSync(s,JSON.stringify(t,null,2)),g.info("writeOdrPackagesConfig end")};
10
10
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/utils/ensureDirSync.ts","../src/utils/logger.ts","../src/utils/removeEmptyDir.ts","../src/constants/index.ts","../src/utils/getDirSizeSync.ts","../src/utils/deleteJsFilesSync.ts","../src/utils/deleteNoJsFilesSync.ts","../src/utils/removeSystemUseless.ts","../src/utils/getIndependentPackagesConfig.ts","../src/utils/getMainPkgSize.ts","../src/utils/getProjectSize.ts","../src/utils/getGameEngine.ts","../src/utils/unity/isUnityEngine.ts","../src/libs/odrPkgs/utils.ts","../src/libs/checkPkgs/checkProject.ts","../src/libs/checkPkgs/checkMainpackage.ts","../src/libs/checkPkgs/checkSubpackages.ts","../src/utils/getSubpackagesConfig.ts","../src/libs/checkPkgs/checkIndependentPackages.ts","../src/libs/checkPkgs/checkAPI.ts","../src/libs/checkPkgs/index.ts","../src/libs/makePkgs/setup.ts","../src/libs/makePkgs/collectMaps.ts","../src/libs/makePkgs/collectDeps.ts","../src/libs/makePkgs/partition.ts","../src/libs/makePkgs/index.ts","../src/utils/asyncPool.ts","../src/libs/makePkgs/pack.ts","../src/libs/odrPkgs/buildOdrPkgs.ts","../src/libs/odrPkgs/getConfigs.ts","../src/libs/buildPkgs/index.ts","../src/utils/overrideConfig.ts","../src/libs/odrPkgs/makeOdrPkgs.ts","../src/libs/debugPkgs/index.ts","../src/libs/mergePkgs/index.ts","../src/libs/getPkgs/index.ts","../src/utils/unity/getWasmBrCodePath.ts","../src/libs/odrPkgs/writeOdrConfig.ts"],"sourcesContent":["import fs from 'fs';\nexport function ensureDirSync(dir) {\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n}\n","import winston from 'winston';\nimport path from 'path';\n\nclass Logger {\n logger: winston.Logger;\n enableLog: boolean;\n output: any;\n constructor() {\n this.logger = null;\n }\n init(output: string, enableLog = true) {\n this.enableLog = enableLog;\n this.logger = winston.createLogger({\n level: 'info',\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.json(), // 输出为 JSON 格式\n ),\n transports: [\n new winston.transports.File({\n filename: path.join(output, 'pack.log'),\n }),\n new winston.transports.Console(),\n ],\n });\n }\n info(msg: string) {\n if (this.enableLog) {\n this.logger.info(msg);\n }\n }\n error(msg) {\n if (this.enableLog) {\n this.logger.error(msg);\n }\n }\n warn(msg) {\n if (this.enableLog) {\n this.logger.warn(msg);\n }\n }\n debug(msg) {\n if (this.enableLog) {\n this.logger.debug(msg);\n }\n }\n log(msg) {\n this.logger.info(msg);\n }\n setOutput(output) {\n this.output = output;\n }\n}\n\nexport const logger = new Logger();\n","import fs from 'fs';\nimport path from 'path';\n\n/**\n * 移除指定目录下所有空文件夹(递归)\n * @param {string} dir 目标目录\n * @returns {boolean} 返回当前目录是否已被删除(即是否为空)\n */\nexport function removeEmptyDir(dir) {\n if (!fs.existsSync(dir)) return false;\n if (!fs.statSync(dir).isDirectory()) return false;\n\n let isEmpty = true;\n const files = fs.readdirSync(dir);\n for (const file of files) {\n const fullPath = path.join(dir, file);\n if (fs.statSync(fullPath).isDirectory()) {\n // 递归处理子目录\n const childIsEmpty = removeEmptyDir(fullPath);\n if (!childIsEmpty) isEmpty = false;\n } else {\n // 有文件,当前目录不为空\n isEmpty = false;\n }\n }\n\n // 如果当前目录为空,删除它\n if (isEmpty) {\n fs.rmSync(dir, { recursive: true });\n return true;\n }\n return false;\n}\n\n","import type { CheckDimension } from '@typings';\nexport const GAME_PACK_CONFIG_FILE_NAME = 'packageConfig.json';\nexport const GAME_PROJECT_CONFIG_FILE_NAME = 'project.config.json';\nexport const GAME_ORIGIN_CONFIG_FILE_NAME = 'game.json';\nexport const GAME_MODULE_CONFIG_FILE_NAME = 'moduleConfig.json';\nexport const GAME_OUTPUT_CONFIG_FILE_NAME = 'output.json';\nexport const GAME_MAIN_PACKAGE_NAME = '__GAME__';\nexport const TTPKG_TAG = 'TPKG';\nexport const STTPKG_TAG = 'SPKG';\nexport const TTPKG_VERSION = 2;\nexport const ARK_KEY_LEN = 32;\nexport const ARK_INT_LEN = 4;\nexport const UNIT32_LEN = 4;\nexport const UINT16_LEN = 2;\nexport const STTPKG_VERSION = 1;\nexport const ZSTD_COMPRESS_LEVEL = 19;\nexport const ROLL_FILE_EXT = [\n '.js',\n '.json',\n '.wxml',\n '.ttml',\n '.wxss',\n '.ttss',\n];\nexport const EXT = '';\nexport const BROTLI_COMPRESS_TYPE = 1;\nexport const ZSTD_COMPRESS_TYPE = 3;\n\nexport const STTPKG_EXT = '.txt';\n\nexport const ODR_CODE_DIR_SUFFIX = '_code';\n\nexport const ODR_ASSET_DIR_SUFFIX = '_asset';\n\n// 60MB const ONE_ODR_PKG_LIMIT = 1024 * 1024;\nexport const ONE_ODR_PKG_LIMIT = 1024 * 1024 * 60;\n\nexport const AVAILABLE_ODR_TAG_LIST = [\n 'ttmg_odr_high_channel',\n 'ttmg_odr_middle_channel',\n 'ttmg_odr_normal_channel',\n];\n\nexport const PROJECT_SIZE_LIMIT = 30 * 1024 * 1024;\n\n\nexport const MAINPACKAGE_SIZE_LIMIT = 4 * 1024 * 1024;\n\n\nexport const CHECK_DIMENSION: Record<string, CheckDimension> = {\n IndependentPackage: 'independent_package',\n MainPackage: 'main_package',\n Project: 'project',\n SubPackage: 'subpackage',\n}\n\nexport const PACKAGE_TYPE = {\n IndependentPackage: 'independent_package',\n SubPackage: 'sub_package',\n MainPackage: 'main_package',\n}\n\nexport const GAME_ENGINES = {\n UNITY: 'unity',\n}","import fs from 'fs';\nimport path from 'path';\n// 递归统计目录下所有文件的大小,支持我过滤某些文件夹\nexport function getDirSizeSync({\n rootDir,\n entryDir,\n filterDirs,\n}: {\n rootDir: string;\n entryDir: string;\n filterDirs: string[];\n}) {\n let totalSize = 0;\n if (!fs.existsSync(entryDir)) return 0;\n const entries = fs.readdirSync(entryDir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(entryDir, entry.name);\n if (entry.isDirectory()) {\n /**\n * 基于 rootDir 算出 fullPath 的相对路径\n */\n const relativePath = path.relative(rootDir, fullPath).replace(/\\\\/g, '/');\n if (!filterDirs.includes(relativePath)) {\n totalSize += getDirSizeSync({\n entryDir: fullPath,\n filterDirs,\n rootDir,\n });\n }\n } else if (entry.isFile()) {\n totalSize += fs.statSync(fullPath).size;\n }\n }\n return totalSize;\n}\n","import fs from 'fs';\nimport path from 'path';\n\n/**\n * 同步删除指定目录及其子目录下所有 .js 文件\n * @param {string} dir 目标目录路径\n */\nexport function deleteJsFilesSync(dir) {\n // 读取目录内容\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // 递归处理子目录\n deleteJsFilesSync(fullPath);\n } else if (\n entry.isFile() &&\n (fullPath.endsWith('.js') || fullPath.endsWith('.js.map'))\n ) {\n try {\n fs.unlinkSync(fullPath);\n } catch (err) {}\n }\n }\n}\n","import fs from 'fs';\nimport path from 'path';\n\nexport function deleteNoJsFilesSync(dir) {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // 递归处理子目录\n deleteNoJsFilesSync(fullPath);\n } else if (\n entry.isFile() &&\n !(fullPath.endsWith('.js') || fullPath.endsWith('.js.map'))\n ) {\n try {\n fs.unlinkSync(fullPath);\n } catch (err) {}\n }\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { logger } from './logger';\n\nconst uselessDirs = ['node_modules', '__MACOSX'];\nconst uselessFiles = ['.DS_Store', 'Thumbs.db'];\n\nexport function removeSystemUseless(gameEntry: string) {\n /**\n * 递归删除目录下的无用文件夹和无用文件\n */\n function removeUselessDirs(dir: string) {\n let files: string[];\n try {\n files = fs.readdirSync(dir);\n } catch (err) {\n // 目录不可访问,跳过\n logger.warn(`无法访问目录: ${dir}, ${err.message}`);\n return;\n }\n files.forEach(file => {\n const filePath = path.join(dir, file);\n try {\n const stat = fs.statSync(filePath);\n if (stat.isDirectory()) {\n if (uselessDirs.includes(file)) {\n // 删除无用目录\n fs.rmSync(filePath, { recursive: true, force: true });\n logger.info(`已删除无用目录: ${filePath}`);\n } else {\n // 递归处理子目录\n removeUselessDirs(filePath);\n }\n } else if (stat.isFile()) {\n if (uselessFiles.includes(file)) {\n // 删除无用文件\n fs.rmSync(filePath, { force: true });\n logger.info(`已删除无用文件: ${filePath}`);\n }\n }\n } catch (err) {\n // 某个文件/目录不可访问,跳过\n logger.warn(`无法处理: ${filePath}, ${err.message}`);\n }\n });\n }\n removeUselessDirs(gameEntry);\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { GAME_ORIGIN_CONFIG_FILE_NAME } from '@constants';\n\nexport function getIndependentPackagesConfig(entryDir: string) {\n try {\n const gameOriginConfigPath = path.join(\n entryDir,\n GAME_ORIGIN_CONFIG_FILE_NAME,\n );\n const gameOriginConfig = JSON.parse(\n fs.readFileSync(gameOriginConfigPath, 'utf-8'),\n );\n return gameOriginConfig?.subpackages?.filter(sub => sub.independent) || [];\n } catch (e) {\n return [];\n }\n}\n","import { getDirSizeSync } from './getDirSizeSync';\nimport path from 'path';\nimport fs from 'fs';\nimport { GAME_ORIGIN_CONFIG_FILE_NAME } from '@constants';\n\nexport function getMainPkgSize({ entryDir }: { entryDir: string }) {\n return getDirSizeSync({\n rootDir: entryDir,\n entryDir,\n filterDirs: getSubpackagesRoots(entryDir),\n });\n}\n\nfunction getSubpackagesRoots(entryDir: string) {\n const originConfigPath = path.join(entryDir, GAME_ORIGIN_CONFIG_FILE_NAME);\n try {\n const originConfig = JSON.parse(fs.readFileSync(originConfigPath, 'utf8'));\n const roots =\n originConfig.subpackages?.map((item: { root: string }) => item.root) ||\n [];\n /**\n * 移除掉头和尾的 /\n */\n return roots.map(root => root.replace(/^\\/|\\/$/g, ''));\n } catch (e) {\n return [];\n }\n}\n","import { getDirSizeSync } from './getDirSizeSync';\n\nexport function getProjectSize({ entryDir }: { entryDir: string }) {\n return getDirSizeSync({\n rootDir: entryDir,\n entryDir,\n filterDirs: [],\n });\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { GAME_ORIGIN_CONFIG_FILE_NAME } from '../constants';\nexport function getGameEngine(gameEntry: string): 'unity' | 'cocos' | 'unknown' {\n const gameJsonConfigPath = path.join(gameEntry, GAME_ORIGIN_CONFIG_FILE_NAME);\n if (!fs.existsSync(gameJsonConfigPath)) {\n return 'unknown';\n }\n let gameJsonConfig: any;\n try {\n gameJsonConfig = JSON.parse(fs.readFileSync(gameJsonConfigPath, 'utf-8'));\n const gameEngine = gameJsonConfig?.gameEngine;\n if (!gameEngine) {\n return 'unknown';\n }\n return gameEngine;\n } catch (error) {\n return 'unknown';\n }\n}","import { getGameEngine } from '../getGameEngine';\n\nexport function isUnityEngine(gameEntry: string) {\n return getGameEngine(gameEntry) === 'unity';\n}","import { logger } from '@utils';\nimport { ODRPackages } from '@typings';\n\n// export function fetchGames(params: { size: number; offset: number }): Promise<{\n// data: Array<{\n// id: string;\n// packages: ODRPackages;\n// }>;\n// total: number;\n// }> {\n// const { size, offset } = params;\n// const url = `https://game-odr.bytedance.net/odr/api/v1/games?size=${size}&offset=${offset}`;\n// return fetch(url).then(res => res.json());\n// }\n\n// export async function fetchAllGames(): Promise<Array<{\n// id: string;\n// packages: ODRPackages;\n// }>> {\n// const size = 100;\n// let offset = 0;\n// let total = 0;\n// const games: Array<{\n// id: string;\n// packages: ODRPackages;\n// }> = [];\n// while (true) {\n// const res = await fetchGames({ size, offset });\n// games.push(...res.data);\n// total = res.total;\n// if (games.length >= total) {\n// break;\n// }\n// offset += size;\n// }\n// return games;\n// }\n\nimport fs from 'fs/promises';\nimport path from 'path';\nimport fetch from 'node-fetch';\n\nexport async function downloadAndSaveCodesAsync(\n games,\n tempDir,\n concurrency = 5, // 并发数\n) {\n // 1. 生成所有下载任务\n const tasks = [];\n\n for (const game of games) {\n const { id: gameId, packages } = game;\n const gameDir = path.join(tempDir, gameId);\n await fs.mkdir(gameDir, { recursive: true });\n\n for (const packageName in packages) {\n const packageInfo = packages[packageName];\n const { code_url } = packageInfo;\n const fileName = `${packageName}.txt`;\n const filePath = path.join(gameDir, fileName);\n\n tasks.push({\n code_url,\n filePath,\n packageName,\n });\n }\n }\n\n // 2. 用并发池执行所有任务\n await asyncPool(concurrency, tasks, async task => {\n const { code_url, filePath, packageName } = task;\n console.log(`start to download ${packageName}`);\n try {\n const res = await fetch(code_url);\n if (!res.ok)\n throw new Error(`Failed to fetch ${code_url}: ${res.statusText}`);\n const buffer = Buffer.from(await res.arrayBuffer());\n await fs.writeFile(filePath, buffer);\n console.log(`finish to download ${packageName}`);\n } catch (err) {\n console.error(`Error downloading ${packageName}:`, err);\n }\n });\n}\n\nasync function asyncPool(poolLimit, array, iteratorFn) {\n const ret = [];\n const executing = [];\n for (const item of array) {\n const p = Promise.resolve().then(() => iteratorFn(item));\n ret.push(p);\n if (poolLimit <= array.length) {\n const e = p.then(() => executing.splice(executing.indexOf(e), 1));\n executing.push(e);\n if (executing.length >= poolLimit) {\n await Promise.race(executing);\n }\n }\n }\n return Promise.all(ret);\n}\n","import path from 'path';\nimport fs from 'fs';\nimport {\n BuildConfig,\n CheckConfigResult,\n CheckSizeResult,\n CheckDimension,\n} from '@typings';\nimport {\n GAME_ORIGIN_CONFIG_FILE_NAME,\n GAME_PROJECT_CONFIG_FILE_NAME,\n CHECK_DIMENSION,\n} from '@constants';\nimport { logger, getProjectSize } from '@utils';\n\nconst defaultCheckConfig: {\n name: string;\n dimension: CheckDimension;\n} = {\n name: 'project',\n dimension: CHECK_DIMENSION.Project,\n};\nexport function checkProject(entryDir: string, config: BuildConfig) {\n logger.info('start check project');\n const checkSizeResult = checkProjectSize(entryDir, config);\n const gameJsonCheckResult = checkGameJson(entryDir, config);\n // const projectConfigCheckResult = checkProjectConfig(entryDir, config);\n const result = [\n checkSizeResult,\n gameJsonCheckResult,\n // projectConfigCheckResult,\n ];\n if (result.every(item => item.passed)) {\n logger.info('check project successfully');\n }\n return result;\n}\n\nexport function checkGameJson(\n entryDir: string,\n config: BuildConfig,\n): CheckConfigResult {\n logger.info('start check config');\n const gameJsonPath = path.join(entryDir, GAME_ORIGIN_CONFIG_FILE_NAME);\n if (!fs.existsSync(gameJsonPath)) {\n const errMsg =\n 'Can not find game.json in game source code, please check it';\n logger.error(errMsg);\n\n if (config?.dev?.enable) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n return {\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n };\n } else {\n throw new Error(errMsg);\n }\n } else {\n const msg = 'Check game.json config successfully';\n logger.info(msg);\n return {\n passed: true,\n msg,\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n type: 'config',\n ...defaultCheckConfig,\n };\n }\n}\n\n/**\n * 检查游戏大小是否超出限制\n * @param param0\n * @returns\n */\n\nexport function checkProjectSize(\n entryDir: string,\n config: BuildConfig,\n): CheckSizeResult {\n logger.info('start check project size');\n const {\n build: { pkgSizeLimit },\n dev,\n } = config;\n const enableDev = dev?.enable;\n const gameSize = getProjectSize({ entryDir });\n const gameSizeMB = (gameSize / (1024 * 1024)).toFixed(2);\n const limitMB = (pkgSizeLimit / (1024 * 1024)).toFixed(2);\n if (gameSize > pkgSizeLimit) {\n const errMsg = `Check project size failed, size: ${gameSizeMB}MB, must not exceed ${limitMB}MB`;\n logger.error(errMsg);\n if (enableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', errMsg);\n return {\n passed: false,\n msg: errMsg,\n type: 'size',\n size: gameSize,\n ...defaultCheckConfig,\n };\n } else {\n throw new Error(errMsg);\n }\n } else {\n /**\n * 游戏大小检查通过\n */\n const logMsg = `Check project size successfully, size: ${gameSizeMB}MB`;\n logger.info(logMsg);\n return {\n passed: true,\n msg: logMsg,\n name: 'project',\n type: 'size',\n size: gameSize,\n ...defaultCheckConfig,\n };\n }\n}\n\nexport function checkProjectConfig(\n entryDir: string,\n config: BuildConfig,\n): CheckConfigResult {\n const enableDev = config.dev?.enable ?? false;\n logger.info('start check project config');\n const gameJsonConfigPath = path.join(entryDir, GAME_PROJECT_CONFIG_FILE_NAME);\n if (!fs.existsSync(gameJsonConfigPath)) {\n const errMsg =\n 'Check project config failed, can not find project.config.json in game source code, please check it';\n logger.error(errMsg);\n if (enableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n return {\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_PROJECT_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n };\n } else {\n throw new Error(errMsg);\n }\n } else {\n let gameJsonConfig: any;\n try {\n gameJsonConfig = JSON.parse(fs.readFileSync(gameJsonConfigPath, 'utf-8'));\n const appid = gameJsonConfig?.appid;\n if (!appid) {\n const errMsg =\n 'Check project config failed, can not find appid in project.config.json, you should add appid(client_key) in project.config.json';\n logger.error(errMsg);\n if (enableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n return {\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_PROJECT_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n };\n } else {\n throw new Error(errMsg);\n }\n } else {\n const msg =\n 'Check project config successfully, appid in project.config.json is valid';\n logger.info(msg);\n return {\n passed: true,\n type: 'config',\n file: GAME_PROJECT_CONFIG_FILE_NAME,\n msg,\n ...defaultCheckConfig,\n };\n }\n } catch (error) {\n const errMsg =\n 'Check project config failed, project.config.json is invalid json format';\n logger.error(errMsg);\n if (enableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n return {\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_PROJECT_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n };\n } else {\n throw error;\n }\n }\n }\n}\n","import * as path from 'path';\nimport * as fs from 'fs';\nimport {\n BuildConfig,\n CheckConfigResult,\n CheckSizeResult,\n CheckDimension,\n} from '@typings';\nimport { CHECK_DIMENSION } from '@constants';\nimport { logger, getMainPkgSize, isUnityEngine } from '@utils';\nconst defaultCheckConfig: {\n name: string;\n dimension: CheckDimension;\n} = {\n name: 'main',\n dimension: CHECK_DIMENSION.MainPackage,\n};\n/**\n * 检查主包大小是否超出限制\n * @param param0\n * @returns\n */\nexport function checkMainPackageSize({\n entryDir,\n config,\n}: {\n entryDir: string;\n config: BuildConfig;\n}): CheckSizeResult {\n logger.info('start check main package size');\n const { build, dev } = config;\n const mainPkgSize = getMainPkgSize({ entryDir });\n const mainPkgSizeMB = (mainPkgSize / (1024 * 1024)).toFixed(2);\n const limitMB = (build.mainPkgSizeLimit / (1024 * 1024)).toFixed(2);\n if (mainPkgSize > build.mainPkgSizeLimit) {\n const errMsg = `Check main package size failed, main package size ${mainPkgSizeMB}MB, must not exceed ${limitMB}MB`;\n logger.error(errMsg);\n if (dev?.enable) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n return {\n passed: false,\n msg: errMsg,\n size: mainPkgSize,\n type: 'size',\n ...defaultCheckConfig,\n };\n } else {\n throw new Error(errMsg);\n }\n } else {\n return {\n passed: true,\n msg: `Check main package size successfully, size: ${mainPkgSizeMB}MB`,\n size: mainPkgSize,\n type: 'size',\n ...defaultCheckConfig,\n };\n }\n}\n\nexport function checkMainPackageEntry({\n entryDir,\n config,\n}: {\n entryDir: string;\n config: BuildConfig;\n}): CheckConfigResult {\n logger.info('start check main package entry');\n const gameJsPath = path.join(entryDir, 'game.js');\n if (!fs.existsSync(gameJsPath)) {\n const errMsg =\n 'Check main package entry failed, game.js must exist in main package!';\n logger.error(errMsg);\n if (config.dev?.enable) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', errMsg);\n return {\n passed: false,\n msg: errMsg,\n type: 'config',\n file: 'game.js',\n ...defaultCheckConfig,\n };\n }\n }\n logger.info('check game.js successfully');\n return {\n passed: true,\n msg: 'Check main package entry successfully, game.js must exist in main package!',\n type: 'config',\n file: 'game.js',\n ...defaultCheckConfig,\n };\n}\n\nexport function checkMainPackage(\n entryDir: string,\n config: BuildConfig,\n): (CheckConfigResult | CheckSizeResult)[] {\n const checkResults = [];\n\n logger.info('start check main package');\n\n /**\n * 检查 game.js 是否存在\n */\n\n checkResults.push(\n checkMainPackageEntry({\n entryDir,\n config,\n }),\n );\n\n /**\n * 检查主包大小是否超出限制, 仅对非unity工程生效\n */\n if (!isUnityEngine(entryDir) && config.build?.mainPkgSizeLimit) {\n checkResults.push(\n checkMainPackageSize({\n entryDir,\n config,\n }),\n );\n }\n if (checkResults.every(item => item.passed)) {\n logger.info('Check main package successfully');\n }\n return checkResults;\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { logger, getSubpackagesConfig } from '@utils';\nimport { GAME_ORIGIN_CONFIG_FILE_NAME } from '@constants';\nimport {\n CheckConfigResult,\n CheckSizeResult,\n BuildConfig,\n CheckDimension,\n} from '@typings';\n\nconst defaultCheckConfig: {\n name: string;\n dimension: CheckDimension;\n} = {\n name: 'subpackage',\n dimension: 'subpackage',\n};\n\nexport function checkSubpackages(\n entryDir: string,\n config?: BuildConfig,\n): (CheckConfigResult | CheckSizeResult)[] {\n const checkResults: (CheckConfigResult | CheckSizeResult)[] = [];\n /**\n * 校验 subpackage 大小\n * 开始校验 subpackages 配置是否有效\n */\n logger.info('start check subpackages in game.json');\n const subpackages = getSubpackagesConfig(entryDir);\n subpackages.forEach(sub => {\n /**\n * 校验 subpackage 配置是否为空\n */\n if (!sub.name || !sub.root) {\n const errMsg =\n 'Check subpackages config failed, the subpackages configuration in game.json is invalid: the root or name field in one or more subpackages is empty. Please ensure that all subpackages have non-empty root and name values.';\n logger.error(errMsg);\n if (config?.dev?.enable) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n checkResults.push({\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n });\n } else {\n throw new Error(errMsg);\n }\n } else {\n checkResults.push({\n passed: true,\n msg: `Check subpackage<${sub.name}> config successfully`,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n });\n }\n /**\n * 校验 subpackage 配置是否有效\n */\n const subpackageEntryDir = path.join(entryDir, sub.root);\n // 检查是文件或者文件夹是否存在\n if (!fs.existsSync(subpackageEntryDir)) {\n const errMsg = `Check subpackage<${sub.name}> config failed, the subpackages configuration in game.json is invalid: can not find subpackage ${sub.name} entry dir, please check it`;\n logger.error(errMsg);\n if (config?.dev?.enable) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n checkResults.push({\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n });\n } else {\n throw new Error(errMsg);\n }\n } else {\n checkResults.push({\n passed: true,\n msg: `Check subpackage<${sub.name}> config successfully`,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n });\n }\n });\n if (checkResults.length && checkResults.every(item => item.passed)) {\n logger.info('Check subpackages config successfully');\n }\n return checkResults;\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { GAME_ORIGIN_CONFIG_FILE_NAME } from '@constants';\n\nexport function getSubpackagesConfig(entryDir: string) {\n try {\n const gameOriginConfigPath = path.join(\n entryDir,\n GAME_ORIGIN_CONFIG_FILE_NAME,\n );\n const gameOriginConfig = JSON.parse(\n fs.readFileSync(gameOriginConfigPath, 'utf-8'),\n );\n return gameOriginConfig?.subpackages?.filter(sub => !sub.independent) || [];\n } catch (e) {\n return [];\n }\n}\n","import path from 'path';\nimport fs from 'fs';\nimport {\n logger,\n getIndependentPackagesConfig,\n getDirSizeSync,\n isUnityEngine,\n} from '@utils';\nimport {\n BuildConfig,\n CheckConfigResult,\n CheckDimension,\n CheckSizeResult,\n} from '@typings';\nimport {\n GAME_ORIGIN_CONFIG_FILE_NAME,\n CHECK_DIMENSION,\n} from '@constants';\n\nconst defaultCheckConfig: {\n dimension: CheckDimension;\n} = {\n dimension: CHECK_DIMENSION.IndependentPackage,\n};\nexport function checkIndependentPackages(\n entryDir: string,\n config?: BuildConfig,\n) {\n const isEnableDev = config?.dev?.enable;\n const checkResults: (CheckConfigResult | CheckSizeResult)[] = [];\n /**\n * 开始校验 subpackages 配置是否有效\n */\n logger.info('start check independent subpackages in game.json');\n const independentSubpackages = getIndependentPackagesConfig(entryDir);\n independentSubpackages.forEach(sub => {\n /**\n * 校验 independent subpackage 配置是否为空\n */\n if (!sub.name || !sub.root) {\n const errMsg =\n 'Check independent subpackages config failed, the subpackages configuration in game.json is invalid: the root or name field in one or more independent subpackages is empty. Please ensure that all independent subpackages have non-empty root and name values.';\n logger.error(errMsg);\n if (isEnableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️${errMsg}`);\n checkResults.push({\n ...defaultCheckConfig,\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n name: sub.name,\n });\n } else {\n throw new Error(errMsg);\n }\n } else {\n checkResults.push({\n ...defaultCheckConfig,\n passed: true,\n msg: `Check independent package<${sub.name}> config successfully`,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n name: sub.name,\n });\n }\n /**\n * 校验 independent subpackage 配置是否有效\n */\n const subpackageEntryDir = path.join(entryDir, sub.root);\n\n // 检查是文件或者文件夹是否存在\n if (!fs.existsSync(subpackageEntryDir)) {\n const errMsg = `Check independent package<${sub.name}> config failed, the subpackages configuration in game.json is invalid: can not find subpackage ${sub.name} entry dir, please check it`;\n logger.error(errMsg);\n if (isEnableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n checkResults.push({\n ...defaultCheckConfig,\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n name: sub.name,\n });\n } else {\n throw new Error(errMsg);\n }\n } else {\n checkResults.push({\n passed: true,\n msg: `Check independent package<${sub.name}> config successfully`,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n dimension: CHECK_DIMENSION.IndependentPackage,\n name: sub.name,\n });\n }\n /**\n * 校验 independent subpackage 包大小,不做校验\n */\n const independentSubPkgSizeLimit =\n config?.build?.independentSubPkgSizeLimit;\n if (!isUnityEngine(entryDir) && independentSubPkgSizeLimit) {\n const checkSizeResult = checkPkgSize({\n entryDir: subpackageEntryDir,\n pkgName: sub.name,\n limit: independentSubPkgSizeLimit,\n dimension: CHECK_DIMENSION.IndependentPackage,\n });\n checkResults.push(checkSizeResult);\n logger.info(checkSizeResult.msg);\n if (!checkSizeResult.passed) {\n if (isEnableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${checkSizeResult.msg}`);\n } else {\n throw new Error(checkSizeResult.msg);\n }\n }\n }\n });\n if (checkResults.length && checkResults.every(item => item.passed)) {\n logger.info('Check independent subpackages config successfully');\n }\n return checkResults;\n}\n\nexport function checkPkgSize({\n entryDir,\n limit,\n pkgName,\n dimension,\n}: {\n entryDir: string;\n limit: number;\n pkgName: string;\n dimension: CheckSizeResult['dimension'];\n}): CheckSizeResult {\n const size = getDirSizeSync({\n rootDir: entryDir,\n entryDir,\n filterDirs: [],\n });\n const passed = size <= limit;\n const sizeMB = size / 1024 / 1024;\n const limitMB = limit / 1024 / 1024;\n return {\n passed,\n msg: passed\n ? `Check package ${pkgName} size ${sizeMB.toFixed(2)}MB check successfully`\n : `Check package ${pkgName} size ${sizeMB.toFixed(2)}MB exceeds limit ${limitMB.toFixed(2)}MB`,\n type: 'size',\n size,\n dimension,\n name: pkgName,\n };\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { CheckAPIResult, BuildConfig } from '@typings';\n\n/**\n * 检查游戏产物中是否调用了指定的 API\n */\n\nconst API_LIST: {\n name: string;\n desc: string;\n}[] = [\n {\n name: 'login',\n desc: 'Login to get open id',\n },\n {\n name: 'createRewardedVideoAd',\n desc: 'Integrate rewarded video ads',\n },\n \n {\n name: 'addShortcut',\n desc: 'Add game shortcut to home screen',\n },\n {\n name: \"getShortcutMissionReward\",\n desc: \"Get shortcut mission reward\"\n },\n {\n name: 'startEntranceMission',\n desc: 'Jump to TikTok personal sidebar',\n },\n {\n name: \"getEntranceMissionReward\",\n desc: \"Get entrance mission reward\"\n }\n];\n\ntype CheckResult = Array<CheckAPIResult>;\n\nexport function checkAPI({\n entryDir,\n config,\n}: {\n entryDir: string;\n config: BuildConfig;\n}): CheckResult {\n if (!config?.build?.enableAPICheck) {\n return [];\n }\n const exts = ['.js', '.ts'];\n // 预编译正则,尽量减少误报:匹配独立的标识符或对象调用形式\n // 例如:\\b(login)\\b 或 \\.login\\s*\\( 或 =\\s*login\\b\n const apiRegexMap = new Map<string, RegExp>(\n API_LIST.map(({ name }) => {\n // 组合模式:独立词边界 或 点调用 或 解构/赋值场景\n const pattern = [\n `\\\\b${escapeRegex(name)}\\\\b`, // 独立标识符\n `\\\\.${escapeRegex(name)}\\\\s*\\\\(`, // 对象.方法(\n `\\\\b${escapeRegex(name)}\\\\s*:\\\\s*`, // 对象字面量属性\n `\\\\b${escapeRegex(name)}\\\\s*=`, // 赋值给该名\n `\\\\b${escapeRegex(name)}\\\\s*\\\\(`, // 直接函数调用\n ].join('|');\n return [name, new RegExp(pattern, 'm')];\n }),\n );\n\n // 结果初始化\n const hitFilesMap = new Map<string, Set<string>>();\n for (const { name } of API_LIST) {\n hitFilesMap.set(name, new Set());\n }\n\n // 深度优先遍历\n const stack: string[] = [entryDir];\n while (stack.length) {\n const current = stack.pop()!;\n const stat = fs.statSync(current);\n\n if (stat.isDirectory()) {\n // 可根据需要排除目录\n const base = path.basename(current);\n if (\n ['node_modules', '.git', 'dist', 'build', 'out', '.cache'].includes(\n base,\n )\n ) {\n continue;\n }\n const children = fs.readdirSync(current);\n for (const child of children) {\n stack.push(path.join(current, child));\n }\n continue;\n }\n\n // 文件:后缀过滤\n const ext = path.extname(current).toLowerCase();\n if (!exts.includes(ext)) {\n continue;\n }\n\n // 读取文本\n let content = '';\n try {\n content = fs.readFileSync(current, 'utf8');\n } catch {\n // 读取失败则跳过\n continue;\n }\n\n // 粗略跳过很大的文件,避免性能问题(可调)\n if (content.length > 5_000_000) continue;\n\n // 检测每个 API\n for (const { name } of API_LIST) {\n const reg = apiRegexMap.get(name)!;\n if (reg.test(content)) {\n hitFilesMap.get(name)!.add(current);\n }\n }\n }\n\n const results: CheckResult = API_LIST.map(({ name }) => {\n const files = Array.from(hitFilesMap.get(name) || []);\n return {\n name,\n msg: `${files.length > 0 ? `${name} integrated!` : `${name} not integrated!`}`,\n passed: files.length > 0,\n files,\n type: 'api',\n required: false,\n dimension: 'project',\n };\n });\n return results;\n}\n\n/**\n * 转义正则特殊字符\n */\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","import { logger } from '@utils';\nimport { BuildConfig, CheckResult } from '@typings';\nimport { checkProject } from './checkProject';\nimport { checkMainPackage } from './checkMainpackage';\nimport { checkSubpackages } from './checkSubpackages';\nimport { checkIndependentPackages } from './checkIndependentPackages';\n\nimport { checkAPI } from './checkAPI';\n\nexport async function checkPkgs({\n entryDir,\n config,\n}: {\n entryDir: string;\n config: BuildConfig;\n}): Promise<CheckResult[]> {\n logger.info('开始校验项目');\n /**\n * 1. 校验项目\n */\n const projectCheckResult = checkProject(entryDir, config);\n /**\n * 2. 校验主包\n */\n const mainPackageCheckResult = checkMainPackage(entryDir, config);\n /**\n * 3. 如果有,校验分包\n */\n const subpackagesCheckResult = checkSubpackages(entryDir, config);\n\n /**\n * 校验独立分包\n */\n const independentPackagesCheckResult = checkIndependentPackages(\n entryDir,\n config,\n );\n\n /**\n * 校验 API 调用\n */\n const apiCheckResult = checkAPI({ entryDir, config });\n\n return [\n ...projectCheckResult,\n ...mainPackageCheckResult,\n ...subpackagesCheckResult,\n ...independentPackagesCheckResult,\n ...apiCheckResult,\n ];\n}\n","import fs from 'fs';\nimport path from 'path';\nimport {\n GAME_PACK_CONFIG_FILE_NAME,\n GAME_ORIGIN_CONFIG_FILE_NAME,\n GAME_MAIN_PACKAGE_NAME,\n STTPKG_EXT,\n PACKAGE_TYPE,\n} from '@constants';\n\nimport { logger } from '@utils';\n\nexport async function setup(entryDir: string, outputDir: string) {\n logger.info('开始基于源代码中的 game.json 生成 packageConfig.json');\n const gameJsonPath = path.join(entryDir, GAME_ORIGIN_CONFIG_FILE_NAME);\n const gameJson = JSON.parse(fs.readFileSync(gameJsonPath, 'utf-8'));\n\n const packages = {};\n // fyf for your feed 缩写,代表可用于视频锚点投放使用的包\n const fyfPackages = [\n {\n value: GAME_MAIN_PACKAGE_NAME,\n label: 'Main (Main package)',\n type: PACKAGE_TYPE.MainPackage,\n },\n ];\n\n // 主包\n packages[GAME_MAIN_PACKAGE_NAME] = {\n url: '',\n md5: '',\n root: '',\n main: 'game.js',\n output: `${GAME_MAIN_PACKAGE_NAME}${STTPKG_EXT}`,\n };\n\n transformSubPackages(gameJson.subpackages).forEach(\n ({ name, root, main, independent }) => {\n // root 是目录\n packages[name] = {\n url: '',\n md5: '',\n root,\n main,\n output: `${name}${STTPKG_EXT}`,\n independent,\n };\n if (independent) {\n fyfPackages.push({\n value: name,\n label: `${name} (Independent package)`,\n type: PACKAGE_TYPE.IndependentPackage,\n });\n }\n },\n );\n\n const result = {\n packages,\n fyf_packages: fyfPackages,\n };\n if (fs.existsSync(outputDir)) {\n fs.rmSync(outputDir, { recursive: true });\n }\n fs.mkdirSync(outputDir);\n fs.writeFileSync(\n path.join(outputDir, GAME_PACK_CONFIG_FILE_NAME),\n JSON.stringify(result, null, 2),\n );\n logger.info('基于源代码中的 game.json 生成 packageConfig.json 成功');\n return result;\n}\n\nfunction transformSubPackages(\n configs: Array<{\n name: string;\n root: string;\n independent?: boolean;\n }>,\n) {\n if (!configs || configs.length === 0) {\n return [];\n }\n function normalizeName(name) {\n return String(name).replace(/^\\/+|\\/+$/g, '');\n }\n\n function getMainFromRoot(root: string) {\n if (isDirectory(root)) {\n // 将 Windows 下的 \\\\ 替换为 /\n return path.join(root, 'game.js').replace(/\\\\/g, '/');\n }\n return root;\n }\n\n function isDirectory(str) {\n // 以 / 结尾,或没有 .js 结尾且没有 . 号\n return str.endsWith('/') || !/\\.[a-zA-Z0-9]+$/.test(str);\n }\n\n function normalizeRoot(root: string): string {\n // 去掉头部和尾部的所有斜杠\n return root.replace(/^\\/+|\\/+$/g, '');\n }\n\n return configs.map(config => {\n const name = normalizeName(config.name);\n let main = getMainFromRoot(config.root);\n // test\n let root = normalizeRoot(config.root);\n return { main, root, name, independent: config.independent || false };\n });\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { logger } from '@utils';\n\nexport function flattenMaps(allMaps) {\n const list = [];\n Object.values(allMaps).forEach(map => {\n Object.values(map).forEach(arr => {\n list.push(...arr);\n });\n });\n return list;\n}\n// 递归收集 JS 文件,但可排除指定目录\nfunction collectPkgJsFiles({\n entry,\n root,\n exts = ['.js', '.ts', '.jsx', '.tsx'],\n excludeDirs = [],\n}: {\n entry: string;\n root: string;\n exts: string[];\n excludeDirs: string[];\n}) {\n let files = [];\n if (!fs.existsSync(entry)) return files;\n const entries = fs.readdirSync(entry, { withFileTypes: true });\n for (const item of entries) {\n const fullPath = path.join(entry, item.name);\n if (item.isDirectory()) {\n /**\n * 计算 item 与 root 的相对路径\n */\n /**\n * 讲 \\ 替换为 /\n */\n const relativePath = path.relative(root, fullPath).replace(/\\\\/g, '/');\n if (excludeDirs.find(dir => dir === relativePath)) {\n continue; // 跳过排除目录\n }\n files = files.concat(\n collectPkgJsFiles({\n entry: fullPath,\n root: root,\n exts: exts,\n excludeDirs,\n }),\n ); // 只排除一级\n } else if (exts.some(ext => item.name.endsWith(ext))) {\n files.push(fullPath);\n }\n }\n return files;\n}\n\n// 构建每个包的 map\nexport function collectMaps(\n entryDir,\n packages: Record<string, { root: string }>,\n) {\n logger.info('开始基于游戏源代码收集分包中的 JS 文件');\n const result = {};\n // 1. 先收集所有分包根目录名(如 subpackages/level1、subpackages/level2)\n const subRoots = Object.values(packages)\n .filter(pkg => pkg.root && pkg.root !== '')\n .map(pkg => pkg.root) // 只提取一级目录名\n .filter(Boolean);\n const uniqueSubRoots = Array.from(new Set(subRoots));\n\n for (const pkgName in packages) {\n const pkg = packages[pkgName];\n let srcRoot;\n let jsFiles;\n if (pkgName === '__GAME__') {\n // 主包:只收集 entryDir 下非分包目录\n jsFiles = collectPkgJsFiles({\n entry: entryDir,\n root: entryDir,\n exts: ['.js', '.ts', '.jsx', '.tsx'],\n excludeDirs: uniqueSubRoots,\n });\n srcRoot = entryDir;\n } else {\n // 分包:只收集自己目录\n srcRoot = path.join(entryDir, pkg.root);\n jsFiles = collectPkgJsFiles({\n entry: srcRoot,\n root: srcRoot,\n exts: ['.js', '.ts', '.jsx', '.tsx'],\n excludeDirs: [],\n });\n }\n // 以包的 srcRoot 为基准生成相对路径\n const list = [];\n jsFiles.forEach(absPath => {\n list.push(path.relative(entryDir, absPath).replace(/\\\\/g, '/'));\n });\n const packNameRoot = packages[pkgName].root;\n result[pkgName] = {\n [packNameRoot ? `${packNameRoot}/game.pack.js` : 'game.pack.js']: list,\n };\n }\n logger.info('基于游戏源代码收集分包中的 JS 文件完成');\n return result;\n}\n","import fs from 'fs';\nimport path from 'path';\nimport acorn from 'acorn';\nimport glob from 'glob';\n\nexport function collectDeps(gameEntry, packages) {\n // 自动扫描 game 目录下的一级文件夹作为根前缀\n const rootPrefixes = getRootPrefixes(gameEntry);\n\n // 查找所有 JS 文件\n const files = glob.sync('**/*.js', {\n cwd: gameEntry,\n ignore: [],\n });\n\n const requireCalls = [];\n\n files.forEach(file => {\n const fullPath = path.join(gameEntry, file);\n const code = fs.readFileSync(fullPath, 'utf-8');\n\n let ast;\n try {\n ast = acorn.parse(code, { ecmaVersion: 'latest', sourceType: 'module' });\n } catch (e) {\n // 跳过无法解析的文件\n return;\n }\n\n walkAst(ast, node => {\n // require('xxx') 或 requireAsync('xxx')\n if (\n node.type === 'CallExpression' &&\n node.callee.type === 'Identifier' &&\n (node.callee.name === 'require' ||\n node.callee.name === 'requireAsync') &&\n node.arguments.length > 0 &&\n node.arguments[0].type === 'Literal' &&\n typeof node.arguments[0].value === 'string'\n ) {\n const requirePath = node.arguments[0].value;\n let resolvedPath = null;\n\n if (requirePath.startsWith('.')) {\n resolvedPath = path.resolve(path.dirname(fullPath), requirePath);\n } else if (requirePath.startsWith('/')) {\n resolvedPath = path.resolve(gameEntry, '.' + requirePath);\n } else {\n for (const prefix of rootPrefixes) {\n if (requirePath.startsWith(prefix)) {\n resolvedPath = path.resolve(gameEntry, requirePath);\n break;\n }\n }\n }\n\n // 校验文件是否存在(支持 .js/.ts/.jsx/.tsx 后缀自动补全)\n if (resolvedPath && !fileExistsWithExtensions(resolvedPath)) {\n resolvedPath = null;\n }\n\n requireCalls.push({\n file: path.relative(gameEntry, fullPath),\n callee: node.callee.name,\n requirePath,\n resolvedPath: resolvedPath\n ? path.relative(gameEntry, resolvedPath)\n : '',\n });\n }\n });\n });\n\n const newRequireCalls = requireCalls.map(i => {\n /**\n * 基于 packages 来判断\n */\n let depModule = '';\n Object.keys(packages).forEach(pkg => {\n if (i.resolvedPath && i.resolvedPath.startsWith(packages[pkg].root)) {\n depModule = pkg;\n }\n });\n\n let curModule = '';\n Object.keys(packages).forEach(pkg => {\n if (i.file.startsWith(packages[pkg].root)) {\n curModule = pkg;\n }\n });\n return {\n ...i,\n curModule,\n depModule,\n };\n });\n\n // 只统计 JS/TS/JSX/TSX 文件依赖\n const exts = ['.js', '.ts', '.jsx', '.tsx'];\n const isJsLike = f => exts.some(ext => f.endsWith(ext));\n\n const result = newRequireCalls.reduce((acc, cur) => {\n if (!acc[cur.curModule]) {\n acc[cur.curModule] = {};\n }\n if (cur.curModule === cur.depModule) {\n return acc;\n }\n if (cur.resolvedPath && isJsLike(cur.resolvedPath)) {\n acc[cur.curModule] = {\n ...acc[cur.curModule],\n [cur.resolvedPath]: cur.depModule,\n };\n }\n return acc;\n }, {});\n return result;\n}\n\nfunction getRootPrefixes(gameEntry) {\n return fs\n .readdirSync(gameEntry)\n .filter(name => {\n const fullPath = path.join(gameEntry, name);\n return (\n fs.statSync(fullPath).isDirectory() &&\n !['node_modules', 'dist', 'build', 'output'].includes(name)\n );\n })\n .map(name => name + '/');\n}\n\nfunction walkAst(node, cb) {\n cb(node);\n for (let key in node) {\n if (node.hasOwnProperty(key)) {\n const child = node[key];\n if (Array.isArray(child)) {\n child.forEach(c => c && typeof c.type === 'string' && walkAst(c, cb));\n } else if (child && typeof child.type === 'string') {\n walkAst(child, cb);\n }\n }\n }\n}\n\n// 支持 .js/.ts/.jsx/.tsx 自动补全\nfunction fileExistsWithExtensions(filePath) {\n if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) return true;\n const exts = ['.js', '.ts', '.jsx', '.tsx'];\n for (const ext of exts) {\n if (fs.existsSync(filePath + ext) && fs.statSync(filePath + ext).isFile())\n return true;\n }\n return false;\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { ensureDirSync } from '@utils';\n\nexport async function partition({\n pkgRoot,\n destRoot,\n packedFiles,\n gameEntry,\n gameOutput,\n skipDirs = [],\n isRoot = true,\n}) {\n if (!fs.existsSync(pkgRoot)) return;\n const entries = fs.readdirSync(pkgRoot, { withFileTypes: true });\n for (const entry of entries) {\n const srcPath = path.join(pkgRoot, entry.name);\n const destPath = path.join(destRoot, entry.name);\n const fullPath = path.join(pkgRoot, entry.name);\n // 只在第一层判断是否跳过分包目录\n if (entry.isDirectory()) {\n const relativePath = path.relative(gameEntry, fullPath).replace(/\\\\/g, '/');\n if (skipDirs.find(dir => dir === relativePath)) {\n continue; // 跳过分包目录\n }\n }\n if (entry.isDirectory()) {\n partition({\n pkgRoot: srcPath,\n destRoot: destPath,\n gameOutput,\n packedFiles,\n gameEntry,\n skipDirs,\n isRoot: false, // 递归下去不再判断\n });\n } else {\n ensureDirSync(path.dirname(destPath));\n if (!packedFiles.includes(path.relative(gameEntry, srcPath).replace(/\\\\/g, '/'))) {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n }\n}\n","import path from 'path';\nimport { BuildConfig, ProjectConfig } from '@typings';\nimport { logger, removeEmptyDir, removeSystemUseless, asyncPool } from '@utils';\nimport { setup } from './setup';\nimport { flattenMaps, collectMaps } from './collectMaps';\nimport { collectDeps } from './collectDeps';\nimport { pack } from './pack';\nimport { partition } from './partition';\n\nfunction getSkipDirs(packages: ProjectConfig['packages']\n) {\n const skipDirs = [];\n if (packages) {\n skipDirs.push(...Object.values(packages).map(item => item.root));\n }\n return skipDirs;\n}\n\nexport async function makePkgs({\n gameEntry,\n gameOutput,\n config,\n}: {\n gameEntry: string;\n gameOutput: string;\n config: BuildConfig;\n}) {\n let startTime = Date.now();\n removeSystemUseless(gameEntry);\n logger.info(`pack start,startTime:${startTime}`);\n const { packages } = await setup(gameEntry, gameOutput);\n const allDeps = collectDeps(gameEntry, packages);\n const allMaps = collectMaps(gameEntry, packages);\n const pkgOutput = {};\n\n /**\n * 基于 asyncPool 并发打包\n */\n\n await asyncPool(10, Object.keys(allMaps), async pkgName => {\n logger.info(`开始基于游戏源代码打包,包名:${pkgName}`);\n let startTime = Date.now();\n const pkgConfig = packages[pkgName];\n const pkgRoot = path.join(gameEntry, pkgConfig.root);\n const destRoot = path.join(gameOutput, pkgName, pkgConfig.root);\n /**\n * 打包\n */\n await pack({\n gameEntry,\n allDeps,\n allMaps,\n pkgName,\n pkgConfig,\n destRoot,\n config,\n });\n\n /**\n * 分包\n */\n await partition({\n gameEntry,\n gameOutput,\n pkgRoot,\n destRoot,\n packedFiles: flattenMaps(allMaps),\n // 这里写的不对,应该是 每一个分包都要跳过\n skipDirs: getSkipDirs(packages),\n });\n\n const pkgRootDir = path.join(gameOutput, pkgName);\n removeEmptyDir(pkgRootDir);\n logger.info(`基于游戏源代码打包分包完成,包名:${pkgName}`);\n logger.info(\n `基于游戏源代码打包分包耗时,包名:${pkgName},耗时:${Date.now() - startTime\n }ms`,\n );\n });\n\n\n logger.info(`pack end,duration:${Date.now() - startTime}ms`);\n\n return pkgOutput;\n}\n","export async function asyncPool<T, R>(\n poolLimit: number,\n array: T[],\n iteratorFn: (item: T) => Promise<R>,\n): Promise<R[]> {\n const ret: Promise<R>[] = [];\n const executing: Promise<void>[] = [];\n for (const item of array) {\n // 创建处理当前 item 的 Promise\n const p = Promise.resolve().then(() => iteratorFn(item));\n ret.push(p);\n\n if (poolLimit <= array.length) {\n // 包装 Promise,处理完成后从 executing 中移除\n const e = p.then(() => {\n executing.splice(executing.indexOf(e), 1);\n });\n executing.push(e);\n\n // 达到并发限制时,等待任意一个任务完成\n if (executing.length >= poolLimit) {\n await Promise.race(executing);\n }\n }\n }\n // 等待所有任务完成\n return Promise.all(ret);\n}\n","import fs from 'fs';\nimport path from 'path';\nimport MagicString, { Bundle } from 'magic-string';\nimport { transformSync } from 'esbuild'\nimport { GAME_MODULE_CONFIG_FILE_NAME } from '@constants';\nimport { BuildConfig } from '@typings';\nimport { logger, ensureDirSync } from '@utils';\n\nexport function pack({\n gameEntry,\n pkgName,\n allDeps,\n allMaps,\n pkgConfig,\n destRoot,\n config,\n}: {\n gameEntry: string;\n pkgName: string;\n allDeps: Record<string, string[]>;\n allMaps: Record<string, Record<string, string[]>>;\n pkgConfig: {\n main: string;\n root: string;\n };\n destRoot: string;\n config: BuildConfig;\n}) {\n let startTime = Date.now();\n logger.info(`pack start,startTime:${startTime}`);\n const packMap = allMaps[pkgName];\n const moduleConfig = {\n main: pkgConfig.main,\n deps: allDeps[pkgName] || {},\n map: allMaps[pkgName],\n };\n\n ensureDirSync(destRoot);\n fs.writeFileSync(\n path.join(destRoot, GAME_MODULE_CONFIG_FILE_NAME),\n JSON.stringify(moduleConfig),\n );\n\n for (const packFileName in packMap) {\n const relPaths = packMap[packFileName];\n if (!Array.isArray(relPaths) || relPaths.length === 0) continue;\n\n const concat = new Bundle({ separator: '\\n' });\n for (const relPath of relPaths) {\n const absPath = path.join(gameEntry, relPath);\n if (!fs.existsSync(absPath)) continue;\n if (path.basename(absPath) === packFileName) continue;\n\n if (/\\.js$/i.test(relPath)) {\n try {\n const { code } = transformSync(fs.readFileSync(absPath, 'utf-8'), {\n loader: 'js',\n format: 'cjs',\n target: 'es2015',\n })\n // const code = fs.readFileSync(absPath, 'utf-8');\n const fileId = relPath.replace(/\\\\/g, '/');\n const defineHeader = `define(\"game:${fileId}\", [\"require\", \"requireAsync\", \"module\", \"exports\", \"sandboxGlobal\"], function(require, requireAsync, module, exports, sandboxGlobal){\\nwith(sandboxGlobal){\\n`;\n const defineFooter = `\\n}\\n});\\n`;\n const fileMagic = new MagicString(code, { filename: fileId });\n fileMagic.prepend(defineHeader);\n fileMagic.append(defineFooter);\n concat.addSource({ content: fileMagic, filename: fileId });\n } catch (e) {\n logger.error(`pack error, relPath:${relPath},e:${e}`);\n }\n }\n }\n const outFile = path.join(destRoot, path.basename(packFileName));\n const bundledCode = concat.toString();\n\n if (config?.dev?.enableSourcemap) {\n const map = concat.generateMap({\n hires: true,\n includeContent: true,\n file: path.basename(packFileName), // 推荐用最终输出文件名\n });\n /**\n * 如果是走内敛\n */\n if (config?.dev?.inlineSourcemap) {\n // 生成 base 64\n const base64 = Buffer.from(map.toString()).toString('base64');\n const sourcemapContent = `data:application/json;base64,${base64}`;\n // 4. 写入 sourcemap 内容\n const fileContent =\n bundledCode +\n `\\n//# sourceMappingURL=${sourcemapContent}` + // 只写文件名即可,和 JS 文件同目录\n `\\n//# sourceURL=${packFileName}`;\n fs.writeFileSync(outFile, fileContent, 'utf-8');\n } else {\n const sourcemapBaseUrl = `http://${config?.dev?.host}:${config?.dev?.port}/game/files`;\n // 1. 生成 sourcemap 文件路径\n const mapFileName = path.basename(packFileName) + '.map';\n const mapFilePath = path.join(destRoot, mapFileName);\n // 2. 写入 sourcemap 文件\n fs.writeFileSync(mapFilePath, map.toString(), 'utf-8');\n // 3. JS 文件末尾加外链注释\n const fileContent =\n bundledCode +\n `\\n//# sourceMappingURL=${sourcemapBaseUrl}/${packFileName}.map` + // 只写文件名即可,和 JS 文件同目录\n `\\n//# sourceURL=${packFileName}`;\n fs.writeFileSync(outFile, fileContent, 'utf-8');\n }\n } else {\n const fileContent = bundledCode + `\\n//# sourceURL=${packFileName}`;\n\n fs.writeFileSync(outFile, fileContent, 'utf-8');\n }\n\n logger.info(`pack end,packName:${pkgName}`);\n }\n}\n","/**\n * 合并请求拆包\n */\nimport fs from 'fs';\nimport path from 'path';\nimport { getDirSizeSync, logger } from '@utils';\nimport { downloadAndSaveCodesAsync } from './utils';\nimport { AVAILABLE_ODR_TAG_LIST, ONE_ODR_PKG_LIMIT } from '@constants';\nimport { getOdrConfigs } from './getConfigs';\n\nexport async function buildOdrPkgs({ tempDir }: { tempDir: string }) {\n if (fs.existsSync(tempDir)) {\n fs.rmSync(tempDir, { recursive: true });\n }\n fs.mkdirSync(tempDir);\n const games = getOdrConfigs();\n logger.info('odr_games');\n await downloadAndSaveCodesAsync(games, tempDir);\n const gamesContentSize = {};\n for (const game of games) {\n const { id: gameId } = game;\n const gameDir = path.join(tempDir, gameId);\n gamesContentSize[gameId] = getDirSizeSync({\n rootDir: tempDir,\n entryDir: gameDir,\n filterDirs: [],\n });\n }\n // ODR TAG 分配\n const odrTagGameMap = {};\n AVAILABLE_ODR_TAG_LIST.forEach(tag => {\n odrTagGameMap[tag] = [];\n });\n // 用于产出 TTMGODRConfig\n const TTMGODRConfig = {};\n for (const game of games) {\n const { id: gameId, packages } = game;\n const gameSize = gamesContentSize[gameId];\n if (gameSize > ONE_ODR_PKG_LIMIT) continue;\n let assignedTag = null;\n for (const odrTag of AVAILABLE_ODR_TAG_LIST) {\n const odrTagDir = path.join(tempDir, odrTag);\n if (!fs.existsSync(odrTagDir)) fs.mkdirSync(odrTagDir);\n const currentTagSize = odrTagGameMap[odrTag].reduce(\n (sum, gid) => sum + gamesContentSize[gid],\n 0,\n );\n if (currentTagSize + gameSize <= ONE_ODR_PKG_LIMIT) {\n // 复制资源\n const srcDir = path.join(tempDir, gameId);\n const destDir = path.join(odrTagDir, gameId);\n fs.cpSync(srcDir, destDir, { recursive: true });\n odrTagGameMap[odrTag].push(gameId);\n assignedTag = odrTag;\n break;\n }\n }\n if (!assignedTag) continue; // 没有分配成功就跳过\n // 构建 TTMGODRConfig\n\n TTMGODRConfig[gameId] = {\n tag: assignedTag,\n packages: {},\n };\n for (const packageName in packages) {\n const pkg = packages[packageName];\n logger.info(`TTMGODRConfig[gameId].packages, ${pkg}, ${packageName}`);\n TTMGODRConfig[gameId].packages[packageName] = {\n root: pkg.root,\n main: pkg.main,\n // code_md5: pkg.code_md5,\n asset_md5: pkg.asset_md5,\n asset_url: pkg.asset_url,\n };\n }\n console.log(`finish to build ${gameId}`);\n fs.rmSync(path.join(tempDir, gameId), { recursive: true });\n }\n // 写入 JSON 文件\n const configPath = path.join(tempDir, 'TTMG_ODR_CONFIG.json');\n fs.writeFileSync(configPath, JSON.stringify(TTMGODRConfig, null, 2), 'utf-8');\n logger.info(`TTMG_ODR_CONFIG.json 已生成: ${configPath}`);\n}\n","import data from './config.json';\n\nexport function getOdrConfigs() {\n const { MinisPackagingInfoMap } = data;\n return Object.keys(MinisPackagingInfoMap).map(clientKey => {\n return {\n id: clientKey,\n packages: JSON.parse(MinisPackagingInfoMap[clientKey].ODRPackages),\n };\n });\n}\n","import { logger, overrideConfig } from '@utils';\nimport { BuildConfig } from '@typings';\nimport { checkPkgs } from '../checkPkgs';\nimport { makePkgs } from '../makePkgs';\nimport { makeOdrPkgs } from '../odrPkgs';\n\nexport async function buildPkgs(originConfig: BuildConfig) {\n const { entry: entryDir, output: outputDir, build } = originConfig;\n let startTime = Date.now();\n logger.init(outputDir, true);\n logger.info(`TTMG_PACK_VERSION: ${process.env.TTMG_PACK_VERSION}`);\n logger.info(`pack start, startTime:${startTime}`);\n const config = overrideConfig(entryDir, originConfig);\n\n /**\n * 校验\n */\n await checkPkgs({\n entryDir,\n config,\n });\n /**\n * 打包\n */\n await makePkgs({\n config,\n gameEntry: entryDir,\n gameOutput: outputDir,\n });\n\n if (build?.enableOdr) {\n /**\n * 等待文件全部读写完成后\n */\n await makeOdrPkgs(outputDir);\n /**\n * 分拆 odr 包\n */\n }\n\n logger.info(`pack end:${Date.now() - startTime}ms`);\n}\n","import { BuildConfig } from '@typings';\nimport { isUnityEngine } from './unity';\n\n// 面向高鹏编程 😢\n/**\n * 覆盖配置,根据游戏引擎类型,设置主包和独立子包的大小限制\n * @param entryDir 游戏项目入口目录\n * @param config 原始构建配置\n * @returns 覆盖后的构建配置\n */\nexport function overrideConfig(\n entryDir: string,\n config: BuildConfig,\n): BuildConfig { \n const isUnity = isUnityEngine(entryDir);\n return {\n ...config,\n build: {\n ...config.build,\n mainPkgSizeLimit: !isUnity ? config.build?.mainPkgSizeLimit : null,\n independentSubPkgSizeLimit: !isUnity\n ? config.build?.independentSubPkgSizeLimit\n : null,\n },\n };\n}\n","import path from 'path';\nimport fs from 'fs';\nimport {\n ensureDirSync,\n deleteNoJsFilesSync,\n logger,\n deleteJsFilesSync,\n} from '@utils';\n\nimport {\n GAME_PACK_CONFIG_FILE_NAME,\n ODR_ASSET_DIR_SUFFIX,\n ODR_CODE_DIR_SUFFIX,\n STTPKG_EXT,\n} from '@constants';\n\nexport async function makeOdrPkgs(outputDir: string) {\n let startTime = Date.now();\n logger.info(`makeOdrPkgs start, ${startTime}`);\n const outputPath = path.join(outputDir, GAME_PACK_CONFIG_FILE_NAME);\n const config = JSON.parse(fs.readFileSync(outputPath, 'utf-8'));\n const packages = config.packages;\n for (const pkgName in packages) {\n /**\n * 将原本的分包配置,转换为 odr 的配置,\n * 将原本产物按照原路径,分别拆分成两个文件夹:js 部分 package_name_code,asset 部分 package_name_asset\n */\n const pkgOutput = path.join(outputDir, pkgName);\n const codeOutput = path.join(outputDir, `${pkgName}${ODR_CODE_DIR_SUFFIX}`);\n const assetOutput = path.join(\n outputDir,\n `${pkgName}${ODR_ASSET_DIR_SUFFIX}`,\n );\n ensureDirSync(codeOutput);\n ensureDirSync(assetOutput);\n fs.cpSync(pkgOutput, codeOutput, { recursive: true });\n fs.cpSync(pkgOutput, assetOutput, { recursive: true });\n deleteNoJsFilesSync(codeOutput);\n deleteJsFilesSync(assetOutput);\n\n /**\n * 写入配置\n */\n packages[`${pkgName}${ODR_CODE_DIR_SUFFIX}`] = {\n ...packages[pkgName],\n code_url: '',\n code_md5: '',\n output: `${pkgName}${ODR_CODE_DIR_SUFFIX}${STTPKG_EXT}`,\n };\n packages[`${pkgName}${ODR_ASSET_DIR_SUFFIX}`] = {\n ...packages[pkgName],\n asset_url: '',\n asset_md5: '',\n output: `${pkgName}${ODR_ASSET_DIR_SUFFIX}${STTPKG_EXT}`,\n };\n }\n fs.writeFileSync(outputPath, JSON.stringify(config, null, 2));\n logger.info(`makeOdrPkgs end, ${Date.now() - startTime}ms`);\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { logger } from '@utils';\nimport { GAME_PACK_CONFIG_FILE_NAME } from '@constants';\nimport { BuildConfig, CheckResult, ProjectConfig } from '@typings';\nimport { checkPkgs } from '../checkPkgs';\nimport { mergePkgs } from '../mergePkgs';\nimport { makePkgs } from '../makePkgs';\n\nexport async function debugPkgs(config: BuildConfig): Promise<{\n isSuccess: boolean;\n errorMsg?: string;\n packages?: ProjectConfig['packages'];\n checkResults?: CheckResult[];\n}> {\n const {\n entry: entryDir,\n output: outputDir,\n dev: { enableLog },\n } = config;\n logger.init(outputDir, enableLog);\n try {\n /**\n * 校验\n */\n const checkResults = await checkPkgs({\n entryDir,\n config,\n });\n\n /**\n * 打包\n */\n await makePkgs({\n gameEntry: entryDir,\n gameOutput: outputDir,\n config,\n });\n\n /**\n * 合并\n */\n await mergePkgs(outputDir);\n\n /**\n * 返回 packageConfig\n */\n const packageConfig = fs.readFileSync(\n path.join(outputDir, GAME_PACK_CONFIG_FILE_NAME),\n 'utf-8',\n );\n const packageConfigJson = JSON.parse(packageConfig);\n return {\n isSuccess: true,\n packages: packageConfigJson.packages,\n checkResults,\n };\n } catch (error) {\n return {\n isSuccess: false,\n errorMsg: error.message,\n };\n }\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { logger } from '@utils';\nimport { ProjectConfig } from '@typings';\nimport { GAME_PACK_CONFIG_FILE_NAME } from '@constants';\n\n/**\n * 将 packages 中的每个 package 下的文件内容合并到 outputDir 下,不保留 package name\n * @param outputDir 输出目录\n */\nexport async function mergePkgs(outputDir: string) {\n logger.info('mergePkgs start');\n const gamePackConfigPath = path.join(outputDir, GAME_PACK_CONFIG_FILE_NAME);\n let gamePackConfig: ProjectConfig;\n try {\n gamePackConfig = JSON.parse(fs.readFileSync(gamePackConfigPath, 'utf-8'));\n } catch (err) {\n logger.error(\n `读取配置文件失败: ${gamePackConfigPath}, err: ${err.message}`,\n );\n return;\n }\n\n const packages = gamePackConfig.packages;\n if (!packages || typeof packages !== 'object') {\n logger.error('配置文件中 packages 字段无效, 请检查配置');\n return;\n }\n\n for (const pkgName of Object.keys(packages)) {\n const pkgDir = path.join(outputDir, pkgName);\n if (!fs.existsSync(pkgDir)) {\n logger.warn(`package 目录不存在: ${pkgDir}`);\n continue;\n }\n\n const files = await fs.promises.readdir(pkgDir);\n for (const file of files) {\n const srcPath = path.join(pkgDir, file);\n const destPath = path.join(outputDir, file);\n\n try {\n const stat = await fs.promises.stat(srcPath);\n if (stat.isFile()) {\n await fs.promises.copyFile(srcPath, destPath);\n // 复制好了之后就删除\n await fs.promises.rm(srcPath, {\n recursive: true,\n force: true,\n });\n } else if (stat.isDirectory()) {\n await fs.promises.cp(srcPath, destPath, { recursive: true });\n // 复制好了之后就删除\n await fs.promises.rm(srcPath, { recursive: true, force: true }); \n } else if (stat.isSymbolicLink()) {\n const linkTarget = fs.readlinkSync(srcPath);\n // 判断目标是否已存在符号链接\n if (fs.existsSync(destPath)) {\n await fs.promises.rm(destPath, { force: true });\n }\n await fs.promises.symlink(\n linkTarget,\n destPath,\n stat.isDirectory() ? 'dir' : 'file',\n );\n }\n logger.info(`合并文件/目录: ${srcPath} -> ${destPath}`);\n } catch (err) {\n logger.error(`处理文件失败: ${srcPath}, err: ${err.message}`);\n }\n }\n /**\n * 如果最后 pkgDir 为空,就删除 \n */\n if (fs.readdirSync(pkgDir).length === 0) {\n fs.rmSync(pkgDir, { recursive: true, force: true });\n logger.info(`已删除 package 目录: ${pkgDir}`);\n }\n }\n\n logger.info('mergePkgs 完成');\n}\n","import path from 'path';\nimport { GAME_MAIN_PACKAGE_NAME } from '@constants';\nimport type { GetPkgsResult } from '@typings';\nimport {\n getDirSizeSync,\n getIndependentPackagesConfig,\n getMainPkgSize,\n getProjectSize,\n getGameEngine,\n getWasmBrCodePath,\n} from '@utils';\n\nexport async function getPkgs({\n entryDir,\n}: {\n entryDir: string;\n}): Promise<GetPkgsResult> {\n const independentPackages = getIndependentPackagesConfig(entryDir);\n /**\n *\n */\n const packages: GetPkgsResult['packages'] = [{\n type: 'main',\n size: getMainPkgSize({ entryDir }),\n name: GAME_MAIN_PACKAGE_NAME,\n root: '',\n },\n ...independentPackages.map(sub => ({\n type: 'independent',\n size: getDirSizeSync({\n rootDir: entryDir,\n entryDir: path.join(entryDir, sub.root),\n filterDirs: [],\n }),\n name: sub.name,\n root: sub.root,\n }))];\n const wasmCodePath = getWasmBrCodePath({ entryDir });\n if (wasmCodePath) {\n packages.push({\n type: 'wasmcode',\n name: 'wasmcode',\n root: wasmCodePath,\n });\n }\n return {\n size: getProjectSize({\n entryDir,\n }),\n engine: getGameEngine(entryDir),\n packages\n };\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { isUnityEngine } from './isUnityEngine';\n\n\nexport function getWasmBrCodePath({\n entryDir,\n}: {\n entryDir: string;\n}): string {\n if (!isUnityEngine(entryDir)) {\n return '';\n } else {\n /**\n * 检查项目下存在一个名为 wasmcode 的文件夹,且文件夹下存在一个文件后缀为 .webgl.wasm.code.unityweb.wasm.br 的文件。,如果满足条件,就展示 true,否则 返回 false\n */\n\n const wasmCodeDir = path.join(entryDir, 'wasmcode');\n if (!fs.existsSync(wasmCodeDir)) {\n return '';\n }\n const wasmBrFiles = fs.readdirSync(wasmCodeDir).filter(file => file.endsWith('.webgl.wasm.code.unityweb.wasm.br'));\n if (wasmBrFiles.length === 0) {\n return '';\n } else {\n return path.relative(entryDir, path.join(wasmCodeDir, wasmBrFiles[0]));\n }\n }\n}","import { logger } from '@utils';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\nimport {\n GAME_PACK_CONFIG_FILE_NAME,\n ODR_ASSET_DIR_SUFFIX,\n ODR_CODE_DIR_SUFFIX,\n} from '@constants';\n\n/**\n * 将 packageConfig packages 中 分拆的包 配置迁移到 odr_packages 中\n */\n\nexport async function writeOdrConfig(outputDir: string) {\n logger.info('writeOdrPackagesConfig start');\n const outputPath = path.join(outputDir, GAME_PACK_CONFIG_FILE_NAME);\n const config = JSON.parse(fs.readFileSync(outputPath, 'utf-8'));\n const packages = config.packages;\n const odrPackages = config.odr_packages || {};\n for (const pkgName in packages) {\n if (pkgName.endsWith(ODR_CODE_DIR_SUFFIX)) {\n /**\n * 找到 assets 对应的包\n */\n const pkgConfig = packages[pkgName];\n const relatedPkgName = pkgName.split(ODR_CODE_DIR_SUFFIX)[0];\n if (!odrPackages[relatedPkgName]) {\n odrPackages[relatedPkgName] = {};\n }\n odrPackages[relatedPkgName] = {\n ...odrPackages[relatedPkgName],\n root: pkgConfig.root,\n code_output: pkgConfig.output,\n code_md5: pkgConfig.md5,\n main: pkgConfig.main,\n };\n delete packages[pkgName];\n }\n if (pkgName.endsWith(ODR_ASSET_DIR_SUFFIX)) {\n const relatedPkgName = pkgName.split(ODR_ASSET_DIR_SUFFIX)[0];\n const pkgConfig = packages[pkgName];\n odrPackages[relatedPkgName] = {\n ...odrPackages[relatedPkgName],\n root: pkgConfig.root,\n asset_output: pkgConfig.output,\n asset_md5: pkgConfig.md5,\n };\n delete packages[pkgName];\n }\n }\n config.odr_packages = odrPackages;\n fs.writeFileSync(outputPath, JSON.stringify(config, null, 2));\n logger.info('writeOdrPackagesConfig end');\n}\n"],"names":["ensureDirSync","dir","fs","existsSync","mkdirSync","recursive","logger","constructor","this","init","output","enableLog","winston","createLogger","level","format","combine","timestamp","json","transports","File","filename","path","join","Console","info","msg","error","warn","debug","log","setOutput","removeEmptyDir","statSync","isDirectory","isEmpty","files","readdirSync","file","fullPath","rmSync","GAME_PACK_CONFIG_FILE_NAME","GAME_ORIGIN_CONFIG_FILE_NAME","GAME_MAIN_PACKAGE_NAME","STTPKG_EXT","ODR_CODE_DIR_SUFFIX","ODR_ASSET_DIR_SUFFIX","ONE_ODR_PKG_LIMIT","AVAILABLE_ODR_TAG_LIST","CHECK_DIMENSION","PACKAGE_TYPE","getDirSizeSync","rootDir","entryDir","filterDirs","totalSize","entries","withFileTypes","entry","name","relativePath","relative","replace","includes","isFile","size","deleteJsFilesSync","endsWith","unlinkSync","err","deleteNoJsFilesSync","uselessDirs","uselessFiles","getIndependentPackagesConfig","gameOriginConfigPath","gameOriginConfig","JSON","parse","readFileSync","subpackages","_a","filter","sub","independent","e","getMainPkgSize","getSubpackagesRoots","originConfigPath","originConfig","map","item","root","getProjectSize","getGameEngine","gameEntry","gameJsonConfigPath","gameJsonConfig","gameEngine","isUnityEngine","async","downloadAndSaveCodesAsync","games","tempDir","concurrency","tasks","game","id","gameId","packages","gameDir","mkdir","packageName","packageInfo","code_url","fileName","filePath","push","poolLimit","array","iteratorFn","ret","executing","p","Promise","resolve","then","length","splice","indexOf","race","all","asyncPool","task","console","res","fetch","ok","Error","statusText","buffer","Buffer","from","arrayBuffer","writeFile","defaultCheckConfig","dimension","checkProject","config","checkSizeResult","build","pkgSizeLimit","dev","enableDev","enable","gameSize","gameSizeMB","toFixed","limitMB","errMsg","Object","assign","passed","type","logMsg","checkProjectSize","gameJsonCheckResult","gameJsonPath","checkGameJson","result","every","checkMainPackage","checkResults","gameJsPath","checkMainPackageEntry","mainPkgSizeLimit","mainPkgSize","mainPkgSizeMB","checkMainPackageSize","checkSubpackages","getSubpackagesConfig","forEach","subpackageEntryDir","_b","checkIndependentPackages","isEnableDev","independentSubPkgSizeLimit","limit","pkgName","sizeMB","checkPkgSize","API_LIST","desc","escapeRegex","s","checkPkgs","projectCheckResult","mainPackageCheckResult","subpackagesCheckResult","independentPackagesCheckResult","apiCheckResult","enableAPICheck","exts","apiRegexMap","Map","pattern","RegExp","hitFilesMap","set","Set","stack","current","pop","base","basename","children","child","ext","extname","toLowerCase","content","get","test","add","Array","required","checkAPI","setup","outputDir","gameJson","fyfPackages","value","label","url","md5","main","configs","normalizeName","String","getMainFromRoot","str","normalizeRoot","transformSubPackages","fyf_packages","writeFileSync","stringify","flattenMaps","allMaps","list","values","arr","collectPkgJsFiles","excludeDirs","find","concat","some","collectDeps","rootPrefixes","getRootPrefixes","glob","sync","cwd","ignore","requireCalls","code","ast","acorn","ecmaVersion","sourceType","walkAst","node","callee","arguments","requirePath","resolvedPath","startsWith","dirname","prefix","fileExistsWithExtensions","newRequireCalls","i","depModule","keys","pkg","curModule","reduce","acc","cur","f","cb","key","hasOwnProperty","isArray","c","partition","pkgRoot","destRoot","packedFiles","gameOutput","skipDirs","isRoot","srcPath","destPath","copyFileSync","getSkipDirs","makePkgs","startTime","Date","now","removeUselessDirs","message","stat","force","removeSystemUseless","allDeps","subRoots","Boolean","uniqueSubRoots","srcRoot","jsFiles","absPath","packNameRoot","collectMaps","pkgConfig","packMap","moduleConfig","deps","packFileName","relPaths","Bundle","separator","relPath","transformSync","loader","target","fileId","defineHeader","defineFooter","fileMagic","MagicString","prepend","append","addSource","outFile","bundledCode","toString","enableSourcemap","generateMap","hires","includeContent","inlineSourcemap","fileContent","sourcemapBaseUrl","_c","host","_d","port","mapFileName","mapFilePath","pack","MinisPackagingInfoMap","data","clientKey","ODRPackages","getOdrConfigs","gamesContentSize","odrTagGameMap","tag","TTMGODRConfig","assignedTag","odrTag","odrTagDir","sum","gid","srcDir","destDir","cpSync","asset_md5","asset_url","configPath","isUnity","overrideConfig","enableOdr","outputPath","pkgOutput","codeOutput","assetOutput","code_md5","makeOdrPkgs","gamePackConfigPath","gamePackConfig","pkgDir","promises","readdir","copyFile","rm","cp","isSymbolicLink","linkTarget","readlinkSync","symlink","mergePkgs","packageConfig","isSuccess","errorMsg","independentPackages","wasmCodePath","wasmCodeDir","wasmBrFiles","getWasmBrCodePath","engine","odrPackages","odr_packages","relatedPkgName","split","code_output","asset_output"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../src/utils/ensureDirSync.ts","../src/utils/logger.ts","../src/utils/removeEmptyDir.ts","../src/constants/index.ts","../src/utils/getDirSizeSync.ts","../src/utils/deleteJsFilesSync.ts","../src/utils/deleteNoJsFilesSync.ts","../src/utils/removeSystemUseless.ts","../src/utils/getIndependentPackagesConfig.ts","../src/utils/getMainPkgSize.ts","../src/utils/getProjectSize.ts","../src/utils/overrideConfig.ts","../src/utils/getGameEngine.ts","../src/libs/odrPkgs/utils.ts","../src/libs/checkPkgs/checkProject.ts","../src/libs/checkPkgs/checkMainpackage.ts","../src/libs/checkPkgs/checkSubpackages.ts","../src/utils/getSubpackagesConfig.ts","../src/libs/checkPkgs/checkIndependentPackages.ts","../src/libs/checkPkgs/checkAPI.ts","../src/libs/checkPkgs/index.ts","../src/libs/makePkgs/setup.ts","../src/libs/makePkgs/collectMaps.ts","../src/libs/makePkgs/collectDeps.ts","../src/libs/makePkgs/partition.ts","../src/libs/makePkgs/index.ts","../src/utils/asyncPool.ts","../src/libs/makePkgs/pack.ts","../src/libs/odrPkgs/buildOdrPkgs.ts","../src/libs/odrPkgs/getConfigs.ts","../src/libs/buildPkgs/index.ts","../src/libs/odrPkgs/makeOdrPkgs.ts","../src/libs/debugPkgs/index.ts","../src/libs/mergePkgs/index.ts","../src/libs/getPkgs/index.ts","../src/libs/odrPkgs/writeOdrConfig.ts"],"sourcesContent":["import fs from 'fs';\nexport function ensureDirSync(dir) {\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n}\n","import winston from 'winston';\nimport path from 'path';\n\nclass Logger {\n logger: winston.Logger;\n enableLog: boolean;\n output: any;\n constructor() {\n this.logger = null;\n }\n init(output: string, enableLog = true) {\n this.enableLog = enableLog;\n this.logger = winston.createLogger({\n level: 'info',\n format: winston.format.combine(\n winston.format.timestamp(),\n winston.format.json(), // 输出为 JSON 格式\n ),\n transports: [\n new winston.transports.File({\n filename: path.join(output, 'pack.log'),\n }),\n new winston.transports.Console(),\n ],\n });\n }\n info(msg: string) {\n if (this.enableLog) {\n this.logger.info(msg);\n }\n }\n error(msg) {\n if (this.enableLog) {\n this.logger.error(msg);\n }\n }\n warn(msg) {\n if (this.enableLog) {\n this.logger.warn(msg);\n }\n }\n debug(msg) {\n if (this.enableLog) {\n this.logger.debug(msg);\n }\n }\n log(msg) {\n this.logger.info(msg);\n }\n setOutput(output) {\n this.output = output;\n }\n}\n\nexport const logger = new Logger();\n","import fs from 'fs';\nimport path from 'path';\n\n/**\n * 移除指定目录下所有空文件夹(递归)\n * @param {string} dir 目标目录\n * @returns {boolean} 返回当前目录是否已被删除(即是否为空)\n */\nexport function removeEmptyDir(dir) {\n if (!fs.existsSync(dir)) return false;\n if (!fs.statSync(dir).isDirectory()) return false;\n\n let isEmpty = true;\n const files = fs.readdirSync(dir);\n for (const file of files) {\n const fullPath = path.join(dir, file);\n if (fs.statSync(fullPath).isDirectory()) {\n // 递归处理子目录\n const childIsEmpty = removeEmptyDir(fullPath);\n if (!childIsEmpty) isEmpty = false;\n } else {\n // 有文件,当前目录不为空\n isEmpty = false;\n }\n }\n\n // 如果当前目录为空,删除它\n if (isEmpty) {\n fs.rmSync(dir, { recursive: true });\n return true;\n }\n return false;\n}\n\n","import type { CheckDimension } from '@typings';\nexport const GAME_PACK_CONFIG_FILE_NAME = 'packageConfig.json';\nexport const GAME_PROJECT_CONFIG_FILE_NAME = 'project.config.json';\nexport const GAME_ORIGIN_CONFIG_FILE_NAME = 'game.json';\nexport const GAME_MODULE_CONFIG_FILE_NAME = 'moduleConfig.json';\nexport const GAME_OUTPUT_CONFIG_FILE_NAME = 'output.json';\nexport const GAME_MAIN_PACKAGE_NAME = '__GAME__';\nexport const TTPKG_TAG = 'TPKG';\nexport const STTPKG_TAG = 'SPKG';\nexport const TTPKG_VERSION = 2;\nexport const ARK_KEY_LEN = 32;\nexport const ARK_INT_LEN = 4;\nexport const UNIT32_LEN = 4;\nexport const UINT16_LEN = 2;\nexport const STTPKG_VERSION = 1;\nexport const ZSTD_COMPRESS_LEVEL = 19;\nexport const ROLL_FILE_EXT = [\n '.js',\n '.json',\n '.wxml',\n '.ttml',\n '.wxss',\n '.ttss',\n];\nexport const EXT = '';\nexport const BROTLI_COMPRESS_TYPE = 1;\nexport const ZSTD_COMPRESS_TYPE = 3;\n\nexport const STTPKG_EXT = '.txt';\n\nexport const ODR_CODE_DIR_SUFFIX = '_code';\n\nexport const ODR_ASSET_DIR_SUFFIX = '_asset';\n\n// 60MB const ONE_ODR_PKG_LIMIT = 1024 * 1024;\nexport const ONE_ODR_PKG_LIMIT = 1024 * 1024 * 60;\n\nexport const AVAILABLE_ODR_TAG_LIST = [\n 'ttmg_odr_high_channel',\n 'ttmg_odr_middle_channel',\n 'ttmg_odr_normal_channel',\n];\n\nexport const PROJECT_SIZE_LIMIT = 30 * 1024 * 1024;\n\n\nexport const MAINPACKAGE_SIZE_LIMIT = 4 * 1024 * 1024;\n\n\nexport const CHECK_DIMENSION: Record<string, CheckDimension> = {\n IndependentPackage: 'independent_package',\n MainPackage: 'main_package',\n Project: 'project',\n SubPackage: 'subpackage',\n}\n\nexport const PACKAGE_TYPE = {\n IndependentPackage: 'independent_package',\n SubPackage: 'sub_package',\n MainPackage: 'main_package',\n}\n\nexport const GAME_ENGINES = {\n UNITY: 'unity',\n}","import fs from 'fs';\nimport path from 'path';\n// 递归统计目录下所有文件的大小,支持我过滤某些文件夹\nexport function getDirSizeSync({\n rootDir,\n entryDir,\n filterDirs,\n}: {\n rootDir: string;\n entryDir: string;\n filterDirs: string[];\n}) {\n let totalSize = 0;\n if (!fs.existsSync(entryDir)) return 0;\n const entries = fs.readdirSync(entryDir, { withFileTypes: true });\n for (const entry of entries) {\n const fullPath = path.join(entryDir, entry.name);\n if (entry.isDirectory()) {\n /**\n * 基于 rootDir 算出 fullPath 的相对路径\n */\n const relativePath = path.relative(rootDir, fullPath).replace(/\\\\/g, '/');\n if (!filterDirs.includes(relativePath)) {\n totalSize += getDirSizeSync({\n entryDir: fullPath,\n filterDirs,\n rootDir,\n });\n }\n } else if (entry.isFile()) {\n totalSize += fs.statSync(fullPath).size;\n }\n }\n return totalSize;\n}\n","import fs from 'fs';\nimport path from 'path';\n\n/**\n * 同步删除指定目录及其子目录下所有 .js 文件\n * @param {string} dir 目标目录路径\n */\nexport function deleteJsFilesSync(dir) {\n // 读取目录内容\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // 递归处理子目录\n deleteJsFilesSync(fullPath);\n } else if (\n entry.isFile() &&\n (fullPath.endsWith('.js') || fullPath.endsWith('.js.map'))\n ) {\n try {\n fs.unlinkSync(fullPath);\n } catch (err) {}\n }\n }\n}\n","import fs from 'fs';\nimport path from 'path';\n\nexport function deleteNoJsFilesSync(dir) {\n const entries = fs.readdirSync(dir, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = path.join(dir, entry.name);\n\n if (entry.isDirectory()) {\n // 递归处理子目录\n deleteNoJsFilesSync(fullPath);\n } else if (\n entry.isFile() &&\n !(fullPath.endsWith('.js') || fullPath.endsWith('.js.map'))\n ) {\n try {\n fs.unlinkSync(fullPath);\n } catch (err) {}\n }\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { logger } from './logger';\n\nconst uselessDirs = ['node_modules', '__MACOSX'];\nconst uselessFiles = ['.DS_Store', 'Thumbs.db'];\n\nexport function removeSystemUseless(gameEntry: string) {\n /**\n * 递归删除目录下的无用文件夹和无用文件\n */\n function removeUselessDirs(dir: string) {\n let files: string[];\n try {\n files = fs.readdirSync(dir);\n } catch (err) {\n // 目录不可访问,跳过\n logger.warn(`无法访问目录: ${dir}, ${err.message}`);\n return;\n }\n files.forEach(file => {\n const filePath = path.join(dir, file);\n try {\n const stat = fs.statSync(filePath);\n if (stat.isDirectory()) {\n if (uselessDirs.includes(file)) {\n // 删除无用目录\n fs.rmSync(filePath, { recursive: true, force: true });\n logger.info(`已删除无用目录: ${filePath}`);\n } else {\n // 递归处理子目录\n removeUselessDirs(filePath);\n }\n } else if (stat.isFile()) {\n if (uselessFiles.includes(file)) {\n // 删除无用文件\n fs.rmSync(filePath, { force: true });\n logger.info(`已删除无用文件: ${filePath}`);\n }\n }\n } catch (err) {\n // 某个文件/目录不可访问,跳过\n logger.warn(`无法处理: ${filePath}, ${err.message}`);\n }\n });\n }\n removeUselessDirs(gameEntry);\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { GAME_ORIGIN_CONFIG_FILE_NAME } from '@constants';\n\nexport function getIndependentPackagesConfig(entryDir: string) {\n try {\n const gameOriginConfigPath = path.join(\n entryDir,\n GAME_ORIGIN_CONFIG_FILE_NAME,\n );\n const gameOriginConfig = JSON.parse(\n fs.readFileSync(gameOriginConfigPath, 'utf-8'),\n );\n return gameOriginConfig?.subpackages?.filter(sub => sub.independent) || [];\n } catch (e) {\n return [];\n }\n}\n","import { getDirSizeSync } from './getDirSizeSync';\nimport path from 'path';\nimport fs from 'fs';\nimport { GAME_ORIGIN_CONFIG_FILE_NAME } from '@constants';\n\nexport function getMainPkgSize({ entryDir }: { entryDir: string }) {\n return getDirSizeSync({\n rootDir: entryDir,\n entryDir,\n filterDirs: getSubpackagesRoots(entryDir),\n });\n}\n\nfunction getSubpackagesRoots(entryDir: string) {\n const originConfigPath = path.join(entryDir, GAME_ORIGIN_CONFIG_FILE_NAME);\n try {\n const originConfig = JSON.parse(fs.readFileSync(originConfigPath, 'utf8'));\n const roots =\n originConfig.subpackages?.map((item: { root: string }) => item.root) ||\n [];\n /**\n * 移除掉头和尾的 /\n */\n return roots.map(root => root.replace(/^\\/|\\/$/g, ''));\n } catch (e) {\n return [];\n }\n}\n","import { getDirSizeSync } from './getDirSizeSync';\n\nexport function getProjectSize({ entryDir }: { entryDir: string }) {\n return getDirSizeSync({\n rootDir: entryDir,\n entryDir,\n filterDirs: [],\n });\n}\n","import { BuildConfig } from '@typings';\nimport { GAME_ENGINES } from '@constants';\nimport { getGameEngine } from './getGameEngine';\n\n// 面向高鹏编程 😢\n/**\n * 覆盖配置,根据游戏引擎类型,设置主包和独立子包的大小限制\n * @param entryDir 游戏项目入口目录\n * @param config 原始构建配置\n * @returns 覆盖后的构建配置\n */\nexport function overrideConfig(\n entryDir: string,\n config: BuildConfig,\n): BuildConfig {\n const isUnity = getGameEngine(entryDir) === GAME_ENGINES.UNITY;\n return {\n ...config,\n build: {\n ...config.build,\n mainPkgSizeLimit: !isUnity ? config.build?.mainPkgSizeLimit : null,\n independentSubPkgSizeLimit: !isUnity\n ? config.build?.independentSubPkgSizeLimit\n : null,\n },\n };\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { GAME_ORIGIN_CONFIG_FILE_NAME } from '../constants';\nexport function getGameEngine(gameEntry: string): string {\n const gameJsonConfigPath = path.join(gameEntry, GAME_ORIGIN_CONFIG_FILE_NAME);\n if (!fs.existsSync(gameJsonConfigPath)) {\n return '';\n }\n let gameJsonConfig: any;\n try {\n gameJsonConfig = JSON.parse(fs.readFileSync(gameJsonConfigPath, 'utf-8'));\n const gameEngine = gameJsonConfig?.gameEngine;\n if (!gameEngine) {\n return '';\n }\n return gameEngine;\n } catch (error) {\n return '';\n }\n}","import { logger } from '@utils';\nimport { ODRPackages } from '@typings';\n\n// export function fetchGames(params: { size: number; offset: number }): Promise<{\n// data: Array<{\n// id: string;\n// packages: ODRPackages;\n// }>;\n// total: number;\n// }> {\n// const { size, offset } = params;\n// const url = `https://game-odr.bytedance.net/odr/api/v1/games?size=${size}&offset=${offset}`;\n// return fetch(url).then(res => res.json());\n// }\n\n// export async function fetchAllGames(): Promise<Array<{\n// id: string;\n// packages: ODRPackages;\n// }>> {\n// const size = 100;\n// let offset = 0;\n// let total = 0;\n// const games: Array<{\n// id: string;\n// packages: ODRPackages;\n// }> = [];\n// while (true) {\n// const res = await fetchGames({ size, offset });\n// games.push(...res.data);\n// total = res.total;\n// if (games.length >= total) {\n// break;\n// }\n// offset += size;\n// }\n// return games;\n// }\n\nimport fs from 'fs/promises';\nimport path from 'path';\nimport fetch from 'node-fetch';\n\nexport async function downloadAndSaveCodesAsync(\n games,\n tempDir,\n concurrency = 5, // 并发数\n) {\n // 1. 生成所有下载任务\n const tasks = [];\n\n for (const game of games) {\n const { id: gameId, packages } = game;\n const gameDir = path.join(tempDir, gameId);\n await fs.mkdir(gameDir, { recursive: true });\n\n for (const packageName in packages) {\n const packageInfo = packages[packageName];\n const { code_url } = packageInfo;\n const fileName = `${packageName}.txt`;\n const filePath = path.join(gameDir, fileName);\n\n tasks.push({\n code_url,\n filePath,\n packageName,\n });\n }\n }\n\n // 2. 用并发池执行所有任务\n await asyncPool(concurrency, tasks, async task => {\n const { code_url, filePath, packageName } = task;\n console.log(`start to download ${packageName}`);\n try {\n const res = await fetch(code_url);\n if (!res.ok)\n throw new Error(`Failed to fetch ${code_url}: ${res.statusText}`);\n const buffer = Buffer.from(await res.arrayBuffer());\n await fs.writeFile(filePath, buffer);\n console.log(`finish to download ${packageName}`);\n } catch (err) {\n console.error(`Error downloading ${packageName}:`, err);\n }\n });\n}\n\nasync function asyncPool(poolLimit, array, iteratorFn) {\n const ret = [];\n const executing = [];\n for (const item of array) {\n const p = Promise.resolve().then(() => iteratorFn(item));\n ret.push(p);\n if (poolLimit <= array.length) {\n const e = p.then(() => executing.splice(executing.indexOf(e), 1));\n executing.push(e);\n if (executing.length >= poolLimit) {\n await Promise.race(executing);\n }\n }\n }\n return Promise.all(ret);\n}\n","import path from 'path';\nimport fs from 'fs';\nimport {\n BuildConfig,\n CheckConfigResult,\n CheckSizeResult,\n CheckDimension,\n} from '@typings';\nimport {\n GAME_ORIGIN_CONFIG_FILE_NAME,\n GAME_PROJECT_CONFIG_FILE_NAME,\n CHECK_DIMENSION,\n} from '@constants';\nimport { logger, getProjectSize } from '@utils';\n\nconst defaultCheckConfig: {\n name: string;\n dimension: CheckDimension;\n} = {\n name: 'project',\n dimension: CHECK_DIMENSION.Project,\n};\nexport function checkProject(entryDir: string, config: BuildConfig) {\n logger.info('start check project');\n const checkSizeResult = checkProjectSize(entryDir, config);\n const gameJsonCheckResult = checkGameJson(entryDir, config);\n // const projectConfigCheckResult = checkProjectConfig(entryDir, config);\n const result = [\n checkSizeResult,\n gameJsonCheckResult,\n // projectConfigCheckResult,\n ];\n if (result.every(item => item.passed)) {\n logger.info('check project successfully');\n }\n return result;\n}\n\nexport function checkGameJson(\n entryDir: string,\n config: BuildConfig,\n): CheckConfigResult {\n logger.info('start check config');\n const gameJsonPath = path.join(entryDir, GAME_ORIGIN_CONFIG_FILE_NAME);\n if (!fs.existsSync(gameJsonPath)) {\n const errMsg =\n 'Can not find game.json in game source code, please check it';\n logger.error(errMsg);\n\n if (config?.dev?.enable) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n return {\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n };\n } else {\n throw new Error(errMsg);\n }\n } else {\n const msg = 'Check game.json config successfully';\n logger.info(msg);\n return {\n passed: true,\n msg,\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n type: 'config',\n ...defaultCheckConfig,\n };\n }\n}\n\n/**\n * 检查游戏大小是否超出限制\n * @param param0\n * @returns\n */\n\nexport function checkProjectSize(\n entryDir: string,\n config: BuildConfig,\n): CheckSizeResult {\n logger.info('start check project size');\n const {\n build: { pkgSizeLimit },\n dev,\n } = config;\n const enableDev = dev?.enable;\n const gameSize = getProjectSize({ entryDir });\n const gameSizeMB = (gameSize / (1024 * 1024)).toFixed(2);\n const limitMB = (pkgSizeLimit / (1024 * 1024)).toFixed(2);\n if (gameSize > pkgSizeLimit) {\n const errMsg = `Check project size failed, size: ${gameSizeMB}MB, must not exceed ${limitMB}MB`;\n logger.error(errMsg);\n if (enableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', errMsg);\n return {\n passed: false,\n msg: errMsg,\n type: 'size',\n size: gameSize,\n ...defaultCheckConfig,\n };\n } else {\n throw new Error(errMsg);\n }\n } else {\n /**\n * 游戏大小检查通过\n */\n const logMsg = `Check project size successfully, size: ${gameSizeMB}MB`;\n logger.info(logMsg);\n return {\n passed: true,\n msg: logMsg,\n name: 'project',\n type: 'size',\n size: gameSize,\n ...defaultCheckConfig,\n };\n }\n}\n\nexport function checkProjectConfig(\n entryDir: string,\n config: BuildConfig,\n): CheckConfigResult {\n const enableDev = config.dev?.enable ?? false;\n logger.info('start check project config');\n const gameJsonConfigPath = path.join(entryDir, GAME_PROJECT_CONFIG_FILE_NAME);\n if (!fs.existsSync(gameJsonConfigPath)) {\n const errMsg =\n 'Check project config failed, can not find project.config.json in game source code, please check it';\n logger.error(errMsg);\n if (enableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n return {\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_PROJECT_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n };\n } else {\n throw new Error(errMsg);\n }\n } else {\n let gameJsonConfig: any;\n try {\n gameJsonConfig = JSON.parse(fs.readFileSync(gameJsonConfigPath, 'utf-8'));\n const appid = gameJsonConfig?.appid;\n if (!appid) {\n const errMsg =\n 'Check project config failed, can not find appid in project.config.json, you should add appid(client_key) in project.config.json';\n logger.error(errMsg);\n if (enableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n return {\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_PROJECT_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n };\n } else {\n throw new Error(errMsg);\n }\n } else {\n const msg =\n 'Check project config successfully, appid in project.config.json is valid';\n logger.info(msg);\n return {\n passed: true,\n type: 'config',\n file: GAME_PROJECT_CONFIG_FILE_NAME,\n msg,\n ...defaultCheckConfig,\n };\n }\n } catch (error) {\n const errMsg =\n 'Check project config failed, project.config.json is invalid json format';\n logger.error(errMsg);\n if (enableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n return {\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_PROJECT_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n };\n } else {\n throw error;\n }\n }\n }\n}\n","import * as path from 'path';\nimport * as fs from 'fs';\nimport {\n BuildConfig,\n CheckConfigResult,\n CheckSizeResult,\n CheckDimension,\n} from '@typings';\nimport { CHECK_DIMENSION, GAME_ENGINES } from '@constants';\nimport { logger, getMainPkgSize, getGameEngine } from '@utils';\nconst defaultCheckConfig: {\n name: string;\n dimension: CheckDimension;\n} = {\n name: 'main',\n dimension: CHECK_DIMENSION.MainPackage,\n};\n/**\n * 检查主包大小是否超出限制\n * @param param0\n * @returns\n */\nexport function checkMainPackageSize({\n entryDir,\n config,\n}: {\n entryDir: string;\n config: BuildConfig;\n}): CheckSizeResult {\n logger.info('start check main package size');\n const { build, dev } = config;\n const mainPkgSize = getMainPkgSize({ entryDir });\n const mainPkgSizeMB = (mainPkgSize / (1024 * 1024)).toFixed(2);\n const limitMB = (build.mainPkgSizeLimit / (1024 * 1024)).toFixed(2);\n if (mainPkgSize > build.mainPkgSizeLimit) {\n const errMsg = `Check main package size failed, main package size ${mainPkgSizeMB}MB, must not exceed ${limitMB}MB`;\n logger.error(errMsg);\n if (dev?.enable) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n return {\n passed: false,\n msg: errMsg,\n size: mainPkgSize,\n type: 'size',\n ...defaultCheckConfig,\n };\n } else {\n throw new Error(errMsg);\n }\n } else {\n return {\n passed: true,\n msg: `Check main package size successfully, size: ${mainPkgSizeMB}MB`,\n size: mainPkgSize,\n type: 'size',\n ...defaultCheckConfig,\n };\n }\n}\n\nexport function checkMainPackageEntry({\n entryDir,\n config,\n}: {\n entryDir: string;\n config: BuildConfig;\n}): CheckConfigResult {\n logger.info('start check main package entry');\n const gameJsPath = path.join(entryDir, 'game.js');\n if (!fs.existsSync(gameJsPath)) {\n const errMsg =\n 'Check main package entry failed, game.js must exist in main package!';\n logger.error(errMsg);\n if (config.dev?.enable) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', errMsg);\n return {\n passed: false,\n msg: errMsg,\n type: 'config',\n file: 'game.js',\n ...defaultCheckConfig,\n };\n }\n }\n logger.info('check game.js successfully');\n return {\n passed: true,\n msg: 'Check main package entry successfully, game.js must exist in main package!',\n type: 'config',\n file: 'game.js',\n ...defaultCheckConfig,\n };\n}\n\nexport function checkMainPackage(\n entryDir: string,\n config: BuildConfig,\n): (CheckConfigResult | CheckSizeResult)[] {\n const checkResults = [];\n\n logger.info('start check main package');\n\n /**\n * 检查 game.js 是否存在\n */\n\n checkResults.push(\n checkMainPackageEntry({\n entryDir,\n config,\n }),\n );\n\n /**\n * 检查主包大小是否超出限制, 仅对非unity工程生效\n */\n if (config.build?.mainPkgSizeLimit) {\n checkResults.push(\n checkMainPackageSize({\n entryDir,\n config,\n }),\n );\n }\n if (checkResults.every(item => item.passed)) {\n logger.info('Check main package successfully');\n }\n return checkResults;\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { logger, getSubpackagesConfig } from '@utils';\nimport { GAME_ORIGIN_CONFIG_FILE_NAME } from '@constants';\nimport {\n CheckConfigResult,\n CheckSizeResult,\n BuildConfig,\n CheckDimension,\n} from '@typings';\n\nconst defaultCheckConfig: {\n name: string;\n dimension: CheckDimension;\n} = {\n name: 'subpackage',\n dimension: 'subpackage',\n};\n\nexport function checkSubpackages(\n entryDir: string,\n config?: BuildConfig,\n): (CheckConfigResult | CheckSizeResult)[] {\n const checkResults: (CheckConfigResult | CheckSizeResult)[] = [];\n /**\n * 校验 subpackage 大小\n * 开始校验 subpackages 配置是否有效\n */\n logger.info('start check subpackages in game.json');\n const subpackages = getSubpackagesConfig(entryDir);\n subpackages.forEach(sub => {\n /**\n * 校验 subpackage 配置是否为空\n */\n if (!sub.name || !sub.root) {\n const errMsg =\n 'Check subpackages config failed, the subpackages configuration in game.json is invalid: the root or name field in one or more subpackages is empty. Please ensure that all subpackages have non-empty root and name values.';\n logger.error(errMsg);\n if (config?.dev?.enable) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n checkResults.push({\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n });\n } else {\n throw new Error(errMsg);\n }\n } else {\n checkResults.push({\n passed: true,\n msg: `Check subpackage<${sub.name}> config successfully`,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n });\n }\n /**\n * 校验 subpackage 配置是否有效\n */\n const subpackageEntryDir = path.join(entryDir, sub.root);\n // 检查是文件或者文件夹是否存在\n if (!fs.existsSync(subpackageEntryDir)) {\n const errMsg = `Check subpackage<${sub.name}> config failed, the subpackages configuration in game.json is invalid: can not find subpackage ${sub.name} entry dir, please check it`;\n logger.error(errMsg);\n if (config?.dev?.enable) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n checkResults.push({\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n });\n } else {\n throw new Error(errMsg);\n }\n } else {\n checkResults.push({\n passed: true,\n msg: `Check subpackage<${sub.name}> config successfully`,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n ...defaultCheckConfig,\n });\n }\n });\n if (checkResults.length && checkResults.every(item => item.passed)) {\n logger.info('Check subpackages config successfully');\n }\n return checkResults;\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { GAME_ORIGIN_CONFIG_FILE_NAME } from '@constants';\n\nexport function getSubpackagesConfig(entryDir: string) {\n try {\n const gameOriginConfigPath = path.join(\n entryDir,\n GAME_ORIGIN_CONFIG_FILE_NAME,\n );\n const gameOriginConfig = JSON.parse(\n fs.readFileSync(gameOriginConfigPath, 'utf-8'),\n );\n return gameOriginConfig?.subpackages?.filter(sub => !sub.independent) || [];\n } catch (e) {\n return [];\n }\n}\n","import path from 'path';\nimport fs from 'fs';\nimport {\n logger,\n getIndependentPackagesConfig,\n getDirSizeSync,\n getGameEngine,\n} from '@utils';\nimport {\n BuildConfig,\n CheckConfigResult,\n CheckDimension,\n CheckSizeResult,\n} from '@typings';\nimport {\n GAME_ORIGIN_CONFIG_FILE_NAME,\n CHECK_DIMENSION,\n} from '@constants';\n\nconst defaultCheckConfig: {\n dimension: CheckDimension;\n} = {\n dimension: CHECK_DIMENSION.IndependentPackage,\n};\nexport function checkIndependentPackages(\n entryDir: string,\n config?: BuildConfig,\n) {\n const isEnableDev = config?.dev?.enable;\n const checkResults: (CheckConfigResult | CheckSizeResult)[] = [];\n /**\n * 开始校验 subpackages 配置是否有效\n */\n logger.info('start check independent subpackages in game.json');\n const independentSubpackages = getIndependentPackagesConfig(entryDir);\n independentSubpackages.forEach(sub => {\n /**\n * 校验 independent subpackage 配置是否为空\n */\n if (!sub.name || !sub.root) {\n const errMsg =\n 'Check independent subpackages config failed, the subpackages configuration in game.json is invalid: the root or name field in one or more independent subpackages is empty. Please ensure that all independent subpackages have non-empty root and name values.';\n logger.error(errMsg);\n if (isEnableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️${errMsg}`);\n checkResults.push({\n ...defaultCheckConfig,\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n name: sub.name,\n });\n } else {\n throw new Error(errMsg);\n }\n } else {\n checkResults.push({\n ...defaultCheckConfig,\n passed: true,\n msg: `Check independent package<${sub.name}> config successfully`,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n name: sub.name,\n });\n }\n /**\n * 校验 independent subpackage 配置是否有效\n */\n const subpackageEntryDir = path.join(entryDir, sub.root);\n\n // 检查是文件或者文件夹是否存在\n if (!fs.existsSync(subpackageEntryDir)) {\n const errMsg = `Check independent package<${sub.name}> config failed, the subpackages configuration in game.json is invalid: can not find subpackage ${sub.name} entry dir, please check it`;\n logger.error(errMsg);\n if (isEnableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${errMsg}`);\n checkResults.push({\n ...defaultCheckConfig,\n passed: false,\n msg: errMsg,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n name: sub.name,\n });\n } else {\n throw new Error(errMsg);\n }\n } else {\n checkResults.push({\n passed: true,\n msg: `Check independent package<${sub.name}> config successfully`,\n type: 'config',\n file: GAME_ORIGIN_CONFIG_FILE_NAME,\n dimension: CHECK_DIMENSION.IndependentPackage,\n name: sub.name,\n });\n }\n /**\n * 校验 independent subpackage 包大小,不做校验\n */\n const independentSubPkgSizeLimit =\n config?.build?.independentSubPkgSizeLimit;\n if (independentSubPkgSizeLimit) {\n const checkSizeResult = checkPkgSize({\n entryDir: subpackageEntryDir,\n pkgName: sub.name,\n limit: independentSubPkgSizeLimit,\n dimension: CHECK_DIMENSION.IndependentPackage,\n });\n checkResults.push(checkSizeResult);\n logger.info(checkSizeResult.msg);\n if (!checkSizeResult.passed) {\n if (isEnableDev) {\n console.log('\\x1b[1m\\x1b[33m%s\\x1b[0m', `❗️ ${checkSizeResult.msg}`);\n } else {\n throw new Error(checkSizeResult.msg);\n }\n }\n }\n });\n if (checkResults.length && checkResults.every(item => item.passed)) {\n logger.info('Check independent subpackages config successfully');\n }\n return checkResults;\n}\n\nexport function checkPkgSize({\n entryDir,\n limit,\n pkgName,\n dimension,\n}: {\n entryDir: string;\n limit: number;\n pkgName: string;\n dimension: CheckSizeResult['dimension'];\n}): CheckSizeResult {\n const size = getDirSizeSync({\n rootDir: entryDir,\n entryDir,\n filterDirs: [],\n });\n const passed = size <= limit;\n const sizeMB = size / 1024 / 1024;\n const limitMB = limit / 1024 / 1024;\n return {\n passed,\n msg: passed\n ? `Check package ${pkgName} size ${sizeMB.toFixed(2)}MB check successfully`\n : `Check package ${pkgName} size ${sizeMB.toFixed(2)}MB exceeds limit ${limitMB.toFixed(2)}MB`,\n type: 'size',\n size,\n dimension,\n name: pkgName,\n };\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { CheckAPIResult, BuildConfig } from '@typings';\n\n/**\n * 检查游戏产物中是否调用了指定的 API\n */\n\nconst API_LIST: {\n name: string;\n desc: string;\n}[] = [\n {\n name: 'login',\n desc: 'Login to get open id',\n },\n {\n name: 'createRewardedVideoAd',\n desc: 'Integrate rewarded video ads',\n },\n \n {\n name: 'addShortcut',\n desc: 'Add game shortcut to home screen',\n },\n {\n name: \"getShortcutMissionReward\",\n desc: \"Get shortcut mission reward\"\n },\n {\n name: 'startEntranceMission',\n desc: 'Jump to TikTok personal sidebar',\n },\n {\n name: \"getEntranceMissionReward\",\n desc: \"Get entrance mission reward\"\n }\n];\n\ntype CheckResult = Array<CheckAPIResult>;\n\nexport function checkAPI({\n entryDir,\n config,\n}: {\n entryDir: string;\n config: BuildConfig;\n}): CheckResult {\n if (!config?.build?.enableAPICheck) {\n return [];\n }\n const exts = ['.js', '.ts'];\n // 预编译正则,尽量减少误报:匹配独立的标识符或对象调用形式\n // 例如:\\b(login)\\b 或 \\.login\\s*\\( 或 =\\s*login\\b\n const apiRegexMap = new Map<string, RegExp>(\n API_LIST.map(({ name }) => {\n // 组合模式:独立词边界 或 点调用 或 解构/赋值场景\n const pattern = [\n `\\\\b${escapeRegex(name)}\\\\b`, // 独立标识符\n `\\\\.${escapeRegex(name)}\\\\s*\\\\(`, // 对象.方法(\n `\\\\b${escapeRegex(name)}\\\\s*:\\\\s*`, // 对象字面量属性\n `\\\\b${escapeRegex(name)}\\\\s*=`, // 赋值给该名\n `\\\\b${escapeRegex(name)}\\\\s*\\\\(`, // 直接函数调用\n ].join('|');\n return [name, new RegExp(pattern, 'm')];\n }),\n );\n\n // 结果初始化\n const hitFilesMap = new Map<string, Set<string>>();\n for (const { name } of API_LIST) {\n hitFilesMap.set(name, new Set());\n }\n\n // 深度优先遍历\n const stack: string[] = [entryDir];\n while (stack.length) {\n const current = stack.pop()!;\n const stat = fs.statSync(current);\n\n if (stat.isDirectory()) {\n // 可根据需要排除目录\n const base = path.basename(current);\n if (\n ['node_modules', '.git', 'dist', 'build', 'out', '.cache'].includes(\n base,\n )\n ) {\n continue;\n }\n const children = fs.readdirSync(current);\n for (const child of children) {\n stack.push(path.join(current, child));\n }\n continue;\n }\n\n // 文件:后缀过滤\n const ext = path.extname(current).toLowerCase();\n if (!exts.includes(ext)) {\n continue;\n }\n\n // 读取文本\n let content = '';\n try {\n content = fs.readFileSync(current, 'utf8');\n } catch {\n // 读取失败则跳过\n continue;\n }\n\n // 粗略跳过很大的文件,避免性能问题(可调)\n if (content.length > 5_000_000) continue;\n\n // 检测每个 API\n for (const { name } of API_LIST) {\n const reg = apiRegexMap.get(name)!;\n if (reg.test(content)) {\n hitFilesMap.get(name)!.add(current);\n }\n }\n }\n\n const results: CheckResult = API_LIST.map(({ name }) => {\n const files = Array.from(hitFilesMap.get(name) || []);\n return {\n name,\n msg: `${files.length > 0 ? `${name} integrated!` : `${name} not integrated!`}`,\n passed: files.length > 0,\n files,\n type: 'api',\n required: false,\n dimension: 'project',\n };\n });\n return results;\n}\n\n/**\n * 转义正则特殊字符\n */\nfunction escapeRegex(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n","import { logger } from '@utils';\nimport { BuildConfig } from '@typings';\nimport { CheckResult } from '@typings';\nimport { checkProject } from './checkProject';\nimport { checkMainPackage } from './checkMainpackage';\nimport { checkSubpackages } from './checkSubpackages';\nimport { checkIndependentPackages } from './checkIndependentPackages';\nimport { checkAPI } from './checkAPI';\n\nexport async function checkPkgs({\n entryDir,\n config,\n}: {\n entryDir: string;\n config: BuildConfig;\n}): Promise<CheckResult[]> {\n logger.info('开始校验项目');\n /**\n * 1. 校验项目\n */\n const projectCheckResult = checkProject(entryDir, config);\n /**\n * 2. 校验主包\n */\n const mainPackageCheckResult = checkMainPackage(entryDir, config);\n /**\n * 3. 如果有,校验分包\n */\n const subpackagesCheckResult = checkSubpackages(entryDir, config);\n\n /**\n * 校验独立分包\n */\n const independentPackagesCheckResult = checkIndependentPackages(\n entryDir,\n config,\n );\n\n /**\n * 校验 API 调用\n */\n const apiCheckResult = checkAPI({ entryDir, config });\n\n return [\n ...projectCheckResult,\n ...mainPackageCheckResult,\n ...subpackagesCheckResult,\n ...independentPackagesCheckResult,\n ...apiCheckResult,\n ];\n}\n","import fs from 'fs';\nimport path from 'path';\nimport {\n GAME_PACK_CONFIG_FILE_NAME,\n GAME_ORIGIN_CONFIG_FILE_NAME,\n GAME_MAIN_PACKAGE_NAME,\n STTPKG_EXT,\n PACKAGE_TYPE,\n} from '@constants';\n\nimport { logger } from '@utils';\n\nexport async function setup(entryDir: string, outputDir: string) {\n logger.info('开始基于源代码中的 game.json 生成 packageConfig.json');\n const gameJsonPath = path.join(entryDir, GAME_ORIGIN_CONFIG_FILE_NAME);\n const gameJson = JSON.parse(fs.readFileSync(gameJsonPath, 'utf-8'));\n\n const packages = {};\n // fyf for your feed 缩写,代表可用于视频锚点投放使用的包\n const fyfPackages = [\n {\n value: GAME_MAIN_PACKAGE_NAME,\n label: 'Main (Main package)',\n type: PACKAGE_TYPE.MainPackage,\n },\n ];\n\n // 主包\n packages[GAME_MAIN_PACKAGE_NAME] = {\n url: '',\n md5: '',\n root: '',\n main: 'game.js',\n output: `${GAME_MAIN_PACKAGE_NAME}${STTPKG_EXT}`,\n };\n\n transformSubPackages(gameJson.subpackages).forEach(\n ({ name, root, main, independent }) => {\n // root 是目录\n packages[name] = {\n url: '',\n md5: '',\n root,\n main,\n output: `${name}${STTPKG_EXT}`,\n independent,\n };\n if (independent) {\n fyfPackages.push({\n value: name,\n label: `${name} (Independent package)`,\n type: PACKAGE_TYPE.IndependentPackage,\n });\n }\n },\n );\n\n const result = {\n packages,\n fyf_packages: fyfPackages,\n };\n if (fs.existsSync(outputDir)) {\n fs.rmSync(outputDir, { recursive: true });\n }\n fs.mkdirSync(outputDir);\n fs.writeFileSync(\n path.join(outputDir, GAME_PACK_CONFIG_FILE_NAME),\n JSON.stringify(result, null, 2),\n );\n logger.info('基于源代码中的 game.json 生成 packageConfig.json 成功');\n return result;\n}\n\nfunction transformSubPackages(\n configs: Array<{\n name: string;\n root: string;\n independent?: boolean;\n }>,\n) {\n if (!configs || configs.length === 0) {\n return [];\n }\n function normalizeName(name) {\n return String(name).replace(/^\\/+|\\/+$/g, '');\n }\n\n function getMainFromRoot(root: string) {\n if (isDirectory(root)) {\n // 将 Windows 下的 \\\\ 替换为 /\n return path.join(root, 'game.js').replace(/\\\\/g, '/');\n }\n return root;\n }\n\n function isDirectory(str) {\n // 以 / 结尾,或没有 .js 结尾且没有 . 号\n return str.endsWith('/') || !/\\.[a-zA-Z0-9]+$/.test(str);\n }\n\n function normalizeRoot(root: string): string {\n // 去掉头部和尾部的所有斜杠\n return root.replace(/^\\/+|\\/+$/g, '');\n }\n\n return configs.map(config => {\n const name = normalizeName(config.name);\n let main = getMainFromRoot(config.root);\n // test\n let root = normalizeRoot(config.root);\n return { main, root, name, independent: config.independent || false };\n });\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { logger } from '@utils';\n\nexport function flattenMaps(allMaps) {\n const list = [];\n Object.values(allMaps).forEach(map => {\n Object.values(map).forEach(arr => {\n list.push(...arr);\n });\n });\n return list;\n}\n// 递归收集 JS 文件,但可排除指定目录\nfunction collectPkgJsFiles({\n entry,\n root,\n exts = ['.js', '.ts', '.jsx', '.tsx'],\n excludeDirs = [],\n}: {\n entry: string;\n root: string;\n exts: string[];\n excludeDirs: string[];\n}) {\n let files = [];\n if (!fs.existsSync(entry)) return files;\n const entries = fs.readdirSync(entry, { withFileTypes: true });\n for (const item of entries) {\n const fullPath = path.join(entry, item.name);\n if (item.isDirectory()) {\n /**\n * 计算 item 与 root 的相对路径\n */\n /**\n * 讲 \\ 替换为 /\n */\n const relativePath = path.relative(root, fullPath).replace(/\\\\/g, '/');\n if (excludeDirs.find(dir => dir === relativePath)) {\n continue; // 跳过排除目录\n }\n files = files.concat(\n collectPkgJsFiles({\n entry: fullPath,\n root: root,\n exts: exts,\n excludeDirs,\n }),\n ); // 只排除一级\n } else if (exts.some(ext => item.name.endsWith(ext))) {\n files.push(fullPath);\n }\n }\n return files;\n}\n\n// 构建每个包的 map\nexport function collectMaps(\n entryDir,\n packages: Record<string, { root: string }>,\n) {\n logger.info('开始基于游戏源代码收集分包中的 JS 文件');\n const result = {};\n // 1. 先收集所有分包根目录名(如 subpackages/level1、subpackages/level2)\n const subRoots = Object.values(packages)\n .filter(pkg => pkg.root && pkg.root !== '')\n .map(pkg => pkg.root) // 只提取一级目录名\n .filter(Boolean);\n const uniqueSubRoots = Array.from(new Set(subRoots));\n\n for (const pkgName in packages) {\n const pkg = packages[pkgName];\n let srcRoot;\n let jsFiles;\n if (pkgName === '__GAME__') {\n // 主包:只收集 entryDir 下非分包目录\n jsFiles = collectPkgJsFiles({\n entry: entryDir,\n root: entryDir,\n exts: ['.js', '.ts', '.jsx', '.tsx'],\n excludeDirs: uniqueSubRoots,\n });\n srcRoot = entryDir;\n } else {\n // 分包:只收集自己目录\n srcRoot = path.join(entryDir, pkg.root);\n jsFiles = collectPkgJsFiles({\n entry: srcRoot,\n root: srcRoot,\n exts: ['.js', '.ts', '.jsx', '.tsx'],\n excludeDirs: [],\n });\n }\n // 以包的 srcRoot 为基准生成相对路径\n const list = [];\n jsFiles.forEach(absPath => {\n list.push(path.relative(entryDir, absPath).replace(/\\\\/g, '/'));\n });\n const packNameRoot = packages[pkgName].root;\n result[pkgName] = {\n [packNameRoot ? `${packNameRoot}/game.pack.js` : 'game.pack.js']: list,\n };\n }\n logger.info('基于游戏源代码收集分包中的 JS 文件完成');\n return result;\n}\n","import fs from 'fs';\nimport path from 'path';\nimport acorn from 'acorn';\nimport glob from 'glob';\n\nexport function collectDeps(gameEntry, packages) {\n // 自动扫描 game 目录下的一级文件夹作为根前缀\n const rootPrefixes = getRootPrefixes(gameEntry);\n\n // 查找所有 JS 文件\n const files = glob.sync('**/*.js', {\n cwd: gameEntry,\n ignore: [],\n });\n\n const requireCalls = [];\n\n files.forEach(file => {\n const fullPath = path.join(gameEntry, file);\n const code = fs.readFileSync(fullPath, 'utf-8');\n\n let ast;\n try {\n ast = acorn.parse(code, { ecmaVersion: 'latest', sourceType: 'module' });\n } catch (e) {\n // 跳过无法解析的文件\n return;\n }\n\n walkAst(ast, node => {\n // require('xxx') 或 requireAsync('xxx')\n if (\n node.type === 'CallExpression' &&\n node.callee.type === 'Identifier' &&\n (node.callee.name === 'require' ||\n node.callee.name === 'requireAsync') &&\n node.arguments.length > 0 &&\n node.arguments[0].type === 'Literal' &&\n typeof node.arguments[0].value === 'string'\n ) {\n const requirePath = node.arguments[0].value;\n let resolvedPath = null;\n\n if (requirePath.startsWith('.')) {\n resolvedPath = path.resolve(path.dirname(fullPath), requirePath);\n } else if (requirePath.startsWith('/')) {\n resolvedPath = path.resolve(gameEntry, '.' + requirePath);\n } else {\n for (const prefix of rootPrefixes) {\n if (requirePath.startsWith(prefix)) {\n resolvedPath = path.resolve(gameEntry, requirePath);\n break;\n }\n }\n }\n\n // 校验文件是否存在(支持 .js/.ts/.jsx/.tsx 后缀自动补全)\n if (resolvedPath && !fileExistsWithExtensions(resolvedPath)) {\n resolvedPath = null;\n }\n\n requireCalls.push({\n file: path.relative(gameEntry, fullPath),\n callee: node.callee.name,\n requirePath,\n resolvedPath: resolvedPath\n ? path.relative(gameEntry, resolvedPath)\n : '',\n });\n }\n });\n });\n\n const newRequireCalls = requireCalls.map(i => {\n /**\n * 基于 packages 来判断\n */\n let depModule = '';\n Object.keys(packages).forEach(pkg => {\n if (i.resolvedPath && i.resolvedPath.startsWith(packages[pkg].root)) {\n depModule = pkg;\n }\n });\n\n let curModule = '';\n Object.keys(packages).forEach(pkg => {\n if (i.file.startsWith(packages[pkg].root)) {\n curModule = pkg;\n }\n });\n return {\n ...i,\n curModule,\n depModule,\n };\n });\n\n // 只统计 JS/TS/JSX/TSX 文件依赖\n const exts = ['.js', '.ts', '.jsx', '.tsx'];\n const isJsLike = f => exts.some(ext => f.endsWith(ext));\n\n const result = newRequireCalls.reduce((acc, cur) => {\n if (!acc[cur.curModule]) {\n acc[cur.curModule] = {};\n }\n if (cur.curModule === cur.depModule) {\n return acc;\n }\n if (cur.resolvedPath && isJsLike(cur.resolvedPath)) {\n acc[cur.curModule] = {\n ...acc[cur.curModule],\n [cur.resolvedPath]: cur.depModule,\n };\n }\n return acc;\n }, {});\n return result;\n}\n\nfunction getRootPrefixes(gameEntry) {\n return fs\n .readdirSync(gameEntry)\n .filter(name => {\n const fullPath = path.join(gameEntry, name);\n return (\n fs.statSync(fullPath).isDirectory() &&\n !['node_modules', 'dist', 'build', 'output'].includes(name)\n );\n })\n .map(name => name + '/');\n}\n\nfunction walkAst(node, cb) {\n cb(node);\n for (let key in node) {\n if (node.hasOwnProperty(key)) {\n const child = node[key];\n if (Array.isArray(child)) {\n child.forEach(c => c && typeof c.type === 'string' && walkAst(c, cb));\n } else if (child && typeof child.type === 'string') {\n walkAst(child, cb);\n }\n }\n }\n}\n\n// 支持 .js/.ts/.jsx/.tsx 自动补全\nfunction fileExistsWithExtensions(filePath) {\n if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) return true;\n const exts = ['.js', '.ts', '.jsx', '.tsx'];\n for (const ext of exts) {\n if (fs.existsSync(filePath + ext) && fs.statSync(filePath + ext).isFile())\n return true;\n }\n return false;\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { ensureDirSync } from '@utils';\n\nexport async function partition({\n pkgRoot,\n destRoot,\n packedFiles,\n gameEntry,\n gameOutput,\n skipDirs = [],\n isRoot = true,\n}) {\n if (!fs.existsSync(pkgRoot)) return;\n const entries = fs.readdirSync(pkgRoot, { withFileTypes: true });\n for (const entry of entries) {\n const srcPath = path.join(pkgRoot, entry.name);\n const destPath = path.join(destRoot, entry.name);\n const fullPath = path.join(pkgRoot, entry.name);\n // 只在第一层判断是否跳过分包目录\n if (entry.isDirectory()) {\n const relativePath = path.relative(gameEntry, fullPath).replace(/\\\\/g, '/');\n if (skipDirs.find(dir => dir === relativePath)) {\n continue; // 跳过分包目录\n }\n }\n if (entry.isDirectory()) {\n partition({\n pkgRoot: srcPath,\n destRoot: destPath,\n gameOutput,\n packedFiles,\n gameEntry,\n skipDirs,\n isRoot: false, // 递归下去不再判断\n });\n } else {\n ensureDirSync(path.dirname(destPath));\n if (!packedFiles.includes(path.relative(gameEntry, srcPath).replace(/\\\\/g, '/'))) {\n fs.copyFileSync(srcPath, destPath);\n }\n }\n }\n}\n","import path from 'path';\nimport { BuildConfig, ProjectConfig } from '@typings';\nimport { logger, removeEmptyDir, removeSystemUseless, asyncPool } from '@utils';\nimport { setup } from './setup';\nimport { flattenMaps, collectMaps } from './collectMaps';\nimport { collectDeps } from './collectDeps';\nimport { pack } from './pack';\nimport { partition } from './partition';\n\nfunction getSkipDirs(packages: ProjectConfig['packages']\n) {\n const skipDirs = [];\n if (packages) {\n skipDirs.push(...Object.values(packages).map(item => item.root));\n }\n return skipDirs;\n}\n\nexport async function makePkgs({\n gameEntry,\n gameOutput,\n config,\n}: {\n gameEntry: string;\n gameOutput: string;\n config: BuildConfig;\n}) {\n let startTime = Date.now();\n removeSystemUseless(gameEntry);\n logger.info(`pack start,startTime:${startTime}`);\n const { packages } = await setup(gameEntry, gameOutput);\n const allDeps = collectDeps(gameEntry, packages);\n const allMaps = collectMaps(gameEntry, packages);\n const pkgOutput = {};\n\n /**\n * 基于 asyncPool 并发打包\n */\n\n await asyncPool(10, Object.keys(allMaps), async pkgName => {\n logger.info(`开始基于游戏源代码打包,包名:${pkgName}`);\n let startTime = Date.now();\n const pkgConfig = packages[pkgName];\n const pkgRoot = path.join(gameEntry, pkgConfig.root);\n const destRoot = path.join(gameOutput, pkgName, pkgConfig.root);\n /**\n * 打包\n */\n await pack({\n gameEntry,\n allDeps,\n allMaps,\n pkgName,\n pkgConfig,\n destRoot,\n config,\n });\n\n /**\n * 分包\n */\n await partition({\n gameEntry,\n gameOutput,\n pkgRoot,\n destRoot,\n packedFiles: flattenMaps(allMaps),\n // 这里写的不对,应该是 每一个分包都要跳过\n skipDirs: getSkipDirs(packages),\n });\n\n const pkgRootDir = path.join(gameOutput, pkgName);\n removeEmptyDir(pkgRootDir);\n logger.info(`基于游戏源代码打包分包完成,包名:${pkgName}`);\n logger.info(\n `基于游戏源代码打包分包耗时,包名:${pkgName},耗时:${Date.now() - startTime\n }ms`,\n );\n });\n\n\n logger.info(`pack end,duration:${Date.now() - startTime}ms`);\n\n return pkgOutput;\n}\n","export async function asyncPool<T, R>(\n poolLimit: number,\n array: T[],\n iteratorFn: (item: T) => Promise<R>,\n): Promise<R[]> {\n const ret: Promise<R>[] = [];\n const executing: Promise<void>[] = [];\n for (const item of array) {\n // 创建处理当前 item 的 Promise\n const p = Promise.resolve().then(() => iteratorFn(item));\n ret.push(p);\n\n if (poolLimit <= array.length) {\n // 包装 Promise,处理完成后从 executing 中移除\n const e = p.then(() => {\n executing.splice(executing.indexOf(e), 1);\n });\n executing.push(e);\n\n // 达到并发限制时,等待任意一个任务完成\n if (executing.length >= poolLimit) {\n await Promise.race(executing);\n }\n }\n }\n // 等待所有任务完成\n return Promise.all(ret);\n}\n","import fs from 'fs';\nimport path from 'path';\nimport MagicString, { Bundle } from 'magic-string';\nimport { transformSync } from 'esbuild'\nimport { GAME_MODULE_CONFIG_FILE_NAME } from '@constants';\nimport { BuildConfig } from '@typings';\nimport { logger, ensureDirSync } from '@utils';\n\nexport function pack({\n gameEntry,\n pkgName,\n allDeps,\n allMaps,\n pkgConfig,\n destRoot,\n config,\n}: {\n gameEntry: string;\n pkgName: string;\n allDeps: Record<string, string[]>;\n allMaps: Record<string, Record<string, string[]>>;\n pkgConfig: {\n main: string;\n root: string;\n };\n destRoot: string;\n config: BuildConfig;\n}) {\n let startTime = Date.now();\n logger.info(`pack start,startTime:${startTime}`);\n const packMap = allMaps[pkgName];\n const moduleConfig = {\n main: pkgConfig.main,\n deps: allDeps[pkgName] || {},\n map: allMaps[pkgName],\n };\n\n ensureDirSync(destRoot);\n fs.writeFileSync(\n path.join(destRoot, GAME_MODULE_CONFIG_FILE_NAME),\n JSON.stringify(moduleConfig),\n );\n\n for (const packFileName in packMap) {\n const relPaths = packMap[packFileName];\n if (!Array.isArray(relPaths) || relPaths.length === 0) continue;\n\n const concat = new Bundle({ separator: '\\n' });\n for (const relPath of relPaths) {\n const absPath = path.join(gameEntry, relPath);\n if (!fs.existsSync(absPath)) continue;\n if (path.basename(absPath) === packFileName) continue;\n\n if (/\\.js$/i.test(relPath)) {\n try {\n const { code } = transformSync(fs.readFileSync(absPath, 'utf-8'), {\n loader: 'js',\n format: 'cjs',\n target: 'es2015',\n minify: false, // 关闭压缩,避免字面量与属性被改写\n charset: 'utf8', // 避免 ascii-only 导致 unicode 再编码\n keepNames: true\n });\n // const code = fs.readFileSync(absPath, 'utf-8');\n const fileId = relPath.replace(/\\\\/g, '/');\n const defineHeader = `define(\"game:${fileId}\", [\"require\", \"requireAsync\", \"module\", \"exports\", \"sandboxGlobal\"], function(require, requireAsync, module, exports, sandboxGlobal){\\nwith(sandboxGlobal){\\n`;\n const defineFooter = `\\n}\\n});\\n`;\n const fileMagic = new MagicString(code, { filename: fileId });\n fileMagic.prepend(defineHeader);\n fileMagic.append(defineFooter);\n concat.addSource({ content: fileMagic, filename: fileId });\n } catch (e) {\n logger.error(`pack error, relPath:${relPath},e:${e}`);\n }\n }\n }\n const outFile = path.join(destRoot, path.basename(packFileName));\n const bundledCode = concat.toString();\n\n if (config?.dev?.enableSourcemap) {\n const map = concat.generateMap({\n hires: true,\n includeContent: true,\n file: path.basename(packFileName), // 推荐用最终输出文件名\n });\n /**\n * 如果是走内敛\n */\n if (config?.dev?.inlineSourcemap) {\n // 生成 base 64\n const base64 = Buffer.from(map.toString()).toString('base64');\n const sourcemapContent = `data:application/json;base64,${base64}`;\n // 4. 写入 sourcemap 内容\n const fileContent =\n bundledCode +\n `\\n//# sourceMappingURL=${sourcemapContent}` + // 只写文件名即可,和 JS 文件同目录\n `\\n//# sourceURL=${packFileName}`;\n fs.writeFileSync(outFile, fileContent, 'utf-8');\n } else {\n const sourcemapBaseUrl = `http://${config?.dev?.host}:${config?.dev?.port}/game/files`;\n // 1. 生成 sourcemap 文件路径\n const mapFileName = path.basename(packFileName) + '.map';\n const mapFilePath = path.join(destRoot, mapFileName);\n // 2. 写入 sourcemap 文件\n fs.writeFileSync(mapFilePath, map.toString(), 'utf-8');\n // 3. JS 文件末尾加外链注释\n const fileContent =\n bundledCode +\n `\\n//# sourceMappingURL=${sourcemapBaseUrl}/${packFileName}.map` + // 只写文件名即可,和 JS 文件同目录\n `\\n//# sourceURL=${packFileName}`;\n fs.writeFileSync(outFile, fileContent, 'utf-8');\n }\n } else {\n const fileContent = bundledCode + `\\n//# sourceURL=${packFileName}`;\n\n fs.writeFileSync(outFile, fileContent, 'utf-8');\n }\n\n logger.info(`pack end,packName:${pkgName}`);\n }\n}\n","/**\n * 合并请求拆包\n */\nimport fs from 'fs';\nimport path from 'path';\nimport { getDirSizeSync, logger } from '@utils';\nimport { downloadAndSaveCodesAsync } from './utils';\nimport { AVAILABLE_ODR_TAG_LIST, ONE_ODR_PKG_LIMIT } from '@constants';\nimport { getOdrConfigs } from './getConfigs';\n\nexport async function buildOdrPkgs({ tempDir }: { tempDir: string }) {\n if (fs.existsSync(tempDir)) {\n fs.rmSync(tempDir, { recursive: true });\n }\n fs.mkdirSync(tempDir);\n const games = getOdrConfigs();\n logger.info('odr_games');\n await downloadAndSaveCodesAsync(games, tempDir);\n const gamesContentSize = {};\n for (const game of games) {\n const { id: gameId } = game;\n const gameDir = path.join(tempDir, gameId);\n gamesContentSize[gameId] = getDirSizeSync({\n rootDir: tempDir,\n entryDir: gameDir,\n filterDirs: [],\n });\n }\n // ODR TAG 分配\n const odrTagGameMap = {};\n AVAILABLE_ODR_TAG_LIST.forEach(tag => {\n odrTagGameMap[tag] = [];\n });\n // 用于产出 TTMGODRConfig\n const TTMGODRConfig = {};\n for (const game of games) {\n const { id: gameId, packages } = game;\n const gameSize = gamesContentSize[gameId];\n if (gameSize > ONE_ODR_PKG_LIMIT) continue;\n let assignedTag = null;\n for (const odrTag of AVAILABLE_ODR_TAG_LIST) {\n const odrTagDir = path.join(tempDir, odrTag);\n if (!fs.existsSync(odrTagDir)) fs.mkdirSync(odrTagDir);\n const currentTagSize = odrTagGameMap[odrTag].reduce(\n (sum, gid) => sum + gamesContentSize[gid],\n 0,\n );\n if (currentTagSize + gameSize <= ONE_ODR_PKG_LIMIT) {\n // 复制资源\n const srcDir = path.join(tempDir, gameId);\n const destDir = path.join(odrTagDir, gameId);\n fs.cpSync(srcDir, destDir, { recursive: true });\n odrTagGameMap[odrTag].push(gameId);\n assignedTag = odrTag;\n break;\n }\n }\n if (!assignedTag) continue; // 没有分配成功就跳过\n // 构建 TTMGODRConfig\n\n TTMGODRConfig[gameId] = {\n tag: assignedTag,\n packages: {},\n };\n for (const packageName in packages) {\n const pkg = packages[packageName];\n logger.info(`TTMGODRConfig[gameId].packages, ${pkg}, ${packageName}`);\n TTMGODRConfig[gameId].packages[packageName] = {\n root: pkg.root,\n main: pkg.main,\n // code_md5: pkg.code_md5,\n asset_md5: pkg.asset_md5,\n asset_url: pkg.asset_url,\n };\n }\n console.log(`finish to build ${gameId}`);\n fs.rmSync(path.join(tempDir, gameId), { recursive: true });\n }\n // 写入 JSON 文件\n const configPath = path.join(tempDir, 'TTMG_ODR_CONFIG.json');\n fs.writeFileSync(configPath, JSON.stringify(TTMGODRConfig, null, 2), 'utf-8');\n logger.info(`TTMG_ODR_CONFIG.json 已生成: ${configPath}`);\n}\n","import data from './config.json';\n\nexport function getOdrConfigs() {\n const { MinisPackagingInfoMap } = data;\n return Object.keys(MinisPackagingInfoMap).map(clientKey => {\n return {\n id: clientKey,\n packages: JSON.parse(MinisPackagingInfoMap[clientKey].ODRPackages),\n };\n });\n}\n","import { logger, overrideConfig } from '@utils';\nimport { BuildConfig } from '@typings';\nimport { checkPkgs } from '../checkPkgs';\nimport { makePkgs } from '../makePkgs';\nimport { makeOdrPkgs } from '../odrPkgs';\n\nexport async function buildPkgs(originConfig: BuildConfig) {\n const { entry: entryDir, output: outputDir, build } = originConfig;\n let startTime = Date.now();\n logger.init(outputDir, true);\n logger.info(`TTMG_PACK_VERSION: ${process.env.TTMG_PACK_VERSION}`);\n logger.info(`pack start, startTime:${startTime}`);\n const config = overrideConfig(entryDir, originConfig);\n\n /**\n * 校验\n */\n await checkPkgs({\n entryDir,\n config,\n });\n /**\n * 打包\n */\n await makePkgs({\n config,\n gameEntry: entryDir,\n gameOutput: outputDir,\n });\n\n if (build?.enableOdr) {\n /**\n * 等待文件全部读写完成后\n */\n await makeOdrPkgs(outputDir);\n /**\n * 分拆 odr 包\n */\n }\n\n logger.info(`pack end:${Date.now() - startTime}ms`);\n}\n","import path from 'path';\nimport fs from 'fs';\nimport {\n ensureDirSync,\n deleteNoJsFilesSync,\n logger,\n deleteJsFilesSync,\n} from '@utils';\n\nimport {\n GAME_PACK_CONFIG_FILE_NAME,\n ODR_ASSET_DIR_SUFFIX,\n ODR_CODE_DIR_SUFFIX,\n STTPKG_EXT,\n} from '@constants';\n\nexport async function makeOdrPkgs(outputDir: string) {\n let startTime = Date.now();\n logger.info(`makeOdrPkgs start, ${startTime}`);\n const outputPath = path.join(outputDir, GAME_PACK_CONFIG_FILE_NAME);\n const config = JSON.parse(fs.readFileSync(outputPath, 'utf-8'));\n const packages = config.packages;\n for (const pkgName in packages) {\n /**\n * 将原本的分包配置,转换为 odr 的配置,\n * 将原本产物按照原路径,分别拆分成两个文件夹:js 部分 package_name_code,asset 部分 package_name_asset\n */\n const pkgOutput = path.join(outputDir, pkgName);\n const codeOutput = path.join(outputDir, `${pkgName}${ODR_CODE_DIR_SUFFIX}`);\n const assetOutput = path.join(\n outputDir,\n `${pkgName}${ODR_ASSET_DIR_SUFFIX}`,\n );\n ensureDirSync(codeOutput);\n ensureDirSync(assetOutput);\n fs.cpSync(pkgOutput, codeOutput, { recursive: true });\n fs.cpSync(pkgOutput, assetOutput, { recursive: true });\n deleteNoJsFilesSync(codeOutput);\n deleteJsFilesSync(assetOutput);\n\n /**\n * 写入配置\n */\n packages[`${pkgName}${ODR_CODE_DIR_SUFFIX}`] = {\n ...packages[pkgName],\n code_url: '',\n code_md5: '',\n output: `${pkgName}${ODR_CODE_DIR_SUFFIX}${STTPKG_EXT}`,\n };\n packages[`${pkgName}${ODR_ASSET_DIR_SUFFIX}`] = {\n ...packages[pkgName],\n asset_url: '',\n asset_md5: '',\n output: `${pkgName}${ODR_ASSET_DIR_SUFFIX}${STTPKG_EXT}`,\n };\n }\n fs.writeFileSync(outputPath, JSON.stringify(config, null, 2));\n logger.info(`makeOdrPkgs end, ${Date.now() - startTime}ms`);\n}\n","import fs from 'fs';\nimport path from 'path';\nimport { logger, overrideConfig } from '@utils';\nimport { GAME_PACK_CONFIG_FILE_NAME } from '@constants';\nimport { BuildConfig, CheckResult, ProjectConfig } from '@typings';\nimport { checkPkgs } from '../checkPkgs';\nimport { mergePkgs } from '../mergePkgs';\nimport { makePkgs } from '../makePkgs';\n\nexport async function debugPkgs(originConfig: BuildConfig): Promise<{\n isSuccess: boolean;\n errorMsg?: string;\n packages?: ProjectConfig['packages'];\n checkResults?: CheckResult[];\n}> {\n const {\n entry: entryDir,\n output: outputDir,\n dev: { enableLog },\n } = originConfig;\n logger.init(outputDir, enableLog);\n const config = overrideConfig(entryDir, originConfig);\n try {\n /**\n * 校验\n */\n const checkResults = await checkPkgs({\n entryDir,\n config,\n });\n\n /**\n * 打包\n */\n await makePkgs({\n gameEntry: entryDir,\n gameOutput: outputDir,\n config,\n });\n\n /**\n * 合并\n */\n await mergePkgs(outputDir);\n\n /**\n * 返回 packageConfig\n */\n const packageConfig = fs.readFileSync(\n path.join(outputDir, GAME_PACK_CONFIG_FILE_NAME),\n 'utf-8',\n );\n const packageConfigJson = JSON.parse(packageConfig);\n return {\n isSuccess: true,\n packages: packageConfigJson.packages,\n checkResults,\n };\n } catch (error) {\n return {\n isSuccess: false,\n errorMsg: error.message,\n };\n }\n}\n","import path from 'path';\nimport fs from 'fs';\nimport { logger } from '@utils';\nimport { ProjectConfig } from '@typings';\nimport { GAME_PACK_CONFIG_FILE_NAME } from '@constants';\n\n/**\n * 将 packages 中的每个 package 下的文件内容合并到 outputDir 下,不保留 package name\n * @param outputDir 输出目录\n */\nexport async function mergePkgs(outputDir: string) {\n logger.info('mergePkgs start');\n const gamePackConfigPath = path.join(outputDir, GAME_PACK_CONFIG_FILE_NAME);\n let gamePackConfig: ProjectConfig;\n try {\n gamePackConfig = JSON.parse(fs.readFileSync(gamePackConfigPath, 'utf-8'));\n } catch (err) {\n logger.error(\n `读取配置文件失败: ${gamePackConfigPath}, err: ${err.message}`,\n );\n return;\n }\n\n const packages = gamePackConfig.packages;\n if (!packages || typeof packages !== 'object') {\n logger.error('配置文件中 packages 字段无效, 请检查配置');\n return;\n }\n\n for (const pkgName of Object.keys(packages)) {\n const pkgDir = path.join(outputDir, pkgName);\n if (!fs.existsSync(pkgDir)) {\n logger.warn(`package 目录不存在: ${pkgDir}`);\n continue;\n }\n\n const files = await fs.promises.readdir(pkgDir);\n for (const file of files) {\n const srcPath = path.join(pkgDir, file);\n const destPath = path.join(outputDir, file);\n\n try {\n const stat = await fs.promises.stat(srcPath);\n if (stat.isFile()) {\n await fs.promises.copyFile(srcPath, destPath);\n // 复制好了之后就删除\n await fs.promises.rm(srcPath, {\n recursive: true,\n force: true,\n });\n } else if (stat.isDirectory()) {\n await fs.promises.cp(srcPath, destPath, { recursive: true });\n // 复制好了之后就删除\n await fs.promises.rm(srcPath, { recursive: true, force: true }); \n } else if (stat.isSymbolicLink()) {\n const linkTarget = fs.readlinkSync(srcPath);\n // 判断目标是否已存在符号链接\n if (fs.existsSync(destPath)) {\n await fs.promises.rm(destPath, { force: true });\n }\n await fs.promises.symlink(\n linkTarget,\n destPath,\n stat.isDirectory() ? 'dir' : 'file',\n );\n }\n logger.info(`合并文件/目录: ${srcPath} -> ${destPath}`);\n } catch (err) {\n logger.error(`处理文件失败: ${srcPath}, err: ${err.message}`);\n }\n }\n /**\n * 如果最后 pkgDir 为空,就删除 \n */\n if (fs.readdirSync(pkgDir).length === 0) {\n fs.rmSync(pkgDir, { recursive: true, force: true });\n logger.info(`已删除 package 目录: ${pkgDir}`);\n }\n }\n\n logger.info('mergePkgs 完成');\n}\n","import path from 'path';\nimport { GAME_MAIN_PACKAGE_NAME } from '@constants';\nimport {\n getDirSizeSync,\n getIndependentPackagesConfig,\n getMainPkgSize,\n getProjectSize,\n} from '@utils';\n\ninterface GetPkgsResult {\n size: number;\n packages: {\n type: 'main' | 'subpackage' | 'independent';\n size: number;\n name: string;\n root: string;\n }[];\n}\n\nexport async function getPkgs({\n entryDir,\n}: {\n entryDir: string;\n}): Promise<GetPkgsResult> {\n const independentPackages = getIndependentPackagesConfig(entryDir);\n /**\n *\n */\n return {\n size: getProjectSize({\n entryDir,\n }),\n packages: [\n {\n type: 'main',\n size: getMainPkgSize({ entryDir }),\n name: GAME_MAIN_PACKAGE_NAME,\n root: '',\n },\n ...independentPackages.map(sub => ({\n type: 'independent',\n size: getDirSizeSync({\n rootDir: entryDir,\n entryDir: path.join(entryDir, sub.root),\n filterDirs: [],\n }),\n name: sub.name,\n root: sub.root,\n })),\n ],\n };\n}\n","import { logger } from '@utils';\nimport * as path from 'path';\nimport * as fs from 'fs';\n\nimport {\n GAME_PACK_CONFIG_FILE_NAME,\n ODR_ASSET_DIR_SUFFIX,\n ODR_CODE_DIR_SUFFIX,\n} from '@constants';\n\n/**\n * 将 packageConfig packages 中 分拆的包 配置迁移到 odr_packages 中\n */\n\nexport async function writeOdrConfig(outputDir: string) {\n logger.info('writeOdrPackagesConfig start');\n const outputPath = path.join(outputDir, GAME_PACK_CONFIG_FILE_NAME);\n const config = JSON.parse(fs.readFileSync(outputPath, 'utf-8'));\n const packages = config.packages;\n const odrPackages = config.odr_packages || {};\n for (const pkgName in packages) {\n if (pkgName.endsWith(ODR_CODE_DIR_SUFFIX)) {\n /**\n * 找到 assets 对应的包\n */\n const pkgConfig = packages[pkgName];\n const relatedPkgName = pkgName.split(ODR_CODE_DIR_SUFFIX)[0];\n if (!odrPackages[relatedPkgName]) {\n odrPackages[relatedPkgName] = {};\n }\n odrPackages[relatedPkgName] = {\n ...odrPackages[relatedPkgName],\n root: pkgConfig.root,\n code_output: pkgConfig.output,\n code_md5: pkgConfig.md5,\n main: pkgConfig.main,\n };\n delete packages[pkgName];\n }\n if (pkgName.endsWith(ODR_ASSET_DIR_SUFFIX)) {\n const relatedPkgName = pkgName.split(ODR_ASSET_DIR_SUFFIX)[0];\n const pkgConfig = packages[pkgName];\n odrPackages[relatedPkgName] = {\n ...odrPackages[relatedPkgName],\n root: pkgConfig.root,\n asset_output: pkgConfig.output,\n asset_md5: pkgConfig.md5,\n };\n delete packages[pkgName];\n }\n }\n config.odr_packages = odrPackages;\n fs.writeFileSync(outputPath, JSON.stringify(config, null, 2));\n logger.info('writeOdrPackagesConfig end');\n}\n"],"names":["ensureDirSync","dir","fs","existsSync","mkdirSync","recursive","logger","constructor","this","init","output","enableLog","winston","createLogger","level","format","combine","timestamp","json","transports","File","filename","path","join","Console","info","msg","error","warn","debug","log","setOutput","removeEmptyDir","statSync","isDirectory","isEmpty","files","readdirSync","file","fullPath","rmSync","GAME_PACK_CONFIG_FILE_NAME","GAME_ORIGIN_CONFIG_FILE_NAME","GAME_MAIN_PACKAGE_NAME","STTPKG_EXT","ODR_CODE_DIR_SUFFIX","ODR_ASSET_DIR_SUFFIX","ONE_ODR_PKG_LIMIT","AVAILABLE_ODR_TAG_LIST","CHECK_DIMENSION","PACKAGE_TYPE","GAME_ENGINES","getDirSizeSync","rootDir","entryDir","filterDirs","totalSize","entries","withFileTypes","entry","name","relativePath","relative","replace","includes","isFile","size","deleteJsFilesSync","endsWith","unlinkSync","err","deleteNoJsFilesSync","uselessDirs","uselessFiles","getIndependentPackagesConfig","gameOriginConfigPath","gameOriginConfig","JSON","parse","readFileSync","subpackages","_a","filter","sub","independent","e","getMainPkgSize","getSubpackagesRoots","originConfigPath","originConfig","map","item","root","getProjectSize","overrideConfig","config","isUnity","gameEntry","gameJsonConfigPath","gameJsonConfig","gameEngine","getGameEngine","Object","assign","build","mainPkgSizeLimit","independentSubPkgSizeLimit","_b","async","downloadAndSaveCodesAsync","games","tempDir","concurrency","tasks","game","id","gameId","packages","gameDir","mkdir","packageName","packageInfo","code_url","fileName","filePath","push","poolLimit","array","iteratorFn","ret","executing","p","Promise","resolve","then","length","splice","indexOf","race","all","asyncPool","task","console","res","fetch","ok","Error","statusText","buffer","Buffer","from","arrayBuffer","writeFile","defaultCheckConfig","dimension","checkProject","checkSizeResult","pkgSizeLimit","dev","enableDev","enable","gameSize","gameSizeMB","toFixed","limitMB","errMsg","passed","type","logMsg","checkProjectSize","gameJsonCheckResult","gameJsonPath","checkGameJson","result","every","checkMainPackage","checkResults","gameJsPath","checkMainPackageEntry","mainPkgSize","mainPkgSizeMB","checkMainPackageSize","checkSubpackages","getSubpackagesConfig","forEach","subpackageEntryDir","checkIndependentPackages","isEnableDev","limit","pkgName","sizeMB","checkPkgSize","API_LIST","desc","escapeRegex","s","checkPkgs","projectCheckResult","mainPackageCheckResult","subpackagesCheckResult","independentPackagesCheckResult","apiCheckResult","enableAPICheck","exts","apiRegexMap","Map","pattern","RegExp","hitFilesMap","set","Set","stack","current","pop","base","basename","children","child","ext","extname","toLowerCase","content","get","test","add","Array","required","checkAPI","setup","outputDir","gameJson","fyfPackages","value","label","url","md5","main","configs","normalizeName","String","getMainFromRoot","str","normalizeRoot","transformSubPackages","fyf_packages","writeFileSync","stringify","flattenMaps","allMaps","list","values","arr","collectPkgJsFiles","excludeDirs","find","concat","some","collectDeps","rootPrefixes","getRootPrefixes","glob","sync","cwd","ignore","requireCalls","code","ast","acorn","ecmaVersion","sourceType","walkAst","node","callee","arguments","requirePath","resolvedPath","startsWith","dirname","prefix","fileExistsWithExtensions","newRequireCalls","i","depModule","keys","pkg","curModule","reduce","acc","cur","f","cb","key","hasOwnProperty","isArray","c","partition","pkgRoot","destRoot","packedFiles","gameOutput","skipDirs","isRoot","srcPath","destPath","copyFileSync","getSkipDirs","makePkgs","startTime","Date","now","removeUselessDirs","message","stat","force","removeSystemUseless","allDeps","subRoots","Boolean","uniqueSubRoots","srcRoot","jsFiles","absPath","packNameRoot","collectMaps","pkgConfig","packMap","moduleConfig","deps","packFileName","relPaths","Bundle","separator","relPath","transformSync","loader","target","minify","charset","keepNames","fileId","defineHeader","defineFooter","fileMagic","MagicString","prepend","append","addSource","outFile","bundledCode","toString","enableSourcemap","generateMap","hires","includeContent","inlineSourcemap","fileContent","sourcemapBaseUrl","_c","host","_d","port","mapFileName","mapFilePath","pack","MinisPackagingInfoMap","data","clientKey","ODRPackages","getOdrConfigs","gamesContentSize","odrTagGameMap","tag","TTMGODRConfig","assignedTag","odrTag","odrTagDir","sum","gid","srcDir","destDir","cpSync","asset_md5","asset_url","configPath","enableOdr","outputPath","pkgOutput","codeOutput","assetOutput","code_md5","makeOdrPkgs","gamePackConfigPath","gamePackConfig","pkgDir","promises","readdir","copyFile","rm","cp","isSymbolicLink","linkTarget","readlinkSync","symlink","mergePkgs","packageConfig","isSuccess","errorMsg","independentPackages","odrPackages","odr_packages","relatedPkgName","split","code_output","asset_output"],"mappings":"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"}
@@ -1,4 +1,5 @@
1
- import { BuildConfig, CheckResult } from '../../typings';
1
+ import { BuildConfig } from '../../typings';
2
+ import { CheckResult } from '../../typings';
2
3
  export declare function checkPkgs({ entryDir, config, }: {
3
4
  entryDir: string;
4
5
  config: BuildConfig;
@@ -1,5 +1,5 @@
1
1
  import { BuildConfig, CheckResult, ProjectConfig } from '../../typings';
2
- export declare function debugPkgs(config: BuildConfig): Promise<{
2
+ export declare function debugPkgs(originConfig: BuildConfig): Promise<{
3
3
  isSuccess: boolean;
4
4
  errorMsg?: string;
5
5
  packages?: ProjectConfig['packages'];
@@ -1,4 +1,13 @@
1
- import type { GetPkgsResult } from '../../typings';
1
+ interface GetPkgsResult {
2
+ size: number;
3
+ packages: {
4
+ type: 'main' | 'subpackage' | 'independent';
5
+ size: number;
6
+ name: string;
7
+ root: string;
8
+ }[];
9
+ }
2
10
  export declare function getPkgs({ entryDir, }: {
3
11
  entryDir: string;
4
12
  }): Promise<GetPkgsResult>;
13
+ export {};
@@ -61,13 +61,3 @@ export interface CheckAPIResult {
61
61
  required: boolean;
62
62
  dimension: CheckDimension;
63
63
  }
64
- export interface GetPkgsResult {
65
- engine: 'unity' | 'cocos' | 'unknown';
66
- size: number;
67
- packages: {
68
- type: 'main' | 'subpackage' | 'independent' | 'wasmcode';
69
- size?: number;
70
- name: string;
71
- root: string;
72
- }[];
73
- }
@@ -1 +1 @@
1
- export declare function getGameEngine(gameEntry: string): 'unity' | 'cocos' | 'unknown';
1
+ export declare function getGameEngine(gameEntry: string): string;
@@ -19,4 +19,3 @@ export { getMainPkgSize } from './getMainPkgSize';
19
19
  export { getProjectSize } from './getProjectSize';
20
20
  export { getGameEngine } from './getGameEngine';
21
21
  export { overrideConfig } from './overrideConfig';
22
- export { getWasmBrCodePath, isUnityEngine, hasWasmBrCode } from './unity';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "ttmg-pack",
3
3
  "author": "ttmg",
4
- "version": "0.1.5",
4
+ "version": "0.1.6",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
@@ -9,8 +9,7 @@
9
9
  "prepublishOnly": "npm run build",
10
10
  "watch": "rollup -c --watch",
11
11
  "test": "npm run build && node __TEST__/index.js",
12
- "debug": "npm run build && node __TEST__/debug.js",
13
- "get": "npm run build && node __TEST__/get.js"
12
+ "debug": "npm run build && node __TEST__/debug.js"
14
13
  },
15
14
  "files": [
16
15
  "dist"