pubo-node 1.0.198 → 1.0.202

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/README.md ADDED
@@ -0,0 +1,320 @@
1
+ # pubo-node
2
+
3
+ Node.js 工具库,提供文件存储、FTP 客户端、gRPC 客户端、进程管理、网络工具、ROS 主题管理和文件系统操作等功能。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ npm install pubo-node
9
+ ```
10
+
11
+ ## API 文档
12
+
13
+ ### JsonStorage
14
+
15
+ 基于 JSON 的文件存储类,支持多进程同步。
16
+
17
+ **构造函数**
18
+ ```typescript
19
+ constructor(path: string, options: JsonStorageOptions = {})
20
+ ```
21
+ - `path`: 存储文件路径
22
+ - `options`: 可选配置
23
+ - `initialState`: 初始状态,程序运行时会重置为初始值
24
+ - `defaultState`: 默认状态
25
+
26
+ **方法**
27
+ - `async get(key?: string): Promise<any>`
28
+ - 获取指定键的值,不传键则返回整个状态
29
+ - `async set(key: string, values: any): Promise<void>`
30
+ - 设置指定键的值
31
+ - `async merge(values: any): Promise<void>`
32
+ - 合并多个键值到状态
33
+ - `async remove(key: string): Promise<void>`
34
+ - 删除指定键
35
+
36
+ ### FtpClient
37
+
38
+ FTP 客户端类,支持连接池和异步操作。
39
+
40
+ **构造函数**
41
+ ```typescript
42
+ constructor(options: FtpConnectOptions)
43
+ ```
44
+ - `options`: 连接选项
45
+ - `user`: 用户名
46
+ - `host`: 主机地址
47
+ - `password`: 密码
48
+ - `driver`: FTP 驱动
49
+
50
+ **方法**
51
+ - `async get(path: string): Promise<Buffer>`
52
+ - 下载文件
53
+ - `async put(input: string | Buffer | Stream, path: string): Promise<string>`
54
+ - 上传文件
55
+ - `async delete(path: string): Promise<string>`
56
+ - 删除文件
57
+ - `async list(path: string): Promise<FtpFile[]>`
58
+ - 列出目录文件
59
+ - `async rename(path: string, old: string): Promise<string>`
60
+ - 重命名文件
61
+
62
+ ### FtpClientPool
63
+
64
+ FTP 客户端连接池,管理多个 FTP 连接。
65
+
66
+ **构造函数**
67
+ ```typescript
68
+ constructor({ maxConnection = 5, ...options }: { maxConnection?: number } & FtpConnectOptions)
69
+ ```
70
+ - `maxConnection`: 最大连接数,默认 5
71
+ - `options`: 同 FtpClient 连接选项
72
+
73
+ **方法**
74
+ 同 FtpClient 接口。
75
+
76
+ ### createRpcClient
77
+
78
+ 创建 gRPC 客户端。
79
+
80
+ **函数签名**
81
+ ```typescript
82
+ function createRpcClient<T>({ url, options = {}, ServiceImp, Grpc, cert }: CreateClientProps): T
83
+ ```
84
+ - `url`: gRPC 服务地址
85
+ - `options`: 连接选项
86
+ - `ServiceImp`: 服务实现类
87
+ - `Grpc`: gRPC 模块
88
+ - `cert`: TLS 证书缓冲区
89
+
90
+ ### GrpcList
91
+
92
+ 全局 gRPC 客户端列表,用于管理所有创建的 gRPC 客户端。
93
+
94
+ ### isPortAvailable
95
+
96
+ 检查端口是否可用。
97
+
98
+ **函数签名**
99
+ ```typescript
100
+ function isPortAvailable(port: number): Promise<boolean>
101
+ ```
102
+
103
+ ### 进程管理函数
104
+
105
+ 以下函数由 `PProcess` 接口提供,具体实现根据操作系统(Linux/Windows)不同。
106
+
107
+ #### getProcessName
108
+ ```typescript
109
+ function getProcessName(pid: number): Promise<string>
110
+ ```
111
+ 获取进程名称。
112
+
113
+ #### getPidByPort
114
+ ```typescript
115
+ function getPidByPort(port: number): Promise<number>
116
+ ```
117
+ 根据端口号获取进程 PID。
118
+
119
+ #### getProcessCpuUseByPid
120
+ ```typescript
121
+ function getProcessCpuUseByPid(pid: number): Promise<number>
122
+ ```
123
+ 获取进程 CPU 使用率(百分比)。
124
+
125
+ #### getProcessCommandByPid
126
+ ```typescript
127
+ function getProcessCommandByPid(pid: number): Promise<string>
128
+ ```
129
+ 获取进程命令行。
130
+
131
+ #### isProcessDied
132
+ ```typescript
133
+ function isProcessDied(pid: number): Promise<boolean>
134
+ ```
135
+ 判断进程是否已死亡。
136
+
137
+ #### getProcessByPpid
138
+ ```typescript
139
+ function getProcessByPpid(ppid: number): Promise<number[]>
140
+ ```
141
+ 获取指定父进程的所有子进程 PID 列表。
142
+
143
+ #### getProcessTree
144
+ ```typescript
145
+ function getProcessTree(pid: number, tree?: any): Promise<any>
146
+ ```
147
+ 获取进程树结构。
148
+
149
+ #### getProcessList
150
+ ```typescript
151
+ function getProcessList(pid: number): Promise<number[]>
152
+ ```
153
+ 获取从叶子到根的所有进程 PID 列表。
154
+
155
+ #### SIGKILL
156
+ ```typescript
157
+ function SIGKILL(pid: number, signal = 2, times = 1): Promise<{ success: boolean; error: string }>
158
+ ```
159
+ 杀死进程及其子进程。
160
+
161
+ #### heartbeat
162
+ ```typescript
163
+ function heartbeat(): void
164
+ ```
165
+ 子进程心跳包,每6秒发送一次。
166
+
167
+ #### getAudioCards
168
+ ```typescript
169
+ function getAudioCards(filter?: string): Promise<{ text: string; index: string }[]>
170
+ ```
171
+ 获取音频设备列表(仅 Linux)。
172
+
173
+ #### getDiskUsage
174
+ ```typescript
175
+ function getDiskUsage(): Promise<DiskInfo[]>
176
+ ```
177
+ 获取磁盘使用情况。
178
+
179
+ ### 网络工具
180
+
181
+ #### getNetworks
182
+ ```typescript
183
+ function getNetworks(): Promise<any[]>
184
+ ```
185
+ 获取网络接口信息(通过 lshw 命令)。
186
+
187
+ #### getWifiName
188
+ ```typescript
189
+ function getWifiName(): Promise<string>
190
+ ```
191
+ 获取无线网络接口名称。
192
+
193
+ ### RosTopicManager
194
+
195
+ ROS 主题管理器,用于创建和管理 ROS 主题。
196
+
197
+ **方法**
198
+ - `getTopic(topic: string, messageType: string): RosTopic`
199
+ - 获取或创建 ROS 主题实例
200
+
201
+ ### RosTopic
202
+
203
+ ROS 主题类,支持订阅、取消订阅和发布消息。
204
+
205
+ **构造函数**
206
+ ```typescript
207
+ constructor(topic: string, messageType: string)
208
+ ```
209
+
210
+ **方法**
211
+ - `async subscribe(): Promise<void>`
212
+ - 订阅主题
213
+ - `async unsubscribe(): Promise<void>`
214
+ - 取消订阅
215
+ - `async publish(payload: any): Promise<void>`
216
+ - 发布消息到主题
217
+
218
+ ### PuboFileSystem
219
+
220
+ 文件系统操作接口,提供 Promise 化的 fs 方法。
221
+
222
+ **方法**
223
+ - `read<TBuffer extends NodeJS.ArrayBufferView>(fd: number, buffer?: TBuffer, offset?: number, length?: number, position?: fs.ReadPosition | null): Promise<[number, TBuffer]>`
224
+ - 从文件描述符读取数据
225
+ - `stat(path: fs.PathLike): Promise<fs.Stats>`
226
+ - 获取文件状态
227
+ - `readFile(path: fs.PathOrFileDescriptor, options?: { encoding?: null; flag?: string } & EventEmitter.Abortable | null): Promise<Buffer>`
228
+ - 读取文件内容
229
+ - `writeFile(file: fs.PathOrFileDescriptor, data: string | NodeJS.ArrayBufferView, options?: fs.WriteFileOptions): Promise<void>`
230
+ - 写入文件
231
+ - `readdir(path: fs.PathLike, options?: BufferEncoding | { encoding: BufferEncoding | null; withFileTypes: false } | null): Promise<string[]>`
232
+ - 读取目录内容
233
+ - `open(path: fs.PathLike, flags?: fs.OpenMode, mode?: fs.Mode | null): Promise<number>`
234
+ - 打开文件
235
+ - `close(fd: number): Promise<void>`
236
+ - 关闭文件描述符
237
+ - `mkdir(path: fs.PathLike, options?: fs.MakeDirectoryOptions): Promise<void>`
238
+ - 创建目录
239
+ - `rm(path: fs.PathLike): Promise<void>`
240
+ - 删除文件或目录
241
+ - `write<TBuffer extends NodeJS.ArrayBufferView>(fd: number, buffer: TBuffer, offset?: number | null, length?: number | null, position?: number | null): Promise<void>`
242
+ - 写入数据到文件描述符
243
+
244
+ ### PProcess
245
+
246
+ 进程管理接口,定义了跨平台的进程操作方法。由 `PProcessLinux` 和 `PProcessWin32` 实现。
247
+
248
+ **方法**
249
+ 参见上述进程管理函数。
250
+
251
+ ## 类型定义
252
+
253
+ ### FtpConnectOptions
254
+ ```typescript
255
+ interface FtpConnectOptions {
256
+ user: string;
257
+ host: string;
258
+ password: string;
259
+ driver: any;
260
+ }
261
+ ```
262
+
263
+ ### FtpFile
264
+ ```typescript
265
+ interface FtpFile {
266
+ name: string;
267
+ owner: string;
268
+ group: string;
269
+ size: number;
270
+ date: Date;
271
+ type: string;
272
+ }
273
+ ```
274
+
275
+ ### DiskInfo
276
+ ```typescript
277
+ interface DiskInfo {
278
+ fileSystem: string;
279
+ size: number;
280
+ used: number;
281
+ avail: number;
282
+ usedPercent: number;
283
+ mounted: number;
284
+ }
285
+ ```
286
+
287
+ ### JsonStorageOptions
288
+ ```typescript
289
+ interface JsonStorageOptions {
290
+ initialState?: any;
291
+ defaultState?: any;
292
+ }
293
+ ```
294
+
295
+ ## 示例
296
+
297
+ ```javascript
298
+ const { JsonStorage, FtpClient, isPortAvailable } = require('pubo-node');
299
+
300
+ // 使用 JsonStorage
301
+ const storage = new JsonStorage('./data.json', { initialState: { count: 0 } });
302
+ await storage.set('count', 1);
303
+ const value = await storage.get('count');
304
+
305
+ // 使用 FTP 客户端
306
+ const ftp = new FtpClient({
307
+ user: 'user',
308
+ host: 'localhost',
309
+ password: 'pass',
310
+ driver: require('ftp')
311
+ });
312
+ const files = await ftp.list('/');
313
+
314
+ // 检查端口
315
+ const available = await isPortAvailable(8080);
316
+ ```
317
+
318
+ ## 许可证
319
+
320
+ MIT
@@ -1,15 +1,18 @@
1
1
  export declare function getProcessName(pid: any): Promise<string>;
2
- export declare function getPidByPort(port: any): Promise<unknown>;
2
+ export declare function getPidByPort(port: any): Promise<number>;
3
3
  export declare function getProcessCpuUseByPid(pid: number): Promise<number>;
4
4
  export declare function getProcessCommandByPid(pid: number): Promise<string>;
5
5
  export declare function isProcessDied(pid: number): Promise<boolean>;
6
6
  export declare function getProcessByPpid(pid: number): Promise<number[]>;
7
7
  export declare const getProcessTree: (pid: number, tree?: any) => Promise<any>;
8
8
  export declare const getProcessList: (pid: any) => Promise<number[]>;
9
- export declare function SIGKILL(pid: number, signal?: number, times?: number): Promise<unknown>;
9
+ export declare function SIGKILL(pid: number, signal?: number, times?: number): Promise<{
10
+ success: boolean;
11
+ error: string;
12
+ }>;
10
13
  export declare const heartbeat: () => void;
11
14
  export declare const getAudioCards: (filter?: string) => Promise<{
12
15
  text: string;
13
16
  index: string;
14
17
  }[]>;
15
- export declare const getDiskUsage: () => Promise<unknown>;
18
+ export declare const getDiskUsage: () => Promise<import("./p-process-type").DiskInfo[]>;
@@ -8,129 +8,33 @@ exports.getProcessCommandByPid = getProcessCommandByPid;
8
8
  exports.isProcessDied = isProcessDied;
9
9
  exports.getProcessByPpid = getProcessByPpid;
10
10
  exports.SIGKILL = SIGKILL;
11
- const child_process_1 = require("child_process");
12
11
  const pubo_utils_1 = require("pubo-utils");
12
+ const linux_1 = require("./linux");
13
+ const win32_1 = require("./win32");
14
+ const processManager = process.platform === 'win32' ? new win32_1.PProcessWin32() : new linux_1.PProcessLinux();
13
15
  // 获取进程名称
14
16
  function getProcessName(pid) {
15
- if (process.platform === 'win32') {
16
- // 使用tasklist命令获取进程信息
17
- return new Promise((resolve, reject) => {
18
- (0, child_process_1.exec)(`tasklist /fi "PID eq ${pid}" /fo csv /nh`, (err, stdout) => {
19
- if (err) {
20
- reject(err);
21
- }
22
- else {
23
- // 解析CSV格式的输出
24
- const match = stdout.match(/^"(.+?)"/);
25
- if (match && match[1]) {
26
- resolve(match[1]);
27
- }
28
- else {
29
- reject('process not found');
30
- }
31
- }
32
- });
33
- });
34
- }
35
- return new Promise((resolve, reject) => {
36
- (0, child_process_1.exec)(`grep "Name:" /proc/${pid}/status`, (err, data) => {
37
- if (err) {
38
- reject(err);
39
- }
40
- else {
41
- resolve(data.toString().split(':')[1]?.trim());
42
- }
43
- });
44
- });
17
+ return processManager.getProcessName(pid);
45
18
  }
46
19
  // 根据端口号获取进程PID
47
20
  async function getPidByPort(port) {
48
- if (!port) {
49
- return '';
50
- }
51
- if (process.platform === 'win32') {
52
- return new Promise((resolve, reject) => {
53
- (0, child_process_1.exec)(`netstat -ano | findstr "${port}"`, (error, stdout) => {
54
- if (error) {
55
- reject(error);
56
- return;
57
- }
58
- const arr = stdout.split('\n');
59
- if (!arr[0]) {
60
- resolve('');
61
- return;
62
- }
63
- const tmp = arr[0].split(' ');
64
- const res = tmp.pop();
65
- resolve(res);
66
- });
67
- });
68
- }
69
- return new Promise((resolve, reject) => {
70
- (0, child_process_1.exec)(`lsof -i:${port} | awk '{print $2}'`, (err, stdout) => {
71
- if (err) {
72
- reject(err);
73
- }
74
- else {
75
- let res = stdout.split('\n')[1];
76
- if (res) {
77
- res = res.trim();
78
- }
79
- resolve(res);
80
- }
81
- });
82
- });
21
+ return processManager.getPidByPort(port);
83
22
  }
84
23
  // 获取进程 cpu 使用率
85
24
  function getProcessCpuUseByPid(pid) {
86
- return new Promise((resolve) => {
87
- (0, child_process_1.exec)(`ps -p ${pid} -o %cpu=`, (err, stdout) => {
88
- if (err) {
89
- resolve(-1);
90
- }
91
- else {
92
- resolve(parseFloat(stdout.toString()));
93
- }
94
- });
95
- });
25
+ return processManager.getProcessCpuUseByPid(pid);
96
26
  }
97
27
  // 获取进程 command
98
28
  function getProcessCommandByPid(pid) {
99
- return new Promise((resolve) => {
100
- (0, child_process_1.exec)(`ps -p ${pid} -o command=`, (err, stdout) => {
101
- if (err) {
102
- resolve('');
103
- }
104
- else {
105
- resolve(stdout.toString().split('\n')[0]);
106
- }
107
- });
108
- });
29
+ return processManager.getProcessCommandByPid(pid);
109
30
  }
110
31
  // 判断进程是否死亡
111
32
  async function isProcessDied(pid) {
112
- const used = await getProcessCpuUseByPid(pid);
113
- // console.log(`pid: ${pid}, used: ${used}`);
114
- return used < 0;
33
+ return processManager.isProcessDied(pid);
115
34
  }
116
35
  // 获取子进程
117
36
  function getProcessByPpid(pid) {
118
- return new Promise((resolve) => {
119
- let child = (0, child_process_1.exec)(`ps -o pid --no-headers --ppid ${pid}`, (err, stdout) => {
120
- if (err) {
121
- resolve([]);
122
- child = null;
123
- }
124
- else {
125
- resolve(stdout
126
- .split('\n')
127
- .filter((item) => !!item)
128
- .map((item) => parseInt(item.trim()))
129
- .filter((item) => item !== child.pid && !isNaN(item)));
130
- child = null;
131
- }
132
- });
133
- });
37
+ return processManager.getProcessByPpid(pid);
134
38
  }
135
39
  // 获取进程树
136
40
  const getProcessTree = async (pid, tree) => {
@@ -154,22 +58,6 @@ const getProcessTree = async (pid, tree) => {
154
58
  }
155
59
  };
156
60
  exports.getProcessTree = getProcessTree;
157
- // 杀死进程
158
- async function _SIGKILL(pid, signal = 2, times = 1) {
159
- if (times > 5) {
160
- throw new Error('SIGKILL 失败. times > 5');
161
- }
162
- await new Promise((resolve) => (0, child_process_1.exec)(`kill -${signal} ${pid}`, resolve));
163
- try {
164
- await (0, pubo_utils_1.waitFor)(async () => isProcessDied(pid), {
165
- checkTime: 100,
166
- timeout: 4000,
167
- });
168
- }
169
- catch (err) {
170
- await _SIGKILL(pid, 9, times + 1);
171
- }
172
- }
173
61
  // 广度优先遍历进程树,将pid放入tmp
174
62
  const flatProcessTree = (tree, tmp) => {
175
63
  if (tree.children) {
@@ -195,23 +83,7 @@ const getProcessList = async (pid) => {
195
83
  exports.getProcessList = getProcessList;
196
84
  // 杀死进程以及子进程
197
85
  async function SIGKILL(pid, signal = 2, times = 1) {
198
- if (process.platform === 'win32') {
199
- return new Promise((resolve) => {
200
- (0, child_process_1.exec)(`taskkill /pid ${pid} /T /F`, resolve);
201
- });
202
- }
203
- const tmp = await (0, exports.getProcessList)(pid);
204
- const res = { success: true, error: null };
205
- for (const item of tmp) {
206
- try {
207
- await _SIGKILL(item, signal, times);
208
- }
209
- catch (err) {
210
- res.error = err;
211
- res.success = false;
212
- }
213
- }
214
- return res;
86
+ return processManager.SIGKILL(pid, signal, times);
215
87
  }
216
88
  // 子进程心跳包
217
89
  const heartbeat = () => {
@@ -225,61 +97,17 @@ const heartbeat = () => {
225
97
  }, 6000);
226
98
  };
227
99
  exports.heartbeat = heartbeat;
228
- const parseAudioCard = (v) => {
229
- let card = /card \d/.exec(v) ?? ['card 1'];
230
- card = parseInt(card[0].replace('card ', ''), 10);
231
- let device = /device \d/.exec(v) ?? ['device 0'];
232
- device = parseInt(device[0].replace('device ', ''), 10);
233
- return { text: v, index: `hw:${card},${device}` };
234
- };
235
100
  const getAudioCards = (filter = '') => {
236
- if (process.platform === 'win32') {
237
- return Promise.resolve([]);
101
+ if (processManager.getAudioCards) {
102
+ return processManager.getAudioCards(filter);
238
103
  }
239
- return new Promise((resolve, reject) => {
240
- (0, child_process_1.exec)(`arecord -l`, (err, stdout) => {
241
- if (err) {
242
- reject(err);
243
- }
244
- else {
245
- const arr = stdout
246
- .toString()
247
- .split('\n')
248
- .filter((item) => item.includes('card') && (filter ? item.includes(filter) : true))
249
- .map((item) => parseAudioCard(item));
250
- resolve(arr);
251
- }
252
- });
253
- });
104
+ return Promise.resolve([]);
254
105
  };
255
106
  exports.getAudioCards = getAudioCards;
256
- const dic = ['fileSystem', 'size', 'used', 'avail', 'usedPercent', 'mounted'];
257
- const parser = (str) => {
258
- return str
259
- .split('\n')
260
- .filter((item) => item)
261
- .map((item) => item.split(' ').filter((s) => !!s))
262
- .map((item) => {
263
- const res = {};
264
- dic.forEach((key, i) => (res[key] = item[i]));
265
- return res;
266
- })
267
- .map((item) => ({
268
- ...item,
269
- total: parseFloat(item.size),
270
- percentage: parseFloat(item['use%']),
271
- }));
272
- };
273
107
  const getDiskUsage = async () => {
274
- return new Promise((resolve) => {
275
- (0, child_process_1.exec)('df -h | grep G', (err, stdout) => {
276
- if (err) {
277
- resolve([]);
278
- }
279
- else {
280
- resolve(parser(stdout.toString()));
281
- }
282
- });
283
- });
108
+ if (processManager.getDiskUsage) {
109
+ return processManager.getDiskUsage();
110
+ }
111
+ return Promise.resolve([]);
284
112
  };
285
113
  exports.getDiskUsage = getDiskUsage;
@@ -11,4 +11,9 @@ export declare class PProcessLinux implements PProcess {
11
11
  success: boolean;
12
12
  error: string;
13
13
  }>;
14
+ getDiskUsage(): Promise<any>;
15
+ getAudioCards(filter?: string): Promise<{
16
+ text: string;
17
+ index: string;
18
+ }[]>;
14
19
  }
@@ -113,5 +113,58 @@ class PProcessLinux {
113
113
  }
114
114
  return res;
115
115
  }
116
+ async getDiskUsage() {
117
+ return new Promise((resolve) => {
118
+ (0, child_process_1.exec)('df -h | grep G', (err, stdout) => {
119
+ if (err) {
120
+ resolve([]);
121
+ }
122
+ else {
123
+ resolve(parser(stdout.toString()));
124
+ }
125
+ });
126
+ });
127
+ }
128
+ getAudioCards(filter = '') {
129
+ return new Promise((resolve, reject) => {
130
+ (0, child_process_1.exec)(`arecord -l`, (err, stdout) => {
131
+ if (err) {
132
+ reject(err);
133
+ }
134
+ else {
135
+ const arr = stdout
136
+ .toString()
137
+ .split('\n')
138
+ .filter((item) => item.includes('card') && (filter ? item.includes(filter) : true))
139
+ .map((item) => parseAudioCard(item));
140
+ resolve(arr);
141
+ }
142
+ });
143
+ });
144
+ }
116
145
  }
117
146
  exports.PProcessLinux = PProcessLinux;
147
+ const parseAudioCard = (v) => {
148
+ let card = /card \d/.exec(v) ?? ['card 1'];
149
+ card = parseInt(card[0].replace('card ', ''), 10);
150
+ let device = /device \d/.exec(v) ?? ['device 0'];
151
+ device = parseInt(device[0].replace('device ', ''), 10);
152
+ return { text: v, index: `hw:${card},${device}` };
153
+ };
154
+ const dic = ['fileSystem', 'size', 'used', 'avail', 'usedPercent', 'mounted'];
155
+ const parser = (str) => {
156
+ return str
157
+ .split('\n')
158
+ .filter((item) => item)
159
+ .map((item) => item.split(' ').filter((s) => !!s))
160
+ .map((item) => {
161
+ const res = {};
162
+ dic.forEach((key, i) => (res[key] = item[i]));
163
+ return res;
164
+ })
165
+ .map((item) => ({
166
+ ...item,
167
+ total: parseFloat(item.size),
168
+ percentage: parseFloat(item['use%']),
169
+ }));
170
+ };
@@ -17,8 +17,13 @@ export interface PProcess {
17
17
  getProcessCommandByPid(pid: number): Promise<string>;
18
18
  isProcessDied(pid: number): Promise<boolean>;
19
19
  getProcessByPpid(ppid: number): Promise<number[]>;
20
- SIGKILL(pid: number): Promise<{
20
+ SIGKILL(pid: number, signal?: number, times?: number): Promise<{
21
21
  success: boolean;
22
22
  error: string;
23
23
  }>;
24
+ getDiskUsage?(): Promise<DiskInfo[]>;
25
+ getAudioCards?(filter?: string): Promise<{
26
+ text: string;
27
+ index: string;
28
+ }[]>;
24
29
  }
@@ -6,8 +6,10 @@ export declare class PProcessWin32 implements PProcess {
6
6
  getProcessCommandByPid(pid: number): Promise<string>;
7
7
  isProcessDied(pid: number): Promise<boolean>;
8
8
  getProcessByPpid(ppid: number): Promise<number[]>;
9
- SIGKILL(pid: number): Promise<{
9
+ SIGKILL(pid: number, signal?: number, times?: number): Promise<{
10
10
  success: boolean;
11
11
  error: string;
12
12
  }>;
13
+ getDiskUsage(): Promise<any>;
14
+ getAudioCards(): Promise<never[]>;
13
15
  }
@@ -103,12 +103,57 @@ class PProcessWin32 {
103
103
  });
104
104
  });
105
105
  }
106
- async SIGKILL(pid) {
106
+ async SIGKILL(pid, signal, times) {
107
107
  return new Promise((resolve) => {
108
108
  (0, child_process_1.exec)(`taskkill /pid ${pid} /T /F`, (err) => {
109
109
  resolve({ success: true, error: err.toString() });
110
110
  });
111
111
  });
112
112
  }
113
+ async getDiskUsage() {
114
+ return new Promise((resolve) => {
115
+ (0, child_process_1.exec)('wmic logicaldisk get Caption,FreeSpace,Size /format:csv', (err, stdout) => {
116
+ if (err) {
117
+ resolve([]);
118
+ return;
119
+ }
120
+ const lines = stdout.split('\r\n').filter((line) => line.trim() !== '');
121
+ // format:csv output has a header line "Node,Caption,FreeSpace,Size" usually.
122
+ // It might also have empty lines.
123
+ const disks = lines
124
+ .map((line) => {
125
+ // CSV parsing: simple split by comma
126
+ const parts = line.split(',').map((s) => s.trim());
127
+ if (parts.length < 4)
128
+ return null; // Node, Caption, FreeSpace, Size
129
+ // Header check
130
+ if (parts[1] === 'Caption')
131
+ return null;
132
+ const caption = parts[1];
133
+ const freeSpace = parseInt(parts[2]);
134
+ const size = parseInt(parts[3]);
135
+ if (isNaN(size) || isNaN(freeSpace))
136
+ return null;
137
+ const used = size - freeSpace;
138
+ const usedPercent = size > 0 ? (used / size) * 100 : 0;
139
+ return {
140
+ fileSystem: caption,
141
+ size: size, // bytes
142
+ used: used,
143
+ avail: freeSpace,
144
+ usedPercent: `${usedPercent.toFixed(0)}%`,
145
+ mounted: caption,
146
+ total: size,
147
+ percentage: parseFloat(usedPercent.toFixed(0)),
148
+ };
149
+ })
150
+ .filter((item) => item);
151
+ resolve(disks);
152
+ });
153
+ });
154
+ }
155
+ getAudioCards() {
156
+ return Promise.resolve([]);
157
+ }
113
158
  }
114
159
  exports.PProcessWin32 = PProcessWin32;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pubo-node",
3
- "version": "1.0.198",
3
+ "version": "1.0.202",
4
4
  "main": "./lib/index.js",
5
5
  "types": "./lib/index.d.ts",
6
6
  "sideEffects": false,
@@ -18,10 +18,10 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@types/node": "^17.0.25",
21
- "pubo-utils": "^1.0.198",
21
+ "pubo-utils": "^1.0.202",
22
22
  "yaml": "^2.5.1"
23
23
  },
24
- "gitHead": "da780d47ff24acca2543274d7d3e82af581e1485",
24
+ "gitHead": "6cab20969ce73935cf78b48ddecfab0adca48174",
25
25
  "devDependencies": {
26
26
  "del": "^5.1.0",
27
27
  "eslint": "^8.42.0",