recker 1.0.79 → 1.0.80-next.70ea84d

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 (196) hide show
  1. package/dist/browser/browser/mini.d.ts +2 -2
  2. package/dist/browser/browser/recker-mini.d.ts +8 -8
  3. package/dist/browser/browser/recker.d.ts +11 -8
  4. package/dist/browser/browser/recker.js +54 -6
  5. package/dist/browser/core/client.d.ts +15 -10
  6. package/dist/browser/core/client.js +54 -38
  7. package/dist/browser/index.iife.min.js +129 -130
  8. package/dist/browser/index.min.js +129 -130
  9. package/dist/browser/index.mini.iife.js +5697 -636
  10. package/dist/browser/index.mini.iife.min.js +47 -48
  11. package/dist/browser/index.mini.min.js +47 -48
  12. package/dist/browser/index.mini.umd.js +5697 -636
  13. package/dist/browser/index.mini.umd.min.js +47 -48
  14. package/dist/browser/index.umd.min.js +129 -130
  15. package/dist/browser/mini.d.ts +2 -2
  16. package/dist/browser/plugins/proxy-rotator.d.ts +2 -2
  17. package/dist/browser/plugins/proxy-rotator.js +6 -28
  18. package/dist/browser/recker-mini.d.ts +8 -8
  19. package/dist/browser/recker.d.ts +11 -8
  20. package/dist/browser/recker.js +54 -6
  21. package/dist/browser/scrape/document.js +2 -2
  22. package/dist/browser/scrape/element.js +7 -1
  23. package/dist/browser/scrape/parser/nodes/html.js +1 -1
  24. package/dist/browser/scrape/spider.d.ts +52 -0
  25. package/dist/browser/scrape/spider.js +620 -38
  26. package/dist/browser/scrape/types.d.ts +2 -0
  27. package/dist/browser/search/google.d.ts +26 -1
  28. package/dist/browser/search/google.js +427 -45
  29. package/dist/browser/seo/analyzer.d.ts +1 -0
  30. package/dist/browser/seo/analyzer.js +144 -1
  31. package/dist/browser/seo/index.d.ts +1 -1
  32. package/dist/browser/seo/keyword-campaign-analyzer.d.ts +2 -0
  33. package/dist/browser/seo/keyword-campaign-analyzer.js +538 -0
  34. package/dist/browser/seo/keyword-campaign-seed-advanced.d.ts +17 -0
  35. package/dist/browser/seo/keyword-campaign-seed-advanced.js +269 -0
  36. package/dist/browser/seo/keyword-campaign-seed-core.d.ts +29 -0
  37. package/dist/browser/seo/keyword-campaign-seed-core.js +525 -0
  38. package/dist/browser/seo/keyword-campaign-shared.d.ts +165 -0
  39. package/dist/browser/seo/keyword-campaign-shared.js +59 -0
  40. package/dist/browser/seo/keyword-campaign.d.ts +4 -107
  41. package/dist/browser/seo/keyword-campaign.js +2 -380
  42. package/dist/browser/seo/keywords.js +5 -22
  43. package/dist/browser/seo/types.d.ts +19 -0
  44. package/dist/browser/transport/curl.d.ts +5 -1
  45. package/dist/browser/transport/curl.js +207 -50
  46. package/dist/browser/transport/undici.d.ts +4 -3
  47. package/dist/browser/transport/undici.js +123 -49
  48. package/dist/browser/types/index.d.ts +9 -3
  49. package/dist/browser/utils/binary-manager.js +26 -3
  50. package/dist/browser/utils/block-detector.d.ts +8 -0
  51. package/dist/browser/utils/block-detector.js +542 -7
  52. package/dist/cli/commands/hls-runner.js +5 -4
  53. package/dist/cli/commands/live-runner.js +5 -4
  54. package/dist/cli/commands/loadtest-runner.js +3 -2
  55. package/dist/cli/commands/search.d.ts +2 -0
  56. package/dist/cli/commands/search.js +105 -0
  57. package/dist/cli/commands/seo-runner.js +9 -7
  58. package/dist/cli/commands/seo.js +140 -1
  59. package/dist/cli/commands/serve.js +75 -131
  60. package/dist/cli/commands/server-runner.js +59 -82
  61. package/dist/cli/commands/spider-runner.d.ts +37 -1
  62. package/dist/cli/commands/spider-runner.js +134 -10
  63. package/dist/cli/commands/spider.d.ts +18 -1
  64. package/dist/cli/commands/spider.js +457 -27
  65. package/dist/cli/events/handlers/cli.js +30 -1
  66. package/dist/cli/events/handlers/tui.js +26 -0
  67. package/dist/cli/events/types.d.ts +27 -0
  68. package/dist/cli/handler.d.ts +2 -12
  69. package/dist/cli/handler.js +20 -15
  70. package/dist/cli/handlers/protocols.js +39 -12
  71. package/dist/cli/handlers/search.d.ts +2 -0
  72. package/dist/cli/handlers/search.js +171 -0
  73. package/dist/cli/handlers/seo-analyze.d.ts +1 -0
  74. package/dist/cli/handlers/seo-analyze.js +666 -0
  75. package/dist/cli/handlers/seo-robots.d.ts +1 -0
  76. package/dist/cli/handlers/seo-robots.js +76 -0
  77. package/dist/cli/handlers/seo-serp.d.ts +54 -0
  78. package/dist/cli/handlers/seo-serp.js +243 -0
  79. package/dist/cli/handlers/seo-sitemap.d.ts +1 -0
  80. package/dist/cli/handlers/seo-sitemap.js +55 -0
  81. package/dist/cli/handlers/seo-spider.d.ts +1 -0
  82. package/dist/cli/handlers/seo-spider.js +334 -0
  83. package/dist/cli/handlers/seo.d.ts +8 -4
  84. package/dist/cli/handlers/seo.js +294 -442
  85. package/dist/cli/handlers/spider.js +94 -17
  86. package/dist/cli/handlers/streaming.js +5 -1
  87. package/dist/cli/index.js +11 -2
  88. package/dist/cli/presets.d.ts +1 -1
  89. package/dist/cli/presets.js +15 -4
  90. package/dist/cli/tui/app.js +6 -1
  91. package/dist/cli/tui/components/rich-response.d.ts +72 -0
  92. package/dist/cli/tui/components/rich-response.js +117 -0
  93. package/dist/cli/tui/executor-commands/background.js +30 -24
  94. package/dist/cli/tui/executor-commands/testing.js +3 -2
  95. package/dist/cli/tui/hooks/useDomains.d.ts +17 -0
  96. package/dist/cli/tui/hooks/useHelp.js +15 -2
  97. package/dist/cli/tui/job-manager.d.ts +4 -4
  98. package/dist/cli/tui/job-manager.js +5 -1
  99. package/dist/cli/tui/spider-tui.d.ts +63 -0
  100. package/dist/cli/tui/spider-tui.js +120 -2
  101. package/dist/cli/types.d.ts +12 -0
  102. package/dist/cli/types.js +1 -0
  103. package/dist/cli/utils/option-helpers.d.ts +10 -0
  104. package/dist/cli/utils/option-helpers.js +63 -0
  105. package/dist/cli/utils/score-color.d.ts +11 -0
  106. package/dist/cli/utils/score-color.js +11 -0
  107. package/dist/cli/utils/serp-campaign.d.ts +53 -0
  108. package/dist/cli/utils/serp-campaign.js +53 -0
  109. package/dist/cli/utils/serp-config.d.ts +26 -0
  110. package/dist/cli/utils/serp-config.js +125 -0
  111. package/dist/core/client.d.ts +15 -10
  112. package/dist/core/client.js +54 -38
  113. package/dist/index.d.ts +1 -0
  114. package/dist/index.js +1 -0
  115. package/dist/mcp/cli.js +35 -34
  116. package/dist/mcp/client.d.ts +2 -2
  117. package/dist/mcp/client.js +20 -2
  118. package/dist/mcp/contract.d.ts +1 -1
  119. package/dist/mcp/profiles.js +5 -1
  120. package/dist/mcp/prompts/index.js +8 -4
  121. package/dist/mcp/resources/index.js +46 -23
  122. package/dist/mcp/server.js +9 -6
  123. package/dist/mcp/tools/protocols.js +9 -2
  124. package/dist/mcp/tools/registry.js +13 -3
  125. package/dist/mcp/tools/seo.js +427 -2
  126. package/dist/mcp/types.d.ts +5 -1
  127. package/dist/plugins/proxy-rotator.d.ts +2 -2
  128. package/dist/plugins/proxy-rotator.js +6 -28
  129. package/dist/raffel/client.d.ts +38 -0
  130. package/dist/raffel/client.js +282 -0
  131. package/dist/raffel/index.d.ts +2 -0
  132. package/dist/raffel/index.js +2 -0
  133. package/dist/raffel/types.d.ts +40 -0
  134. package/dist/raffel/types.js +14 -0
  135. package/dist/recker.d.ts +13 -7
  136. package/dist/recker.js +58 -6
  137. package/dist/scrape/document.js +2 -2
  138. package/dist/scrape/element.js +7 -1
  139. package/dist/scrape/parser/nodes/html.js +1 -1
  140. package/dist/scrape/spider.d.ts +52 -0
  141. package/dist/scrape/spider.js +620 -38
  142. package/dist/scrape/types.d.ts +2 -0
  143. package/dist/search/google.d.ts +26 -1
  144. package/dist/search/google.js +427 -45
  145. package/dist/search/index.d.ts +1 -1
  146. package/dist/seo/analyzer.d.ts +1 -0
  147. package/dist/seo/analyzer.js +144 -1
  148. package/dist/seo/index.d.ts +1 -1
  149. package/dist/seo/keyword-campaign-analyzer.d.ts +2 -0
  150. package/dist/seo/keyword-campaign-analyzer.js +538 -0
  151. package/dist/seo/keyword-campaign-seed-advanced.d.ts +17 -0
  152. package/dist/seo/keyword-campaign-seed-advanced.js +269 -0
  153. package/dist/seo/keyword-campaign-seed-core.d.ts +29 -0
  154. package/dist/seo/keyword-campaign-seed-core.js +525 -0
  155. package/dist/seo/keyword-campaign-shared.d.ts +165 -0
  156. package/dist/seo/keyword-campaign-shared.js +59 -0
  157. package/dist/seo/keyword-campaign.d.ts +4 -107
  158. package/dist/seo/keyword-campaign.js +2 -380
  159. package/dist/seo/keywords.js +5 -22
  160. package/dist/seo/types.d.ts +19 -0
  161. package/dist/template/index.d.ts +1 -1
  162. package/dist/template/types.d.ts +0 -2
  163. package/dist/testing/index.d.ts +1 -22
  164. package/dist/testing/index.js +1 -11
  165. package/dist/transport/curl.d.ts +5 -1
  166. package/dist/transport/curl.js +207 -50
  167. package/dist/transport/undici.d.ts +4 -3
  168. package/dist/transport/undici.js +123 -49
  169. package/dist/types/index.d.ts +9 -3
  170. package/dist/utils/binary-manager.js +26 -3
  171. package/dist/utils/block-detector.d.ts +8 -0
  172. package/dist/utils/block-detector.js +542 -7
  173. package/dist/version.js +1 -1
  174. package/package.json +12 -1
  175. package/dist/testing/mock-dns-server.d.ts +0 -69
  176. package/dist/testing/mock-dns-server.js +0 -269
  177. package/dist/testing/mock-ftp-server.d.ts +0 -89
  178. package/dist/testing/mock-ftp-server.js +0 -562
  179. package/dist/testing/mock-hls-server.d.ts +0 -80
  180. package/dist/testing/mock-hls-server.js +0 -381
  181. package/dist/testing/mock-http-server.d.ts +0 -124
  182. package/dist/testing/mock-http-server.js +0 -343
  183. package/dist/testing/mock-proxy-server.d.ts +0 -108
  184. package/dist/testing/mock-proxy-server.js +0 -615
  185. package/dist/testing/mock-sse-server.d.ts +0 -76
  186. package/dist/testing/mock-sse-server.js +0 -291
  187. package/dist/testing/mock-telnet-server.d.ts +0 -59
  188. package/dist/testing/mock-telnet-server.js +0 -274
  189. package/dist/testing/mock-udp-server.d.ts +0 -43
  190. package/dist/testing/mock-udp-server.js +0 -188
  191. package/dist/testing/mock-websocket-server.d.ts +0 -76
  192. package/dist/testing/mock-websocket-server.js +0 -334
  193. package/dist/testing/mock-whois-server.d.ts +0 -56
  194. package/dist/testing/mock-whois-server.js +0 -234
  195. package/dist/testing/proxy-certs.d.ts +0 -19
  196. package/dist/testing/proxy-certs.js +0 -208
