@ttmg/cli 0.3.2-beta.1 → 0.3.2-beta.12

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.
Files changed (65) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/index.js +8404 -1071
  3. package/dist/index.js.map +1 -1
  4. package/dist/package.json +8 -3
  5. package/dist/public/assets/index-B7gDE9jg.js +1 -0
  6. package/dist/public/assets/index-BB5kLk47.css +1 -0
  7. package/dist/public/assets/index-BGB_3rmy.js +23 -0
  8. package/dist/public/assets/index-BGB_3rmy.js.br +0 -0
  9. package/dist/public/assets/index-BGxy8aq-.js +1 -0
  10. package/dist/public/assets/index-BGxy8aq-.js.br +0 -0
  11. package/dist/public/assets/index-BPf4cmgA.css +1 -0
  12. package/dist/public/assets/index-Be7GH3NR.js +1 -0
  13. package/dist/public/assets/index-Bf6aJOeV.css +1 -0
  14. package/dist/public/assets/index-BkiB8M4Y.css +1 -0
  15. package/dist/public/assets/index-BkiB8M4Y.css.br +0 -0
  16. package/dist/public/assets/index-Bq6YxKLX.css +1 -0
  17. package/dist/public/assets/index-BwbPFgZF.css +1 -0
  18. package/dist/public/assets/index-C-hKdJe4.js +1 -0
  19. package/dist/public/assets/index-C250u6X0.css +1 -0
  20. package/dist/public/assets/index-C250u6X0.css.br +0 -0
  21. package/dist/public/assets/index-C8f539tK.css +1 -0
  22. package/dist/public/assets/index-CZeMe3yb.js +1 -0
  23. package/dist/public/assets/index-CZeMe3yb.js.br +0 -0
  24. package/dist/public/assets/index-DCvzzS3c.js +1 -0
  25. package/dist/public/assets/index-DCvzzS3c.js.br +0 -0
  26. package/dist/public/assets/index-DPSts5Re.css +1 -0
  27. package/dist/public/assets/index-DPSts5Re.css.br +0 -0
  28. package/dist/public/assets/index-DTYGiGBE.js +1 -0
  29. package/dist/public/assets/index-DXFg6tGR.css +1 -0
  30. package/dist/public/assets/index-DZh72DCT.js +1 -0
  31. package/dist/public/assets/index-NjsKimh-.js +1 -0
  32. package/dist/public/assets/index-dPxUjVAV.js +1 -0
  33. package/dist/public/assets/index-sz2rmYug.js +1 -0
  34. package/dist/public/assets/index-yh4tKekV.css +1 -0
  35. package/dist/public/index.html +2 -2
  36. package/dist/scripts/build.js +23 -0
  37. package/dist/scripts/resetLocalState.js +48 -0
  38. package/dist/scripts/setup.js +30 -0
  39. package/dist/scripts/test-protocol.js +29 -0
  40. package/dist/scripts/test-regression.js +94 -0
  41. package/dist/scripts/test-regression.ts +93 -0
  42. package/dist/scripts/worker.js +62 -12
  43. package/package.json +8 -3
  44. package/dist/public/assets/index-9wLHKdTg.css +0 -1
  45. package/dist/public/assets/index-9wLHKdTg.css.br +0 -0
  46. package/dist/public/assets/index-B_lMekya.js +0 -67
  47. package/dist/public/assets/index-B_lMekya.js.br +0 -0
  48. package/dist/public/assets/index-Cuov3ysP.js +0 -67
  49. package/dist/public/assets/index-Cuov3ysP.js.br +0 -0
  50. package/dist/public/assets/index-D51pZ7N1.css +0 -1
  51. package/dist/public/assets/index-D51pZ7N1.css.br +0 -0
  52. package/dist/public/assets/index-D5if59dO.js +0 -67
  53. package/dist/public/assets/index-D5if59dO.js.br +0 -0
  54. package/dist/public/assets/index-D7VJivFN.js +0 -67
  55. package/dist/public/assets/index-D7VJivFN.js.br +0 -0
  56. package/dist/public/assets/index-D9N96fJ2.js +0 -67
  57. package/dist/public/assets/index-D9N96fJ2.js.br +0 -0
  58. package/dist/public/assets/index-DER-DYLd.css +0 -1
  59. package/dist/public/assets/index-DER-DYLd.css.br +0 -0
  60. package/dist/public/assets/index-YhxvkywD.js +0 -67
  61. package/dist/public/assets/index-YhxvkywD.js.br +0 -0
  62. package/dist/public/assets/index-sCifET6h.css +0 -1
  63. package/dist/public/assets/index-sCifET6h.css.br +0 -0
  64. /package/dist/{template → openDataContext/template}/open_context.html.hbs +0 -0
  65. /package/dist/{template → openDataContext/template}/open_context_sdk.js.hbs +0 -0
