@devkong/cli 0.0.67-alpha.1 → 0.0.67-alpha.10

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.
@@ -1,28 +1,28 @@
1
- @echo off
2
-
3
- set EXTENSION_DIR=%1
4
- echo %EXTENSION_DIR%
5
-
6
- where python >nul 2>&1
7
- if %errorlevel% equ 0 (
8
- set PYTHON_CMD=python
9
- ) else (
10
- set PYTHON_CMD=python3
11
- )
12
-
13
- where pip >nul 2>&1
14
- if %errorlevel% equ 0 (
15
- set PIP_CMD=pip
16
- ) else (
17
- set PIP_CMD=pip3
18
- )
19
-
20
- cd %EXTENSION_DIR%
21
-
22
- %PYTHON_CMD% -m venv .venv
23
-
24
- call .venv\Scripts\activate.bat
25
-
26
- %PIP_CMD% freeze > requirements-lock.txt
27
- %PIP_CMD% install --default-timeout=120 -r requirements.txt -r requirements-dev.txt
28
- %PIP_CMD% freeze > requirements-lock.txt
1
+ @echo off
2
+
3
+ set EXTENSION_DIR=%1
4
+ echo %EXTENSION_DIR%
5
+
6
+ where python >nul 2>&1
7
+ if %errorlevel% equ 0 (
8
+ set PYTHON_CMD=python
9
+ ) else (
10
+ set PYTHON_CMD=python3
11
+ )
12
+
13
+ cd %EXTENSION_DIR%
14
+
15
+ REM Recreate the venv from scratch so a stale interpreter path (e.g. left over
16
+ REM after a Python upgrade or a moved/copied project) can't leave pip pointing
17
+ REM at a missing binary.
18
+ %PYTHON_CMD% -m venv --clear .venv
19
+ if errorlevel 1 exit /b 1
20
+
21
+ call .venv\Scripts\activate.bat
22
+
23
+ REM Invoke pip via `python -m pip` rather than the pip/pip3 wrapper so we don't
24
+ REM depend on the wrapper script's (possibly stale) shebang.
25
+ python -m pip freeze > requirements-lock.txt
26
+ python -m pip install --default-timeout=120 -r requirements.txt -r requirements-dev.txt
27
+ if errorlevel 1 exit /b 1
28
+ python -m pip freeze > requirements-lock.txt
@@ -1,4 +1,5 @@
1
1
  #!/bin/bash
2
+ set -e
2
3
 
3
4
  EXTENSION_DIR=$1
4
5
 
@@ -8,18 +9,17 @@ else
8
9
  PYTHON_CMD="python3"
9
10
  fi
10
11
 
11
- if [ -x "$(command -v python)" ]; then
12
- PIP_CMD="pip"
13
- else
14
- PIP_CMD="pip3"
15
- fi
16
-
17
12
  cd "$EXTENSION_DIR" || exit
18
13
 
19
- $PYTHON_CMD -m venv .venv
14
+ # Recreate the venv from scratch so a stale interpreter path (e.g. left over
15
+ # after a Python/nvm/pyenv upgrade) can't leave pip pointing at a missing
16
+ # binary, which fails with "cannot execute: required file not found".
17
+ $PYTHON_CMD -m venv --clear .venv
20
18
 
21
19
  source .venv/bin/activate
22
20
 
23
- $PIP_CMD freeze > requirements-lock.txt
24
- $PIP_CMD install --default-timeout=120 -r requirements-dev.txt -r requirements.txt
25
- $PIP_CMD freeze > requirements-lock.txt
21
+ # Invoke pip via `python -m pip` rather than the pip/pip3 wrapper so we don't
22
+ # depend on the wrapper script's (possibly stale) shebang.
23
+ python -m pip freeze > requirements-lock.txt
24
+ python -m pip install --default-timeout=120 -r requirements-dev.txt -r requirements.txt
25
+ python -m pip freeze > requirements-lock.txt
package/index.js CHANGED
@@ -60750,10 +60750,8 @@ async function spawnCommand(commandText, logger = null, shell = false) {
60750
60750
  }
