zklib-ts 1.0.6 → 1.0.8
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/dist/helper/command.d.ts +11 -5
- package/dist/helper/terminal.d.ts +541 -0
- package/dist/helper/utils.d.ts +42 -5
- package/dist/index.cjs.js +1593 -873
- package/dist/index.d.ts +7 -6
- package/dist/index.es.js +1593 -873
- package/dist/models/Attendance.d.ts +3 -0
- package/dist/models/Finger.d.ts +2 -1
- package/dist/services/options.service.d.ts +49 -0
- package/dist/services/transaction.service.d.ts +1 -1
- package/dist/services/user.service.d.ts +4 -4
- package/dist/ztcp.cjs.js +802 -0
- package/dist/ztcp.d.ts +16 -37
- package/dist/ztcp.js +800 -0
- package/dist/zudp.cjs.js +531 -0
- package/dist/zudp.d.ts +2 -2
- package/dist/zudp.js +510 -0
- package/package.json +87 -69
package/dist/zudp.js
ADDED
|
@@ -0,0 +1,510 @@
|
|
|
1
|
+
import { authKey, createUDPHeader, decodeUDPHeader, exportErrorMessage, checkNotEventUDP, decodeUserData28, decodeRecordData16, decodeRecordRealTimeLog18 } from './helper/utils';
|
|
2
|
+
import { COMMANDS, Constants, REQUEST_DATA } from './helper/command';
|
|
3
|
+
import { appendFile } from 'fs';
|
|
4
|
+
import * as dgram from 'node:dgram';
|
|
5
|
+
|
|
6
|
+
const parseCurrentTime = () => {
|
|
7
|
+
const currentTime = new Date();
|
|
8
|
+
return {
|
|
9
|
+
year: currentTime.getFullYear(),
|
|
10
|
+
month: currentTime.getMonth() + 1,
|
|
11
|
+
day: currentTime.getDate(),
|
|
12
|
+
hour: currentTime.getHours(),
|
|
13
|
+
second: currentTime.getSeconds()
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
const log = (text) => {
|
|
17
|
+
const currentTime = parseCurrentTime();
|
|
18
|
+
const fileName = `${currentTime.day}`.padStart(2, '0') +
|
|
19
|
+
`${currentTime.month}`.padStart(2, '0') +
|
|
20
|
+
`${currentTime.year}.err.log`;
|
|
21
|
+
const logMessage = `\n [${currentTime.hour}:${currentTime.second}] ${text}`;
|
|
22
|
+
appendFile(fileName, logMessage, () => { });
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
*
|
|
27
|
+
* @param {number} time
|
|
28
|
+
*/
|
|
29
|
+
const decode = time => {
|
|
30
|
+
const second = time % 60;
|
|
31
|
+
time = (time - second) / 60;
|
|
32
|
+
const minute = time % 60;
|
|
33
|
+
time = (time - minute) / 60;
|
|
34
|
+
const hour = time % 24;
|
|
35
|
+
time = (time - hour) / 24;
|
|
36
|
+
const day = time % 31 + 1;
|
|
37
|
+
time = (time - (day - 1)) / 31;
|
|
38
|
+
const month = time % 12;
|
|
39
|
+
time = (time - month) / 12;
|
|
40
|
+
const year = time + 2000;
|
|
41
|
+
return new Date(year, month, day, hour, minute, second);
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
* @param {Date} date
|
|
46
|
+
*/
|
|
47
|
+
const encode = date => {
|
|
48
|
+
return (((date.getFullYear() % 100) * 12 * 31 + date.getMonth() * 31 + date.getDate() - 1) * (24 * 60 * 60) +
|
|
49
|
+
(date.getHours() * 60 + date.getMinutes()) * 60 +
|
|
50
|
+
date.getSeconds());
|
|
51
|
+
};
|
|
52
|
+
var timeParser = { encode, decode };
|
|
53
|
+
|
|
54
|
+
class ZUDP {
|
|
55
|
+
ip;
|
|
56
|
+
port;
|
|
57
|
+
timeout;
|
|
58
|
+
socket;
|
|
59
|
+
sessionId;
|
|
60
|
+
replyId;
|
|
61
|
+
inport;
|
|
62
|
+
comm_key;
|
|
63
|
+
constructor(ip, port, timeout, inport, comm_key = 0) {
|
|
64
|
+
this.ip = ip;
|
|
65
|
+
this.port = port;
|
|
66
|
+
this.timeout = timeout;
|
|
67
|
+
this.socket = null;
|
|
68
|
+
this.sessionId = null;
|
|
69
|
+
this.replyId = 0;
|
|
70
|
+
this.inport = inport;
|
|
71
|
+
this.comm_key = comm_key;
|
|
72
|
+
}
|
|
73
|
+
createSocket(cbError, cbClose) {
|
|
74
|
+
return new Promise((resolve, reject) => {
|
|
75
|
+
this.socket = dgram.createSocket('udp4');
|
|
76
|
+
this.socket.setMaxListeners(Infinity);
|
|
77
|
+
this.socket.once('error', (err) => {
|
|
78
|
+
this.socket = null;
|
|
79
|
+
reject(err);
|
|
80
|
+
if (cbError)
|
|
81
|
+
cbError(err);
|
|
82
|
+
});
|
|
83
|
+
this.socket.once('close', () => {
|
|
84
|
+
this.socket = null;
|
|
85
|
+
if (cbClose)
|
|
86
|
+
cbClose('udp');
|
|
87
|
+
});
|
|
88
|
+
this.socket.once('listening', () => {
|
|
89
|
+
resolve(this.socket);
|
|
90
|
+
});
|
|
91
|
+
try {
|
|
92
|
+
this.socket.bind(this.inport);
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
this.socket = null;
|
|
96
|
+
reject(err);
|
|
97
|
+
if (cbError)
|
|
98
|
+
cbError(err);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
async connect() {
|
|
103
|
+
try {
|
|
104
|
+
let reply = await this.executeCmd(COMMANDS.CMD_CONNECT, '');
|
|
105
|
+
if (reply.readUInt16LE(0) === COMMANDS.CMD_ACK_OK) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
if (reply.readUInt16LE(0) === COMMANDS.CMD_ACK_UNAUTH) {
|
|
109
|
+
const hashedCommkey = authKey(this.comm_key, this.sessionId);
|
|
110
|
+
reply = await this.executeCmd(COMMANDS.CMD_AUTH, hashedCommkey);
|
|
111
|
+
if (reply.readUInt16LE(0) === COMMANDS.CMD_ACK_OK) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
throw new Error('Authentication error');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
throw new Error('NO_REPLY_ON_CMD_CONNECT');
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
console.error('Error in connect method:', err);
|
|
124
|
+
throw err;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async closeSocket() {
|
|
128
|
+
return new Promise((resolve, reject) => {
|
|
129
|
+
if (!this.socket) {
|
|
130
|
+
resolve(true);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const timeout = 2000;
|
|
134
|
+
const timer = setTimeout(() => {
|
|
135
|
+
console.warn('Socket close timeout');
|
|
136
|
+
resolve(true);
|
|
137
|
+
}, timeout);
|
|
138
|
+
this.socket.removeAllListeners('message');
|
|
139
|
+
// @ts-ignore
|
|
140
|
+
this.socket.close((err) => {
|
|
141
|
+
clearTimeout(timer);
|
|
142
|
+
if (err) {
|
|
143
|
+
console.error('Error closing socket:', err);
|
|
144
|
+
reject(err);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
resolve(true);
|
|
148
|
+
}
|
|
149
|
+
this.socket = null;
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
writeMessage(msg, connect) {
|
|
154
|
+
return new Promise((resolve, reject) => {
|
|
155
|
+
if (!this.socket) {
|
|
156
|
+
reject(new Error('Socket not initialized'));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
let sendTimeoutId;
|
|
160
|
+
const onMessage = (data) => {
|
|
161
|
+
clearTimeout(sendTimeoutId);
|
|
162
|
+
this.socket.removeListener('message', onMessage);
|
|
163
|
+
resolve(data);
|
|
164
|
+
};
|
|
165
|
+
this.socket.once('message', onMessage);
|
|
166
|
+
this.socket.send(msg, 0, msg.length, this.port, this.ip, (err) => {
|
|
167
|
+
if (err) {
|
|
168
|
+
this.socket.removeListener('message', onMessage);
|
|
169
|
+
reject(err);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (this.timeout) {
|
|
173
|
+
sendTimeoutId = setTimeout(() => {
|
|
174
|
+
this.socket.removeListener('message', onMessage);
|
|
175
|
+
reject(new Error('TIMEOUT_ON_WRITING_MESSAGE'));
|
|
176
|
+
}, connect ? 2000 : this.timeout);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
requestData(msg) {
|
|
182
|
+
return new Promise((resolve, reject) => {
|
|
183
|
+
if (!this.socket) {
|
|
184
|
+
reject(new Error('Socket not initialized'));
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
let sendTimeoutId;
|
|
188
|
+
let responseTimeoutId;
|
|
189
|
+
const handleOnData = (data) => {
|
|
190
|
+
if (checkNotEventUDP(data))
|
|
191
|
+
return;
|
|
192
|
+
clearTimeout(sendTimeoutId);
|
|
193
|
+
clearTimeout(responseTimeoutId);
|
|
194
|
+
this.socket.removeListener('message', handleOnData);
|
|
195
|
+
resolve(data);
|
|
196
|
+
};
|
|
197
|
+
const onReceiveTimeout = () => {
|
|
198
|
+
this.socket.removeListener('message', handleOnData);
|
|
199
|
+
reject(new Error('TIMEOUT_ON_RECEIVING_REQUEST_DATA'));
|
|
200
|
+
};
|
|
201
|
+
this.socket.on('message', handleOnData);
|
|
202
|
+
this.socket.send(msg, 0, msg.length, this.port, this.ip, (err) => {
|
|
203
|
+
if (err) {
|
|
204
|
+
this.socket.removeListener('message', handleOnData);
|
|
205
|
+
reject(err);
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
responseTimeoutId = setTimeout(onReceiveTimeout, this.timeout);
|
|
209
|
+
});
|
|
210
|
+
sendTimeoutId = setTimeout(() => {
|
|
211
|
+
this.socket.removeListener('message', handleOnData);
|
|
212
|
+
reject(new Error('TIMEOUT_IN_RECEIVING_RESPONSE_AFTER_REQUESTING_DATA'));
|
|
213
|
+
}, this.timeout);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
async executeCmd(command, data) {
|
|
217
|
+
try {
|
|
218
|
+
if (command === COMMANDS.CMD_CONNECT) {
|
|
219
|
+
this.sessionId = 0;
|
|
220
|
+
this.replyId = 0;
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
this.replyId++;
|
|
224
|
+
}
|
|
225
|
+
const buf = createUDPHeader(command, this.sessionId, this.replyId, data);
|
|
226
|
+
const reply = await this.writeMessage(buf, command === COMMANDS.CMD_CONNECT || command === COMMANDS.CMD_EXIT);
|
|
227
|
+
if (reply && reply.length > 0) {
|
|
228
|
+
if (command === COMMANDS.CMD_CONNECT) {
|
|
229
|
+
this.sessionId = reply.readUInt16LE(4);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return reply;
|
|
233
|
+
}
|
|
234
|
+
catch (err) {
|
|
235
|
+
console.error(`Error executing command ${command}:`, err);
|
|
236
|
+
throw err;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
async sendChunkRequest(start, size) {
|
|
240
|
+
this.replyId++;
|
|
241
|
+
const reqData = Buffer.alloc(8);
|
|
242
|
+
reqData.writeUInt32LE(start, 0);
|
|
243
|
+
reqData.writeUInt32LE(size, 4);
|
|
244
|
+
const buf = createUDPHeader(COMMANDS.CMD_DATA_RDY, this.sessionId, this.replyId, reqData);
|
|
245
|
+
try {
|
|
246
|
+
await new Promise((resolve, reject) => {
|
|
247
|
+
this.socket.send(buf, 0, buf.length, this.port, this.ip, (err) => {
|
|
248
|
+
if (err) {
|
|
249
|
+
log(`[UDP][SEND_CHUNK_REQUEST] Error sending chunk request: ${err.message}`);
|
|
250
|
+
reject(err);
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
resolve();
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
catch (error) {
|
|
259
|
+
log(`[UDP][SEND_CHUNK_REQUEST] Exception: ${error.message}`);
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
async readWithBuffer(reqData, cb = null) {
|
|
264
|
+
this.replyId++;
|
|
265
|
+
const buf = createUDPHeader(COMMANDS.CMD_DATA_WRRQ, this.sessionId, this.replyId, reqData);
|
|
266
|
+
try {
|
|
267
|
+
const reply = await this.requestData(buf);
|
|
268
|
+
const header = decodeUDPHeader(reply.subarray(0, 8));
|
|
269
|
+
switch (header.commandId) {
|
|
270
|
+
case COMMANDS.CMD_DATA:
|
|
271
|
+
return { data: reply.subarray(8), err: null };
|
|
272
|
+
case COMMANDS.CMD_ACK_OK:
|
|
273
|
+
case COMMANDS.CMD_PREPARE_DATA:
|
|
274
|
+
return await this.handleChunkedData(reply, header.commandId, cb);
|
|
275
|
+
default:
|
|
276
|
+
throw new Error('ERROR_IN_UNHANDLE_CMD ' + exportErrorMessage(header.commandId));
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
catch (err) {
|
|
280
|
+
return { data: null, err: err };
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
async handleChunkedData(reply, commandId, cb) {
|
|
284
|
+
return new Promise((resolve) => {
|
|
285
|
+
const recvData = reply.subarray(8);
|
|
286
|
+
const size = recvData.readUIntLE(1, 4);
|
|
287
|
+
let totalBuffer = Buffer.from([]);
|
|
288
|
+
const timeout = 3000;
|
|
289
|
+
let timer = setTimeout(() => {
|
|
290
|
+
this.socket.removeListener('message', handleOnData);
|
|
291
|
+
resolve({ data: null, err: new Error('TIMEOUT WHEN RECEIVING PACKET') });
|
|
292
|
+
}, timeout);
|
|
293
|
+
const internalCallback = (replyData, err = null) => {
|
|
294
|
+
this.socket.removeListener('message', handleOnData);
|
|
295
|
+
clearTimeout(timer);
|
|
296
|
+
resolve({ data: err ? null : replyData, err });
|
|
297
|
+
};
|
|
298
|
+
const handleOnData = (reply) => {
|
|
299
|
+
if (checkNotEventUDP(reply))
|
|
300
|
+
return;
|
|
301
|
+
clearTimeout(timer);
|
|
302
|
+
timer = setTimeout(() => {
|
|
303
|
+
internalCallback(totalBuffer, new Error(`TIMEOUT !! ${(size - totalBuffer.length) / size} % REMAIN !`));
|
|
304
|
+
}, timeout);
|
|
305
|
+
const header = decodeUDPHeader(reply);
|
|
306
|
+
switch (header.commandId) {
|
|
307
|
+
case COMMANDS.CMD_PREPARE_DATA:
|
|
308
|
+
break;
|
|
309
|
+
case COMMANDS.CMD_DATA:
|
|
310
|
+
totalBuffer = Buffer.concat([totalBuffer, reply.subarray(8)]);
|
|
311
|
+
cb && cb(totalBuffer.length, size);
|
|
312
|
+
break;
|
|
313
|
+
case COMMANDS.CMD_ACK_OK:
|
|
314
|
+
if (totalBuffer.length === size) {
|
|
315
|
+
internalCallback(totalBuffer);
|
|
316
|
+
}
|
|
317
|
+
break;
|
|
318
|
+
default:
|
|
319
|
+
internalCallback(Buffer.from([]), new Error('ERROR_IN_UNHANDLE_CMD ' + exportErrorMessage(header.commandId)));
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
this.socket.on('message', handleOnData);
|
|
323
|
+
const chunkCount = Math.ceil(size / Constants.MAX_CHUNK);
|
|
324
|
+
for (let i = 0; i < chunkCount; i++) {
|
|
325
|
+
const start = i * Constants.MAX_CHUNK;
|
|
326
|
+
const chunkSize = (i === chunkCount - 1) ? size % Constants.MAX_CHUNK : Constants.MAX_CHUNK;
|
|
327
|
+
this.sendChunkRequest(start, chunkSize).catch(err => {
|
|
328
|
+
internalCallback(Buffer.from([]), err);
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
async getUsers() {
|
|
334
|
+
try {
|
|
335
|
+
if (this.socket) {
|
|
336
|
+
await this.freeData();
|
|
337
|
+
}
|
|
338
|
+
const data = await this.readWithBuffer(REQUEST_DATA.GET_USERS);
|
|
339
|
+
if (this.socket) {
|
|
340
|
+
await this.freeData();
|
|
341
|
+
}
|
|
342
|
+
const USER_PACKET_SIZE = 28;
|
|
343
|
+
let userData = data.data?.subarray(4) || Buffer.from([]);
|
|
344
|
+
const users = [];
|
|
345
|
+
while (userData.length >= USER_PACKET_SIZE) {
|
|
346
|
+
const user = decodeUserData28(userData.subarray(0, USER_PACKET_SIZE));
|
|
347
|
+
users.push(user);
|
|
348
|
+
userData = userData.subarray(USER_PACKET_SIZE);
|
|
349
|
+
}
|
|
350
|
+
return { data: users };
|
|
351
|
+
}
|
|
352
|
+
catch (err) {
|
|
353
|
+
throw new Error(err.message);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
async getAttendances(callbackInProcess) {
|
|
357
|
+
try {
|
|
358
|
+
if (this.socket) {
|
|
359
|
+
await this.freeData();
|
|
360
|
+
}
|
|
361
|
+
const data = await this.readWithBuffer(REQUEST_DATA.GET_ATTENDANCE_LOGS);
|
|
362
|
+
if (this.socket) {
|
|
363
|
+
await this.freeData();
|
|
364
|
+
}
|
|
365
|
+
const RECORD_PACKET_SIZE = 16;
|
|
366
|
+
let recordData = data.data?.subarray(4) || Buffer.from([]);
|
|
367
|
+
const records = [];
|
|
368
|
+
while (recordData.length >= RECORD_PACKET_SIZE) {
|
|
369
|
+
const record = decodeRecordData16(recordData.subarray(0, RECORD_PACKET_SIZE));
|
|
370
|
+
records.push({ ...record, ip: this.ip });
|
|
371
|
+
recordData = recordData.subarray(RECORD_PACKET_SIZE);
|
|
372
|
+
}
|
|
373
|
+
return { data: records, err: data.err };
|
|
374
|
+
}
|
|
375
|
+
catch (err) {
|
|
376
|
+
return { data: [], err: err };
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
async freeData() {
|
|
380
|
+
try {
|
|
381
|
+
const resp = await this.executeCmd(COMMANDS.CMD_FREE_DATA, Buffer.alloc(0));
|
|
382
|
+
return !!resp;
|
|
383
|
+
}
|
|
384
|
+
catch (err) {
|
|
385
|
+
console.error('Error freeing data:', err);
|
|
386
|
+
throw err;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
async getInfo() {
|
|
390
|
+
try {
|
|
391
|
+
const data = await this.executeCmd(COMMANDS.CMD_GET_FREE_SIZES, Buffer.alloc(0));
|
|
392
|
+
return {
|
|
393
|
+
userCounts: data.readUIntLE(24, 4),
|
|
394
|
+
logCounts: data.readUIntLE(40, 4),
|
|
395
|
+
logCapacity: data.readUIntLE(72, 4)
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
catch (err) {
|
|
399
|
+
console.error('Error retrieving info:', err);
|
|
400
|
+
throw err;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
async getTime() {
|
|
404
|
+
try {
|
|
405
|
+
const response = await this.executeCmd(COMMANDS.CMD_GET_TIME, Buffer.alloc(0));
|
|
406
|
+
const timeValue = response.readUInt32LE(8);
|
|
407
|
+
return timeParser.decode(timeValue);
|
|
408
|
+
}
|
|
409
|
+
catch (err) {
|
|
410
|
+
console.error('Error retrieving time:', err);
|
|
411
|
+
throw err;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
async setTime(tm) {
|
|
415
|
+
try {
|
|
416
|
+
const commandBuffer = Buffer.alloc(32);
|
|
417
|
+
commandBuffer.writeUInt32LE(timeParser.encode(new Date(tm)), 0);
|
|
418
|
+
await this.executeCmd(COMMANDS.CMD_SET_TIME, commandBuffer);
|
|
419
|
+
return true;
|
|
420
|
+
}
|
|
421
|
+
catch (err) {
|
|
422
|
+
console.error('Error setting time:', err);
|
|
423
|
+
throw err;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
async clearAttendanceLog() {
|
|
427
|
+
try {
|
|
428
|
+
return !!await this.executeCmd(COMMANDS.CMD_CLEAR_ATTLOG, Buffer.alloc(0));
|
|
429
|
+
}
|
|
430
|
+
catch (err) {
|
|
431
|
+
console.error('Error clearing attendance log:', err);
|
|
432
|
+
throw err;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
async clearData() {
|
|
436
|
+
try {
|
|
437
|
+
return !!await this.executeCmd(COMMANDS.CMD_CLEAR_DATA, Buffer.alloc(0));
|
|
438
|
+
}
|
|
439
|
+
catch (err) {
|
|
440
|
+
console.error('Error clearing data:', err);
|
|
441
|
+
throw err;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
async disableDevice() {
|
|
445
|
+
try {
|
|
446
|
+
const resp = await this.executeCmd(COMMANDS.CMD_DISABLEDEVICE, REQUEST_DATA.DISABLE_DEVICE);
|
|
447
|
+
return !!resp;
|
|
448
|
+
}
|
|
449
|
+
catch (err) {
|
|
450
|
+
console.error('Error disabling device:', err);
|
|
451
|
+
throw err;
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
async enableDevice() {
|
|
455
|
+
try {
|
|
456
|
+
const resp = await this.executeCmd(COMMANDS.CMD_ENABLEDEVICE, Buffer.alloc(0));
|
|
457
|
+
return !!resp;
|
|
458
|
+
}
|
|
459
|
+
catch (err) {
|
|
460
|
+
console.error('Error enabling device:', err);
|
|
461
|
+
throw err;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
async disconnect() {
|
|
465
|
+
try {
|
|
466
|
+
await this.executeCmd(COMMANDS.CMD_EXIT, Buffer.alloc(0));
|
|
467
|
+
}
|
|
468
|
+
catch (err) {
|
|
469
|
+
console.error('Error executing disconnect command:', err);
|
|
470
|
+
}
|
|
471
|
+
try {
|
|
472
|
+
await this.closeSocket();
|
|
473
|
+
}
|
|
474
|
+
catch (err) {
|
|
475
|
+
console.error('Error closing the socket:', err);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
async getRealTimeLogs(cb = () => { }) {
|
|
479
|
+
this.replyId++;
|
|
480
|
+
const buf = createUDPHeader(COMMANDS.CMD_REG_EVENT, this.sessionId, this.replyId, REQUEST_DATA.GET_REAL_TIME_EVENT);
|
|
481
|
+
try {
|
|
482
|
+
this.socket.send(buf, 0, buf.length, this.port, this.ip, (err) => {
|
|
483
|
+
if (err) {
|
|
484
|
+
console.error('Error sending UDP message:', err);
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
console.log('UDP message sent successfully');
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
catch (err) {
|
|
491
|
+
console.error('Error during send operation:', err);
|
|
492
|
+
return;
|
|
493
|
+
}
|
|
494
|
+
const handleMessage = (data) => {
|
|
495
|
+
if (!checkNotEventUDP(data))
|
|
496
|
+
return;
|
|
497
|
+
if (data.length === 18) {
|
|
498
|
+
cb(decodeRecordRealTimeLog18(data));
|
|
499
|
+
}
|
|
500
|
+
};
|
|
501
|
+
if (this.socket.listenerCount('message') === 0) {
|
|
502
|
+
this.socket.on('message', handleMessage);
|
|
503
|
+
}
|
|
504
|
+
else {
|
|
505
|
+
console.warn('Multiple message listeners detected. Ensure only one listener is attached.');
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
export { ZUDP };
|
package/package.json
CHANGED
|
@@ -1,69 +1,87 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "zklib-ts",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Unofficial zkteco library allows Node.js developers to easily interface with ZK BioMetric Fingerprint Attendance Devices",
|
|
5
|
-
"main": "dist/index.cjs.js",
|
|
6
|
-
"module": "dist/index.es.js",
|
|
7
|
-
"typings": "dist/index",
|
|
8
|
-
"types": "dist/index.d.ts",
|
|
9
|
-
"type": "commonjs",
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"
|
|
68
|
-
|
|
69
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "zklib-ts",
|
|
3
|
+
"version": "1.0.8",
|
|
4
|
+
"description": "Unofficial zkteco library allows Node.js developers to easily interface with ZK BioMetric Fingerprint Attendance Devices",
|
|
5
|
+
"main": "dist/index.cjs.js",
|
|
6
|
+
"module": "dist/index.es.js",
|
|
7
|
+
"typings": "dist/index",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"type": "commonjs",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/index.es.js",
|
|
13
|
+
"require": "./dist/index.cjs.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
},
|
|
16
|
+
"./ztcp": {
|
|
17
|
+
"import": "./dist/ztcp.js",
|
|
18
|
+
"require": "./dist/ztcp.cjs.js",
|
|
19
|
+
"types": "./dist/ztcp.d.ts"
|
|
20
|
+
},
|
|
21
|
+
"./zudp": {
|
|
22
|
+
"import": "./dist/zudp.js",
|
|
23
|
+
"require": "./dist/zudp.cjs.js",
|
|
24
|
+
"types": "./dist/zudp.d.ts"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist/",
|
|
29
|
+
"README.md"
|
|
30
|
+
],
|
|
31
|
+
"repositoryUrl": "https://github.com/guspaz0/zklib-ts.git",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/guspaz0/zklib-ts.git"
|
|
35
|
+
},
|
|
36
|
+
"keywords": [
|
|
37
|
+
"typescript",
|
|
38
|
+
"javascript",
|
|
39
|
+
"jest",
|
|
40
|
+
"ip",
|
|
41
|
+
"libs",
|
|
42
|
+
"device",
|
|
43
|
+
"zkteco",
|
|
44
|
+
"address",
|
|
45
|
+
"realtime",
|
|
46
|
+
"real-time",
|
|
47
|
+
"biometric",
|
|
48
|
+
"attendance",
|
|
49
|
+
"biometric attendance",
|
|
50
|
+
"biometric attendance device"
|
|
51
|
+
],
|
|
52
|
+
"author": "Gustavo Paz",
|
|
53
|
+
"license": "MIT",
|
|
54
|
+
"directories": {
|
|
55
|
+
"test": "tests"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@rollup/plugin-commonjs": "^28.0.3",
|
|
59
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
60
|
+
"@rollup/plugin-typescript": "^12.1.2",
|
|
61
|
+
"@types/jest": "^29.5.14",
|
|
62
|
+
"@types/mocha": "^10.0.10",
|
|
63
|
+
"@types/node": "^22.19.17",
|
|
64
|
+
"dotenv": "^16.4.7",
|
|
65
|
+
"jest": "30.2.0",
|
|
66
|
+
"rollup": "^4.37.0",
|
|
67
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
68
|
+
"ts-jest": "29.4.6",
|
|
69
|
+
"ts-node": "^10.9.2",
|
|
70
|
+
"tslib": "^2.8.1",
|
|
71
|
+
"typescript": "^5.8.2"
|
|
72
|
+
},
|
|
73
|
+
"config": {
|
|
74
|
+
"commitizen": {
|
|
75
|
+
"path": "./node_modules/cz-conventional-changelog"
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"precommit": [
|
|
79
|
+
"build"
|
|
80
|
+
],
|
|
81
|
+
"scripts": {
|
|
82
|
+
"test": "jest",
|
|
83
|
+
"build": "rollup -c",
|
|
84
|
+
"watch": "rollup -c --watch",
|
|
85
|
+
"lint": "eslint ."
|
|
86
|
+
}
|
|
87
|
+
}
|