@@ -42,22 +42,27 @@ export function registerServeCommand(program) {
42
42
  .example('rek serve http --echo', 'Echo mode')
43
43
  .action(async (args, cmdObj) => {
44
44
  const options = cmdObj.opts ? cmdObj.opts() : {};
45
- const { MockHttpServer } = await import('../../testing/mock-http-server.js');
45
+ const { createMockHttpServer } = await import('../../testing/index.js');
46
46
  const port = options.port || 3000;
47
47
  const host = options.host || '127.0.0.1';
48
48
  const delay = options.delay || 0;
49
49
  const useCors = !options['no-cors'];
50
- const server = await MockHttpServer.create({
50
+ const server = await createMockHttpServer({
51
51
  port,
52
52
  host,
53
53
  delay,
54
54
  cors: useCors,
55
55
  });
56
56
  if (options.echo) {
57
- server.any('/*', (req) => ({
57
+ const echoHandler = (req) => ({
58
58
  status: 200,
59
59
  body: { method: req.method, path: req.path, query: req.query, headers: req.headers, body: req.body },
60
- }));
60
+ });
61
+ server.get('/*', echoHandler);
62
+ server.post('/*', echoHandler);
63
+ server.put('/*', echoHandler);
64
+ server.patch('/*', echoHandler);
65
+ server.delete('/*', echoHandler);
61
66
  }
62
67
  console.log(colors.green(`
63
68
  ┌─────────────────────────────────────────────┐
@@ -69,8 +74,9 @@ export function registerServeCommand(program) {
69
74
  ├─────────────────────────────────────────────┤
70
75
  │ Press ${colors.bold('Ctrl+C')} to stop │
71
76
  └─────────────────────────────────────────────┘`));
72
- server.on('request', (req) => {
77
+ server.addInterceptor((req, res) => {
73
78
  console.log(colors.gray(`${new Date().toISOString()} `) + colors.cyan(req.method.padEnd(7)) + req.path);
79
+ return res;
74
80
  });
75
81
  process.on('SIGINT', async () => {
76
82
  console.log(colors.yellow('\nShutting down...'));
@@ -105,7 +111,7 @@ export function registerServeCommand(program) {
105
111
  .example('rek serve webhook --status=200', 'Return 200 OK')
106
112
  .action(async (args, cmdObj) => {
107
113
  const options = cmdObj.opts ? cmdObj.opts() : {};
108
- const { createWebhookServer } = await import('../../testing/mock-http-server.js');
114
+ const { createMockHttpServer } = await import('../../testing/index.js');
109
115
  const port = options.port || 3000;
110
116
  const host = options.host || '127.0.0.1';
111
117
  const status = options.status || 204;
@@ -113,12 +119,13 @@ export function registerServeCommand(program) {
113
119
  console.error(colors.red('Status must be 200 or 204'));
114
120
  process.exit(1);
115
121
  }
116
- const server = await createWebhookServer({
117
- port,
118
- host,
119
- status: status,
120
- log: !options.quiet,
121
- });
122
+ const webhookHandler = () => ({ status });
123
+ const server = await createMockHttpServer({ port, host });
124
+ server.get('/*', webhookHandler);
125
+ server.post('/*', webhookHandler);
126
+ server.put('/*', webhookHandler);
127
+ server.patch('/*', webhookHandler);
128
+ server.delete('/*', webhookHandler);
122
129
  console.log(colors.green(`
123
130
  ┌─────────────────────────────────────────────┐
124
131
  │ ${colors.bold('Recker Webhook Receiver')} │
@@ -133,7 +140,7 @@ export function registerServeCommand(program) {
133
140
  └─────────────────────────────────────────────┘`));
134
141
  process.on('SIGINT', async () => {
135
142
  console.log(colors.yellow('\nShutting down...'));
136
- console.log(colors.gray(`Total webhooks received: ${server.webhooks.length}`));
143
+ console.log(colors.gray(`Total webhooks received: ${server.statistics.totalRequests}`));
137
144
  await server.stop();
138
145
  process.exit(0);
139
146
  });
@@ -167,33 +174,24 @@ export function registerServeCommand(program) {
167
174
  .example('rek serve ws --no-echo', 'Disable echo mode')
168
175
  .action(async (args, cmdObj) => {
169
176
  const options = cmdObj.opts ? cmdObj.opts() : {};
170
- const { MockWebSocketServer } = await import('../../testing/mock-websocket-server.js');
177
+ const { createMockWebSocketServer } = await import('../../testing/index.js');
171
178
  const port = options.port || 8080;
172
179
  const host = options.host || '127.0.0.1';
173
- const delay = options.delay || 0;
174
180
  const echo = !options['no-echo'];
175
- const server = await MockWebSocketServer.create({
176
- port,
177
- host,
178
- echo,
179
- delay,
180
- });
181
+ const server = await createMockWebSocketServer({ port, host });
182
+ if (!echo) {
183
+ server.setMessageHandler(() => undefined);
184
+ }
181
185
  console.log(colors.green(`
182
186
  ┌─────────────────────────────────────────────┐
183
187
  │ ${colors.bold('Recker Mock WebSocket Server')} │
184
188
  ├─────────────────────────────────────────────┤
185
189
  │ URL: ${colors.cyan(server.url.padEnd(37))}│
186
190
  │ Echo: ${colors.yellow((echo ? 'Enabled' : 'Disabled').padEnd(36))}│
187
- │ Delay: ${colors.gray((delay + 'ms').padEnd(35))}
188
191
  ├─────────────────────────────────────────────┤
189
192
  │ Press ${colors.bold('Ctrl+C')} to stop │
190
193
  └─────────────────────────────────────────────┘`));
191
- server.on('connection', (client) => console.log(colors.green(`+ Connected: ${client.id}`)));
192
- server.on('message', (msg, client) => {
193
- const d = msg.data.toString();
194
- console.log(colors.gray(`${new Date().toISOString()} `) + colors.cyan(client.id) + ` ${d.slice(0, 50)}${d.length > 50 ? '...' : ''}`);
195
- });
196
- server.on('disconnect', (client) => console.log(colors.red(`- Disconnected: ${client.id}`)));
194
+ server.on('connection', (socket) => console.log(colors.green(`+ Connected: ${socket._socket?.remoteAddress ?? 'client'}`)));
197
195
  process.on('SIGINT', async () => {
198
196
  console.log(colors.yellow('\nShutting down...'));
199
197
  await server.stop();
@@ -231,19 +229,15 @@ export function registerServeCommand(program) {
231
229
  .example('rek serve sse --heartbeat=5000', 'Heartbeat every 5s')
232
230
  .action(async (args, cmdObj) => {
233
231
  const options = cmdObj.opts ? cmdObj.opts() : {};
234
- const { MockSSEServer } = await import('../../testing/mock-sse-server.js');
232
+ const { createMockSSEServer } = await import('../../testing/index.js');
235
233
  const readline = await import('node:readline');
236
234
  const port = options.port || 8081;
237
235
  const host = options.host || '127.0.0.1';
238
236
  const path = options.path || '/events';
239
237
  const heartbeat = options.heartbeat || 0;
240
- const server = await MockSSEServer.create({
241
- port,
242
- host,
243
- path,
244
- });
238
+ const server = await createMockSSEServer({ port, host, path });
245
239
  if (heartbeat > 0)
246
- server.startPeriodicEvents('heartbeat', heartbeat);
240
+ server.startPeriodicEvents('heartbeat', heartbeat, () => ({ data: 'heartbeat', event: 'heartbeat' }));
247
241
  console.log(colors.green(`
248
242
  ┌─────────────────────────────────────────────┐
249
243
  │ ${colors.bold('Recker Mock SSE Server')} │
@@ -259,8 +253,8 @@ export function registerServeCommand(program) {
259
253
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
260
254
  rl.on('line', (line) => {
261
255
  if (line.trim()) {
262
- const sent = server.sendData(line.trim());
263
- console.log(colors.gray(`Broadcast to ${sent} client(s): ${line.trim()}`));
256
+ server.sendEvent({ data: line.trim() });
257
+ console.log(colors.gray(`Broadcast to ${server.connectionCount} client(s): ${line.trim()}`));
264
258
  }
265
259
  });
266
260
  process.on('SIGINT', async () => {
@@ -315,8 +309,7 @@ export function registerServeCommand(program) {
315
309
  .example('rek serve hls -Q 1080p,720p', 'Custom qualities')
316
310
  .action(async (args, cmdObj) => {
317
311
  const options = cmdObj.opts ? cmdObj.opts() : {};
318
- const { MockHlsServer } = await import('../../testing/mock-hls-server.js');
319
- const http = await import('node:http');
312
+ const { createMockHlsServer } = await import('../../testing/index.js');
320
313
  const port = options.port || 8082;
321
314
  const host = options.host || '127.0.0.1';
322
315
  const mode = options.mode || 'vod';
@@ -329,44 +322,26 @@ export function registerServeCommand(program) {
329
322
  bandwidth: [5000000, 2500000, 1400000][i] || 500000,
330
323
  resolution: ['1920x1080', '1280x720', '854x480'][i] || '640x360',
331
324
  }));
332
- const baseUrl = `http://${host}:${port}`;
333
- const hlsServer = await MockHlsServer.create({
334
- baseUrl,
325
+ const hlsServer = await createMockHlsServer({
326
+ port,
327
+ host,
335
328
  mode: mode,
336
329
  segmentCount: segments,
337
330
  segmentDuration: duration,
338
- multiQuality: variants.length > 1,
339
- variants: variants.length > 1 ? variants : undefined,
331
+ variants,
340
332
  });
341
- const httpServer = http.createServer(async (req, res) => {
342
- const url = `${baseUrl}${req.url}`;
343
- try {
344
- const response = await hlsServer.transport.dispatch({ url, method: req.method || 'GET' });
345
- res.statusCode = response.status;
346
- response.headers.forEach((value, key) => res.setHeader(key, value));
347
- const body = await response.arrayBuffer();
348
- res.end(Buffer.from(body));
349
- }
350
- catch {
351
- res.statusCode = 404;
352
- res.end('Not Found');
353
- }
354
- });
355
- httpServer.listen(port, host, () => {
356
- console.log(colors.green(`
333
+ console.log(colors.green(`
357
334
  ┌─────────────────────────────────────────────┐
358
335
  │ ${colors.bold('Recker Mock HLS Server')} │
359
336
  ├─────────────────────────────────────────────┤
360
- │ Master: ${colors.cyan((hlsServer.manifestUrl).padEnd(34))}│
337
+ │ Master: ${colors.cyan(hlsServer.masterUrl.padEnd(34))}│
361
338
  │ Mode: ${colors.yellow(mode.padEnd(36))}│
362
339
  │ Qualities: ${colors.cyan(qualities.join(', ').padEnd(31))}
363
340
  ├─────────────────────────────────────────────┤
364
341
  │ Press ${colors.bold('Ctrl+C')} to stop │
365
342
  └─────────────────────────────────────────────┘`));
366
- });
367
343
  process.on('SIGINT', async () => {
368
344
  console.log(colors.yellow('\nShutting down...'));
369
- httpServer.close();
370
345
  await hlsServer.stop();
371
346
  process.exit(0);
372
347
  });
@@ -392,16 +367,13 @@ export function registerServeCommand(program) {
392
367
  .example('rek serve udp', 'Start on port 9000')
393
368
  .action(async (args, cmdObj) => {
394
369
  const options = cmdObj.opts ? cmdObj.opts() : {};
395
- const { MockUDPServer } = await import('../../testing/mock-udp-server.js');
370
+ const { createMockUdpServer } = await import('../../testing/index.js');
396
371
  const port = options.port || 9000;
397
372
  const host = options.host || '127.0.0.1';
398
373
  const echo = !options['no-echo'];
399
- const server = new MockUDPServer({
400
- port,
401
- host,
402
- echo,
403
- });
404
- await server.start();
374
+ const server = await createMockUdpServer({ port, host });
375
+ if (!echo)
376
+ server.setMessageHandler(() => undefined);
405
377
  console.log(colors.green(`
406
378
  ┌─────────────────────────────────────────────┐
407
379
  │ ${colors.bold('Recker Mock UDP Server')} │
@@ -411,9 +383,9 @@ export function registerServeCommand(program) {
411
383
  ├─────────────────────────────────────────────┤
412
384
  │ Press ${colors.bold('Ctrl+C')} to stop │
413
385
  └─────────────────────────────────────────────┘`));
414
- server.on('message', (msg) => {
415
- const d = msg.data.toString();
416
- console.log(colors.gray(`${new Date().toISOString()} `) + colors.cyan(`${msg.rinfo.address}:${msg.rinfo.port}`) + ` ${d.slice(0, 50)}${d.length > 50 ? '...' : ''}`);
386
+ server.on('message', (message, rinfo) => {
387
+ const d = Buffer.isBuffer(message) ? message.toString() : String(message);
388
+ console.log(colors.gray(`${new Date().toISOString()} `) + colors.cyan(`${rinfo.address}:${rinfo.port}`) + ` ${d.slice(0, 50)}${d.length > 50 ? '...' : ''}`);
417
389
  });
418
390
  process.on('SIGINT', async () => {
419
391
  console.log(colors.yellow('\nShutting down...'));
@@ -445,15 +417,11 @@ export function registerServeCommand(program) {
445
417
  .example('rek serve dns', 'Start on port 5353')
446
418
  .action(async (args, cmdObj) => {
447
419
  const options = cmdObj.opts ? cmdObj.opts() : {};
448
- const { MockDnsServer } = await import('../../testing/mock-dns-server.js');
420
+ const { createMockDnsServer } = await import('../../testing/index.js');
449
421
  const port = options.port || 5353;
450
422
  const host = options.host || '127.0.0.1';
451
423
  const delay = options.delay || 0;
452
- const server = await MockDnsServer.create({
453
- port,
454
- host,
455
- delay,
456
- });
424
+ const server = await createMockDnsServer({ port, host, delay });
457
425
  console.log(colors.green(`
458
426
  ┌─────────────────────────────────────────────┐
459
427
  │ ${colors.bold('Recker Mock DNS Server')} │
@@ -465,7 +433,7 @@ export function registerServeCommand(program) {
465
433
  │ Press ${colors.bold('Ctrl+C')} to stop │
466
434
  └─────────────────────────────────────────────┘`));
467
435
  server.on('query', (query) => {
468
- console.log(colors.gray(`${new Date().toISOString()} `) + colors.cyan(query.type.padEnd(6)) + ` ${query.domain}`);
436
+ console.log(colors.gray(`${new Date().toISOString()} `) + colors.cyan(query.type.padEnd(6)) + ` ${query.name}`);
469
437
  });
470
438
  process.on('SIGINT', async () => {
471
439
  console.log(colors.yellow('\nShutting down...'));
@@ -497,15 +465,11 @@ export function registerServeCommand(program) {
497
465
  .example('rek serve whois', 'Start on port 4343')
498
466
  .action(async (args, cmdObj) => {
499
467
  const options = cmdObj.opts ? cmdObj.opts() : {};
500
- const { MockWhoisServer } = await import('../../testing/mock-whois-server.js');
468
+ const { createMockWhoisServer } = await import('../../testing/index.js');
501
469
  const port = options.port || 4343;
502
470
  const host = options.host || '127.0.0.1';
503
471
  const delay = options.delay || 0;
504
- const server = await MockWhoisServer.create({
505
- port,
506
- host,
507
- delay,
508
- });
472
+ const server = await createMockWhoisServer({ port, host, responseDelay: delay });
509
473
  console.log(colors.green(`
510
474
  ┌─────────────────────────────────────────────┐
511
475
  │ ${colors.bold('Recker Mock WHOIS Server')} │
@@ -550,17 +514,12 @@ export function registerServeCommand(program) {
550
514
  .example('rek serve telnet', 'Start on port 2323')
551
515
  .action(async (args, cmdObj) => {
552
516
  const options = cmdObj.opts ? cmdObj.opts() : {};
553
- const { MockTelnetServer } = await import('../../testing/mock-telnet-server.js');
517
+ const { createMockTelnetServer } = await import('../../testing/index.js');
554
518
  const port = options.port || 2323;
555
519
  const host = options.host || '127.0.0.1';
556
520
  const delay = options.delay || 0;
557
521
  const echo = !options['no-echo'];
558
- const server = await MockTelnetServer.create({
559
- port,
560
- host,
561
- echo,
562
- delay,
563
- });
522
+ const server = await createMockTelnetServer({ port, host, responseDelay: delay });
564
523
  console.log(colors.green(`
565
524
  ┌─────────────────────────────────────────────┐
566
525
  │ ${colors.bold('Recker Mock Telnet Server')} │
@@ -620,21 +579,14 @@ export function registerServeCommand(program) {
620
579
  .example('rek serve ftp -u admin -P secret', 'Custom credentials')
621
580
  .action(async (args, cmdObj) => {
622
581
  const options = cmdObj.opts ? cmdObj.opts() : {};
623
- const { MockFtpServer } = await import('../../testing/mock-ftp-server.js');
582
+ const { createMockFtpServer } = await import('../../testing/index.js');
624
583
  const port = options.port || 2121;
625
584
  const host = options.host || '127.0.0.1';
626
585
  const username = options.username || 'user';
627
586
  const password = options.password || 'pass';
628
587
  const delay = options.delay || 0;
629
588
  const anonymous = !options['no-anonymous'];
630
- const server = await MockFtpServer.create({
631
- port,
632
- host,
633
- username,
634
- password,
635
- anonymous,
636
- delay,
637
- });
589
+ const server = await createMockFtpServer({ port, host });
638
590
  console.log(colors.green(`
639
591
  ┌─────────────────────────────────────────────┐
640
592
  │ ${colors.bold('Recker Mock FTP Server')} │
@@ -688,17 +640,16 @@ export function registerServeCommand(program) {
688
640
  .example('curl -x http://localhost:8888 https://api.github.com/users', 'Test with curl')
689
641
  .action(async (args, cmdObj) => {
690
642
  const options = cmdObj.opts ? cmdObj.opts() : {};
691
- const { MockProxyServer } = await import('../../testing/mock-proxy-server.js');
643
+ const { createMockProxyServer } = await import('../../testing/index.js');
692
644
  const port = options.port || 8888;
693
645
  const host = options.host || '127.0.0.1';
694
646
  const mode = options.intercept ? 'intercept' : 'forward';
695
647
  const logPayloads = options['log-payloads'] || false;
696
648
  const verbose = options.verbose || false;
697
- const server = await MockProxyServer.create({
649
+ const server = await createMockProxyServer({
698
650
  port,
699
651
  host,
700
652
  mode: mode,
701
- verbose,
702
653
  intercept: mode === 'intercept' ? { logPayloads } : undefined,
703
654
  });
704
655
  const modeLabel = mode === 'intercept' ? 'Intercept (MITM)' : 'Forward (Tunnel)';
@@ -717,49 +668,42 @@ export function registerServeCommand(program) {
717
668
  if (mode === 'intercept') {
718
669
  console.log(colors.yellow('\n⚠️ MITM mode active - clients must trust the proxy CA certificate'));
719
670
  }
720
- server.on('request', (req) => {
721
- const method = req.method.padEnd(7);
722
- const status = req.isHttps ? colors.cyan('HTTPS') : colors.gray('HTTP ');
723
- const target = `${req.targetHost}:${req.targetPort}`;
671
+ server.on('request', ({ request, response }) => {
672
+ const method = (request.method ?? 'GET').padEnd(7);
673
+ const url = request.url ?? '';
674
+ const isHttps = url.startsWith('https');
675
+ const proto = isHttps ? colors.cyan('HTTPS') : colors.gray('HTTP ');
676
+ const pathname = url ? (() => { try {
677
+ return new URL(url).pathname;
678
+ }
679
+ catch {
680
+ return url;
681
+ } })() : '';
724
682
  console.log(colors.gray(`${new Date().toISOString()} `) +
725
683
  colors.green(method) +
726
- status + ' ' +
727
- colors.cyan(target) +
728
- (req.method !== 'CONNECT' ? ` ${colors.gray(new URL(req.url).pathname)}` : ''));
729
- });
730
- server.on('response', (res) => {
731
- const statusColor = res.statusCode >= 500 ? colors.red :
732
- res.statusCode >= 400 ? colors.yellow :
733
- res.statusCode >= 300 ? colors.cyan :
734
- colors.green;
735
- console.log(colors.gray(`${new Date().toISOString()} `) +
736
- statusColor(`← ${res.statusCode}`) +
737
- colors.gray(` ${res.latency}ms`) +
738
- (res.size > 0 ? colors.gray(` ${formatBytes(res.size)}`) : ''));
684
+ proto + ' ' +
685
+ colors.cyan(url.replace(/^https?:\/\/[^/]+/, '').slice(0, 40) || '/') +
686
+ (response?.statusCode ? ` ${colors.gray(`← ${response.statusCode}`)}` : ''));
739
687
  });
740
688
  server.on('error', (err) => {
741
689
  console.log(colors.gray(`${new Date().toISOString()} `) +
742
- colors.red(`✗ ${err.type}: ${err.message}`) +
743
- (err.targetHost ? colors.gray(` → ${err.targetHost}:${err.targetPort}`) : ''));
690
+ colors.red(`✗ ${err.message ?? err}`));
744
691
  });
745
692
  let statsInterval;
746
693
  if (verbose) {
747
694
  statsInterval = setInterval(() => {
748
- const stats = server.stats;
695
+ const stats = server.statistics;
749
696
  console.log(colors.gray(`\n[stats] ${stats.totalRequests} req | ` +
750
- `${stats.successCount} ok | ${stats.errorCount} err | ` +
751
- `${formatBytes(stats.bytesIn)} in | ${formatBytes(stats.bytesOut)} out | ` +
752
- `${stats.avgLatency}ms avg | ${stats.requestsPerSecond} rps\n`));
697
+ `${formatBytes(stats.totalBytesTransferred)} transferred\n`));
753
698
  }, 30000);
754
699
  }
755
700
  process.on('SIGINT', async () => {
756
701
  console.log(colors.yellow('\nShutting down...'));
757
702
  if (statsInterval)
758
703
  clearInterval(statsInterval);
759
- const stats = server.stats;
704
+ const stats = server.statistics;
760
705
  console.log(colors.gray(`Final stats: ${stats.totalRequests} requests | ` +
761
- `${stats.successCount} success | ${stats.errorCount} errors | ` +
762
- `${formatBytes(stats.bytesIn + stats.bytesOut)} transferred`));
706
+ `${formatBytes(stats.totalBytesTransferred)} transferred`));
763
707
  await server.stop();
764
708
  process.exit(0);
765
709
  });