@devkong/cli 0.0.67-alpha.2 → 0.0.67-alpha.4

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/index.js CHANGED
@@ -60795,13 +60795,6 @@ function printError(message2, error) {
60795
60795
  function escapePathSpaces(sourcePath) {
60796
60796
  return sourcePath.indexOf(" ") <= 0 ? sourcePath : `"${sourcePath}"`;
60797
60797
  }
60798
- function renderProgressBar(elapsedSeconds, timeoutSeconds, status) {
60799
- const width = 24;
60800
- const ratio = timeoutSeconds > 0 ? Math.min(1, elapsedSeconds / timeoutSeconds) : 0;
60801
- const filled = Math.round(width * ratio);
60802
- const bar = "\u2588".repeat(filled) + "\u2591".repeat(width - filled);
60803
- return `[${bar}] ${elapsedSeconds}s / ${timeoutSeconds}s \xB7 ${status}`;
60804
- }
60805
60798
 
60806
60799
  // packages/kong-cli/src/common/profile.ts
60807
60800
  var KONG_CONFIG_DIR = import_path3.default.join((0, import_os.homedir)(), ".kong");
@@ -63465,19 +63458,33 @@ async function getDeploymentLog(management, query) {
63465
63458
  ]);
63466
63459
  return [...aliasEvents, ...baseEvents].sort((a, b) => b.created.localeCompare(a.created));
63467
63460
  }
63461
+ function deploymentErrorMessage(events) {
63462
+ const failure = events.find(isFailureEvent);
63463
+ if (!failure) {
63464
+ return "Deployment failed.";
63465
+ }
63466
+ const data = failure.eventData;
63467
+ const detail = typeof data?.message === "string" ? data.message : typeof data?.error === "string" ? data.error : void 0;
63468
+ return detail ? `${failure.action}: ${detail}` : failure.action;
63469
+ }
63468
63470
  var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
63469
63471
  async function pollDeployment(management, input) {
63470
63472
  const interval = input.intervalMs ?? 2e3;
63471
63473
  const startedAt = Date.now();
63472
63474
  const deadline = startedAt + input.timeoutSeconds * 1e3;
63473
63475
  const elapsed = () => Math.min(input.timeoutSeconds, Math.round((Date.now() - startedAt) / 1e3));
63474
- const report = (status) => input.onProgress?.({ status, elapsedSeconds: elapsed(), timeoutSeconds: input.timeoutSeconds });
63476
+ const report = (current) => input.onProgress?.({
63477
+ status: current.status,
63478
+ events: current.events,
63479
+ elapsedSeconds: elapsed(),
63480
+ timeoutSeconds: input.timeoutSeconds
63481
+ });
63475
63482
  let result = analyzeDeployment(await getDeploymentLog(management, input));
63476
- report(result.status);
63483
+ report(result);
63477
63484
  while (!result.terminal && Date.now() < deadline) {
63478
63485
  await sleep(interval);
63479
63486
  result = analyzeDeployment(await getDeploymentLog(management, input));
63480
- report(result.status);
63487
+ report(result);
63481
63488
  }
63482
63489
  return {
63483
63490
  ...result,
@@ -63564,44 +63571,39 @@ var SetAliasCommand = class {
63564
63571
  updatedBy: ""
63565
63572
  };
63566
63573
  await this.publicClient.assignExtensionAlias(ctx.kongJson.id, alias);
63567
- task.output = [
63568
- "Please wait a moment for it to appear in the UI",
63569
- joinUrlAndPath(this.profile.kongBaseUrl, "/extensions/aliases")
63570
- ].join("\n");
63574
+ task.output = joinUrlAndPath(this.profile.kongBaseUrl, "/extensions/aliases");
63571
63575
  },
63572
63576
  rendererOptions: { persistentOutput: true }
63573
63577
  },
