@gogoqiu/tencent-http-server 0.0.3

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 (84) hide show
  1. package/bin/gogoqiu-node-http-service +3 -0
  2. package/dist/build.d.ts +3 -0
  3. package/dist/build.d.ts.map +1 -0
  4. package/dist/build.js +3 -0
  5. package/dist/build.js.map +1 -0
  6. package/dist/routes/index.d.ts +4 -0
  7. package/dist/routes/index.d.ts.map +1 -0
  8. package/dist/routes/index.js +106 -0
  9. package/dist/routes/index.js.map +1 -0
  10. package/dist/server.d.ts +3 -0
  11. package/dist/server.d.ts.map +1 -0
  12. package/dist/server.js +318 -0
  13. package/dist/server.js.map +1 -0
  14. package/dist/serverCmd.d.ts +8 -0
  15. package/dist/serverCmd.d.ts.map +1 -0
  16. package/dist/serverCmd.js +44 -0
  17. package/dist/serverCmd.js.map +1 -0
  18. package/dist/shell/install.d.ts +5 -0
  19. package/dist/shell/install.d.ts.map +1 -0
  20. package/dist/shell/install.js +221 -0
  21. package/dist/shell/install.js.map +1 -0
  22. package/dist/shell/postinst.d.ts +2 -0
  23. package/dist/shell/postinst.d.ts.map +1 -0
  24. package/dist/shell/postinst.js +4 -0
  25. package/dist/shell/postinst.js.map +1 -0
  26. package/dist/shell.d.ts +2 -0
  27. package/dist/shell.d.ts.map +1 -0
  28. package/dist/shell.js +249 -0
  29. package/dist/shell.js.map +1 -0
  30. package/package.json +82 -0
  31. package/public/captures1//346/265/213/350/257/225/347/224/250captures +0 -0
  32. package/public/chat/offer.html +796 -0
  33. package/public/chat/options.html +58 -0
  34. package/public/chat/server-info.html +32 -0
  35. package/public/chat2.html +272 -0
  36. package/public/chat3.html +246 -0
  37. package/public/chat4.html +302 -0
  38. package/public/chat5.html +41 -0
  39. package/public/formdata.html +41 -0
  40. package/public/hls-player.htm +41 -0
  41. package/public/img/back.svg +1 -0
  42. package/public/img/offline.svg +1 -0
  43. package/public/img/online.svg +1 -0
  44. package/public/ip-record.html +28 -0
  45. package/public/js/encrypt.js +36 -0
  46. package/public/js/socket.io.min.js +7 -0
  47. package/public/js/socket.io.min.js.map +1 -0
  48. package/public/myhost/hostReg.html +35 -0
  49. package/public/mylog-chat.htm +260 -0
  50. package/public/mylog3.html +245 -0
  51. package/public/navbar.css +17 -0
  52. package/public/readme.txt +3 -0
  53. package/public/scroll.htm +139 -0
  54. package/public/ssh-client.html +0 -0
  55. package/public/upload-file.html +226 -0
  56. package/public/upload.html +23 -0
  57. package/public/uploads1/files-1757866537383-447469495.jpg +0 -0
  58. package/public/uploads1/files-1757867389485-764531720.jpg +0 -0
  59. package/public/uploads1/files-1757867518311-278635302.jpg +0 -0
  60. package/public/uploads1/files-1757867629687-688924576.jpg +0 -0
  61. package/public/uploads1/files-1757868630683-52261917.jpg +0 -0
  62. package/public/uploads1/files-1757869187061-619427683.jpg +0 -0
  63. package/public/uploads1/small_files-1757869187061-619427683.jpg +0 -0
  64. package/public/uploads1//346/265/213/350/257/225/347/224/250upload +0 -0
  65. package/public/utils.html +57 -0
  66. package/public/utils.js +161 -0
  67. package/public/webrtc/rtc-client.html +238 -0
  68. package/public/webrtc/rtc-file-transfer-client.html +238 -0
  69. package/public/webrtc/rtc-file-transfer-server.html +453 -0
  70. package/public/webrtc/rtc-server.html +453 -0
  71. package/public/webrtc/video-client-input.html +264 -0
  72. package/public/webrtc/video-server-input.html +312 -0
  73. package/public/webrtc/webrtc-chat-with-files.html +581 -0
  74. package/public/webrtc/webrtc-chat.html +367 -0
  75. package/public/webrtc/webrtc-file-offer.html +88 -0
  76. package/public/webrtc/webrtc1.html +186 -0
  77. package/readme.txt +71 -0
  78. package/views/chat.ejs +53 -0
  79. package/views/index.ejs +125 -0
  80. package/views/special-message.ejs +8 -0
  81. package/views/ssh.ejs +142 -0
  82. package/views/utils.ejs +0 -0
  83. package/views/webrtc/client.ejs +203 -0
  84. package/views/webrtc/server.ejs +365 -0
