@kolatts/pncli 1.7.0 → 1.8.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/NOTICE +22 -398
- package/README.md +40 -17
- package/copilot-instructions.md +118 -16
- package/dist/{chunk-HWXXNMGE.js → chunk-QQ7UKWTU.js} +282 -9
- package/dist/chunk-QQ7UKWTU.js.map +1 -0
- package/dist/{chunk-VEHCNGUP.js → chunk-S4SJLY4M.js} +42 -2
- package/dist/chunk-S4SJLY4M.js.map +1 -0
- package/dist/{chunk-KT3XINLJ.js → chunk-VDL32PSG.js} +3 -2
- package/dist/chunk-VDL32PSG.js.map +1 -0
- package/dist/cli.js +1036 -81
- package/dist/cli.js.map +1 -1
- package/dist/{config-IJ57IIQA.js → config-PXL632ZX.js} +2 -2
- package/dist/{core-AJYPJ2Z7.js → core-SWYVXOQ4.js} +2 -2
- package/dist/{http-FC24JSK7.js → http-TID3W235.js} +2 -2
- package/package.json +5 -2
- package/dist/chunk-HWXXNMGE.js.map +0 -1
- package/dist/chunk-KT3XINLJ.js.map +0 -1
- package/dist/chunk-VEHCNGUP.js.map +0 -1
- /package/dist/{config-IJ57IIQA.js.map → config-PXL632ZX.js.map} +0 -0
- /package/dist/{core-AJYPJ2Z7.js.map → core-SWYVXOQ4.js.map} +0 -0
- /package/dist/{http-FC24JSK7.js.map → http-TID3W235.js.map} +0 -0
package/copilot-instructions.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## What is pncli?
|
|
6
6
|
|
|
7
|
-
pncli is a CLI tool that provides structured JSON access to Jira, Bitbucket, Confluence, SonarQube, SDElements, and local git state. Use it for all interactions with these services. It exists because MCP servers aren't available in this environment — pncli is your agent-friendly shim layer.
|
|
7
|
+
pncli is a CLI tool that provides structured JSON access to Jira, Bitbucket, Confluence, SonarQube, SDElements, Azure DevOps Server, Jenkins, JFrog Artifactory, IBM UrbanCode Deploy, Checkmarx, and local git state. Use it for all interactions with these services. It exists because MCP servers aren't available in this environment — pncli is your agent-friendly shim layer.
|
|
8
8
|
|
|
9
9
|
## Important
|
|
10
10
|
|
|
@@ -30,9 +30,7 @@ pncli ships with Claude Code skills — step-by-step workflow guides that agents
|
|
|
30
30
|
pncli skills install
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
This downloads the latest pncli skills from GitHub
|
|
34
|
-
|
|
35
|
-
Use `--skip-instructions` to skip downloading `copilot-instructions.md`.
|
|
33
|
+
This downloads the latest pncli skills from GitHub. Default installs to `.agents/skills/` (GitHub Copilot). For Claude Code, add `--agent claude-code`. For user-scope, add `--scope user`. Only pncli-managed skills are replaced — any custom skills you've added are left untouched.
|
|
36
34
|
|
|
37
35
|
To see what's installed locally:
|
|
38
36
|
|
|
@@ -42,7 +40,7 @@ pncli skills list
|
|
|
42
40
|
|
|
43
41
|
## Common Workflows
|
|
44
42
|
|
|
45
|
-
> These workflows are also available as
|
|
43
|
+
> These workflows are also available as skills — run `pncli skills install` (Copilot default) or `pncli skills install --agent claude-code` (Claude Code) to download them into your repo. Add `--scope user` for global access.
|
|
46
44
|
|
|
47
45
|
### Review a Pull Request
|
|
48
46
|
|
|
@@ -374,7 +372,8 @@ pncli sonar issues
|
|
|
374
372
|
--resolved <bool> Filter resolved issues: true or false
|
|
375
373
|
--page <n> Page number (1-based) (default: "1")
|
|
376
374
|
--page-size <n> Results per page (max 500) (default: "100")
|
|
377
|
-
--all Fetch all pages (
|
|
375
|
+
--all Fetch all pages (consider --output-file for large
|
|
376
|
+
results; ignores --page/--page-size)
|
|
378
377
|
|
|
379
378
|
pncli sonar measures
|
|
380
379
|
--project <key> SonarQube project key (or set defaults.sonar.project in
|
|
@@ -387,7 +386,7 @@ pncli sonar projects
|
|
|
387
386
|
--query <text> Search query
|
|
388
387
|
--page <n> Page number (1-based) (default: "1")
|
|
389
388
|
--page-size <n> Results per page (default: "100")
|
|
390
|
-
--all Fetch all pages
|
|
389
|
+
--all Fetch all pages (consider --output-file for large results)
|
|
391
390
|
|
|
392
391
|
pncli sonar hotspots
|
|
393
392
|
--project <key> SonarQube project key (or set defaults.sonar.project in
|
|
@@ -397,7 +396,8 @@ pncli sonar hotspots
|
|
|
397
396
|
--branch <name> Branch name
|
|
398
397
|
--page <n> Page number (1-based) (default: "1")
|
|
399
398
|
--page-size <n> Results per page (default: "100")
|
|
400
|
-
--all Fetch all pages
|
|
399
|
+
--all Fetch all pages (consider --output-file for large
|
|
400
|
+
results)
|
|
401
401
|
```
|
|
402
402
|
|
|
403
403
|
### Sde
|
|
@@ -414,7 +414,8 @@ pncli sde users
|
|
|
414
414
|
--active <bool> Filter by active status: true or false
|
|
415
415
|
--page <n> Page number (1-based) (default: "1")
|
|
416
416
|
--page-size <n> Results per page (default: "100")
|
|
417
|
-
--all Fetch all pages
|
|
417
|
+
--all Fetch all pages (consider --output-file for large
|
|
418
|
+
results)
|
|
418
419
|
|
|
419
420
|
pncli sde projects
|
|
420
421
|
--name <name> Filter by project name
|
|
@@ -428,7 +429,7 @@ pncli sde projects
|
|
|
428
429
|
task_counts,permissions
|
|
429
430
|
--page <n> Page number (1-based) (default: "1")
|
|
430
431
|
--page-size <n> Results per page (default: "100")
|
|
431
|
-
--all Fetch all pages
|
|
432
|
+
--all Fetch all pages (consider --output-file for large results)
|
|
432
433
|
|
|
433
434
|
pncli sde project
|
|
434
435
|
--id <id> Project ID (or set defaults.sde.project in config)
|
|
@@ -455,7 +456,8 @@ pncli sde tasks
|
|
|
455
456
|
how_tos,last_note,references,regulation_sections
|
|
456
457
|
--page <n> Page number (1-based) (default: "1")
|
|
457
458
|
--page-size <n> Results per page (default: "100")
|
|
458
|
-
--all Fetch all pages
|
|
459
|
+
--all Fetch all pages (consider --output-file for large
|
|
460
|
+
results)
|
|
459
461
|
|
|
460
462
|
pncli sde task
|
|
461
463
|
--project <id> Project ID (or set defaults.sde.project in config)
|
|
@@ -475,7 +477,8 @@ pncli sde threats
|
|
|
475
477
|
--component-id <id> Filter by component ID
|
|
476
478
|
--page <n> Page number (1-based) (default: "1")
|
|
477
479
|
--page-size <n> Results per page (default: "100")
|
|
478
|
-
--all Fetch all pages
|
|
480
|
+
--all Fetch all pages (consider --output-file for large
|
|
481
|
+
results)
|
|
479
482
|
```
|
|
480
483
|
|
|
481
484
|
### Deps
|
|
@@ -530,6 +533,7 @@ pncli config set
|
|
|
530
533
|
pncli config test
|
|
531
534
|
|
|
532
535
|
pncli config check
|
|
536
|
+
--output <format> Output format: json or table (default: "json")
|
|
533
537
|
```
|
|
534
538
|
|
|
535
539
|
### Ado
|
|
@@ -548,16 +552,113 @@ pncli ado repo
|
|
|
548
552
|
pncli ado pipeline
|
|
549
553
|
```
|
|
550
554
|
|
|
555
|
+
### Jenkins
|
|
556
|
+
|
|
557
|
+
```
|
|
558
|
+
pncli jenkins pipeline
|
|
559
|
+
```
|
|
560
|
+
|
|
561
|
+
### Artifactory
|
|
562
|
+
|
|
563
|
+
```
|
|
564
|
+
pncli artifactory ping
|
|
565
|
+
|
|
566
|
+
pncli artifactory repos
|
|
567
|
+
--type <type> Filter by type: local, virtual, remote, federated
|
|
568
|
+
--package-type <type> Filter by package type: npm, maven, nuget, docker,
|
|
569
|
+
pypi, etc.
|
|
570
|
+
|
|
571
|
+
pncli artifactory artifact-info
|
|
572
|
+
|
|
573
|
+
pncli artifactory properties-get
|
|
574
|
+
|
|
575
|
+
pncli artifactory properties-set
|
|
576
|
+
--recursive Apply recursively to folder contents (default: false)
|
|
577
|
+
|
|
578
|
+
pncli artifactory search
|
|
579
|
+
--repo <name> Filter by repository key
|
|
580
|
+
--name <pattern> Filter by artifact name (supports * and ? wildcards)
|
|
581
|
+
--path <pattern> Filter by artifact path (supports * and ? wildcards)
|
|
582
|
+
--after <date> Created after this date (ISO 8601, e.g. 2024-01-01)
|
|
583
|
+
--before <date> Created before this date (ISO 8601)
|
|
584
|
+
--limit <n> Maximum results to return (default: 100) (default: "100")
|
|
585
|
+
--properties Include artifact properties in results (default: false)
|
|
586
|
+
|
|
587
|
+
pncli artifactory builds
|
|
588
|
+
|
|
589
|
+
pncli artifactory build-runs
|
|
590
|
+
|
|
591
|
+
pncli artifactory build-info
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
### Udeploy
|
|
595
|
+
|
|
596
|
+
```
|
|
597
|
+
pncli udeploy apps
|
|
598
|
+
|
|
599
|
+
pncli udeploy environments
|
|
600
|
+
|
|
601
|
+
pncli udeploy components
|
|
602
|
+
|
|
603
|
+
pncli udeploy versions
|
|
604
|
+
--component <name> Component name or ID
|
|
605
|
+
|
|
606
|
+
pncli udeploy import-version
|
|
607
|
+
--component <name> Component name or ID
|
|
608
|
+
--name <name> Version name
|
|
609
|
+
--no-finish Skip marking the version as finished importing
|
|
610
|
+
|
|
611
|
+
pncli udeploy run
|
|
612
|
+
--process <name> Application process name or ID
|
|
613
|
+
--component <name> Component name (repeatable) (default: [])
|
|
614
|
+
--component-version <name> Component version (repeatable; positionally paired
|
|
615
|
+
with --component) (default: [])
|
|
616
|
+
--snapshot <name> Snapshot name or ID (alternative to specifying
|
|
617
|
+
versions)
|
|
618
|
+
--only-changed Deploy only changed components (default: false)
|
|
619
|
+
--wait Poll until the process completes (default: false)
|
|
620
|
+
--timeout <ms> Max wait time in milliseconds (default: "600000")
|
|
621
|
+
|
|
622
|
+
pncli udeploy request-status
|
|
623
|
+
--request-id <id> Request ID returned by udeploy run
|
|
624
|
+
|
|
625
|
+
pncli udeploy request-info
|
|
626
|
+
--request-id <id> Request ID returned by udeploy run
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
### Checkmarx
|
|
630
|
+
|
|
631
|
+
```
|
|
632
|
+
pncli checkmarx project list
|
|
633
|
+
|
|
634
|
+
pncli checkmarx project get
|
|
635
|
+
--id <id> Project ID (required)
|
|
636
|
+
|
|
637
|
+
pncli checkmarx scan list
|
|
638
|
+
--project <id> Filter by project ID
|
|
639
|
+
--last <n> Return only the last N scans per project
|
|
640
|
+
|
|
641
|
+
pncli checkmarx scan get
|
|
642
|
+
--id <id> Scan ID (required)
|
|
643
|
+
|
|
644
|
+
pncli checkmarx scan stats
|
|
645
|
+
--id <id> Scan ID (required)
|
|
646
|
+
```
|
|
647
|
+
|
|
551
648
|
### Skills
|
|
552
649
|
|
|
553
650
|
```
|
|
554
651
|
pncli skills install
|
|
555
|
-
--
|
|
556
|
-
|
|
557
|
-
|
|
652
|
+
--agent <agent> Target agent host: github-copilot | claude-code (default:
|
|
653
|
+
"github-copilot")
|
|
654
|
+
--scope <scope> Installation scope: project | user (default: "project")
|
|
655
|
+
--target <dir> Override install directory (ignores --agent and --scope)
|
|
558
656
|
|
|
559
657
|
pncli skills list
|
|
560
|
-
--
|
|
658
|
+
--agent <agent> Target agent host: github-copilot | claude-code (default:
|
|
659
|
+
"github-copilot")
|
|
660
|
+
--scope <scope> Installation scope: project | user (default: "project")
|
|
661
|
+
--target <dir> Override skills directory to scan
|
|
561
662
|
```
|
|
562
663
|
|
|
563
664
|
<!-- COMMAND-REFERENCE:END -->
|
|
@@ -575,5 +676,6 @@ Always check `ok` before accessing `data`.
|
|
|
575
676
|
- Use `--dry-run` to preview API calls without executing
|
|
576
677
|
- Use `--verbose` to see full response metadata for debugging
|
|
577
678
|
- Use `--pretty` when running manually for readable output
|
|
679
|
+
- Use `--output-file <path>` to write JSON output to a file instead of stdout — recommended for commands that produce large payloads (search, logs, `--all` pagination) to avoid flooding agent context
|
|
578
680
|
- Pipe output through `jq` for ad-hoc filtering (if available)
|
|
579
681
|
- Defaults from `.pncli.json` are applied automatically — you rarely need to pass `--project`, `--type`, or `--priority` flags for Jira
|
|
@@ -38,8 +38,10 @@ import fs from "fs";
|
|
|
38
38
|
import chalk from "chalk";
|
|
39
39
|
var globalOptions = { pretty: false, verbose: false };
|
|
40
40
|
var globalUser = { email: void 0, userId: void 0 };
|
|
41
|
+
var outputFile;
|
|
41
42
|
function setGlobalOptions(opts) {
|
|
42
|
-
globalOptions = opts;
|
|
43
|
+
globalOptions = { pretty: opts.pretty, verbose: opts.verbose };
|
|
44
|
+
outputFile = opts.outputFile;
|
|
43
45
|
}
|
|
44
46
|
function setGlobalUser(user) {
|
|
45
47
|
globalUser = user;
|
|
@@ -53,15 +55,29 @@ function buildMeta(service, action, startTime) {
|
|
|
53
55
|
user: globalUser.email ?? globalUser.userId ? globalUser : void 0
|
|
54
56
|
};
|
|
55
57
|
}
|
|
58
|
+
function writeToFile(filePath, content) {
|
|
59
|
+
try {
|
|
60
|
+
fs.writeFileSync(filePath, content, "utf8");
|
|
61
|
+
} catch (writeErr) {
|
|
62
|
+
process.stderr.write(
|
|
63
|
+
`Warning: could not write to output file "${filePath}": ${writeErr.message}
|
|
64
|
+
`
|
|
65
|
+
);
|
|
66
|
+
process.exitCode = ExitCode.GENERAL_ERROR;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
56
69
|
function success(data, service, action, startTime) {
|
|
57
70
|
const envelope = {
|
|
58
71
|
ok: true,
|
|
59
72
|
data,
|
|
60
73
|
meta: buildMeta(service, action, startTime)
|
|
61
74
|
};
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
75
|
+
const out = (globalOptions.pretty ? JSON.stringify(envelope, null, 2) : JSON.stringify(envelope)) + "\n";
|
|
76
|
+
if (outputFile) {
|
|
77
|
+
writeToFile(outputFile, out);
|
|
78
|
+
} else {
|
|
79
|
+
process.stdout.write(out);
|
|
80
|
+
}
|
|
65
81
|
}
|
|
66
82
|
function fail(err, service, action, startTime) {
|
|
67
83
|
const errorDetail = {
|
|
@@ -78,10 +94,14 @@ function fail(err, service, action, startTime) {
|
|
|
78
94
|
if (msg) process.stderr.write(msg + "\n");
|
|
79
95
|
const output = (globalOptions.pretty ? JSON.stringify(envelope, null, 2) : JSON.stringify(envelope)) + "\n";
|
|
80
96
|
const exitCode = err instanceof PncliError ? exitCodeFromStatus(err.status) : ExitCode.GENERAL_ERROR;
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
97
|
+
if (outputFile) {
|
|
98
|
+
writeToFile(outputFile, output);
|
|
99
|
+
} else {
|
|
100
|
+
try {
|
|
101
|
+
fs.writeSync(process.stdout.fd, output);
|
|
102
|
+
} catch (writeErr) {
|
|
103
|
+
if (writeErr.code !== "EPIPE") throw writeErr;
|
|
104
|
+
}
|
|
85
105
|
}
|
|
86
106
|
process.exitCode = exitCode;
|
|
87
107
|
throw new PncliError(errorDetail.message, errorDetail.status);
|
|
@@ -124,6 +144,66 @@ async function buildAdoFetcher(config) {
|
|
|
124
144
|
});
|
|
125
145
|
}
|
|
126
146
|
|
|
147
|
+
// src/lib/checkmarxFetch.ts
|
|
148
|
+
var CX_CLIENT_ID = "resource_owner_client";
|
|
149
|
+
var CX_CLIENT_SECRET = "014DF517-39D1-4453-B7B3-9930C563627C";
|
|
150
|
+
var CX_SCOPE = "sast_api offline_access";
|
|
151
|
+
function buildCheckmarxFetcher(config) {
|
|
152
|
+
const { baseUrl, username, password } = config.checkmarx;
|
|
153
|
+
if (!baseUrl) throw new PncliError("Checkmarx baseUrl not configured. Run: pncli config init", 1);
|
|
154
|
+
if (!username) throw new PncliError("Checkmarx username not configured. Run: pncli config init", 1);
|
|
155
|
+
if (!password) throw new PncliError("Checkmarx password not configured. Run: pncli config init", 1);
|
|
156
|
+
const resolvedUsername = username;
|
|
157
|
+
const resolvedPassword = password;
|
|
158
|
+
const tokenUrl = `${baseUrl.replace(/\/$/, "")}/cxrestapi/auth/identity/connect/token`;
|
|
159
|
+
let cache = null;
|
|
160
|
+
async function getToken() {
|
|
161
|
+
const now = Date.now();
|
|
162
|
+
if (cache && cache.expiresAt - now > 6e4) {
|
|
163
|
+
return cache.value;
|
|
164
|
+
}
|
|
165
|
+
const body = new URLSearchParams({
|
|
166
|
+
grant_type: "password",
|
|
167
|
+
client_id: CX_CLIENT_ID,
|
|
168
|
+
client_secret: CX_CLIENT_SECRET,
|
|
169
|
+
scope: CX_SCOPE,
|
|
170
|
+
username: resolvedUsername,
|
|
171
|
+
password: resolvedPassword
|
|
172
|
+
});
|
|
173
|
+
const response = await fetch(tokenUrl, {
|
|
174
|
+
method: "POST",
|
|
175
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
176
|
+
body: body.toString()
|
|
177
|
+
});
|
|
178
|
+
if (!response.ok) {
|
|
179
|
+
const text = await response.text().catch(() => "");
|
|
180
|
+
throw new PncliError(
|
|
181
|
+
`Checkmarx token exchange failed (${response.status}): ${text || response.statusText}`,
|
|
182
|
+
response.status
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
const data = await response.json();
|
|
186
|
+
if (!data.access_token) {
|
|
187
|
+
throw new PncliError("Checkmarx token endpoint returned no access_token", response.status);
|
|
188
|
+
}
|
|
189
|
+
cache = {
|
|
190
|
+
value: data.access_token,
|
|
191
|
+
expiresAt: now + data.expires_in * 1e3
|
|
192
|
+
};
|
|
193
|
+
return cache.value;
|
|
194
|
+
}
|
|
195
|
+
return async (url, init) => {
|
|
196
|
+
const token = await getToken();
|
|
197
|
+
return fetch(url, {
|
|
198
|
+
...init,
|
|
199
|
+
headers: {
|
|
200
|
+
...init?.headers,
|
|
201
|
+
"Authorization": `Bearer ${token}`
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
|
|
127
207
|
// src/lib/http.ts
|
|
128
208
|
function buildUrl(base, path, params) {
|
|
129
209
|
const url = new URL(path, base.endsWith("/") ? base : base + "/");
|
|
@@ -207,6 +287,7 @@ var HttpClient = class {
|
|
|
207
287
|
config;
|
|
208
288
|
dryRun;
|
|
209
289
|
adoFetcher = null;
|
|
290
|
+
checkmarxFetcher = null;
|
|
210
291
|
constructor(config, dryRun = false) {
|
|
211
292
|
this.config = config;
|
|
212
293
|
this.dryRun = dryRun;
|
|
@@ -457,6 +538,172 @@ Headers: ${JSON.stringify(safeHeaders, null, 2)}
|
|
|
457
538
|
}
|
|
458
539
|
return results;
|
|
459
540
|
}
|
|
541
|
+
jenkinsHeaders() {
|
|
542
|
+
const { username, apiToken } = this.config.jenkins;
|
|
543
|
+
if (!username || !apiToken) throw new PncliError("Jenkins credentials not configured. Run: pncli config init");
|
|
544
|
+
const creds = Buffer.from(`${username}:${apiToken}`).toString("base64");
|
|
545
|
+
return {
|
|
546
|
+
"Authorization": `Basic ${creds}`,
|
|
547
|
+
"Content-Type": "application/json",
|
|
548
|
+
"Accept": "application/json",
|
|
549
|
+
"Connection": "close"
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
artifactoryHeaders() {
|
|
553
|
+
const { token } = this.config.artifactory;
|
|
554
|
+
if (!token) throw new PncliError("Artifactory credentials not configured. Run: pncli config init");
|
|
555
|
+
return {
|
|
556
|
+
"Authorization": `Bearer ${token}`,
|
|
557
|
+
"Content-Type": "application/json",
|
|
558
|
+
"Accept": "application/json",
|
|
559
|
+
"Connection": "close"
|
|
560
|
+
};
|
|
561
|
+
}
|
|
562
|
+
udeployHeaders() {
|
|
563
|
+
const { pat, username, password } = this.config.udeploy;
|
|
564
|
+
let encoded;
|
|
565
|
+
if (username && password) {
|
|
566
|
+
encoded = Buffer.from(`${username}:${password}`).toString("base64");
|
|
567
|
+
} else if (username && pat) {
|
|
568
|
+
encoded = Buffer.from(`${username}:${pat}`).toString("base64");
|
|
569
|
+
} else if (pat) {
|
|
570
|
+
encoded = Buffer.from(`PasswordIsAuthToken:${JSON.stringify({ token: pat })}`).toString("base64");
|
|
571
|
+
} else {
|
|
572
|
+
throw new PncliError("UDeploy credentials not configured. Run: pncli config init");
|
|
573
|
+
}
|
|
574
|
+
return {
|
|
575
|
+
"Authorization": `Basic ${encoded}`,
|
|
576
|
+
"Content-Type": "application/json",
|
|
577
|
+
"Accept": "application/json",
|
|
578
|
+
"Connection": "close"
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
async jenkins(path, opts = {}) {
|
|
582
|
+
const baseUrl = this.config.jenkins.baseUrl;
|
|
583
|
+
if (!baseUrl) throw new PncliError("Jenkins baseUrl not configured. Run: pncli config init");
|
|
584
|
+
const url = buildUrl(baseUrl, path, opts.params);
|
|
585
|
+
const headers = this.jenkinsHeaders();
|
|
586
|
+
const init = {
|
|
587
|
+
method: opts.method ?? "GET",
|
|
588
|
+
headers,
|
|
589
|
+
body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0
|
|
590
|
+
};
|
|
591
|
+
if (this.dryRun) {
|
|
592
|
+
const safeHeaders = { ...headers, Authorization: "[REDACTED]" };
|
|
593
|
+
const msg = `DRY RUN: ${init.method} ${url}
|
|
594
|
+
Headers: ${JSON.stringify(safeHeaders, null, 2)}
|
|
595
|
+
` + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}
|
|
596
|
+
` : "");
|
|
597
|
+
fs2.writeSync(process.stderr.fd, msg);
|
|
598
|
+
process.exitCode = ExitCode.SUCCESS;
|
|
599
|
+
throw new PncliError("dry-run", 0);
|
|
600
|
+
}
|
|
601
|
+
return request(url, init, opts.timeoutMs ?? 3e4);
|
|
602
|
+
}
|
|
603
|
+
async jenkinsRaw(path, opts = {}) {
|
|
604
|
+
const baseUrl = this.config.jenkins.baseUrl;
|
|
605
|
+
if (!baseUrl) throw new PncliError("Jenkins baseUrl not configured. Run: pncli config init");
|
|
606
|
+
const url = buildUrl(baseUrl, path, opts.params);
|
|
607
|
+
const headers = this.jenkinsHeaders();
|
|
608
|
+
if (this.dryRun) {
|
|
609
|
+
const safeHeaders = { ...headers, Authorization: "[REDACTED]" };
|
|
610
|
+
const msg = `DRY RUN: ${opts.method ?? "GET"} ${url}
|
|
611
|
+
Headers: ${JSON.stringify(safeHeaders, null, 2)}
|
|
612
|
+
` + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}
|
|
613
|
+
` : "");
|
|
614
|
+
fs2.writeSync(process.stderr.fd, msg);
|
|
615
|
+
process.exitCode = ExitCode.SUCCESS;
|
|
616
|
+
throw new PncliError("dry-run", 0);
|
|
617
|
+
}
|
|
618
|
+
const response = await fetchWithTimeout(url, {
|
|
619
|
+
method: opts.method ?? "GET",
|
|
620
|
+
headers,
|
|
621
|
+
body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0
|
|
622
|
+
}, opts.timeoutMs ?? 3e4);
|
|
623
|
+
if (!response.ok) {
|
|
624
|
+
let message = `HTTP ${response.status} ${response.statusText}`;
|
|
625
|
+
try {
|
|
626
|
+
const parsed = JSON.parse(await response.text());
|
|
627
|
+
if (parsed.message) message = String(parsed.message);
|
|
628
|
+
} catch {
|
|
629
|
+
}
|
|
630
|
+
throw new PncliError(message, response.status, url);
|
|
631
|
+
}
|
|
632
|
+
return { status: response.status, headers: response.headers, text: await response.text() };
|
|
633
|
+
}
|
|
634
|
+
async artifactory(path, opts = {}) {
|
|
635
|
+
const baseUrl = this.config.artifactory.baseUrl;
|
|
636
|
+
if (!baseUrl) throw new PncliError("Artifactory baseUrl not configured. Run: pncli config init");
|
|
637
|
+
const url = buildUrl(baseUrl, path, opts.params);
|
|
638
|
+
const headers = { ...this.artifactoryHeaders(), ...opts.headers };
|
|
639
|
+
const body = opts.body !== void 0 ? typeof opts.body === "string" ? opts.body : JSON.stringify(opts.body) : void 0;
|
|
640
|
+
const init = {
|
|
641
|
+
method: opts.method ?? "GET",
|
|
642
|
+
headers,
|
|
643
|
+
body
|
|
644
|
+
};
|
|
645
|
+
if (this.dryRun) {
|
|
646
|
+
const safeHeaders = { ...headers, Authorization: "[REDACTED]" };
|
|
647
|
+
const msg = `DRY RUN: ${init.method} ${url}
|
|
648
|
+
Headers: ${JSON.stringify(safeHeaders, null, 2)}
|
|
649
|
+
` + (opts.body ? `Body: ${typeof opts.body === "string" ? opts.body : JSON.stringify(opts.body, null, 2)}
|
|
650
|
+
` : "");
|
|
651
|
+
fs2.writeSync(process.stderr.fd, msg);
|
|
652
|
+
process.exitCode = ExitCode.SUCCESS;
|
|
653
|
+
throw new PncliError("dry-run", 0);
|
|
654
|
+
}
|
|
655
|
+
return request(url, init, opts.timeoutMs ?? 3e4);
|
|
656
|
+
}
|
|
657
|
+
async udeploy(path, opts = {}) {
|
|
658
|
+
const baseUrl = this.config.udeploy.baseUrl;
|
|
659
|
+
if (!baseUrl) throw new PncliError("UDeploy baseUrl not configured. Run: pncli config init");
|
|
660
|
+
const url = buildUrl(baseUrl, path, opts.params);
|
|
661
|
+
const headers = this.udeployHeaders();
|
|
662
|
+
const init = {
|
|
663
|
+
method: opts.method ?? "GET",
|
|
664
|
+
headers,
|
|
665
|
+
body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0
|
|
666
|
+
};
|
|
667
|
+
if (this.dryRun) {
|
|
668
|
+
const safeHeaders = { ...headers, Authorization: "[REDACTED]" };
|
|
669
|
+
const msg = `DRY RUN: ${init.method} ${url}
|
|
670
|
+
Headers: ${JSON.stringify(safeHeaders, null, 2)}
|
|
671
|
+
` + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}
|
|
672
|
+
` : "");
|
|
673
|
+
fs2.writeSync(process.stderr.fd, msg);
|
|
674
|
+
process.exitCode = ExitCode.SUCCESS;
|
|
675
|
+
throw new PncliError("dry-run", 0);
|
|
676
|
+
}
|
|
677
|
+
return request(url, init, opts.timeoutMs ?? 3e4);
|
|
678
|
+
}
|
|
679
|
+
async artifactoryText(path, opts = {}) {
|
|
680
|
+
const baseUrl = this.config.artifactory.baseUrl;
|
|
681
|
+
if (!baseUrl) throw new PncliError("Artifactory baseUrl not configured. Run: pncli config init");
|
|
682
|
+
const url = buildUrl(baseUrl, path, opts.params);
|
|
683
|
+
const headers = { ...this.artifactoryHeaders(), Accept: "text/plain", ...opts.headers };
|
|
684
|
+
if (this.dryRun) {
|
|
685
|
+
const safeHeaders = { ...headers, Authorization: "[REDACTED]" };
|
|
686
|
+
fs2.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? "GET"} ${url}
|
|
687
|
+
Headers: ${JSON.stringify(safeHeaders, null, 2)}
|
|
688
|
+
`);
|
|
689
|
+
process.exitCode = ExitCode.SUCCESS;
|
|
690
|
+
throw new PncliError("dry-run", 0);
|
|
691
|
+
}
|
|
692
|
+
const response = await fetchWithTimeout(url, {
|
|
693
|
+
method: opts.method ?? "GET",
|
|
694
|
+
headers
|
|
695
|
+
}, opts.timeoutMs ?? 3e4);
|
|
696
|
+
if (!response.ok) {
|
|
697
|
+
let message = `HTTP ${response.status} ${response.statusText}`;
|
|
698
|
+
try {
|
|
699
|
+
const parsed = JSON.parse(await response.text());
|
|
700
|
+
if (parsed.message) message = String(parsed.message);
|
|
701
|
+
} catch {
|
|
702
|
+
}
|
|
703
|
+
throw new PncliError(message, response.status, url);
|
|
704
|
+
}
|
|
705
|
+
return response.text();
|
|
706
|
+
}
|
|
460
707
|
sonarHeaders() {
|
|
461
708
|
const { token } = this.config.sonar;
|
|
462
709
|
if (!token) throw new PncliError("SonarQube credentials not configured. Run: pncli config init");
|
|
@@ -538,6 +785,32 @@ Headers: ${JSON.stringify(safeHeaders, null, 2)}
|
|
|
538
785
|
}
|
|
539
786
|
return results;
|
|
540
787
|
}
|
|
788
|
+
getCheckmarxFetcher() {
|
|
789
|
+
if (!this.checkmarxFetcher) {
|
|
790
|
+
this.checkmarxFetcher = buildCheckmarxFetcher(this.config);
|
|
791
|
+
}
|
|
792
|
+
return this.checkmarxFetcher;
|
|
793
|
+
}
|
|
794
|
+
async checkmarx(path, opts = {}) {
|
|
795
|
+
const baseUrl = this.config.checkmarx.baseUrl;
|
|
796
|
+
if (!baseUrl) throw new PncliError("Checkmarx baseUrl not configured. Run: pncli config init");
|
|
797
|
+
const url = buildUrl(baseUrl, path, opts.params);
|
|
798
|
+
if (this.dryRun) {
|
|
799
|
+
const msg = `DRY RUN: ${opts.method ?? "GET"} ${url}
|
|
800
|
+
` + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}
|
|
801
|
+
` : "");
|
|
802
|
+
fs2.writeSync(process.stderr.fd, msg);
|
|
803
|
+
process.exitCode = ExitCode.SUCCESS;
|
|
804
|
+
throw new PncliError("dry-run", 0);
|
|
805
|
+
}
|
|
806
|
+
const fetcher = this.getCheckmarxFetcher();
|
|
807
|
+
const init = {
|
|
808
|
+
method: opts.method ?? "GET",
|
|
809
|
+
headers: { "Accept": "application/json", "Content-Type": "application/json", ...opts.headers },
|
|
810
|
+
body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0
|
|
811
|
+
};
|
|
812
|
+
return request(url, init, opts.timeoutMs ?? 3e4, fetcher);
|
|
813
|
+
}
|
|
541
814
|
};
|
|
542
815
|
function createHttpClient(config, dryRun = false) {
|
|
543
816
|
return new HttpClient(config, dryRun);
|
|
@@ -555,4 +828,4 @@ export {
|
|
|
555
828
|
HttpClient,
|
|
556
829
|
createHttpClient
|
|
557
830
|
};
|
|
558
|
-
//# sourceMappingURL=chunk-
|
|
831
|
+
//# sourceMappingURL=chunk-QQ7UKWTU.js.map
|