fast-cocos 1.0.0

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.
@@ -0,0 +1,8 @@
1
+ {
2
+ "copy": [
3
+ {
4
+ "from": "src/xlsx/template",
5
+ "to": "dist/xlsx/template"
6
+ }
7
+ ]
8
+ }
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.audio = exports.Audio = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const xlsx_1 = __importDefault(require("xlsx"));
10
+ const logger_1 = __importDefault(require("../../logger"));
11
+ const utils_1 = require("../../utils");
12
+ class Audio {
13
+ parse(options) {
14
+ const files = utils_1.utils.findFiles(options.source, [".xlsx"]);
15
+ for (const filePath of files) {
16
+ const dir = path_1.default.dirname(filePath);
17
+ const xlsxName = path_1.default.basename(filePath, path_1.default.extname(filePath));
18
+ const bundle = options.bundle || xlsxName;
19
+ const outAudioDir = path_1.default.join(options.output, xlsxName, "audio");
20
+ const oldMp3 = utils_1.utils.findFiles(outAudioDir, [".mp3"]);
21
+ const newMp3 = [];
22
+ // 读取 Excel 文件
23
+ const workbook = xlsx_1.default.readFile(filePath);
24
+ const sheet = workbook.Sheets[workbook.SheetNames[0]];
25
+ const json = xlsx_1.default.utils.sheet_to_json(sheet);
26
+ const fileDir = path_1.default.join(dir, xlsxName);
27
+ const fileName = xlsxName.charAt(0).toUpperCase() + xlsxName.slice(1) + "Audio";
28
+ let str = `export const ${fileName} = {`;
29
+ const lastIndex = json.length - 1;
30
+ json.forEach((item, index) => {
31
+ const fileName = item["文件名"];
32
+ const refName = item["引用名"];
33
+ const srcPath = path_1.default.join(fileDir, `${fileName}.mp3`);
34
+ const dstPath = path_1.default.join(outAudioDir, `${refName}.mp3`);
35
+ if (fs_1.default.existsSync(srcPath)) {
36
+ utils_1.utils.copyFileSync(srcPath, dstPath);
37
+ newMp3.push(dstPath);
38
+ // 生成ts文件内容
39
+ let key = refName;
40
+ if (key.includes(".")) {
41
+ key = `"${refName}"`;
42
+ }
43
+ let value;
44
+ if (options.bundle) {
45
+ value = `"${bundle}://${xlsxName}/audio/${refName}"${index === lastIndex ? "" : ","} // ${fileName}`;
46
+ }
47
+ else {
48
+ value = `"${xlsxName}://audio/${refName}"${index === lastIndex ? "" : ","} // ${fileName}`;
49
+ }
50
+ str += `\n ${key}: ${value}`;
51
+ }
52
+ else {
53
+ logger_1.default.error(`文件不存在: ${srcPath}`);
54
+ }
55
+ });
56
+ str += "\n};\n";
57
+ // 导出ts配置文件
58
+ const tsFilePath = path_1.default.join(options.script, xlsxName, "config", `${fileName}.ts`);
59
+ utils_1.utils.writeFileSync(tsFilePath, str);
60
+ // 删除未使用mp3文件
61
+ oldMp3
62
+ .filter((v) => !newMp3.includes(v))
63
+ .forEach((v) => {
64
+ utils_1.utils.rmSync(v);
65
+ utils_1.utils.rmSync(v + ".meta");
66
+ });
67
+ }
68
+ }
69
+ }
70
+ exports.Audio = Audio;
71
+ exports.audio = new Audio();
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const commander_1 = require("commander");
13
+ const audio_1 = require("./audio");
14
+ function main() {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ commander_1.program
17
+ .name("audio")
18
+ .description("audio config table parser")
19
+ .version("1.0.0")
20
+ .requiredOption("-s, --source <directory>", "source directory")
21
+ .requiredOption("-o, --output <directory>", "output directory")
22
+ .requiredOption("--script <directory>", "script directory")
23
+ .option("-b, --bundle <bundle>", "bundle name")
24
+ .parse(process.argv);
25
+ const options = commander_1.program.opts();
26
+ audio_1.audio.parse({
27
+ source: options.source,
28
+ output: options.output,
29
+ script: options.script,
30
+ bundle: options.bundle
31
+ });
32
+ });
33
+ }
34
+ void main().catch((err) => {
35
+ console.error(err);
36
+ process.exit(1);
37
+ });
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.bmfont = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const spritesmith_1 = __importDefault(require("spritesmith"));
10
+ const utils_1 = require("../../utils");
11
+ class BMFont {
12
+ /**
13
+ * 解析bmfont
14
+ * @param options 选项
15
+ */
16
+ parse(options) {
17
+ const subDirs = utils_1.utils.getSubDirsSync(options.source);
18
+ for (const dir of subDirs) {
19
+ const modelName = path_1.default.basename(dir);
20
+ const outputDir = path_1.default.join(options.output, modelName, "bmfont");
21
+ // 所有字体目录
22
+ utils_1.utils
23
+ .getSubDirsSync(dir)
24
+ .filter((dir) => utils_1.utils.containsFileExt(dir, ".png"))
25
+ .forEach((fontDir) => this.run(fontDir, outputDir));
26
+ }
27
+ }
28
+ run(fontDir, outputDir) {
29
+ const fontName = path_1.default.basename(fontDir);
30
+ const pngPath = path_1.default.join(outputDir, `${fontName}.png`);
31
+ const fntPath = path_1.default.join(outputDir, `${fontName}.fnt`);
32
+ const config = {
33
+ src: utils_1.utils.findFiles(fontDir, [".png"]),
34
+ exportOpts: {
35
+ format: "png"
36
+ },
37
+ algorithm: "left-right"
38
+ };
39
+ spritesmith_1.default.run(config, (err, result) => {
40
+ if (err) {
41
+ console.log(err);
42
+ return;
43
+ }
44
+ // console.log("result:", result);
45
+ utils_1.utils.mkdir(path_1.default.dirname(pngPath));
46
+ fs_1.default.writeFileSync(pngPath, result.image);
47
+ console.info("\x1b[35m%s\x1b[0m", "生成png文件:" + pngPath);
48
+ // 字符头
49
+ let maxHeight = 0;
50
+ // 字符
51
+ let chars = "";
52
+ const { coordinates } = result;
53
+ for (const key in coordinates) {
54
+ if (Object.hasOwnProperty.call(coordinates, key)) {
55
+ let fileName = path_1.default.basename(key, path_1.default.extname(key));
56
+ /**
57
+ * 这里对文件名字进行判断:
58
+ * 由于部分字符,例如冒号:是无法做文件名字的,因此,这里为了兼容处理,可以使用16进制进行文件命名;
59
+ * 如果是0x开头的命名,这里默认为该文件是16进制文件
60
+ */
61
+ let id = fileName.charCodeAt(0);
62
+ if (fileName.indexOf("0x") === 0) {
63
+ // 16进制字符
64
+ const hexStr = fileName.split("0x")[1];
65
+ id = this.hex2int(hexStr);
66
+ fileName = String.fromCharCode(id);
67
+ }
68
+ else {
69
+ // 标准的英文字符
70
+ id = fileName.charCodeAt(0);
71
+ }
72
+ const { x, y, width, height } = coordinates[key];
73
+ chars += `char id=${id} x=${x} y=${y} width=${width} height=${height} `;
74
+ chars += `xoffset=0 yoffset=0 xadvance=${width} page=0 chnl=15 letter="${fileName}"\n`;
75
+ maxHeight = Math.max(maxHeight, height);
76
+ }
77
+ }
78
+ // 头部说明
79
+ const { width, height } = result.properties;
80
+ let header = `info face="" size=${maxHeight} bold=0 italic=0 charset="" unicode=1 stretchH=200 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0\n`;
81
+ header += `common lineHeight=${maxHeight} base=${maxHeight} scaleW=${width} scaleH=${height} pages=1 packed=0\n`;
82
+ header += `page id=0 file="${fontName}.png"\n`;
83
+ header += `chars count=${Object.keys(coordinates).length}\n`;
84
+ const fntStr = header + chars + "kernings count=0";
85
+ fs_1.default.writeFileSync(fntPath, fntStr);
86
+ console.info("\x1b[35m%s\x1b[0m", "生成fnt文件:" + fntPath);
87
+ });
88
+ }
89
+ /**
90
+ * 将十六进制转换为整数
91
+ * @param {string} hex 十六进制
92
+ * */
93
+ hex2int(hex) {
94
+ let len = hex.length, a = new Array(len), code;
95
+ for (let i = 0; i < len; i++) {
96
+ code = hex.charCodeAt(i);
97
+ if (48 <= code && code < 58) {
98
+ code -= 48;
99
+ }
100
+ else {
101
+ code = (code & 0xdf) - 65 + 10;
102
+ }
103
+ a[i] = code;
104
+ }
105
+ return a.reduce(function (acc, c) {
106
+ acc = 16 * acc + c;
107
+ return acc;
108
+ }, 0);
109
+ }
110
+ }
111
+ exports.bmfont = new BMFont();
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const commander_1 = require("commander");
13
+ const BMFont_1 = require("./BMFont");
14
+ function main() {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ commander_1.program
17
+ .name("bmfont")
18
+ .description("bmfont parser")
19
+ .version("1.0.0")
20
+ .requiredOption("-s, --source <source>", "source directory")
21
+ .requiredOption("-o, --output <output>", "output directory")
22
+ .parse(process.argv);
23
+ const options = commander_1.program.opts();
24
+ BMFont_1.bmfont.parse({
25
+ source: options.source,
26
+ output: options.output
27
+ });
28
+ });
29
+ }
30
+ void main().catch((err) => {
31
+ console.error(err);
32
+ process.exit(1);
33
+ });
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __importDefault = (this && this.__importDefault) || function (mod) {
4
+ return (mod && mod.__esModule) ? mod : { "default": mod };
5
+ };
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const USAGE = `fast-cocos <command>
10
+
11
+ Usage:
12
+
13
+ fast-cocos xlsx export xlsx config tables
14
+ fast-cocos audio export audio config spreadsheet
15
+ fast-cocos ttf export ttf fonts
16
+ fast-cocos robot send dingtalk / feishu (lark) messages
17
+ fast-cocos bmfont export bmfont fonts
18
+ fast-cocos xxteakey generate xxteakey`;
19
+ function printUsage() {
20
+ console.info(USAGE);
21
+ }
22
+ function printVersion() {
23
+ const packageJsonPath = path_1.default.join(__dirname, "..", "package.json");
24
+ const packageJson = JSON.parse(fs_1.default.readFileSync(packageJsonPath, "utf8"));
25
+ console.info(packageJson.version);
26
+ }
27
+ function printUnknownCommandHint(cmd) {
28
+ console.error(`Unknown command: "${cmd}"`);
29
+ console.error("");
30
+ console.error("To see a list of supported fast-cocos commands, run:");
31
+ console.error("fast-cocos help");
32
+ }
33
+ function commandModuleJsExists(absPathWithoutExt) {
34
+ return fs_1.default.existsSync(`${absPathWithoutExt}.js`);
35
+ }
36
+ function requireCommand(cmd, absPathWithoutExt) {
37
+ if (!commandModuleJsExists(absPathWithoutExt)) {
38
+ printUnknownCommandHint(cmd);
39
+ process.exit(1);
40
+ }
41
+ require(absPathWithoutExt);
42
+ }
43
+ function main() {
44
+ const [, , cmd] = process.argv;
45
+ if (!cmd || cmd === "-h" || cmd === "--help" || cmd === "help") {
46
+ printUsage();
47
+ process.exit(0);
48
+ }
49
+ if (cmd === "-v" || cmd === "--version") {
50
+ printVersion();
51
+ process.exit(0);
52
+ }
53
+ const key = cmd.toLowerCase();
54
+ const rest = process.argv.slice(3);
55
+ process.argv = [process.argv[0], process.argv[1], ...rest];
56
+ requireCommand(cmd, path_1.default.join(__dirname, key, "src", "index"));
57
+ // process.exit(1);
58
+ }
59
+ main();
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.bmfont = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const spritesmith_1 = __importDefault(require("spritesmith"));
10
+ const utils_1 = require("../../utils");
11
+ class BMFont {
12
+ /**
13
+ * 解析bmfont
14
+ * @param options 选项
15
+ */
16
+ parse(options) {
17
+ const subDirs = utils_1.utils.getSubDirsSync(options.source);
18
+ for (const dir of subDirs) {
19
+ const modelName = path_1.default.basename(dir);
20
+ const outputDir = path_1.default.join(options.output, modelName, "bmfont");
21
+ // 所有字体目录
22
+ utils_1.utils
23
+ .getSubDirsSync(dir)
24
+ .filter((dir) => utils_1.utils.containsFileExt(dir, ".png"))
25
+ .forEach((fontDir) => this.run(fontDir, outputDir));
26
+ }
27
+ }
28
+ run(fontDir, outputDir) {
29
+ const fontName = path_1.default.basename(fontDir);
30
+ const pngPath = path_1.default.join(outputDir, `${fontName}.png`);
31
+ const fntPath = path_1.default.join(outputDir, `${fontName}.fnt`);
32
+ const config = {
33
+ src: utils_1.utils.findFiles(fontDir, [".png"]),
34
+ exportOpts: {
35
+ format: "png"
36
+ },
37
+ algorithm: "left-right"
38
+ };
39
+ spritesmith_1.default.run(config, (err, result) => {
40
+ if (err) {
41
+ console.log(err);
42
+ return;
43
+ }
44
+ // console.log("result:", result);
45
+ utils_1.utils.mkdir(path_1.default.dirname(pngPath));
46
+ fs_1.default.writeFileSync(pngPath, result.image);
47
+ console.info("\x1b[35m%s\x1b[0m", "生成png文件:" + pngPath);
48
+ // 字符头
49
+ let maxHeight = 0;
50
+ // 字符
51
+ let chars = "";
52
+ const { coordinates } = result;
53
+ for (const key in coordinates) {
54
+ if (Object.hasOwnProperty.call(coordinates, key)) {
55
+ let fileName = path_1.default.basename(key, path_1.default.extname(key));
56
+ /**
57
+ * 这里对文件名字进行判断:
58
+ * 由于部分字符,例如冒号:是无法做文件名字的,因此,这里为了兼容处理,可以使用16进制进行文件命名;
59
+ * 如果是0x开头的命名,这里默认为该文件是16进制文件
60
+ */
61
+ let id = fileName.charCodeAt(0);
62
+ if (fileName.indexOf("0x") === 0) {
63
+ // 16进制字符
64
+ const hexStr = fileName.split("0x")[1];
65
+ id = this.hex2int(hexStr);
66
+ fileName = String.fromCharCode(id);
67
+ }
68
+ else {
69
+ // 标准的英文字符
70
+ id = fileName.charCodeAt(0);
71
+ }
72
+ const { x, y, width, height } = coordinates[key];
73
+ chars += `char id=${id} x=${x} y=${y} width=${width} height=${height} `;
74
+ chars += `xoffset=0 yoffset=0 xadvance=${width} page=0 chnl=15 letter="${fileName}"\n`;
75
+ maxHeight = Math.max(maxHeight, height);
76
+ }
77
+ }
78
+ // 头部说明
79
+ const { width, height } = result.properties;
80
+ let header = `info face="" size=${maxHeight} bold=0 italic=0 charset="" unicode=1 stretchH=200 smooth=1 aa=1 padding=0,0,0,0 spacing=1,1 outline=0\n`;
81
+ header += `common lineHeight=${maxHeight} base=${maxHeight} scaleW=${width} scaleH=${height} pages=1 packed=0\n`;
82
+ header += `page id=0 file="${fontName}.png"\n`;
83
+ header += `chars count=${Object.keys(coordinates).length}\n`;
84
+ const fntStr = header + chars + "kernings count=0";
85
+ fs_1.default.writeFileSync(fntPath, fntStr);
86
+ console.info("\x1b[35m%s\x1b[0m", "生成fnt文件:" + fntPath);
87
+ });
88
+ }
89
+ /**
90
+ * 将十六进制转换为整数
91
+ * @param {string} hex 十六进制
92
+ * */
93
+ hex2int(hex) {
94
+ let len = hex.length, a = new Array(len), code;
95
+ for (let i = 0; i < len; i++) {
96
+ code = hex.charCodeAt(i);
97
+ if (48 <= code && code < 58) {
98
+ code -= 48;
99
+ }
100
+ else {
101
+ code = (code & 0xdf) - 65 + 10;
102
+ }
103
+ a[i] = code;
104
+ }
105
+ return a.reduce(function (acc, c) {
106
+ acc = 16 * acc + c;
107
+ return acc;
108
+ }, 0);
109
+ }
110
+ }
111
+ exports.bmfont = new BMFont();
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const commander_1 = require("commander");
13
+ const JSON_1 = require("./JSON");
14
+ function main() {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ commander_1.program
17
+ .name("bmfont")
18
+ .description("bmfont parser")
19
+ .version("1.0.0")
20
+ .requiredOption("-s, --source <source>", "source directory")
21
+ .requiredOption("-o, --output <output>", "output directory")
22
+ .parse(process.argv);
23
+ const options = commander_1.program.opts();
24
+ JSON_1.bmfont.parse({
25
+ source: options.source,
26
+ output: options.output
27
+ });
28
+ });
29
+ }
30
+ void main().catch((err) => {
31
+ console.error(err);
32
+ process.exit(1);
33
+ });
package/dist/logger.js ADDED
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ /*
3
+ * @Author : 杨海金
4
+ * @Date : 2025-05-07 00:00:00
5
+ * @LastEditors : 杨海金
6
+ * @LastEditTime : 2025-05-07 09:27:22
7
+ * @Description : 输出日志
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ class Logger {
11
+ log(...args) {
12
+ console.log("\x1b[37m%s\x1b[0m", this.format(...args));
13
+ }
14
+ error(...args) {
15
+ console.log("\x1b[31m%s\x1b[0m", this.format(...args));
16
+ }
17
+ warn(...args) {
18
+ console.log("\x1b[33m%s\x1b[0m", this.format(...args));
19
+ }
20
+ info(...args) {
21
+ console.log("\x1b[32m%s\x1b[0m", this.format(...args));
22
+ }
23
+ format(...args) {
24
+ let preStr = "";
25
+ while (args[0] == "\n") {
26
+ preStr += args.shift();
27
+ }
28
+ let message = "";
29
+ args.forEach((arg) => {
30
+ if (Array.isArray(arg)) {
31
+ message += JSON.stringify(arg) + " ";
32
+ }
33
+ else if (typeof arg === "string" || typeof arg === "number") {
34
+ message += arg + " ";
35
+ }
36
+ else {
37
+ message += JSON.stringify(arg) + " ";
38
+ }
39
+ });
40
+ const timeStr = "[" + new Date().toLocaleString() + "] ";
41
+ return preStr + timeStr + message;
42
+ }
43
+ }
44
+ const logger = new Logger();
45
+ exports.default = logger;
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.robot = void 0;
7
+ const https_1 = __importDefault(require("https"));
8
+ const logger_1 = __importDefault(require("../../logger"));
9
+ class Robot {
10
+ /**
11
+ * 发送内容到钉钉
12
+ * @param url 钉钉机器人地址
13
+ * @param content 内容
14
+ */
15
+ sendToDingTalk(url, content) {
16
+ return new Promise((resolve) => {
17
+ if (!url) {
18
+ logger_1.default.warn("未配置钉钉机器人地址");
19
+ resolve();
20
+ return;
21
+ }
22
+ logger_1.default.info("发送钉钉消息:");
23
+ logger_1.default.info(url);
24
+ logger_1.default.info(content);
25
+ // 发送的数据,钉钉机器人支持多种格式,例如 text、markdown、link 等
26
+ const postData = JSON.stringify({
27
+ msgtype: "text",
28
+ text: { content },
29
+ at: {
30
+ atMobiles: [], // 可@特定手机号的人
31
+ isAtAll: true // 是否@全体成员
32
+ }
33
+ });
34
+ // 配置请求选项
35
+ const _url = new URL(url); // 使用URL对象解析
36
+ const options = {
37
+ hostname: _url.hostname,
38
+ path: _url.pathname + _url.search,
39
+ port: 443,
40
+ method: "POST",
41
+ headers: { "Content-Type": "application/json" }
42
+ };
43
+ // 创建并发送请求
44
+ const req = https_1.default.request(options, (res) => {
45
+ let data = "";
46
+ res.on("data", (chunk) => (data += chunk));
47
+ res.on("end", () => {
48
+ logger_1.default.log("成功发送到钉钉:", data);
49
+ resolve();
50
+ });
51
+ });
52
+ // 处理错误
53
+ req.on("error", (e) => {
54
+ logger_1.default.error(`发送到钉钉失败: ${e.message}`);
55
+ resolve();
56
+ });
57
+ // 写入请求数据并结束请求
58
+ req.write(postData);
59
+ req.end();
60
+ });
61
+ }
62
+ /**
63
+ * 发送内容到钉钉
64
+ * @param url 机器人地址
65
+ * @param text 内容
66
+ */
67
+ sendToFeiShu(url, text) {
68
+ return new Promise((resolve) => {
69
+ if (!url) {
70
+ logger_1.default.warn("未配置飞书机器人地址");
71
+ resolve();
72
+ return;
73
+ }
74
+ logger_1.default.info("发送飞书消息:");
75
+ logger_1.default.info(url);
76
+ logger_1.default.info(text);
77
+ // 发送的数据,钉钉机器人支持多种格式,例如 text、markdown、link 等
78
+ const message = JSON.stringify({
79
+ msg_type: "text",
80
+ content: {
81
+ text
82
+ },
83
+ at: {
84
+ at_user_ids: ["all"]
85
+ }
86
+ });
87
+ // 配置请求选项
88
+ const _url = new URL(url); // 使用URL对象解析
89
+ const options = {
90
+ hostname: _url.hostname,
91
+ path: _url.pathname + _url.search,
92
+ port: 443,
93
+ method: "POST",
94
+ headers: {
95
+ "Content-Type": "application/json",
96
+ "Content-Length": Buffer.byteLength(message)
97
+ }
98
+ };
99
+ // 创建并发送请求
100
+ const req = https_1.default.request(options, (res) => {
101
+ let data = "";
102
+ res.on("data", (chunk) => (data += chunk));
103
+ res.on("end", () => {
104
+ logger_1.default.log("成功发送到飞书:", data);
105
+ resolve();
106
+ });
107
+ });
108
+ // 处理错误
109
+ req.on("error", (e) => {
110
+ logger_1.default.error(`发送到飞书失败: ${e.message}`);
111
+ resolve();
112
+ });
113
+ // 写入请求数据并结束请求
114
+ req.write(message);
115
+ req.end();
116
+ });
117
+ }
118
+ }
119
+ exports.robot = new Robot();
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ const commander_1 = require("commander");
13
+ const Robot_1 = require("./Robot");
14
+ function main() {
15
+ return __awaiter(this, void 0, void 0, function* () {
16
+ commander_1.program
17
+ .name("audio")
18
+ .description("audio config table parser")
19
+ .version("1.0.0")
20
+ .requiredOption("-t, --type <type>", "type: dingtalk, feishu")
21
+ .requiredOption("-u, --url <url>", "url")
22
+ .requiredOption("-m, --message <message>", "message")
23
+ .parse(process.argv);
24
+ const options = commander_1.program.opts();
25
+ if (options.type === "dingtalk") {
26
+ yield Robot_1.robot.sendToDingTalk(options.url, options.message);
27
+ }
28
+ else if (options.type === "feishu") {
29
+ yield Robot_1.robot.sendToFeiShu(options.url, options.message);
30
+ }
31
+ else {
32
+ console.error("Invalid type");
33
+ process.exit(1);
34
+ }
35
+ });
36
+ }
37
+ void main().catch((err) => {
38
+ console.error(err);
39
+ process.exit(1);
40
+ });