60751
60751
  async function spawnCommandWithArgs(command, commandArgs, logger = null, shell = false) {
60752
60752
  return new Promise((resolve2, reject) => {
60753
- const child = (0, import_child_process.spawn)(command, commandArgs, {
60754
- shell: shell || process.platform !== "win32",
60755
- stdio: ["pipe", "pipe", "pipe"]
60756
- });
60753
+ const useShell = shell || process.platform !== "win32";
60754
+ const child = useShell ? (0, import_child_process.spawn)([command, ...commandArgs].join(" "), { shell: true, stdio: ["pipe", "pipe", "pipe"] }) : (0, import_child_process.spawn)(command, commandArgs, { shell: false, stdio: ["pipe", "pipe", "pipe"] });
60757
60755
  let stdout = "";
60758
60756
  let stderr = "";
60759
60757
  child.stdout.on("data", (data) => {
@@ -60797,13 +60795,6 @@ function printError(message2, error) {
60797
60795
  function escapePathSpaces(sourcePath) {
60798
60796
  return sourcePath.indexOf(" ") <= 0 ? sourcePath : `"${sourcePath}"`;
60799
60797
  }
60800
- function renderProgressBar(elapsedSeconds, timeoutSeconds, status) {
60801
- const width = 24;
60802
- const ratio = timeoutSeconds > 0 ? Math.min(1, elapsedSeconds / timeoutSeconds) : 0;
60803
- const filled = Math.round(width * ratio);
60804
- const bar = "\u2588".repeat(filled) + "\u2591".repeat(width - filled);
60805
- return `[${bar}] ${elapsedSeconds}s / ${timeoutSeconds}s \xB7 ${status}`;
60806
- }
60807
60798
 
60808
60799
  // packages/kong-cli/src/common/profile.ts
60809
60800
  var KONG_CONFIG_DIR = import_path3.default.join((0, import_os.homedir)(), ".kong");
@@ -60854,14 +60845,14 @@ var ConfigureCommand = class {
60854
60845
  const { profileName } = await dist_default14.prompt({
60855
60846
  type: "select",
60856
60847
  name: "profileName",
60857
- message: "Select a profile to configure:",
60848
+ message: "select a profile to configure:",
60858
60849
  choices: [...profileNames, "Create a new profile"]
60859
60850
  });
60860
60851
  if (profileName === "Create a new profile") {
60861
60852
  const { newProfileName } = await dist_default14.prompt({
60862
60853
  type: "input",
60863
60854
  name: "newProfileName",
60864
- message: "Enter name for the new profile:",
60855
+ message: "enter name for the new profile:",
60865
60856
  validate: (input) => profileNames.includes(input) ? "Profile already exists!" : true
60866
60857
  });
60867
60858
  return [newProfileName, createEmptyProfile()];
@@ -60872,20 +60863,20 @@ var ConfigureCommand = class {
60872
60863
  const answerUrl = await dist_default14.prompt({
60873
60864
  type: "input",
60874
60865
  name: "kongUrl",
60875
- message: `Enter URL for profile "${name}":`,
60866
+ message: `enter URL for profile "${name}":`,
60876
60867
  default: profile.kongBaseUrl
60877
60868
  });
60878
60869
  const answerUserName = await dist_default14.prompt({
60879
60870
  type: "input",
60880
60871
  name: "userName",
60881
- message: `Enter user name for profile "${name}":`,
60872
+ message: `enter user name for profile "${name}":`,
60882
60873
  default: profile.userName
60883
60874
  });
60884
60875
  const answerPassword = await dist_default14.prompt({
60885
60876
  type: "password",
60886
60877
  name: "password",
60887
60878
  mask: "*",
60888
- message: `Enter password for user "${answerUserName.userName}":`,
60879
+ message: `enter password for user "${answerUserName.userName}":`,
60889
60880
  default: ""
60890
60881
  });
60891
60882
  const updated = {
@@ -60897,7 +60888,7 @@ var ConfigureCommand = class {
60897
60888
  const entry = new import_keyring.Entry(updated.kongBaseUrl, updated.userName);
60898
60889
  entry.setPassword(answerPassword.password);
60899
60890
  }
60900
- console.log(`Configuration for profile "${name}" has been updated`);
60891
+ console.log(`configuration for profile "${name}" has been updated`);
60901
60892
  return updated;
60902
60893
  }
60903
60894
  };
@@ -62932,7 +62923,7 @@ var InstallCommand = class {
62932
62923
  async execute(workspaceDirectory) {
62933
62924
  await new Listr([
62934
62925
  {
62935
- title: "Installing dependencies with pip",
62926
+ title: "installing dependencies with pip",
62936
62927
  task: async (_2, task) => {
62937
62928
  const scriptPath = this.scriptPath();
62938
62929
  await spawnCommandWithArgs(
@@ -63103,12 +63094,12 @@ var ManagementClient = class {
63103
63094
  const url2 = joinUrlAndPath(this.baseUrl, "v1/extensions", extensionId, "/aliases");
63104
63095
  return (await axios_default.get(url2, await this.requestConfigProvider())).data;
63105
63096
  }
63106
- async getAuditLog(objectType2, objectId) {
63097
+ async getAuditLog(objectType2, objectId, createdAfter) {
63107
63098
  const url2 = joinUrlAndPath(this.baseUrl, "v1/audit");
63108
63099
  const config = await this.requestConfigProvider();
63109
63100
  const response = await axios_default.get(url2, {
63110
63101
  ...config,
63111
- params: { ...config.params, objectType: objectType2, objectId }
63102
+ params: { ...config.params, objectType: objectType2, objectId, createdAfter }
63112
63103
  });
63113
63104
  return response.data;
63114
63105
  }
@@ -63128,17 +63119,19 @@ var ListAliasesCommand = class {
63128
63119
  await new Listr(
63129
63120
  [
63130
63121
  {
63131
- title: "List extension aliases",
63122
+ title: "list extension aliases",
63132
63123
  task: async (ctx, task) => {
63133
63124
  const kongJson = getKongJson();
63134
63125
  const aliases = await this.managementClient.getExtensionSnapshotAliases(kongJson.id);
63135
63126
  if (aliases.length === 0) {
63136
- task.output = "No aliases available";
63127
+ task.output = "no aliases available";
63137
63128
  } else {
63138
63129
  const result = [];
63139
63130
  for (const alias of aliases) {
63140
63131
  for (const item of alias.use) {
63141
- result.push(`${alias.name}, ${item.snapshot.version}, ${item.balance}%`);
63132
+ result.push(
63133
+ `${alias.name}, ${item.snapshot.version}, ${item.balance ? `${item.balance}%` : "shadow"}`
63134
+ );
63142
63135
  }
63143
63136
  }
63144
63137
  task.output = result.join("\n");
@@ -63174,12 +63167,12 @@ var ListVersionsCommand = class {
63174
63167
  await new Listr(
63175
63168
  [
63176
63169
  {
63177
- title: "List extension snapshot versions",
63170
+ title: "list extension snapshot versions",
63178
63171
  task: async (ctx, task) => {
63179
63172
  const kongJson = getKongJson();
63180
63173
  const versions = await this.managementClient.getExtensionSnapshotVersions(kongJson.id);
63181
63174
  if (versions.length === 0) {
63182
- task.output = "No versions available";
63175
+ task.output = "no versions available";
63183
63176
  } else {
63184
63177
  const result = [];
63185
63178
  for (const ver of versions) {
@@ -63270,7 +63263,7 @@ var PublishVersionCommand = class {
63270
63263
  const kongJson = getKongJson();
63271
63264
  if (kongJson.sdk === "kotlin" && !this.contractPath) {
63272
63265
  yield {
63273
- title: "Build extension",
63266
+ title: "build extension",
63274
63267
  task: async (ctx, task) => {
63275
63268
  const logger = new ListrTaskLogger(task, this.verbose ? 3 /* DEBUG */ : 0 /* INFO */);
63276
63269
  const cmdText = this.getKotlinBuildCmdTask();
@@ -63281,7 +63274,7 @@ var PublishVersionCommand = class {
63281
63274
  };
63282
63275
  }
63283
63276
  yield {
63284
- title: "Generate schema",
63277
+ title: "generate schema",
63285
63278
  task: async (ctx, task) => {
63286
63279
  const logger = new ListrTaskLogger(task, this.verbose ? 3 /* DEBUG */ : 0 /* INFO */);
63287
63280
  if (this.contractPath) {
@@ -63296,13 +63289,13 @@ var PublishVersionCommand = class {
63296
63289
  rendererOptions: this.defaultRendererOptions
63297
63290
  };
63298
63291
  yield {
63299
- title: "Get publish details",
63292
+ title: "get publish details",
63300
63293
  task: async (ctx) => {
63301
63294
  ctx.publishDetails = await this.registryClient.getPublishDetails(appName);
63302
63295
  }
63303
63296
  };
63304
63297
  yield {
63305
- title: "Docker login",
63298
+ title: "docker login",
63306
63299
  task: async (ctx, task) => {
63307
63300
  const publishDetails = ctx.publishDetails;
63308
63301
  const regUrl = this.resolveRegistryUrl(publishDetails.repoName);
@@ -63314,7 +63307,7 @@ var PublishVersionCommand = class {
63314
63307
  rendererOptions: this.defaultRendererOptions
63315
63308
  };
63316
63309
  yield {
63317
- title: "Docker build",
63310
+ title: "docker build",
63318
63311
  task: async (ctx, task) => {
63319
63312
  const publishDetails = ctx.publishDetails;
63320
63313
  const regUrl = this.resolveRegistryUrl(publishDetails.repoName);
@@ -63327,7 +63320,7 @@ var PublishVersionCommand = class {
63327
63320
  rendererOptions: this.defaultRendererOptions
63328
63321
  };
63329
63322
  yield {
63330
- title: "Docker push",
63323
+ title: "docker push",
63331
63324
  task: async (ctx, task) => {
63332
63325
  const cmd = this.dockerPushCmdText(ctx.fullImageName);
63333
63326
  await spawnCommand(
@@ -63338,7 +63331,7 @@ var PublishVersionCommand = class {
63338
63331
  rendererOptions: this.defaultRendererOptions
63339
63332
  };
63340
63333
  yield {
63341
- title: "Save publish details",
63334
+ title: "save publish details",
63342
63335
  task: async (ctx, task) => {
63343
63336
  const publishDetails = ctx.publishDetails;
63344
63337
  let autoGeneratedContract;
@@ -63407,7 +63400,7 @@ var PublishVersionCommand = class {
63407
63400
  });
63408
63401
  await this.managementClient.createExtensionSnapshot(kongJson.id, snapshot);
63409
63402
  task.output = [
63410
- `The version ${publishDetails.imageVersion} has been successfully published!`,
63403
+ `the version ${publishDetails.imageVersion} has been successfully published!`,
63411
63404
  joinUrlAndPath(this.profile.kongBaseUrl, "/extensions/aliases")
63412
63405
  ].join("\n");
63413
63406
  },
@@ -63441,7 +63434,7 @@ var PublishVersionCommand = class {
63441
63434
 
63442
63435
  // packages/kong-cli/src/common/deployment.ts
63443
63436
  var DEPLOY_SUCCESS_ACTIONS = /* @__PURE__ */ new Set(["deployment completed"]);
63444
- var DEPLOY_FAILURE_ACTIONS = /* @__PURE__ */ new Set(["deployment failed", "save deployment details"]);
63437
+ var DEPLOY_FAILURE_ACTIONS = /* @__PURE__ */ new Set(["deployment failed"]);
63445
63438
  function isFailureEvent(event) {
63446
63439
  return event.eventType === "error" || DEPLOY_FAILURE_ACTIONS.has(event.action);
63447
63440
  }
@@ -63462,24 +63455,42 @@ function analyzeDeployment(events) {
63462
63455
  }
63463
63456
  async function getDeploymentLog(management, query) {
63464
63457
  const [aliasEvents, baseEvents] = await Promise.all([
63465
- management.getAuditLog(query.objectType, `${query.basedOnId}-${query.aliasName}`),
63466
- management.getAuditLog(query.objectType, query.basedOnId)
63458
+ management.getAuditLog(
63459
+ query.objectType,
63460
+ `${query.basedOnId}-${query.aliasName}`,
63461
+ query.createdAfter
63462
+ ),
63463
+ management.getAuditLog(query.objectType, query.basedOnId, query.createdAfter)
63467
63464
  ]);
63468
63465
  return [...aliasEvents, ...baseEvents].sort((a, b) => b.created.localeCompare(a.created));
63469
63466
  }
63467
+ function deploymentErrorMessage(events) {
63468
+ const failure = events.find(isFailureEvent);
63469
+ if (!failure) {
63470
+ return "Deployment failed.";
63471
+ }
63472
+ const data = failure.eventData;
63473
+ const detail = typeof data?.message === "string" ? data.message : typeof data?.error === "string" ? data.error : void 0;
63474
+ return detail ? `${failure.action}: ${detail}` : failure.action;
63475
+ }
63470
63476
  var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
63471
63477
  async function pollDeployment(management, input) {
63472
63478
  const interval = input.intervalMs ?? 2e3;
63473
63479
  const startedAt = Date.now();
63474
63480
  const deadline = startedAt + input.timeoutSeconds * 1e3;
63475
63481
  const elapsed = () => Math.min(input.timeoutSeconds, Math.round((Date.now() - startedAt) / 1e3));
63476
- const report = (status) => input.onProgress?.({ status, elapsedSeconds: elapsed(), timeoutSeconds: input.timeoutSeconds });
63482
+ const report = (current) => input.onProgress?.({
63483
+ status: current.status,
63484
+ events: current.events,
63485
+ elapsedSeconds: elapsed(),
63486
+ timeoutSeconds: input.timeoutSeconds
63487
+ });
63477
63488
  let result = analyzeDeployment(await getDeploymentLog(management, input));
63478
- report(result.status);
63489
+ report(result);
63479
63490
  while (!result.terminal && Date.now() < deadline) {
63480
63491
  await sleep(interval);
63481
63492
  result = analyzeDeployment(await getDeploymentLog(management, input));
63482
- report(result.status);
63493
+ report(result);
63483
63494
  }
63484
63495
  return {
63485
63496
  ...result,
@@ -63511,6 +63522,24 @@ function validateName(value) {
63511
63522
  );
63512
63523
  }
63513
63524
  }
63525
+ var DEPLOY_STEPS = [
63526
+ "create deployment",
63527
+ "save deployment details",
63528
+ "deployment completed"
63529
+ ];
63530
+ function createDeploySteps() {
63531
+ return DEPLOY_STEPS.map((action) => {
63532
+ const handlers = {
63533
+ resolve: () => void 0,
63534
+ reject: () => void 0
63535
+ };
63536
+ const done = new Promise((resolve2, reject) => {
63537
+ handlers.resolve = resolve2;
63538
+ handlers.reject = reject;
63539
+ });
63540
+ return { action, done, settle: (error) => error ? handlers.reject(error) : handlers.resolve() };
63541
+ });
63542
+ }
63514
63543
  var SetAliasCommand = class {
63515
63544
  constructor(profile) {
63516
63545
  this.profile = profile;
@@ -63520,10 +63549,12 @@ var SetAliasCommand = class {
63520
63549
  }
63521
63550
  async execute(aliasName, extensionVersion, timeoutSeconds) {
63522
63551
  validateName(aliasName);
63552
+ const startedAt = utcNow(DEFAULT_TIMEZONE);
63553
+ const steps = createDeploySteps();
63523
63554
  await new Listr(
63524
63555
  [
63525
63556
  {
63526
- title: "Get snapshot details",
63557
+ title: "get snapshot details",
63527
63558
  task: async (ctx, task) => {
63528
63559
  ctx.kongJson = getKongJson();
63529
63560
  ctx.snapshot = await this.managementClient.getExtensionSnapshot(
@@ -63536,7 +63567,7 @@ var SetAliasCommand = class {
63536
63567
  }
63537
63568
  },
63538
63569
  {
63539
- title: "Assign extension alias",
63570
+ title: "assign extension alias",
63540
63571
  task: async (ctx, task) => {
63541
63572
  const now = utcNow(DEFAULT_TIMEZONE);
63542
63573
  const aliasUse = {
@@ -63566,45 +63597,12 @@ var SetAliasCommand = class {
63566
63597
  updatedBy: ""
63567
63598
  };
63568
63599
  await this.publicClient.assignExtensionAlias(ctx.kongJson.id, alias);
63569
- task.output = [
63570
- "Please wait a moment for it to appear in the UI",
63571
- joinUrlAndPath(this.profile.kongBaseUrl, "/extensions/aliases")
63572
- ].join("\n");
63600
+ this.pollDeploymentSteps(steps, ctx.kongJson.id, aliasName, startedAt, timeoutSeconds);
63573
63601
  },
63574
63602
  rendererOptions: { persistentOutput: true }
63575
63603
  },
63576
- {
63577
- title: "Wait for deployment",
63578
- task: async (ctx, task) => {
63579
- let status = "pending";
63580
- const startedAt = Date.now();
63581
- const render = () => {
63582
- const elapsed = Math.min(timeoutSeconds, Math.round((Date.now() - startedAt) / 1e3));
63583
- task.output = renderProgressBar(elapsed, timeoutSeconds, status);
63584
- };
63585
- render();
63586
- const ticker = setInterval(render, 1e3);
63587
- try {
63588
- const result = await pollDeployment(this.managementClient, {
63589
- objectType: "extension_alias" /* EXTENSION_ALIAS */,
63590
- basedOnId: ctx.kongJson.id,
63591
- aliasName,
63592
- timeoutSeconds,
63593
- onProgress: (progress) => {
63594
- status = progress.status;
63595
- render();
63596
- }
63597
- });
63598
- if (result.status === "failed") {
63599
- throw new AppError("Deployment failed. Check the alias logs in the UI.");
63600
- }
63601
- task.output = result.timedOut ? `Still deploying after ${result.waitedSeconds}s \u2014 check the UI for completion.` : `Deployment ${result.status} in ${result.waitedSeconds}s.`;
63602
- } finally {
63603
- clearInterval(ticker);
63604
- }
63605
- },
63606
- rendererOptions: { persistentOutput: true }
63607
- }
63604
+ // Known deployment steps as a checklist; each ticks off on its event.
63605
+ ...steps.map((step) => ({ title: step.action, task: () => step.done }))
63608
63606
  ],
63609
63607
  {
63610
63608
  renderer: "default",
@@ -63616,6 +63614,47 @@ var SetAliasCommand = class {
63616
63614
  }
63617
63615
  ).run();
63618
63616
  }
63617
+ /**
63618
+ * Poll the deployment audit log and settle one step per matching event. Runs
63619
+ * detached from the task list; it settles a step as its event arrives and
63620
+ * fails the rest on a failed/timed-out deployment, stopping on the failed or
63621
+ * "deployment completed" event (poll terminal).
63622
+ */
63623
+ pollDeploymentSteps(steps, basedOnId, aliasName, createdAfter, timeoutSeconds) {
63624
+ const pending = new Map(steps.map((step) => [step.action, step]));
63625
+ const seen = /* @__PURE__ */ new Set();
63626
+ void pollDeployment(this.managementClient, {
63627
+ objectType: "EXTENSION_ALIAS",
63628
+ basedOnId,
63629
+ aliasName,
63630
+ createdAfter,
63631
+ timeoutSeconds,
63632
+ onProgress: (progress) => {
63633
+ for (const event of [...progress.events].reverse()) {
63634
+ if (seen.has(event.action)) {
63635
+ continue;
63636
+ }
63637
+ seen.add(event.action);
63638
+ pending.get(event.action)?.settle();
63639
+ }
63640
+ }
63641
+ }).then((result) => {
63642
+ if (result.status === "failed") {
63643
+ const error = new AppError(deploymentErrorMessage(result.events));
63644
+ steps.forEach((step) => step.settle(error));
63645
+ } else if (result.timedOut) {
63646
+ const error = new AppError(
63647
+ `Still deploying after ${result.waitedSeconds}s \u2014 check the UI for completion.`
63648
+ );
63649
+ steps.forEach((step) => step.settle(error));
63650
+ } else {
63651
+ steps.forEach((step) => step.settle());
63652
+ }
63653
+ }).catch((error) => {
63654
+ const wrapped = error instanceof Error ? error : new AppError(String(error));
63655
+ steps.forEach((step) => step.settle(wrapped));
63656
+ });
63657
+ }
63619
63658
  };
63620
63659
 
63621
63660
  // packages/kong-cli/src/common/cli.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devkong/cli",
3
- "version": "0.0.67-alpha.1",
3
+ "version": "0.0.67-alpha.10",
4
4
  "type": "commonjs",
5
5
  "main": "./index.js",
6
6
  "typings": "./index.d.ts",
@@ -5,4 +5,11 @@ export declare class SetAliasCommand {
5
5
  private managementClient;
6
6
  constructor(profile: Profile);
7
7
  execute(aliasName: string, extensionVersion: number, timeoutSeconds: number): Promise<void>;
8
+ /**
9
+ * Poll the deployment audit log and settle one step per matching event. Runs
10
+ * detached from the task list; it settles a step as its event arrives and
11
+ * fails the rest on a failed/timed-out deployment, stopping on the failed or
12
+ * "deployment completed" event (poll terminal).
13
+ */
14
+ private pollDeploymentSteps;
8
15
  }
@@ -1,12 +1,19 @@
1
- import { AppAuditLog, AuditObjectType } from "@kong/contract";
1
+ import { AppAuditLog } from "@kong/contract";
2
2
  import { Loading } from "@kong/ts";
3
3
  import { ManagementClient } from "../services/managementClient";
4
- /** Audit object types that carry a deployment trail. */
5
- export type DeployObjectType = AuditObjectType.EXTENSION_ALIAS | AuditObjectType.PROCESS_ALIAS;
4
+ /**
5
+ * Audit object types that carry a deployment trail. These are the management
6
+ * `AuditObjectType` JVM enum *constant names* (not the `extension_alias` JSON
7
+ * wire value): the `/v1/audit` `objectType` query param is resolved server-side
8
+ * via `Enum.valueOf`, which matches the constant name.
9
+ */
10
+ export type DeployObjectType = "EXTENSION_ALIAS" | "PROCESS_ALIAS";
6
11
  export interface DeploymentQuery {
7
12
  objectType: DeployObjectType;
8
13
  basedOnId: string;
9
14
  aliasName: string;
15
+ /** Only fetch audit events created at/after this UTC timestamp (ISO-8601). */
16
+ createdAfter?: string;
10
17
  }
11
18
  export interface DeploymentResult {
12
19
  /**
@@ -31,9 +38,17 @@ export declare function analyzeDeployment(events: AppAuditLog[]): DeploymentResu
31
38
  * `basedOnId`, so both object ids are fetched and merged newest-first.
32
39
  */
33
40
  export declare function getDeploymentLog(management: ManagementClient, query: DeploymentQuery): Promise<AppAuditLog[]>;
41
+ /**
42
+ * Best-effort human-readable reason for a failed deployment, pulled from the
43
+ * first failure event's `eventData` (falling back to its action label) so the
44
+ * actual backend error can be surfaced to the console.
45
+ */
46
+ export declare function deploymentErrorMessage(events: AppAuditLog[]): string;
34
47
  export interface PollProgress {
35
48
  /** Latest analyzed deployment status. */
36
49
  status: Loading;
50
+ /** Full deployment audit log analyzed so far, newest first. */
51
+ events: AppAuditLog[];
37
52
  /** Seconds elapsed since polling started (capped at `timeoutSeconds`). */
38
53
  elapsedSeconds: number;
39
54
  /** 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;
@@ -1,5 +1,6 @@
1
- import { AppAuditLog, AppExtension, AppExtensionAlias, AppSnapshot, AppSnapshotDetails, AuditObjectType } from "@kong/contract";
1
+ import { AppAuditLog, AppExtension, AppExtensionAlias, AppSnapshot, AppSnapshotDetails } from "@kong/contract";
2
2
  import { Optional, UrlText } from "@kong/ts";
3
+ import { DeployObjectType } from "../common/deployment";
3
4
  import { RequestConfigProvider } from "./api";
4
5
  export declare class ManagementClient {
5
6
  private requestConfigProvider;
@@ -10,5 +11,5 @@ export declare class ManagementClient {
10
11
  getExtensionSnapshot(extensionId: AppExtension["id"], extensionSnapshotVersion: AppSnapshot["version"]): Promise<Optional<AppSnapshotDetails>>;
11
12
  getExtensionSnapshotVersions(extensionId: AppExtension["id"]): Promise<AppSnapshot[]>;
12
13
  getExtensionSnapshotAliases(extensionId: AppExtension["id"]): Promise<AppExtensionAlias[]>;
13
- getAuditLog(objectType: AuditObjectType, objectId: string): Promise<AppAuditLog[]>;
14
+ getAuditLog(objectType: DeployObjectType, objectId: string, createdAfter?: string): Promise<AppAuditLog[]>;
14
15
  }
@@ -1,7 +1,7 @@
1
1
  export { makeServerlessJavaAppProps, serverlessFlowBuilder, stringifyServerlessFlow, } from "./lib/kongServerless";
2
2
  export type { FloweyServerlessBuilder } from "./lib/kongServerless";
3
3
  export type { KongSpecJobSession } from "./lib/kongSession";
4
- export type { KongSpecAction, KongSpecActionCallFunction, KongSpecActionCallProcess, KongSpecActionDelay, KongSpecActionInject, KongSpecActionSendEvent, KongSpecAnnotation, KongSpecBranch, KongSpecCache, KongSpecCallModel, KongSpecCircuitBreaker, KongSpecCondition, KongSpecEffect, KongSpecEffectStatus, KongSpecError, KongSpecEventBroker, KongSpecEventConnection, KongSpecFeatureCompensation, KongSpecFlow, KongSpecFunctionRef, KongSpecHowToInvoke, KongSpecHowToOutput, KongSpecHowToStore, KongSpecOutputAppend, KongSpecProcessRef, KongSpecRecord, KongSpecRecordHeader, KongSpecRetry, KongSpecRule, KongSpecSecretRef, KongSpecSecretType, KongSpecState, KongSpecStateCallFunction, KongSpecStateCallProcess, KongSpecStateCompensate, KongSpecStateDelay, KongSpecStateExit, KongSpecStateFail, KongSpecStateForeach, KongSpecStateInject, KongSpecStateParallel, KongSpecStateResult, KongSpecStateRule, KongSpecStateSendEvent, KongSpecStateStart, KongSpecStateSucceed, KongSpecStateSwitch, KongSpecStateWaitEvent, KongSpecStoreRetryControl, KongSpecSupportsActions, KongSpecSupportsErrors, KongSpecSupportsInvoke, KongSpecSupportsOutputSample, KongSpecSupportsOutputStore, KongSpecSupportsTransition, } from "./lib/kongSpec";
4
+ export type { KongSpecAction, KongSpecActionCallFunction, KongSpecActionCallProcess, KongSpecActionDelay, KongSpecActionInject, KongSpecActionSendEvent, KongSpecAnnotation, KongSpecBranch, KongSpecCache, KongSpecCallModel, KongSpecCircuitBreaker, KongSpecCondition, KongSpecEffect, KongSpecEffectStatus, KongSpecError, KongSpecEventBroker, KongSpecEventConnection, KongSpecFeatureCompensation, KongSpecFlow, KongSpecFunctionRef, KongSpecHowToInvoke, KongSpecHowToOutput, KongSpecHowToStore, KongSpecOutputAppend, KongSpecProcessRef, KongSpecRecord, KongSpecRecordHeader, KongSpecRetry, KongSpecRule, KongSpecSecretRef, KongSpecSecretType, KongSpecState, KongSpecStateCallFunction, KongSpecStateCallProcess, KongSpecStateCompensate, KongSpecStateDelay, KongSpecStateExit, KongSpecStateFail, KongSpecStateForeach, KongSpecStateInject, KongSpecStateParallel, KongSpecStateResult, KongSpecStateRule, KongSpecStateSendEvent, KongSpecStateStart, KongSpecStateSucceed, KongSpecStateSwitch, KongSpecStateWaitEvent, KongSpecStoreRetryControl, KongSpecSupportsActions, KongSpecSupportsErrors, KongSpecSupportsInvoke, KongSpecSupportsOutputSample, KongSpecSupportsOutputStore, KongSpecSupportsTaskMode, KongSpecSupportsTransition, } from "./lib/kongSpec";
5
5
  export { KongSpecBuild } from "./lib/kongSpecBuild";
6
6
  export { KongSpecDoc } from "./lib/kongSpecDoc";
7
7
  export { KongSpecEnv } from "./lib/kongSpecEnv";
@@ -14,5 +14,7 @@ export { KongSpecRef } from "./lib/kongSpecRef";
14
14
  export type { KongSpecActionPath, KongSpecStatePath } from "./lib/kongSpecRef";
15
15
  export { convertSpecToServerless } from "./lib/kongSpecToServerless";
16
16
  export { findSourceState, getActions, getConnectedExitStates, getDependencies, outputAggregator, outputAggregatorUnsafe, parallelStateOutputAggregator, parallelStateOutputAggregatorUnsafe, quoteSecretReferences, traverseFlowUp, } from "./lib/kongSpecUtils";
17
+ export { getKongFunctionOperations, getKongFunctionOperationSchema, getKongSpecXUI, getKongSpecXUIComponentConfig, isKongFunctionContractSchema, } from "./lib/kongSpecFunctionContract";
18
+ export type { KongSpecXUIComponentConfig, KongSpecXUIConfig, KongSpecXUIFormConfig, KongSpecXUISecretConfig, } from "./lib/kongSpecFunctionContract";
17
19
  export { validate } from "./lib/kongSpecValidate";
18
20
  export type { KongSpecValidationIssue, KongSpecValidators } from "./lib/kongSpecValidate";
@@ -106,7 +106,10 @@ export interface KongSpecSupportsDataGuards {
106
106
  export interface KongSpecSupportsOutputSample {
107
107
  outputSample: Optional<JsonText>;
108
108
  }
109
- export interface KongSpecCallModel extends KongSpecSupportsInput, KongSpecSupportsOutputFilter, KongSpecSupportsOutputStore, KongSpecSupportsOutputAppend, KongSpecSupportsOutputSample, KongSpecSupportsDataGuards, KongSpecSupportsInvoke {
109
+ export interface KongSpecSupportsTaskMode {
110
+ mode: "blocking" | "non-blocking";
111
+ }
112
+ export interface KongSpecCallModel extends KongSpecSupportsInput, KongSpecSupportsOutputFilter, KongSpecSupportsOutputStore, KongSpecSupportsOutputAppend, KongSpecSupportsOutputSample, KongSpecSupportsDataGuards, KongSpecSupportsTaskMode, KongSpecSupportsInvoke {
110
113
  }
111
114
  export interface KongSpecSupportsErrors {
112
115
  errors: KongSpecError[];
@@ -15,6 +15,7 @@ export declare class KongSpecDoc {
15
15
  static aboutIdentify: string;
16
16
  static aboutSizeLimit: (bytes: string) => string;
17
17
  static aboutCallFunction: string;
18
+ static aboutMode: string;
18
19
  static aboutCallProcess: string;
19
20
  static aboutCompensate: string;
20
21
  static aboutFail: string;
@@ -0,0 +1,26 @@
1
+ import { Optional } from "@kong/ts";
2
+ import { JSONSchema7 } from "json-schema";
3
+ import { KongSpecSecretType } from "./kongSpec";
4
+ export interface KongSpecXUISecretConfig {
5
+ purpose: string;
6
+ types: Array<KongSpecSecretType>;
7
+ }
8
+ export interface KongSpecXUIComponentConfig {
9
+ type: "TEXT_AREA";
10
+ }
11
+ export type KongSpecXUIFormConfig = Record<string, KongSpecXUIComponentConfig>;
12
+ export interface KongSpecXUIConfig {
13
+ version?: number;
14
+ secrets: Array<KongSpecXUISecretConfig>;
15
+ form: KongSpecXUIFormConfig;
16
+ }
17
+ /** Reads the `x-ui` block of a schema, if present. */
18
+ export declare function getKongSpecXUI(schema: Optional<JSONSchema7> | null): Optional<KongSpecXUIConfig>;
19
+ /** Reads the `x-ui.form` component config for a property path (e.g. `[".notes"]`). */
20
+ export declare function getKongSpecXUIComponentConfig(schema: Optional<JSONSchema7> | null, path: string[]): Optional<KongSpecXUIComponentConfig>;
21
+ /** True when the schema describes a KongFunctionContract (i.e. it exposes a `request` envelope). */
22
+ export declare function isKongFunctionContractSchema(schema: Optional<JSONSchema7> | null): boolean;
23
+ /** The operation names of a contract schema — all object properties except `request`. */
24
+ export declare function getKongFunctionOperations(schema: Optional<JSONSchema7> | null): string[];
25
+ /** The sub-schema describing the payload of a single operation. */
26
+ export declare function getKongFunctionOperationSchema(schema: Optional<JSONSchema7> | null, operation: string): Optional<JSONSchema7>;
@@ -8,7 +8,7 @@ interface TestItem {
8
8
  interface Dependency {
9
9
  type: "function" | "process";
10
10
  tenant: SessionTenant;
11
- basedOn: KongSpecFunctionRef["basedOn"] | KongSpecFunctionRef["basedOn"];
11
+ basedOn: KongSpecFunctionRef["basedOn"] | KongSpecProcessRef["basedOn"];
12
12
  aliasName: KongSpecFunctionRef["aliasName"] | KongSpecProcessRef["aliasName"];
13
13
  usage: Array<KongSpecAction["name"] | KongSpecState["name"]>;
14
14
  }
@@ -1,5 +1,5 @@
1
1
  import { AppSnapshot } from "./appSnapshot";
2
2
  export interface AppAliasUse {
3
3
  snapshot: AppSnapshot;
4
- balance: number;
4
+ balance: number | null;
5
5
  }
@@ -3,7 +3,7 @@ import { AppAliasUse } from "./appAliasUse";
3
3
  import { AppSnapshotDetails } from "./appSnapshotDetails";
4
4
  export interface AppAliasUseDetails extends AppAliasUse {
5
5
  snapshot: AppSnapshotDetails;
6
- balance: number;
6
+ balance: number | null;
7
7
  inputFilter?: JqFilter;
8
8
  outputFilter?: JqFilter;
9
9
  }