@@ -0,0 +1,93 @@
1
+
2
+ import path from 'path';
3
+ import fs from 'fs';
4
+ import os from 'os';
5
+ import { HttpsProxyAgent } from 'https-proxy-agent';
6
+
7
+ // Mock TTMGRC logic
8
+ const MOCK_CONFIG_PATH = path.join(process.cwd(), '.ttmgrc_test_regression');
9
+
10
+ function getTTMGRC() {
11
+ if (!fs.existsSync(MOCK_CONFIG_PATH)) return null;
12
+ return JSON.parse(fs.readFileSync(MOCK_CONFIG_PATH, 'utf8'));
13
+ }
14
+
15
+ function setTTMGRC(config: any) {
16
+ const origin = getTTMGRC() || {};
17
+ fs.writeFileSync(MOCK_CONFIG_PATH, JSON.stringify({ ...origin, ...config }));
18
+ }
19
+
20
+ // Replicate request.ts logic
21
+ function getAxiosProxyConfig() {
22
+ const config = getTTMGRC();
23
+ const proxyUrl = config?.proxy;
24
+ if (proxyUrl) {
25
+ return {
26
+ httpsAgent: new HttpsProxyAgent(proxyUrl),
27
+ httpAgent: new HttpsProxyAgent(proxyUrl),
28
+ proxy: false as const,
29
+ };
30
+ }
31
+ return {};
32
+ }
33
+
34
+ async function testRegression() {
35
+ console.log('--- Starting Regression Test ---');
36
+
37
+ // 1. Cleanup
38
+ if (fs.existsSync(MOCK_CONFIG_PATH)) fs.unlinkSync(MOCK_CONFIG_PATH);
39
+
40
+ // 2. Default State (No Config)
41
+ console.log('Testing default state (no proxy config)...');
42
+ const defaultConfig = getAxiosProxyConfig();
43
+ if (Object.keys(defaultConfig).length === 0) {
44
+ console.log('✅ Default config is empty (Axios will use env vars by default).');
45
+ } else {
46
+ console.error('❌ Default config is NOT empty.');
47
+ console.log(defaultConfig);
48
+ process.exit(1);
49
+ }
50
+
51
+ // 3. Set Proxy
52
+ const testProxy = 'http://127.0.0.1:7890';
53
+ console.log(`Setting proxy to ${testProxy}...`);
54
+ setTTMGRC({ proxy: testProxy });
55
+ const activeConfig = getAxiosProxyConfig();
56
+ if (activeConfig.proxy === false) {
57
+ console.log('✅ Proxy configured correctly.');
58
+ } else {
59
+ console.error('❌ Proxy config failed.');
60
+ process.exit(1);
61
+ }
62
+
63
+ // 4. Delete Proxy (Simulate `ttmg config delete proxy` which sets it to undefined/null)
64
+ console.log('Deleting proxy config...');
65
+ setTTMGRC({ proxy: undefined }); // In JSON.stringify, undefined fields are omitted
66
+
67
+ // Verify file content actually lacks "proxy"
68
+ const fileContent = fs.readFileSync(MOCK_CONFIG_PATH, 'utf8');
69
+ if (fileContent.includes('"proxy"')) {
70
+ // If setTTMGRC implementation merges, we might need to explicitly set to null or check merge logic
71
+ // In the mock above: { ...origin, ...config }. If config has {proxy: undefined}, it overrides?
72
+ // JSON.stringify({a:1, b:undefined}) -> "{\"a\":1}"
73
+ console.log(' (Proxy key removed from JSON)');
74
+ }
75
+
76
+ const revertedConfig = getAxiosProxyConfig();
77
+ if (Object.keys(revertedConfig).length === 0) {
78
+ console.log('✅ Reverted to default state successfully.');
79
+ } else {
80
+ console.error('❌ Revert failed. Config still active:');
81
+ console.log(revertedConfig);
82
+ process.exit(1);
83
+ }
84
+
85
+ // 5. Cleanup
86
+ if (fs.existsSync(MOCK_CONFIG_PATH)) fs.unlinkSync(MOCK_CONFIG_PATH);
87
+ console.log('--- Regression Test Passed ---');
88
+ }
89
+
90
+ testRegression().catch(err => {
91
+ console.error(err);
92
+ process.exit(1);
93
+ });
@@ -10,6 +10,47 @@ const semver = require('semver');
10
10
  const { parentPort } = require('worker_threads');
