@qodalis/cli-speed-test 2.4.1 → 2.5.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 +2 -2
- package/public-api.js +1 -1
- package/public-api.js.map +1 -1
- package/public-api.mjs +1 -1
- package/public-api.mjs.map +1 -1
- package/umd/index.global.js +2 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qodalis/cli-speed-test",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.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.
|
|
23
|
+
"@qodalis/cli-core": "2.5.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.
|
|
8
|
+
var LIBRARY_VERSION = "2.5.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.4.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.5.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.
|
|
6
|
+
var LIBRARY_VERSION = "2.5.0";
|
|
7
7
|
var API_VERSION = 2;
|
|
8
8
|
|
|
9
9
|
// src/lib/processors/cli-speed-test-command-processor.ts
|
package/public-api.mjs.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":["avgSpeed"],"mappings":"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","file":"public-api.mjs","sourcesContent":["\n// Automatically generated during build\nexport const LIBRARY_VERSION = '2.4.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.5.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/umd/index.global.js
CHANGED
|
@@ -1925,6 +1925,7 @@ var speedTest = (() => {
|
|
|
1925
1925
|
if (!provider) return {};
|
|
1926
1926
|
return typeof provider === "function" ? provider() : provider;
|
|
1927
1927
|
}
|
|
1928
|
+
var ICliSecretStore_TOKEN = createCliToken("cli-secret-store");
|
|
1928
1929
|
var ICliCommandGuard_TOKEN = createCliToken("cli-command-guard");
|
|
1929
1930
|
var ICliEventBus_TOKEN = createCliToken("cli-event-bus");
|
|
1930
1931
|
var DefaultLibraryAuthor = {
|
|
@@ -2858,7 +2859,7 @@ var speedTest = (() => {
|
|
|
2858
2859
|
};
|
|
2859
2860
|
|
|
2860
2861
|
// src/lib/version.ts
|
|
2861
|
-
var LIBRARY_VERSION = "2.
|
|
2862
|
+
var LIBRARY_VERSION = "2.5.0";
|
|
2862
2863
|
var API_VERSION2 = 2;
|
|
2863
2864
|
|
|
2864
2865
|
// src/lib/processors/cli-speed-test-command-processor.ts
|