@maoyugames/phaser-framework 1.0.18 → 1.0.25

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/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import '../chunk-PKBMQBKP.js';
3
- import pc6 from 'picocolors';
3
+ import pc from 'picocolors';
4
4
  import { resolve, join, extname, relative, basename, dirname } from 'path';
5
5
  import { randomBytes } from 'crypto';
6
6
  import fse from 'fs-extra';
@@ -11,7 +11,14 @@ import http from 'http';
11
11
  import { spawnSync } from 'child_process';
12
12
 
13
13
  // src/cli/platforms-meta.ts
14
- var ALL_PLATFORMS = ["web", "tiktok", "wechat", "facebook", "capacitor"];
14
+ var ALL_PLATFORMS = [
15
+ "web",
16
+ "tiktok",
17
+ "wechat",
18
+ "facebook",
19
+ "capacitor",
20
+ "youtube"
21
+ ];
15
22
  var ISOLATION_RULES = {
16
23
  web: {
17
24
  // 标准 H5,不该含任何小游戏 SDK 适配
@@ -22,27 +29,50 @@ var ISOLATION_RULES = {
22
29
  "wx.connectSocket",
23
30
  "wx.request",
24
31
  "wx.setStorageSync",
25
- "wx.requestMidasPayment"
32
+ "wx.requestMidasPayment",
33
+ "ytgame.game",
34
+ "ytgame.system",
35
+ "ytgame.engagement"
26
36
  ]
27
37
  },
28
38
  tiktok: {
29
- // TikTok 包不得含微信 / Facebook
39
+ // TikTok 包不得含微信 / Facebook / YouTube
30
40
  forbidden: [
31
41
  "FBInstant.player",
32
42
  "FBInstant.initializeAsync",
33
43
  "wx.connectSocket",
34
44
  "wx.request",
35
45
  "wx.setStorageSync",
36
- "wx.requestMidasPayment"
46
+ "wx.requestMidasPayment",
47
+ "ytgame.game",
48
+ "ytgame.system",
49
+ "ytgame.engagement"
37
50
  ]
38
51
  },
39
52
  wechat: {
40
- // 微信包不得含 TikTok / Facebook
41
- forbidden: ["TTMinis.game", "FBInstant.player", "FBInstant.initializeAsync", "FBInstant.payments"]
53
+ // 微信包不得含 TikTok / Facebook / YouTube
54
+ forbidden: [
55
+ "TTMinis.game",
56
+ "FBInstant.player",
57
+ "FBInstant.initializeAsync",
58
+ "FBInstant.payments",
59
+ "ytgame.game",
60
+ "ytgame.system",
61
+ "ytgame.engagement"
62
+ ]
42
63
  },
43
64
  facebook: {
44
- // Facebook 包不得含 TikTok / 微信
45
- forbidden: ["TTMinis.game", "wx.connectSocket", "wx.request", "wx.setStorageSync", "wx.requestMidasPayment"]
65
+ // Facebook 包不得含 TikTok / 微信 / YouTube
66
+ forbidden: [
67
+ "TTMinis.game",
68
+ "wx.connectSocket",
69
+ "wx.request",
70
+ "wx.setStorageSync",
71
+ "wx.requestMidasPayment",
72
+ "ytgame.game",
73
+ "ytgame.system",
74
+ "ytgame.engagement"
75
+ ]
46
76
  },
47
77
  capacitor: {
48
78
  // 原生 App 包不得含任何小游戏 SDK 适配
@@ -53,6 +83,22 @@ var ISOLATION_RULES = {
53
83
  "wx.connectSocket",
54
84
  "wx.request",
55
85
  "wx.setStorageSync",
86
+ "wx.requestMidasPayment",
87
+ "ytgame.game",
88
+ "ytgame.system",
89
+ "ytgame.engagement"
90
+ ]
91
+ },
92
+ youtube: {
93
+ // YouTube Playables 包不得含 TikTok / 微信 / Facebook
94
+ forbidden: [
95
+ "TTMinis.game",
96
+ "FBInstant.player",
97
+ "FBInstant.initializeAsync",
98
+ "FBInstant.payments",
99
+ "wx.connectSocket",
100
+ "wx.request",
101
+ "wx.setStorageSync",
56
102
  "wx.requestMidasPayment"
57
103
  ]
58
104
  }
@@ -62,7 +108,10 @@ var SIZE_LIMITS = {
62
108
  // TikTok 整包硬上限 50MB
63
109
  tiktok: { totalHardLimit: 50 * MB },
64
110
  // 微信主包建议 ≤ 4MB(分包另算,给提示而非硬失败)
65
- wechat: { mainBundleSoftLimit: 4 * MB }
111
+ wechat: { mainBundleSoftLimit: 4 * MB },
112
+ // YouTube Playables 整包硬上限 100MB(官方上限,留足余量);主 bundle 给软提示
113
+ // 文档:https://developers.google.com/youtube/gaming/playables/reference/getting_started
114
+ youtube: { totalHardLimit: 100 * MB, mainBundleSoftLimit: 8 * MB }
66
115
  };
67
116
  function formatBytes(bytes) {
68
117
  if (bytes < 1024) return `${bytes} B`;
@@ -188,7 +237,8 @@ var PLATFORM_CLASS = {
188
237
  tiktok: "TikTokPlatform",
189
238
  wechat: "WeChatPlatform",
190
239
  facebook: "FacebookPlatform",
191
- capacitor: "CapacitorPlatform"
240
+ capacitor: "CapacitorPlatform",
241
+ youtube: "YouTubePlatform"
192
242
  };
193
243
  function renderEntry(opts) {
194
244
  const { platform, projectRoot } = opts;
@@ -373,6 +423,8 @@ function renderFacebookAppConfig(cfg) {
373
423
  const obj = {
374
424
  instant_games: {
375
425
  platform_version: "RICH_GAMEPLAY",
426
+ // 必填,当前唯一合法值 NAV_BAR(游戏上方固定顶栏菜单)。
427
+ navigation_menu_version: "NAV_BAR",
376
428
  orientation
377
429
  },
378
430
  app_id: cfg?.appId ?? "YOUR_FB_APP_ID",
@@ -637,7 +689,7 @@ function writeShellFiles(distDir, projectRoot, files) {
637
689
  const dst = join(distDir, f.relPath);
638
690
  fse.ensureDirSync(resolve(dst, ".."));
639
691
  fse.writeFileSync(dst, f.content, "utf-8");
640
- console.log(pc6.green(` \u2713 ${f.relPath} \u2192 ${relative(projectRoot, dst)}`));
692
+ console.log(pc.green(` \u2713 ${f.relPath} \u2192 ${relative(projectRoot, dst)}`));
641
693
  }
642
694
  }
643
695
  function injectShell(opts) {
@@ -646,35 +698,55 @@ function injectShell(opts) {
646
698
  case "web":
647
699
  return true;
648
700
  case "tiktok": {
649
- console.log(pc6.cyan(` \u25B6 [tiktok] \u6CE8\u5165 minigame.config.json + \u6E05\u7406\u7A7A\u6587\u4EF6`));
701
+ console.log(pc.cyan(` \u25B6 [tiktok] \u6CE8\u5165 minigame.config.json + \u6E05\u7406\u7A7A\u6587\u4EF6`));
650
702
  writeShellFiles(distDir, projectRoot, [
651
703
  { relPath: "minigame.config.json", content: renderTikTokMinigameConfig(config.tiktok) }
652
704
  ]);
653
705
  const removed = removeEmptyFiles(distDir);
654
706
  if (removed.length > 0) {
655
- console.log(pc6.gray(` \u6E05\u7406 ${removed.length} \u4E2A\u7A7A\u6587\u4EF6: ${removed.map((p) => relative(distDir, p)).join(", ")}`));
707
+ console.log(pc.gray(` \u6E05\u7406 ${removed.length} \u4E2A\u7A7A\u6587\u4EF6: ${removed.map((p) => relative(distDir, p)).join(", ")}`));
656
708
  }
657
709
  if (!config.tiktok?.clientKey) {
658
- console.log(pc6.yellow(pc6.bold(" \u26A0 platform.config.tiktok.clientKey \u672A\u914D\u7F6E")));
659
- console.log(pc6.yellow(' index.html \u5DF2\u6CE8\u5165 TTMinis.game.init({clientKey: ""}),\u63D0\u5BA1\u4F1A\u88AB\u62D2\u3002'));
660
- console.log(pc6.yellow(" \u8BF7\u5728 platform.config.ts \u7684 tiktok \u6BB5\u586B clientKey(\u5F00\u53D1\u8005\u540E\u53F0\u62FF)\u3002"));
710
+ console.log(pc.yellow(pc.bold(" \u26A0 platform.config.tiktok.clientKey \u672A\u914D\u7F6E")));
711
+ console.log(pc.yellow(' index.html \u5DF2\u6CE8\u5165 TTMinis.game.init({clientKey: ""}),\u63D0\u5BA1\u4F1A\u88AB\u62D2\u3002'));
712
+ console.log(pc.yellow(" \u8BF7\u5728 platform.config.ts \u7684 tiktok \u6BB5\u586B clientKey(\u5F00\u53D1\u8005\u540E\u53F0\u62FF)\u3002"));
661
713
  }
662
714
  return true;
663
715
  }
664
716
  case "facebook": {
665
- console.log(pc6.cyan(` \u25B6 [facebook] \u6CE8\u5165\u5916\u58F3\u6587\u4EF6`));
717
+ console.log(pc.cyan(` \u25B6 [facebook] \u6CE8\u5165\u5916\u58F3\u6587\u4EF6`));
666
718
  writeShellFiles(distDir, projectRoot, [renderFacebookAppConfig(config.facebook)]);
719
+ const removed = removeEmptyFiles(distDir);
720
+ if (removed.length > 0) {
721
+ console.log(
722
+ pc.gray(
723
+ ` \u6E05\u7406 ${removed.length} \u4E2A\u7A7A\u6587\u4EF6: ${removed.map((p) => relative(distDir, p)).join(", ")}`
724
+ )
725
+ );
726
+ }
727
+ return true;
728
+ }
729
+ case "youtube": {
730
+ console.log(pc.cyan(` \u25B6 [youtube] \u6E05\u7406\u7A7A\u6587\u4EF6`));
731
+ const removed = removeEmptyFiles(distDir);
732
+ if (removed.length > 0) {
733
+ console.log(
734
+ pc.gray(
735
+ ` \u6E05\u7406 ${removed.length} \u4E2A\u7A7A\u6587\u4EF6: ${removed.map((p) => relative(distDir, p)).join(", ")}`
736
+ )
737
+ );
738
+ }
667
739
  return true;
668
740
  }
669
741
  case "capacitor": {
670
- console.log(pc6.cyan(` \u25B6 [capacitor] \u751F\u6210 capacitor.config.ts(\u9879\u76EE\u6839)`));
742
+ console.log(pc.cyan(` \u25B6 [capacitor] \u751F\u6210 capacitor.config.ts(\u9879\u76EE\u6839)`));
671
743
  const capCfgPath = resolve(projectRoot, "capacitor.config.ts");
672
744
  fse.writeFileSync(capCfgPath, renderCapacitorConfig(config.capacitor), "utf-8");
673
- console.log(pc6.green(` \u2713 capacitor.config.ts \u2192 ${relative(projectRoot, capCfgPath)}`));
745
+ console.log(pc.green(` \u2713 capacitor.config.ts \u2192 ${relative(projectRoot, capCfgPath)}`));
674
746
  return true;
675
747
  }
676
748
  case "wechat": {
677
- console.log(pc6.cyan(` \u25B6 [wechat] \u6CE8\u5165\u5916\u58F3\u6587\u4EF6`));
749
+ console.log(pc.cyan(` \u25B6 [wechat] \u6CE8\u5165\u5916\u58F3\u6587\u4EF6`));
678
750
  writeShellFiles(distDir, projectRoot, renderWeChatShells(config.wechat));
679
751
  copyPublicAssetsToWechat(projectRoot, distDir);
680
752
  copyWechatVendor(projectRoot, distDir);
@@ -687,37 +759,37 @@ function injectShell(opts) {
687
759
  function copyPublicAssetsToWechat(projectRoot, distDir) {
688
760
  const srcPublic = resolve(projectRoot, "src/game/public");
689
761
  if (!fse.existsSync(srcPublic)) return;
690
- console.log(pc6.cyan(" \u25B6 [wechat] \u62F7\u8D1D\u4E1A\u52A1\u9759\u6001\u8D44\u6E90(src/game/public)"));
762
+ console.log(pc.cyan(" \u25B6 [wechat] \u62F7\u8D1D\u4E1A\u52A1\u9759\u6001\u8D44\u6E90(src/game/public)"));
691
763
  fse.copySync(srcPublic, distDir);
692
- console.log(pc6.green(" \u2713 src/game/public/* \u2192 dist/wechat/"));
764
+ console.log(pc.green(" \u2713 src/game/public/* \u2192 dist/wechat/"));
693
765
  }
694
766
  function copyWechatVendor(projectRoot, distDir) {
695
- console.log(pc6.cyan(" \u25B6 [wechat] \u68C0\u6D4B\u5FAE\u4FE1\u9002\u914D\u5668(vendor)"));
767
+ console.log(pc.cyan(" \u25B6 [wechat] \u68C0\u6D4B\u5FAE\u4FE1\u9002\u914D\u5668(vendor)"));
696
768
  const dirs = wechatVendorDirs(projectRoot);
697
769
  const adapter = dirs.map((d) => join(d, "weapp-adapter.js")).find((p) => fse.existsSync(p));
698
770
  if (adapter) {
699
771
  fse.copyFileSync(adapter, join(distDir, "weapp-adapter.js"));
700
- console.log(pc6.green(" \u2713 weapp-adapter.js \u2192 dist/wechat/weapp-adapter.js"));
772
+ console.log(pc.green(" \u2713 weapp-adapter.js \u2192 dist/wechat/weapp-adapter.js"));
701
773
  const vendorDir = resolve(adapter, "..");
702
774
  const symbol = join(vendorDir, "symbol.js");
703
775
  if (fse.existsSync(symbol)) {
704
776
  fse.copyFileSync(symbol, join(distDir, "symbol.js"));
705
- console.log(pc6.green(" \u2713 symbol.js \u2192 dist/wechat/symbol.js"));
777
+ console.log(pc.green(" \u2713 symbol.js \u2192 dist/wechat/symbol.js"));
706
778
  }
707
779
  return true;
708
780
  }
709
- console.log(pc6.yellow(pc6.bold(" \u26A0 \u7F3A\u5C11\u5FAE\u4FE1\u9002\u914D\u5668 weapp-adapter.js")));
781
+ console.log(pc.yellow(pc.bold(" \u26A0 \u7F3A\u5C11\u5FAE\u4FE1\u9002\u914D\u5668 weapp-adapter.js")));
710
782
  console.log(
711
- pc6.yellow(
783
+ pc.yellow(
712
784
  " \u5FAE\u4FE1\u5C0F\u6E38\u620F\u65E0 DOM,\u9700\u6B64\u5B98\u65B9\u9002\u914D\u5668\u6CE8\u5165 canvas/document shim,\u5426\u5219 game.js \u542F\u52A8\u5373\u62A5\u9519\u3002"
713
785
  )
714
786
  );
715
- console.log(pc6.yellow(` \u8BF7\u628A\u5B98\u65B9 weapp-adapter.js(\u53CA\u53EF\u9009 symbol.js)\u653E\u5230\u4EE5\u4E0B\u4EFB\u4E00\u76EE\u5F55\u540E\u91CD\u65B0\u6784\u5EFA:`));
787
+ console.log(pc.yellow(` \u8BF7\u628A\u5B98\u65B9 weapp-adapter.js(\u53CA\u53EF\u9009 symbol.js)\u653E\u5230\u4EE5\u4E0B\u4EFB\u4E00\u76EE\u5F55\u540E\u91CD\u65B0\u6784\u5EFA:`));
716
788
  for (const d of wechatVendorDirs(projectRoot)) {
717
- console.log(pc6.yellow(` - ${relative(projectRoot, d)}/weapp-adapter.js`));
789
+ console.log(pc.yellow(` - ${relative(projectRoot, d)}/weapp-adapter.js`));
718
790
  }
719
791
  console.log(
720
- pc6.yellow(" \u83B7\u53D6\u65B9\u5F0F:\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u65B0\u5EFA\u300C\u5C0F\u6E38\u620F\u300D\u9879\u76EE\u6A21\u677F\u91CC\u9644\u5E26 weapp-adapter.js\u3002")
792
+ pc.yellow(" \u83B7\u53D6\u65B9\u5F0F:\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u65B0\u5EFA\u300C\u5C0F\u6E38\u620F\u300D\u9879\u76EE\u6A21\u677F\u91CC\u9644\u5E26 weapp-adapter.js\u3002")
721
793
  );
722
794
  return false;
723
795
  }
@@ -741,43 +813,47 @@ function findMainBundle(files) {
741
813
  }
742
814
  function checkPlatform(platform, distDir) {
743
815
  if (!fse.existsSync(distDir)) {
744
- console.log(pc6.gray(` [${platform}] \u672A\u6784\u5EFA,\u8DF3\u8FC7`));
816
+ console.log(pc.gray(` [${platform}] \u672A\u6784\u5EFA,\u8DF3\u8FC7`));
745
817
  return true;
746
818
  }
747
819
  const files = listFiles(distDir);
748
820
  const total = files.reduce((s, f) => s + f.size, 0);
749
821
  const main2 = findMainBundle(files);
750
822
  const limits = SIZE_LIMITS[platform];
751
- console.log(pc6.cyan(` [${platform}]`));
752
- console.log(` \u603B\u4F53\u79EF:${pc6.bold(formatBytes(total))}(${files.length} \u4E2A\u6587\u4EF6)`);
823
+ console.log(pc.cyan(` [${platform}]`));
824
+ console.log(` \u603B\u4F53\u79EF:${pc.bold(formatBytes(total))}(${files.length} \u4E2A\u6587\u4EF6)`);
753
825
  if (main2) {
754
- console.log(` \u4E3B bundle:${basename(main2.path)} = ${pc6.bold(formatBytes(main2.size))}`);
826
+ console.log(` \u4E3B bundle:${basename(main2.path)} = ${pc.bold(formatBytes(main2.size))}`);
755
827
  }
756
828
  let ok = true;
757
829
  if (limits?.totalHardLimit) {
758
830
  if (total > limits.totalHardLimit) {
759
831
  console.log(
760
- pc6.red(
761
- ` \u2717 \u8D85\u51FA TikTok \u6574\u5305\u786C\u4E0A\u9650 ${formatBytes(limits.totalHardLimit)}(\u8D85 ${formatBytes(total - limits.totalHardLimit)})`
832
+ pc.red(
833
+ ` \u2717 \u8D85\u51FA ${platform} \u6574\u5305\u786C\u4E0A\u9650 ${formatBytes(limits.totalHardLimit)}(\u8D85 ${formatBytes(total - limits.totalHardLimit)})`
762
834
  )
763
835
  );
764
836
  ok = false;
765
837
  } else {
766
838
  console.log(
767
- pc6.green(` \u2713 \u5728 TikTok 50MB \u6574\u5305\u4E0A\u9650\u5185(\u4F59 ${formatBytes(limits.totalHardLimit - total)})`)
839
+ pc.green(
840
+ ` \u2713 \u5728 ${platform} \u6574\u5305\u786C\u4E0A\u9650 ${formatBytes(limits.totalHardLimit)} \u5185(\u4F59 ${formatBytes(limits.totalHardLimit - total)})`
841
+ )
768
842
  );
769
843
  }
770
844
  }
771
845
  if (limits?.mainBundleSoftLimit && main2) {
772
846
  if (main2.size > limits.mainBundleSoftLimit) {
773
847
  console.log(
774
- pc6.yellow(
775
- ` \u26A0 \u5FAE\u4FE1\u4E3B\u5305\u8D85\u8FC7\u5EFA\u8BAE ${formatBytes(limits.mainBundleSoftLimit)}(\u5F53\u524D ${formatBytes(main2.size)});\u5EFA\u8BAE\u62C6\u5206\u5305\u6216\u88C1\u526A\u8D44\u6E90,\u4F46\u4E0D\u963B\u65AD\u6784\u5EFA`
848
+ pc.yellow(
849
+ ` \u26A0 ${platform} \u4E3B\u5305\u8D85\u8FC7\u5EFA\u8BAE ${formatBytes(limits.mainBundleSoftLimit)}(\u5F53\u524D ${formatBytes(main2.size)});\u5EFA\u8BAE\u62C6\u5206\u5305\u6216\u88C1\u526A\u8D44\u6E90,\u4F46\u4E0D\u963B\u65AD\u6784\u5EFA`
776
850
  )
777
851
  );
778
852
  } else {
779
853
  console.log(
780
- pc6.green(` \u2713 \u5FAE\u4FE1\u4E3B\u5305\u5728 4MB \u5EFA\u8BAE\u503C\u5185(\u4F59 ${formatBytes(limits.mainBundleSoftLimit - main2.size)})`)
854
+ pc.green(
855
+ ` \u2713 ${platform} \u4E3B\u5305\u5728\u5EFA\u8BAE\u503C ${formatBytes(limits.mainBundleSoftLimit)} \u5185(\u4F59 ${formatBytes(limits.mainBundleSoftLimit - main2.size)})`
856
+ )
781
857
  );
782
858
  }
783
859
  }
@@ -786,29 +862,29 @@ function checkPlatform(platform, distDir) {
786
862
  function runSizeCheck(target) {
787
863
  const ctx = resolveProject();
788
864
  const targets = target ? isPlatform(target) ? [target] : invalidTarget(target) : ALL_PLATFORMS;
789
- console.log(pc6.cyan(pc6.bold("\u25B6 \u4EA7\u7269\u4F53\u79EF\u68C0\u67E5")));
865
+ console.log(pc.cyan(pc.bold("\u25B6 \u4EA7\u7269\u4F53\u79EF\u68C0\u67E5")));
790
866
  let allOk = true;
791
867
  for (const p of targets) {
792
868
  const distDir = join(ctx.root, "dist", p);
793
869
  if (!checkPlatform(p, distDir)) allOk = false;
794
870
  }
795
871
  if (!allOk) {
796
- console.log(pc6.red(pc6.bold("\n\u2717 \u4F53\u79EF\u68C0\u67E5\u672A\u901A\u8FC7(\u5B58\u5728\u8D85\u786C\u4E0A\u9650\u7684\u5E73\u53F0)")));
872
+ console.log(pc.red(pc.bold("\n\u2717 \u4F53\u79EF\u68C0\u67E5\u672A\u901A\u8FC7(\u5B58\u5728\u8D85\u786C\u4E0A\u9650\u7684\u5E73\u53F0)")));
797
873
  return false;
798
874
  }
799
- console.log(pc6.green(pc6.bold("\n\u2713 \u4F53\u79EF\u68C0\u67E5\u5B8C\u6210")));
875
+ console.log(pc.green(pc.bold("\n\u2713 \u4F53\u79EF\u68C0\u67E5\u5B8C\u6210")));
800
876
  return true;
801
877
  }
802
878
  function sizeCheckPlatform(platform, distDir) {
803
- console.log(pc6.cyan(pc6.bold("\u25B6 \u4EA7\u7269\u4F53\u79EF\u68C0\u67E5")));
879
+ console.log(pc.cyan(pc.bold("\u25B6 \u4EA7\u7269\u4F53\u79EF\u68C0\u67E5")));
804
880
  const ok = checkPlatform(platform, distDir);
805
- if (ok) console.log(pc6.green(pc6.bold("\u2713 \u4F53\u79EF\u68C0\u67E5\u5B8C\u6210")));
806
- else console.log(pc6.red(pc6.bold("\u2717 \u4F53\u79EF\u68C0\u67E5\u672A\u901A\u8FC7")));
881
+ if (ok) console.log(pc.green(pc.bold("\u2713 \u4F53\u79EF\u68C0\u67E5\u5B8C\u6210")));
882
+ else console.log(pc.red(pc.bold("\u2717 \u4F53\u79EF\u68C0\u67E5\u672A\u901A\u8FC7")));
807
883
  return ok;
808
884
  }
809
885
  function invalidTarget(target) {
810
- console.log(pc6.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
811
- console.log(pc6.gray(`\u53EF\u9009:${ALL_PLATFORMS.join(" / ")}`));
886
+ console.log(pc.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
887
+ console.log(pc.gray(`\u53EF\u9009:${ALL_PLATFORMS.join(" / ")}`));
812
888
  process.exit(1);
813
889
  }
814
890
  function collectJsFiles(dir) {
@@ -830,12 +906,12 @@ function snippetAround(text, index, span = 60) {
830
906
  function verifyPlatform(platform, distDir, projectRoot) {
831
907
  const rules = ISOLATION_RULES[platform];
832
908
  if (!fse.existsSync(distDir)) {
833
- console.log(pc6.gray(` [${platform}] \u672A\u6784\u5EFA(${relative(projectRoot, distDir)} \u4E0D\u5B58\u5728),\u8DF3\u8FC7`));
909
+ console.log(pc.gray(` [${platform}] \u672A\u6784\u5EFA(${relative(projectRoot, distDir)} \u4E0D\u5B58\u5728),\u8DF3\u8FC7`));
834
910
  return 0;
835
911
  }
836
912
  const files = collectJsFiles(distDir);
837
913
  if (files.length === 0) {
838
- console.log(pc6.yellow(` [${platform}] \u672A\u53D1\u73B0 JS \u4EA7\u7269,\u8DF3\u8FC7`));
914
+ console.log(pc.yellow(` [${platform}] \u672A\u53D1\u73B0 JS \u4EA7\u7269,\u8DF3\u8FC7`));
839
915
  return 0;
840
916
  }
841
917
  let hits = 0;
@@ -849,13 +925,13 @@ function verifyPlatform(platform, distDir, projectRoot) {
849
925
  hits++;
850
926
  perSig++;
851
927
  const rel = relative(projectRoot, file);
852
- console.log(pc6.red(` \u2717 [${platform}] \u547D\u4E2D\u7981\u7528 SDK \u7B7E\u540D ${pc6.bold(sig)}`));
853
- console.log(pc6.gray(` \u6587\u4EF6:${rel}`));
854
- console.log(pc6.gray(` \u7247\u6BB5:\u2026${snippetAround(text, idx)}\u2026`));
928
+ console.log(pc.red(` \u2717 [${platform}] \u547D\u4E2D\u7981\u7528 SDK \u7B7E\u540D ${pc.bold(sig)}`));
929
+ console.log(pc.gray(` \u6587\u4EF6:${rel}`));
930
+ console.log(pc.gray(` \u7247\u6BB5:\u2026${snippetAround(text, idx)}\u2026`));
855
931
  from = idx + sig.length;
856
932
  idx = text.indexOf(sig, from);
857
933
  if (perSig >= 3 && idx !== -1) {
858
- console.log(pc6.gray(` (\u8BE5\u7B7E\u540D\u5728\u672C\u6587\u4EF6\u8FD8\u6709\u66F4\u591A\u547D\u4E2D,\u5DF2\u6298\u53E0)`));
934
+ console.log(pc.gray(` (\u8BE5\u7B7E\u540D\u5728\u672C\u6587\u4EF6\u8FD8\u6709\u66F4\u591A\u547D\u4E2D,\u5DF2\u6298\u53E0)`));
859
935
  break;
860
936
  }
861
937
  }
@@ -863,7 +939,7 @@ function verifyPlatform(platform, distDir, projectRoot) {
863
939
  }
864
940
  if (hits === 0) {
865
941
  console.log(
866
- pc6.green(` \u2713 [${platform}] \u9694\u79BB\u901A\u8FC7(\u626B\u63CF ${files.length} \u4E2A JS \u6587\u4EF6,\u65E0\u5176\u5B83\u5E73\u53F0 SDK \u7B7E\u540D)`)
942
+ pc.green(` \u2713 [${platform}] \u9694\u79BB\u901A\u8FC7(\u626B\u63CF ${files.length} \u4E2A JS \u6587\u4EF6,\u65E0\u5176\u5B83\u5E73\u53F0 SDK \u7B7E\u540D)`)
867
943
  );
868
944
  }
869
945
  return hits;
@@ -871,32 +947,32 @@ function verifyPlatform(platform, distDir, projectRoot) {
871
947
  function runVerifyIsolation(target) {
872
948
  const ctx = resolveProject();
873
949
  const targets = target ? isPlatform(target) ? [target] : invalidTarget2(target) : ALL_PLATFORMS;
874
- console.log(pc6.cyan(pc6.bold("\u25B6 SDK \u9694\u79BB\u6821\u9A8C")));
950
+ console.log(pc.cyan(pc.bold("\u25B6 SDK \u9694\u79BB\u6821\u9A8C")));
875
951
  let totalHits = 0;
876
952
  for (const p of targets) {
877
953
  totalHits += verifyPlatform(p, join(ctx.root, "dist", p), ctx.root);
878
954
  }
879
955
  if (totalHits > 0) {
880
- console.log(pc6.red(pc6.bold(`
956
+ console.log(pc.red(pc.bold(`
881
957
  \u2717 \u9694\u79BB\u6821\u9A8C\u5931\u8D25:\u5171\u53D1\u73B0 ${totalHits} \u5904\u8DE8\u5E73\u53F0 SDK \u7B7E\u540D\u6CC4\u6F0F`)));
882
958
  return false;
883
959
  }
884
- console.log(pc6.green(pc6.bold("\n\u2713 \u9694\u79BB\u6821\u9A8C\u5168\u90E8\u901A\u8FC7")));
960
+ console.log(pc.green(pc.bold("\n\u2713 \u9694\u79BB\u6821\u9A8C\u5168\u90E8\u901A\u8FC7")));
885
961
  return true;
886
962
  }
887
963
  function verifyIsolationPlatform(platform, distDir, projectRoot) {
888
- console.log(pc6.cyan(pc6.bold("\u25B6 SDK \u9694\u79BB\u6821\u9A8C")));
964
+ console.log(pc.cyan(pc.bold("\u25B6 SDK \u9694\u79BB\u6821\u9A8C")));
889
965
  const hits = verifyPlatform(platform, distDir, projectRoot);
890
966
  if (hits > 0) {
891
- console.log(pc6.red(pc6.bold(`\u2717 \u9694\u79BB\u6821\u9A8C\u5931\u8D25:${hits} \u5904\u8DE8\u5E73\u53F0 SDK \u7B7E\u540D\u6CC4\u6F0F`)));
967
+ console.log(pc.red(pc.bold(`\u2717 \u9694\u79BB\u6821\u9A8C\u5931\u8D25:${hits} \u5904\u8DE8\u5E73\u53F0 SDK \u7B7E\u540D\u6CC4\u6F0F`)));
892
968
  return false;
893
969
  }
894
- console.log(pc6.green(pc6.bold("\u2713 \u9694\u79BB\u6821\u9A8C\u901A\u8FC7")));
970
+ console.log(pc.green(pc.bold("\u2713 \u9694\u79BB\u6821\u9A8C\u901A\u8FC7")));
895
971
  return true;
896
972
  }
897
973
  function invalidTarget2(target) {
898
- console.log(pc6.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
899
- console.log(pc6.gray(`\u53EF\u9009:${ALL_PLATFORMS.join(" / ")}`));
974
+ console.log(pc.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
975
+ console.log(pc.gray(`\u53EF\u9009:${ALL_PLATFORMS.join(" / ")}`));
900
976
  process.exit(1);
901
977
  }
902
978
 
@@ -946,6 +1022,57 @@ function renderWebHtml(cfg, scriptSrc) {
946
1022
  `;
947
1023
  }
948
1024
 
1025
+ // src/cli/shells/youtube.ts
1026
+ var DEFAULT_SDK_URL2 = "https://www.youtube.com/game_api/v1";
1027
+ function renderYouTubeHtml(cfg, scriptSrc) {
1028
+ const title = escapeHtml(cfg?.title ?? "YouTube Playable");
1029
+ const sdkUrl = (cfg?.sdkUrl ?? DEFAULT_SDK_URL2).trim();
1030
+ return `<!doctype html>
1031
+ <html lang="en">
1032
+ <head>
1033
+ <meta charset="UTF-8" />
1034
+ <!--
1035
+ YouTube Playables SDK \u6CE8\u5165:\u5FC5\u987B\u662F\u9875\u9762\u7B2C\u4E00\u4E2A\u811A\u672C,\u653E <head> \u4E14\u5728\u6E38\u620F bundle \u4E4B\u524D\u3002
1036
+ \u8FD0\u884C\u65F6\u6302\u8F7D\u5168\u5C40 ytgame.*(firstFrameReady/gameReady/saveData/loadData/sendScore/ads \u7B49)\u3002
1037
+ \u6587\u6863:https://developers.google.com/youtube/gaming/playables/reference/getting_started
1038
+ -->
1039
+ <script src="${escapeAttr(sdkUrl)}"></script>
1040
+ <meta
1041
+ name="viewport"
1042
+ content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
1043
+ />
1044
+ <title>${title}</title>
1045
+ <style>
1046
+ html,
1047
+ body {
1048
+ margin: 0;
1049
+ padding: 0;
1050
+ width: 100%;
1051
+ height: 100%;
1052
+ background: #000;
1053
+ overflow: hidden;
1054
+ box-sizing: border-box;
1055
+ }
1056
+ #game-root {
1057
+ width: 100%;
1058
+ height: 100%;
1059
+ }
1060
+ #game-root canvas {
1061
+ display: block;
1062
+ margin: 0 auto;
1063
+ }
1064
+ </style>
1065
+ </head>
1066
+ <body>
1067
+ <!-- \u6E38\u620F\u753B\u5E03\u6302\u8F7D\u70B9 -->
1068
+ <div id="game-root"></div>
1069
+ <!-- YouTube \u5E73\u53F0\u5165\u53E3:\u4EC5\u9759\u6001 import YouTube \u9002\u914D\u5668 -->
1070
+ <script type="module" src="${scriptSrc}"></script>
1071
+ </body>
1072
+ </html>
1073
+ `;
1074
+ }
1075
+
949
1076
  // src/cli/commands/build.ts
950
1077
  function cacheDir(projectRoot) {
951
1078
  return resolve(projectRoot, "node_modules/.cache/pf");
@@ -960,6 +1087,8 @@ function renderHtmlShell(platform, config, scriptSrc) {
960
1087
  return renderFacebookHtml(config.facebook, scriptSrc);
961
1088
  case "capacitor":
962
1089
  return renderCapacitorHtml(config.capacitor, scriptSrc);
1090
+ case "youtube":
1091
+ return renderYouTubeHtml(config.youtube, scriptSrc);
963
1092
  default:
964
1093
  throw new Error(`renderHtmlShell \u4E0D\u652F\u6301\u5E73\u53F0:${platform}`);
965
1094
  }
@@ -990,7 +1119,7 @@ function findFirstHtml(dir) {
990
1119
  return void 0;
991
1120
  }
992
1121
  async function buildPlatform(platform, ctx, config, vite) {
993
- console.log(pc6.bgCyan(pc6.black(` \u6784\u5EFA\u5E73\u53F0:${platform} `)));
1122
+ console.log(pc.bgCyan(pc.black(` \u6784\u5EFA\u5E73\u53F0:${platform} `)));
994
1123
  const cache = cacheDir(ctx.root);
995
1124
  fse.ensureDirSync(cache);
996
1125
  const hash = randomBytes(4).toString("hex");
@@ -1010,7 +1139,7 @@ async function buildPlatform(platform, ctx, config, vite) {
1010
1139
  tempFiles.push(htmlPath);
1011
1140
  inputFile = htmlPath;
1012
1141
  }
1013
- console.log(pc6.cyan(` \u25B6 [${platform}] vite build`));
1142
+ console.log(pc.cyan(` \u25B6 [${platform}] vite build`));
1014
1143
  const inlineConfig = createPlatformConfig(platform, {
1015
1144
  projectRoot: ctx.root,
1016
1145
  viteRoot: platform === "wechat" ? ctx.root : cache,
@@ -1023,22 +1152,22 @@ async function buildPlatform(platform, ctx, config, vite) {
1023
1152
  if (platform !== "wechat") {
1024
1153
  normalizeHtmlOutput(distDir);
1025
1154
  }
1026
- console.log(pc6.green(` \u2713 [${platform}] vite build \u5B8C\u6210 \u2192 ${relative(ctx.root, distDir)}`));
1155
+ console.log(pc.green(` \u2713 [${platform}] vite build \u5B8C\u6210 \u2192 ${relative(ctx.root, distDir)}`));
1027
1156
  const injectOk = injectShell({ platform, projectRoot: ctx.root, distDir, config });
1028
1157
  const sizeOk = sizeCheckPlatform(platform, distDir);
1029
1158
  const isoOk = verifyIsolationPlatform(platform, distDir, ctx.root);
1030
1159
  const allOk = injectOk && sizeOk && isoOk;
1031
1160
  if (allOk) {
1032
- console.log(pc6.green(pc6.bold(`\u2713 [${platform}] \u6784\u5EFA + \u6821\u9A8C\u5B8C\u6210 \u2192 ${relative(ctx.root, distDir)}
1161
+ console.log(pc.green(pc.bold(`\u2713 [${platform}] \u6784\u5EFA + \u6821\u9A8C\u5B8C\u6210 \u2192 ${relative(ctx.root, distDir)}
1033
1162
  `)));
1034
1163
  } else {
1035
- console.log(pc6.red(pc6.bold(`\u2717 [${platform}] \u6821\u9A8C/\u6CE8\u5165\u672A\u5168\u90E8\u901A\u8FC7
1164
+ console.log(pc.red(pc.bold(`\u2717 [${platform}] \u6821\u9A8C/\u6CE8\u5165\u672A\u5168\u90E8\u901A\u8FC7
1036
1165
  `)));
1037
1166
  }
1038
1167
  return allOk;
1039
1168
  } catch (e) {
1040
- console.log(pc6.red(` \u2717 [${platform}] vite build \u5931\u8D25:${e.message}`));
1041
- if (e.stack) console.log(pc6.gray(e.stack ?? ""));
1169
+ console.log(pc.red(` \u2717 [${platform}] vite build \u5931\u8D25:${e.message}`));
1170
+ if (e.stack) console.log(pc.gray(e.stack ?? ""));
1042
1171
  return false;
1043
1172
  } finally {
1044
1173
  for (const f of tempFiles) {
@@ -1051,37 +1180,37 @@ async function buildPlatform(platform, ctx, config, vite) {
1051
1180
  }
1052
1181
  async function runBuild(target) {
1053
1182
  if (!target) {
1054
- console.log(pc6.red("\u7528\u6CD5:pf build <web|tiktok|wechat|facebook|capacitor|all>"));
1183
+ console.log(pc.red("\u7528\u6CD5:pf build <web|tiktok|wechat|facebook|capacitor|all>"));
1055
1184
  return false;
1056
1185
  }
1057
1186
  const platforms = target === "all" ? ALL_PLATFORMS : isPlatform(target) ? [target] : null;
1058
1187
  if (!platforms) {
1059
- console.log(pc6.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
1060
- console.log(pc6.gray(`\u53EF\u9009:${ALL_PLATFORMS.join(" / ")} / all`));
1188
+ console.log(pc.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
1189
+ console.log(pc.gray(`\u53EF\u9009:${ALL_PLATFORMS.join(" / ")} / all`));
1061
1190
  return false;
1062
1191
  }
1063
1192
  const ctx = resolveProject();
1064
1193
  const config = await loadPlatformConfig(ctx);
1065
1194
  const vite = await loadViteFromRoot(ctx.root);
1066
- console.log(pc6.cyan(pc6.bold(`\u25B6 \u5F00\u59CB\u6784\u5EFA:${platforms.join(", ")}(\u9879\u76EE:${ctx.root})
1195
+ console.log(pc.cyan(pc.bold(`\u25B6 \u5F00\u59CB\u6784\u5EFA:${platforms.join(", ")}(\u9879\u76EE:${ctx.root})
1067
1196
  `)));
1068
1197
  const results = [];
1069
1198
  for (const p of platforms) {
1070
1199
  results.push({ platform: p, ok: await buildPlatform(p, ctx, config, vite) });
1071
1200
  }
1072
- console.log(pc6.cyan(pc6.bold("\u25B6 \u6784\u5EFA\u6C47\u603B")));
1201
+ console.log(pc.cyan(pc.bold("\u25B6 \u6784\u5EFA\u6C47\u603B")));
1073
1202
  let allOk = true;
1074
1203
  for (const r of results) {
1075
- if (r.ok) console.log(pc6.green(` \u2713 ${r.platform}`));
1204
+ if (r.ok) console.log(pc.green(` \u2713 ${r.platform}`));
1076
1205
  else {
1077
- console.log(pc6.red(` \u2717 ${r.platform}`));
1206
+ console.log(pc.red(` \u2717 ${r.platform}`));
1078
1207
  allOk = false;
1079
1208
  }
1080
1209
  }
1081
1210
  if (!allOk) {
1082
- console.log(pc6.red(pc6.bold("\n\u2717 \u5B58\u5728\u6784\u5EFA/\u6821\u9A8C\u5931\u8D25\u7684\u5E73\u53F0")));
1211
+ console.log(pc.red(pc.bold("\n\u2717 \u5B58\u5728\u6784\u5EFA/\u6821\u9A8C\u5931\u8D25\u7684\u5E73\u53F0")));
1083
1212
  } else {
1084
- console.log(pc6.green(pc6.bold("\n\u2713 \u5168\u90E8\u5B8C\u6210")));
1213
+ console.log(pc.green(pc.bold("\n\u2713 \u5168\u90E8\u5B8C\u6210")));
1085
1214
  }
1086
1215
  return allOk;
1087
1216
  }
@@ -1098,6 +1227,8 @@ function renderHtmlShell2(platform, config, scriptSrc) {
1098
1227
  return renderFacebookHtml(config.facebook, scriptSrc);
1099
1228
  case "capacitor":
1100
1229
  return renderCapacitorHtml(config.capacitor, scriptSrc);
1230
+ case "youtube":
1231
+ return renderYouTubeHtml(config.youtube, scriptSrc);
1101
1232
  default:
1102
1233
  throw new Error(`dev \u4E0D\u652F\u6301\u5E73\u53F0:${platform}`);
1103
1234
  }
@@ -1105,8 +1236,8 @@ function renderHtmlShell2(platform, config, scriptSrc) {
1105
1236
  async function runDev(target) {
1106
1237
  const platform = target ? isPlatform(target) ? target : invalidTarget3(target) : "web";
1107
1238
  if (platform === "wechat") {
1108
- console.log(pc6.red("\u2717 wechat \u65E0 HTML dev server \u5F62\u6001\u3002"));
1109
- console.log(pc6.yellow(" \u8BF7\u7528 `pf build wechat` \u4EA7\u51FA dist/wechat,\u518D\u7528\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u6253\u5F00\u9884\u89C8\u3002"));
1239
+ console.log(pc.red("\u2717 wechat \u65E0 HTML dev server \u5F62\u6001\u3002"));
1240
+ console.log(pc.yellow(" \u8BF7\u7528 `pf build wechat` \u4EA7\u51FA dist/wechat,\u518D\u7528\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u6253\u5F00\u9884\u89C8\u3002"));
1110
1241
  return false;
1111
1242
  }
1112
1243
  const ctx = resolveProject();
@@ -1158,9 +1289,9 @@ async function runDev(target) {
1158
1289
  await server.listen();
1159
1290
  const info = server.resolvedUrls;
1160
1291
  const url = info?.local?.[0] ?? "http://localhost:5173/";
1161
- console.log(pc6.green(pc6.bold(`\u25B6 [${platform}] dev server \u5C31\u7EEA`)));
1162
- console.log(` \u6253\u5F00:${pc6.cyan(url)}`);
1163
- console.log(pc6.gray(" (Ctrl+C \u9000\u51FA,\u4E34\u65F6\u5165\u53E3\u4F1A\u81EA\u52A8\u6E05\u7406)"));
1292
+ console.log(pc.green(pc.bold(`\u25B6 [${platform}] dev server \u5C31\u7EEA`)));
1293
+ console.log(` \u6253\u5F00:${pc.cyan(url)}`);
1294
+ console.log(pc.gray(" (Ctrl+C \u9000\u51FA,\u4E34\u65F6\u5165\u53E3\u4F1A\u81EA\u52A8\u6E05\u7406)"));
1164
1295
  const onExit = async () => {
1165
1296
  cleanup();
1166
1297
  await server.close();
@@ -1171,12 +1302,12 @@ async function runDev(target) {
1171
1302
  return true;
1172
1303
  } catch (e) {
1173
1304
  cleanup();
1174
- console.log(pc6.red(`\u2717 dev server \u542F\u52A8\u5931\u8D25:${e.message}`));
1305
+ console.log(pc.red(`\u2717 dev server \u542F\u52A8\u5931\u8D25:${e.message}`));
1175
1306
  return false;
1176
1307
  }
1177
1308
  }
1178
1309
  function invalidTarget3(target) {
1179
- console.log(pc6.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
1310
+ console.log(pc.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
1180
1311
  process.exit(1);
1181
1312
  }
1182
1313
  var CONTENT_TYPES = {
@@ -1250,35 +1381,35 @@ async function readViewport(ctx) {
1250
1381
  async function runVerify(target, opts = {}) {
1251
1382
  const platform = target ? isPlatform(target) ? target : invalid(target) : "web";
1252
1383
  if (platform === "wechat") {
1253
- console.log(pc6.yellow("\u26A0 wechat \u65E0 DOM\u3001\u9700\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177,\u65E0\u6CD5\u7528\u6D4F\u89C8\u5668 verify\u3002"));
1254
- console.log(pc6.gray(" \u8BF7 `pf build wechat` \u540E\u7528\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u6253\u5F00 dist/wechat \u9884\u89C8\u9A8C\u8BC1\u3002"));
1384
+ console.log(pc.yellow("\u26A0 wechat \u65E0 DOM\u3001\u9700\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177,\u65E0\u6CD5\u7528\u6D4F\u89C8\u5668 verify\u3002"));
1385
+ console.log(pc.gray(" \u8BF7 `pf build wechat` \u540E\u7528\u5FAE\u4FE1\u5F00\u53D1\u8005\u5DE5\u5177\u6253\u5F00 dist/wechat \u9884\u89C8\u9A8C\u8BC1\u3002"));
1255
1386
  return false;
1256
1387
  }
1257
1388
  const ctx = resolveProject();
1258
1389
  const pw = resolvePlaywright(ctx.root);
1259
1390
  if (!pw) {
1260
- console.log(pc6.red("\u2717 pf verify \u9700\u8981 Playwright(\u53EF\u9009\u4F9D\u8D56,\u672A\u5B89\u88C5)\u3002"));
1261
- console.log(pc6.yellow(" \u5B89\u88C5:") + pc6.cyan(" npm i -D playwright"));
1262
- console.log(pc6.gray(" \u6D4F\u89C8\u5668\u4F18\u5148\u7528\u7CFB\u7EDF Chrome(channel:chrome),\u901A\u5E38\u65E0\u9700 `npx playwright install`\u3002"));
1391
+ console.log(pc.red("\u2717 pf verify \u9700\u8981 Playwright(\u53EF\u9009\u4F9D\u8D56,\u672A\u5B89\u88C5)\u3002"));
1392
+ console.log(pc.yellow(" \u5B89\u88C5:") + pc.cyan(" npm i -D playwright"));
1393
+ console.log(pc.gray(" \u6D4F\u89C8\u5668\u4F18\u5148\u7528\u7CFB\u7EDF Chrome(channel:chrome),\u901A\u5E38\u65E0\u9700 `npx playwright install`\u3002"));
1263
1394
  return false;
1264
1395
  }
1265
1396
  if (!opts.noBuild) {
1266
- console.log(pc6.cyan(pc6.bold(`\u25B6 [verify] \u5148\u6784\u5EFA ${platform}`)));
1397
+ console.log(pc.cyan(pc.bold(`\u25B6 [verify] \u5148\u6784\u5EFA ${platform}`)));
1267
1398
  const built = await runBuild(platform);
1268
1399
  if (!built) {
1269
- console.log(pc6.red("\u2717 [verify] \u6784\u5EFA\u5931\u8D25,\u7EC8\u6B62\u9A8C\u8BC1"));
1400
+ console.log(pc.red("\u2717 [verify] \u6784\u5EFA\u5931\u8D25,\u7EC8\u6B62\u9A8C\u8BC1"));
1270
1401
  return false;
1271
1402
  }
1272
1403
  }
1273
1404
  const distDir = resolve(ctx.root, "dist", platform);
1274
1405
  if (!existsSync(join(distDir, "index.html"))) {
1275
- console.log(pc6.red(`\u2717 [verify] \u627E\u4E0D\u5230 ${join(distDir, "index.html")}(\u5148 build \u6216\u53BB\u6389 --no-build)`));
1406
+ console.log(pc.red(`\u2717 [verify] \u627E\u4E0D\u5230 ${join(distDir, "index.html")}(\u5148 build \u6216\u53BB\u6389 --no-build)`));
1276
1407
  return false;
1277
1408
  }
1278
1409
  const viewport = await readViewport(ctx);
1279
1410
  const { server, port } = await serveDist(distDir);
1280
1411
  const url = `http://127.0.0.1:${port}/`;
1281
- console.log(pc6.cyan(pc6.bold(`\u25B6 [verify] \u65E0\u5934\u6D4F\u89C8\u5668\u6253\u5F00 ${platform} \u4EA7\u7269`)));
1412
+ console.log(pc.cyan(pc.bold(`\u25B6 [verify] \u65E0\u5934\u6D4F\u89C8\u5668\u6253\u5F00 ${platform} \u4EA7\u7269`)));
1282
1413
  const launchArgs = [
1283
1414
  "--no-sandbox",
1284
1415
  "--use-gl=angle",
@@ -1294,8 +1425,8 @@ async function runVerify(target, opts = {}) {
1294
1425
  browser = await pw.chromium.launch({ headless: true, args: launchArgs });
1295
1426
  } catch (e) {
1296
1427
  server.close();
1297
- console.log(pc6.red(`\u2717 [verify] \u6D4F\u89C8\u5668\u542F\u52A8\u5931\u8D25:${e.message}`));
1298
- console.log(pc6.yellow(" \u88C5\u7CFB\u7EDF Chrome,\u6216\u8FD0\u884C `npx playwright install chromium`\u3002"));
1428
+ console.log(pc.red(`\u2717 [verify] \u6D4F\u89C8\u5668\u542F\u52A8\u5931\u8D25:${e.message}`));
1429
+ console.log(pc.yellow(" \u88C5\u7CFB\u7EDF Chrome,\u6216\u8FD0\u884C `npx playwright install chromium`\u3002"));
1299
1430
  return false;
1300
1431
  }
1301
1432
  }
@@ -1356,7 +1487,7 @@ async function runVerify(target, opts = {}) {
1356
1487
  break;
1357
1488
  }
1358
1489
  }
1359
- console.log(pc6.gray(` \u622A\u56FE(\u5C4F\u5E55\u5B9E\u62CD):${shot}`));
1490
+ console.log(pc.gray(` \u622A\u56FE(\u5C4F\u5E55\u5B9E\u62CD):${shot}`));
1360
1491
  } catch (e) {
1361
1492
  errors.push("VERIFY: " + e.message);
1362
1493
  } finally {
@@ -1365,33 +1496,33 @@ async function runVerify(target, opts = {}) {
1365
1496
  }
1366
1497
  const ok = errors.length === 0 && rendered;
1367
1498
  console.log("");
1368
- console.log(pc6.bold("\u25B6 [verify] \u7ED3\u679C"));
1499
+ console.log(pc.bold("\u25B6 [verify] \u7ED3\u679C"));
1369
1500
  console.log(
1370
1501
  ` canvas:${canvasInfo ? `${canvasInfo.w}\xD7${canvasInfo.h}` : "\u65E0"};\u5728\u89C6\u53E3\u5185:${canvasInView ? "\u662F" : "\u5426"};\u5C4F\u5E55\u989C\u8272\u6570:${distinctColors}(>3 \u89C6\u4E3A\u5DF2\u6E32\u67D3)`
1371
1502
  );
1372
1503
  if (errors.length) {
1373
- console.log(pc6.red(` \u63A7\u5236\u53F0/\u9875\u9762\u9519\u8BEF(${errors.length}):`));
1374
- errors.slice(0, 12).forEach((e) => console.log(pc6.red(" " + e)));
1504
+ console.log(pc.red(` \u63A7\u5236\u53F0/\u9875\u9762\u9519\u8BEF(${errors.length}):`));
1505
+ errors.slice(0, 12).forEach((e) => console.log(pc.red(" " + e)));
1375
1506
  } else {
1376
- console.log(pc6.green(" \u65E0\u63A7\u5236\u53F0/\u9875\u9762\u9519\u8BEF"));
1507
+ console.log(pc.green(" \u65E0\u63A7\u5236\u53F0/\u9875\u9762\u9519\u8BEF"));
1377
1508
  }
1378
1509
  if (ok) {
1379
- console.log(pc6.green(pc6.bold(`
1510
+ console.log(pc.green(pc.bold(`
1380
1511
  \u2713 [verify] ${platform} \u5B9E\u8DD1\u901A\u8FC7(\u5C4F\u5E55\u6E32\u67D3\u6B63\u5E38\u3001\u65E0\u8FD0\u884C\u671F\u9519\u8BEF)`)));
1381
1512
  } else {
1382
1513
  const reason = errors.length ? "\u5B58\u5728\u8FD0\u884C\u671F\u9519\u8BEF" : !canvasInView ? "canvas \u4E0D\u5728\u89C6\u53E3\u5185(\u88AB\u5E03\u5C40\u63A8\u51FA\u5C4F\u5E55/\u9690\u85CF \u2192 \u7528\u6237\u770B\u5230\u9ED1\u5C4F)" : "\u5C4F\u5E55\u753B\u9762\u672A\u6E32\u67D3\u51FA\u5185\u5BB9(\u7591\u4F3C\u5D29\u6E83/\u9ED1\u5C4F)";
1383
- console.log(pc6.red(pc6.bold(`
1514
+ console.log(pc.red(pc.bold(`
1384
1515
  \u2717 [verify] ${platform} \u672A\u901A\u8FC7:${reason}`)));
1385
1516
  }
1386
1517
  return ok;
1387
1518
  }
1388
1519
  function invalid(target) {
1389
- console.log(pc6.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
1520
+ console.log(pc.red(`\u672A\u77E5\u5E73\u53F0:${target}`));
1390
1521
  process.exit(1);
1391
1522
  }
1392
1523
  function spawnCap(projectRoot, args) {
1393
1524
  const npx = process.platform === "win32" ? "npx.cmd" : "npx";
1394
- console.log(pc6.gray(` $ ${npx} cap ${args.join(" ")}`));
1525
+ console.log(pc.gray(` $ ${npx} cap ${args.join(" ")}`));
1395
1526
  const res = spawnSync(npx, ["cap", ...args], {
1396
1527
  cwd: projectRoot,
1397
1528
  stdio: "inherit",
@@ -1399,9 +1530,9 @@ function spawnCap(projectRoot, args) {
1399
1530
  shell: process.platform === "win32"
1400
1531
  });
1401
1532
  if (res.error) {
1402
- console.log(pc6.red(` \u2717 \u6267\u884C\u5931\u8D25:${res.error.message}`));
1533
+ console.log(pc.red(` \u2717 \u6267\u884C\u5931\u8D25:${res.error.message}`));
1403
1534
  console.log(
1404
- pc6.yellow(
1535
+ pc.yellow(
1405
1536
  " \u8BF7\u786E\u8BA4\u5DF2\u5B89\u88C5 Capacitor CLI:npm i -D @capacitor/cli @capacitor/android @capacitor/ios"
1406
1537
  )
1407
1538
  );
@@ -1412,11 +1543,11 @@ function spawnCap(projectRoot, args) {
1412
1543
  function runCap(action, platform) {
1413
1544
  const ctx = resolveProject();
1414
1545
  if (action === "sync") {
1415
- console.log(pc6.cyan(pc6.bold("\u25B6 Capacitor sync")));
1546
+ console.log(pc.cyan(pc.bold("\u25B6 Capacitor sync")));
1416
1547
  const distDir = resolve(ctx.root, "dist", "capacitor");
1417
1548
  if (!fse.existsSync(distDir)) {
1418
- console.log(pc6.red("\u2717 dist/capacitor \u4E0D\u5B58\u5728"));
1419
- console.log(pc6.yellow(" \u8BF7\u5148\u6784\u5EFA:pf build capacitor"));
1549
+ console.log(pc.red("\u2717 dist/capacitor \u4E0D\u5B58\u5728"));
1550
+ console.log(pc.yellow(" \u8BF7\u5148\u6784\u5EFA:pf build capacitor"));
1420
1551
  return false;
1421
1552
  }
1422
1553
  const args = platform ? ["sync", platform] : ["sync"];
@@ -1424,13 +1555,13 @@ function runCap(action, platform) {
1424
1555
  }
1425
1556
  if (action === "open") {
1426
1557
  if (platform !== "android" && platform !== "ios") {
1427
- console.log(pc6.red("\u2717 open \u9700\u6307\u5B9A\u5E73\u53F0:pf cap open <android|ios>"));
1558
+ console.log(pc.red("\u2717 open \u9700\u6307\u5B9A\u5E73\u53F0:pf cap open <android|ios>"));
1428
1559
  return false;
1429
1560
  }
1430
- console.log(pc6.cyan(pc6.bold(`\u25B6 Capacitor open ${platform}`)));
1561
+ console.log(pc.cyan(pc.bold(`\u25B6 Capacitor open ${platform}`)));
1431
1562
  return capExec(ctx.root, ["open", platform]);
1432
1563
  }
1433
- console.log(pc6.red("\u7528\u6CD5:"));
1564
+ console.log(pc.red("\u7528\u6CD5:"));
1434
1565
  console.log(" pf cap sync [android|ios]");
1435
1566
  console.log(" pf cap open <android|ios>");
1436
1567
  return false;
@@ -1482,30 +1613,30 @@ async function main(argv = process.argv.slice(2)) {
1482
1613
  return;
1483
1614
  }
1484
1615
  default: {
1485
- console.log(pc6.yellow(`[pf] \u672A\u77E5\u547D\u4EE4 "${command}"\u3002`));
1486
- console.log(pc6.dim("\u8FD0\u884C `pf help` \u67E5\u770B\u53EF\u7528\u547D\u4EE4\u3002"));
1616
+ console.log(pc.yellow(`[pf] \u672A\u77E5\u547D\u4EE4 "${command}"\u3002`));
1617
+ console.log(pc.dim("\u8FD0\u884C `pf help` \u67E5\u770B\u53EF\u7528\u547D\u4EE4\u3002"));
1487
1618
  process.exitCode = 1;
1488
1619
  }
1489
1620
  }
1490
1621
  } catch (e) {
1491
- console.log(pc6.red(`[pf] \u6267\u884C "${command}" \u51FA\u9519:${e.message}`));
1492
- if (e.stack) console.log(pc6.gray(e.stack ?? ""));
1622
+ console.log(pc.red(`[pf] \u6267\u884C "${command}" \u51FA\u9519:${e.message}`));
1623
+ if (e.stack) console.log(pc.gray(e.stack ?? ""));
1493
1624
  process.exitCode = 1;
1494
1625
  }
1495
1626
  }
1496
1627
  function printHelp() {
1497
- console.log(pc6.bold("@maoyugames/phaser-framework CLI (pf)"));
1498
- console.log(pc6.dim("\u591A\u5E73\u53F0 Phaser \u6846\u67B6\u6784\u5EFA\u5DE5\u5177\u3002"));
1628
+ console.log(pc.bold("@maoyugames/phaser-framework CLI (pf)"));
1629
+ console.log(pc.dim("\u591A\u5E73\u53F0 Phaser \u6846\u67B6\u6784\u5EFA\u5DE5\u5177\u3002"));
1499
1630
  console.log("");
1500
1631
  console.log("\u547D\u4EE4:");
1501
- console.log(` ${pc6.cyan("pf dev [platform]")} \u542F\u52A8\u67D0\u5E73\u53F0 dev server(\u9ED8\u8BA4 web)`);
1502
- console.log(` ${pc6.cyan("pf build <platform|all>")} \u6784\u5EFA\u67D0\u5E73\u53F0/\u5168\u90E8\u5E73\u53F0`);
1503
- console.log(` ${pc6.cyan("pf size-check [platform]")} \u4EA7\u7269\u4F53\u79EF\u68C0\u67E5`);
1504
- console.log(` ${pc6.cyan("pf verify-isolation [platform]")} SDK \u9694\u79BB\u6821\u9A8C`);
1505
- console.log(` ${pc6.cyan("pf verify [platform] [--no-build]")} \u5B9E\u8DD1\u5192\u70DF\u9A8C\u8BC1(Playwright \u65E0\u5934:\u6E32\u67D3+\u65E0\u8FD0\u884C\u671F\u9519\u8BEF)`);
1506
- console.log(` ${pc6.cyan("pf cap <sync|open> [android|ios]")} Capacitor \u539F\u751F\u5DE5\u7A0B\u64CD\u4F5C`);
1632
+ console.log(` ${pc.cyan("pf dev [platform]")} \u542F\u52A8\u67D0\u5E73\u53F0 dev server(\u9ED8\u8BA4 web)`);
1633
+ console.log(` ${pc.cyan("pf build <platform|all>")} \u6784\u5EFA\u67D0\u5E73\u53F0/\u5168\u90E8\u5E73\u53F0`);
1634
+ console.log(` ${pc.cyan("pf size-check [platform]")} \u4EA7\u7269\u4F53\u79EF\u68C0\u67E5`);
1635
+ console.log(` ${pc.cyan("pf verify-isolation [platform]")} SDK \u9694\u79BB\u6821\u9A8C`);
1636
+ console.log(` ${pc.cyan("pf verify [platform] [--no-build]")} \u5B9E\u8DD1\u5192\u70DF\u9A8C\u8BC1(Playwright \u65E0\u5934:\u6E32\u67D3+\u65E0\u8FD0\u884C\u671F\u9519\u8BEF)`);
1637
+ console.log(` ${pc.cyan("pf cap <sync|open> [android|ios]")} Capacitor \u539F\u751F\u5DE5\u7A0B\u64CD\u4F5C`);
1507
1638
  console.log("");
1508
- console.log(pc6.dim("\u5E73\u53F0:web / tiktok / wechat / facebook / capacitor"));
1639
+ console.log(pc.dim("\u5E73\u53F0:web / tiktok / wechat / facebook / capacitor"));
1509
1640
  }
1510
1641
  void main();
1511
1642