recker 1.0.5 → 1.0.6

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 (106) hide show
  1. package/README.md +1 -1
  2. package/dist/ai/adaptive-timeout.d.ts +51 -0
  3. package/dist/ai/adaptive-timeout.d.ts.map +1 -0
  4. package/dist/ai/adaptive-timeout.js +208 -0
  5. package/dist/ai/client.d.ts +24 -0
  6. package/dist/ai/client.d.ts.map +1 -0
  7. package/dist/ai/client.js +289 -0
  8. package/dist/ai/index.d.ts +10 -0
  9. package/dist/ai/index.d.ts.map +1 -0
  10. package/dist/ai/index.js +6 -0
  11. package/dist/ai/providers/anthropic.d.ts +64 -0
  12. package/dist/ai/providers/anthropic.d.ts.map +1 -0
  13. package/dist/ai/providers/anthropic.js +367 -0
  14. package/dist/ai/providers/base.d.ts +49 -0
  15. package/dist/ai/providers/base.d.ts.map +1 -0
  16. package/dist/ai/providers/base.js +145 -0
  17. package/dist/ai/providers/index.d.ts +7 -0
  18. package/dist/ai/providers/index.d.ts.map +1 -0
  19. package/dist/ai/providers/index.js +3 -0
  20. package/dist/ai/providers/openai.d.ts +65 -0
  21. package/dist/ai/providers/openai.d.ts.map +1 -0
  22. package/dist/ai/providers/openai.js +298 -0
  23. package/dist/ai/rate-limiter.d.ts +44 -0
  24. package/dist/ai/rate-limiter.d.ts.map +1 -0
  25. package/dist/ai/rate-limiter.js +212 -0
  26. package/dist/bench/generator.d.ts +19 -0
  27. package/dist/bench/generator.d.ts.map +1 -0
  28. package/dist/bench/generator.js +86 -0
  29. package/dist/bench/stats.d.ts +35 -0
  30. package/dist/bench/stats.d.ts.map +1 -0
  31. package/dist/bench/stats.js +60 -0
  32. package/dist/cli/handler.d.ts +11 -0
  33. package/dist/cli/handler.d.ts.map +1 -0
  34. package/dist/cli/handler.js +92 -0
  35. package/dist/cli/index.d.ts +3 -0
  36. package/dist/cli/index.d.ts.map +1 -0
  37. package/dist/cli/index.js +255 -0
  38. package/dist/cli/presets.d.ts +2 -0
  39. package/dist/cli/presets.d.ts.map +1 -0
  40. package/dist/cli/presets.js +67 -0
  41. package/dist/cli/tui/ai-chat.d.ts +3 -0
  42. package/dist/cli/tui/ai-chat.d.ts.map +1 -0
  43. package/dist/cli/tui/ai-chat.js +100 -0
  44. package/dist/cli/tui/load-dashboard.d.ts +3 -0
  45. package/dist/cli/tui/load-dashboard.d.ts.map +1 -0
  46. package/dist/cli/tui/load-dashboard.js +117 -0
  47. package/dist/cli/tui/shell.d.ts +27 -0
  48. package/dist/cli/tui/shell.d.ts.map +1 -0
  49. package/dist/cli/tui/shell.js +386 -0
  50. package/dist/cli/tui/websocket.d.ts +2 -0
  51. package/dist/cli/tui/websocket.d.ts.map +1 -0
  52. package/dist/cli/tui/websocket.js +87 -0
  53. package/dist/contract/index.d.ts +2 -2
  54. package/dist/contract/index.d.ts.map +1 -1
  55. package/dist/core/client.d.ts +1 -0
  56. package/dist/core/client.d.ts.map +1 -1
  57. package/dist/core/client.js +4 -2
  58. package/dist/core/request-promise.d.ts +1 -1
  59. package/dist/core/request-promise.d.ts.map +1 -1
  60. package/dist/mcp/contract.d.ts +1 -1
  61. package/dist/mcp/contract.d.ts.map +1 -1
  62. package/dist/protocols/ftp.d.ts +28 -5
  63. package/dist/protocols/ftp.d.ts.map +1 -1
  64. package/dist/protocols/ftp.js +549 -136
  65. package/dist/protocols/sftp.d.ts +4 -2
  66. package/dist/protocols/sftp.d.ts.map +1 -1
  67. package/dist/protocols/sftp.js +16 -2
  68. package/dist/protocols/telnet.d.ts +37 -5
  69. package/dist/protocols/telnet.d.ts.map +1 -1
  70. package/dist/protocols/telnet.js +434 -58
  71. package/dist/scrape/document.d.ts.map +1 -1
  72. package/dist/scrape/document.js +7 -12
  73. package/dist/testing/index.d.ts +2 -0
  74. package/dist/testing/index.d.ts.map +1 -1
  75. package/dist/testing/index.js +1 -0
  76. package/dist/testing/mock-udp-server.d.ts +44 -0
  77. package/dist/testing/mock-udp-server.d.ts.map +1 -0
  78. package/dist/testing/mock-udp-server.js +188 -0
  79. package/dist/transport/base-udp.d.ts +36 -0
  80. package/dist/transport/base-udp.d.ts.map +1 -0
  81. package/dist/transport/base-udp.js +188 -0
  82. package/dist/transport/udp-response.d.ts +65 -0
  83. package/dist/transport/udp-response.d.ts.map +1 -0
  84. package/dist/transport/udp-response.js +269 -0
  85. package/dist/transport/udp.d.ts +22 -0
  86. package/dist/transport/udp.d.ts.map +1 -0
  87. package/dist/transport/udp.js +260 -0
  88. package/dist/types/ai.d.ts +268 -0
  89. package/dist/types/ai.d.ts.map +1 -0
  90. package/dist/types/ai.js +1 -0
  91. package/dist/types/udp.d.ts +138 -0
  92. package/dist/types/udp.d.ts.map +1 -0
  93. package/dist/types/udp.js +1 -0
  94. package/dist/udp/index.d.ts +6 -0
  95. package/dist/udp/index.d.ts.map +1 -0
  96. package/dist/udp/index.js +3 -0
  97. package/dist/utils/chart.d.ts +15 -0
  98. package/dist/utils/chart.d.ts.map +1 -0
  99. package/dist/utils/chart.js +94 -0
  100. package/dist/utils/colors.d.ts +27 -0
  101. package/dist/utils/colors.d.ts.map +1 -0
  102. package/dist/utils/colors.js +50 -0
  103. package/dist/utils/optional-require.d.ts +20 -0
  104. package/dist/utils/optional-require.d.ts.map +1 -0
  105. package/dist/utils/optional-require.js +105 -0
  106. package/package.json +53 -12
