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

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
  };
@@ -61095,7 +61086,8 @@ var GenerateCommand = class {
61095
61086
  id,
61096
61087
  platform: sdk,
61097
61088
  nxCloud: "skip",
61098
- packageManager: "npm"
61089
+ packageManager: "npm",
61090
+ trustThirdPartyPreset: true
61099
61091
  });
61100
61092
  }
61101
61093
  };
@@ -62932,7 +62924,7 @@ var InstallCommand = class {
62932
62924
  async execute(workspaceDirectory) {
62933
62925
  await new Listr([
62934
62926
  {
62935
- title: "Installing dependencies with pip",
62927
+ title: "installing dependencies with pip",
62936
62928
  task: async (_2, task) => {
62937
62929
  const scriptPath = this.scriptPath();
62938
62930
  await spawnCommandWithArgs(
@@ -63103,12 +63095,12 @@ var ManagementClient = class {
63103
63095
  const url2 = joinUrlAndPath(this.baseUrl, "v1/extensions", extensionId, "/aliases");
63104
63096
  return (await axios_default.get(url2, await this.requestConfigProvider())).data;
63105
63097
  }
63106
- async getAuditLog(objectType2, objectId) {
63098
+ async getAuditLog(objectType2, objectId, createdAfter) {
63107
63099
  const url2 = joinUrlAndPath(this.baseUrl, "v1/audit");
63108
63100
  const config = await this.requestConfigProvider();
63109
63101
  const response = await axios_default.get(url2, {
63110
63102
  ...config,
63111
- params: { ...config.params, objectType: objectType2, objectId }
63103
+ params: { ...config.params, objectType: objectType2, objectId, createdAfter }
63112
63104
  });
63113
63105
  return response.data;
63114
63106
  }
@@ -63128,17 +63120,19 @@ var ListAliasesCommand = class {
63128
63120
  await new Listr(
63129
63121
  [
63130
63122
  {
63131
- title: "List extension aliases",
63123
+ title: "list extension aliases",
63132
63124
  task: async (ctx, task) => {
63133
63125
  const kongJson = getKongJson();
63134
63126
  const aliases = await this.managementClient.getExtensionSnapshotAliases(kongJson.id);
63135
63127
  if (aliases.length === 0) {
63136
- task.output = "No aliases available";
63128
+ task.output = "no aliases available";
63137
63129
  } else {
63138
63130
  const result = [];
63139
63131
  for (const alias of aliases) {
63140
63132
  for (const item of alias.use) {
63141
- result.push(`${alias.name}, ${item.snapshot.version}, ${item.balance}%`);
63133
+ result.push(
63134
+ `${alias.name}, ${item.snapshot.version}, ${item.balance ? `${item.balance}%` : "shadow"}`
63135
+ );
63142
63136
  }
63143
63137
  }
63144
63138
  task.output = result.join("\n");
@@ -63174,12 +63168,12 @@ var ListVersionsCommand = class {
63174
63168
  await new Listr(
63175
63169
  [
63176
63170
  {
63177
- title: "List extension snapshot versions",
63171
+ title: "list extension snapshot versions",
63178
63172
  task: async (ctx, task) => {
63179
63173
  const kongJson = getKongJson();
63180
63174
  const versions = await this.managementClient.getExtensionSnapshotVersions(kongJson.id);
63181
63175
  if (versions.length === 0) {
63182
- task.output = "No versions available";
63176
+ task.output = "no versions available";
63183
63177
  } else {
63184
63178
  const result = [];
63185
63179
  for (const ver of versions) {
@@ -63270,7 +63264,7 @@ var PublishVersionCommand = class {
63270
63264
  const kongJson = getKongJson();
63271
63265
  if (kongJson.sdk === "kotlin" && !this.contractPath) {
63272
63266
  yield {
63273
- title: "Build extension",
63267
+ title: "build extension",
63274
63268
  task: async (ctx, task) => {
63275
63269
  const logger = new ListrTaskLogger(task, this.verbose ? 3 /* DEBUG */ : 0 /* INFO */);
63276
63270
  const cmdText = this.getKotlinBuildCmdTask();
@@ -63281,7 +63275,7 @@ var PublishVersionCommand = class {
63281
63275
  };
63282
63276
  }
63283
63277
  yield {
63284
- title: "Generate schema",
63278
+ title: "generate schema",
63285
63279
  task: async (ctx, task) => {
63286
63280
  const logger = new ListrTaskLogger(task, this.verbose ? 3 /* DEBUG */ : 0 /* INFO */);
63287
63281
  if (this.contractPath) {
@@ -63296,13 +63290,13 @@ var PublishVersionCommand = class {
63296
63290
  rendererOptions: this.defaultRendererOptions
63297
63291
  };
63298
63292
  yield {
63299
- title: "Get publish details",
63293
+ title: "get publish details",
63300
63294
  task: async (ctx) => {
63301
63295
  ctx.publishDetails = await this.registryClient.getPublishDetails(appName);
63302
63296
  }
63303
63297
  };
63304
63298
  yield {
63305
- title: "Docker login",
63299
+ title: "docker login",
63306
63300
  task: async (ctx, task) => {
63307
63301
  const publishDetails = ctx.publishDetails;
63308
63302
  const regUrl = this.resolveRegistryUrl(publishDetails.repoName);
@@ -63314,7 +63308,7 @@ var PublishVersionCommand = class {
63314
63308
  rendererOptions: this.defaultRendererOptions
63315
63309
  };
63316
63310
  yield {
63317
- title: "Docker build",
63311
+ title: "docker build",
63318
63312
  task: async (ctx, task) => {
63319
63313
  const publishDetails = ctx.publishDetails;
63320
63314
  const regUrl = this.resolveRegistryUrl(publishDetails.repoName);
@@ -63327,7 +63321,7 @@ var PublishVersionCommand = class {
63327
63321
  rendererOptions: this.defaultRendererOptions
63328
63322
  };
63329
63323
  yield {
63330
- title: "Docker push",
63324
+ title: "docker push",
63331
63325
  task: async (ctx, task) => {
63332
63326
  const cmd = this.dockerPushCmdText(ctx.fullImageName);
63333
63327
  await spawnCommand(
@@ -63338,7 +63332,7 @@ var PublishVersionCommand = class {
63338
63332
  rendererOptions: this.defaultRendererOptions
63339
63333
  };
63340
63334
  yield {
63341
- title: "Save publish details",
63335
+ title: "save publish details",
63342
63336
  task: async (ctx, task) => {
63343
63337
  const publishDetails = ctx.publishDetails;
63344
63338
  let autoGeneratedContract;
@@ -63407,7 +63401,7 @@ var PublishVersionCommand = class {
63407
63401
  });
63408
63402
  await this.managementClient.createExtensionSnapshot(kongJson.id, snapshot);
63409
63403
  task.output = [
63410
- `The version ${publishDetails.imageVersion} has been successfully published!`,
63404
+ `the version ${publishDetails.imageVersion} has been successfully published!`,
63411
63405
  joinUrlAndPath(this.profile.kongBaseUrl, "/extensions/aliases")
63412
63406
  ].join("\n");
63413
63407
  },
@@ -63441,7 +63435,7 @@ var PublishVersionCommand = class {
63441
63435
 
63442
63436
  // packages/kong-cli/src/common/deployment.ts
63443
63437
  var DEPLOY_SUCCESS_ACTIONS = /* @__PURE__ */ new Set(["deployment completed"]);
63444
- var DEPLOY_FAILURE_ACTIONS = /* @__PURE__ */ new Set(["deployment failed", "save deployment details"]);
63438
+ var DEPLOY_FAILURE_ACTIONS = /* @__PURE__ */ new Set(["deployment failed"]);
63445
63439
  function isFailureEvent(event) {
63446
63440
  return event.eventType === "error" || DEPLOY_FAILURE_ACTIONS.has(event.action);
63447
63441
  }
@@ -63462,24 +63456,42 @@ function analyzeDeployment(events) {
63462
63456
  }
63463
63457
  async function getDeploymentLog(management, query) {
63464
63458
  const [aliasEvents, baseEvents] = await Promise.all([
63465
- management.getAuditLog(query.objectType, `${query.basedOnId}-${query.aliasName}`),
63466
- management.getAuditLog(query.objectType, query.basedOnId)
63459
+ management.getAuditLog(
63460
+ query.objectType,
63461
+ `${query.basedOnId}-${query.aliasName}`,
63462
+ query.createdAfter
63463
+ ),
63464
+ management.getAuditLog(query.objectType, query.basedOnId, query.createdAfter)
63467
63465
  ]);
63468
63466
  return [...aliasEvents, ...baseEvents].sort((a, b) => b.created.localeCompare(a.created));
63469
63467
  }
63468
+ function deploymentErrorMessage(events) {
63469
+ const failure = events.find(isFailureEvent);
63470
+ if (!failure) {
63471
+ return "Deployment failed.";
63472
+ }
63473
+ const data = failure.eventData;
63474
+ const detail = typeof data?.message === "string" ? data.message : typeof data?.error === "string" ? data.error : void 0;
63475
+ return detail ? `${failure.action}: ${detail}` : failure.action;
63476
+ }
63470
63477
  var sleep = (ms) => new Promise((resolve2) => setTimeout(resolve2, ms));
63471
63478
  async function pollDeployment(management, input) {
63472
63479
  const interval = input.intervalMs ?? 2e3;
63473
63480
  const startedAt = Date.now();
63474
63481
  const deadline = startedAt + input.timeoutSeconds * 1e3;
63475
63482
  const elapsed = () => Math.min(input.timeoutSeconds, Math.round((Date.now() - startedAt) / 1e3));
63476
- const report = (status) => input.onProgress?.({ status, elapsedSeconds: elapsed(), timeoutSeconds: input.timeoutSeconds });
63483
+ const report = (current) => input.onProgress?.({
63484
+ status: current.status,
63485
+ events: current.events,
63486
+ elapsedSeconds: elapsed(),
63487
+ timeoutSeconds: input.timeoutSeconds
63488
+ });
63477
63489
  let result = analyzeDeployment(await getDeploymentLog(management, input));
63478
- report(result.status);
63490
+ report(result);
63479
63491
  while (!result.terminal && Date.now() < deadline) {
63480
63492
  await sleep(interval);
63481
63493
  result = analyzeDeployment(await getDeploymentLog(management, input));
63482
- report(result.status);
63494
+ report(result);
63483
63495
  }
63484
63496
  return {
63485
63497
  ...result,
@@ -63511,6 +63523,24 @@ function validateName(value) {
63511
63523
  );
63512
63524
  }
63513
63525
  }
63526
+ var DEPLOY_STEPS = [
63527
+ "create deployment",
63528
+ "save deployment details",
63529
+ "deployment completed"
63530
+ ];
63531
+ function createDeploySteps() {
63532
+ return DEPLOY_STEPS.map((action) => {
63533
+ const handlers = {
63534
+ resolve: () => void 0,
63535
+ reject: () => void 0
63536
+ };
63537
+ const done = new Promise((resolve2, reject) => {
63538
+ handlers.resolve = resolve2;
63539
+ handlers.reject = reject;
63540
+ });
63541
+ return { action, done, settle: (error) => error ? handlers.reject(error) : handlers.resolve() };
63542
+ });
63543
+ }
63514
63544
  var SetAliasCommand = class {
63515
63545
  constructor(profile) {
63516
63546
  this.profile = profile;
@@ -63520,10 +63550,12 @@ var SetAliasCommand = class {
63520
63550
  }
63521
63551
  async execute(aliasName, extensionVersion, timeoutSeconds) {
63522
63552
  validateName(aliasName);
63553
+ const startedAt = utcNow(DEFAULT_TIMEZONE);
63554
+ const steps = createDeploySteps();
63523
63555
  await new Listr(
63524
63556
  [
63525
63557
  {
63526
- title: "Get snapshot details",
63558
+ title: "get snapshot details",
63527
63559
  task: async (ctx, task) => {
63528
63560
  ctx.kongJson = getKongJson();
63529
63561
  ctx.snapshot = await this.managementClient.getExtensionSnapshot(
@@ -63536,7 +63568,7 @@ var SetAliasCommand = class {
63536
63568
  }
63537
63569
  },
63538
63570
  {
63539
- title: "Assign extension alias",
63571
+ title: "assign extension alias",
63540
63572
  task: async (ctx, task) => {
63541
63573
  const now = utcNow(DEFAULT_TIMEZONE);
63542
63574
  const aliasUse = {
@@ -63566,45 +63598,12 @@ var SetAliasCommand = class {
63566
63598
  updatedBy: ""
63567
63599
  };
63568
63600
  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");
63601
+ this.pollDeploymentSteps(steps, ctx.kongJson.id, aliasName, startedAt, timeoutSeconds);
63573
63602
  },
63574
63603
  rendererOptions: { persistentOutput: true }
63575
63604
  },
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
- }
63605
+ // Known deployment steps as a checklist; each ticks off on its event.
63606
+ ...steps.map((step) => ({ title: step.action, task: () => step.done }))
63608
63607
  ],
63609
63608
  {
63610
63609
  renderer: "default",
@@ -63616,6 +63615,47 @@ var SetAliasCommand = class {
63616
63615
  }
63617
63616
  ).run();
63618
63617
  }
63618
+ /**
63619
+ * Poll the deployment audit log and settle one step per matching event. Runs
63620
+ * detached from the task list; it settles a step as its event arrives and
63621
+ * fails the rest on a failed/timed-out deployment, stopping on the failed or
63622
+ * "deployment completed" event (poll terminal).
63623
+ */
63624
+ pollDeploymentSteps(steps, basedOnId, aliasName, createdAfter, timeoutSeconds) {
63625
+ const pending = new Map(steps.map((step) => [step.action, step]));
63626
+ const seen = /* @__PURE__ */ new Set();
63627
+ void pollDeployment(this.managementClient, {
63628
+ objectType: "EXTENSION_ALIAS",
63629
+ basedOnId,
63630
+ aliasName,
63631
+ createdAfter,
63632
+ timeoutSeconds,
63633
+ onProgress: (progress) => {
63634
+ for (const event of [...progress.events].reverse()) {
63635
+ if (seen.has(event.action)) {
63636
+ continue;
63637
+ }
63638
+ seen.add(event.action);
63639
+ pending.get(event.action)?.settle();
63640
+ }
63641
+ }
63642
+ }).then((result) => {
63643
+ if (result.status === "failed") {
63644
+ const error = new AppError(deploymentErrorMessage(result.events));
63645
+ steps.forEach((step) => step.settle(error));
63646
+ } else if (result.timedOut) {
63647
+ const error = new AppError(
63648
+ `Still deploying after ${result.waitedSeconds}s \u2014 check the UI for completion.`
63649
+ );
63650
+ steps.forEach((step) => step.settle(error));
63651
+ } else {
63652
+ steps.forEach((step) => step.settle());
63653
+ }
63654
+ }).catch((error) => {
63655
+ const wrapped = error instanceof Error ? error : new AppError(String(error));
63656
+ steps.forEach((step) => step.settle(wrapped));
63657
+ });
63658
+ }
63619
63659
  };
63620
63660
 
63621
63661
  // 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.11",
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
  }