@qodalis/cli-speed-test 2.0.0-beta.1 → 2.0.0-beta.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qodalis/cli-speed-test",
3
- "version": "2.0.0-beta.1",
3
+ "version": "2.0.0-beta.11",
4
4
  "description": "@qodalis/cli extension for running network speed tests.",
5
5
  "author": "Nicolae Lupei, Qodalis Solutions",
6
6
  "license": "MIT",
@@ -17,10 +17,10 @@
17
17
  "network",
18
18
  "bandwidth"
19
19
  ],
20
- "umd": "./umd/index.js",
21
- "unpkg": "./umd/index.js",
20
+ "umd": "./umd/index.global.js",
21
+ "unpkg": "./umd/index.global.js",
22
22
  "dependencies": {
23
- "@qodalis/cli-core": "2.0.0-beta.1"
23
+ "@qodalis/cli-core": "2.0.0-beta.11"
24
24
  },
25
25
  "sideEffects": false,
26
26
  "main": "./public-api.js",
package/public-api.js CHANGED
@@ -5,7 +5,7 @@ var cliCore = require('@qodalis/cli-core');
5
5
  // src/lib/processors/cli-speed-test-command-processor.ts
6
6
 
7
7
  // src/lib/version.ts
8
- var LIBRARY_VERSION = "2.0.0-beta.1";
8
+ var LIBRARY_VERSION = "2.0.0-beta.11";
9
9
  var API_VERSION = 2;
10
10
 
11
11
  // src/lib/processors/cli-speed-test-command-processor.ts
