@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.
- package/assets/python-install.bat +28 -28
- package/assets/python-install.sh +10 -10
- package/index.js +118 -78
- package/package.json +1 -1
- package/packages/kong-cli/src/commands/setAliasCommand.d.ts +7 -0
- package/packages/kong-cli/src/common/deployment.d.ts +18 -3
- package/packages/kong-cli/src/common/utils.d.ts +1 -3
- package/packages/kong-cli/src/services/managementClient.d.ts +3 -2
- package/packages/kong-spec/src/index.d.ts +3 -1
- package/packages/kong-spec/src/lib/kongSpec.d.ts +4 -1
- package/packages/kong-spec/src/lib/kongSpecDoc.d.ts +1 -0
- package/packages/kong-spec/src/lib/kongSpecFunctionContract.d.ts +26 -0
- package/packages/kong-spec/src/lib/kongSpecUtils.d.ts +1 -1
- package/packages/kong-ts-contract/src/lib/appAliasUse.d.ts +1 -1
- package/packages/kong-ts-contract/src/lib/appAliasUseDetails.d.ts +1 -1
|
@@ -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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
)
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
+
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
|
package/assets/python-install.sh
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
|
60754
|
-
|
|
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: "
|
|
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: "
|
|
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: `
|
|
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: `
|
|
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: `
|
|
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(`
|
|
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: "
|
|
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: "
|
|
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 = "
|
|
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(
|
|
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: "
|
|
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 = "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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: "
|
|
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
|
-
`
|
|
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"
|
|
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(
|
|
63466
|
-
|
|
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 = (
|
|
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
|
|
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
|
|
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: "
|
|
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: "
|
|
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
|
-
|
|
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
|
-
|
|
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
|
@@ -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
|
|
1
|
+
import { AppAuditLog } from "@kong/contract";
|
|
2
2
|
import { Loading } from "@kong/ts";
|
|
3
3
|
import { ManagementClient } from "../services/managementClient";
|
|
4
|
-
/**
|
|
5
|
-
|
|
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 {
|
|
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
|
|
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:
|
|
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
|
|
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"] |
|
|
11
|
+
basedOn: KongSpecFunctionRef["basedOn"] | KongSpecProcessRef["basedOn"];
|
|
12
12
|
aliasName: KongSpecFunctionRef["aliasName"] | KongSpecProcessRef["aliasName"];
|
|
13
13
|
usage: Array<KongSpecAction["name"] | KongSpecState["name"]>;
|
|
14
14
|
}
|
|
@@ -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
|
}
|