@qodalis/cli-speed-test 2.1.1 → 2.3.0

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.1.1",
3
+ "version": "2.3.0",
4
4
  "description": "@qodalis/cli extension for running network speed tests.",
5
5
  "author": "Nicolae Lupei, Qodalis Solutions",
6
6
  "license": "MIT",
@@ -20,7 +20,7 @@
20
20
  "umd": "./umd/index.global.js",
21
21
  "unpkg": "./umd/index.global.js",
22
22
  "dependencies": {
23
- "@qodalis/cli-core": "2.1.1"
23
+ "@qodalis/cli-core": "2.3.0"
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.1.1";
8
+ var LIBRARY_VERSION = "2.3.0";
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.1.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 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 context.notifier.info('Speed test: download');\n results.download = await this.testDownload(\n downloadUrl,\n context,\n );\n }\n\n if (!downloadOnly) {\n const uploadUrl =\n (command.args['upload-url'] as string) ||\n DEFAULT_UPLOAD_URL;\n context.notifier.info('Speed test: upload');\n results.upload = await this.testUpload(\n uploadUrl,\n context,\n );\n }\n\n this.printSummary(results, context);\n } catch (error: any) {\n if (error.name === 'AbortError' || context.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 }\n }\n\n private async testDownload(\n url: string,\n context: ICliExecutionContext,\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 context.http.fetch(url);\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 context.notifier.info(`Download: ${Math.round(pct)}% ${formatSpeed(avgSpeed)}`);\n } else {\n progressBar.setText(\n `${formatSpeed(avgSpeed)} | ${formatBytes(totalBytes)}`,\n );\n context.notifier.info(`Download: ${formatSpeed(avgSpeed)}`);\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 ): 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 (context.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 context.http.fetch(url, {\n method: 'POST',\n body: chunk,\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 context.notifier.info(`Upload: ${Math.round(pct)}% ${formatSpeed(speed)}`);\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.3.0';\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 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 context.notifier.info('Speed test: download');\n results.download = await this.testDownload(\n downloadUrl,\n context,\n );\n }\n\n if (!downloadOnly) {\n const uploadUrl =\n (command.args['upload-url'] as string) ||\n DEFAULT_UPLOAD_URL;\n context.notifier.info('Speed test: upload');\n results.upload = await this.testUpload(\n uploadUrl,\n context,\n );\n }\n\n this.printSummary(results, context);\n } catch (error: any) {\n if (error.name === 'AbortError' || context.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 }\n }\n\n private async testDownload(\n url: string,\n context: ICliExecutionContext,\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 context.http.fetch(url);\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 context.notifier.info(`Download: ${Math.round(pct)}% ${formatSpeed(avgSpeed)}`);\n } else {\n progressBar.setText(\n `${formatSpeed(avgSpeed)} | ${formatBytes(totalBytes)}`,\n );\n context.notifier.info(`Download: ${formatSpeed(avgSpeed)}`);\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 ): 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 (context.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 context.http.fetch(url, {\n method: 'POST',\n body: chunk,\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 context.notifier.info(`Upload: ${Math.round(pct)}% ${formatSpeed(speed)}`);\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.1.1";
6
+ var LIBRARY_VERSION = "2.3.0";
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.1.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 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 context.notifier.info('Speed test: download');\n results.download = await this.testDownload(\n downloadUrl,\n context,\n );\n }\n\n if (!downloadOnly) {\n const uploadUrl =\n (command.args['upload-url'] as string) ||\n DEFAULT_UPLOAD_URL;\n context.notifier.info('Speed test: upload');\n results.upload = await this.testUpload(\n uploadUrl,\n context,\n );\n }\n\n this.printSummary(results, context);\n } catch (error: any) {\n if (error.name === 'AbortError' || context.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 }\n }\n\n private async testDownload(\n url: string,\n context: ICliExecutionContext,\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 context.http.fetch(url);\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 context.notifier.info(`Download: ${Math.round(pct)}% ${formatSpeed(avgSpeed)}`);\n } else {\n progressBar.setText(\n `${formatSpeed(avgSpeed)} | ${formatBytes(totalBytes)}`,\n );\n context.notifier.info(`Download: ${formatSpeed(avgSpeed)}`);\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 ): 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 (context.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 context.http.fetch(url, {\n method: 'POST',\n body: chunk,\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 context.notifier.info(`Upload: ${Math.round(pct)}% ${formatSpeed(speed)}`);\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.3.0';\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 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 context.notifier.info('Speed test: download');\n results.download = await this.testDownload(\n downloadUrl,\n context,\n );\n }\n\n if (!downloadOnly) {\n const uploadUrl =\n (command.args['upload-url'] as string) ||\n DEFAULT_UPLOAD_URL;\n context.notifier.info('Speed test: upload');\n results.upload = await this.testUpload(\n uploadUrl,\n context,\n );\n }\n\n this.printSummary(results, context);\n } catch (error: any) {\n if (error.name === 'AbortError' || context.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 }\n }\n\n private async testDownload(\n url: string,\n context: ICliExecutionContext,\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 context.http.fetch(url);\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 context.notifier.info(`Download: ${Math.round(pct)}% ${formatSpeed(avgSpeed)}`);\n } else {\n progressBar.setText(\n `${formatSpeed(avgSpeed)} | ${formatBytes(totalBytes)}`,\n );\n context.notifier.info(`Download: ${formatSpeed(avgSpeed)}`);\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 ): 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 (context.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 context.http.fetch(url, {\n method: 'POST',\n body: chunk,\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 context.notifier.info(`Upload: ${Math.round(pct)}% ${formatSpeed(speed)}`);\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"]}
@@ -1978,11 +1978,6 @@ var speedTest = (() => {
1978
1978
  }
1979
1979
  }
1980
1980
  };
1981
- var bootCliModule = async (module2) => {
1982
- if (typeof window !== "undefined" && window.__cliModuleRegistry) {
1983
- await window.__cliModuleRegistry.register(module2);
1984
- }
1985
- };
1986
1981
  var DefaultThemes = {
1987
1982
  default: {
1988
1983
  background: "#070b14",
@@ -2007,6 +2002,31 @@ var speedTest = (() => {
2007
2002
  brightCyan: "#a5f3fc",
2008
2003
  brightWhite: "#f1f5f9"
2009
2004
  },
2005
+ // Soft grey paper and slate text; every color reads at 4.5:1 or more on the background
2006
+ light: {
2007
+ background: "#f7f8fa",
2008
+ foreground: "#334155",
2009
+ cursor: "#4f46e5",
2010
+ cursorAccent: "#f7f8fa",
2011
+ selectionBackground: "#d9def7",
2012
+ selectionForeground: "#1e293b",
2013
+ black: "#334155",
2014
+ red: "#c93c37",
2015
+ green: "#2c7a4b",
2016
+ yellow: "#946200",
2017
+ blue: "#3d5bd9",
2018
+ magenta: "#8b3fc7",
2019
+ cyan: "#0e7586",
2020
+ white: "#5b6577",
2021
+ brightBlack: "#667085",
2022
+ brightRed: "#b42a25",
2023
+ brightGreen: "#1f6a3d",
2024
+ brightYellow: "#7a5100",
2025
+ brightBlue: "#2f47bd",
2026
+ brightMagenta: "#7431ad",
2027
+ brightCyan: "#0a6170",
2028
+ brightWhite: "#1e293b"
2029
+ },
2010
2030
  classic: {
2011
2031
  background: "#0c0c0c",
2012
2032
  foreground: "#cccccc",
@@ -2618,6 +2638,42 @@ var speedTest = (() => {
2618
2638
  }
2619
2639
  };
2620
2640
  DefaultThemes.yellow = DefaultThemes.highContrastLight;
2641
+ var CliPanelPalettes = Object.freeze({
2642
+ dark: Object.freeze({
2643
+ background: "#070b14",
2644
+ headerBackground: "#0f1623",
2645
+ border: "#1e293b",
2646
+ text: "#e2e8f0",
2647
+ textSecondary: "#94a3b8",
2648
+ accent: "#818cf8",
2649
+ hoverBackground: "rgba(129, 140, 248, 0.12)",
2650
+ activeBackground: "rgba(129, 140, 248, 0.22)",
2651
+ danger: "#f87171",
2652
+ shadow: "rgba(0, 0, 0, 0.45)"
2653
+ }),
2654
+ // Soft grey paper instead of pure white, slate text rather than black: easier on the eyes
2655
+ light: Object.freeze({
2656
+ background: "#f7f8fa",
2657
+ headerBackground: "#eceff3",
2658
+ border: "#d9dee6",
2659
+ text: "#1e293b",
2660
+ textSecondary: "#5b6577",
2661
+ accent: "#4f46e5",
2662
+ hoverBackground: "rgba(30, 41, 59, 0.06)",
2663
+ activeBackground: "rgba(79, 70, 229, 0.12)",
2664
+ danger: "#c93c37",
2665
+ shadow: "rgba(15, 23, 42, 0.12)"
2666
+ })
2667
+ });
2668
+ var PALETTE_TERMINALS = {
2669
+ dark: DefaultThemes.default,
2670
+ light: DefaultThemes.light
2671
+ };
2672
+ var bootCliModule = async (module2) => {
2673
+ if (typeof window !== "undefined" && window.__cliModuleRegistry) {
2674
+ await window.__cliModuleRegistry.register(module2);
2675
+ }
2676
+ };
2621
2677
  var DefaultThemeInfos = {
2622
2678
  default: {
2623
2679
  theme: DefaultThemes.default,
@@ -2625,6 +2681,12 @@ var speedTest = (() => {
2625
2681
  tags: ["built-in"],
2626
2682
  description: "Dark indigo theme with soft pastels"
2627
2683
  },
2684
+ light: {
2685
+ theme: DefaultThemes.light,
2686
+ category: "light",
2687
+ tags: ["built-in"],
2688
+ description: "Light counterpart of the default theme"
2689
+ },
2628
2690
  classic: {
2629
2691
  theme: DefaultThemes.classic,
2630
2692
  category: "dark",
@@ -2796,7 +2858,7 @@ var speedTest = (() => {
2796
2858
  };
2797
2859
 
2798
2860
  // src/lib/version.ts
2799
- var LIBRARY_VERSION = "2.1.1";
2861
+ var LIBRARY_VERSION = "2.3.0";
2800
2862
  var API_VERSION2 = 2;
2801
2863
 
2802
2864
  // src/lib/processors/cli-speed-test-command-processor.ts