package/public-api.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../../packages/plugins/speed-test/src/lib/version.ts","../../packages/plugins/speed-test/src/lib/processors/cli-speed-test-command-processor.ts","../../packages/plugins/speed-test/src/public-api.ts"],"names":["DefaultLibraryAuthor","CliForegroundColor","avgSpeed"],"mappings":"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","file":"public-api.js","sourcesContent":["\n// Automatically generated during build\nexport const LIBRARY_VERSION = '2.0.0-beta.1';\nexport const API_VERSION = 2;\n ","import {\n CliForegroundColor,\n CliProcessorMetadata,\n DefaultLibraryAuthor,\n CliProcessCommand,\n ICliCommandProcessor,\n ICliExecutionContext,\n} from '@qodalis/cli-core';\nimport { LIBRARY_VERSION } from '../version';\n\n/**\n * Cloudflare speed test endpoints — edge-served, CORS-enabled, fast worldwide.\n * The `bytes` parameter controls the download size.\n */\nconst DEFAULT_DOWNLOAD_URL =\n 'https://speed.cloudflare.com/__down?bytes=26214400';\n\nconst DEFAULT_UPLOAD_URL = 'https://speed.cloudflare.com/__up';\n\n/** Size of upload test payload in bytes (10 MB). */\nconst UPLOAD_SIZE = 10 * 1024 * 1024;\n\n/** Format bytes/second as a human-readable speed string. */\nfunction formatSpeed(bytesPerSecond: number): string {\n const mbps = (bytesPerSecond * 8) / (1024 * 1024);\n if (mbps >= 1) return `${mbps.toFixed(2)} Mbps`;\n const kbps = (bytesPerSecond * 8) / 1024;\n if (kbps >= 1) return `${kbps.toFixed(1)} Kbps`;\n return `${(bytesPerSecond * 8).toFixed(0)} bps`;\n}\n\n/** Format bytes as a human-readable size string. */\nfunction formatBytes(bytes: number): string {\n if (bytes >= 1024 * 1024)\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${bytes} B`;\n}\n\nexport class CliSpeedTestCommandProcessor implements ICliCommandProcessor {\n command = 'speed-test';\n\n description = 'Run an internet speed test';\n\n author = DefaultLibraryAuthor;\n\n version = LIBRARY_VERSION;\n\n processors?: ICliCommandProcessor[] = [];\n\n parameters = [\n {\n name: 'download-url',\n description: 'Custom URL for the download test',\n type: 'string' as const,\n required: false,\n },\n {\n name: 'upload-url',\n description: 'Custom URL for the upload test',\n type: 'string' as const,\n required: false,\n },\n {\n name: 'download-only',\n description: 'Only run the download test',\n type: 'boolean' as const,\n required: false,\n },\n {\n name: 'upload-only',\n description: 'Only run the upload test',\n type: 'boolean' as const,\n required: false,\n },\n ];\n\n metadata?: CliProcessorMetadata = {\n icon: '🚀',\n requiredCoreVersion: '>=2.0.0 <3.0.0',\n requiredCliVersion: '>=2.0.0 <3.0.0',\n };\n\n constructor() {\n this.processors = [\n {\n command: 'run',\n description: 'Run the internet speed test',\n processCommand: async (command, context) => {\n await this.runSpeedTest(command, context);\n },\n },\n ];\n }\n\n async processCommand(\n command: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n await this.runSpeedTest(command, context);\n }\n\n writeDescription(context: ICliExecutionContext): void {\n const { writer } = context;\n writer.writeln(this.description);\n writer.writeln();\n writer.writeln('Usage:');\n writer.writeln(\n ` ${writer.wrapInColor('speed-test', CliForegroundColor.Cyan)} Run download & upload test`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --download-only', CliForegroundColor.Cyan)} Download only`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --upload-only', CliForegroundColor.Cyan)} Upload only`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --download-url=<url>', CliForegroundColor.Cyan)} Custom download URL`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --upload-url=<url>', CliForegroundColor.Cyan)} Custom upload URL`,\n );\n writer.writeln();\n writer.writeln(\n `Press ${writer.wrapInColor('Ctrl+C', CliForegroundColor.Yellow)} to abort the test`,\n );\n }\n\n private async runSpeedTest(\n command: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n const downloadOnly = !!command.args['download-only'];\n const uploadOnly = !!command.args['upload-only'];\n\n const controller = new AbortController();\n const subscription = context.onAbort.subscribe(() => {\n controller.abort();\n });\n\n const results: { download?: number; upload?: number } = {};\n\n try {\n if (!uploadOnly) {\n const downloadUrl =\n (command.args['download-url'] as string) ||\n DEFAULT_DOWNLOAD_URL;\n results.download = await this.testDownload(\n downloadUrl,\n context,\n controller.signal,\n );\n }\n\n if (!downloadOnly) {\n const uploadUrl =\n (command.args['upload-url'] as string) ||\n DEFAULT_UPLOAD_URL;\n results.upload = await this.testUpload(\n uploadUrl,\n context,\n controller.signal,\n );\n }\n\n this.printSummary(results, context);\n } catch (error: any) {\n if (error.name === 'AbortError' || controller.signal.aborted) {\n context.writer.writeWarning('Speed test aborted');\n } else {\n context.writer.writeError(\n `Speed test failed: ${error.message || error}`,\n );\n }\n } finally {\n subscription.unsubscribe();\n }\n }\n\n private async testDownload(\n url: string,\n context: ICliExecutionContext,\n signal: AbortSignal,\n ): Promise<number> {\n context.writer.writeln();\n\n const progressBar = context.progressBar;\n const spinner = context.spinner;\n\n // Show spinner while waiting for connection (DNS, TLS, TTFB)\n spinner?.show('Connecting...');\n\n const response = await fetch(url, { signal });\n\n if (!response.ok) {\n spinner?.hide();\n throw new Error(`Download failed: HTTP ${response.status}`);\n }\n\n spinner?.hide();\n context.writer.writeInfo('Running download test...');\n\n const contentLength = parseInt(\n response.headers.get('content-length') || '0',\n 10,\n );\n\n progressBar.show();\n progressBar.update(0);\n\n // Start timing AFTER connection is established (exclude TTFB)\n const startTime = performance.now();\n let totalBytes = 0;\n\n const reader = response.body!.getReader();\n let lastUpdateTime = startTime;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n totalBytes += value.length;\n\n const now = performance.now();\n if (now - lastUpdateTime > 250) {\n lastUpdateTime = now;\n const elapsedSec = (now - startTime) / 1000;\n const avgSpeed = totalBytes / elapsedSec;\n\n if (contentLength > 0) {\n const pct = Math.min(\n (totalBytes / contentLength) * 100,\n 100,\n );\n progressBar.update(pct);\n progressBar.setText(\n `${formatSpeed(avgSpeed)} | ${formatBytes(totalBytes)} / ${formatBytes(contentLength)}`,\n );\n } else {\n progressBar.setText(\n `${formatSpeed(avgSpeed)} | ${formatBytes(totalBytes)}`,\n );\n }\n }\n }\n\n progressBar.complete();\n progressBar.hide();\n\n const totalSec = (performance.now() - startTime) / 1000;\n const avgSpeed = totalBytes / totalSec;\n\n context.writer.writeSuccess(\n `Download: ${formatSpeed(avgSpeed)} (${formatBytes(totalBytes)} in ${totalSec.toFixed(1)}s)`,\n );\n\n return avgSpeed;\n }\n\n private async testUpload(\n url: string,\n context: ICliExecutionContext,\n signal: AbortSignal,\n ): Promise<number> {\n context.writer.writeln();\n context.writer.writeInfo(\n `Running upload test (${formatBytes(UPLOAD_SIZE)})...`,\n );\n\n const progressBar = context.progressBar;\n progressBar.show();\n progressBar.update(0);\n\n // Fill with pseudo-random data to prevent compression from skewing results.\n // crypto.getRandomValues() is limited to 65536 bytes per call.\n const payload = new Uint8Array(UPLOAD_SIZE);\n const chunkSize = 65536;\n for (let offset = 0; offset < UPLOAD_SIZE; offset += chunkSize) {\n const length = Math.min(chunkSize, UPLOAD_SIZE - offset);\n crypto.getRandomValues(new Uint8Array(payload.buffer, offset, length));\n }\n\n // Use multiple smaller fetch() calls to measure upload speed.\n // A single large POST to Cloudflare's __up may be blocked by CORS\n // when custom headers trigger a preflight. Chunking also lets us\n // report progress without XHR.\n const CHUNK = 1024 * 1024; // 1 MB per request\n const totalChunks = Math.ceil(UPLOAD_SIZE / CHUNK);\n let uploaded = 0;\n const startTime = performance.now();\n\n for (let i = 0; i < totalChunks; i++) {\n if (signal.aborted) {\n throw new DOMException('Upload aborted', 'AbortError');\n }\n\n const start = i * CHUNK;\n const end = Math.min(start + CHUNK, UPLOAD_SIZE);\n const chunk = payload.slice(start, end);\n\n await fetch(url, {\n method: 'POST',\n body: chunk,\n signal,\n });\n\n uploaded += chunk.length;\n\n const elapsed = (performance.now() - startTime) / 1000;\n const speed = uploaded / elapsed;\n const pct = (uploaded / UPLOAD_SIZE) * 100;\n progressBar.update(pct);\n progressBar.setText(\n `${formatSpeed(speed)} | ${formatBytes(uploaded)} / ${formatBytes(UPLOAD_SIZE)}`,\n );\n }\n\n const totalSec = (performance.now() - startTime) / 1000;\n const avgSpeed = UPLOAD_SIZE / totalSec;\n\n progressBar.complete();\n progressBar.hide();\n\n context.writer.writeSuccess(\n `Upload: ${formatSpeed(avgSpeed)} (${formatBytes(UPLOAD_SIZE)} in ${totalSec.toFixed(1)}s)`,\n );\n\n return avgSpeed;\n }\n\n private printSummary(\n results: { download?: number; upload?: number },\n context: ICliExecutionContext,\n ): void {\n context.writer.writeln();\n\n const headers = ['Test', 'Speed'];\n const rows: string[][] = [];\n\n if (results.download !== undefined) {\n rows.push(['Download', formatSpeed(results.download)]);\n }\n if (results.upload !== undefined) {\n rows.push(['Upload', formatSpeed(results.upload)]);\n }\n\n context.writer.writeTable(headers, rows);\n context.process.output(results);\n }\n}\n","/*\n * Public API Surface of speed-test\n */\n\nexport * from './lib/processors/cli-speed-test-command-processor';\n\nimport { ICliModule } from '@qodalis/cli-core';\nimport { CliSpeedTestCommandProcessor } from './lib/processors/cli-speed-test-command-processor';\nimport { API_VERSION } from './lib/version';\n\nexport const speedTestModule: ICliModule = {\n apiVersion: API_VERSION,\n name: '@qodalis/cli-speed-test',\n processors: [new CliSpeedTestCommandProcessor()],\n translations: {\n es: { 'cli.speed-test.description': 'Ejecutar una prueba de velocidad de internet' },\n fr: { 'cli.speed-test.description': 'Lancer un test de débit internet' },\n de: { 'cli.speed-test.description': 'Internet-Geschwindigkeitstest durchführen' },\n pt: { 'cli.speed-test.description': 'Executar um teste de velocidade de internet' },\n it: { 'cli.speed-test.description': 'Eseguire un test di velocità internet' },\n ja: { 'cli.speed-test.description': 'インターネット速度テストを実行' },\n ko: { 'cli.speed-test.description': '인터넷 속도 테스트 실행' },\n zh: { 'cli.speed-test.description': '运行网络速度测试' },\n ru: { 'cli.speed-test.description': 'Запустить тест скорости интернета' },\n ro: { 'cli.speed-test.description': 'Rulează un test de viteză a internetului' },\n },\n};\n"]}
1
+ {"version":3,"sources":["../../packages/plugins/speed-test/src/lib/version.ts","../../packages/plugins/speed-test/src/lib/processors/cli-speed-test-command-processor.ts","../../packages/plugins/speed-test/src/public-api.ts"],"names":["DefaultLibraryAuthor","CliForegroundColor","avgSpeed"],"mappings":"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","file":"public-api.js","sourcesContent":["\n// Automatically generated during build\nexport const LIBRARY_VERSION = '2.0.0-beta.11';\nexport const API_VERSION = 2;\n ","import {\n CliForegroundColor,\n CliProcessorMetadata,\n DefaultLibraryAuthor,\n CliProcessCommand,\n ICliCommandProcessor,\n ICliExecutionContext,\n} from '@qodalis/cli-core';\nimport { LIBRARY_VERSION } from '../version';\n\n/**\n * Cloudflare speed test endpoints — edge-served, CORS-enabled, fast worldwide.\n * The `bytes` parameter controls the download size.\n */\nconst DEFAULT_DOWNLOAD_URL =\n 'https://speed.cloudflare.com/__down?bytes=26214400';\n\nconst DEFAULT_UPLOAD_URL = 'https://speed.cloudflare.com/__up';\n\n/** Size of upload test payload in bytes (10 MB). */\nconst UPLOAD_SIZE = 10 * 1024 * 1024;\n\n/** Format bytes/second as a human-readable speed string. */\nfunction formatSpeed(bytesPerSecond: number): string {\n const mbps = (bytesPerSecond * 8) / (1024 * 1024);\n if (mbps >= 1) return `${mbps.toFixed(2)} Mbps`;\n const kbps = (bytesPerSecond * 8) / 1024;\n if (kbps >= 1) return `${kbps.toFixed(1)} Kbps`;\n return `${(bytesPerSecond * 8).toFixed(0)} bps`;\n}\n\n/** Format bytes as a human-readable size string. */\nfunction formatBytes(bytes: number): string {\n if (bytes >= 1024 * 1024)\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${bytes} B`;\n}\n\nexport class CliSpeedTestCommandProcessor implements ICliCommandProcessor {\n command = 'speed-test';\n\n description = 'Run an internet speed test';\n\n author = DefaultLibraryAuthor;\n\n version = LIBRARY_VERSION;\n\n processors?: ICliCommandProcessor[] = [];\n\n parameters = [\n {\n name: 'download-url',\n description: 'Custom URL for the download test',\n type: 'string' as const,\n required: false,\n },\n {\n name: 'upload-url',\n description: 'Custom URL for the upload test',\n type: 'string' as const,\n required: false,\n },\n {\n name: 'download-only',\n description: 'Only run the download test',\n type: 'boolean' as const,\n required: false,\n },\n {\n name: 'upload-only',\n description: 'Only run the upload test',\n type: 'boolean' as const,\n required: false,\n },\n ];\n\n metadata?: CliProcessorMetadata = {\n icon: '🚀',\n requiredCoreVersion: '>=2.0.0 <3.0.0',\n requiredCliVersion: '>=2.0.0 <3.0.0',\n };\n\n constructor() {\n this.processors = [\n {\n command: 'run',\n description: 'Run the internet speed test',\n processCommand: async (command, context) => {\n await this.runSpeedTest(command, context);\n },\n },\n ];\n }\n\n async processCommand(\n command: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n await this.runSpeedTest(command, context);\n }\n\n writeDescription(context: ICliExecutionContext): void {\n const { writer } = context;\n writer.writeln(this.description);\n writer.writeln();\n writer.writeln('Usage:');\n writer.writeln(\n ` ${writer.wrapInColor('speed-test', CliForegroundColor.Cyan)} Run download & upload test`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --download-only', CliForegroundColor.Cyan)} Download only`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --upload-only', CliForegroundColor.Cyan)} Upload only`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --download-url=<url>', CliForegroundColor.Cyan)} Custom download URL`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --upload-url=<url>', CliForegroundColor.Cyan)} Custom upload URL`,\n );\n writer.writeln();\n writer.writeln(\n `Press ${writer.wrapInColor('Ctrl+C', CliForegroundColor.Yellow)} to abort the test`,\n );\n }\n\n private async runSpeedTest(\n command: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n const downloadOnly = !!command.args['download-only'];\n const uploadOnly = !!command.args['upload-only'];\n\n const controller = new AbortController();\n const subscription = context.onAbort.subscribe(() => {\n controller.abort();\n });\n\n const results: { download?: number; upload?: number } = {};\n\n try {\n if (!uploadOnly) {\n const downloadUrl =\n (command.args['download-url'] as string) ||\n DEFAULT_DOWNLOAD_URL;\n results.download = await this.testDownload(\n downloadUrl,\n context,\n controller.signal,\n );\n }\n\n if (!downloadOnly) {\n const uploadUrl =\n (command.args['upload-url'] as string) ||\n DEFAULT_UPLOAD_URL;\n results.upload = await this.testUpload(\n uploadUrl,\n context,\n controller.signal,\n );\n }\n\n this.printSummary(results, context);\n } catch (error: any) {\n if (error.name === 'AbortError' || controller.signal.aborted) {\n context.writer.writeWarning('Speed test aborted');\n } else {\n context.writer.writeError(\n `Speed test failed: ${error.message || error}`,\n );\n }\n } finally {\n subscription.unsubscribe();\n }\n }\n\n private async testDownload(\n url: string,\n context: ICliExecutionContext,\n signal: AbortSignal,\n ): Promise<number> {\n context.writer.writeln();\n\n const progressBar = context.progressBar;\n const spinner = context.spinner;\n\n // Show spinner while waiting for connection (DNS, TLS, TTFB)\n spinner?.show('Connecting...');\n\n const response = await fetch(url, { signal });\n\n if (!response.ok) {\n spinner?.hide();\n throw new Error(`Download failed: HTTP ${response.status}`);\n }\n\n spinner?.hide();\n context.writer.writeInfo('Running download test...');\n\n const contentLength = parseInt(\n response.headers.get('content-length') || '0',\n 10,\n );\n\n progressBar.show();\n progressBar.update(0);\n\n // Start timing AFTER connection is established (exclude TTFB)\n const startTime = performance.now();\n let totalBytes = 0;\n\n const reader = response.body!.getReader();\n let lastUpdateTime = startTime;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n totalBytes += value.length;\n\n const now = performance.now();\n if (now - lastUpdateTime > 250) {\n lastUpdateTime = now;\n const elapsedSec = (now - startTime) / 1000;\n const avgSpeed = totalBytes / elapsedSec;\n\n if (contentLength > 0) {\n const pct = Math.min(\n (totalBytes / contentLength) * 100,\n 100,\n );\n progressBar.update(pct);\n progressBar.setText(\n `${formatSpeed(avgSpeed)} | ${formatBytes(totalBytes)} / ${formatBytes(contentLength)}`,\n );\n } else {\n progressBar.setText(\n `${formatSpeed(avgSpeed)} | ${formatBytes(totalBytes)}`,\n );\n }\n }\n }\n\n progressBar.complete();\n progressBar.hide();\n\n const totalSec = (performance.now() - startTime) / 1000;\n const avgSpeed = totalBytes / totalSec;\n\n context.writer.writeSuccess(\n `Download: ${formatSpeed(avgSpeed)} (${formatBytes(totalBytes)} in ${totalSec.toFixed(1)}s)`,\n );\n\n return avgSpeed;\n }\n\n private async testUpload(\n url: string,\n context: ICliExecutionContext,\n signal: AbortSignal,\n ): Promise<number> {\n context.writer.writeln();\n context.writer.writeInfo(\n `Running upload test (${formatBytes(UPLOAD_SIZE)})...`,\n );\n\n const progressBar = context.progressBar;\n progressBar.show();\n progressBar.update(0);\n\n // Fill with pseudo-random data to prevent compression from skewing results.\n // crypto.getRandomValues() is limited to 65536 bytes per call.\n const payload = new Uint8Array(UPLOAD_SIZE);\n const chunkSize = 65536;\n for (let offset = 0; offset < UPLOAD_SIZE; offset += chunkSize) {\n const length = Math.min(chunkSize, UPLOAD_SIZE - offset);\n crypto.getRandomValues(new Uint8Array(payload.buffer, offset, length));\n }\n\n // Use multiple smaller fetch() calls to measure upload speed.\n // A single large POST to Cloudflare's __up may be blocked by CORS\n // when custom headers trigger a preflight. Chunking also lets us\n // report progress without XHR.\n const CHUNK = 1024 * 1024; // 1 MB per request\n const totalChunks = Math.ceil(UPLOAD_SIZE / CHUNK);\n let uploaded = 0;\n const startTime = performance.now();\n\n for (let i = 0; i < totalChunks; i++) {\n if (signal.aborted) {\n throw new DOMException('Upload aborted', 'AbortError');\n }\n\n const start = i * CHUNK;\n const end = Math.min(start + CHUNK, UPLOAD_SIZE);\n const chunk = payload.slice(start, end);\n\n await fetch(url, {\n method: 'POST',\n body: chunk,\n signal,\n });\n\n uploaded += chunk.length;\n\n const elapsed = (performance.now() - startTime) / 1000;\n const speed = uploaded / elapsed;\n const pct = (uploaded / UPLOAD_SIZE) * 100;\n progressBar.update(pct);\n progressBar.setText(\n `${formatSpeed(speed)} | ${formatBytes(uploaded)} / ${formatBytes(UPLOAD_SIZE)}`,\n );\n }\n\n const totalSec = (performance.now() - startTime) / 1000;\n const avgSpeed = UPLOAD_SIZE / totalSec;\n\n progressBar.complete();\n progressBar.hide();\n\n context.writer.writeSuccess(\n `Upload: ${formatSpeed(avgSpeed)} (${formatBytes(UPLOAD_SIZE)} in ${totalSec.toFixed(1)}s)`,\n );\n\n return avgSpeed;\n }\n\n private printSummary(\n results: { download?: number; upload?: number },\n context: ICliExecutionContext,\n ): void {\n context.writer.writeln();\n\n const headers = ['Test', 'Speed'];\n const rows: string[][] = [];\n\n if (results.download !== undefined) {\n rows.push(['Download', formatSpeed(results.download)]);\n }\n if (results.upload !== undefined) {\n rows.push(['Upload', formatSpeed(results.upload)]);\n }\n\n context.writer.writeTable(headers, rows);\n context.process.output(results);\n }\n}\n","/*\n * Public API Surface of speed-test\n */\n\nexport * from './lib/processors/cli-speed-test-command-processor';\n\nimport { ICliModule } from '@qodalis/cli-core';\nimport { CliSpeedTestCommandProcessor } from './lib/processors/cli-speed-test-command-processor';\nimport { API_VERSION } from './lib/version';\n\nexport const speedTestModule: ICliModule = {\n apiVersion: API_VERSION,\n name: '@qodalis/cli-speed-test',\n processors: [new CliSpeedTestCommandProcessor()],\n translations: {\n es: { 'cli.speed-test.description': 'Ejecutar una prueba de velocidad de internet' },\n fr: { 'cli.speed-test.description': 'Lancer un test de débit internet' },\n de: { 'cli.speed-test.description': 'Internet-Geschwindigkeitstest durchführen' },\n pt: { 'cli.speed-test.description': 'Executar um teste de velocidade de internet' },\n it: { 'cli.speed-test.description': 'Eseguire un test di velocità internet' },\n ja: { 'cli.speed-test.description': 'インターネット速度テストを実行' },\n ko: { 'cli.speed-test.description': '인터넷 속도 테스트 실행' },\n zh: { 'cli.speed-test.description': '运行网络速度测试' },\n ru: { 'cli.speed-test.description': 'Запустить тест скорости интернета' },\n ro: { 'cli.speed-test.description': 'Rulează un test de viteză a internetului' },\n },\n};\n"]}
package/public-api.mjs CHANGED
@@ -3,7 +3,7 @@ import { DefaultLibraryAuthor, CliForegroundColor } from '@qodalis/cli-core';
3
3
  // src/lib/processors/cli-speed-test-command-processor.ts