11
11
  const { execSync } = require('child_process');
12
12
 
13
+ const messages = {
14
+ 'en-US': {
15
+ 'worker.compile.missingClientKey': 'Missing clientKey',
16
+ 'worker.compile.tempDir': 'Game local debug assets temp directory: {dir}',
17
+ 'worker.compile.initOutputFailed':
18
+ 'Failed to initialize output directory: {error}',
19
+ 'worker.compile.buildFailed': 'Build failed',
20
+ 'worker.update.noGlobalInstall': 'Global install of {pkgName} was not detected',
21
+ 'worker.update.available': 'Update available!',
22
+ 'worker.update.changelog': 'Changelog:',
23
+ 'worker.update.toUpdate': 'To update, run:',
24
+ },
25
+ 'zh-CN': {
26
+ 'worker.compile.missingClientKey': '缺少 clientKey',
27
+ 'worker.compile.tempDir': '游戏本地调试资源临时目录:{dir}',
28
+ 'worker.compile.initOutputFailed': '初始化输出目录失败:{error}',
29
+ 'worker.compile.buildFailed': '构建失败',
30
+ 'worker.update.noGlobalInstall': '未检测到全局安装的 {pkgName}',
31
+ 'worker.update.available': '检测到可用更新!',
32
+ 'worker.update.changelog': '更新日志:',
33
+ 'worker.update.toUpdate': '执行以下命令升级:',
34
+ },
35
+ };
36
+
37
+ let currentLang = 'en-US';
38
+
39
+ function setWorkerLanguage(lang) {
40
+ currentLang = lang === 'zh-CN' ? 'zh-CN' : 'en-US';
41
+ }
42
+
43
+ function t(key, params = {}) {
44
+ const template =
45
+ (messages[currentLang] && messages[currentLang][key]) ||
46
+ messages['en-US'][key] ||
47
+ key;
48
+ return template.replace(/\{(\w+)\}/g, (_, token) => {
49
+ if (params[token] === undefined) return `{${token}}`;
50
+ return String(params[token]);
51
+ });
52
+ }
53
+
13
54
  /**
14
55
  * 获取 npm 最新版本
15
56
  */