@@ -0,0 +1,221 @@
1
+ import { SetupLinuxService, outputInfo, outputWarn, outputErr, runCmd, check } from "@gogoqiu/node-base";
2
+ import path from "path";
3
+ import fs from "fs";
4
+ import os from "os";
5
+ import process from "process";
6
+ // "name": "@gogoqiu/aliyun-http-server",
7
+ //export const serviceName = "gogoqiu-node-http-server-aliyun"
8
+ function getContent($script) {
9
+ const service = `[Unit]
10
+ Description=Server Touch My Host
11
+
12
+ [Service]
13
+ ExecStart=node ${$script}
14
+ ExecReload=/bin/kill -SIGHUP $MAINPID
15
+ ExecStop=/bin/kill -SIGINT $MAINPID
16
+
17
+ [Install]
18
+ WantedBy=multi-user.target
19
+ `;
20
+ return service;
21
+ }
22
+ function setServiceFile(root, serviceName) {
23
+ outputInfo("--setService--");
24
+ // 拼接service文件参数
25
+ const script = path.join(root, "dist", "serverCmd.js");
26
+ console.log("脚本路径", script);
27
+ const content = getContent(script);
28
+ const serPath = `/lib/systemd/system/${serviceName}.service`;
29
+ if (fs.existsSync(serPath)) {
30
+ console.log("覆盖", "size", serPath, fs.statSync(serPath).size);
31
+ }
32
+ // 写入文件
33
+ fs.writeFileSync(serPath, content, "utf-8");
34
+ }
35
+ async function setLinuxService(root, serviceName) {
36
+ /*
37
+ 服务名更新:
38
+ node-http-server-aliyun => gogoqiu-node-http-server-aliyun
39
+ 停止服务
40
+ 清理工作
41
+
42
+ 之前的服务名改名了,停止不存在的服务, check: 5
43
+ 已经停止的服务,再次停止, check: 0
44
+ */
45
+ //const serviceName = "gogoqiu-node-http-server-aliyun"
46
+ console.log("停止服务", "systemctl", ["stop", serviceName]);
47
+ let { code } = await runCmd("systemctl", ["stop", serviceName]);
48
+ check(code);
49
+ console.log("停止自启动", "systemctl", ["disable", serviceName]);
50
+ ({ code } = await runCmd("systemctl", ["disable", serviceName]));
51
+ check(code);
52
+ //const serivce = "/lib/systemd/system/gogoqiu-node-http-server-aliyun.service";
53
+ const serPath = `/lib/systemd/system/${serviceName}.service`;
54
+ if (fs.existsSync(serPath)) {
55
+ console.log("删除", serPath);
56
+ fs.unlinkSync(serPath);
57
+ }
58
+ // 如涉及包更新,即覆盖安装新包,旧服务已存在,需要先停止服务。
59
+ //stopService( serviceName )
60
+ // public/views注入dist目录
61
+ setServiceFile(root, serviceName);
62
+ /*
63
+ systemctl start node-http-server-aliyun
64
+ systemctl enable node-http-server-aliyun
65
+ */
66
+ console.log("重载服务", "daemon-reload");
67
+ ({ code } = await runCmd("systemctl", ["daemon-reload"]));
68
+ check(code);
69
+ console.log("设置服务自启动", serviceName);
70
+ ({ code } = await runCmd("systemctl", ["enable", serviceName]));
71
+ check(code);
72
+ console.log("启动服务");
73
+ ({ code } = await runCmd("systemctl", ["start", serviceName]));
74
+ check(code);
75
+ }
76
+ /*
77
+ */
78
+ function createFs(root, subdirs, serviceName) {
79
+ outputInfo("--setupAssetDirs--");
80
+ // base
81
+ const base = path.join(os.homedir(), serviceName);
82
+ if (fs.existsSync(base)) {
83
+ outputWarn("用户目录已存在, 沿用", base);
84
+ }
85
+ else {
86
+ console.log("创建目录", base);
87
+ fs.mkdirSync(base, { recursive: true });
88
+ }
89
+ for (const subdir of subdirs) {
90
+ console.log("--用户目录操作--");
91
+ // 获得用户目录下的目录路径
92
+ const baseSubdir = path.join(base, subdir);
93
+ // 先建立base子目录
94
+ if (fs.existsSync(baseSubdir)) {
95
+ outputWarn("用户目录已存在, 沿用", baseSubdir);
96
+ }
97
+ else {
98
+ console.log("创建目录", baseSubdir);
99
+ fs.mkdirSync(baseSubdir, { recursive: true });
100
+ }
101
+ console.log("--public目录操作--");
102
+ const p = path.join(root, "public", subdir);
103
+ if (fs.existsSync(p)) {
104
+ const fname = p + "_" + Date.now();
105
+ fs.renameSync(p, fname);
106
+ outputWarn("已存在, 移动", p, "=>", fname);
107
+ }
108
+ console.log("构建软链接", baseSubdir, p);
109
+ fs.symlinkSync(baseSubdir, p, os.platform() == "win32" ? "junction" : null);
110
+ // ls -al /usr/lib/node_modules/@gogoqiu/aliyun-http-server/public/
111
+ console.log("校验");
112
+ const s = fs.lstatSync(p);
113
+ if (s.isSymbolicLink()) {
114
+ // fs.readlinkSync与const fs = require('fs').promises;await fs.readlink区别
115
+ const targetPath = fs.readlinkSync(p);
116
+ console.log(`- 指向目标:${targetPath}`);
117
+ }
118
+ else {
119
+ outputErr(`不是一个软链接`, p);
120
+ }
121
+ }
122
+ }
123
+ /*
124
+ disc
125
+ public
126
+ view
127
+ 打包时
128
+ app.use(express.static(path.join(_dirname, 'web'))); //pages
129
+ const resources = path.join(_dirname, 'public')
130
+ app.use(express.static( resources ));
131
+
132
+ function ln-dist-resources(){
133
+ if [ ! -d "dist" ]; then
134
+ output_warn "dist目录不存在, 创建"
135
+ mkdir dist
136
+ fi
137
+ # static
138
+ ln -s $shelldir/views $shelldir/dist/views
139
+ # views
140
+ ln -s $shelldir/public $shelldir/dist/public
141
+ }
142
+ */
143
+ function adoptPublic(root, isLinux, serviceName) {
144
+ outputInfo("--adoptPublic--");
145
+ root = fs.realpathSync(root);
146
+ /*
147
+ video-site的二级链接
148
+ 链接到public
149
+ public链接到dist/public
150
+ */
151
+ if (isLinux) {
152
+ console.log("静态目录", "软链接/symlinkSync", root, "/public=>/dist/public");
153
+ fs.symlinkSync(path.join(root, "public"), path.join(root, "dist", "public"));
154
+ console.log("模板目录", "软链接/symlinkSync", root, "/views=>/dist/views");
155
+ fs.symlinkSync(path.join(root, "views"), path.join(root, "dist", "views"));
156
+ }
157
+ else {
158
+ // win32
159
+ console.log("静态目录", "symlinkSync", "public", "dist/public");
160
+ fs.symlinkSync(path.join(root, "public"), path.join(root, "dist", "public"), "junction");
161
+ console.log("模板目录", "symlinkSync", "views", "dist/views");
162
+ fs.symlinkSync(path.join(root, "views"), path.join(root, "dist", "views"), "junction");
163
+ }
164
+ //console.log( "public/captures[upload]将在服务器启动时建立" )
165
+ createFs(root, ['captures', 'uploads'], serviceName);
166
+ }
167
+ function test() {
168
+ outputInfo("--fetch localhost 80--");
169
+ setTimeout(() => {
170
+ fetch("http://localhost").then(r => r.text()).then(r => console.log(r));
171
+ }, 2000);
172
+ }
173
+ export async function startService(serviceName) {
174
+ await runCmd("systemctl", ["start", serviceName]);
175
+ }
176
+ export async function stopService(serviceName) {
177
+ await runCmd("systemctl", ["stop", serviceName]);
178
+ }
179
+ export async function restartService(serviceName) {
180
+ await runCmd("systemctl", ["restart", serviceName]);
181
+ }
182
+ export async function setup(root, serviceName, isFirst) {
183
+ outputInfo("--setup--");
184
+ if (os.platform() == "linux") {
185
+ if (process.getuid && process.getuid() === 0) {
186
+ adoptPublic(root, true, serviceName);
187
+ // setLinuxService( root, serviceName )
188
+ const obj = {};
189
+ // 竟然不用命令行参数
190
+ obj[serviceName] = path.join("dist", "serverCmd.js");
191
+ new SetupLinuxService(root, obj, isFirst)
192
+ .setServices();
193
+ await new Promise((res, rej) => {
194
+ //setTimeout(test, 2000);
195
+ outputInfo("--fetch localhost 80--");
196
+ setTimeout(async () => {
197
+ try {
198
+ await fetch("http://localhost");
199
+ console.log("fetch ok");
200
+ }
201
+ catch (err) {
202
+ console.log("无法访问");
203
+ }
204
+ res(0);
205
+ }, 5000);
206
+ });
207
+ }
208
+ else {
209
+ console.log('Not running as root');
210
+ process.exit(1);
211
+ }
212
+ }
213
+ else if (os.platform() == "win32") {
214
+ adoptPublic(root, false, serviceName);
215
+ }
216
+ else {
217
+ console.log('No support platform', os.platform());
218
+ process.exit(1);
219
+ }
220
+ }
221
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/shell/install.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport {\n getPackageInfoFromScriptPath, getProjectRoot, getVersion, SetupLinuxService,\n initLog, logError, logInfo, logWarn, outputInfo, outputWarn, outputErr,\n runCmd, RunResult, check\n} from \"@gogoqiu/node-base\"\nimport path from \"path\"\nimport fs from \"fs\"\nimport os from \"os\"\nimport process from \"process\"\n\n// \"name\": \"@gogoqiu/aliyun-http-server\",\n//export const serviceName = \"gogoqiu-node-http-server-aliyun\"\n\nfunction getContent($script: string) {\n const service = `[Unit]\nDescription=Server Touch My Host\n\n[Service]\nExecStart=node ${$script}\nExecReload=/bin/kill -SIGHUP $MAINPID\nExecStop=/bin/kill -SIGINT $MAINPID\n\n[Install]\nWantedBy=multi-user.target\n`\n return service;\n}\n\nfunction setServiceFile(root: string, serviceName: string) {\n outputInfo(\"--setService--\")\n // 拼接service文件参数\n const script = path.join(root, \"dist\", \"serverCmd.js\")\n console.log(\"脚本路径\", script)\n const content = getContent(script)\n const serPath = `/lib/systemd/system/${serviceName}.service`;\n if (fs.existsSync(serPath)) {\n console.log(\"覆盖\", \"size\", serPath, fs.statSync(serPath).size)\n }\n // 写入文件\n fs.writeFileSync(serPath, content, \"utf-8\")\n}\n\nasync function setLinuxService(root: string, serviceName: string) {\n /*\n 服务名更新:\n node-http-server-aliyun => gogoqiu-node-http-server-aliyun\n 停止服务\n 清理工作\n\n 之前的服务名改名了,停止不存在的服务, check: 5\n 已经停止的服务,再次停止, check: 0\n */\n //const serviceName = \"gogoqiu-node-http-server-aliyun\"\n console.log(\"停止服务\", \"systemctl\", [\"stop\", serviceName])\n let { code } = await runCmd(\"systemctl\", [\"stop\", serviceName]);\n check(code);\n console.log(\"停止自启动\", \"systemctl\", [\"disable\", serviceName]);\n ({ code } = await runCmd(\"systemctl\", [\"disable\", serviceName]));\n check(code);\n //const serivce = \"/lib/systemd/system/gogoqiu-node-http-server-aliyun.service\";\n const serPath = `/lib/systemd/system/${serviceName}.service`;\n if (fs.existsSync(serPath)) {\n console.log(\"删除\", serPath)\n fs.unlinkSync(serPath);\n }\n // 如涉及包更新,即覆盖安装新包,旧服务已存在,需要先停止服务。\n //stopService( serviceName ) \n // public/views注入dist目录\n\n setServiceFile(root, serviceName);\n /*\n systemctl start node-http-server-aliyun\n systemctl enable node-http-server-aliyun\n */\n\n console.log(\"重载服务\", \"daemon-reload\");\n ({ code } = await runCmd(\"systemctl\", [\"daemon-reload\"]));\n check(code);\n console.log(\"设置服务自启动\", serviceName);\n ({ code } = await runCmd(\"systemctl\", [\"enable\", serviceName]));\n check(code);\n\n console.log(\"启动服务\");\n ({ code } = await runCmd(\"systemctl\", [\"start\", serviceName]))\n check(code)\n}\n\n/*\n*/\nfunction createFs(root: string, subdirs: string[], serviceName: string) {\n outputInfo(\"--setupAssetDirs--\")\n // base\n const base = path.join(os.homedir(), serviceName);\n if (fs.existsSync(base)) {\n outputWarn(\"用户目录已存在, 沿用\", base)\n } else {\n console.log(\"创建目录\", base)\n fs.mkdirSync(base, { recursive: true })\n }\n for (const subdir of subdirs) {\n console.log(\"--用户目录操作--\")\n // 获得用户目录下的目录路径\n const baseSubdir = path.join(base, subdir)\n // 先建立base子目录\n if (fs.existsSync(baseSubdir)) {\n outputWarn(\"用户目录已存在, 沿用\", baseSubdir)\n } else {\n console.log(\"创建目录\", baseSubdir)\n fs.mkdirSync(baseSubdir, { recursive: true })\n }\n console.log(\"--public目录操作--\")\n const p = path.join(root, \"public\", subdir)\n if (fs.existsSync(p)) {\n const fname = p + \"_\" + Date.now()\n fs.renameSync(p, fname)\n outputWarn(\"已存在, 移动\", p, \"=>\", fname)\n }\n console.log(\"构建软链接\", baseSubdir, p)\n fs.symlinkSync(baseSubdir, p, os.platform() == \"win32\" ? \"junction\" : null)\n // ls -al /usr/lib/node_modules/@gogoqiu/aliyun-http-server/public/\n console.log(\"校验\")\n const s = fs.lstatSync(p)\n if (s.isSymbolicLink()) {\n // fs.readlinkSync与const fs = require('fs').promises;await fs.readlink区别\n const targetPath = fs.readlinkSync(p)\n console.log(`- 指向目标:${targetPath}`);\n } else {\n outputErr(`不是一个软链接`, p);\n }\n }\n}\n/*\ndisc\npublic\nview\n打包时\napp.use(express.static(path.join(_dirname, 'web'))); //pages\nconst resources = path.join(_dirname, 'public')\napp.use(express.static( resources ));\n\nfunction ln-dist-resources(){\n if [ ! -d \"dist\" ]; then\n output_warn \"dist目录不存在, 创建\"\n mkdir dist\n fi\n # static\n ln -s $shelldir/views $shelldir/dist/views\n # views\n ln -s $shelldir/public $shelldir/dist/public\n}\n*/\nfunction adoptPublic(root: string, isLinux: boolean, serviceName: string) {\n outputInfo(\"--adoptPublic--\")\n root = fs.realpathSync(root)\n /*\n video-site的二级链接\n 链接到public\n public链接到dist/public\n */\n if (isLinux) {\n console.log(\"静态目录\", \"软链接/symlinkSync\", root, \"/public=>/dist/public\")\n fs.symlinkSync(path.join(root, \"public\"), path.join(root, \"dist\", \"public\"))\n console.log(\"模板目录\", \"软链接/symlinkSync\", root, \"/views=>/dist/views\")\n fs.symlinkSync(path.join(root, \"views\"), path.join(root, \"dist\", \"views\"))\n }\n else {\n // win32\n console.log(\"静态目录\", \"symlinkSync\", \"public\", \"dist/public\")\n fs.symlinkSync(path.join(root, \"public\"), path.join(root, \"dist\", \"public\"), \"junction\")\n console.log(\"模板目录\", \"symlinkSync\", \"views\", \"dist/views\")\n fs.symlinkSync(path.join(root, \"views\"), path.join(root, \"dist\", \"views\"), \"junction\")\n }\n //console.log( \"public/captures[upload]将在服务器启动时建立\" )\n createFs(root, ['captures', 'uploads'], serviceName)\n}\n\nfunction test() {\n outputInfo(\"--fetch localhost 80--\")\n setTimeout(() => {\n fetch(\"http://localhost\",).then(r => r.text()).then(r => console.log(r))\n }, 2000)\n}\n\n\n\nexport async function startService(serviceName: string) {\n await runCmd(\"systemctl\", [\"start\", serviceName])\n}\n\nexport async function stopService(serviceName: string) {\n await runCmd(\"systemctl\", [\"stop\", serviceName])\n}\n\nexport async function restartService(serviceName: string) {\n await runCmd(\"systemctl\", [\"restart\", serviceName])\n}\n\nexport async function setup(root: string, serviceName: string, isFirst: boolean) {\n outputInfo(\"--setup--\")\n if (os.platform() == \"linux\") {\n if (process.getuid && process.getuid() === 0) {\n adoptPublic(root, true, serviceName)\n // setLinuxService( root, serviceName )\n const obj = {};\n // 竟然不用命令行参数\n obj[serviceName] = path.join(\"dist\", \"serverCmd.js\")\n new SetupLinuxService(root, obj, isFirst)\n .setServices();\n await new Promise((res, rej) => {\n //setTimeout(test, 2000);\n outputInfo(\"--fetch localhost 80--\")\n setTimeout(async () => {\n try {\n await fetch(\"http://localhost\",);\n console.log(\"fetch ok\")\n } catch (err) {\n console.log(\"无法访问\")\n }\n res(0);\n }, 5000)\n })\n } else {\n console.log('Not running as root');\n process.exit(1);\n }\n } else if (os.platform() == \"win32\") {\n adoptPublic(root, false, serviceName)\n } else {\n console.log('No support platform', os.platform());\n process.exit(1);\n }\n}"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=postinst.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postinst.d.ts","sourceRoot":"","sources":["../../src/shell/postinst.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ //import { setup, serviceName, startService, stopService } from "./install.js"
2
+ export {};
3
+ //setup()
4
+ //# sourceMappingURL=postinst.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"postinst.js","sourceRoot":"","sources":["../../src/shell/postinst.ts"],"names":[],"mappings":"AAAA,8EAA8E;;AAE9E,SAAS","sourcesContent":["//import { setup, serviceName, startService, stopService } from \"./install.js\"\n\n//setup()"]}
@@ -0,0 +1,2 @@
1
+ export declare function sendMail(subject: string, text: string, html: string): Promise<void>;
2
+ //# sourceMappingURL=shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../src/shell.ts"],"names":[],"mappings":"AA8CA,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,iBAgCzE"}
package/dist/shell.js ADDED
@@ -0,0 +1,249 @@
1
+ /*
2
+ for bin/node-http-service
3
+ */
4
+ import { getProjectRoot, getPackageInfo, initLog, check, getStrictServiceName, outputErr, runCmd } from "@gogoqiu/node-base";
5
+ import path from "path";
6
+ import fs from "fs";
7
+ import os from "os";
8
+ import process from "process";
9
+ import { program } from "commander";
10
+ import { initServer } from "./server.js";
11
+ import { restartService, setup, startService, stopService } from "./shell/install.js";
12
+ import { buildTime } from "./build.js";
13
+ import nodemailer from 'nodemailer';
14
+ import readline from 'readline';
15
+ function symlink(root, dst) {
16
+ /*
17
+ 本地root的dist目录投射到http服务器的public目录
18
+ */
19
+ const dist = path.join(root, "dist");
20
+ if (fs.existsSync(path.join(dst, ".."))
21
+ && !fs.existsSync(dst)
22
+ && fs.existsSync(dist)) {
23
+ console.log("建立软链接", dist, "=>", dst);
24
+ fs.symlinkSync(dist, dst, os.platform() == "win32" ? "junction" : null);
25
+ console.log("校验");
26
+ const s = fs.lstatSync(dst);
27
+ if (s.isSymbolicLink() && fs.readlinkSync(dst) == dist) {
28
+ console.log(`校验成功`);
29
+ }
30
+ else {
31
+ outputErr(`不是一个软链接或者并不指向`, dist, fs.readlinkSync(dst));
32
+ }
33
+ }
34
+ else {
35
+ console.error("中止", "dist路径(源)不存在/目标路径已存在/目标路径父目录不存在", dist, dst, fs.realpathSync(path.join(dst, "..")));
36
+ }
37
+ }
38
+ /*
39
+ */
40
+ export async function sendMail(subject, text, html) {
41
+ // 1. 创建邮件传输器(配置 SMTP 服务)
42
+ const transporter = nodemailer.createTransport({
43
+ host: 'smtp.qq.com', // SMTP 服务器地址
44
+ port: 465, // SSL 端口(非 SSL 用 587,但推荐 SSL)
45
+ secure: true, // 开启 SSL(端口 465 时必须为 true)
46
+ auth: {
47
+ user: '88051420@qq.com', // 发送方邮箱地址
48
+ pass: 'wmywjsdmsjpwbhfa', // 不是邮箱密码,是 SMTP 授权码
49
+ },
50
+ });
51
+ // 2. 配置邮件内容
52
+ const mailOptions = {
53
+ from: '"ME" <88051420@qq.com>', // 发送方(格式:"名称" <邮箱>)
54
+ to: '88051420@qq.com', // 接收方(多个邮箱用逗号分隔)
55
+ //cc: '抄送方@xxx.com', // 抄送(可选)
56
+ //bcc: '密送方@xxx.com', // 密送(可选,接收方看不到)
57
+ subject: subject, // 邮件主题
58
+ text: text, // 纯文本正文
59
+ html: html, // HTML 正文(支持标签、图片、链接等)
60
+ };
61
+ try {
62
+ const info = await transporter.sendMail(mailOptions);
63
+ console.log('邮件发送成功!邮件 ID:', info.messageId);
64
+ console.log('预览链接:', nodemailer.getTestMessageUrl(info)); // 仅测试环境有效
65
+ }
66
+ catch (error) {
67
+ console.error('邮件发送失败:', error.message);
68
+ // 打印详细错误信息(调试用)
69
+ if (error.response) {
70
+ console.error('SMTP 响应:', error.response);
71
+ }
72
+ }
73
+ }
74
+ function get_input(title) {
75
+ return new Promise((res, rej) => {
76
+ // 创建 readline 接口
77
+ const rl = readline.createInterface({
78
+ input: process.stdin,
79
+ output: process.stdout
80
+ });
81
+ rl.question(title, (answer) => {
82
+ console.log("answer: ", answer);
83
+ res(answer);
84
+ rl.close();
85
+ });
86
+ });
87
+ }
88
+ function main() {
89
+ const root = getProjectRoot();
90
+ const info = getPackageInfo(root);
91
+ const v = info.version;
92
+ let serviceName = getStrictServiceName(info);
93
+ console.log("服务名", serviceName);
94
+ /*
95
+ 投射信息
96
+ hashinfo
97
+ */
98
+ // 参考:
99
+ // code /mnt/Data/init/git_spsp/nodejs2/vite-vscode1/src/chat/src/chat.ts
100
+ program
101
+ .name('http-control-util')
102
+ .description('CLI to aliyun')
103
+ .version(`${v}/${buildTime}`);
104
+ program.command('setup')
105
+ .description('安装, 并配置服务')
106
+ //.option('--is-first', "是否需要关闭既有服务", false)
107
+ //.argument('<destFolderPath>', '解压目录')
108
+ .action(async (options) => {
109
+ console.log("1. 首次安装, 如linux, 构建服务文件, 无需关闭之前的服务");
110
+ console.log("2. 更新版本, 子站点需要重新关联本服务器, 重启服务");
111
+ console.log("3. 更新子站点, video-site");
112
+ const ans = await get_input("选择那种情况(1/2/3)");
113
+ if (ans === "1") {
114
+ await setup(root, serviceName, true);
115
+ console.log("服务已启动");
116
+ }
117
+ else if (ans === "2") {
118
+ await setup(root, serviceName, false);
119
+ console.log("服务已启动, 手动调用子站点重关联");
120
+ }
121
+ else if (ans === "3") {
122
+ //await setup(root, serviceName, options.isFirst)
123
+ console.log("未知");
124
+ }
125
+ else {
126
+ console.log("无效选择");
127
+ }
128
+ });
129
+ program.command('start')
130
+ .description('启动服务')
131
+ .action(async (options) => {
132
+ await startService(serviceName);
133
+ });
134
+ program.command('stop')
135
+ .description('停止服务')
136
+ .action(async (options) => {
137
+ await stopService(serviceName);
138
+ });
139
+ program.command('restart')
140
+ .description('重启服务')
141
+ .action(async (options) => {
142
+ await restartService(serviceName);
143
+ });
144
+ program.command('serviceName')
145
+ .description('服务名')
146
+ .action((options) => {
147
+ console.log(serviceName);
148
+ });
149
+ program.command('run')
150
+ .description('前台运行')
151
+ .option('--port <number>', "listen port", "80") //out
152
+ .option('--debug', "debug mode", false) //out
153
+ .option('--user-dir <string>', "用户空间(captures, uploads...)", os.homedir())
154
+ .action((options) => {
155
+ initLog(info);
156
+ initServer(options, root, info);
157
+ });
158
+ program.command('installVideoSite')
159
+ .description('安装@gogoqiu/video-site并配置')
160
+ .action((options) => {
161
+ });
162
+ /*
163
+ 安装后端,附带前端
164
+ 前端文件目录投射到后端静态目录的符号
165
+ 前端项目是不存在mjs/cjs区分的,就是dist目录
166
+ public内的投射:
167
+ 自投射: 根目录下views=>/dist/views, public=>/dist/public
168
+ 外部投射: 外部目录下的dist=>/dist/public/${alias}
169
+ */
170
+ program.command('installComp')
171
+ .description('安装组件, 比如video-site')
172
+ //.option( "--alias <string>", `投射的节点名, 安装的组件dist投射到本项目public/\${alias},\
173
+ //未指定, 则投射到Date.now()`, false )
174
+ .argument('<name>', '组件名')
175
+ .argument('<alias>', `安装的组件dist投射到本项目public/\${alias}`)
176
+ .action(async (name, options) => {
177
+ /*
178
+ if( os.platform() != "linux"){
179
+ console.error("只支持linux平台")
180
+ process.exit(1)
181
+ }
182
+ */
183
+ // 组件hook, 如安装完成, 运行, 确保${name}组件存在
184
+ const { code, stdout, stderr } = await runCmd("npm", ["install", "-g", name]);
185
+ check(code);
186
+ // 包安装模式
187
+ /*
188
+ const dir = `/usr/lib/node_modules/${name}/bin/aliyun-http-server`
189
+ console.log( "执行hooks", path.join( dir, "postinst" ) )
190
+ await runCmd( path.join( dir, "postinst" ), [] )
191
+ */
192
+ const pRoot = getProjectDir(root, name);
193
+ const src = path.join(pRoot, "dist");
194
+ const dst = path.join(root, "public", options.alias ? options.alias : Date.now().toString());
195
+ if (fs.existsSync(dst)) {
196
+ console.error("覆盖", "目标已存在", dst);
197
+ fs.unlinkSync(dst);
198
+ }
199
+ console.log("建立软链接", src, "=>", dst);
200
+ fs.symlinkSync(src, dst, os.platform() == "win32" ? "junction" : null);
201
+ });
202
+ program.command('postMail')
203
+ .description('发送email')
204
+ .action(async (options) => {
205
+ // 1. 创建邮件传输器(配置 SMTP 服务)
206
+ const transporter = nodemailer.createTransport({
207
+ host: 'smtp.qq.com', // SMTP 服务器地址
208
+ port: 465, // SSL 端口(非 SSL 用 587,但推荐 SSL)
209
+ secure: true, // 开启 SSL(端口 465 时必须为 true)
210
+ auth: {
211
+ user: '88051420@qq.com', // 发送方邮箱地址
212
+ pass: 'wmywjsdmsjpwbhfa', // 不是邮箱密码,是 SMTP 授权码
213
+ },
214
+ });
215
+ // 2. 配置邮件内容
216
+ const mailOptions = {
217
+ from: '"ME" <88051420@qq.com>', // 发送方(格式:"名称" <邮箱>)
218
+ to: '88051420@qq.com', // 接收方(多个邮箱用逗号分隔)
219
+ //cc: '抄送方@xxx.com', // 抄送(可选)
220
+ //bcc: '密送方@xxx.com', // 密送(可选,接收方看不到)
221
+ subject: 'Node.js 发送的测试邮件', // 邮件主题
222
+ text: '这是纯文本内容(如果接收方不支持 HTML 则显示此内容)', // 纯文本正文
223
+ html: `
224
+ <h1>HTML 邮件内容</h1>
225
+ <p>这是 <strong>加粗文本</strong></p>
226
+ <a href="https://nodejs.org">Node.js 官网</a>
227
+ <img src="https://nodejs.org/static/images/logo.svg" alt="Node.js Logo" />
228
+ `, // HTML 正文(支持标签、图片、链接等)
229
+ };
230
+ try {
231
+ const info = await transporter.sendMail(mailOptions);
232
+ console.log('邮件发送成功!邮件 ID:', info.messageId);
233
+ console.log('预览链接:', nodemailer.getTestMessageUrl(info)); // 仅测试环境有效
234
+ }
235
+ catch (error) {
236
+ console.error('邮件发送失败:', error.message);
237
+ // 打印详细错误信息(调试用)
238
+ if (error.response) {
239
+ console.error('SMTP 响应:', error.response);
240
+ }
241
+ }
242
+ });
243
+ program.parse();
244
+ }
245
+ function getProjectDir(root, name) {
246
+ return fs.realpathSync(path.join(root, "..", name));
247
+ }
248
+ main();
249
+ //# sourceMappingURL=shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.js","sourceRoot":"","sources":["../src/shell.ts"],"names":[],"mappings":"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","sourcesContent":["\n/*\nfor bin/node-http-service\n*/\nimport {\n getPackageInfoFromScriptPath, getProjectRoot, getVersion, getPackageInfo,\n initLog, logError, logInfo, logWarn, check, getServiceName, getStrictServiceName,\n outputInfo, outputWarn, outputErr, runCmd, RunResult\n} from \"@gogoqiu/node-base\"\nimport path from \"path\"\nimport fs from \"fs\"\nimport os from \"os\"\nimport process from \"process\"\n\nimport { Command, program } from \"commander\"\nimport { initServer } from \"./server.js\";\nimport { restartService, setup, startService, stopService } from \"./shell/install.js\"\nimport { buildTime } from \"./build.js\"\nimport nodemailer from 'nodemailer';\nimport readline from 'readline';\n\nfunction symlink(root, dst) {\n /*\n 本地root的dist目录投射到http服务器的public目录\n */\n const dist = path.join(root, \"dist\")\n if (fs.existsSync(path.join(dst, \"..\"))\n && !fs.existsSync(dst)\n && fs.existsSync(dist)) {\n console.log(\"建立软链接\", dist, \"=>\", dst)\n fs.symlinkSync(dist, dst, os.platform() == \"win32\" ? \"junction\" : null)\n console.log(\"校验\")\n const s = fs.lstatSync(dst)\n if (s.isSymbolicLink() && fs.readlinkSync(dst) == dist) {\n console.log(`校验成功`);\n } else {\n outputErr(`不是一个软链接或者并不指向`, dist, fs.readlinkSync(dst));\n }\n } else {\n console.error(\"中止\", \"dist路径(源)不存在/目标路径已存在/目标路径父目录不存在\",\n dist, dst, fs.realpathSync(path.join(dst, \"..\")))\n }\n}\n\n/*\n*/\nexport async function sendMail(subject: string, text: string, html: string) {\n // 1. 创建邮件传输器(配置 SMTP 服务)\n const transporter = nodemailer.createTransport({\n host: 'smtp.qq.com', // SMTP 服务器地址\n port: 465, // SSL 端口(非 SSL 用 587,但推荐 SSL)\n secure: true, // 开启 SSL(端口 465 时必须为 true)\n auth: {\n user: '88051420@qq.com', // 发送方邮箱地址\n pass: 'wmywjsdmsjpwbhfa', // 不是邮箱密码,是 SMTP 授权码\n },\n });\n // 2. 配置邮件内容\n const mailOptions = {\n from: '\"ME\" <88051420@qq.com>', // 发送方(格式:\"名称\" <邮箱>)\n to: '88051420@qq.com', // 接收方(多个邮箱用逗号分隔)\n //cc: '抄送方@xxx.com', // 抄送(可选)\n //bcc: '密送方@xxx.com', // 密送(可选,接收方看不到)\n subject: subject, // 邮件主题\n text: text, // 纯文本正文\n html: html, // HTML 正文(支持标签、图片、链接等)\n };\n try {\n const info = await transporter.sendMail(mailOptions);\n console.log('邮件发送成功!邮件 ID:', info.messageId);\n console.log('预览链接:', nodemailer.getTestMessageUrl(info)); // 仅测试环境有效\n } catch (error) {\n console.error('邮件发送失败:', error.message);\n // 打印详细错误信息(调试用)\n if (error.response) {\n console.error('SMTP 响应:', error.response);\n }\n }\n}\n\nfunction get_input(title: string): Promise<string> {\n return new Promise((res, rej) => {\n // 创建 readline 接口\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n rl.question(title, (answer) => {\n console.log(\"answer: \", answer)\n res(answer)\n rl.close();\n })\n })\n}\n\nfunction main() {\n const root = getProjectRoot()\n const info = getPackageInfo(root);\n const v = info.version\n let serviceName = getStrictServiceName(info)\n console.log(\"服务名\", serviceName)\n /*\n 投射信息\n hashinfo\n */\n // 参考:\n // code /mnt/Data/init/git_spsp/nodejs2/vite-vscode1/src/chat/src/chat.ts\n program\n .name('http-control-util')\n .description('CLI to aliyun')\n .version(`${v}/${buildTime}`)\n\n program.command('setup')\n .description('安装, 并配置服务')\n //.option('--is-first', \"是否需要关闭既有服务\", false)\n //.argument('<destFolderPath>', '解压目录')\n .action(async (options) => {\n console.log(\"1. 首次安装, 如linux, 构建服务文件, 无需关闭之前的服务\")\n console.log(\"2. 更新版本, 子站点需要重新关联本服务器, 重启服务\")\n console.log(\"3. 更新子站点, video-site\")\n const ans = await get_input(\"选择那种情况(1/2/3)\")\n if (ans === \"1\") {\n await setup(root, serviceName, true)\n console.log(\"服务已启动\")\n } else if (ans === \"2\") {\n await setup(root, serviceName, false)\n console.log(\"服务已启动, 手动调用子站点重关联\")\n } else if (ans === \"3\") {\n //await setup(root, serviceName, options.isFirst)\n console.log(\"未知\")\n } else {\n console.log(\"无效选择\")\n }\n });\n\n program.command('start')\n .description('启动服务')\n .action(async (options) => {\n await startService(serviceName)\n });\n\n program.command('stop')\n .description('停止服务')\n .action(async (options) => {\n await stopService(serviceName)\n });\n\n program.command('restart')\n .description('重启服务')\n .action(async (options) => {\n await restartService(serviceName)\n });\n\n program.command('serviceName')\n .description('服务名')\n .action((options) => {\n console.log(serviceName)\n });\n\n program.command('run')\n .description('前台运行')\n .option('--port <number>', \"listen port\", \"80\")//out\n .option('--debug', \"debug mode\", false)//out\n .option('--user-dir <string>', \"用户空间(captures, uploads...)\", os.homedir())\n .action((options) => {\n initLog(info)\n initServer(options, root, info);\n });\n\n program.command('installVideoSite')\n .description('安装@gogoqiu/video-site并配置')\n .action((options) => {\n\n });\n\n /*\n 安装后端,附带前端\n 前端文件目录投射到后端静态目录的符号\n 前端项目是不存在mjs/cjs区分的,就是dist目录\n public内的投射:\n 自投射: 根目录下views=>/dist/views, public=>/dist/public\n 外部投射: 外部目录下的dist=>/dist/public/${alias}\n */\n program.command('installComp')\n .description('安装组件, 比如video-site')\n //.option( \"--alias <string>\", `投射的节点名, 安装的组件dist投射到本项目public/\\${alias},\\ \n //未指定, 则投射到Date.now()`, false )\n .argument('<name>', '组件名')\n .argument('<alias>', `安装的组件dist投射到本项目public/\\${alias}`)\n .action(async (name, options) => {\n /*\n if( os.platform() != \"linux\"){\n console.error(\"只支持linux平台\")\n process.exit(1)\n }\n */\n // 组件hook, 如安装完成, 运行, 确保${name}组件存在\n const { code, stdout, stderr } = await runCmd(\"npm\", [\"install\", \"-g\", name])\n check(code)\n // 包安装模式\n /*\n const dir = `/usr/lib/node_modules/${name}/bin/aliyun-http-server`\n console.log( \"执行hooks\", path.join( dir, \"postinst\" ) ) \n await runCmd( path.join( dir, \"postinst\" ), [] )\n */\n const pRoot = getProjectDir(root, name)\n\n const src = path.join(pRoot, \"dist\")\n const dst = path.join(root, \"public\",\n options.alias ? options.alias : Date.now().toString())\n if (fs.existsSync(dst)) {\n console.error(\"覆盖\", \"目标已存在\", dst)\n fs.unlinkSync(dst)\n }\n console.log(\"建立软链接\", src, \"=>\", dst)\n fs.symlinkSync(src, dst, os.platform() == \"win32\" ? \"junction\" : null)\n });\n\n program.command('postMail')\n .description('发送email')\n .action(async (options) => {\n // 1. 创建邮件传输器(配置 SMTP 服务)\n const transporter = nodemailer.createTransport({\n host: 'smtp.qq.com', // SMTP 服务器地址\n port: 465, // SSL 端口(非 SSL 用 587,但推荐 SSL)\n secure: true, // 开启 SSL(端口 465 时必须为 true)\n auth: {\n user: '88051420@qq.com', // 发送方邮箱地址\n pass: 'wmywjsdmsjpwbhfa', // 不是邮箱密码,是 SMTP 授权码\n },\n });\n // 2. 配置邮件内容\n const mailOptions = {\n from: '\"ME\" <88051420@qq.com>', // 发送方(格式:\"名称\" <邮箱>)\n to: '88051420@qq.com', // 接收方(多个邮箱用逗号分隔)\n //cc: '抄送方@xxx.com', // 抄送(可选)\n //bcc: '密送方@xxx.com', // 密送(可选,接收方看不到)\n subject: 'Node.js 发送的测试邮件', // 邮件主题\n text: '这是纯文本内容(如果接收方不支持 HTML 则显示此内容)', // 纯文本正文\n html: `\n <h1>HTML 邮件内容</h1>\n <p>这是 <strong>加粗文本</strong></p>\n <a href=\"https://nodejs.org\">Node.js 官网</a>\n <img src=\"https://nodejs.org/static/images/logo.svg\" alt=\"Node.js Logo\" />\n `, // HTML 正文(支持标签、图片、链接等)\n };\n try {\n const info = await transporter.sendMail(mailOptions);\n console.log('邮件发送成功!邮件 ID:', info.messageId);\n console.log('预览链接:', nodemailer.getTestMessageUrl(info)); // 仅测试环境有效\n } catch (error) {\n console.error('邮件发送失败:', error.message);\n // 打印详细错误信息(调试用)\n if (error.response) {\n console.error('SMTP 响应:', error.response);\n }\n }\n })\n\n program.parse();\n}\n\nfunction getProjectDir(root: string, name: string) {\n return fs.realpathSync(path.join(root, \"..\", name))\n}\n\nmain()"]}
package/package.json ADDED
@@ -0,0 +1,82 @@
1
+ {
2
+ "name": "@gogoqiu/tencent-http-server",
3
+ "type": "module",
4
+ "version": "0.0.3",
5
+ "description": "tencent网站",
6
+ "scripts": {
7
+ "build": "tsc -p tsconfig.json",
8
+ "dev": "pm2 start dist/server.js --watch"
9
+ },
10
+ "dependencies": {
11
+ "@gogoqiu/node-base": "^0.0.68",
12
+ "@gogoqiu/repo-http-server": "^2.0.30",
13
+ "@gogoqiu/ts-base": "^0.0.35",
14
+ "axios": "^1.7.8",
15
+ "body-parser": "^2.2.0",
16
+ "commander": "^14.0.0",
17
+ "cookie-parser": "^1.4.7",
18
+ "cors": "^2.8.5",
19
+ "debug": "^4.4.1",
20
+ "ejs": "^3.1.10",
21
+ "express": "^5.1.0",
22
+ "log4js": "^6.9.1",
23
+ "morgan": "^1.10.0",
24
+ "multer": "^2.0.1",
25
+ "mysql2": "^3.14.3",
26
+ "node-media-server": "^4.0.18",
27
+ "nodemailer": "^7.0.10",
28
+ "rotating-file-stream": "^3.2.6",
29
+ "sharp": "^0.34.3",
30
+ "socket.io": "^4.8.1",
31
+ "ssh2": "^1.16.0",
32
+ "ws": "^8.18.2"
33
+ },
34
+ "devDependencies": {
35
+ "@rollup/plugin-commonjs": "^28.0.6",
36
+ "@rollup/plugin-json": "^6.1.0",
37
+ "@rollup/plugin-node-resolve": "^16.0.1",
38
+ "@rollup/plugin-terser": "^0.4.4",
39
+ "@rollup/plugin-typescript": "^12.1.4",
40
+ "@types/body-parser": "^1.19.5",
41
+ "@types/cookie-parser": "^1.4.8",
42
+ "@types/debug": "^4.1.12",
43
+ "@types/ejs": "^3.1.5",
44
+ "@types/express": "^5.0.1",
45
+ "@types/morgan": "^1.9.9",
46
+ "@types/multer": "^1.4.13",
47
+ "@types/node": "^22.10.1",
48
+ "@types/nodemailer": "^7.0.4",
49
+ "@types/ssh2": "^1.15.5",
50
+ "@types/ws": "^8.18.1",
51
+ "rollup": "^4.46.3",
52
+ "rollup-plugin-copy": "^3.5.0",
53
+ "rollup-plugin-node-polyfills": "^0.2.1",
54
+ "ts-node-dev": "^2.0.0",
55
+ "tslib": "^2.8.1"
56
+ },
57
+ "files": [
58
+ "bin",
59
+ "cert",
60
+ "dist",
61
+ "public",
62
+ "views"
63
+ ],
64
+ "bin": {
65
+ "gogoqiu-node-http-service": "./bin/gogoqiu-node-http-service"
66
+ },
67
+ "binDescription": {
68
+ "gogoqiu-node-http-service": "安装工具"
69
+ },
70
+ "publishConfig": {
71
+ "access": "public",
72
+ "registry": "https://registry.npmjs.org/"
73
+ },
74
+ "module": "./dist/index.js",
75
+ "types": "./dist/index.d.ts",
76
+ "exports": {
77
+ ".": {
78
+ "import": "./dist/index.js",
79
+ "types": "./dist/index.d.ts"
80
+ }
81
+ }
82
+ }