4
4
 
5
5
  // src/lib/version.ts
6
- var LIBRARY_VERSION = "2.0.0-beta.1";
6
+ var LIBRARY_VERSION = "2.0.0-beta.11";
7
7
  var API_VERSION = 2;
8
8
 
9
9
  // src/lib/processors/cli-speed-test-command-processor.ts
@@ -1 +1 @@
1
- {"version":3,"sources":["../../packages/plugins/speed-test/src/lib/version.ts","../../packages/plugins/speed-test/src/lib/processors/cli-speed-test-command-processor.ts","../../packages/plugins/speed-test/src/public-api.ts"],"names":["avgSpeed"],"mappings":"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","file":"public-api.mjs","sourcesContent":["\n// Automatically generated during build\nexport const LIBRARY_VERSION = '2.0.0-beta.1';\nexport const API_VERSION = 2;\n ","import {\n CliForegroundColor,\n CliProcessorMetadata,\n DefaultLibraryAuthor,\n CliProcessCommand,\n ICliCommandProcessor,\n ICliExecutionContext,\n} from '@qodalis/cli-core';\nimport { LIBRARY_VERSION } from '../version';\n\n/**\n * Cloudflare speed test endpoints — edge-served, CORS-enabled, fast worldwide.\n * The `bytes` parameter controls the download size.\n */\nconst DEFAULT_DOWNLOAD_URL =\n 'https://speed.cloudflare.com/__down?bytes=26214400';\n\nconst DEFAULT_UPLOAD_URL = 'https://speed.cloudflare.com/__up';\n\n/** Size of upload test payload in bytes (10 MB). */\nconst UPLOAD_SIZE = 10 * 1024 * 1024;\n\n/** Format bytes/second as a human-readable speed string. */\nfunction formatSpeed(bytesPerSecond: number): string {\n const mbps = (bytesPerSecond * 8) / (1024 * 1024);\n if (mbps >= 1) return `${mbps.toFixed(2)} Mbps`;\n const kbps = (bytesPerSecond * 8) / 1024;\n if (kbps >= 1) return `${kbps.toFixed(1)} Kbps`;\n return `${(bytesPerSecond * 8).toFixed(0)} bps`;\n}\n\n/** Format bytes as a human-readable size string. */\nfunction formatBytes(bytes: number): string {\n if (bytes >= 1024 * 1024)\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${bytes} B`;\n}\n\nexport class CliSpeedTestCommandProcessor implements ICliCommandProcessor {\n command = 'speed-test';\n\n description = 'Run an internet speed test';\n\n author = DefaultLibraryAuthor;\n\n version = LIBRARY_VERSION;\n\n processors?: ICliCommandProcessor[] = [];\n\n parameters = [\n {\n name: 'download-url',\n description: 'Custom URL for the download test',\n type: 'string' as const,\n required: false,\n },\n {\n name: 'upload-url',\n description: 'Custom URL for the upload test',\n type: 'string' as const,\n required: false,\n },\n {\n name: 'download-only',\n description: 'Only run the download test',\n type: 'boolean' as const,\n required: false,\n },\n {\n name: 'upload-only',\n description: 'Only run the upload test',\n type: 'boolean' as const,\n required: false,\n },\n ];\n\n metadata?: CliProcessorMetadata = {\n icon: '🚀',\n requiredCoreVersion: '>=2.0.0 <3.0.0',\n requiredCliVersion: '>=2.0.0 <3.0.0',\n };\n\n constructor() {\n this.processors = [\n {\n command: 'run',\n description: 'Run the internet speed test',\n processCommand: async (command, context) => {\n await this.runSpeedTest(command, context);\n },\n },\n ];\n }\n\n async processCommand(\n command: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n await this.runSpeedTest(command, context);\n }\n\n writeDescription(context: ICliExecutionContext): void {\n const { writer } = context;\n writer.writeln(this.description);\n writer.writeln();\n writer.writeln('Usage:');\n writer.writeln(\n ` ${writer.wrapInColor('speed-test', CliForegroundColor.Cyan)} Run download & upload test`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --download-only', CliForegroundColor.Cyan)} Download only`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --upload-only', CliForegroundColor.Cyan)} Upload only`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --download-url=<url>', CliForegroundColor.Cyan)} Custom download URL`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --upload-url=<url>', CliForegroundColor.Cyan)} Custom upload URL`,\n );\n writer.writeln();\n writer.writeln(\n `Press ${writer.wrapInColor('Ctrl+C', CliForegroundColor.Yellow)} to abort the test`,\n );\n }\n\n private async runSpeedTest(\n command: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n const downloadOnly = !!command.args['download-only'];\n const uploadOnly = !!command.args['upload-only'];\n\n const controller = new AbortController();\n const subscription = context.onAbort.subscribe(() => {\n controller.abort();\n });\n\n const results: { download?: number; upload?: number } = {};\n\n try {\n if (!uploadOnly) {\n const downloadUrl =\n (command.args['download-url'] as string) ||\n DEFAULT_DOWNLOAD_URL;\n results.download = await this.testDownload(\n downloadUrl,\n context,\n controller.signal,\n );\n }\n\n if (!downloadOnly) {\n const uploadUrl =\n (command.args['upload-url'] as string) ||\n DEFAULT_UPLOAD_URL;\n results.upload = await this.testUpload(\n uploadUrl,\n context,\n controller.signal,\n );\n }\n\n this.printSummary(results, context);\n } catch (error: any) {\n if (error.name === 'AbortError' || controller.signal.aborted) {\n context.writer.writeWarning('Speed test aborted');\n } else {\n context.writer.writeError(\n `Speed test failed: ${error.message || error}`,\n );\n }\n } finally {\n subscription.unsubscribe();\n }\n }\n\n private async testDownload(\n url: string,\n context: ICliExecutionContext,\n signal: AbortSignal,\n ): Promise<number> {\n context.writer.writeln();\n\n const progressBar = context.progressBar;\n const spinner = context.spinner;\n\n // Show spinner while waiting for connection (DNS, TLS, TTFB)\n spinner?.show('Connecting...');\n\n const response = await fetch(url, { signal });\n\n if (!response.ok) {\n spinner?.hide();\n throw new Error(`Download failed: HTTP ${response.status}`);\n }\n\n spinner?.hide();\n context.writer.writeInfo('Running download test...');\n\n const contentLength = parseInt(\n response.headers.get('content-length') || '0',\n 10,\n );\n\n progressBar.show();\n progressBar.update(0);\n\n // Start timing AFTER connection is established (exclude TTFB)\n const startTime = performance.now();\n let totalBytes = 0;\n\n const reader = response.body!.getReader();\n let lastUpdateTime = startTime;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n totalBytes += value.length;\n\n const now = performance.now();\n if (now - lastUpdateTime > 250) {\n lastUpdateTime = now;\n const elapsedSec = (now - startTime) / 1000;\n const avgSpeed = totalBytes / elapsedSec;\n\n if (contentLength > 0) {\n const pct = Math.min(\n (totalBytes / contentLength) * 100,\n 100,\n );\n progressBar.update(pct);\n progressBar.setText(\n `${formatSpeed(avgSpeed)} | ${formatBytes(totalBytes)} / ${formatBytes(contentLength)}`,\n );\n } else {\n progressBar.setText(\n `${formatSpeed(avgSpeed)} | ${formatBytes(totalBytes)}`,\n );\n }\n }\n }\n\n progressBar.complete();\n progressBar.hide();\n\n const totalSec = (performance.now() - startTime) / 1000;\n const avgSpeed = totalBytes / totalSec;\n\n context.writer.writeSuccess(\n `Download: ${formatSpeed(avgSpeed)} (${formatBytes(totalBytes)} in ${totalSec.toFixed(1)}s)`,\n );\n\n return avgSpeed;\n }\n\n private async testUpload(\n url: string,\n context: ICliExecutionContext,\n signal: AbortSignal,\n ): Promise<number> {\n context.writer.writeln();\n context.writer.writeInfo(\n `Running upload test (${formatBytes(UPLOAD_SIZE)})...`,\n );\n\n const progressBar = context.progressBar;\n progressBar.show();\n progressBar.update(0);\n\n // Fill with pseudo-random data to prevent compression from skewing results.\n // crypto.getRandomValues() is limited to 65536 bytes per call.\n const payload = new Uint8Array(UPLOAD_SIZE);\n const chunkSize = 65536;\n for (let offset = 0; offset < UPLOAD_SIZE; offset += chunkSize) {\n const length = Math.min(chunkSize, UPLOAD_SIZE - offset);\n crypto.getRandomValues(new Uint8Array(payload.buffer, offset, length));\n }\n\n // Use multiple smaller fetch() calls to measure upload speed.\n // A single large POST to Cloudflare's __up may be blocked by CORS\n // when custom headers trigger a preflight. Chunking also lets us\n // report progress without XHR.\n const CHUNK = 1024 * 1024; // 1 MB per request\n const totalChunks = Math.ceil(UPLOAD_SIZE / CHUNK);\n let uploaded = 0;\n const startTime = performance.now();\n\n for (let i = 0; i < totalChunks; i++) {\n if (signal.aborted) {\n throw new DOMException('Upload aborted', 'AbortError');\n }\n\n const start = i * CHUNK;\n const end = Math.min(start + CHUNK, UPLOAD_SIZE);\n const chunk = payload.slice(start, end);\n\n await fetch(url, {\n method: 'POST',\n body: chunk,\n signal,\n });\n\n uploaded += chunk.length;\n\n const elapsed = (performance.now() - startTime) / 1000;\n const speed = uploaded / elapsed;\n const pct = (uploaded / UPLOAD_SIZE) * 100;\n progressBar.update(pct);\n progressBar.setText(\n `${formatSpeed(speed)} | ${formatBytes(uploaded)} / ${formatBytes(UPLOAD_SIZE)}`,\n );\n }\n\n const totalSec = (performance.now() - startTime) / 1000;\n const avgSpeed = UPLOAD_SIZE / totalSec;\n\n progressBar.complete();\n progressBar.hide();\n\n context.writer.writeSuccess(\n `Upload: ${formatSpeed(avgSpeed)} (${formatBytes(UPLOAD_SIZE)} in ${totalSec.toFixed(1)}s)`,\n );\n\n return avgSpeed;\n }\n\n private printSummary(\n results: { download?: number; upload?: number },\n context: ICliExecutionContext,\n ): void {\n context.writer.writeln();\n\n const headers = ['Test', 'Speed'];\n const rows: string[][] = [];\n\n if (results.download !== undefined) {\n rows.push(['Download', formatSpeed(results.download)]);\n }\n if (results.upload !== undefined) {\n rows.push(['Upload', formatSpeed(results.upload)]);\n }\n\n context.writer.writeTable(headers, rows);\n context.process.output(results);\n }\n}\n","/*\n * Public API Surface of speed-test\n */\n\nexport * from './lib/processors/cli-speed-test-command-processor';\n\nimport { ICliModule } from '@qodalis/cli-core';\nimport { CliSpeedTestCommandProcessor } from './lib/processors/cli-speed-test-command-processor';\nimport { API_VERSION } from './lib/version';\n\nexport const speedTestModule: ICliModule = {\n apiVersion: API_VERSION,\n name: '@qodalis/cli-speed-test',\n processors: [new CliSpeedTestCommandProcessor()],\n translations: {\n es: { 'cli.speed-test.description': 'Ejecutar una prueba de velocidad de internet' },\n fr: { 'cli.speed-test.description': 'Lancer un test de débit internet' },\n de: { 'cli.speed-test.description': 'Internet-Geschwindigkeitstest durchführen' },\n pt: { 'cli.speed-test.description': 'Executar um teste de velocidade de internet' },\n it: { 'cli.speed-test.description': 'Eseguire un test di velocità internet' },\n ja: { 'cli.speed-test.description': 'インターネット速度テストを実行' },\n ko: { 'cli.speed-test.description': '인터넷 속도 테스트 실행' },\n zh: { 'cli.speed-test.description': '运行网络速度测试' },\n ru: { 'cli.speed-test.description': 'Запустить тест скорости интернета' },\n ro: { 'cli.speed-test.description': 'Rulează un test de viteză a internetului' },\n },\n};\n"]}
1
+ {"version":3,"sources":["../../packages/plugins/speed-test/src/lib/version.ts","../../packages/plugins/speed-test/src/lib/processors/cli-speed-test-command-processor.ts","../../packages/plugins/speed-test/src/public-api.ts"],"names":["avgSpeed"],"mappings":"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","file":"public-api.mjs","sourcesContent":["\n// Automatically generated during build\nexport const LIBRARY_VERSION = '2.0.0-beta.11';\nexport const API_VERSION = 2;\n ","import {\n CliForegroundColor,\n CliProcessorMetadata,\n DefaultLibraryAuthor,\n CliProcessCommand,\n ICliCommandProcessor,\n ICliExecutionContext,\n} from '@qodalis/cli-core';\nimport { LIBRARY_VERSION } from '../version';\n\n/**\n * Cloudflare speed test endpoints — edge-served, CORS-enabled, fast worldwide.\n * The `bytes` parameter controls the download size.\n */\nconst DEFAULT_DOWNLOAD_URL =\n 'https://speed.cloudflare.com/__down?bytes=26214400';\n\nconst DEFAULT_UPLOAD_URL = 'https://speed.cloudflare.com/__up';\n\n/** Size of upload test payload in bytes (10 MB). */\nconst UPLOAD_SIZE = 10 * 1024 * 1024;\n\n/** Format bytes/second as a human-readable speed string. */\nfunction formatSpeed(bytesPerSecond: number): string {\n const mbps = (bytesPerSecond * 8) / (1024 * 1024);\n if (mbps >= 1) return `${mbps.toFixed(2)} Mbps`;\n const kbps = (bytesPerSecond * 8) / 1024;\n if (kbps >= 1) return `${kbps.toFixed(1)} Kbps`;\n return `${(bytesPerSecond * 8).toFixed(0)} bps`;\n}\n\n/** Format bytes as a human-readable size string. */\nfunction formatBytes(bytes: number): string {\n if (bytes >= 1024 * 1024)\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${bytes} B`;\n}\n\nexport class CliSpeedTestCommandProcessor implements ICliCommandProcessor {\n command = 'speed-test';\n\n description = 'Run an internet speed test';\n\n author = DefaultLibraryAuthor;\n\n version = LIBRARY_VERSION;\n\n processors?: ICliCommandProcessor[] = [];\n\n parameters = [\n {\n name: 'download-url',\n description: 'Custom URL for the download test',\n type: 'string' as const,\n required: false,\n },\n {\n name: 'upload-url',\n description: 'Custom URL for the upload test',\n type: 'string' as const,\n required: false,\n },\n {\n name: 'download-only',\n description: 'Only run the download test',\n type: 'boolean' as const,\n required: false,\n },\n {\n name: 'upload-only',\n description: 'Only run the upload test',\n type: 'boolean' as const,\n required: false,\n },\n ];\n\n metadata?: CliProcessorMetadata = {\n icon: '🚀',\n requiredCoreVersion: '>=2.0.0 <3.0.0',\n requiredCliVersion: '>=2.0.0 <3.0.0',\n };\n\n constructor() {\n this.processors = [\n {\n command: 'run',\n description: 'Run the internet speed test',\n processCommand: async (command, context) => {\n await this.runSpeedTest(command, context);\n },\n },\n ];\n }\n\n async processCommand(\n command: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n await this.runSpeedTest(command, context);\n }\n\n writeDescription(context: ICliExecutionContext): void {\n const { writer } = context;\n writer.writeln(this.description);\n writer.writeln();\n writer.writeln('Usage:');\n writer.writeln(\n ` ${writer.wrapInColor('speed-test', CliForegroundColor.Cyan)} Run download & upload test`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --download-only', CliForegroundColor.Cyan)} Download only`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --upload-only', CliForegroundColor.Cyan)} Upload only`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --download-url=<url>', CliForegroundColor.Cyan)} Custom download URL`,\n );\n writer.writeln(\n ` ${writer.wrapInColor('speed-test --upload-url=<url>', CliForegroundColor.Cyan)} Custom upload URL`,\n );\n writer.writeln();\n writer.writeln(\n `Press ${writer.wrapInColor('Ctrl+C', CliForegroundColor.Yellow)} to abort the test`,\n );\n }\n\n private async runSpeedTest(\n command: CliProcessCommand,\n context: ICliExecutionContext,\n ): Promise<void> {\n const downloadOnly = !!command.args['download-only'];\n const uploadOnly = !!command.args['upload-only'];\n\n const controller = new AbortController();\n const subscription = context.onAbort.subscribe(() => {\n controller.abort();\n });\n\n const results: { download?: number; upload?: number } = {};\n\n try {\n if (!uploadOnly) {\n const downloadUrl =\n (command.args['download-url'] as string) ||\n DEFAULT_DOWNLOAD_URL;\n results.download = await this.testDownload(\n downloadUrl,\n context,\n controller.signal,\n );\n }\n\n if (!downloadOnly) {\n const uploadUrl =\n (command.args['upload-url'] as string) ||\n DEFAULT_UPLOAD_URL;\n results.upload = await this.testUpload(\n uploadUrl,\n context,\n controller.signal,\n );\n }\n\n this.printSummary(results, context);\n } catch (error: any) {\n if (error.name === 'AbortError' || controller.signal.aborted) {\n context.writer.writeWarning('Speed test aborted');\n } else {\n context.writer.writeError(\n `Speed test failed: ${error.message || error}`,\n );\n }\n } finally {\n subscription.unsubscribe();\n }\n }\n\n private async testDownload(\n url: string,\n context: ICliExecutionContext,\n signal: AbortSignal,\n ): Promise<number> {\n context.writer.writeln();\n\n const progressBar = context.progressBar;\n const spinner = context.spinner;\n\n // Show spinner while waiting for connection (DNS, TLS, TTFB)\n spinner?.show('Connecting...');\n\n const response = await fetch(url, { signal });\n\n if (!response.ok) {\n spinner?.hide();\n throw new Error(`Download failed: HTTP ${response.status}`);\n }\n\n spinner?.hide();\n context.writer.writeInfo('Running download test...');\n\n const contentLength = parseInt(\n response.headers.get('content-length') || '0',\n 10,\n );\n\n progressBar.show();\n progressBar.update(0);\n\n // Start timing AFTER connection is established (exclude TTFB)\n const startTime = performance.now();\n let totalBytes = 0;\n\n const reader = response.body!.getReader();\n let lastUpdateTime = startTime;\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n totalBytes += value.length;\n\n const now = performance.now();\n if (now - lastUpdateTime > 250) {\n lastUpdateTime = now;\n const elapsedSec = (now - startTime) / 1000;\n const avgSpeed = totalBytes / elapsedSec;\n\n if (contentLength > 0) {\n const pct = Math.min(\n (totalBytes / contentLength) * 100,\n 100,\n );\n progressBar.update(pct);\n progressBar.setText(\n `${formatSpeed(avgSpeed)} | ${formatBytes(totalBytes)} / ${formatBytes(contentLength)}`,\n );\n } else {\n progressBar.setText(\n `${formatSpeed(avgSpeed)} | ${formatBytes(totalBytes)}`,\n );\n }\n }\n }\n\n progressBar.complete();\n progressBar.hide();\n\n const totalSec = (performance.now() - startTime) / 1000;\n const avgSpeed = totalBytes / totalSec;\n\n context.writer.writeSuccess(\n `Download: ${formatSpeed(avgSpeed)} (${formatBytes(totalBytes)} in ${totalSec.toFixed(1)}s)`,\n );\n\n return avgSpeed;\n }\n\n private async testUpload(\n url: string,\n context: ICliExecutionContext,\n signal: AbortSignal,\n ): Promise<number> {\n context.writer.writeln();\n context.writer.writeInfo(\n `Running upload test (${formatBytes(UPLOAD_SIZE)})...`,\n );\n\n const progressBar = context.progressBar;\n progressBar.show();\n progressBar.update(0);\n\n // Fill with pseudo-random data to prevent compression from skewing results.\n // crypto.getRandomValues() is limited to 65536 bytes per call.\n const payload = new Uint8Array(UPLOAD_SIZE);\n const chunkSize = 65536;\n for (let offset = 0; offset < UPLOAD_SIZE; offset += chunkSize) {\n const length = Math.min(chunkSize, UPLOAD_SIZE - offset);\n crypto.getRandomValues(new Uint8Array(payload.buffer, offset, length));\n }\n\n // Use multiple smaller fetch() calls to measure upload speed.\n // A single large POST to Cloudflare's __up may be blocked by CORS\n // when custom headers trigger a preflight. Chunking also lets us\n // report progress without XHR.\n const CHUNK = 1024 * 1024; // 1 MB per request\n const totalChunks = Math.ceil(UPLOAD_SIZE / CHUNK);\n let uploaded = 0;\n const startTime = performance.now();\n\n for (let i = 0; i < totalChunks; i++) {\n if (signal.aborted) {\n throw new DOMException('Upload aborted', 'AbortError');\n }\n\n const start = i * CHUNK;\n const end = Math.min(start + CHUNK, UPLOAD_SIZE);\n const chunk = payload.slice(start, end);\n\n await fetch(url, {\n method: 'POST',\n body: chunk,\n signal,\n });\n\n uploaded += chunk.length;\n\n const elapsed = (performance.now() - startTime) / 1000;\n const speed = uploaded / elapsed;\n const pct = (uploaded / UPLOAD_SIZE) * 100;\n progressBar.update(pct);\n progressBar.setText(\n `${formatSpeed(speed)} | ${formatBytes(uploaded)} / ${formatBytes(UPLOAD_SIZE)}`,\n );\n }\n\n const totalSec = (performance.now() - startTime) / 1000;\n const avgSpeed = UPLOAD_SIZE / totalSec;\n\n progressBar.complete();\n progressBar.hide();\n\n context.writer.writeSuccess(\n `Upload: ${formatSpeed(avgSpeed)} (${formatBytes(UPLOAD_SIZE)} in ${totalSec.toFixed(1)}s)`,\n );\n\n return avgSpeed;\n }\n\n private printSummary(\n results: { download?: number; upload?: number },\n context: ICliExecutionContext,\n ): void {\n context.writer.writeln();\n\n const headers = ['Test', 'Speed'];\n const rows: string[][] = [];\n\n if (results.download !== undefined) {\n rows.push(['Download', formatSpeed(results.download)]);\n }\n if (results.upload !== undefined) {\n rows.push(['Upload', formatSpeed(results.upload)]);\n }\n\n context.writer.writeTable(headers, rows);\n context.process.output(results);\n }\n}\n","/*\n * Public API Surface of speed-test\n */\n\nexport * from './lib/processors/cli-speed-test-command-processor';\n\nimport { ICliModule } from '@qodalis/cli-core';\nimport { CliSpeedTestCommandProcessor } from './lib/processors/cli-speed-test-command-processor';\nimport { API_VERSION } from './lib/version';\n\nexport const speedTestModule: ICliModule = {\n apiVersion: API_VERSION,\n name: '@qodalis/cli-speed-test',\n processors: [new CliSpeedTestCommandProcessor()],\n translations: {\n es: { 'cli.speed-test.description': 'Ejecutar una prueba de velocidad de internet' },\n fr: { 'cli.speed-test.description': 'Lancer un test de débit internet' },\n de: { 'cli.speed-test.description': 'Internet-Geschwindigkeitstest durchführen' },\n pt: { 'cli.speed-test.description': 'Executar um teste de velocidade de internet' },\n it: { 'cli.speed-test.description': 'Eseguire un test di velocità internet' },\n ja: { 'cli.speed-test.description': 'インターネット速度テストを実行' },\n ko: { 'cli.speed-test.description': '인터넷 속도 테스트 실행' },\n zh: { 'cli.speed-test.description': '运行网络速度测试' },\n ru: { 'cli.speed-test.description': 'Запустить тест скорости интернета' },\n ro: { 'cli.speed-test.description': 'Rulează un test de viteză a internetului' },\n },\n};\n"]}
@@ -1838,9 +1838,11 @@ var speedTest = (() => {
1838
1838
  email: "nicolae.lupei@qodalis.com"
1839
1839
  };
1840
1840
  var semver = __toESM(require_semver2());
1841
+ var API_VERSION = 2;
1842
+ var VERSIONS_ENDPOINT = "/api/qcli/versions";
1841
1843
  var ServerVersionNegotiator = class {
1842
1844
  static {
1843
- this.CLIENT_SUPPORTED_VERSIONS = [2];
1845
+ this.CLIENT_SUPPORTED_VERSIONS = [API_VERSION];
1844
1846
  }
1845
1847
  /**
1846
1848
  * Given a server's version info, pick the highest mutually compatible version.
@@ -1859,14 +1861,14 @@ var speedTest = (() => {
1859
1861
  */
1860
1862
  static async discover(baseUrl) {
1861
1863
  try {
1862
- const response = await fetch(`${baseUrl}/api/cli/versions`);
1864
+ const response = await fetch(`${baseUrl}${VERSIONS_ENDPOINT}`);
1863
1865
  if (!response.ok) return null;
1864
1866
  const info = await response.json();
1865
1867
  const version = this.negotiate(info);
1866
1868
  if (version === null) return null;
1867
1869
  return {
1868
1870
  apiVersion: version,
1869
- basePath: `${baseUrl}/api/v${version}/cli`
1871
+ basePath: `${baseUrl}/api/v${version}/qcli`
1870
1872
  };
1871
1873
  } catch {
1872
1874
  return null;
@@ -2691,8 +2693,8 @@ var speedTest = (() => {
2691
2693
  };
2692
2694
 
2693
2695
  // src/lib/version.ts
2694
- var LIBRARY_VERSION = "2.0.0-beta.1";
2695
- var API_VERSION = 2;
2696
+ var LIBRARY_VERSION = "2.0.0-beta.11";
2697
+ var API_VERSION2 = 2;
2696
2698
 
2697
2699
  // src/lib/processors/cli-speed-test-command-processor.ts
2698
2700
  var DEFAULT_DOWNLOAD_URL = "https://speed.cloudflare.com/__down?bytes=26214400";
@@ -2946,7 +2948,7 @@ var speedTest = (() => {
2946
2948
 
2947
2949
  // src/cli-entrypoint.ts
2948
2950
  var module = {
2949
- apiVersion: API_VERSION,
2951
+ apiVersion: API_VERSION2,
2950
2952
  name: "@qodalis/cli-speed-test",
2951
2953
  processors: [new CliSpeedTestCommandProcessor()]
2952
2954
  };