@ooneex/cli 1.24.0 → 1.26.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/dist/index.js CHANGED
@@ -33598,6 +33598,212 @@ var ensureModule = async (module) => {
33598
33598
  };
33599
33599
 
33600
33600
  // src/commands/BenchmarkRunCommand.ts
33601
+ var dim = (s) => `\x1B[2m${s}\x1B[22m`;
33602
+ var bold = (s) => `\x1B[1m${s}\x1B[22m`;
33603
+ var cyan = (s) => `\x1B[36m${s}\x1B[39m`;
33604
+ var green = (s) => `\x1B[32m${s}\x1B[39m`;
33605
+ var yellow = (s) => `\x1B[33m${s}\x1B[39m`;
33606
+ var red = (s) => `\x1B[31m${s}\x1B[39m`;
33607
+ var magenta = (s) => `\x1B[35m${s}\x1B[39m`;
33608
+ function formatBytes(bytes) {
33609
+ if (bytes >= 1073741824)
33610
+ return `${(bytes / 1073741824).toFixed(2)} GB`;
33611
+ if (bytes >= 1048576)
33612
+ return `${(bytes / 1048576).toFixed(2)} MB`;
33613
+ if (bytes >= 1024)
33614
+ return `${(bytes / 1024).toFixed(2)} KB`;
33615
+ return `${bytes} B`;
33616
+ }
33617
+ function formatNumber(n) {
33618
+ return n.toLocaleString("en-US");
33619
+ }
33620
+ function formatLatency(ms) {
33621
+ if (ms >= 1000)
33622
+ return `${(ms / 1000).toFixed(2)} s`;
33623
+ return `${ms.toFixed(2)} ms`;
33624
+ }
33625
+ function printHeader(config, url, connections, duration) {
33626
+ const method = (config.method ?? "GET").toUpperCase();
33627
+ const title = config.name || "Benchmark";
33628
+ process.stdout.write(`
33629
+ `);
33630
+ process.stdout.write(` ${bold(cyan(title))}
33631
+ `);
33632
+ if (config.description) {
33633
+ process.stdout.write(` ${dim(config.description)}
33634
+ `);
33635
+ }
33636
+ process.stdout.write(` ${bold(method)} ${cyan(url)}
33637
+ `);
33638
+ process.stdout.write(` ${dim(`${connections} connections`)} ${dim("|")} ${dim(`${duration}s duration`)}
33639
+ `);
33640
+ process.stdout.write(`
33641
+ `);
33642
+ }
33643
+ function printResults(result) {
33644
+ const w = process.stdout.write.bind(process.stdout);
33645
+ const line = dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
33646
+ w(` ${bold(magenta("Latency"))}
33647
+ `);
33648
+ w(`${line}
33649
+ `);
33650
+ w(` ${dim("Avg")} ${bold(formatLatency(result.latency.average))}
33651
+ `);
33652
+ w(` ${dim("p50")} ${formatLatency(result.latency.p50)}
33653
+ `);
33654
+ w(` ${dim("p90")} ${formatLatency(result.latency.p90)}
33655
+ `);
33656
+ w(` ${dim("p97.5")} ${yellow(formatLatency(result.latency.p97_5))}
33657
+ `);
33658
+ w(` ${dim("p99")} ${yellow(formatLatency(result.latency.p99))}
33659
+ `);
33660
+ w(` ${dim("Max")} ${red(formatLatency(result.latency.max))}
33661
+ `);
33662
+ w(` ${dim("StdDev")} ${formatLatency(result.latency.stddev)}
33663
+ `);
33664
+ w(`
33665
+ `);
33666
+ w(` ${bold(magenta("Throughput"))}
33667
+ `);
33668
+ w(`${line}
33669
+ `);
33670
+ w(` ${dim("Req/Sec")} ${bold(formatNumber(Math.round(result.requests.average)))} avg`);
33671
+ w(` ${dim("(")}${formatNumber(result.requests.min)} ${dim("\u2014")} ${formatNumber(result.requests.max)}${dim(")")}
33672
+ `);
33673
+ w(` ${dim("Bytes/Sec")} ${bold(formatBytes(result.throughput.average))} avg`);
33674
+ w(` ${dim("(")}${formatBytes(result.throughput.min)} ${dim("\u2014")} ${formatBytes(result.throughput.max)}${dim(")")}
33675
+ `);
33676
+ w(`
33677
+ `);
33678
+ w(` ${bold(magenta("Summary"))}
33679
+ `);
33680
+ w(`${line}
33681
+ `);
33682
+ const totalRequests = result.requests.sent;
33683
+ const totalData = result.throughput.total;
33684
+ const dur = result.duration;
33685
+ w(` ${dim("URL")} ${cyan(result.url)}
33686
+ `);
33687
+ const successCount = result["2xx"] ?? 0;
33688
+ w(` ${dim("Total Requests")} ${bold(green(formatNumber(totalRequests)))}
33689
+ `);
33690
+ w(` ${dim("Success (2xx)")} ${successCount > 0 ? green(formatNumber(successCount)) : red("0")}
33691
+ `);
33692
+ w(` ${dim("Total Data")} ${formatBytes(totalData)}
33693
+ `);
33694
+ w(` ${dim("Duration")} ${dur.toFixed(2)}s
33695
+ `);
33696
+ if (result.errors > 0) {
33697
+ w(` ${dim("Errors")} ${red(String(result.errors))}
33698
+ `);
33699
+ } else {
33700
+ w(` ${dim("Errors")} ${green("0")}
33701
+ `);
33702
+ }
33703
+ if (result.timeouts > 0) {
33704
+ w(` ${dim("Timeouts")} ${red(String(result.timeouts))}
33705
+ `);
33706
+ } else {
33707
+ w(` ${dim("Timeouts")} ${green("0")}
33708
+ `);
33709
+ }
33710
+ if (result.non2xx > 0) {
33711
+ w(` ${dim("Non-2xx")} ${red(formatNumber(result.non2xx))}
33712
+ `);
33713
+ } else {
33714
+ w(` ${dim("Non-2xx")} ${green("0")}
33715
+ `);
33716
+ }
33717
+ if (result.mismatches > 0) {
33718
+ w(` ${dim("Mismatches")} ${red(String(result.mismatches))}
33719
+ `);
33720
+ }
33721
+ w(`
33722
+ `);
33723
+ printPerformanceAnalysis(result);
33724
+ }
33725
+ function printPerformanceAnalysis(result) {
33726
+ const w = process.stdout.write.bind(process.stdout);
33727
+ const line = dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
33728
+ w(` ${bold(magenta("Performance Analysis"))}
33729
+ `);
33730
+ w(`${line}
33731
+ `);
33732
+ const avgReqPerSec = result.requests.average;
33733
+ const connections = result.connections;
33734
+ const avgLatencyMs = result.latency.average;
33735
+ const p99LatencyMs = result.latency.p99;
33736
+ const errorRate = result.requests.sent > 0 ? (result.errors + result.non2xx) / result.requests.sent * 100 : 0;
33737
+ const successRate = 100 - errorRate;
33738
+ const latencyHeadroom = p99LatencyMs < 50 ? 4 : p99LatencyMs < 100 ? 3 : p99LatencyMs < 500 ? 2 : 1;
33739
+ const errorFactor = errorRate < 1 ? 1 : errorRate < 5 ? 0.5 : 0.2;
33740
+ const estimatedMaxClients = Math.round(connections * latencyHeadroom * errorFactor);
33741
+ const estimatedMaxReqPerSec = Math.round(result.requests.max * errorFactor);
33742
+ const avgResponseTime = avgLatencyMs;
33743
+ const reqPerConnection = avgReqPerSec / connections;
33744
+ w(` ${dim("Success Rate")} ${successRate >= 99 ? green(`${successRate.toFixed(1)}%`) : successRate >= 95 ? yellow(`${successRate.toFixed(1)}%`) : red(`${successRate.toFixed(1)}%`)}
33745
+ `);
33746
+ w(` ${dim("Avg Resp Time")} ${avgResponseTime < 10 ? green(formatLatency(avgResponseTime)) : avgResponseTime < 100 ? yellow(formatLatency(avgResponseTime)) : red(formatLatency(avgResponseTime))}
33747
+ `);
33748
+ w(` ${dim("Req/Connection")} ${formatNumber(Math.round(reqPerConnection))} req/sec
33749
+ `);
33750
+ w(`
33751
+ `);
33752
+ w(` ${dim("Est. Max Clients")} ${bold(cyan(formatNumber(estimatedMaxClients)))} concurrent
33753
+ `);
33754
+ w(` ${dim("Est. Max Req/Sec")} ${bold(cyan(formatNumber(estimatedMaxReqPerSec)))}
33755
+ `);
33756
+ w(`
33757
+ `);
33758
+ const grade = getPerformanceGrade(avgLatencyMs, p99LatencyMs, errorRate, avgReqPerSec);
33759
+ w(` ${dim("Grade")} ${grade.color(bold(grade.label))}
33760
+ `);
33761
+ w(` ${grade.color(grade.message)}
33762
+ `);
33763
+ w(`
33764
+ `);
33765
+ }
33766
+ function getPerformanceGrade(avgLatency, p99Latency, errorRate, reqPerSec) {
33767
+ let score = 100;
33768
+ if (avgLatency > 500)
33769
+ score -= 40;
33770
+ else if (avgLatency > 100)
33771
+ score -= 25;
33772
+ else if (avgLatency > 50)
33773
+ score -= 15;
33774
+ else if (avgLatency > 10)
33775
+ score -= 5;
33776
+ if (p99Latency > 1000)
33777
+ score -= 25;
33778
+ else if (p99Latency > 500)
33779
+ score -= 15;
33780
+ else if (p99Latency > 100)
33781
+ score -= 8;
33782
+ if (errorRate > 10)
33783
+ score -= 30;
33784
+ else if (errorRate > 5)
33785
+ score -= 20;
33786
+ else if (errorRate > 1)
33787
+ score -= 10;
33788
+ else if (errorRate > 0)
33789
+ score -= 3;
33790
+ if (reqPerSec > 1e4)
33791
+ score = Math.min(100, score + 5);
33792
+ if (score >= 90) {
33793
+ return { label: "A Excellent", message: " Server handles load with low latency and high reliability", color: green };
33794
+ }
33795
+ if (score >= 75) {
33796
+ return { label: "B Good", message: " Server performs well under load with acceptable latency", color: green };
33797
+ }
33798
+ if (score >= 60) {
33799
+ return { label: "C Fair", message: " Server shows moderate latency or occasional errors under load", color: yellow };
33800
+ }
33801
+ if (score >= 40) {
33802
+ return { label: "D Poor", message: " Server struggles with high latency or significant errors", color: red };
33803
+ }
33804
+ return { label: "F Critical", message: " Server cannot handle the load \u2014 consider scaling or optimization", color: red };
33805
+ }
33806
+
33601
33807
  class BenchmarkRunCommand {
33602
33808
  getName() {
33603
33809
  return "benchmark:run";
@@ -33628,7 +33834,7 @@ class BenchmarkRunCommand {
33628
33834
  logger.error("Target is required. Use --target to specify the benchmark target.", undefined, {
33629
33835
  showTimestamp: false,
33630
33836
  showArrow: false,
33631
- useSymbol: false
33837
+ useSymbol: true
33632
33838
  });
33633
33839
  return;
33634
33840
  }
@@ -33647,7 +33853,7 @@ class BenchmarkRunCommand {
33647
33853
  logger.error(`No benchmark configuration found for target "${target}" in ${controllersLocalDir}`, undefined, {
33648
33854
  showTimestamp: false,
33649
33855
  showArrow: false,
33650
- useSymbol: false
33856
+ useSymbol: true
33651
33857
  });
33652
33858
  return;
33653
33859
  }
@@ -33661,36 +33867,40 @@ class BenchmarkRunCommand {
33661
33867
  const urlPath = this.buildUrl(config);
33662
33868
  const port = Bun.env.PORT ?? "80";
33663
33869
  const url = `http://localhost:${port}${urlPath}`;
33664
- logger.info(`Running benchmark: ${config.name || benchFile}`, undefined, {
33665
- showTimestamp: false,
33666
- showArrow: false,
33667
- useSymbol: false
33668
- });
33669
- if (config.description) {
33670
- logger.info(`Description: ${config.description}`, undefined, {
33671
- showTimestamp: false,
33672
- showArrow: false,
33673
- useSymbol: false
33674
- });
33675
- }
33870
+ const connections = config.connections ?? 10;
33871
+ const duration = config.duration ?? 10;
33872
+ printHeader(config, url, connections, duration);
33676
33873
  const opts = {
33677
33874
  url,
33678
- connections: config.connections ?? 10,
33679
- duration: config.duration ?? 10,
33875
+ connections,
33876
+ duration,
33680
33877
  method: config.method ?? "GET"
33681
33878
  };
33682
33879
  if (config.payload && Object.keys(config.payload).length > 0) {
33683
33880
  opts.body = JSON.stringify(config.payload);
33684
33881
  opts.headers = { "Content-Type": "application/json" };
33685
33882
  }
33686
- const result = await import_autocannon.default(opts);
33687
- logger.success(`Benchmark completed: ${config.name || benchFile}`, undefined, {
33688
- showTimestamp: false,
33689
- showArrow: false,
33690
- useSymbol: false
33883
+ const result = await new Promise((resolve, reject) => {
33884
+ const instance = import_autocannon.default(opts, (err, result2) => {
33885
+ if (err) {
33886
+ reject(err);
33887
+ } else {
33888
+ resolve(result2);
33889
+ }
33890
+ });
33891
+ import_autocannon.default.track(instance, {
33892
+ renderProgressBar: true,
33893
+ renderResultsTable: false,
33894
+ renderLatencyTable: false,
33895
+ progressBarString: ` ${dim("Progress")} [:bar] :percent ${dim(":elapsed/:eta")}`
33896
+ });
33897
+ process.once("SIGINT", () => {
33898
+ instance.stop();
33899
+ });
33691
33900
  });
33692
- process.stdout.write(`${import_autocannon.default.printResult(result)}
33901
+ process.stdout.write(`
33693
33902
  `);
33903
+ printResults(result);
33694
33904
  }
33695
33905
  }
33696
33906
  }
@@ -34419,7 +34629,7 @@ class MakeBenchmarkCommand {
34419
34629
  logger2.error(`Controller not found: ${controllerFilePath}`, undefined, {
34420
34630
  showTimestamp: false,
34421
34631
  showArrow: false,
34422
- useSymbol: false
34632
+ useSymbol: true
34423
34633
  });
34424
34634
  return;
34425
34635
  }
@@ -34451,7 +34661,7 @@ class MakeBenchmarkCommand {
34451
34661
  logger.success(`${join10(controllersLocalDir, benchmarkFileName)} created successfully`, undefined, {
34452
34662
  showTimestamp: false,
34453
34663
  showArrow: false,
34454
- useSymbol: false
34664
+ useSymbol: true
34455
34665
  });
34456
34666
  }
34457
34667
  }
@@ -50230,7 +50440,7 @@ class MigrationUpCommand {
50230
50440
  logger.warn("No modules with migrations found", undefined, {
50231
50441
  showTimestamp: false,
50232
50442
  showArrow: false,
50233
- useSymbol: false
50443
+ useSymbol: true
50234
50444
  });
50235
50445
  return;
50236
50446
  }
@@ -50249,7 +50459,7 @@ class MigrationUpCommand {
50249
50459
  logger.warn("No modules with migrations found", undefined, {
50250
50460
  showTimestamp: false,
50251
50461
  showArrow: false,
50252
- useSymbol: false
50462
+ useSymbol: true
50253
50463
  });
50254
50464
  return;
50255
50465
  }
@@ -50258,7 +50468,7 @@ class MigrationUpCommand {
50258
50468
  logger.info(`Running migrations for ${name}...`, undefined, {
50259
50469
  showTimestamp: false,
50260
50470
  showArrow: false,
50261
- useSymbol: false
50471
+ useSymbol: true
50262
50472
  });
50263
50473
  const args = ["bun", "run", migrationUpPath];
50264
50474
  if (options.drop) {
@@ -50274,13 +50484,13 @@ class MigrationUpCommand {
50274
50484
  logger.success(`Migrations completed for ${name}`, undefined, {
50275
50485
  showTimestamp: false,
50276
50486
  showArrow: false,
50277
- useSymbol: false
50487
+ useSymbol: true
50278
50488
  });
50279
50489
  } else {
50280
50490
  logger.error(`Migrations failed for ${name} (exit code: ${exitCode})`, undefined, {
50281
50491
  showTimestamp: false,
50282
50492
  showArrow: false,
50283
- useSymbol: false
50493
+ useSymbol: true
50284
50494
  });
50285
50495
  }
50286
50496
  }
@@ -50435,7 +50645,7 @@ class SeedRunCommand {
50435
50645
  logger.warn("No modules with seeds found", undefined, {
50436
50646
  showTimestamp: false,
50437
50647
  showArrow: false,
50438
- useSymbol: false
50648
+ useSymbol: true
50439
50649
  });
50440
50650
  return;
50441
50651
  }
@@ -50454,7 +50664,7 @@ class SeedRunCommand {
50454
50664
  logger.warn("No modules with seeds found", undefined, {
50455
50665
  showTimestamp: false,
50456
50666
  showArrow: false,
50457
- useSymbol: false
50667
+ useSymbol: true
50458
50668
  });
50459
50669
  return;
50460
50670
  }
@@ -50463,7 +50673,7 @@ class SeedRunCommand {
50463
50673
  logger.info(`Running seeds for ${name}...`, undefined, {
50464
50674
  showTimestamp: false,
50465
50675
  showArrow: false,
50466
- useSymbol: false
50676
+ useSymbol: true
50467
50677
  });
50468
50678
  const args = ["bun", "run", seedRunPath];
50469
50679
  if (options.drop) {
@@ -50479,13 +50689,13 @@ class SeedRunCommand {
50479
50689
  logger.success(`Seeds completed for ${name}`, undefined, {
50480
50690
  showTimestamp: false,
50481
50691
  showArrow: false,
50482
- useSymbol: false
50692
+ useSymbol: true
50483
50693
  });
50484
50694
  } else {
50485
50695
  logger.error(`Seeds failed for ${name} (exit code: ${exitCode})`, undefined, {
50486
50696
  showTimestamp: false,
50487
50697
  showArrow: false,
50488
- useSymbol: false
50698
+ useSymbol: true
50489
50699
  });
50490
50700
  }
50491
50701
  }
@@ -50497,4 +50707,4 @@ SeedRunCommand = __legacyDecorateClassTS([
50497
50707
  // src/index.ts
50498
50708
  await run();
50499
50709
 
50500
- //# debugId=41F87182B7D4D33B64756E2164756E21
50710
+ //# debugId=09575D96B4766A7164756E2164756E21