@ttmg/cli 0.1.0-beta.12 → 0.1.0-beta.14
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 +8 -0
- package/dist/index.js +155 -120
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -16,11 +16,31 @@ var require$$6 = require('crypto');
|
|
|
16
16
|
var require$$5$1 = require('archiver');
|
|
17
17
|
var multer = require('multer');
|
|
18
18
|
var WebSocket = require('ws');
|
|
19
|
+
var glob = require('glob');
|
|
19
20
|
var got = require('got');
|
|
20
21
|
var FormData = require('form-data');
|
|
21
22
|
var ttmgPack = require('ttmg-pack');
|
|
22
23
|
var qrcode = require('qrcode-terminal');
|
|
23
24
|
|
|
25
|
+
function _interopNamespaceDefault(e) {
|
|
26
|
+
var n = Object.create(null);
|
|
27
|
+
if (e) {
|
|
28
|
+
Object.keys(e).forEach(function (k) {
|
|
29
|
+
if (k !== 'default') {
|
|
30
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
31
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () { return e[k]; }
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
n.default = e;
|
|
39
|
+
return Object.freeze(n);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
var glob__namespace = /*#__PURE__*/_interopNamespaceDefault(glob);
|
|
43
|
+
|
|
24
44
|
function getDefaultExportFromCjs (x) {
|
|
25
45
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
26
46
|
}
|
|
@@ -275,10 +295,10 @@ async function openUrl(url) {
|
|
|
275
295
|
'--auto-open-devtools-for-tabs', // 自动打开 DevTools
|
|
276
296
|
'--no-default-browser-check',
|
|
277
297
|
'--allow-insecure-localhost',
|
|
278
|
-
'--ignore-certificate-errors',
|
|
279
298
|
'--allow-running-insecure-content',
|
|
280
299
|
'--remote-allow-origins=*',
|
|
281
300
|
'--user-data-dir=/tmp/chrome-debug-profile',
|
|
301
|
+
'--disable-popup-blocking',
|
|
282
302
|
],
|
|
283
303
|
});
|
|
284
304
|
await new Promise(() => { });
|
|
@@ -676,6 +696,79 @@ function requireBundle () {
|
|
|
676
696
|
var bundleExports = requireBundle();
|
|
677
697
|
var index = /*@__PURE__*/getDefaultExportFromCjs(bundleExports);
|
|
678
698
|
|
|
699
|
+
const CONFIG_DIR = path.join(os.homedir(), '.ttmg-cli');
|
|
700
|
+
path.join(CONFIG_DIR, 'config.json');
|
|
701
|
+
/**
|
|
702
|
+
* 获取 Client Key(选择或输入)
|
|
703
|
+
*/
|
|
704
|
+
function getClientKey() {
|
|
705
|
+
/**
|
|
706
|
+
* 读取 project.config.json 中的 appid/appId
|
|
707
|
+
*/
|
|
708
|
+
const projectConfigPath = path.join(process.cwd(), 'project.config.json');
|
|
709
|
+
let clientKey;
|
|
710
|
+
try {
|
|
711
|
+
const projectConfig = JSON.parse(fs.readFileSync(projectConfigPath, 'utf-8'));
|
|
712
|
+
clientKey = projectConfig.appid || projectConfig.appId;
|
|
713
|
+
}
|
|
714
|
+
catch (e) {
|
|
715
|
+
console.log('read project.config.json failed', e);
|
|
716
|
+
clientKey = '';
|
|
717
|
+
}
|
|
718
|
+
if (clientKey) {
|
|
719
|
+
return clientKey;
|
|
720
|
+
}
|
|
721
|
+
else {
|
|
722
|
+
console.log(chalk.red.bold('No appid found in project.config.json, you should provide it in project.config.json'));
|
|
723
|
+
process.exit(1);
|
|
724
|
+
}
|
|
725
|
+
// const keys = readClientKeys();
|
|
726
|
+
// if (keys.length > 0) {
|
|
727
|
+
// // 有历史 key,展示选择框
|
|
728
|
+
// const { selectedKey } = await inquirer.prompt([
|
|
729
|
+
// {
|
|
730
|
+
// type: 'list',
|
|
731
|
+
// name: 'selectedKey',
|
|
732
|
+
// message: 'Please select your game id(client_key):',
|
|
733
|
+
// choices: [...keys, new inquirer.Separator(), 'Add new game id'],
|
|
734
|
+
// },
|
|
735
|
+
// ]);
|
|
736
|
+
// if (selectedKey === 'Add new game id') {
|
|
737
|
+
// // 输入新 key
|
|
738
|
+
// const { newKey } = await inquirer.prompt([
|
|
739
|
+
// {
|
|
740
|
+
// type: 'input',
|
|
741
|
+
// name: 'newKey',
|
|
742
|
+
// message: 'Please input your new game id(client_key):',
|
|
743
|
+
// validate: (input: string) => (input ? true : 'Please input game id'),
|
|
744
|
+
// },
|
|
745
|
+
// ]);
|
|
746
|
+
// saveClientKey(newKey);
|
|
747
|
+
// clientKey = newKey;
|
|
748
|
+
// } else {
|
|
749
|
+
// clientKey = selectedKey;
|
|
750
|
+
// }
|
|
751
|
+
// } else {
|
|
752
|
+
// // 没有历史 key,让用户输入
|
|
753
|
+
// const { newKey } = await inquirer.prompt([
|
|
754
|
+
// {
|
|
755
|
+
// type: 'input',
|
|
756
|
+
// name: 'newKey',
|
|
757
|
+
// message: 'Please input your game id(client_key):',
|
|
758
|
+
// validate: (input: string) => (input ? true : 'Please input game id'),
|
|
759
|
+
// },
|
|
760
|
+
// ]);
|
|
761
|
+
// saveClientKey(newKey);
|
|
762
|
+
// clientKey = newKey;
|
|
763
|
+
// }
|
|
764
|
+
// return clientKey;
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
function getOutputDir() {
|
|
768
|
+
const clientKey = getClientKey();
|
|
769
|
+
return path.join(os.homedir(), '__TTMG__', clientKey);
|
|
770
|
+
}
|
|
771
|
+
|
|
679
772
|
class Store {
|
|
680
773
|
constructor(initialState) {
|
|
681
774
|
this.listeners = [];
|
|
@@ -746,6 +839,24 @@ async function createServer() {
|
|
|
746
839
|
app.use(express.json());
|
|
747
840
|
// 解析 FormData body
|
|
748
841
|
app.use(express.urlencoded({ extended: true }));
|
|
842
|
+
/**
|
|
843
|
+
* 支持文件访问
|
|
844
|
+
*/
|
|
845
|
+
const outputDir = getOutputDir();
|
|
846
|
+
/**
|
|
847
|
+
*
|
|
848
|
+
*/
|
|
849
|
+
app.use(express.static(outputDir));
|
|
850
|
+
/**
|
|
851
|
+
* 支持获取文件
|
|
852
|
+
*/
|
|
853
|
+
app.get('/game/files/:fileName', async (req, res) => {
|
|
854
|
+
const { fileName } = req.params;
|
|
855
|
+
res.sendFile(path.join(outputDir, fileName));
|
|
856
|
+
});
|
|
857
|
+
/**
|
|
858
|
+
* 支持文件访问
|
|
859
|
+
*/
|
|
749
860
|
/**
|
|
750
861
|
* TODO: 提供的接口供客户端进行调用,告诉 NodeServer 客户端的 host 和 port
|
|
751
862
|
*/
|
|
@@ -797,79 +908,6 @@ function closeServer() {
|
|
|
797
908
|
});
|
|
798
909
|
}
|
|
799
910
|
|
|
800
|
-
const CONFIG_DIR = path.join(os.homedir(), '.ttmg-cli');
|
|
801
|
-
path.join(CONFIG_DIR, 'config.json');
|
|
802
|
-
/**
|
|
803
|
-
* 获取 Client Key(选择或输入)
|
|
804
|
-
*/
|
|
805
|
-
function getClientKey() {
|
|
806
|
-
/**
|
|
807
|
-
* 读取 project.config.json 中的 appid/appId
|
|
808
|
-
*/
|
|
809
|
-
const projectConfigPath = path.join(process.cwd(), 'project.config.json');
|
|
810
|
-
let clientKey;
|
|
811
|
-
try {
|
|
812
|
-
const projectConfig = JSON.parse(fs.readFileSync(projectConfigPath, 'utf-8'));
|
|
813
|
-
clientKey = projectConfig.appid || projectConfig.appId;
|
|
814
|
-
}
|
|
815
|
-
catch (e) {
|
|
816
|
-
console.log('read project.config.json failed', e);
|
|
817
|
-
clientKey = '';
|
|
818
|
-
}
|
|
819
|
-
if (clientKey) {
|
|
820
|
-
return clientKey;
|
|
821
|
-
}
|
|
822
|
-
else {
|
|
823
|
-
console.log(chalk.red.bold('No appid found in project.config.json, you should provide it in project.config.json'));
|
|
824
|
-
process.exit(1);
|
|
825
|
-
}
|
|
826
|
-
// const keys = readClientKeys();
|
|
827
|
-
// if (keys.length > 0) {
|
|
828
|
-
// // 有历史 key,展示选择框
|
|
829
|
-
// const { selectedKey } = await inquirer.prompt([
|
|
830
|
-
// {
|
|
831
|
-
// type: 'list',
|
|
832
|
-
// name: 'selectedKey',
|
|
833
|
-
// message: 'Please select your game id(client_key):',
|
|
834
|
-
// choices: [...keys, new inquirer.Separator(), 'Add new game id'],
|
|
835
|
-
// },
|
|
836
|
-
// ]);
|
|
837
|
-
// if (selectedKey === 'Add new game id') {
|
|
838
|
-
// // 输入新 key
|
|
839
|
-
// const { newKey } = await inquirer.prompt([
|
|
840
|
-
// {
|
|
841
|
-
// type: 'input',
|
|
842
|
-
// name: 'newKey',
|
|
843
|
-
// message: 'Please input your new game id(client_key):',
|
|
844
|
-
// validate: (input: string) => (input ? true : 'Please input game id'),
|
|
845
|
-
// },
|
|
846
|
-
// ]);
|
|
847
|
-
// saveClientKey(newKey);
|
|
848
|
-
// clientKey = newKey;
|
|
849
|
-
// } else {
|
|
850
|
-
// clientKey = selectedKey;
|
|
851
|
-
// }
|
|
852
|
-
// } else {
|
|
853
|
-
// // 没有历史 key,让用户输入
|
|
854
|
-
// const { newKey } = await inquirer.prompt([
|
|
855
|
-
// {
|
|
856
|
-
// type: 'input',
|
|
857
|
-
// name: 'newKey',
|
|
858
|
-
// message: 'Please input your game id(client_key):',
|
|
859
|
-
// validate: (input: string) => (input ? true : 'Please input game id'),
|
|
860
|
-
// },
|
|
861
|
-
// ]);
|
|
862
|
-
// saveClientKey(newKey);
|
|
863
|
-
// clientKey = newKey;
|
|
864
|
-
// }
|
|
865
|
-
// return clientKey;
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
function getOutputDir() {
|
|
869
|
-
const clientKey = getClientKey();
|
|
870
|
-
return path.join(os.homedir(), '__TTMG__', clientKey);
|
|
871
|
-
}
|
|
872
|
-
|
|
873
911
|
async function uploadGame() {
|
|
874
912
|
const outputDir = getOutputDir();
|
|
875
913
|
console.log(chalk.yellow.bold('Start compress game resource'));
|
|
@@ -881,58 +919,40 @@ async function uploadGame() {
|
|
|
881
919
|
isSuccess: res?.statusCode === 200,
|
|
882
920
|
};
|
|
883
921
|
}
|
|
884
|
-
function zipDirectory(sourceDir, outPath) {
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
output.on('close', () =>
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
});
|
|
892
|
-
output.on('error', err => {
|
|
893
|
-
// console.error('Compress directory error:', err);
|
|
894
|
-
reject(err);
|
|
895
|
-
});
|
|
896
|
-
archive.on('error', err => {
|
|
897
|
-
reject(err);
|
|
898
|
-
});
|
|
922
|
+
async function zipDirectory(sourceDir, outPath) {
|
|
923
|
+
const output = fs.createWriteStream(outPath);
|
|
924
|
+
const archive = require$$5$1('zip', { zlib: { level: 9 } });
|
|
925
|
+
return new Promise(async (resolve, reject) => {
|
|
926
|
+
output.on('close', () => resolve());
|
|
927
|
+
output.on('error', err => reject(err));
|
|
928
|
+
archive.on('error', err => reject(err));
|
|
899
929
|
archive.pipe(output);
|
|
900
|
-
|
|
901
|
-
|
|
930
|
+
try {
|
|
931
|
+
// 注意这里用 await glob.glob
|
|
932
|
+
const files = await glob__namespace.glob('**/*', {
|
|
933
|
+
cwd: sourceDir,
|
|
934
|
+
nodir: true,
|
|
935
|
+
ignore: '**/*.js.map',
|
|
936
|
+
});
|
|
937
|
+
files.forEach(file => {
|
|
938
|
+
archive.file(path.join(sourceDir, file), { name: file });
|
|
939
|
+
});
|
|
940
|
+
archive.finalize();
|
|
941
|
+
}
|
|
942
|
+
catch (err) {
|
|
943
|
+
reject(err);
|
|
944
|
+
}
|
|
902
945
|
});
|
|
903
946
|
}
|
|
904
|
-
/**
|
|
905
|
-
* 上传 zip 文件到指定接口
|
|
906
|
-
* @param zipFilePath zip 文件路径
|
|
907
|
-
* @param uploadUrl 上传接口
|
|
908
|
-
*/
|
|
909
|
-
// export async function uploadZip(zipPath: string) {
|
|
910
|
-
// const form = new FormData();
|
|
911
|
-
// form.append('file', fs.createReadStream(zipPath), 'upload.zip');
|
|
912
|
-
// try {
|
|
913
|
-
// console.log(chalk.yellow.bold('Start upload resource to client'));
|
|
914
|
-
// const { clientServerHost, clientServerPort } = store.getState();
|
|
915
|
-
// const res = await axios.post(
|
|
916
|
-
// `http://${clientServerHost}:${clientServerPort}/game/upload`,
|
|
917
|
-
// form,
|
|
918
|
-
// {
|
|
919
|
-
// headers: form.getHeaders(),
|
|
920
|
-
// },
|
|
921
|
-
// );
|
|
922
|
-
// fs.unlinkSync(zipPath);
|
|
923
|
-
// return res;
|
|
924
|
-
// } catch (err: any) {
|
|
925
|
-
// console.error('Upload resource to client failed:', err.message);
|
|
926
|
-
// }
|
|
927
|
-
// }
|
|
928
|
-
// 使用 require 语法,完全兼容 CommonJS
|
|
929
947
|
async function uploadZip(zipPath) {
|
|
930
948
|
const form = new FormData();
|
|
931
949
|
form.append('file', fs.createReadStream(zipPath), {
|
|
932
950
|
filename: 'upload.zip',
|
|
933
951
|
contentType: 'application/zip',
|
|
934
952
|
});
|
|
935
|
-
|
|
953
|
+
// 帮我计算下文件大小,变成 MB 为单位
|
|
954
|
+
const fileSize = fs.statSync(zipPath).size / 1024 / 1024;
|
|
955
|
+
console.log(chalk.yellow.bold(`Start upload resource to client, size: ${fileSize.toFixed(2)} MB`));
|
|
936
956
|
const { clientServerHost, clientServerPort } = store.getState();
|
|
937
957
|
const url = `http://${clientServerHost}:${clientServerPort}/game/upload`;
|
|
938
958
|
try {
|
|
@@ -948,6 +968,7 @@ async function uploadZip(zipPath) {
|
|
|
948
968
|
process.stdout.write(`\r${chalk.cyan('Uploading progress: ')}${chalk.green(percent + '%')}`);
|
|
949
969
|
// 生成标准的 百分比
|
|
950
970
|
wsServer?.sendUploadStatus('process', {
|
|
971
|
+
status: 'process',
|
|
951
972
|
progress: `${percent}%`,
|
|
952
973
|
});
|
|
953
974
|
});
|
|
@@ -1015,18 +1036,22 @@ class WsServer {
|
|
|
1015
1036
|
.then(res => {
|
|
1016
1037
|
if (res.isSuccess) {
|
|
1017
1038
|
this.sendUploadStatus('success', {
|
|
1039
|
+
status: 'success',
|
|
1018
1040
|
packages: store.getState().packages,
|
|
1041
|
+
clientKey: getClientKey(),
|
|
1019
1042
|
isSuccess: res.isSuccess,
|
|
1020
1043
|
});
|
|
1021
1044
|
}
|
|
1022
1045
|
else {
|
|
1023
1046
|
this.sendUploadStatus('error', {
|
|
1047
|
+
status: 'error',
|
|
1024
1048
|
errMsg: res.errorMsg,
|
|
1025
1049
|
});
|
|
1026
1050
|
}
|
|
1027
1051
|
})
|
|
1028
1052
|
.catch(() => {
|
|
1029
1053
|
this.sendUploadStatus('error', {
|
|
1054
|
+
status: 'error',
|
|
1030
1055
|
isSuccess: false,
|
|
1031
1056
|
});
|
|
1032
1057
|
console.log(chalk.red.bold('Start upload resource to client failed!'));
|
|
@@ -1101,10 +1126,20 @@ async function prepareResource() {
|
|
|
1101
1126
|
if (!fs.existsSync(outputDir)) {
|
|
1102
1127
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
1103
1128
|
}
|
|
1104
|
-
await console.log(entryDir);
|
|
1105
1129
|
const { isSuccess, errorMsg, packages } = await ttmgPack.debugPkgs({
|
|
1106
1130
|
entry: entryDir,
|
|
1107
1131
|
output: outputDir,
|
|
1132
|
+
dev: {
|
|
1133
|
+
enable: true,
|
|
1134
|
+
port: DEV_PORT,
|
|
1135
|
+
host: 'localhost',
|
|
1136
|
+
enableSourcemap: true,
|
|
1137
|
+
enableLog: false,
|
|
1138
|
+
},
|
|
1139
|
+
build: {
|
|
1140
|
+
pkgSizeLimit: 30 * 1024 * 1024,
|
|
1141
|
+
mainPkgSizeLimit: 4 * 1024 * 1024,
|
|
1142
|
+
},
|
|
1108
1143
|
});
|
|
1109
1144
|
if (!isSuccess) {
|
|
1110
1145
|
console.log(chalk.redBright('Build game package failed, Please check the error message below:'));
|
|
@@ -1123,12 +1158,12 @@ async function prepareResource() {
|
|
|
1123
1158
|
async function watchChange() {
|
|
1124
1159
|
let debounceTimer = null;
|
|
1125
1160
|
fs.watch(process.cwd(), (eventType, filename) => {
|
|
1126
|
-
console.log(chalk.yellow('game resource change, restart to upload'));
|
|
1127
1161
|
// 清除之前的定时器
|
|
1128
1162
|
if (debounceTimer)
|
|
1129
1163
|
clearTimeout(debounceTimer);
|
|
1130
1164
|
// 重新设置定时器
|
|
1131
1165
|
debounceTimer = setTimeout(async () => {
|
|
1166
|
+
console.log(chalk.yellow('game resource change, restart to upload'));
|
|
1132
1167
|
await prepareResource();
|
|
1133
1168
|
wsServer.send({
|
|
1134
1169
|
method: 'resourceChange',
|
|
@@ -1187,7 +1222,7 @@ async function dev() {
|
|
|
1187
1222
|
await watchChange();
|
|
1188
1223
|
}
|
|
1189
1224
|
|
|
1190
|
-
var version = "0.1.0-beta.
|
|
1225
|
+
var version = "0.1.0-beta.14";
|
|
1191
1226
|
var pkg = {
|
|
1192
1227
|
version: version};
|
|
1193
1228
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttmg/cli",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.14",
|
|
4
4
|
"description": "TikTok Mini Game Command Line Tool",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"bin": {
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
"estraverse": "^5.3.0",
|
|
35
35
|
"express": "^5.1.0",
|
|
36
36
|
"form-data": "^4.0.4",
|
|
37
|
+
"glob": "^11.0.3",
|
|
37
38
|
"got": "^11.8.5",
|
|
38
39
|
"inquirer": "^12.7.0",
|
|
39
40
|
"jsdom": "^26.1.0",
|
|
@@ -41,7 +42,7 @@
|
|
|
41
42
|
"open": "^10.2.0",
|
|
42
43
|
"prettier": "^3.6.2",
|
|
43
44
|
"qrcode-terminal": "^0.12.0",
|
|
44
|
-
"ttmg-pack": "^0.0.
|
|
45
|
+
"ttmg-pack": "^0.0.20",
|
|
45
46
|
"ws": "^8.18.3"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|