@@ -63,11 +104,12 @@ function getGlobalVersion(pkgName) {
63
104
 
64
105
  async function compile(context = {}) {
65
106
  try {
66
- const { clientKey, outputDir, entryDir, devPort, mode } = context;
107
+ const { clientKey, outputDir, entryDir, devPort, mode, lang } = context;
108
+ setWorkerLanguage(lang);
67
109
 
68
110
  // 参数校验
69
111
  if (!clientKey) {
70
- const message = '缺少 clientKey';
112
+ const message = t('worker.compile.missingClientKey');
71
113
  if (mode !== 'watch') {
72
114
  parentPort?.postMessage({ type: 'error', error: message });
73
115
  return;
@@ -79,8 +121,9 @@ async function compile(context = {}) {
79
121
  try {
80
122
  console.log(
81
123
  chalk(
82
- `🔍 Game local debug assets temp directory`,
83
- chalk.yellow.underline(outputDir),
124
+ `🔍 ${t('worker.compile.tempDir', {
125
+ dir: chalk.yellow.underline(outputDir),
126
+ })}`,
84
127
  ),
85
128
  );
86
129
  if (fs.existsSync(outputDir)) {
@@ -90,7 +133,9 @@ async function compile(context = {}) {
90
133
  // 目录操作失败也上报
91
134
  parentPort?.postMessage({
92
135
  type: 'error',
93
- error: `初始化输出目录失败: ${e?.message || e}`,
136
+ error: t('worker.compile.initOutputFailed', {
137
+ error: e?.message || e,
138
+ }),
94
139
  });
95
140
  return;
96
141
  }
@@ -118,6 +163,8 @@ async function compile(context = {}) {
118
163
  // 如果 ttmg-pack 支持透传选项,可考虑加上 stdio/并发等设置:
119
164
  // spawnOptions: { stdio: ['ignore', 'pipe', 'pipe'] },
120
165
  // concurrency: 4,
166
+ }, {
167
+ lang,
121
168
  });
122
169
  if (fs.existsSync(path.join(outputDir, '__TTMG_TEMP__'))) {
123
170
  fs.rmSync(path.join(outputDir, '__TTMG_TEMP__'), {
@@ -131,7 +178,7 @@ async function compile(context = {}) {
131
178
  type: 'status',
132
179
  status: 'end',
133
180
  isSuccess: false,
134
- errorMsg: errorMsg || '构建失败',
181
+ errorMsg: errorMsg || t('worker.compile.buildFailed'),
135
182
  });
136
183
  } else {
137
184
  parentPort?.postMessage({
@@ -149,8 +196,9 @@ async function compile(context = {}) {
149
196
  }
150
197
  }
151
198
 
152
- async function checkUpdate() {
199
+ async function checkUpdate(context = {}) {
153
200
  try {
201
+ setWorkerLanguage(context?.lang);
154
202
  const pkgName = '@ttmg/cli';
155
203
  const [oldVersion, newVersion] = await Promise.all([
156
204
  getGlobalVersion(pkgName),
@@ -162,7 +210,9 @@ async function checkUpdate() {
162
210
  }
163
211
 
164
212
  if (!oldVersion) {
165
- console.log(chalk.yellow(`未检测到全局安装的 ${pkgName}`));
213
+ console.log(
214
+ chalk.yellow(t('worker.update.noGlobalInstall', { pkgName })),
215
+ );
166
216
  return;
167
217
  }
168
218
 
@@ -177,9 +227,9 @@ async function checkUpdate() {
177
227
  if (oldVersionIsBeta && oldVersionMajor >= newVersionMajor) return;
178
228
 
179
229
  const message = `
180
- ${chalk.bold('Update available!')} ${chalk.red(oldVersion)} ${chalk.white('→')} ${chalk.green(newVersion)}.
181
- ${chalk.magenta('Changelog:')} ${chalk.cyan(`https://npmjs.com/package/${pkgName}/v/${newVersion}`)}
182
- To update, run: ${chalk.magenta(`npm i -g ${pkgName}`)}
230
+ ${chalk.bold(t('worker.update.available'))} ${chalk.red(oldVersion)} ${chalk.white('→')} ${chalk.green(newVersion)}.
231
+ ${chalk.magenta(t('worker.update.changelog'))} ${chalk.cyan(`https://npmjs.com/package/${pkgName}/v/${newVersion}`)}
232
+ ${t('worker.update.toUpdate')} ${chalk.magenta(`npm i -g ${pkgName}`)}
183
233
  `.trim();
184
234
 
185
235
  // 动态引入 boxen,避免主线程初始化时不必要的 require
@@ -204,7 +254,7 @@ if (parentPort) {
204
254
  if (msg?.type === 'compile') {
205
255
  await compile(msg.context);
206
256
  } else if (msg?.type === 'checkUpdate') {
207
- await checkUpdate();
257
+ await checkUpdate({ lang: msg?.lang });
208
258
  }
209
259
  } catch (e) {
210
260
  parentPort.postMessage({ type: 'error', error: e?.message || String(e) });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttmg/cli",
3
- "version": "0.3.2-beta.1",
3
+ "version": "0.3.2-beta.12",
4
4
  "description": "TikTok Mini Game Command Line Tool",
5
5
  "license": "ISC",
6
6
  "bin": {
@@ -11,7 +11,10 @@
11
11
  ],
12
12
  "scripts": {
13
13
  "prepublish": "npm run build",
14
- "build": "rollup -c"
14
+ "build": "node scripts/build.js",
15
+ "setup": "node scripts/setup.js",
16
+ "reset:local-state": "node scripts/resetLocalState.js",
17
+ "dev:link": "npm run build && npm link"
15
18
  },
16
19
  "keywords": [
17
20
  "TTMG",
@@ -38,6 +41,7 @@
38
41
  "glob": "^11.0.3",
39
42
  "got": "^11.8.5",
40
43
  "handlebars": "4.7.8",
44
+ "https-proxy-agent": "^5.0.1",
41
45
  "inquirer": "^12.7.0",
42
46
  "jsdom": "^26.1.0",
43
47
  "mime-types": "^3.0.1",
@@ -48,7 +52,8 @@
48
52
  "prettier": "^3.6.2",
49
53
  "qs": "6.12.1",
50
54
  "semver": "^7.7.2",
51
- "ttmg-pack": "0.3.1",
55
+ "socks-proxy-agent": "^9.0.0",
56
+ "ttmg-pack": "0.4.3",
52
57
  "ws": "^8.18.3"
53
58
  },
54
59
  "devDependencies": {