@kolatts/pncli 6.0.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/{chunk-WDWAPTVC.js → chunk-GHZMFNSX.js} +12 -1
- package/dist/chunk-GHZMFNSX.js.map +1 -0
- package/dist/{chunk-BOFSNQQ2.js → chunk-MBJ4ZYL7.js} +2 -1
- package/dist/chunk-MBJ4ZYL7.js.map +1 -0
- package/dist/{chunk-4FR4WGNR.js → chunk-RZV64BWP.js} +36 -2
- package/dist/chunk-RZV64BWP.js.map +1 -0
- package/dist/cli.js +434 -91
- package/dist/cli.js.map +1 -1
- package/dist/{config-5LC7ZTEP.js → config-DYIXSPLA.js} +2 -2
- package/dist/{http-DJSGEGD6.js → http-F24ORY6C.js} +3 -3
- package/dist/{output-HDUIIXUI.js → output-XE6XDAAR.js} +2 -2
- package/package.json +1 -1
- package/skills/pncli/SKILL.md +2 -1
- package/skills/pncli/elasticsearch.md +53 -0
- package/skills/pncli/marketplace.md +1 -1
- package/skills/pncli/openshift.md +17 -0
- package/dist/chunk-4FR4WGNR.js.map +0 -1
- package/dist/chunk-BOFSNQQ2.js.map +0 -1
- package/dist/chunk-WDWAPTVC.js.map +0 -1
- /package/dist/{config-5LC7ZTEP.js.map → config-DYIXSPLA.js.map} +0 -0
- /package/dist/{http-DJSGEGD6.js.map → http-F24ORY6C.js.map} +0 -0
- /package/dist/{output-HDUIIXUI.js.map → output-XE6XDAAR.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -28,13 +28,13 @@ import {
|
|
|
28
28
|
windowsListCredentials,
|
|
29
29
|
writeGlobalConfig,
|
|
30
30
|
writeRepoConfig
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-GHZMFNSX.js";
|
|
32
32
|
import {
|
|
33
33
|
configureTls,
|
|
34
34
|
createHttpClient,
|
|
35
35
|
describeFetchError,
|
|
36
36
|
validateAlationAccessToken
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-RZV64BWP.js";
|
|
38
38
|
import {
|
|
39
39
|
ExitCode,
|
|
40
40
|
fail,
|
|
@@ -44,7 +44,7 @@ import {
|
|
|
44
44
|
success,
|
|
45
45
|
warn,
|
|
46
46
|
writeRawOutput
|
|
47
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-MBJ4ZYL7.js";
|
|
48
48
|
import {
|
|
49
49
|
PncliError
|
|
50
50
|
} from "./chunk-HRNOAQDN.js";
|
|
@@ -579,6 +579,20 @@ function getGitContext(config) {
|
|
|
579
579
|
return { root, branch, project, repo, ado: adoContext, github: githubContext };
|
|
580
580
|
}
|
|
581
581
|
|
|
582
|
+
// src/lib/dates.ts
|
|
583
|
+
function parseDateOption(flag, value) {
|
|
584
|
+
const date = new Date(value);
|
|
585
|
+
if (Number.isNaN(date.getTime())) {
|
|
586
|
+
throw new PncliError(`Invalid ${flag} value "${value}". Use an ISO 8601 date such as 2025-01-31 or 2025-01-31T09:00:00Z.`, 1);
|
|
587
|
+
}
|
|
588
|
+
return date;
|
|
589
|
+
}
|
|
590
|
+
function inDateRange(time, after, before) {
|
|
591
|
+
if (after && time < after.getTime()) return false;
|
|
592
|
+
if (before && time >= before.getTime()) return false;
|
|
593
|
+
return true;
|
|
594
|
+
}
|
|
595
|
+
|
|
582
596
|
// src/services/bitbucket/client.ts
|
|
583
597
|
var API = "/rest/api/1.0";
|
|
584
598
|
var BitbucketClient = class {
|
|
@@ -587,19 +601,32 @@ var BitbucketClient = class {
|
|
|
587
601
|
}
|
|
588
602
|
http;
|
|
589
603
|
async listPRs(opts) {
|
|
590
|
-
|
|
604
|
+
const userFilters = {};
|
|
605
|
+
let n = 1;
|
|
606
|
+
if (opts.author) {
|
|
607
|
+
userFilters[`username.${n}`] = opts.author;
|
|
608
|
+
userFilters[`role.${n}`] = "AUTHOR";
|
|
609
|
+
n++;
|
|
610
|
+
}
|
|
611
|
+
if (opts.reviewer) {
|
|
612
|
+
userFilters[`username.${n}`] = opts.reviewer;
|
|
613
|
+
userFilters[`role.${n}`] = "REVIEWER";
|
|
614
|
+
}
|
|
615
|
+
const prs = await this.http.paginate(
|
|
591
616
|
(start, limit) => this.http.bitbucket(
|
|
592
617
|
`${API}/projects/${opts.project}/repos/${opts.repo}/pull-requests`,
|
|
593
618
|
{
|
|
594
619
|
params: {
|
|
595
620
|
state: opts.state ?? "OPEN",
|
|
596
|
-
...
|
|
621
|
+
...userFilters,
|
|
597
622
|
start,
|
|
598
623
|
limit
|
|
599
624
|
}
|
|
600
625
|
}
|
|
601
626
|
)
|
|
602
627
|
);
|
|
628
|
+
if (!opts.createdAfter && !opts.createdBefore) return prs;
|
|
629
|
+
return prs.filter((pr) => inDateRange(pr.createdDate, opts.createdAfter, opts.createdBefore));
|
|
603
630
|
}
|
|
604
631
|
async getPR(project, repo, id2) {
|
|
605
632
|
return this.http.bitbucket(
|
|
@@ -716,8 +743,8 @@ var BitbucketClient = class {
|
|
|
716
743
|
}
|
|
717
744
|
async resolveComment(project, repo, prId, commentId, version) {
|
|
718
745
|
await this.http.bitbucket(
|
|
719
|
-
`${API}/projects/${project}/repos/${repo}/pull-requests/${prId}/comments/${commentId}
|
|
720
|
-
{ method: "PUT",
|
|
746
|
+
`${API}/projects/${project}/repos/${repo}/pull-requests/${prId}/comments/${commentId}`,
|
|
747
|
+
{ method: "PUT", body: { version, threadResolved: true } }
|
|
721
748
|
);
|
|
722
749
|
}
|
|
723
750
|
async deleteComment(project, repo, prId, commentId, version) {
|
|
@@ -790,6 +817,12 @@ var BitbucketClient = class {
|
|
|
790
817
|
const pr = await this.getPR(project, repo, prId);
|
|
791
818
|
return pr.reviewers;
|
|
792
819
|
}
|
|
820
|
+
async listDefaultReviewers(project, repo) {
|
|
821
|
+
const result = await this.http.bitbucket(
|
|
822
|
+
`/rest/default-reviewers/1.0/projects/${encodeURIComponent(project)}/repos/${encodeURIComponent(repo)}/conditions`
|
|
823
|
+
);
|
|
824
|
+
return Array.isArray(result) ? result : [];
|
|
825
|
+
}
|
|
793
826
|
async addReviewer(project, repo, prId, username) {
|
|
794
827
|
return this.http.bitbucket(
|
|
795
828
|
`${API}/projects/${project}/repos/${repo}/pull-requests/${prId}/participants`,
|
|
@@ -2110,23 +2143,28 @@ var JiraClient = class {
|
|
|
2110
2143
|
}
|
|
2111
2144
|
});
|
|
2112
2145
|
}
|
|
2113
|
-
async search(jql, maxResults, customFields) {
|
|
2146
|
+
async search(jql, maxResults, customFields, startAt, fieldsOverride) {
|
|
2114
2147
|
const standardFields = ["summary", "status", "priority", "assignee", "issuetype", "project", "created", "updated", "labels", "reporter"];
|
|
2115
|
-
const fields = customFields?.length ? [...standardFields, ...customFields.map((f) => f.id)] : standardFields;
|
|
2116
|
-
|
|
2117
|
-
|
|
2148
|
+
const fields = fieldsOverride?.length ? fieldsOverride : customFields?.length ? [...standardFields, ...customFields.map((f) => f.id)] : standardFields;
|
|
2149
|
+
const first = startAt ?? 0;
|
|
2150
|
+
const issues = [];
|
|
2151
|
+
let total = 0;
|
|
2152
|
+
let next = first;
|
|
2153
|
+
while (true) {
|
|
2154
|
+
const pageSize = maxResults === void 0 ? 100 : Math.min(100, maxResults - issues.length);
|
|
2155
|
+
if (pageSize <= 0 && issues.length > 0) break;
|
|
2156
|
+
const page = await this.http.jira(`${API2}/search`, {
|
|
2118
2157
|
method: "POST",
|
|
2119
|
-
body: { jql, maxResults, fields }
|
|
2158
|
+
body: { jql, startAt: next, maxResults: pageSize, fields }
|
|
2120
2159
|
});
|
|
2160
|
+
const items = page.issues ?? [];
|
|
2161
|
+
issues.push(...items);
|
|
2162
|
+
total = page.total;
|
|
2163
|
+
next += items.length;
|
|
2164
|
+
if (next >= total || items.length === 0) break;
|
|
2165
|
+
if (maxResults !== void 0 && issues.length >= maxResults) break;
|
|
2121
2166
|
}
|
|
2122
|
-
|
|
2123
|
-
const result = await this.http.jira(`${API2}/search`, {
|
|
2124
|
-
method: "POST",
|
|
2125
|
-
body: { jql, startAt, maxResults: max, fields }
|
|
2126
|
-
});
|
|
2127
|
-
return { ...result, values: result.issues };
|
|
2128
|
-
});
|
|
2129
|
-
return { issues: allIssues, total: allIssues.length, startAt: 0, maxResults: allIssues.length };
|
|
2167
|
+
return { issues, total, startAt: first, maxResults: issues.length };
|
|
2130
2168
|
}
|
|
2131
2169
|
async fetchFields() {
|
|
2132
2170
|
const fields = await this.http.jira(`${API2}/field`);
|
|
@@ -2277,6 +2315,10 @@ var JiraClient = class {
|
|
|
2277
2315
|
function schemaToPncliType(schema) {
|
|
2278
2316
|
if (!schema) return void 0;
|
|
2279
2317
|
const custom = schema.custom ?? "";
|
|
2318
|
+
if (custom.endsWith(":gh-epic-link")) return "string";
|
|
2319
|
+
if (custom.endsWith(":gh-sprint")) return "number";
|
|
2320
|
+
if (custom.endsWith(":gh-lexo-rank")) return "string";
|
|
2321
|
+
if (custom.endsWith(":jpo-custom-field-parent")) return "string";
|
|
2280
2322
|
if (custom.includes("cascadingselect")) return "cascading-select";
|
|
2281
2323
|
if (custom.includes("multicheckboxes") || custom.includes("multiselect")) return "multi-select";
|
|
2282
2324
|
if (custom.includes("select") || custom.includes("radiobuttons")) return "select";
|
|
@@ -2521,6 +2563,13 @@ function resolveJqlInput(jql, jqlFile) {
|
|
|
2521
2563
|
if (!trimmed) throw new PncliError("JQL query is empty", 1);
|
|
2522
2564
|
return trimmed;
|
|
2523
2565
|
}
|
|
2566
|
+
function parseStartAt(raw) {
|
|
2567
|
+
if (raw === void 0) return void 0;
|
|
2568
|
+
if (!/^\d+$/.test(raw)) {
|
|
2569
|
+
throw new PncliError(`--start-at must be a non-negative integer, got "${raw}"`, 1);
|
|
2570
|
+
}
|
|
2571
|
+
return parseInt(raw, 10);
|
|
2572
|
+
}
|
|
2524
2573
|
function registerJiraCommands(program2) {
|
|
2525
2574
|
const jira = program2.command("jira").description("Jira Data Cloud operations");
|
|
2526
2575
|
jira.command("get-issue").description("Get a Jira issue by key").requiredOption("--key <issue-key>", "Issue key (e.g. PROJ-123)").action(async (opts) => {
|
|
@@ -2680,14 +2729,24 @@ function registerJiraCommands(program2) {
|
|
|
2680
2729
|
fail(err, "jira", "list-comments", start);
|
|
2681
2730
|
}
|
|
2682
2731
|
});
|
|
2683
|
-
jira.command("search").description("Search Jira issues with JQL (consider --output-file for large results)").option("--jql <query>", "JQL query string").option("--jql-file <path>", "Path to a file containing the JQL query ('-' = stdin)").option("--max-results <n>", "Maximum number of results").action(async (opts) => {
|
|
2732
|
+
jira.command("search").description("Search Jira issues with JQL (consider --output-file for large results)").option("--jql <query>", "JQL query string").option("--jql-file <path>", "Path to a file containing the JQL query ('-' = stdin)").option("--max-results <n>", "Maximum number of results").option("--start-at <n>", "Index of the first result to return (for resuming or paging)").option("--fields <list>", 'Comma-separated fields to return instead of the default set (names or ids, e.g. summary,status,"Story Points")').action(async (opts) => {
|
|
2684
2733
|
const start = Date.now();
|
|
2685
2734
|
try {
|
|
2686
2735
|
const { client, fieldMap, customFields } = getClientAndFields(program2);
|
|
2687
2736
|
const jql = resolveJqlInput(opts.jql, opts.jqlFile);
|
|
2737
|
+
let fieldsOverride;
|
|
2738
|
+
if (opts.fields !== void 0) {
|
|
2739
|
+
fieldsOverride = opts.fields.split(",").map((s) => s.trim()).filter(Boolean).map((name) => {
|
|
2740
|
+
const id2 = resolveFieldKey(name, fieldMap);
|
|
2741
|
+
if (id2 === void 0) throw new PncliError(`Unknown field in --fields: "${name}". Use a field id or a registered custom field name.`, 1);
|
|
2742
|
+
return id2;
|
|
2743
|
+
});
|
|
2744
|
+
if (fieldsOverride.length === 0) throw new PncliError("--fields must list at least one field", 1);
|
|
2745
|
+
}
|
|
2688
2746
|
const maxResults = opts.maxResults ? parseInt(opts.maxResults, 10) : void 0;
|
|
2747
|
+
const startAt = parseStartAt(opts.startAt);
|
|
2689
2748
|
const translatedJql = translateJql(jql, fieldMap);
|
|
2690
|
-
const data = await client.search(translatedJql, maxResults, customFields);
|
|
2749
|
+
const data = await client.search(translatedJql, maxResults, customFields, startAt, fieldsOverride);
|
|
2691
2750
|
const translatedIssues = data.issues.map((issue) => ({
|
|
2692
2751
|
...issue,
|
|
2693
2752
|
fields: translateFieldsInOutput(issue.fields, fieldMap)
|
|
@@ -2932,11 +2991,13 @@ function registerBitbucketCommands(program2) {
|
|
|
2932
2991
|
fail(err, "bitbucket", "create-repo", start);
|
|
2933
2992
|
}
|
|
2934
2993
|
});
|
|
2935
|
-
bb.command("list-prs").description("List pull requests").option("--state <state>", "PR state: OPEN|MERGED|DECLINED|ALL", "OPEN").option("--author <username>", "Filter by author username").option("--reviewer <username>", "Filter by reviewer username").action(async (opts) => {
|
|
2994
|
+
bb.command("list-prs").description("List pull requests").option("--state <state>", "PR state: OPEN|MERGED|DECLINED|ALL", "OPEN").option("--author <username>", "Filter by author username").option("--reviewer <username>", "Filter by reviewer username").option("--created-after <date>", "Only PRs created on/after this ISO 8601 date (e.g. 2025-01-31)").option("--created-before <date>", "Only PRs created before this ISO 8601 date").action(async (opts) => {
|
|
2936
2995
|
const start = Date.now();
|
|
2937
2996
|
try {
|
|
2997
|
+
const createdAfter = opts.createdAfter ? parseDateOption("--created-after", opts.createdAfter) : void 0;
|
|
2998
|
+
const createdBefore = opts.createdBefore ? parseDateOption("--created-before", opts.createdBefore) : void 0;
|
|
2938
2999
|
const { client, project, repo } = getClient2(bb);
|
|
2939
|
-
const data = await client.listPRs({ project, repo, state: opts.state, author: opts.author, reviewer: opts.reviewer });
|
|
3000
|
+
const data = await client.listPRs({ project, repo, state: opts.state, author: opts.author, reviewer: opts.reviewer, createdAfter, createdBefore });
|
|
2940
3001
|
success(data, "bitbucket", "list-prs", start);
|
|
2941
3002
|
} catch (err) {
|
|
2942
3003
|
fail(err, "bitbucket", "list-prs", start);
|
|
@@ -3015,8 +3076,8 @@ function registerBitbucketCommands(program2) {
|
|
|
3015
3076
|
const { client, project, repo } = getClient2(bb);
|
|
3016
3077
|
const prId = parseInt(opts.id, 10);
|
|
3017
3078
|
const pr = await client.getPR(project, repo, prId);
|
|
3018
|
-
const reviewers = opts.reviewers ? opts.reviewers.split(",").map((s) => s.trim()) :
|
|
3019
|
-
const data = await client.updatePR({ project, repo, id: prId, title: opts.title, description: opts.description, reviewers, version: pr.version });
|
|
3079
|
+
const reviewers = opts.reviewers ? opts.reviewers.split(",").map((s) => s.trim()) : (pr.reviewers ?? []).map((r) => r.user.name);
|
|
3080
|
+
const data = await client.updatePR({ project, repo, id: prId, title: opts.title ?? pr.title, description: opts.description ?? pr.description, reviewers, version: pr.version });
|
|
3020
3081
|
success(data, "bitbucket", "update-pr", start);
|
|
3021
3082
|
} catch (err) {
|
|
3022
3083
|
fail(err, "bitbucket", "update-pr", start);
|
|
@@ -3098,7 +3159,7 @@ function registerBitbucketCommands(program2) {
|
|
|
3098
3159
|
fail(err, "bitbucket", "reply-comment", start);
|
|
3099
3160
|
}
|
|
3100
3161
|
});
|
|
3101
|
-
bb.command("resolve-comment").description("Resolve a comment on a pull request").requiredOption("--pr <pr-id>", "Pull request ID").requiredOption("--comment-id <id>", "Comment ID").option("--comment-version <n>", "Comment version, as reported by list-comments", "0").action(async (opts) => {
|
|
3162
|
+
bb.command("resolve-comment").description("Resolve a comment thread on a pull request (use the root comment ID, not a reply)").requiredOption("--pr <pr-id>", "Pull request ID").requiredOption("--comment-id <id>", "Comment ID").option("--comment-version <n>", "Comment version, as reported by list-comments", "0").action(async (opts) => {
|
|
3102
3163
|
const start = Date.now();
|
|
3103
3164
|
try {
|
|
3104
3165
|
const { client, project, repo } = getClient2(bb);
|
|
@@ -3179,6 +3240,16 @@ function registerBitbucketCommands(program2) {
|
|
|
3179
3240
|
fail(err, "bitbucket", "list-reviewers", start);
|
|
3180
3241
|
}
|
|
3181
3242
|
});
|
|
3243
|
+
bb.command("list-default-reviewers").description("List the default-reviewer conditions configured for a repository").action(async () => {
|
|
3244
|
+
const start = Date.now();
|
|
3245
|
+
try {
|
|
3246
|
+
const { client, project, repo } = getClient2(bb);
|
|
3247
|
+
const data = await client.listDefaultReviewers(project, repo);
|
|
3248
|
+
success(data, "bitbucket", "list-default-reviewers", start);
|
|
3249
|
+
} catch (err) {
|
|
3250
|
+
fail(err, "bitbucket", "list-default-reviewers", start);
|
|
3251
|
+
}
|
|
3252
|
+
});
|
|
3182
3253
|
bb.command("add-reviewer").description("Add a reviewer to a pull request").requiredOption("--pr <pr-id>", "Pull request ID").requiredOption("--user <username>", "Username to add as a reviewer").action(async (opts) => {
|
|
3183
3254
|
const start = Date.now();
|
|
3184
3255
|
try {
|
|
@@ -3221,7 +3292,7 @@ var GitHubClient = class {
|
|
|
3221
3292
|
}
|
|
3222
3293
|
http;
|
|
3223
3294
|
async listPRs(opts) {
|
|
3224
|
-
|
|
3295
|
+
const prs = await this.http.githubPaginate(
|
|
3225
3296
|
(page, perPage) => this.http.github(
|
|
3226
3297
|
`/repos/${opts.owner}/${opts.repo}/pulls`,
|
|
3227
3298
|
{
|
|
@@ -3235,6 +3306,10 @@ var GitHubClient = class {
|
|
|
3235
3306
|
}
|
|
3236
3307
|
)
|
|
3237
3308
|
);
|
|
3309
|
+
const author = opts.author?.toLowerCase();
|
|
3310
|
+
return prs.filter(
|
|
3311
|
+
(pr) => (!author || pr.user?.login?.toLowerCase() === author) && inDateRange(Date.parse(pr.created_at), opts.createdAfter, opts.createdBefore)
|
|
3312
|
+
);
|
|
3238
3313
|
}
|
|
3239
3314
|
async getPR(owner, repo, pullNumber) {
|
|
3240
3315
|
return this.http.github(`/repos/${owner}/${repo}/pulls/${pullNumber}`);
|
|
@@ -3777,16 +3852,21 @@ function registerGitHubCommands(program2) {
|
|
|
3777
3852
|
fail(err, "github", "create-issue", start);
|
|
3778
3853
|
}
|
|
3779
3854
|
});
|
|
3780
|
-
gh.command("list-prs").description("List pull requests").addOption(new Option("--state <state>", "PR state").choices(["open", "closed", "all"]).default("open")).option("--head <branch>", "Filter by head branch (user:branch)").option("--base <branch>", "Filter by base branch").action(async (opts) => {
|
|
3855
|
+
gh.command("list-prs").description("List pull requests").addOption(new Option("--state <state>", "PR state").choices(["open", "closed", "all"]).default("open")).option("--head <branch>", "Filter by head branch (user:branch)").option("--base <branch>", "Filter by base branch").option("--author <login>", "Filter by author login").option("--created-after <date>", "Only PRs created on/after this ISO 8601 date (e.g. 2025-01-31)").option("--created-before <date>", "Only PRs created before this ISO 8601 date").action(async (opts) => {
|
|
3781
3856
|
const start = Date.now();
|
|
3782
3857
|
try {
|
|
3858
|
+
const createdAfter = opts.createdAfter ? parseDateOption("--created-after", opts.createdAfter) : void 0;
|
|
3859
|
+
const createdBefore = opts.createdBefore ? parseDateOption("--created-before", opts.createdBefore) : void 0;
|
|
3783
3860
|
const { client, owner, repo } = getClient3(gh);
|
|
3784
3861
|
const data = await client.listPRs({
|
|
3785
3862
|
owner,
|
|
3786
3863
|
repo,
|
|
3787
3864
|
state: opts.state,
|
|
3788
3865
|
head: opts.head,
|
|
3789
|
-
base: opts.base
|
|
3866
|
+
base: opts.base,
|
|
3867
|
+
author: opts.author,
|
|
3868
|
+
createdAfter,
|
|
3869
|
+
createdBefore
|
|
3790
3870
|
});
|
|
3791
3871
|
success(data, "github", "list-prs", start);
|
|
3792
3872
|
} catch (err) {
|
|
@@ -7109,7 +7189,7 @@ var AdoWorkClient = class {
|
|
|
7109
7189
|
const result = await this.http.ado(
|
|
7110
7190
|
`/${encodeURIComponent(collection)}/${encodeURIComponent(project)}/_apis/wit/workItems/${workItemId}/comments?api-version=${API_PREVIEW}`
|
|
7111
7191
|
);
|
|
7112
|
-
return result.value ?? [];
|
|
7192
|
+
return result.comments ?? result.value ?? [];
|
|
7113
7193
|
}
|
|
7114
7194
|
async addComment(collection, project, workItemId, text) {
|
|
7115
7195
|
return this.http.ado(
|
|
@@ -7356,7 +7436,7 @@ function registerSauceLabsCommands(program2) {
|
|
|
7356
7436
|
function run(action, fn) {
|
|
7357
7437
|
return async (...args) => {
|
|
7358
7438
|
const start = Date.now();
|
|
7359
|
-
const { success: success2, fail: fail2 } = await import("./output-
|
|
7439
|
+
const { success: success2, fail: fail2 } = await import("./output-XE6XDAAR.js");
|
|
7360
7440
|
try {
|
|
7361
7441
|
success2(await fn(getHttp(program2), ...args), SERVICE, action, start);
|
|
7362
7442
|
} catch (err) {
|
|
@@ -7982,6 +8062,18 @@ async function runCredentialChecks(cfg, http) {
|
|
|
7982
8062
|
results.logscale = categorize(err);
|
|
7983
8063
|
}
|
|
7984
8064
|
}
|
|
8065
|
+
if (!cfg.elasticsearch.apiKey) {
|
|
8066
|
+
results.elasticsearch = { status: "blank", message: "not configured" };
|
|
8067
|
+
} else if (!cfg.elasticsearch.baseUrl) {
|
|
8068
|
+
results.elasticsearch = { status: "error", message: "baseUrl not configured" };
|
|
8069
|
+
} else {
|
|
8070
|
+
try {
|
|
8071
|
+
await http.elasticsearch("/_cluster/health", { timeoutMs: 1e4 });
|
|
8072
|
+
results.elasticsearch = { status: "valid", message: "ok" };
|
|
8073
|
+
} catch (err) {
|
|
8074
|
+
results.elasticsearch = categorize(err);
|
|
8075
|
+
}
|
|
8076
|
+
}
|
|
7985
8077
|
if (!cfg.splitio.adminApiKey) {
|
|
7986
8078
|
results.splitio = { status: "blank", message: "not configured" };
|
|
7987
8079
|
} else if (!cfg.splitio.baseUrl) {
|
|
@@ -9417,7 +9509,7 @@ function pullMarketplace(marketplacePath, m, marketplaceName) {
|
|
|
9417
9509
|
}
|
|
9418
9510
|
const updated = !pullOutput.includes("Already up to date");
|
|
9419
9511
|
if (pullOutput.trim() && updated) warn(pullOutput.trim());
|
|
9420
|
-
warn(updated ? `"${marketplaceName}" updated.` : `"${marketplaceName}" already up to date \u2014
|
|
9512
|
+
warn(updated ? `"${marketplaceName}" updated.` : `"${marketplaceName}" already up to date \u2014 refreshing installed plugins from the local clone.`);
|
|
9421
9513
|
return { updated };
|
|
9422
9514
|
}
|
|
9423
9515
|
function installPluginsForMarketplace(marketplacePath, marketplaceName, repoUrl, pluginNames, targetDir) {
|
|
@@ -9467,13 +9559,6 @@ function installMarketplaceToTarget(m, marketplacePath, pluginChoices, pluginFil
|
|
|
9467
9559
|
} else {
|
|
9468
9560
|
requested = [pluginFilter];
|
|
9469
9561
|
}
|
|
9470
|
-
const missing = requested.filter((name) => !installedHere.includes(name));
|
|
9471
|
-
if (!opts.updated && !opts.force) {
|
|
9472
|
-
if (missing.length === 0) {
|
|
9473
|
-
return { ...base, plugins: {}, total: 0, skipped: true, message: "No changes detected \u2014 skipping install. Use --force to reinstall anyway." };
|
|
9474
|
-
}
|
|
9475
|
-
requested = missing;
|
|
9476
|
-
}
|
|
9477
9562
|
const { results, totalInstalled } = installPluginsForMarketplace(marketplacePath, marketplaceName, m.repoUrl, requested, target.target);
|
|
9478
9563
|
return { ...base, plugins: results, total: totalInstalled };
|
|
9479
9564
|
}
|
|
@@ -10107,7 +10192,7 @@ Plugin skills always install at user scope. --agent picks the host (default: ${D
|
|
|
10107
10192
|
fail(err, "skills", "marketplace-remove", start);
|
|
10108
10193
|
}
|
|
10109
10194
|
});
|
|
10110
|
-
marketplace.command("sync").description("With no arguments, refreshes every already-installed plugin from every marketplace (same as --marketplace all --installed-only). Pass --force, a plugin, or --marketplace to get the interactive picker instead.").argument("[plugin]", 'Plugin name to install, or "all" to install every plugin (skips interactive selection)').option("--marketplace <name>", 'Marketplace name to sync, or "all" to sync every registered marketplace (skips interactive selection)').option("--agent <agent>", `Target agent host: ${AGENT_CHOICES} (default: ${DEFAULT_AGENT})`).option("--claude", "Shorthand for --agent claude-code").option("--all-agents", "Install to every supported agent host in one run").option("--force",
|
|
10195
|
+
marketplace.command("sync").description("With no arguments, refreshes every already-installed plugin from every marketplace (same as --marketplace all --installed-only). Pass --force, a plugin, or --marketplace to get the interactive picker instead.").argument("[plugin]", 'Plugin name to install, or "all" to install every plugin (skips interactive selection)').option("--marketplace <name>", 'Marketplace name to sync, or "all" to sync every registered marketplace (skips interactive selection)').option("--agent <agent>", `Target agent host: ${AGENT_CHOICES} (default: ${DEFAULT_AGENT})`).option("--claude", "Shorthand for --agent claude-code").option("--all-agents", "Install to every supported agent host in one run").option("--force", "Opt into the interactive picker instead of the installed-only shorthand (plugins are always refreshed from the local clone, with or without new upstream changes)").option("--installed-only", "Only sync plugins that are already installed \u2014 skip plugins newly added to the marketplace").option("--no-instructions", "Do not apply the shipped AGENTS.md / CLAUDE.md to user-level instructions files").action(async (plugin, opts) => {
|
|
10111
10196
|
const start = Date.now();
|
|
10112
10197
|
try {
|
|
10113
10198
|
const configPath = getGlobalConfigPath();
|
|
@@ -10600,19 +10685,31 @@ function copyPluginSkills(skillsSrc, targetDir, meta) {
|
|
|
10600
10685
|
(name) => fs6.statSync(path11.join(skillsSrc, name)).isDirectory()
|
|
10601
10686
|
);
|
|
10602
10687
|
const installed = [];
|
|
10688
|
+
const active = [];
|
|
10603
10689
|
const failed = [];
|
|
10690
|
+
const disabledHere = meta ? readInstalledMeta(targetDir).disabled ?? {} : {};
|
|
10604
10691
|
for (const skillName of skillNames) {
|
|
10605
10692
|
const dest = path11.resolve(targetDir, skillName);
|
|
10606
10693
|
if (!dest.startsWith(resolvedTarget + path11.sep)) {
|
|
10607
10694
|
failed.push(skillName);
|
|
10608
10695
|
continue;
|
|
10609
10696
|
}
|
|
10697
|
+
const stashed = disabledHere[skillName];
|
|
10698
|
+
if (meta && stashed && stashed.plugin === meta.plugin) {
|
|
10699
|
+
const stashDest = path11.join(targetDir, DISABLED_SUBDIR, skillName);
|
|
10700
|
+
fs6.mkdirSync(path11.dirname(stashDest), { recursive: true });
|
|
10701
|
+
fs6.rmSync(stashDest, { recursive: true, force: true });
|
|
10702
|
+
fs6.cpSync(path11.join(skillsSrc, skillName), stashDest, { recursive: true });
|
|
10703
|
+
installed.push(skillName);
|
|
10704
|
+
continue;
|
|
10705
|
+
}
|
|
10610
10706
|
fs6.rmSync(dest, { recursive: true, force: true });
|
|
10611
10707
|
fs6.cpSync(path11.join(skillsSrc, skillName), dest, { recursive: true });
|
|
10612
10708
|
installed.push(skillName);
|
|
10709
|
+
active.push(skillName);
|
|
10613
10710
|
}
|
|
10614
10711
|
if (meta) {
|
|
10615
|
-
recordInstalledSkills(targetDir,
|
|
10712
|
+
recordInstalledSkills(targetDir, active, {
|
|
10616
10713
|
source: "marketplace",
|
|
10617
10714
|
marketplace: meta.marketplace,
|
|
10618
10715
|
plugin: meta.plugin,
|
|
@@ -10911,6 +11008,16 @@ function registerConfigCommands(program2) {
|
|
|
10911
11008
|
} else {
|
|
10912
11009
|
results.logscale = { ok: null, message: "not configured" };
|
|
10913
11010
|
}
|
|
11011
|
+
if (cfg.elasticsearch.baseUrl && cfg.elasticsearch.apiKey) {
|
|
11012
|
+
try {
|
|
11013
|
+
await http.elasticsearch("/_cluster/health");
|
|
11014
|
+
results.elasticsearch = { ok: true, message: "connected" };
|
|
11015
|
+
} catch (err) {
|
|
11016
|
+
results.elasticsearch = { ok: false, message: err instanceof Error ? err.message : String(err) };
|
|
11017
|
+
}
|
|
11018
|
+
} else {
|
|
11019
|
+
results.elasticsearch = { ok: null, message: "not configured" };
|
|
11020
|
+
}
|
|
10914
11021
|
if (cfg.splitio.baseUrl && cfg.splitio.adminApiKey) {
|
|
10915
11022
|
try {
|
|
10916
11023
|
await http.splitio("/internal/api/v2/workspaces");
|
|
@@ -10995,6 +11102,7 @@ function registerConfigCommands(program2) {
|
|
|
10995
11102
|
"dynatrace_platform",
|
|
10996
11103
|
...dynamicEnvKeys,
|
|
10997
11104
|
"logscale",
|
|
11105
|
+
"elasticsearch",
|
|
10998
11106
|
"splitio",
|
|
10999
11107
|
"figma",
|
|
11000
11108
|
"alation",
|
|
@@ -11550,6 +11658,40 @@ async function initGlobalConfig(start) {
|
|
|
11550
11658
|
}
|
|
11551
11659
|
}
|
|
11552
11660
|
}
|
|
11661
|
+
process.stderr.write("\n\u2500\u2500 Elasticsearch \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
|
|
11662
|
+
const useElasticsearch = await confirm({
|
|
11663
|
+
message: "Configure Elasticsearch for log and document searches?",
|
|
11664
|
+
default: false
|
|
11665
|
+
});
|
|
11666
|
+
let elasticsearchBaseUrl = "";
|
|
11667
|
+
let elasticsearchApiKey = "";
|
|
11668
|
+
if (useElasticsearch) {
|
|
11669
|
+
elasticsearchBaseUrl = await input2({
|
|
11670
|
+
message: "Elasticsearch base URL (e.g. https://elasticsearch.imagile.dev:9200):",
|
|
11671
|
+
default: ""
|
|
11672
|
+
});
|
|
11673
|
+
elasticsearchApiKey = await password2({
|
|
11674
|
+
message: 'Elasticsearch API key (the base64 "encoded" value from Kibana \u2192 Stack Management \u2192 API keys):'
|
|
11675
|
+
});
|
|
11676
|
+
if (elasticsearchBaseUrl && elasticsearchApiKey) {
|
|
11677
|
+
process.stderr.write("\n Verifying connection...\n");
|
|
11678
|
+
try {
|
|
11679
|
+
const tempConfig = {
|
|
11680
|
+
...loadConfig(),
|
|
11681
|
+
elasticsearch: {
|
|
11682
|
+
baseUrl: normalizeBaseUrl(elasticsearchBaseUrl),
|
|
11683
|
+
apiKey: elasticsearchApiKey
|
|
11684
|
+
}
|
|
11685
|
+
};
|
|
11686
|
+
const tempHttp = createHttpClient(tempConfig);
|
|
11687
|
+
await tempHttp.elasticsearch("/_cluster/health");
|
|
11688
|
+
process.stderr.write(" Connected.\n");
|
|
11689
|
+
} catch (err) {
|
|
11690
|
+
warn(`Could not connect to Elasticsearch: ${err instanceof Error ? err.message : String(err)}`);
|
|
11691
|
+
warn("Config will be saved anyway. Check your URL and API key and re-run pncli config init or pncli config test.");
|
|
11692
|
+
}
|
|
11693
|
+
}
|
|
11694
|
+
}
|
|
11553
11695
|
process.stderr.write("\n\u2500\u2500 Split.IO \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
|
|
11554
11696
|
const useSplitio = await confirm({
|
|
11555
11697
|
message: "Configure Split.IO for feature flag administration?",
|
|
@@ -11847,6 +11989,12 @@ async function initGlobalConfig(start) {
|
|
|
11847
11989
|
token: logscaleToken || void 0
|
|
11848
11990
|
}
|
|
11849
11991
|
} : {},
|
|
11992
|
+
...useElasticsearch && elasticsearchBaseUrl ? {
|
|
11993
|
+
elasticsearch: {
|
|
11994
|
+
baseUrl: normalizeBaseUrl(elasticsearchBaseUrl),
|
|
11995
|
+
apiKey: elasticsearchApiKey || void 0
|
|
11996
|
+
}
|
|
11997
|
+
} : {},
|
|
11850
11998
|
...useSplitio && splitioBaseUrl ? {
|
|
11851
11999
|
splitio: {
|
|
11852
12000
|
baseUrl: normalizeBaseUrl(splitioBaseUrl),
|
|
@@ -12314,6 +12462,7 @@ function registerDoctorCommands(program2) {
|
|
|
12314
12462
|
|
|
12315
12463
|
// src/services/ado/client/git.ts
|
|
12316
12464
|
var API7 = "7.1";
|
|
12465
|
+
var REQUIRED_REVIEWERS_POLICY_TYPE = "fd2167ab-b0be-447a-8ec8-39368250530e";
|
|
12317
12466
|
var AdoGitClient = class {
|
|
12318
12467
|
constructor(http) {
|
|
12319
12468
|
this.http = http;
|
|
@@ -12348,6 +12497,10 @@ var AdoGitClient = class {
|
|
|
12348
12497
|
"searchCriteria.status": opts.status ?? "active",
|
|
12349
12498
|
...opts.creatorAlias ? { "searchCriteria.creatorId": opts.creatorAlias } : {},
|
|
12350
12499
|
...opts.reviewerAlias ? { "searchCriteria.reviewerId": opts.reviewerAlias } : {},
|
|
12500
|
+
// minTime/maxTime only take effect alongside queryTimeRangeType.
|
|
12501
|
+
...opts.createdAfter || opts.createdBefore ? { "searchCriteria.queryTimeRangeType": "created" } : {},
|
|
12502
|
+
...opts.createdAfter ? { "searchCriteria.minTime": opts.createdAfter.toISOString() } : {},
|
|
12503
|
+
...opts.createdBefore ? { "searchCriteria.maxTime": opts.createdBefore.toISOString() } : {},
|
|
12351
12504
|
"$top": pageSize,
|
|
12352
12505
|
"$skip": skip
|
|
12353
12506
|
};
|
|
@@ -12409,6 +12562,20 @@ var AdoGitClient = class {
|
|
|
12409
12562
|
const pr = await this.getPR(collection, project, repo, prId);
|
|
12410
12563
|
return pr.reviewers;
|
|
12411
12564
|
}
|
|
12565
|
+
/**
|
|
12566
|
+
* Default reviewers in Azure DevOps are "Required reviewers" branch policies.
|
|
12567
|
+
* Returns the policy configurations of that type whose scope covers the repo
|
|
12568
|
+
* (a scope entry with a null repositoryId applies project-wide).
|
|
12569
|
+
*/
|
|
12570
|
+
async listDefaultReviewers(collection, project, repo) {
|
|
12571
|
+
const repoInfo = await this.getRepo(collection, project, repo);
|
|
12572
|
+
const result = await this.http.ado(
|
|
12573
|
+
`/${encodeURIComponent(collection)}/${encodeURIComponent(project)}/_apis/policy/configurations?api-version=${API7}`
|
|
12574
|
+
);
|
|
12575
|
+
return (result.value ?? []).filter(
|
|
12576
|
+
(c) => c.type?.id === REQUIRED_REVIEWERS_POLICY_TYPE && (c.settings?.scope ?? []).some((s) => !s.repositoryId || s.repositoryId === repoInfo.id)
|
|
12577
|
+
);
|
|
12578
|
+
}
|
|
12412
12579
|
// ── Threads / Comments ────────────────────────────────────────────
|
|
12413
12580
|
async listThreads(collection, project, repo, prId) {
|
|
12414
12581
|
const result = await this.http.ado(
|
|
@@ -13073,14 +13240,18 @@ function registerAdoRepoCommands(ado) {
|
|
|
13073
13240
|
fail(err, "ado", "repo-get", start);
|
|
13074
13241
|
}
|
|
13075
13242
|
});
|
|
13076
|
-
repo.command("list-prs").description("List pull requests").option("--state <state>", "PR state: active|abandoned|completed|all", "active").option("--creator <alias>", "Filter by creator").option("--reviewer <alias>", "Filter by reviewer").action(async (opts) => {
|
|
13243
|
+
repo.command("list-prs").description("List pull requests").option("--state <state>", "PR state: active|abandoned|completed|all", "active").option("--creator <alias>", "Filter by creator").option("--reviewer <alias>", "Filter by reviewer").option("--created-after <date>", "Only PRs created on/after this ISO 8601 date (e.g. 2025-01-31)").option("--created-before <date>", "Only PRs created before this ISO 8601 date").action(async (opts) => {
|
|
13077
13244
|
const start = Date.now();
|
|
13078
13245
|
try {
|
|
13246
|
+
const createdAfter = opts.createdAfter ? parseDateOption("--created-after", opts.createdAfter) : void 0;
|
|
13247
|
+
const createdBefore = opts.createdBefore ? parseDateOption("--created-before", opts.createdBefore) : void 0;
|
|
13079
13248
|
const { collection, project, repo: repo2, gitClient } = getAdoContext(ado, true);
|
|
13080
13249
|
const data = await gitClient.listPRs(collection, project, repo2, {
|
|
13081
13250
|
status: opts.state,
|
|
13082
13251
|
creatorAlias: opts.creator,
|
|
13083
|
-
reviewerAlias: opts.reviewer
|
|
13252
|
+
reviewerAlias: opts.reviewer,
|
|
13253
|
+
createdAfter,
|
|
13254
|
+
createdBefore
|
|
13084
13255
|
});
|
|
13085
13256
|
success(data, "ado", "repo-list-prs", start);
|
|
13086
13257
|
} catch (err) {
|
|
@@ -13301,16 +13472,26 @@ function registerAdoRepoCommands(ado) {
|
|
|
13301
13472
|
fail(err, "ado", "repo-list-reviewers", start);
|
|
13302
13473
|
}
|
|
13303
13474
|
});
|
|
13475
|
+
repo.command("list-default-reviewers").description("List required-reviewer branch policies (default reviewers) that apply to the repository").action(async () => {
|
|
13476
|
+
const start = Date.now();
|
|
13477
|
+
try {
|
|
13478
|
+
const { collection, project, repo: repo2, gitClient } = getAdoContext(ado, true);
|
|
13479
|
+
const data = await gitClient.listDefaultReviewers(collection, project, repo2);
|
|
13480
|
+
success(data, "ado", "repo-list-default-reviewers", start);
|
|
13481
|
+
} catch (err) {
|
|
13482
|
+
fail(err, "ado", "repo-list-default-reviewers", start);
|
|
13483
|
+
}
|
|
13484
|
+
});
|
|
13304
13485
|
const voteCmd = (name, description, vote, action) => {
|
|
13305
13486
|
repo.command(name).description(description).requiredOption("--pr <n>", "Pull request ID").action(async (opts) => {
|
|
13306
13487
|
const start = Date.now();
|
|
13307
13488
|
try {
|
|
13308
13489
|
const globalOpts = ado.optsWithGlobals();
|
|
13309
|
-
const { loadConfig: lc } = await import("./config-
|
|
13490
|
+
const { loadConfig: lc } = await import("./config-DYIXSPLA.js");
|
|
13310
13491
|
const config = lc({ configPath: globalOpts.config });
|
|
13311
13492
|
const { collection, project, repo: repo2, gitClient } = getAdoContext(ado, true);
|
|
13312
13493
|
const { AdoCoreClient: AdoCoreClient2 } = await import("./core-SWYVXOQ4.js");
|
|
13313
|
-
const { createHttpClient: createHttpClient2 } = await import("./http-
|
|
13494
|
+
const { createHttpClient: createHttpClient2 } = await import("./http-F24ORY6C.js");
|
|
13314
13495
|
const http = createHttpClient2(config, Boolean(globalOpts.dryRun));
|
|
13315
13496
|
const coreClient = new AdoCoreClient2(http);
|
|
13316
13497
|
const me = await coreClient.getConnectionData(collection);
|
|
@@ -14498,6 +14679,55 @@ function registerOpenShiftCommands(program2) {
|
|
|
14498
14679
|
fail(err, "openshift", "pods", start);
|
|
14499
14680
|
}
|
|
14500
14681
|
});
|
|
14682
|
+
oc.command("deployments").description("List Deployments (or OpenShift DeploymentConfigs with --deployment-configs) for a namespace, read-only. Use --raw to return the full unmodified objects.").requiredOption("--namespace <ns>", "Kubernetes namespace").option("--label-selector <selector>", "Label selector (e.g. app=my-app)").option("--deployment-configs", "Read OpenShift DeploymentConfigs (apps.openshift.io/v1) instead of Deployments (apps/v1)", false).option("--raw", "Return full objects without summarization (includes pod template, env vars, strategy, etc.)", false).action(async (opts) => {
|
|
14683
|
+
const start = Date.now();
|
|
14684
|
+
try {
|
|
14685
|
+
const http = getHttp2(oc);
|
|
14686
|
+
const params = {};
|
|
14687
|
+
if (opts.labelSelector) params["labelSelector"] = opts.labelSelector;
|
|
14688
|
+
const kind = opts.deploymentConfigs ? "DeploymentConfig" : "Deployment";
|
|
14689
|
+
const path14 = opts.deploymentConfigs ? `/apis/apps.openshift.io/v1/namespaces/${encodeURIComponent(opts.namespace)}/deploymentconfigs` : `/apis/apps/v1/namespaces/${encodeURIComponent(opts.namespace)}/deployments`;
|
|
14690
|
+
const list = await http.openshift(path14, { params });
|
|
14691
|
+
if (opts.raw) {
|
|
14692
|
+
success(
|
|
14693
|
+
{ namespace: opts.namespace, kind, count: list.items.length, deployments: list.items },
|
|
14694
|
+
"openshift",
|
|
14695
|
+
"deployments",
|
|
14696
|
+
start
|
|
14697
|
+
);
|
|
14698
|
+
return;
|
|
14699
|
+
}
|
|
14700
|
+
const deployments = list.items.map((d) => {
|
|
14701
|
+
const desired = d.spec.replicas ?? 0;
|
|
14702
|
+
const status = d.status ?? {};
|
|
14703
|
+
const entry = {
|
|
14704
|
+
name: d.metadata.name,
|
|
14705
|
+
ready: `${status.readyReplicas ?? 0}/${desired}`,
|
|
14706
|
+
desiredReplicas: desired,
|
|
14707
|
+
readyReplicas: status.readyReplicas ?? 0,
|
|
14708
|
+
updatedReplicas: status.updatedReplicas ?? 0,
|
|
14709
|
+
availableReplicas: status.availableReplicas ?? 0,
|
|
14710
|
+
unavailableReplicas: status.unavailableReplicas ?? 0,
|
|
14711
|
+
age: podAge(d.metadata.creationTimestamp),
|
|
14712
|
+
images: (d.spec.template?.spec?.containers ?? []).map((c) => ({ name: c.name, image: c.image }))
|
|
14713
|
+
};
|
|
14714
|
+
if (d.spec.strategy?.type) entry["strategy"] = d.spec.strategy.type;
|
|
14715
|
+
if (status.latestVersion !== void 0) entry["latestVersion"] = status.latestVersion;
|
|
14716
|
+
const problems = (status.conditions ?? []).filter(
|
|
14717
|
+
(c) => c.type === "Available" && c.status === "False" || c.type === "Progressing" && c.status === "False" || c.type === "ReplicaFailure"
|
|
14718
|
+
);
|
|
14719
|
+
if (problems.length > 0) {
|
|
14720
|
+
entry["conditions"] = problems.map((c) => ({ type: c.type, status: c.status, reason: c.reason, message: c.message }));
|
|
14721
|
+
}
|
|
14722
|
+
if (d.metadata.labels && Object.keys(d.metadata.labels).length > 0) entry["labels"] = d.metadata.labels;
|
|
14723
|
+
return entry;
|
|
14724
|
+
});
|
|
14725
|
+
deployments.sort((a, b) => (b["unavailableReplicas"] ?? 0) - (a["unavailableReplicas"] ?? 0));
|
|
14726
|
+
success({ namespace: opts.namespace, kind, count: deployments.length, deployments }, "openshift", "deployments", start);
|
|
14727
|
+
} catch (err) {
|
|
14728
|
+
fail(err, "openshift", "deployments", start);
|
|
14729
|
+
}
|
|
14730
|
+
});
|
|
14501
14731
|
oc.command("events").description("List Warning events for a namespace \u2014 pre-filtered for LLM analysis").requiredOption("--namespace <ns>", "Kubernetes namespace").option("--field-selector <selector>", "Additional field selector (e.g. involvedObject.name=my-pod)").option("--all", "Include Normal events in addition to Warning events", false).action(async (opts) => {
|
|
14502
14732
|
const start = Date.now();
|
|
14503
14733
|
try {
|
|
@@ -14922,10 +15152,121 @@ function registerLogscaleCommands(program2) {
|
|
|
14922
15152
|
});
|
|
14923
15153
|
}
|
|
14924
15154
|
|
|
15155
|
+
// src/services/elasticsearch/commands.ts
|
|
15156
|
+
function getHttp5(program2) {
|
|
15157
|
+
const opts = program2.optsWithGlobals();
|
|
15158
|
+
return createHttpClient(
|
|
15159
|
+
loadConfig({ configPath: opts.config }),
|
|
15160
|
+
Boolean(opts.dryRun)
|
|
15161
|
+
);
|
|
15162
|
+
}
|
|
15163
|
+
function parseJsonOption(raw, flag) {
|
|
15164
|
+
let parsed;
|
|
15165
|
+
try {
|
|
15166
|
+
parsed = JSON.parse(raw);
|
|
15167
|
+
} catch {
|
|
15168
|
+
throw new PncliError(`${flag} must be valid JSON. Example: ${flag} '{"match_all":{}}'`);
|
|
15169
|
+
}
|
|
15170
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
15171
|
+
throw new PncliError(`${flag} must be a JSON object.`);
|
|
15172
|
+
}
|
|
15173
|
+
return parsed;
|
|
15174
|
+
}
|
|
15175
|
+
function parsePositiveInt(raw, flag) {
|
|
15176
|
+
const n = Number(raw);
|
|
15177
|
+
if (!Number.isInteger(n) || n < 0) throw new PncliError(`${flag} must be a non-negative integer.`);
|
|
15178
|
+
return n;
|
|
15179
|
+
}
|
|
15180
|
+
function indexPath(index) {
|
|
15181
|
+
return index.split(",").map((s) => encodeURIComponent(s.trim())).join(",");
|
|
15182
|
+
}
|
|
15183
|
+
function buildQuery(opts) {
|
|
15184
|
+
if (opts.query && opts.q) throw new PncliError("Use either --query or --q, not both.");
|
|
15185
|
+
if (opts.query) return parseJsonOption(opts.query, "--query");
|
|
15186
|
+
if (opts.q) return { query_string: { query: opts.q } };
|
|
15187
|
+
return { match_all: {} };
|
|
15188
|
+
}
|
|
15189
|
+
function registerElasticsearchCommands(program2) {
|
|
15190
|
+
const es = program2.command("elasticsearch").description("Elasticsearch search operations");
|
|
15191
|
+
const cluster = es.command("cluster").description("Cluster operations");
|
|
15192
|
+
cluster.command("health").description("Show cluster health (status, node and shard counts)").action(async () => {
|
|
15193
|
+
const start = Date.now();
|
|
15194
|
+
try {
|
|
15195
|
+
const data = await getHttp5(program2).elasticsearch("/_cluster/health");
|
|
15196
|
+
success(data, "elasticsearch", "cluster health", start);
|
|
15197
|
+
} catch (err) {
|
|
15198
|
+
fail(err, "elasticsearch", "cluster health", start);
|
|
15199
|
+
}
|
|
15200
|
+
});
|
|
15201
|
+
const indices = es.command("indices").description("Index operations");
|
|
15202
|
+
indices.command("list").description("List indices with health, document count and size").option("--pattern <pattern>", 'Index name or wildcard pattern (e.g. "logs-*")').action(async (opts) => {
|
|
15203
|
+
const start = Date.now();
|
|
15204
|
+
try {
|
|
15205
|
+
const path14 = opts.pattern ? `/_cat/indices/${indexPath(opts.pattern)}` : "/_cat/indices";
|
|
15206
|
+
const data = await getHttp5(program2).elasticsearch(path14, {
|
|
15207
|
+
params: { format: "json", h: "index,health,status,docs.count,store.size,pri,rep" }
|
|
15208
|
+
});
|
|
15209
|
+
success({ count: data.length, indices: data }, "elasticsearch", "indices list", start);
|
|
15210
|
+
} catch (err) {
|
|
15211
|
+
fail(err, "elasticsearch", "indices list", start);
|
|
15212
|
+
}
|
|
15213
|
+
});
|
|
15214
|
+
es.command("search").description("Search one or more indices with Query DSL JSON or a query string").requiredOption("--index <name>", "Index, data stream, alias or wildcard pattern; comma-separate several").option("--query <json>", `Query DSL clause as JSON (e.g. '{"match":{"message":"error"}}')`).option("--q <query-string>", 'Lucene query string (e.g. "level:error AND service:api")').option("--sort <field:order>", 'Sort, e.g. "@timestamp:desc"').option("--source <fields>", "Comma-separated fields to return (_source filtering)").option("--size <n>", "Maximum number of hits to return", "100").option("--from <n>", "Offset of the first hit", "0").option("--timeout-ms <ms>", "Client-side HTTP timeout in milliseconds", "30000").action(async (opts) => {
|
|
15215
|
+
const ts = Date.now();
|
|
15216
|
+
try {
|
|
15217
|
+
const body = {
|
|
15218
|
+
query: buildQuery(opts),
|
|
15219
|
+
size: parsePositiveInt(opts.size, "--size"),
|
|
15220
|
+
from: parsePositiveInt(opts.from, "--from")
|
|
15221
|
+
};
|
|
15222
|
+
if (opts.sort) {
|
|
15223
|
+
const [field, order] = opts.sort.split(":");
|
|
15224
|
+
body.sort = [{ [field]: { order: order ?? "asc" } }];
|
|
15225
|
+
}
|
|
15226
|
+
if (opts.source) body._source = opts.source.split(",").map((s) => s.trim()).filter(Boolean);
|
|
15227
|
+
const data = await getHttp5(program2).elasticsearch(
|
|
15228
|
+
`/${indexPath(opts.index)}/_search`,
|
|
15229
|
+
{ method: "POST", body, timeoutMs: parsePositiveInt(opts.timeoutMs, "--timeout-ms") }
|
|
15230
|
+
);
|
|
15231
|
+
const total = data.hits?.total;
|
|
15232
|
+
const hits = data.hits?.hits ?? [];
|
|
15233
|
+
success(
|
|
15234
|
+
{
|
|
15235
|
+
index: opts.index,
|
|
15236
|
+
took: data.took,
|
|
15237
|
+
timedOut: data.timed_out ?? false,
|
|
15238
|
+
total: typeof total === "object" ? total?.value : total,
|
|
15239
|
+
totalRelation: typeof total === "object" ? total?.relation : void 0,
|
|
15240
|
+
hitCount: hits.length,
|
|
15241
|
+
hits,
|
|
15242
|
+
aggregations: data.aggregations
|
|
15243
|
+
},
|
|
15244
|
+
"elasticsearch",
|
|
15245
|
+
"search",
|
|
15246
|
+
ts
|
|
15247
|
+
);
|
|
15248
|
+
} catch (err) {
|
|
15249
|
+
fail(err, "elasticsearch", "search", ts);
|
|
15250
|
+
}
|
|
15251
|
+
});
|
|
15252
|
+
es.command("count").description("Count documents matching a query").requiredOption("--index <name>", "Index, data stream, alias or wildcard pattern; comma-separate several").option("--query <json>", "Query DSL clause as JSON").option("--q <query-string>", "Lucene query string").action(async (opts) => {
|
|
15253
|
+
const start = Date.now();
|
|
15254
|
+
try {
|
|
15255
|
+
const data = await getHttp5(program2).elasticsearch(
|
|
15256
|
+
`/${indexPath(opts.index)}/_count`,
|
|
15257
|
+
{ method: "POST", body: { query: buildQuery(opts) } }
|
|
15258
|
+
);
|
|
15259
|
+
success({ index: opts.index, count: data.count }, "elasticsearch", "count", start);
|
|
15260
|
+
} catch (err) {
|
|
15261
|
+
fail(err, "elasticsearch", "count", start);
|
|
15262
|
+
}
|
|
15263
|
+
});
|
|
15264
|
+
}
|
|
15265
|
+
|
|
14925
15266
|
// src/services/splitio/commands.ts
|
|
14926
15267
|
import fs11 from "fs";
|
|
14927
15268
|
import confirm2 from "@inquirer/confirm";
|
|
14928
|
-
function
|
|
15269
|
+
function getHttp6(program2) {
|
|
14929
15270
|
const opts = program2.optsWithGlobals();
|
|
14930
15271
|
return createHttpClient(
|
|
14931
15272
|
loadConfig({ configPath: opts.config }),
|
|
@@ -14970,7 +15311,7 @@ function registerSplitioCommands(program2) {
|
|
|
14970
15311
|
workspaces.command("list").description("List all Split.IO workspaces").action(async () => {
|
|
14971
15312
|
const start = Date.now();
|
|
14972
15313
|
try {
|
|
14973
|
-
const http =
|
|
15314
|
+
const http = getHttp6(program2);
|
|
14974
15315
|
const data = await http.splitio("/internal/api/v2/workspaces");
|
|
14975
15316
|
success(
|
|
14976
15317
|
{ count: data.objects.length, workspaces: data.objects },
|
|
@@ -14986,7 +15327,7 @@ function registerSplitioCommands(program2) {
|
|
|
14986
15327
|
environments.command("list").description("List environments in a workspace").requiredOption("--workspace <id>", "Workspace ID").action(async (opts) => {
|
|
14987
15328
|
const start = Date.now();
|
|
14988
15329
|
try {
|
|
14989
|
-
const http =
|
|
15330
|
+
const http = getHttp6(program2);
|
|
14990
15331
|
const data = await http.splitio(
|
|
14991
15332
|
`/internal/api/v2/environments/ws/${encodeURIComponent(opts.workspace)}`
|
|
14992
15333
|
);
|
|
@@ -15004,7 +15345,7 @@ function registerSplitioCommands(program2) {
|
|
|
15004
15345
|
flags.command("list").description("List feature flags in a workspace").requiredOption("--workspace <id>", "Workspace ID").option("--limit <n>", "Maximum number of flags to return", "50").option("--offset <n>", "Pagination offset", "0").option("--flag-set <name>", "Filter by flag set name").action(async (opts) => {
|
|
15005
15346
|
const start = Date.now();
|
|
15006
15347
|
try {
|
|
15007
|
-
const http =
|
|
15348
|
+
const http = getHttp6(program2);
|
|
15008
15349
|
const params = {
|
|
15009
15350
|
limit: parseInt(opts.limit, 10),
|
|
15010
15351
|
offset: parseInt(opts.offset, 10)
|
|
@@ -15027,7 +15368,7 @@ function registerSplitioCommands(program2) {
|
|
|
15027
15368
|
flags.command("get").description("Get a flag definition").requiredOption("--workspace <id>", "Workspace ID").requiredOption("--flag <name>", "Feature flag name").option("--environment <id>", "Environment ID \u2014 include targeting rules for this environment").action(async (opts) => {
|
|
15028
15369
|
const start = Date.now();
|
|
15029
15370
|
try {
|
|
15030
|
-
const http =
|
|
15371
|
+
const http = getHttp6(program2);
|
|
15031
15372
|
if (opts.environment) {
|
|
15032
15373
|
const data = await http.splitio(
|
|
15033
15374
|
`/internal/api/v2/splits/ws/${encodeURIComponent(opts.workspace)}/name/${encodeURIComponent(opts.flag)}/environment/${encodeURIComponent(opts.environment)}`
|
|
@@ -15049,7 +15390,7 @@ function registerSplitioCommands(program2) {
|
|
|
15049
15390
|
if (!opts.inputFile) throw new PncliError("--input-file is required for flags update");
|
|
15050
15391
|
const definition = loadInputFile(opts.inputFile);
|
|
15051
15392
|
await confirmWrite(opts, `UPDATE ${opts.flag} in ${opts.environment}`);
|
|
15052
|
-
const http =
|
|
15393
|
+
const http = getHttp6(program2);
|
|
15053
15394
|
const body = {
|
|
15054
15395
|
...buildCrBase(opts),
|
|
15055
15396
|
operationType: "UPDATE_SPLIT_DEFINITION",
|
|
@@ -15075,7 +15416,7 @@ function registerSplitioCommands(program2) {
|
|
|
15075
15416
|
if (!opts.treatment && !opts.weights) {
|
|
15076
15417
|
throw new PncliError("Either --treatment or --weights must be specified");
|
|
15077
15418
|
}
|
|
15078
|
-
const http =
|
|
15419
|
+
const http = getHttp6(program2);
|
|
15079
15420
|
const current = await http.splitio(
|
|
15080
15421
|
`/internal/api/v2/splits/ws/${encodeURIComponent(opts.workspace)}/name/${encodeURIComponent(opts.flag)}/environment/${encodeURIComponent(opts.environment)}`
|
|
15081
15422
|
);
|
|
@@ -15113,7 +15454,7 @@ function registerSplitioCommands(program2) {
|
|
|
15113
15454
|
flags.command("set-default").description("Update the fallback default rule for traffic matching no targeting rule").requiredOption("--workspace <id>", "Workspace ID").requiredOption("--flag <name>", "Feature flag name").requiredOption("--environment <id>", "Environment ID").requiredOption("--treatment <name>", "Treatment to assign as the default").requiredOption("--mnemonic <text>", "Short Change Request title (mnemonic)").requiredOption("--description <text>", "Change Request description").requiredOption("--change-number <CHG>", "Change request number (e.g. CHG0001234)").option("--approvers <ids>", "Comma-separated Split user IDs required to approve this CR").option("--yes", "Skip interactive confirmation prompt").action(async (opts) => {
|
|
15114
15455
|
const start = Date.now();
|
|
15115
15456
|
try {
|
|
15116
|
-
const http =
|
|
15457
|
+
const http = getHttp6(program2);
|
|
15117
15458
|
const current = await http.splitio(
|
|
15118
15459
|
`/internal/api/v2/splits/ws/${encodeURIComponent(opts.workspace)}/name/${encodeURIComponent(opts.flag)}/environment/${encodeURIComponent(opts.environment)}`
|
|
15119
15460
|
);
|
|
@@ -15146,7 +15487,7 @@ function registerSplitioCommands(program2) {
|
|
|
15146
15487
|
const enable = opts.enabled.toLowerCase() !== "false" && opts.enabled !== "0";
|
|
15147
15488
|
const opType = enable ? "RESTORE_SPLIT" : "KILL_SPLIT";
|
|
15148
15489
|
await confirmWrite(opts, `${opType} ${opts.flag} in ${opts.environment}`);
|
|
15149
|
-
const http =
|
|
15490
|
+
const http = getHttp6(program2);
|
|
15150
15491
|
const body = {
|
|
15151
15492
|
...buildCrBase(opts),
|
|
15152
15493
|
operationType: opType,
|
|
@@ -15169,7 +15510,7 @@ function registerSplitioCommands(program2) {
|
|
|
15169
15510
|
const entries = loadInputFile(opts.inputFile);
|
|
15170
15511
|
if (!Array.isArray(entries)) throw new PncliError("Input file must be a JSON array of {flag, enabled} objects");
|
|
15171
15512
|
await confirmWrite(opts, `BATCH_TOGGLE ${entries.length} flags in ${opts.environment}`);
|
|
15172
|
-
const http =
|
|
15513
|
+
const http = getHttp6(program2);
|
|
15173
15514
|
const results = [];
|
|
15174
15515
|
for (const entry of entries) {
|
|
15175
15516
|
try {
|
|
@@ -15203,7 +15544,7 @@ function registerSplitioCommands(program2) {
|
|
|
15203
15544
|
const start = Date.now();
|
|
15204
15545
|
try {
|
|
15205
15546
|
await confirmWrite(opts, `KILL ${opts.flag} in ${opts.environment}`);
|
|
15206
|
-
const http =
|
|
15547
|
+
const http = getHttp6(program2);
|
|
15207
15548
|
const body = {
|
|
15208
15549
|
...buildCrBase(opts),
|
|
15209
15550
|
operationType: "KILL_SPLIT",
|
|
@@ -15223,7 +15564,7 @@ function registerSplitioCommands(program2) {
|
|
|
15223
15564
|
const start = Date.now();
|
|
15224
15565
|
try {
|
|
15225
15566
|
await confirmWrite(opts, `RESTORE ${opts.flag} in ${opts.environment}`);
|
|
15226
|
-
const http =
|
|
15567
|
+
const http = getHttp6(program2);
|
|
15227
15568
|
const body = {
|
|
15228
15569
|
...buildCrBase(opts),
|
|
15229
15570
|
operationType: "RESTORE_SPLIT",
|
|
@@ -15243,7 +15584,7 @@ function registerSplitioCommands(program2) {
|
|
|
15243
15584
|
const start = Date.now();
|
|
15244
15585
|
try {
|
|
15245
15586
|
await confirmWrite(opts, `ARCHIVE ${opts.flag}`);
|
|
15246
|
-
const http =
|
|
15587
|
+
const http = getHttp6(program2);
|
|
15247
15588
|
const body = {
|
|
15248
15589
|
...buildCrBase(opts),
|
|
15249
15590
|
operationType: "ARCHIVE_SPLIT",
|
|
@@ -15263,7 +15604,7 @@ function registerSplitioCommands(program2) {
|
|
|
15263
15604
|
changeRequests.command("list").description("List Change Requests for a workspace").requiredOption("--workspace <id>", "Workspace ID").option("--environment <id>", "Filter by environment ID").option("--status <status>", "Filter by status (REQUESTED, APPROVED, REJECTED, PUBLISHED)").option("--limit <n>", "Maximum number of results", "25").option("--offset <n>", "Pagination offset", "0").action(async (opts) => {
|
|
15264
15605
|
const start = Date.now();
|
|
15265
15606
|
try {
|
|
15266
|
-
const http =
|
|
15607
|
+
const http = getHttp6(program2);
|
|
15267
15608
|
const params = {
|
|
15268
15609
|
limit: parseInt(opts.limit, 10),
|
|
15269
15610
|
offset: parseInt(opts.offset, 10)
|
|
@@ -15287,7 +15628,7 @@ function registerSplitioCommands(program2) {
|
|
|
15287
15628
|
changeRequests.command("get").description("Get a Change Request by ID").requiredOption("--id <id>", "Change Request ID").action(async (opts) => {
|
|
15288
15629
|
const start = Date.now();
|
|
15289
15630
|
try {
|
|
15290
|
-
const http =
|
|
15631
|
+
const http = getHttp6(program2);
|
|
15291
15632
|
const data = await http.splitio(
|
|
15292
15633
|
`/internal/api/v2/changeRequests/${encodeURIComponent(opts.id)}`
|
|
15293
15634
|
);
|
|
@@ -15339,7 +15680,7 @@ function findNodeIdInUrl(url) {
|
|
|
15339
15680
|
if (!new URL(url).searchParams.has("node-id")) return void 0;
|
|
15340
15681
|
return parseNodeId(url);
|
|
15341
15682
|
}
|
|
15342
|
-
function
|
|
15683
|
+
function getHttp7(program2) {
|
|
15343
15684
|
const opts = program2.optsWithGlobals();
|
|
15344
15685
|
return createHttpClient(
|
|
15345
15686
|
loadConfig({ configPath: opts.config }),
|
|
@@ -15350,12 +15691,12 @@ function registerFigmaCommands(program2) {
|
|
|
15350
15691
|
const figma = program2.command("figma").description("Figma design operations (files, comments, versions)");
|
|
15351
15692
|
figma.command("file").description("Get a Figma file \u2014 metadata, structure, and component/style inventory (or a single node with --node-id)").argument("<file-key-or-url>", "Figma file key or full Figma URL (https://www.figma.com/design/<key>/...); a node-id query param is auto-detected").option("--document", "Include the full document node tree (can be large; omitted by default)").option("--node-id <id>", "Fetch only this node and its descendants instead of the whole file (overrides any node-id detected in the URL)").action(async (fileKeyOrUrl, opts) => {
|
|
15352
15693
|
const start = Date.now();
|
|
15353
|
-
const { success: success2, fail: fail2 } = await import("./output-
|
|
15694
|
+
const { success: success2, fail: fail2 } = await import("./output-XE6XDAAR.js");
|
|
15354
15695
|
try {
|
|
15355
15696
|
const fileKey = parseFileKey(fileKeyOrUrl);
|
|
15356
15697
|
const nodeId = opts.nodeId ? parseNodeId(opts.nodeId) : isUrl(fileKeyOrUrl) ? findNodeIdInUrl(fileKeyOrUrl) : void 0;
|
|
15357
15698
|
if (nodeId) {
|
|
15358
|
-
const data2 = await
|
|
15699
|
+
const data2 = await getHttp7(program2).figma(
|
|
15359
15700
|
`/v1/files/${encodeURIComponent(fileKey)}/nodes`,
|
|
15360
15701
|
{ params: { ids: nodeId } }
|
|
15361
15702
|
);
|
|
@@ -15384,7 +15725,7 @@ function registerFigmaCommands(program2) {
|
|
|
15384
15725
|
if (!opts.document) {
|
|
15385
15726
|
params["depth"] = 1;
|
|
15386
15727
|
}
|
|
15387
|
-
const data = await
|
|
15728
|
+
const data = await getHttp7(program2).figma(`/v1/files/${encodeURIComponent(fileKey)}`, { params });
|
|
15388
15729
|
success2(
|
|
15389
15730
|
{
|
|
15390
15731
|
fileKey,
|
|
@@ -15409,12 +15750,12 @@ function registerFigmaCommands(program2) {
|
|
|
15409
15750
|
});
|
|
15410
15751
|
figma.command("comments").description("Get comments on a Figma file").argument("<file-key-or-url>", "Figma file key or full Figma URL").option("--as-of <date>", "ISO 8601 timestamp \u2014 return only comments created before this time").action(async (fileKeyOrUrl, opts) => {
|
|
15411
15752
|
const start = Date.now();
|
|
15412
|
-
const { success: success2, fail: fail2 } = await import("./output-
|
|
15753
|
+
const { success: success2, fail: fail2 } = await import("./output-XE6XDAAR.js");
|
|
15413
15754
|
try {
|
|
15414
15755
|
const fileKey = parseFileKey(fileKeyOrUrl);
|
|
15415
15756
|
const params = {};
|
|
15416
15757
|
if (opts.asOf) params["as_of"] = opts.asOf;
|
|
15417
|
-
const data = await
|
|
15758
|
+
const data = await getHttp7(program2).figma(`/v1/files/${encodeURIComponent(fileKey)}/comments`, { params });
|
|
15418
15759
|
success2(
|
|
15419
15760
|
{ fileKey, count: data.comments.length, comments: data.comments },
|
|
15420
15761
|
"figma",
|
|
@@ -15427,10 +15768,10 @@ function registerFigmaCommands(program2) {
|
|
|
15427
15768
|
});
|
|
15428
15769
|
figma.command("versions").description("Get the version history of a Figma file").argument("<file-key-or-url>", "Figma file key or full Figma URL").action(async (fileKeyOrUrl) => {
|
|
15429
15770
|
const start = Date.now();
|
|
15430
|
-
const { success: success2, fail: fail2 } = await import("./output-
|
|
15771
|
+
const { success: success2, fail: fail2 } = await import("./output-XE6XDAAR.js");
|
|
15431
15772
|
try {
|
|
15432
15773
|
const fileKey = parseFileKey(fileKeyOrUrl);
|
|
15433
|
-
const data = await
|
|
15774
|
+
const data = await getHttp7(program2).figma(`/v1/files/${encodeURIComponent(fileKey)}/versions`);
|
|
15434
15775
|
success2(
|
|
15435
15776
|
{ fileKey, count: data.versions.length, versions: data.versions },
|
|
15436
15777
|
"figma",
|
|
@@ -15443,9 +15784,9 @@ function registerFigmaCommands(program2) {
|
|
|
15443
15784
|
});
|
|
15444
15785
|
figma.command("project-files").description("List files in a Figma project").argument("<project-id>", "Figma project ID (visible in the project URL)").action(async (projectId) => {
|
|
15445
15786
|
const start = Date.now();
|
|
15446
|
-
const { success: success2, fail: fail2 } = await import("./output-
|
|
15787
|
+
const { success: success2, fail: fail2 } = await import("./output-XE6XDAAR.js");
|
|
15447
15788
|
try {
|
|
15448
|
-
const data = await
|
|
15789
|
+
const data = await getHttp7(program2).figma(`/v1/projects/${encodeURIComponent(projectId)}/files`);
|
|
15449
15790
|
success2(
|
|
15450
15791
|
{ projectId, count: data.files.length, files: data.files },
|
|
15451
15792
|
"figma",
|
|
@@ -15458,9 +15799,9 @@ function registerFigmaCommands(program2) {
|
|
|
15458
15799
|
});
|
|
15459
15800
|
figma.command("me").description("Get the current Figma user (useful for verifying credentials)").action(async () => {
|
|
15460
15801
|
const start = Date.now();
|
|
15461
|
-
const { success: success2, fail: fail2 } = await import("./output-
|
|
15802
|
+
const { success: success2, fail: fail2 } = await import("./output-XE6XDAAR.js");
|
|
15462
15803
|
try {
|
|
15463
|
-
const data = await
|
|
15804
|
+
const data = await getHttp7(program2).figma("/v1/me");
|
|
15464
15805
|
success2(data, "figma", "me", start);
|
|
15465
15806
|
} catch (err) {
|
|
15466
15807
|
fail2(err, "figma", "me", start);
|
|
@@ -15575,7 +15916,7 @@ var ALATION_DOCUMENT_INPUT_FILE_EXAMPLE = {
|
|
|
15575
15916
|
template: 7,
|
|
15576
15917
|
fields: { "10001": "Team Data Platform" }
|
|
15577
15918
|
};
|
|
15578
|
-
function
|
|
15919
|
+
function getHttp8(program2) {
|
|
15579
15920
|
const opts = program2.optsWithGlobals();
|
|
15580
15921
|
return createHttpClient(
|
|
15581
15922
|
loadConfig({ configPath: opts.config }),
|
|
@@ -15651,7 +15992,7 @@ function registerAlationCommands(program2) {
|
|
|
15651
15992
|
const params = {};
|
|
15652
15993
|
if (opts.includeUndeployed) params.include_undeployed = true;
|
|
15653
15994
|
if (opts.includeHidden) params.include_hidden = true;
|
|
15654
|
-
const data = await
|
|
15995
|
+
const data = await getHttp8(program2).alation("integration/v1/datasource/", { params });
|
|
15655
15996
|
success({ count: data.length, datasources: data }, "alation", "datasource-list", start);
|
|
15656
15997
|
} catch (err) {
|
|
15657
15998
|
fail(err, "alation", "datasource-list", start);
|
|
@@ -15661,7 +16002,7 @@ function registerAlationCommands(program2) {
|
|
|
15661
16002
|
const start = Date.now();
|
|
15662
16003
|
try {
|
|
15663
16004
|
const dsId = parsePositiveId(id2, "data source ID");
|
|
15664
|
-
const data = await
|
|
16005
|
+
const data = await getHttp8(program2).alation(`integration/v1/datasource/${dsId}/`);
|
|
15665
16006
|
success(data, "alation", "datasource-get", start);
|
|
15666
16007
|
} catch (err) {
|
|
15667
16008
|
fail(err, "alation", "datasource-get", start);
|
|
@@ -15674,7 +16015,7 @@ function registerAlationCommands(program2) {
|
|
|
15674
16015
|
const params = { ...pageParams(opts) };
|
|
15675
16016
|
if (opts.ds) params.ds_id = parsePositiveId(opts.ds, "--ds");
|
|
15676
16017
|
if (opts.name) params.name = opts.name;
|
|
15677
|
-
const data = await
|
|
16018
|
+
const data = await getHttp8(program2).alation("integration/v2/schema/", { params });
|
|
15678
16019
|
success({ count: data.length, limit: params.limit, skip: params.skip, schemas: data }, "alation", "schema-list", start);
|
|
15679
16020
|
} catch (err) {
|
|
15680
16021
|
fail(err, "alation", "schema-list", start);
|
|
@@ -15683,7 +16024,7 @@ function registerAlationCommands(program2) {
|
|
|
15683
16024
|
schema.command("get").description("Get a schema by ID").argument("<id>", "Schema ID").action(async (id2) => {
|
|
15684
16025
|
const start = Date.now();
|
|
15685
16026
|
try {
|
|
15686
|
-
const data = await getOne(
|
|
16027
|
+
const data = await getOne(getHttp8(program2), "integration/v2/schema/", parsePositiveId(id2, "schema ID"), "Schema");
|
|
15687
16028
|
success(data, "alation", "schema-get", start);
|
|
15688
16029
|
} catch (err) {
|
|
15689
16030
|
fail(err, "alation", "schema-get", start);
|
|
@@ -15699,7 +16040,7 @@ function registerAlationCommands(program2) {
|
|
|
15699
16040
|
if (opts.schemaName) params.schema_name = opts.schemaName;
|
|
15700
16041
|
if (opts.name) params.name = opts.name;
|
|
15701
16042
|
if (opts.search) params.name__icontains = opts.search;
|
|
15702
|
-
const data = await
|
|
16043
|
+
const data = await getHttp8(program2).alation("integration/v2/table/", { params });
|
|
15703
16044
|
success({ count: data.length, limit: params.limit, skip: params.skip, tables: data }, "alation", "table-list", start);
|
|
15704
16045
|
} catch (err) {
|
|
15705
16046
|
fail(err, "alation", "table-list", start);
|
|
@@ -15708,7 +16049,7 @@ function registerAlationCommands(program2) {
|
|
|
15708
16049
|
table.command("get").description("Get a table by ID, optionally with its columns").argument("<id>", "Table ID").option("--columns", "Also fetch the table's columns (up to 1000)").action(async (id2, opts) => {
|
|
15709
16050
|
const start = Date.now();
|
|
15710
16051
|
try {
|
|
15711
|
-
const http =
|
|
16052
|
+
const http = getHttp8(program2);
|
|
15712
16053
|
const tableId = parsePositiveId(id2, "table ID");
|
|
15713
16054
|
const data = await getOne(http, "integration/v2/table/", tableId, "Table");
|
|
15714
16055
|
if (opts.columns) {
|
|
@@ -15737,7 +16078,7 @@ function registerAlationCommands(program2) {
|
|
|
15737
16078
|
if (opts.ds) params.ds_id = parsePositiveId(opts.ds, "--ds");
|
|
15738
16079
|
if (opts.name) params.name = opts.name;
|
|
15739
16080
|
if (opts.search) params.name__icontains = opts.search;
|
|
15740
|
-
const data = await
|
|
16081
|
+
const data = await getHttp8(program2).alation("integration/v2/column/", { params });
|
|
15741
16082
|
success({ count: data.length, limit: params.limit, skip: params.skip, columns: data }, "alation", "column-list", start);
|
|
15742
16083
|
} catch (err) {
|
|
15743
16084
|
fail(err, "alation", "column-list", start);
|
|
@@ -15746,7 +16087,7 @@ function registerAlationCommands(program2) {
|
|
|
15746
16087
|
column.command("get").description("Get a column by ID").argument("<id>", "Column ID").action(async (id2) => {
|
|
15747
16088
|
const start = Date.now();
|
|
15748
16089
|
try {
|
|
15749
|
-
const data = await getOne(
|
|
16090
|
+
const data = await getOne(getHttp8(program2), "integration/v2/column/", parsePositiveId(id2, "column ID"), "Column");
|
|
15750
16091
|
success(data, "alation", "column-get", start);
|
|
15751
16092
|
} catch (err) {
|
|
15752
16093
|
fail(err, "alation", "column-get", start);
|
|
@@ -15761,7 +16102,7 @@ function registerAlationCommands(program2) {
|
|
|
15761
16102
|
const params = { q: query, limit, offset };
|
|
15762
16103
|
const otypes = parseOtypes(opts.otype);
|
|
15763
16104
|
if (otypes) params.filters = JSON.stringify({ otypes });
|
|
15764
|
-
const data = await
|
|
16105
|
+
const data = await getHttp8(program2).alation("integration/v1/search/", { params });
|
|
15765
16106
|
success(
|
|
15766
16107
|
{ query, total: data.total, limit: data.limit, offset: data.offset, fullSearchUrl: data.full_search_url, results: data.results },
|
|
15767
16108
|
"alation",
|
|
@@ -15780,7 +16121,7 @@ function registerAlationCommands(program2) {
|
|
|
15780
16121
|
if (opts.hub) params.document_hub_id = parsePositiveId(opts.hub, "--hub");
|
|
15781
16122
|
if (opts.parent) params.parent_folder_id = parsePositiveId(opts.parent, "--parent");
|
|
15782
16123
|
if (opts.search) params.search = opts.search;
|
|
15783
|
-
const data = await
|
|
16124
|
+
const data = await getHttp8(program2).alation("integration/v2/folder/", { params });
|
|
15784
16125
|
success({ count: data.length, limit: params.limit, skip: params.skip, folders: data }, "alation", "folder-list", start);
|
|
15785
16126
|
} catch (err) {
|
|
15786
16127
|
fail(err, "alation", "folder-list", start);
|
|
@@ -15789,7 +16130,7 @@ function registerAlationCommands(program2) {
|
|
|
15789
16130
|
folder.command("get").description("Get a Document Hub folder by ID").argument("<id>", "Folder ID").action(async (id2) => {
|
|
15790
16131
|
const start = Date.now();
|
|
15791
16132
|
try {
|
|
15792
|
-
const data = await getOne(
|
|
16133
|
+
const data = await getOne(getHttp8(program2), "integration/v2/folder/", parsePositiveId(id2, "folder ID"), "Folder");
|
|
15793
16134
|
success(data, "alation", "folder-get", start);
|
|
15794
16135
|
} catch (err) {
|
|
15795
16136
|
fail(err, "alation", "folder-get", start);
|
|
@@ -15805,7 +16146,7 @@ function registerAlationCommands(program2) {
|
|
|
15805
16146
|
if (opts.parentDocument) params.parent_document_id = parsePositiveId(opts.parentDocument, "--parent-document");
|
|
15806
16147
|
if (opts.search) params.search = opts.search;
|
|
15807
16148
|
if (opts.deleted) params.deleted = true;
|
|
15808
|
-
const data = await
|
|
16149
|
+
const data = await getHttp8(program2).alation("integration/v2/document/", { params });
|
|
15809
16150
|
success({ count: data.length, limit: params.limit, skip: params.skip, documents: data }, "alation", "document-list", start);
|
|
15810
16151
|
} catch (err) {
|
|
15811
16152
|
fail(err, "alation", "document-list", start);
|
|
@@ -15814,7 +16155,7 @@ function registerAlationCommands(program2) {
|
|
|
15814
16155
|
document.command("get").description("Get a document by ID, including its custom field values").argument("<id>", "Document ID").action(async (id2) => {
|
|
15815
16156
|
const start = Date.now();
|
|
15816
16157
|
try {
|
|
15817
|
-
const data = await getOne(
|
|
16158
|
+
const data = await getOne(getHttp8(program2), "integration/v2/document/", parsePositiveId(id2, "document ID"), "Document");
|
|
15818
16159
|
success(data, "alation", "document-get", start);
|
|
15819
16160
|
} catch (err) {
|
|
15820
16161
|
fail(err, "alation", "document-get", start);
|
|
@@ -15835,7 +16176,7 @@ function registerAlationCommands(program2) {
|
|
|
15835
16176
|
for (const [key, flag] of [["title", "--title"], ["document_hub_id", "--hub"], ["parent_folder_id", "--folder"]]) {
|
|
15836
16177
|
if (payload[key] === void 0) throw new PncliError(`${flag} is required to create a document (or set it in --input-file)`, 1);
|
|
15837
16178
|
}
|
|
15838
|
-
const data = await
|
|
16179
|
+
const data = await getHttp8(program2).alation("integration/v2/document/", { method: "POST", body: [payload] });
|
|
15839
16180
|
success({ jobId: data.job_id, document: payload, ...overrides.length ? { overrides } : {} }, "alation", "document-create", start);
|
|
15840
16181
|
} catch (err) {
|
|
15841
16182
|
fail(err, "alation", "document-create", start);
|
|
@@ -15853,7 +16194,7 @@ function registerAlationCommands(program2) {
|
|
|
15853
16194
|
throw new PncliError("Nothing to update. Pass --title, --description, --folder, or --input-file.", 1);
|
|
15854
16195
|
}
|
|
15855
16196
|
const body = [{ id: documentId, ...payload }];
|
|
15856
|
-
const data = await
|
|
16197
|
+
const data = await getHttp8(program2).alation("integration/v2/document/", { method: "PUT", body });
|
|
15857
16198
|
success({ jobId: data.job_id, document: body[0], ...overrides.length ? { overrides } : {} }, "alation", "document-update", start);
|
|
15858
16199
|
} catch (err) {
|
|
15859
16200
|
fail(err, "alation", "document-update", start);
|
|
@@ -15864,7 +16205,7 @@ function registerAlationCommands(program2) {
|
|
|
15864
16205
|
const start = Date.now();
|
|
15865
16206
|
try {
|
|
15866
16207
|
const jobId = parsePositiveId(id2, "job ID");
|
|
15867
|
-
const data = await
|
|
16208
|
+
const data = await getHttp8(program2).alation("api/v1/bulk_metadata/job/", { params: { id: jobId } });
|
|
15868
16209
|
success({ jobId, ...data }, "alation", "job-get", start);
|
|
15869
16210
|
} catch (err) {
|
|
15870
16211
|
fail(err, "alation", "job-get", start);
|
|
@@ -15913,6 +16254,7 @@ registerJwtCommands(program);
|
|
|
15913
16254
|
registerOpenShiftCommands(program);
|
|
15914
16255
|
registerDynatraceCommands(program);
|
|
15915
16256
|
registerLogscaleCommands(program);
|
|
16257
|
+
registerElasticsearchCommands(program);
|
|
15916
16258
|
registerSplitioCommands(program);
|
|
15917
16259
|
registerFigmaCommands(program);
|
|
15918
16260
|
registerAlationCommands(program);
|
|
@@ -15933,9 +16275,10 @@ Services:
|
|
|
15933
16275
|
checkmarx Checkmarx One (projects, scans, scan statistics)
|
|
15934
16276
|
contrast Contrast IAST (applications, vulnerability findings, libraries)
|
|
15935
16277
|
sonatypeiq Sonatype IQ Server (applications, organizations, policies)
|
|
15936
|
-
openshift OpenShift / Kubernetes (pods, events, logs, metrics)
|
|
16278
|
+
openshift OpenShift / Kubernetes (pods, deployments, events, logs, metrics)
|
|
15937
16279
|
dynatrace Dynatrace (services, entities, problems, traces, Kubernetes workloads)
|
|
15938
16280
|
logscale LogScale (log query, repositories)
|
|
16281
|
+
elasticsearch Elasticsearch (search, count, indices, cluster health)
|
|
15939
16282
|
splitio Split.IO (feature flags, Change Requests)
|
|
15940
16283
|
figma Figma (files, comments, version history)
|
|
15941
16284
|
alation Alation (data sources, schemas, tables, columns, search, Document Hubs)
|