@@ -1,65 +1,161 @@
1
- import { Telnet as TelnetClient } from 'telnet-client';
2
- export class Telnet {
3
- client;
1
+ import { Socket } from 'node:net';
2
+ import { EventEmitter } from 'node:events';
3
+ const IAC = 255;
4
+ const CMD = {
5
+ SE: 240,
6
+ NOP: 241,
7
+ DM: 242,
8
+ BRK: 243,
9
+ IP: 244,
10
+ AO: 245,
11
+ AYT: 246,
12
+ EC: 247,
13
+ EL: 248,
14
+ GA: 249,
15
+ SB: 250,
16
+ WILL: 251,
17
+ WONT: 252,
18
+ DO: 253,
19
+ DONT: 254,
20
+ IAC: 255,
21
+ };
22
+ const OPT = {
23
+ BINARY: 0,
24
+ ECHO: 1,
25
+ RCP: 2,
26
+ SGA: 3,
27
+ NAMS: 4,
28
+ STATUS: 5,
29
+ TM: 6,
30
+ RCTE: 7,
31
+ NAOL: 8,
32
+ NAOP: 9,
33
+ NAOCRD: 10,
34
+ NAOHTS: 11,
35
+ NAOHTD: 12,
36
+ NAOFFD: 13,
37
+ NAOVTS: 14,
38
+ NAOVTD: 15,
39
+ NAOLFD: 16,
40
+ XASCII: 17,
41
+ LOGOUT: 18,
42
+ BM: 19,
43
+ DET: 20,
44
+ SUPDUP: 21,
45
+ SUPDUPOUTPUT: 22,
46
+ SNDLOC: 23,
47
+ TTYPE: 24,
48
+ EOR: 25,
49
+ TUID: 26,
50
+ OUTMRK: 27,
51
+ TTYLOC: 28,
52
+ OPT3270REGIME: 29,
53
+ X3PAD: 30,
54
+ NAWS: 31,
55
+ TSPEED: 32,
56
+ LFLOW: 33,
57
+ LINEMODE: 34,
58
+ XDISPLOC: 35,
59
+ OLD_ENVIRON: 36,
60
+ AUTHENTICATION: 37,
61
+ ENCRYPT: 38,
62
+ NEW_ENVIRON: 39,
63
+ EXOPL: 255,
64
+ };
65
+ export class Telnet extends EventEmitter {
66
+ socket = null;
4
67
  config;
5
68
  connected = false;
69
+ buffer = Buffer.alloc(0);
70
+ dataBuffer = '';
71
+ loginState = 'pending';
72
+ localOptions = new Set();
73
+ remoteOptions = new Set();
6
74
  constructor(config) {
7
- this.config = config;
8
- this.client = new TelnetClient();
75
+ super();
76
+ this.config = {
77
+ host: config.host,
78
+ port: config.port ?? 23,
79
+ timeout: config.timeout ?? 10000,
80
+ shellPrompt: config.shellPrompt ?? /[$#>]\s*$/,
81
+ loginPrompt: config.loginPrompt ?? /login[: ]*$/i,
82
+ passwordPrompt: config.passwordPrompt ?? /password[: ]*$/i,
83
+ username: config.username ?? '',
84
+ password: config.password ?? '',
85
+ initialLFCR: config.initialLFCR ?? true,
86
+ pageSeparator: config.pageSeparator ?? '',
87
+ execTimeout: config.execTimeout ?? 5000,
88
+ sendTimeout: config.sendTimeout ?? 2000,
89
+ maxBufferLength: config.maxBufferLength ?? 1024 * 1024,
90
+ debug: config.debug ?? false,
91
+ terminalType: config.terminalType ?? 'xterm-256color',
92
+ windowSize: config.windowSize ?? [80, 24],
93
+ };
9
94
  }
10
95
  async connect() {
11
- try {
12
- const params = {
13
- host: this.config.host,
14
- port: this.config.port ?? 23,
15
- timeout: this.config.timeout ?? 10000,
16
- shellPrompt: this.config.shellPrompt ?? /[$#>]\s*$/,
17
- loginPrompt: this.config.loginPrompt ?? /login[: ]*$/i,
18
- passwordPrompt: this.config.passwordPrompt ?? /password[: ]*$/i,
19
- username: this.config.username,
20
- password: this.config.password,
21
- initialLFCR: this.config.initialLFCR ?? true,
22
- pageSeparator: this.config.pageSeparator,
23
- negotiationMandatory: this.config.negotiationMandatory ?? false,
24
- execTimeout: this.config.execTimeout ?? 5000,
25
- sendTimeout: this.config.sendTimeout ?? 2000,
26
- maxBufferLength: this.config.maxBufferLength ?? 1024 * 1024,
27
- debug: this.config.debug ?? false,
28
- };
29
- await this.client.connect(params);
30
- this.connected = true;
31
- return {
32
- success: true,
33
- message: 'Connected successfully'
34
- };
35
- }
36
- catch (error) {
37
- return {
38
- success: false,
39
- message: error instanceof Error ? error.message : 'Connection failed'
40
- };
41
- }
96
+ return new Promise((resolve) => {
97
+ this.socket = new Socket();
98
+ this.socket.setTimeout(this.config.timeout);
99
+ this.socket.on('connect', () => {
100
+ this.debug('Connected to %s:%d', this.config.host, this.config.port);
101
+ this.connected = true;
102
+ if (this.config.initialLFCR) {
103
+ this.socket?.write(Buffer.from([13, 10]));
104
+ }
105
+ });
106
+ this.socket.on('data', (data) => this.handleData(data));
107
+ this.socket.on('close', () => {
108
+ this.debug('Connection closed');
109
+ this.connected = false;
110
+ this.emit('close');
111
+ });
112
+ this.socket.on('error', (err) => {
113
+ this.debug('Socket error: %s', err.message);
114
+ this.emit('error', err);
115
+ resolve({
116
+ success: false,
117
+ message: err.message
118
+ });
119
+ });
120
+ this.socket.on('timeout', () => {
121
+ this.debug('Connection timeout');
122
+ this.socket?.destroy();
123
+ resolve({
124
+ success: false,
125
+ message: 'Connection timeout'
126
+ });
127
+ });
128
+ this.socket.connect(this.config.port, this.config.host);
129
+ this.waitForPromptOrAuth()
130
+ .then(() => {
131
+ resolve({
132
+ success: true,
133
+ message: 'Connected successfully'
134
+ });
135
+ })
136
+ .catch((err) => {
137
+ resolve({
138
+ success: false,
139
+ message: err.message
140
+ });
141
+ });
142
+ });
42
143
  }
43
144
  isConnected() {
44
- return this.connected;
145
+ return this.connected && this.socket !== null && !this.socket.destroyed;
45
146
  }
46
147
  async exec(command, options) {
47
148
  this.ensureConnected();
149
+ const prompt = options?.shellPrompt ?? this.config.shellPrompt;
150
+ const timeout = options?.timeout ?? this.config.execTimeout;
48
151
  try {
49
- const execOptions = {};
50
- if (options?.shellPrompt) {
51
- execOptions.shellPrompt = options.shellPrompt;
52
- }
53
- if (options?.timeout) {
54
- execOptions.timeout = options.timeout;
55
- }
56
- if (options?.sendTimeout) {
57
- execOptions.sendTimeout = options.sendTimeout;
58
- }
59
- const result = await this.client.exec(command, execOptions);
152
+ this.dataBuffer = '';
153
+ this.write(command + '\r\n');
154
+ const output = await this.waitForPattern(prompt, timeout);
155
+ const cleaned = this.cleanOutput(output, command, prompt);
60
156
  return {
61
157
  success: true,
62
- data: result
158
+ data: cleaned
63
159
  };
64
160
  }
65
161
  catch (error) {
@@ -72,10 +168,17 @@ export class Telnet {
72
168
  async send(data, options) {
73
169
  this.ensureConnected();
74
170
  try {
75
- const result = await this.client.send(data, options);
171
+ this.write(data);
172
+ if (options?.waitFor) {
173
+ const output = await this.waitForPattern(options.waitFor, options.timeout ?? this.config.sendTimeout);
174
+ return {
175
+ success: true,
176
+ data: output
177
+ };
178
+ }
76
179
  return {
77
180
  success: true,
78
- data: result
181
+ data: ''
79
182
  };
80
183
  }
81
184
  catch (error) {
@@ -91,10 +194,10 @@ export class Telnet {
91
194
  async waitFor(pattern, timeout) {
92
195
  this.ensureConnected();
93
196
  try {
94
- const result = await this.client.send('', { waitFor: pattern, timeout });
197
+ const output = await this.waitForPattern(pattern, timeout ?? this.config.execTimeout);
95
198
  return {
96
199
  success: true,
97
- data: result
200
+ data: output
98
201
  };
99
202
  }
100
203
  catch (error) {
@@ -104,22 +207,295 @@ export class Telnet {
104
207
  };
105
208
  }
106
209
  }
107
- getClient() {
108
- return this.client;
210
+ getSocket() {
211
+ if (!this.socket) {
212
+ throw new Error('Not connected. Call connect() first.');
213
+ }
214
+ return this.socket;
109
215
  }
110
216
  async close() {
111
217
  this.connected = false;
112
- await this.client.end();
218
+ if (this.socket) {
219
+ this.socket.end();
220
+ this.socket = null;
221
+ }
113
222
  }
114
223
  destroy() {
115
224
  this.connected = false;
116
- this.client.destroy();
225
+ if (this.socket) {
226
+ this.socket.destroy();
227
+ this.socket = null;
228
+ }
229
+ }
230
+ handleData(data) {
231
+ this.debug('Received %d bytes', data.length);
232
+ this.buffer = Buffer.concat([this.buffer, data]);
233
+ if (this.buffer.length > this.config.maxBufferLength) {
234
+ this.buffer = this.buffer.slice(-this.config.maxBufferLength);
235
+ }
236
+ const text = this.processBuffer();
237
+ if (text.length > 0) {
238
+ this.dataBuffer += text;
239
+ this.emit('data', Buffer.from(text));
240
+ this.handleLoginPrompts();
241
+ }
242
+ }
243
+ processBuffer() {
244
+ const textChunks = [];
245
+ let i = 0;
246
+ while (i < this.buffer.length) {
247
+ if (this.buffer[i] === IAC) {
248
+ if (i + 1 >= this.buffer.length) {
249
+ break;
250
+ }
251
+ const cmd = this.buffer[i + 1];
252
+ if (cmd === IAC) {
253
+ textChunks.push(Buffer.from([IAC]));
254
+ i += 2;
255
+ }
256
+ else if (cmd === CMD.SB) {
257
+ const seIndex = this.findSubnegotiationEnd(i + 2);
258
+ if (seIndex === -1) {
259
+ break;
260
+ }
261
+ this.handleSubnegotiation(this.buffer.slice(i + 2, seIndex));
262
+ i = seIndex + 2;
263
+ }
264
+ else if (cmd >= CMD.WILL && cmd <= CMD.DONT) {
265
+ if (i + 2 >= this.buffer.length) {
266
+ break;
267
+ }
268
+ const option = this.buffer[i + 2];
269
+ this.handleNegotiation(cmd, option);
270
+ i += 3;
271
+ }
272
+ else {
273
+ this.debug('IAC command: %d', cmd);
274
+ i += 2;
275
+ }
276
+ }
277
+ else {
278
+ textChunks.push(Buffer.from([this.buffer[i]]));
279
+ i++;
280
+ }
281
+ }
282
+ this.buffer = this.buffer.slice(i);
283
+ if (textChunks.length === 0)
284
+ return '';
285
+ const combined = Buffer.concat(textChunks);
286
+ return combined.toString('utf8').replace(/\x00/g, '');
287
+ }
288
+ findSubnegotiationEnd(start) {
289
+ for (let i = start; i < this.buffer.length - 1; i++) {
290
+ if (this.buffer[i] === IAC && this.buffer[i + 1] === CMD.SE) {
291
+ return i;
292
+ }
293
+ }
294
+ return -1;
295
+ }
296
+ handleNegotiation(command, option) {
297
+ this.debug('Negotiation: %s %d', this.cmdName(command), option);
298
+ this.emit('command', command, option);
299
+ switch (command) {
300
+ case CMD.DO:
301
+ if (this.shouldEnableOption(option)) {
302
+ this.sendCommand(CMD.WILL, option);
303
+ this.localOptions.add(option);
304
+ }
305
+ else {
306
+ this.sendCommand(CMD.WONT, option);
307
+ }
308
+ break;
309
+ case CMD.DONT:
310
+ this.sendCommand(CMD.WONT, option);
311
+ this.localOptions.delete(option);
312
+ break;
313
+ case CMD.WILL:
314
+ if (this.shouldAcceptOption(option)) {
315
+ this.sendCommand(CMD.DO, option);
316
+ this.remoteOptions.add(option);
317
+ }
318
+ else {
319
+ this.sendCommand(CMD.DONT, option);
320
+ }
321
+ break;
322
+ case CMD.WONT:
323
+ this.sendCommand(CMD.DONT, option);
324
+ this.remoteOptions.delete(option);
325
+ break;
326
+ }
327
+ }
328
+ shouldEnableOption(option) {
329
+ switch (option) {
330
+ case OPT.TTYPE:
331
+ case OPT.NAWS:
332
+ case OPT.SGA:
333
+ return true;
334
+ default:
335
+ return false;
336
+ }
337
+ }
338
+ shouldAcceptOption(option) {
339
+ switch (option) {
340
+ case OPT.ECHO:
341
+ case OPT.SGA:
342
+ case OPT.BINARY:
343
+ return true;
344
+ default:
345
+ return false;
346
+ }
347
+ }
348
+ handleSubnegotiation(data) {
349
+ if (data.length < 1)
350
+ return;
351
+ const option = data[0];
352
+ this.debug('Subnegotiation for option %d', option);
353
+ switch (option) {
354
+ case OPT.TTYPE:
355
+ if (data.length >= 2 && data[1] === 1) {
356
+ this.sendSubnegotiation(OPT.TTYPE, Buffer.from([0, ...Buffer.from(this.config.terminalType)]));
357
+ }
358
+ break;
359
+ case OPT.NAWS:
360
+ break;
361
+ }
362
+ }
363
+ sendCommand(command, option) {
364
+ this.debug('Sending: %s %d', this.cmdName(command), option);
365
+ this.socket?.write(Buffer.from([IAC, command, option]));
366
+ }
367
+ sendSubnegotiation(option, data) {
368
+ const packet = Buffer.concat([
369
+ Buffer.from([IAC, CMD.SB, option]),
370
+ data,
371
+ Buffer.from([IAC, CMD.SE])
372
+ ]);
373
+ this.socket?.write(packet);
374
+ }
375
+ sendWindowSize() {
376
+ const [width, height] = this.config.windowSize;
377
+ const data = Buffer.alloc(4);
378
+ data.writeUInt16BE(width, 0);
379
+ data.writeUInt16BE(height, 2);
380
+ this.sendSubnegotiation(OPT.NAWS, data);
381
+ }
382
+ handleLoginPrompts() {
383
+ if (this.loginState === 'authenticated')
384
+ return;
385
+ if (!this.config.username && !this.config.password) {
386
+ this.loginState = 'authenticated';
387
+ return;
388
+ }
389
+ const text = this.dataBuffer;
390
+ if (this.loginState === 'pending' || this.loginState === 'username') {
391
+ if (this.matchPattern(text, this.config.loginPrompt)) {
392
+ if (this.config.username) {
393
+ this.debug('Detected login prompt, sending username');
394
+ this.write(this.config.username + '\r\n');
395
+ this.loginState = 'password';
396
+ this.dataBuffer = '';
397
+ }
398
+ }
399
+ }
400
+ if (this.loginState === 'password') {
401
+ if (this.matchPattern(text, this.config.passwordPrompt)) {
402
+ if (this.config.password) {
403
+ this.debug('Detected password prompt, sending password');
404
+ this.write(this.config.password + '\r\n');
405
+ this.loginState = 'authenticated';
406
+ this.dataBuffer = '';
407
+ }
408
+ }
409
+ }
410
+ }
411
+ async waitForPromptOrAuth() {
412
+ const timeout = this.config.timeout;
413
+ const start = Date.now();
414
+ return new Promise((resolve, reject) => {
415
+ const check = () => {
416
+ if (Date.now() - start > timeout) {
417
+ reject(new Error('Timeout waiting for prompt'));
418
+ return;
419
+ }
420
+ if (this.matchPattern(this.dataBuffer, this.config.shellPrompt)) {
421
+ this.loginState = 'authenticated';
422
+ resolve();
423
+ return;
424
+ }
425
+ setTimeout(check, 100);
426
+ };
427
+ check();
428
+ });
429
+ }
430
+ write(data) {
431
+ if (!this.socket || !this.connected) {
432
+ throw new Error('Not connected');
433
+ }
434
+ const buffer = typeof data === 'string' ? Buffer.from(data) : data;
435
+ this.debug('Sending: %s', buffer.toString().replace(/\r\n/g, '\\r\\n'));
436
+ this.socket.write(buffer);
437
+ }
438
+ waitForPattern(pattern, timeout) {
439
+ return new Promise((resolve, reject) => {
440
+ const start = Date.now();
441
+ const startBuffer = this.dataBuffer;
442
+ const check = () => {
443
+ if (Date.now() - start > timeout) {
444
+ reject(new Error(`Timeout waiting for pattern: ${pattern}`));
445
+ return;
446
+ }
447
+ if (this.matchPattern(this.dataBuffer, pattern)) {
448
+ resolve(this.dataBuffer);
449
+ return;
450
+ }
451
+ setTimeout(check, 50);
452
+ };
453
+ check();
454
+ });
455
+ }
456
+ matchPattern(text, pattern) {
457
+ if (typeof pattern === 'string') {
458
+ return text.includes(pattern);
459
+ }
460
+ return pattern.test(text);
461
+ }
462
+ cleanOutput(output, command, prompt) {
463
+ let cleaned = output;
464
+ const lines = cleaned.split(/\r?\n/);
465
+ if (lines.length > 0 && lines[0].includes(command)) {
466
+ lines.shift();
467
+ }
468
+ cleaned = lines.join('\n');
469
+ if (typeof prompt === 'string') {
470
+ const idx = cleaned.lastIndexOf(prompt);
471
+ if (idx !== -1) {
472
+ cleaned = cleaned.substring(0, idx);
473
+ }
474
+ }
475
+ else {
476
+ cleaned = cleaned.replace(prompt, '');
477
+ }
478
+ return cleaned.trim();
117
479
  }
118
480
  ensureConnected() {
119
- if (!this.connected) {
481
+ if (!this.connected || !this.socket) {
120
482
  throw new Error('Not connected to Telnet server. Call connect() first.');
121
483
  }
122
484
  }
485
+ cmdName(cmd) {
486
+ switch (cmd) {
487
+ case CMD.WILL: return 'WILL';
488
+ case CMD.WONT: return 'WONT';
489
+ case CMD.DO: return 'DO';
490
+ case CMD.DONT: return 'DONT';
491
+ default: return `CMD(${cmd})`;
492
+ }
493
+ }
494
+ debug(format, ...args) {
495
+ if (this.config.debug) {
496
+ console.log(`[Telnet] ${format}`, ...args);
497
+ }
498
+ }
123
499
  }
124
500
  export function createTelnet(config) {
125
501
  return new Telnet(config);
@@ -1 +1 @@
1
- {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/scrape/document.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,SAAS,CAAC;AAEnD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAa7C,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAEhB,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,eAAe,EACf,UAAU,EACV,aAAa,EACb,cAAc,EACd,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAyBpB,qBAAa,cAAc;IACzB,OAAO,CAAC,CAAC,CAAa;IACtB,OAAO,CAAC,OAAO,CAAgB;gBAKnB,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,aAAa;WASrC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAWnF,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IAOvC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IAO5C,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE;IAW5C,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IAOtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE;IAS3C,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAO9B,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAcjC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAO7D,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAcpD,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAO1C,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAUnC,KAAK,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,aAAa,EAAE;IAUvD,MAAM,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,cAAc,EAAE;IAU1D,IAAI,IAAI,aAAa;IAOrB,SAAS,IAAI,aAAa;IAO1B,WAAW,IAAI,eAAe;IAO9B,MAAM,IAAI,UAAU,EAAE;IAOtB,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAOzC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE;IAO3C,OAAO,IAAI,eAAe,EAAE;IAO5B,MAAM,IAAI,cAAc,EAAE;IAkB1B,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,gBAAgB,GAAG,CAAC;IAUvE,OAAO,CAAC,YAAY;IAgDpB,KAAK,IAAI,MAAM,GAAG,SAAS;IAQ3B,IAAI,IAAI,aAAa;IAOrB,IAAI,IAAI,aAAa;IAOrB,IAAI,IAAI,MAAM;IAOd,IAAI,IAAI,aAAa;IAOrB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAOjC,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAS/B,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAiB5D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAiBjE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAazD,IAAI,GAAG,IAAI,UAAU,CAEpB;IAKD,IAAI,OAAO,IAAI,MAAM,GAAG,SAAS,CAEhC;CACF"}
1
+ {"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../../src/scrape/document.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,UAAU,EAAW,MAAM,SAAS,CAAC;AAGnD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAa7C,OAAO,KAAK,EACV,aAAa,EACb,gBAAgB,EAEhB,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,eAAe,EACf,UAAU,EACV,aAAa,EACb,cAAc,EACd,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACvB,MAAM,YAAY,CAAC;AAqBpB,qBAAa,cAAc;IACzB,OAAO,CAAC,CAAC,CAAa;IACtB,OAAO,CAAC,OAAO,CAAgB;gBAKnB,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,aAAa;WASrC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAWnF,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IAOvC,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IAO5C,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE;IAW5C,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IAOtC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,EAAE;IAS3C,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAO9B,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE;IAcjC,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAO7D,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE;IAcpD,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAO1C,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAUnC,KAAK,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,aAAa,EAAE;IAUvD,MAAM,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,cAAc,EAAE;IAU1D,IAAI,IAAI,aAAa;IAOrB,SAAS,IAAI,aAAa;IAO1B,WAAW,IAAI,eAAe;IAO9B,MAAM,IAAI,UAAU,EAAE;IAOtB,KAAK,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAOzC,MAAM,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,cAAc,EAAE;IAO3C,OAAO,IAAI,eAAe,EAAE;IAO5B,MAAM,IAAI,cAAc,EAAE;IAkB1B,OAAO,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,gBAAgB,GAAG,CAAC;IAUvE,OAAO,CAAC,YAAY;IAgDpB,KAAK,IAAI,MAAM,GAAG,SAAS;IAQ3B,IAAI,IAAI,aAAa;IAOrB,IAAI,IAAI,aAAa;IAOrB,IAAI,IAAI,MAAM;IAOd,IAAI,IAAI,aAAa;IAOrB,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAOjC,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAS/B,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAiB5D,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAiBjE,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,aAAa,EAAE;IAazD,IAAI,GAAG,IAAI,UAAU,CAEpB;IAKD,IAAI,OAAO,IAAI,MAAM,GAAG,SAAS,CAEhC;CACF"}
@@ -1,18 +1,13 @@
1
+ import { requireOptional } from '../utils/optional-require.js';
1
2
  import { ScrapeElement } from './element.js';
2
3
  import { extractLinks, extractImages, extractMeta, extractOpenGraph, extractTwitterCard, extractJsonLd, extractForms, extractTables, extractScripts, extractStyles, } from './extractors.js';
3
- let cheerioLoad = null;
4
+ let cheerioModule = null;
4
5
  async function loadCheerio() {
5
- if (cheerioLoad) {
6
- return cheerioLoad;
7
- }
8
- try {
9
- const cheerio = await import('cheerio');
10
- cheerioLoad = cheerio.load;
11
- return cheerioLoad;
12
- }
13
- catch {
14
- throw new Error('cheerio is required for scraping but not installed. Install it with: pnpm add cheerio');
6
+ if (cheerioModule) {
7
+ return cheerioModule;
15
8
  }
9
+ cheerioModule = await requireOptional('cheerio', 'recker/scrape');
10
+ return cheerioModule;
16
11
  }
17
12
  export class ScrapeDocument {
18
13
  $;
@@ -22,7 +17,7 @@ export class ScrapeDocument {
22
17
  this.options = options || {};
23
18
  }
24
19
  static async create(html, options) {
25
- const load = await loadCheerio();
20
+ const { load } = await loadCheerio();
26
21
  return new ScrapeDocument(load(html), options);
27
22
  }
28
23
  select(selector) {
@@ -1,3 +1,5 @@
1
1
  export { MockClient, MockTransport, createMockClient, installGlobalMock, uninstallGlobalMock, MockAgent, } from './mock.js';
2
2
  export type { MockResponseOptions, MockInterceptOptions, } from './mock.js';
3
+ export { MockUDPServer, createMockUDPServer, } from './mock-udp-server.js';
4
+ export type { MockUDPServerOptions, ReceivedMessage, } from './mock-udp-server.js';
3
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAqCA,OAAO,EACL,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,SAAS,GACV,MAAM,WAAW,CAAC;AAEnB,YAAY,EACV,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/testing/index.ts"],"names":[],"mappings":"AAqCA,OAAO,EACL,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,iBAAiB,EACjB,mBAAmB,EACnB,SAAS,GACV,MAAM,WAAW,CAAC;AAEnB,YAAY,EACV,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,aAAa,EACb,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,oBAAoB,EACpB,eAAe,GAChB,MAAM,sBAAsB,CAAC"}
@@ -1 +1,2 @@
1
1
  export { MockClient, MockTransport, createMockClient, installGlobalMock, uninstallGlobalMock, MockAgent, } from './mock.js';
2
+ export { MockUDPServer, createMockUDPServer, } from './mock-udp-server.js';
@@ -0,0 +1,44 @@
1
+ import dgram from 'node:dgram';
2
+ import { EventEmitter } from 'node:events';
3
+ export interface MockUDPServerOptions {
4
+ port?: number;
5
+ host?: string;
6
+ type?: 'udp4' | 'udp6';
7
+ echo?: boolean;
8
+ delay?: number;
9
+ dropRate?: number;
10
+ }
11
+ export interface ReceivedMessage {
12
+ data: Buffer;
13
+ rinfo: dgram.RemoteInfo;
14
+ timestamp: number;
15
+ }
16
+ export declare class MockUDPServer extends EventEmitter {
17
+ private socket;
18
+ private options;
19
+ private responses;
20
+ private _port;
21
+ private _receivedMessages;
22
+ private _started;
23
+ constructor(options?: MockUDPServerOptions);
24
+ get port(): number;
25
+ get address(): string;
26
+ get isRunning(): boolean;
27
+ get receivedMessages(): ReceivedMessage[];
28
+ get messageCount(): number;
29
+ start(): Promise<void>;
30
+ stop(): Promise<void>;
31
+ setResponse(pattern: string | RegExp, response: Buffer | string | ((msg: Buffer, rinfo: dgram.RemoteInfo) => Buffer | string | null)): void;
32
+ setDelay(delay: number): void;
33
+ setDropRate(rate: number): void;
34
+ setEcho(enabled: boolean): void;
35
+ clearMessages(): void;
36
+ clearResponses(): void;
37
+ reset(): void;
38
+ private getResponse;
39
+ sendTo(data: Buffer | string, port: number, address?: string): Promise<void>;
40
+ waitForMessages(count: number, timeout?: number): Promise<ReceivedMessage[]>;
41
+ static create(options?: MockUDPServerOptions): Promise<MockUDPServer>;
42
+ }
43
+ export declare function createMockUDPServer(responses?: Record<string, Buffer | string>, options?: MockUDPServerOptions): Promise<MockUDPServer>;
44
+ //# sourceMappingURL=mock-udp-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mock-udp-server.d.ts","sourceRoot":"","sources":["../../src/testing/mock-udp-server.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,oBAAoB;IAKnC,IAAI,CAAC,EAAE,MAAM,CAAC;IAMd,IAAI,CAAC,EAAE,MAAM,CAAC;IAMd,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAMvB,IAAI,CAAC,EAAE,OAAO,CAAC;IAMf,KAAK,CAAC,EAAE,MAAM,CAAC;IAMf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,MAAM,CAA6B;IAC3C,OAAO,CAAC,OAAO,CAAiC;IAChD,OAAO,CAAC,SAAS,CAA8F;IAC/G,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,QAAQ,CAAkB;gBAEtB,OAAO,GAAE,oBAAyB;IAgB9C,IAAI,IAAI,IAAI,MAAM,CAEjB;IAKD,IAAI,OAAO,IAAI,MAAM,CAEpB;IAKD,IAAI,SAAS,IAAI,OAAO,CAEvB;IAKD,IAAI,gBAAgB,IAAI,eAAe,EAAE,CAExC;IAKD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAKK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2DtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB3B,WAAW,CACT,OAAO,EAAE,MAAM,GAAG,MAAM,EACxB,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC,GAC7F,IAAI;IAkBP,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAO7B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAO/B,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAO/B,aAAa,IAAI,IAAI;IAOrB,cAAc,IAAI,IAAI;IAOtB,KAAK,IAAI,IAAI;IAWb,OAAO,CAAC,WAAW;IAyBb,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,MAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBzF,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,MAAa,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;WAgB3E,MAAM,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,aAAa,CAAC;CAKhF;AAKD,wBAAsB,mBAAmB,CACvC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,EAC3C,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,aAAa,CAAC,CAYxB"}