63574
63578
  {
63575
63579
  title: "Wait for deployment",
63576
63580
  task: async (ctx, task) => {
63577
- let status = "pending";
63578
- const startedAt = Date.now();
63579
- const render = () => {
63580
- const elapsed = Math.min(timeoutSeconds, Math.round((Date.now() - startedAt) / 1e3));
63581
- task.output = renderProgressBar(elapsed, timeoutSeconds, status);
63582
- };
63583
- render();
63584
- const ticker = setInterval(render, 1e3);
63585
- try {
63586
- const result = await pollDeployment(this.managementClient, {
63587
- objectType: "EXTENSION_ALIAS",
63588
- basedOnId: ctx.kongJson.id,
63589
- aliasName,
63590
- timeoutSeconds,
63591
- onProgress: (progress) => {
63592
- status = progress.status;
63593
- render();
63581
+ const seen = /* @__PURE__ */ new Set();
63582
+ const printNewEvents = (events) => {
63583
+ for (const event of [...events].reverse()) {
63584
+ const key = `${event.created}|${event.action}`;
63585
+ if (seen.has(key)) {
63586
+ continue;
63594
63587
  }
63595
- });
63596
- if (result.status === "failed") {
63597
- throw new AppError("Deployment failed. Check the alias logs in the UI.");
63588
+ seen.add(key);
63589
+ task.output = `${event.eventType === "error" ? "\u2717" : "\u2713"} ${event.action}`;
63598
63590
  }
63599
- task.output = result.timedOut ? `Still deploying after ${result.waitedSeconds}s \u2014 check the UI for completion.` : `Deployment ${result.status} in ${result.waitedSeconds}s.`;
63600
- } finally {
63601
- clearInterval(ticker);
63591
+ };
63592
+ const result = await pollDeployment(this.managementClient, {
63593
+ objectType: "EXTENSION_ALIAS",
63594
+ basedOnId: ctx.kongJson.id,
63595
+ aliasName,
63596
+ timeoutSeconds,
63597
+ onProgress: (progress) => printNewEvents(progress.events)
63598
+ });
63599
+ if (result.status === "failed") {
63600
+ throw new AppError(deploymentErrorMessage(result.events));
63601
+ }
63602
+ if (result.timedOut) {
63603
+ task.output = `Still deploying after ${result.waitedSeconds}s \u2014 check the UI for completion.`;
63602
63604
  }
63603
63605
  },
63604
- rendererOptions: { persistentOutput: true }
63606
+ rendererOptions: { bottomBar: Infinity, persistentOutput: true }
63605
63607
  }
63606
63608
  ],
63607
63609
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devkong/cli",
3
- "version": "0.0.67-alpha.2",
3
+ "version": "0.0.67-alpha.4",
4
4
  "type": "commonjs",
5
5
  "main": "./index.js",
6
6
  "typings": "./index.d.ts",
@@ -36,9 +36,17 @@ export declare function analyzeDeployment(events: AppAuditLog[]): DeploymentResu
36
36
  * `basedOnId`, so both object ids are fetched and merged newest-first.
37
37
  */
38
38
  export declare function getDeploymentLog(management: ManagementClient, query: DeploymentQuery): Promise<AppAuditLog[]>;
39
+ /**
40
+ * Best-effort human-readable reason for a failed deployment, pulled from the
41
+ * first failure event's `eventData` (falling back to its action label) so the
42
+ * actual backend error can be surfaced to the console.
43
+ */
44
+ export declare function deploymentErrorMessage(events: AppAuditLog[]): string;
39
45
  export interface PollProgress {
40
46
  /** Latest analyzed deployment status. */
41
47
  status: Loading;
48
+ /** Full deployment audit log analyzed so far, newest first. */
49
+ events: AppAuditLog[];
42
50
  /** Seconds elapsed since polling started (capped at `timeoutSeconds`). */
43
51
  elapsedSeconds: number;
44
52
  /** The configured deploy-wait budget. */
@@ -1,4 +1,4 @@
1
- import { Loading, Optional, ShortUUID } from "@kong/ts";
1
+ import { Optional, ShortUUID } from "@kong/ts";
2
2
  export interface ILogger {
3
3
  info(message: string): void;
4
4
  debug(message: string): void;
@@ -14,5 +14,3 @@ export declare function spawnCommand(commandText: string, logger?: ILogger | nul
14
14
  export declare function spawnCommandWithArgs(command: string, commandArgs: string[], logger?: ILogger | null, shell?: boolean): Promise<string>;
15
15
  export declare function printError(message: string, error: unknown): void;
16
16
  export declare function escapePathSpaces(sourcePath: string): string;
17
- /** Render a fixed-width textual progress bar for live task output. */
18
- export declare function renderProgressBar(elapsedSeconds: number, timeoutSeconds: number, status: Loading): string;