@kolatts/pncli 1.14.1 → 1.16.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/copilot-instructions.md +212 -19
- package/dist/{chunk-CFUUOW7B.js → chunk-P5NWDQ2B.js} +12 -1
- package/dist/chunk-P5NWDQ2B.js.map +1 -0
- package/dist/{chunk-BNMFIGXF.js → chunk-XPPEXJBP.js} +114 -4
- package/dist/chunk-XPPEXJBP.js.map +1 -0
- package/dist/cli.js +725 -109
- package/dist/cli.js.map +1 -1
- package/dist/{config-TL5X47RY.js → config-3QD5Y2O5.js} +2 -2
- package/dist/{http-UN6N4WIB.js → http-5WRBWEM6.js} +2 -2
- package/package.json +1 -1
- package/skills/pncli/SKILL.md +2 -1
- package/skills/pncli/github.md +38 -0
- package/dist/chunk-BNMFIGXF.js.map +0 -1
- package/dist/chunk-CFUUOW7B.js.map +0 -1
- /package/dist/{config-TL5X47RY.js.map → config-3QD5Y2O5.js.map} +0 -0
- /package/dist/{http-UN6N4WIB.js.map → http-5WRBWEM6.js.map} +0 -0
package/copilot-instructions.md
CHANGED
|
@@ -148,9 +148,12 @@ pncli jira create-issue
|
|
|
148
148
|
--priority <name> Priority name
|
|
149
149
|
--assignee <accountId> Assignee account ID
|
|
150
150
|
--labels <labels> Comma-separated labels
|
|
151
|
-
--parent <key> Parent issue key —
|
|
152
|
-
|
|
153
|
-
--field <Name=value> Custom field value
|
|
151
|
+
--parent <key> Parent issue key — sets fields.parent in the create
|
|
152
|
+
payload
|
|
153
|
+
--field <Name=value> Custom field value; use Name=@file.json to read value
|
|
154
|
+
from file (repeatable) (default: [])
|
|
155
|
+
--fields-file <path> Path to a JSON file mapping field names/IDs to their
|
|
156
|
+
Jira API values
|
|
154
157
|
|
|
155
158
|
pncli jira update-issue
|
|
156
159
|
--key <issue-key> Issue key
|
|
@@ -159,7 +162,10 @@ pncli jira update-issue
|
|
|
159
162
|
--priority <name> New priority
|
|
160
163
|
--assignee <accountId> New assignee account ID
|
|
161
164
|
--labels <labels> Comma-separated labels
|
|
162
|
-
--field <Name=value> Custom field value
|
|
165
|
+
--field <Name=value> Custom field value; use Name=@file.json to read value
|
|
166
|
+
from file (repeatable) (default: [])
|
|
167
|
+
--fields-file <path> Path to a JSON file mapping field names/IDs to their
|
|
168
|
+
Jira API values
|
|
163
169
|
|
|
164
170
|
pncli jira transition-issue
|
|
165
171
|
--key <issue-key> Issue key
|
|
@@ -179,6 +185,14 @@ pncli jira search
|
|
|
179
185
|
--jql <query> JQL query string
|
|
180
186
|
--max-results <n> Maximum number of results
|
|
181
187
|
|
|
188
|
+
pncli jira add-label
|
|
189
|
+
--key <issue-key> Issue key
|
|
190
|
+
--labels <labels> Comma-separated labels to add
|
|
191
|
+
|
|
192
|
+
pncli jira remove-label
|
|
193
|
+
--key <issue-key> Issue key
|
|
194
|
+
--labels <labels> Comma-separated labels to remove
|
|
195
|
+
|
|
182
196
|
pncli jira assign
|
|
183
197
|
--key <issue-key> Issue key
|
|
184
198
|
--assignee <accountId> Assignee account ID
|
|
@@ -188,9 +202,25 @@ pncli jira link-issue
|
|
|
188
202
|
--link-type <type> Link type name or ID
|
|
189
203
|
--target <issue-key> Target issue key
|
|
190
204
|
|
|
205
|
+
pncli jira add-attachment
|
|
206
|
+
--key <issue-key> Issue key (e.g. PROJ-123)
|
|
207
|
+
--file <path> Path to the file to upload
|
|
208
|
+
|
|
209
|
+
pncli jira list-attachments
|
|
210
|
+
--key <issue-key> Issue key (e.g. PROJ-123)
|
|
211
|
+
|
|
212
|
+
pncli jira download-attachment
|
|
213
|
+
--key <issue-key> Issue key (e.g. PROJ-123)
|
|
214
|
+
--attachment-id <id> Attachment ID from list-attachments output
|
|
215
|
+
--dir <path> Output directory (default: .pncli relative to cwd)
|
|
216
|
+
|
|
191
217
|
pncli jira fields
|
|
192
|
-
--discover
|
|
193
|
-
--custom-only
|
|
218
|
+
--discover Fetch field metadata from Jira API
|
|
219
|
+
--custom-only Show only custom fields (requires --discover)
|
|
220
|
+
--project <key> Project key — fetches allowedValues for select fields via
|
|
221
|
+
createmeta (requires --discover)
|
|
222
|
+
--issue-type <type> Filter allowedValues to a specific issue type (requires
|
|
223
|
+
--project)
|
|
194
224
|
```
|
|
195
225
|
|
|
196
226
|
### Bitbucket
|
|
@@ -210,6 +240,9 @@ pncli bitbucket create-pr
|
|
|
210
240
|
--target <branch> Target branch (defaults to config)
|
|
211
241
|
--description <desc> PR description
|
|
212
242
|
--reviewers <users> Comma-separated reviewer usernames
|
|
243
|
+
--project <key> Bitbucket project key (overrides parent --project; use
|
|
244
|
+
~username for personal repos)
|
|
245
|
+
--repo <slug> Bitbucket repository slug (overrides parent --repo)
|
|
213
246
|
|
|
214
247
|
pncli bitbucket update-pr
|
|
215
248
|
--id <pr-id> Pull request ID
|
|
@@ -284,6 +317,98 @@ pncli bitbucket get-build-status
|
|
|
284
317
|
--commit <sha> Commit SHA
|
|
285
318
|
```
|
|
286
319
|
|
|
320
|
+
### Github
|
|
321
|
+
|
|
322
|
+
```
|
|
323
|
+
pncli github list-prs
|
|
324
|
+
--state <state> PR state (choices: "open", "closed", "all", default: "open")
|
|
325
|
+
--head <branch> Filter by head branch (user:branch)
|
|
326
|
+
--base <branch> Filter by base branch
|
|
327
|
+
|
|
328
|
+
pncli github get-pr
|
|
329
|
+
--number <n> Pull request number
|
|
330
|
+
|
|
331
|
+
pncli github create-pr
|
|
332
|
+
--title <title> PR title
|
|
333
|
+
--head <branch> Source branch (or user:branch for forks)
|
|
334
|
+
--base <branch> Target branch (defaults to config or main)
|
|
335
|
+
--body <body> PR description
|
|
336
|
+
--draft Create as draft PR
|
|
337
|
+
--owner <owner> GitHub owner (overrides parent --owner)
|
|
338
|
+
--repo <repo> GitHub repository name (overrides parent --repo)
|
|
339
|
+
|
|
340
|
+
pncli github update-pr
|
|
341
|
+
--number <n> Pull request number
|
|
342
|
+
--title <title> New title
|
|
343
|
+
--body <body> New description
|
|
344
|
+
--base <branch> New base branch
|
|
345
|
+
|
|
346
|
+
pncli github merge-pr
|
|
347
|
+
--number <n> Pull request number
|
|
348
|
+
--method <method> Merge method (choices: "merge", "squash", "rebase",
|
|
349
|
+
default: "merge")
|
|
350
|
+
--commit-title <title> Commit title for merge/squash
|
|
351
|
+
--commit-message <msg> Commit message for merge/squash
|
|
352
|
+
|
|
353
|
+
pncli github close-pr
|
|
354
|
+
--number <n> Pull request number
|
|
355
|
+
|
|
356
|
+
pncli github list-comments
|
|
357
|
+
--number <n> Pull request number
|
|
358
|
+
|
|
359
|
+
pncli github add-comment
|
|
360
|
+
--number <n> Pull request number
|
|
361
|
+
--body <text> Comment text
|
|
362
|
+
|
|
363
|
+
pncli github list-review-comments
|
|
364
|
+
--number <n> Pull request number
|
|
365
|
+
|
|
366
|
+
pncli github add-inline-comment
|
|
367
|
+
--number <n> Pull request number
|
|
368
|
+
--commit <sha> Commit SHA the comment is on
|
|
369
|
+
--file <path> File path
|
|
370
|
+
--line <n> Line number
|
|
371
|
+
--body <text> Comment text
|
|
372
|
+
--side <side> Comment side (choices: "LEFT", "RIGHT", default: "RIGHT")
|
|
373
|
+
|
|
374
|
+
pncli github reply-comment
|
|
375
|
+
--number <n> Pull request number
|
|
376
|
+
--comment-id <id> Review comment ID to reply to
|
|
377
|
+
--body <text> Reply text
|
|
378
|
+
|
|
379
|
+
pncli github delete-comment
|
|
380
|
+
--comment-id <id> Comment ID
|
|
381
|
+
|
|
382
|
+
pncli github delete-review-comment
|
|
383
|
+
--comment-id <id> Review comment ID
|
|
384
|
+
|
|
385
|
+
pncli github diff
|
|
386
|
+
--number <n> Pull request number
|
|
387
|
+
|
|
388
|
+
pncli github list-files
|
|
389
|
+
--number <n> Pull request number
|
|
390
|
+
|
|
391
|
+
pncli github list-reviews
|
|
392
|
+
--number <n> Pull request number
|
|
393
|
+
|
|
394
|
+
pncli github approve
|
|
395
|
+
--number <n> Pull request number
|
|
396
|
+
--body <text> Review body text
|
|
397
|
+
|
|
398
|
+
pncli github request-changes
|
|
399
|
+
--number <n> Pull request number
|
|
400
|
+
--body <text> Review feedback text
|
|
401
|
+
|
|
402
|
+
pncli github list-reviewers
|
|
403
|
+
--number <n> Pull request number
|
|
404
|
+
|
|
405
|
+
pncli github get-status
|
|
406
|
+
--ref <ref> Git ref (branch, tag, or commit SHA)
|
|
407
|
+
|
|
408
|
+
pncli github list-checks
|
|
409
|
+
--ref <ref> Git ref (branch, tag, or commit SHA)
|
|
410
|
+
```
|
|
411
|
+
|
|
287
412
|
### Confluence
|
|
288
413
|
|
|
289
414
|
```
|
|
@@ -298,7 +423,7 @@ pncli confluence get-page-by-title
|
|
|
298
423
|
|
|
299
424
|
pncli confluence list-pages
|
|
300
425
|
--space <key> Space key
|
|
301
|
-
--limit <n> Max
|
|
426
|
+
--limit <n> Max total pages to return (default: all)
|
|
302
427
|
--start <n> Offset for first result
|
|
303
428
|
|
|
304
429
|
pncli confluence get-page-children
|
|
@@ -352,7 +477,7 @@ pncli confluence remove-label
|
|
|
352
477
|
|
|
353
478
|
pncli confluence list-spaces
|
|
354
479
|
--type <type> Space type: global or personal
|
|
355
|
-
--limit <n> Max
|
|
480
|
+
--limit <n> Max total spaces to return (default: all)
|
|
356
481
|
|
|
357
482
|
pncli confluence get-space
|
|
358
483
|
--key <space-key> Space key
|
|
@@ -605,6 +730,27 @@ pncli ado work add-comment
|
|
|
605
730
|
--id <n> Work item ID
|
|
606
731
|
--body <text> Comment text
|
|
607
732
|
|
|
733
|
+
pncli ado work add-tag
|
|
734
|
+
--id <n> Work item ID
|
|
735
|
+
--tags <tags> Semicolon- or comma-separated tags to add
|
|
736
|
+
|
|
737
|
+
pncli ado work remove-tag
|
|
738
|
+
--id <n> Work item ID
|
|
739
|
+
--tags <tags> Semicolon- or comma-separated tags to remove
|
|
740
|
+
|
|
741
|
+
pncli ado work list-attachments
|
|
742
|
+
--id <n> Work item ID
|
|
743
|
+
|
|
744
|
+
pncli ado work add-attachment
|
|
745
|
+
--id <n> Work item ID
|
|
746
|
+
--file <path> Path to the file to upload
|
|
747
|
+
--comment <text> Optional comment for the attachment
|
|
748
|
+
|
|
749
|
+
pncli ado work download-attachment
|
|
750
|
+
--id <n> Work item ID
|
|
751
|
+
--attachment-id <guid> Attachment ID from work list-attachments output
|
|
752
|
+
--dir <path> Output directory (default: .pncli relative to cwd)
|
|
753
|
+
|
|
608
754
|
pncli ado work types
|
|
609
755
|
--discover Fetch from server (always true for this command)
|
|
610
756
|
--save Save discovered types to ~/.pncli/config.json
|
|
@@ -723,6 +869,8 @@ pncli ado pipeline run
|
|
|
723
869
|
|
|
724
870
|
pncli ado pipeline list-runs
|
|
725
871
|
--definition <id> Filter by definition ID
|
|
872
|
+
--name <name> Filter by pipeline name (resolved to definition ID; use
|
|
873
|
+
pipeline list to see names)
|
|
726
874
|
--branch <ref> Filter by branch name
|
|
727
875
|
--status <filter> Filter by status (inProgress|completed|cancelling|...)
|
|
728
876
|
--top <n> Maximum results (default: "50")
|
|
@@ -734,20 +882,24 @@ pncli ado pipeline cancel-run
|
|
|
734
882
|
--id <n> Build ID
|
|
735
883
|
|
|
736
884
|
pncli ado pipeline logs
|
|
737
|
-
--id <n>
|
|
738
|
-
--
|
|
885
|
+
--build-id <n> Build (run) ID — from pipeline list-runs or get-run
|
|
886
|
+
--id <n> Build (run) ID — alias for --build-id (kept for backwards
|
|
887
|
+
compatibility)
|
|
888
|
+
--log-id <n> Specific log ID (omit to list all logs)
|
|
739
889
|
```
|
|
740
890
|
|
|
741
891
|
### Jenkins
|
|
742
892
|
|
|
743
893
|
```
|
|
744
894
|
pncli jenkins pipeline list
|
|
895
|
+
--folder <name> Folder name to enumerate (supports nested folders:
|
|
896
|
+
parentFolder/childFolder)
|
|
745
897
|
|
|
746
898
|
pncli jenkins pipeline get
|
|
747
|
-
--name <job> Job name
|
|
899
|
+
--name <job> Job name (use folder/job for folder-scoped jobs)
|
|
748
900
|
|
|
749
901
|
pncli jenkins pipeline run
|
|
750
|
-
--name <job> Job name
|
|
902
|
+
--name <job> Job name (use folder/job for folder-scoped jobs)
|
|
751
903
|
--parameter <k=v> Build parameter (repeatable) (default: [])
|
|
752
904
|
--wait Wait for the build to complete before returning
|
|
753
905
|
--timeout <s> Max wait time in seconds per phase (queue-wait and
|
|
@@ -756,15 +908,15 @@ pncli jenkins pipeline run
|
|
|
756
908
|
--poll <s> Poll interval in seconds (default 10) (default: "10")
|
|
757
909
|
|
|
758
910
|
pncli jenkins pipeline list-runs
|
|
759
|
-
--name <job> Job name
|
|
911
|
+
--name <job> Job name (use folder/job for folder-scoped jobs)
|
|
760
912
|
--top <n> Maximum number of builds to return (default 25) (default: "25")
|
|
761
913
|
|
|
762
914
|
pncli jenkins pipeline get-run
|
|
763
|
-
--name <job> Job name
|
|
915
|
+
--name <job> Job name (use folder/job for folder-scoped jobs)
|
|
764
916
|
--number <n> Build number
|
|
765
917
|
|
|
766
918
|
pncli jenkins pipeline logs
|
|
767
|
-
--name <job> Job name
|
|
919
|
+
--name <job> Job name (use folder/job for folder-scoped jobs)
|
|
768
920
|
--number <n> Build number
|
|
769
921
|
```
|
|
770
922
|
|
|
@@ -795,6 +947,8 @@ pncli artifactory search
|
|
|
795
947
|
--properties Include artifact properties in results (default: false)
|
|
796
948
|
|
|
797
949
|
pncli artifactory builds
|
|
950
|
+
--timeout <s> Request timeout in seconds (default 60; increase for large
|
|
951
|
+
Artifactory instances) (default: "60")
|
|
798
952
|
|
|
799
953
|
pncli artifactory build-runs
|
|
800
954
|
|
|
@@ -946,12 +1100,51 @@ pncli skills list
|
|
|
946
1100
|
--target <dir> Override skills directory to scan
|
|
947
1101
|
|
|
948
1102
|
pncli skills marketplace setup
|
|
949
|
-
--branch <branch> Branch to clone (default:
|
|
950
|
-
--token <token>
|
|
951
|
-
|
|
1103
|
+
--branch <branch> Branch to clone (default: remote HEAD)
|
|
1104
|
+
--token <token> HTTP access token for authenticated clone and pull (GitHub
|
|
1105
|
+
PAT or Bitbucket token)
|
|
1106
|
+
--agent <agent> Target agent host for plugin install: github-copilot |
|
|
1107
|
+
claude-code (default: github-copilot)
|
|
1108
|
+
--claude Shorthand for --agent claude-code
|
|
952
1109
|
|
|
953
1110
|
pncli skills marketplace sync
|
|
954
|
-
--
|
|
1111
|
+
--agent <agent> Target agent host: github-copilot | claude-code (default:
|
|
1112
|
+
github-copilot)
|
|
1113
|
+
--claude Shorthand for --agent claude-code
|
|
1114
|
+
--force Force reinstall even if the marketplace repo has no new
|
|
1115
|
+
changes
|
|
1116
|
+
```
|
|
1117
|
+
|
|
1118
|
+
### Jwt
|
|
1119
|
+
|
|
1120
|
+
```
|
|
1121
|
+
pncli jwt decode
|
|
1122
|
+
```
|
|
1123
|
+
|
|
1124
|
+
### Openshift
|
|
1125
|
+
|
|
1126
|
+
```
|
|
1127
|
+
pncli openshift pods
|
|
1128
|
+
--namespace <ns> Kubernetes namespace
|
|
1129
|
+
--label-selector <selector> Label selector (e.g. app=my-app)
|
|
1130
|
+
|
|
1131
|
+
pncli openshift events
|
|
1132
|
+
--namespace <ns> Kubernetes namespace
|
|
1133
|
+
--field-selector <selector> Additional field selector (e.g.
|
|
1134
|
+
involvedObject.name=my-pod)
|
|
1135
|
+
--all Include Normal events in addition to Warning
|
|
1136
|
+
events (default: false)
|
|
1137
|
+
|
|
1138
|
+
pncli openshift logs
|
|
1139
|
+
--namespace <ns> Kubernetes namespace
|
|
1140
|
+
--pod <name> Pod name
|
|
1141
|
+
--container <name> Container name (defaults to first container)
|
|
1142
|
+
--lines <n> Number of most-recent lines to return (default: "100")
|
|
1143
|
+
--previous Return logs from the previous container instance (default:
|
|
1144
|
+
false)
|
|
1145
|
+
|
|
1146
|
+
pncli openshift pod-metrics
|
|
1147
|
+
--namespace <ns> Kubernetes namespace
|
|
955
1148
|
```
|
|
956
1149
|
|
|
957
1150
|
<!-- COMMAND-REFERENCE:END -->
|
|
@@ -12,6 +12,8 @@ var ENV_KEYS = {
|
|
|
12
12
|
JIRA_API_TOKEN: "PNCLI_JIRA_API_TOKEN",
|
|
13
13
|
BITBUCKET_BASE_URL: "PNCLI_BITBUCKET_BASE_URL",
|
|
14
14
|
BITBUCKET_PAT: "PNCLI_BITBUCKET_PAT",
|
|
15
|
+
GITHUB_BASE_URL: "PNCLI_GITHUB_BASE_URL",
|
|
16
|
+
GITHUB_TOKEN: "PNCLI_GITHUB_TOKEN",
|
|
15
17
|
CONFLUENCE_BASE_URL: "PNCLI_CONFLUENCE_BASE_URL",
|
|
16
18
|
CONFLUENCE_API_TOKEN: "PNCLI_CONFLUENCE_API_TOKEN",
|
|
17
19
|
ARTIFACTORY_BASE_URL: "PNCLI_ARTIFACTORY_BASE_URL",
|
|
@@ -89,6 +91,7 @@ function mergeDefaults(global, repo) {
|
|
|
89
91
|
return {
|
|
90
92
|
jira: { ...global?.jira, ...repo?.jira },
|
|
91
93
|
bitbucket: { ...global?.bitbucket, ...repo?.bitbucket },
|
|
94
|
+
github: { ...global?.github, ...repo?.github },
|
|
92
95
|
sonar: { ...global?.sonar, ...repo?.sonar },
|
|
93
96
|
sde: { ...global?.sde, ...repo?.sde },
|
|
94
97
|
ado: { ...global?.ado, ...repo?.ado },
|
|
@@ -118,6 +121,10 @@ function loadConfig(opts = {}) {
|
|
|
118
121
|
baseUrl: process.env[ENV_KEYS.BITBUCKET_BASE_URL] ?? globalConfig.bitbucket?.baseUrl,
|
|
119
122
|
pat: process.env[ENV_KEYS.BITBUCKET_PAT] ?? globalConfig.bitbucket?.pat
|
|
120
123
|
},
|
|
124
|
+
github: {
|
|
125
|
+
baseUrl: process.env[ENV_KEYS.GITHUB_BASE_URL] ?? globalConfig.github?.baseUrl,
|
|
126
|
+
token: process.env[ENV_KEYS.GITHUB_TOKEN] ?? globalConfig.github?.token
|
|
127
|
+
},
|
|
121
128
|
confluence: {
|
|
122
129
|
baseUrl: process.env[ENV_KEYS.CONFLUENCE_BASE_URL] ?? globalConfig.confluence?.baseUrl,
|
|
123
130
|
apiToken: process.env[ENV_KEYS.CONFLUENCE_API_TOKEN] ?? globalConfig.confluence?.apiToken ?? process.env[ENV_KEYS.JIRA_API_TOKEN] ?? globalConfig.jira?.apiToken,
|
|
@@ -244,6 +251,10 @@ function maskConfig(config) {
|
|
|
244
251
|
...config.bitbucket,
|
|
245
252
|
pat: config.bitbucket.pat ? "***" : void 0
|
|
246
253
|
},
|
|
254
|
+
github: {
|
|
255
|
+
...config.github,
|
|
256
|
+
token: config.github.token ? "***" : void 0
|
|
257
|
+
},
|
|
247
258
|
confluence: {
|
|
248
259
|
...config.confluence,
|
|
249
260
|
apiToken: config.confluence.apiToken ? "***" : void 0
|
|
@@ -308,4 +319,4 @@ export {
|
|
|
308
319
|
setRepoConfigValue,
|
|
309
320
|
maskConfig
|
|
310
321
|
};
|
|
311
|
-
//# sourceMappingURL=chunk-
|
|
322
|
+
//# sourceMappingURL=chunk-P5NWDQ2B.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/lib/config.ts"],"sourcesContent":["import fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport { execSync } from 'child_process';\nimport type { GlobalConfig, RepoConfig, ResolvedConfig, JiraDefaults, BitbucketDefaults, GitHubDefaults, SonarDefaults, SdeDefaults, AdoDefaults, UdeployDefaults } from '../types/config.js';\nimport type { CustomFieldDefinition } from '../types/jira.js';\n\nconst ENV_KEYS = {\n EMAIL: 'PNCLI_EMAIL',\n USERID: 'PNCLI_USERID',\n JIRA_BASE_URL: 'PNCLI_JIRA_BASE_URL',\n JIRA_API_TOKEN: 'PNCLI_JIRA_API_TOKEN',\n BITBUCKET_BASE_URL: 'PNCLI_BITBUCKET_BASE_URL',\n BITBUCKET_PAT: 'PNCLI_BITBUCKET_PAT',\n GITHUB_BASE_URL: 'PNCLI_GITHUB_BASE_URL',\n GITHUB_TOKEN: 'PNCLI_GITHUB_TOKEN',\n CONFLUENCE_BASE_URL: 'PNCLI_CONFLUENCE_BASE_URL',\n CONFLUENCE_API_TOKEN: 'PNCLI_CONFLUENCE_API_TOKEN',\n ARTIFACTORY_BASE_URL: 'PNCLI_ARTIFACTORY_BASE_URL',\n ARTIFACTORY_TOKEN: 'PNCLI_ARTIFACTORY_TOKEN',\n ARTIFACTORY_REPO_NPM: 'PNCLI_ARTIFACTORY_REPO_NPM',\n ARTIFACTORY_REPO_NUGET: 'PNCLI_ARTIFACTORY_REPO_NUGET',\n ARTIFACTORY_REPO_MAVEN: 'PNCLI_ARTIFACTORY_REPO_MAVEN',\n SONAR_BASE_URL: 'PNCLI_SONAR_BASE_URL',\n SONAR_TOKEN: 'PNCLI_SONAR_TOKEN',\n SDE_CONNECTION: 'PNCLI_SDE_CONNECTION',\n ADO_BASE_URL: 'PNCLI_ADO_BASE_URL',\n ADO_PAT: 'PNCLI_ADO_PAT',\n JENKINS_BASE_URL: 'PNCLI_JENKINS_BASE_URL',\n JENKINS_USERNAME: 'PNCLI_JENKINS_USERNAME',\n JENKINS_API_TOKEN: 'PNCLI_JENKINS_API_TOKEN',\n UDEPLOY_BASE_URL: 'PNCLI_UDEPLOY_BASE_URL',\n UDEPLOY_PAT: 'PNCLI_UDEPLOY_PAT',\n UDEPLOY_USERNAME: 'PNCLI_UDEPLOY_USERNAME',\n UDEPLOY_PASSWORD: 'PNCLI_UDEPLOY_PASSWORD',\n CHECKMARX_BASE_URL: 'PNCLI_CHECKMARX_BASE_URL',\n CHECKMARX_USERNAME: 'PNCLI_CHECKMARX_USERNAME',\n CHECKMARX_PASSWORD: 'PNCLI_CHECKMARX_PASSWORD',\n SERVICENOW_BASE_URL: 'PNCLI_SERVICENOW_BASE_URL',\n SERVICENOW_USERNAME: 'PNCLI_SERVICENOW_USERNAME',\n SERVICENOW_PASSWORD: 'PNCLI_SERVICENOW_PASSWORD',\n SERVICENOW_API_TOKEN: 'PNCLI_SERVICENOW_API_TOKEN',\n CONTRAST_BASE_URL: 'PNCLI_CONTRAST_BASE_URL',\n CONTRAST_ORG_UUID: 'PNCLI_CONTRAST_ORG_UUID',\n CONTRAST_API_KEY: 'PNCLI_CONTRAST_API_KEY',\n CONTRAST_SERVICE_KEY: 'PNCLI_CONTRAST_SERVICE_KEY',\n CONTRAST_USERNAME: 'PNCLI_CONTRAST_USERNAME',\n SONATYPEIQ_BASE_URL: 'PNCLI_SONATYPEIQ_BASE_URL',\n SONATYPEIQ_USER_CODE: 'PNCLI_SONATYPEIQ_USER_CODE',\n SONATYPEIQ_PASSCODE: 'PNCLI_SONATYPEIQ_PASSCODE',\n OPENSHIFT_BASE_URL: 'PNCLI_OPENSHIFT_BASE_URL',\n OPENSHIFT_TOKEN: 'PNCLI_OPENSHIFT_TOKEN',\n CONFIG_PATH: 'PNCLI_CONFIG_PATH'\n} as const;\n\nfunction getGlobalConfigPath(overridePath?: string): string {\n if (overridePath) return overridePath;\n const envPath = process.env[ENV_KEYS.CONFIG_PATH];\n if (envPath) return envPath;\n return path.join(os.homedir(), '.pncli', 'config.json');\n}\n\nfunction loadJsonFile<T>(filePath: string): T | null {\n try {\n const content = fs.readFileSync(filePath, 'utf8');\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\nfunction getRepoRoot(): string | null {\n try {\n return execSync('git rev-parse --show-toplevel', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();\n } catch {\n return null;\n }\n}\n\nfunction parseSdeConnection(connection: string): { token: string; baseUrl: string } | null {\n const idx = connection.indexOf('@');\n if (idx <= 0) return null;\n const token = connection.slice(0, idx);\n const host = connection.slice(idx + 1);\n const baseUrl = /^https?:\\/\\//i.test(host) ? host : `https://${host}`;\n return { token, baseUrl };\n}\n\nfunction mergeCustomFields(\n global: CustomFieldDefinition[] | undefined,\n repo: CustomFieldDefinition[] | undefined\n): CustomFieldDefinition[] {\n const map = new Map<string, CustomFieldDefinition>();\n for (const f of global ?? []) map.set(f.id, f);\n for (const f of repo ?? []) map.set(f.id, f); // repo wins\n return Array.from(map.values());\n}\n\nfunction mergeDefaults(\n global: GlobalConfig['defaults'],\n repo: RepoConfig['defaults']\n): { jira: JiraDefaults; bitbucket: BitbucketDefaults; github: GitHubDefaults; sonar: SonarDefaults; sde: SdeDefaults; ado: AdoDefaults; udeploy: UdeployDefaults } {\n return {\n jira: { ...global?.jira, ...repo?.jira },\n bitbucket: { ...global?.bitbucket, ...repo?.bitbucket },\n github: { ...global?.github, ...repo?.github },\n sonar: { ...global?.sonar, ...repo?.sonar },\n sde: { ...global?.sde, ...repo?.sde },\n ado: { ...global?.ado, ...repo?.ado },\n udeploy: { ...global?.udeploy, ...repo?.udeploy }\n };\n}\n\nexport interface LoadConfigOptions {\n configPath?: string;\n}\n\nexport function loadConfig(opts: LoadConfigOptions = {}): ResolvedConfig {\n const globalConfigPath = getGlobalConfigPath(opts.configPath);\n const globalConfig = loadJsonFile<GlobalConfig>(globalConfigPath) ?? {};\n\n const repoRoot = getRepoRoot();\n let repoConfig: RepoConfig = {};\n if (repoRoot) {\n repoConfig = loadJsonFile<RepoConfig>(path.join(repoRoot, '.pncli.json')) ?? {};\n }\n\n const mergedDefaults = mergeDefaults(globalConfig.defaults, repoConfig.defaults);\n\n return {\n user: {\n email: process.env[ENV_KEYS.EMAIL] ?? globalConfig.user?.email,\n userId: process.env[ENV_KEYS.USERID] ?? globalConfig.user?.userId\n },\n jira: {\n baseUrl: process.env[ENV_KEYS.JIRA_BASE_URL] ?? globalConfig.jira?.baseUrl,\n apiToken: process.env[ENV_KEYS.JIRA_API_TOKEN] ?? globalConfig.jira?.apiToken,\n customFields: mergeCustomFields(globalConfig.jira?.customFields, repoConfig.jira?.customFields)\n },\n bitbucket: {\n baseUrl: process.env[ENV_KEYS.BITBUCKET_BASE_URL] ?? globalConfig.bitbucket?.baseUrl,\n pat: process.env[ENV_KEYS.BITBUCKET_PAT] ?? globalConfig.bitbucket?.pat\n },\n github: {\n baseUrl: process.env[ENV_KEYS.GITHUB_BASE_URL] ?? globalConfig.github?.baseUrl,\n token: process.env[ENV_KEYS.GITHUB_TOKEN] ?? globalConfig.github?.token\n },\n confluence: {\n baseUrl: process.env[ENV_KEYS.CONFLUENCE_BASE_URL] ?? globalConfig.confluence?.baseUrl,\n apiToken: process.env[ENV_KEYS.CONFLUENCE_API_TOKEN] ?? globalConfig.confluence?.apiToken\n ?? process.env[ENV_KEYS.JIRA_API_TOKEN] ?? globalConfig.jira?.apiToken,\n apiTokenExplicit: !!(\n process.env[ENV_KEYS.CONFLUENCE_API_TOKEN] ?? globalConfig.confluence?.apiToken\n )\n },\n artifactory: {\n baseUrl: process.env[ENV_KEYS.ARTIFACTORY_BASE_URL] ?? globalConfig.artifactory?.baseUrl,\n token: process.env[ENV_KEYS.ARTIFACTORY_TOKEN] ?? globalConfig.artifactory?.token,\n npmRepo: process.env[ENV_KEYS.ARTIFACTORY_REPO_NPM] ?? globalConfig.artifactory?.npmRepo,\n nugetRepo: process.env[ENV_KEYS.ARTIFACTORY_REPO_NUGET] ?? globalConfig.artifactory?.nugetRepo,\n mavenRepo: process.env[ENV_KEYS.ARTIFACTORY_REPO_MAVEN] ?? globalConfig.artifactory?.mavenRepo\n },\n sonar: {\n baseUrl: process.env[ENV_KEYS.SONAR_BASE_URL] ?? globalConfig.sonar?.baseUrl,\n token: process.env[ENV_KEYS.SONAR_TOKEN] ?? globalConfig.sonar?.token\n },\n sde: (() => {\n const raw = process.env[ENV_KEYS.SDE_CONNECTION] ?? globalConfig.sde?.connection;\n const parsed = raw ? parseSdeConnection(raw) : null;\n return { baseUrl: parsed?.baseUrl, token: parsed?.token };\n })(),\n ado: {\n baseUrl: process.env[ENV_KEYS.ADO_BASE_URL] ?? globalConfig.ado?.baseUrl,\n pat: process.env[ENV_KEYS.ADO_PAT] ?? globalConfig.ado?.pat,\n fieldAliases: globalConfig.ado?.fieldAliases ?? {},\n discoveredFields: globalConfig.ado?.discoveredFields ?? [],\n discoveredTypes: globalConfig.ado?.discoveredTypes ?? []\n },\n jenkins: {\n baseUrl: process.env[ENV_KEYS.JENKINS_BASE_URL] ?? globalConfig.jenkins?.baseUrl,\n username: process.env[ENV_KEYS.JENKINS_USERNAME] ?? globalConfig.jenkins?.username,\n apiToken: process.env[ENV_KEYS.JENKINS_API_TOKEN] ?? globalConfig.jenkins?.apiToken\n },\n udeploy: {\n baseUrl: process.env[ENV_KEYS.UDEPLOY_BASE_URL] ?? globalConfig.udeploy?.baseUrl,\n pat: process.env[ENV_KEYS.UDEPLOY_PAT] ?? globalConfig.udeploy?.pat,\n username: process.env[ENV_KEYS.UDEPLOY_USERNAME] ?? globalConfig.udeploy?.username,\n password: process.env[ENV_KEYS.UDEPLOY_PASSWORD] ?? globalConfig.udeploy?.password,\n },\n checkmarx: {\n baseUrl: process.env[ENV_KEYS.CHECKMARX_BASE_URL] ?? globalConfig.checkmarx?.baseUrl,\n username: process.env[ENV_KEYS.CHECKMARX_USERNAME] ?? globalConfig.checkmarx?.username,\n password: process.env[ENV_KEYS.CHECKMARX_PASSWORD] ?? globalConfig.checkmarx?.password,\n },\n servicenow: {\n baseUrl: process.env[ENV_KEYS.SERVICENOW_BASE_URL] ?? globalConfig.servicenow?.baseUrl,\n username: process.env[ENV_KEYS.SERVICENOW_USERNAME] ?? globalConfig.servicenow?.username,\n password: process.env[ENV_KEYS.SERVICENOW_PASSWORD] ?? globalConfig.servicenow?.password,\n apiToken: process.env[ENV_KEYS.SERVICENOW_API_TOKEN] ?? globalConfig.servicenow?.apiToken,\n },\n contrast: {\n baseUrl: process.env[ENV_KEYS.CONTRAST_BASE_URL] ?? globalConfig.contrast?.baseUrl,\n orgUuid: process.env[ENV_KEYS.CONTRAST_ORG_UUID] ?? globalConfig.contrast?.orgUuid,\n apiKey: process.env[ENV_KEYS.CONTRAST_API_KEY] ?? globalConfig.contrast?.apiKey,\n serviceKey: process.env[ENV_KEYS.CONTRAST_SERVICE_KEY] ?? globalConfig.contrast?.serviceKey,\n username: process.env[ENV_KEYS.CONTRAST_USERNAME] ?? globalConfig.contrast?.username,\n },\n sonatypeiq: {\n baseUrl: process.env[ENV_KEYS.SONATYPEIQ_BASE_URL] ?? globalConfig.sonatypeiq?.baseUrl,\n userCode: process.env[ENV_KEYS.SONATYPEIQ_USER_CODE] ?? globalConfig.sonatypeiq?.userCode,\n passcode: process.env[ENV_KEYS.SONATYPEIQ_PASSCODE] ?? globalConfig.sonatypeiq?.passcode,\n },\n openshift: {\n baseUrl: process.env[ENV_KEYS.OPENSHIFT_BASE_URL] ?? globalConfig.openshift?.baseUrl,\n token: process.env[ENV_KEYS.OPENSHIFT_TOKEN] ?? globalConfig.openshift?.token,\n },\n defaults: mergedDefaults\n };\n}\n\nexport function writeGlobalConfig(config: GlobalConfig, configPath?: string): void {\n const filePath = getGlobalConfigPath(configPath);\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, JSON.stringify(config, null, 2) + '\\n', 'utf8');\n}\n\nexport function writeRepoConfig(config: RepoConfig): void {\n const repoRoot = getRepoRoot();\n const targetDir = repoRoot ?? process.cwd();\n fs.writeFileSync(path.join(targetDir, '.pncli.json'), JSON.stringify(config, null, 2) + '\\n', 'utf8');\n}\n\nexport function setConfigValue(key: string, value: string, configPath?: string): void {\n const filePath = getGlobalConfigPath(configPath);\n const existing = loadJsonFile<GlobalConfig>(filePath) ?? {};\n\n const parts = key.split('.');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let current: any = existing;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]!;\n if (typeof current[part] !== 'object' || current[part] === null) {\n current[part] = {};\n }\n current = current[part];\n }\n current[parts[parts.length - 1]!] = value;\n\n writeGlobalConfig(existing, configPath);\n}\n\nexport function setRepoConfigValue(key: string, value: string): void {\n const repoRoot = getRepoRoot();\n const targetDir = repoRoot ?? process.cwd();\n const filePath = path.join(targetDir, '.pncli.json');\n const existing = loadJsonFile<RepoConfig>(filePath) ?? {};\n\n const parts = key.split('.');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let current: any = existing;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]!;\n if (typeof current[part] !== 'object' || current[part] === null) {\n current[part] = {};\n }\n current = current[part];\n }\n current[parts[parts.length - 1]!] = value;\n\n writeRepoConfig(existing);\n}\n\nexport function maskConfig(config: ResolvedConfig): unknown {\n return {\n ...config,\n jira: {\n ...config.jira,\n apiToken: config.jira.apiToken ? '***' : undefined,\n customFields: config.jira.customFields\n },\n bitbucket: {\n ...config.bitbucket,\n pat: config.bitbucket.pat ? '***' : undefined\n },\n github: {\n ...config.github,\n token: config.github.token ? '***' : undefined\n },\n confluence: {\n ...config.confluence,\n apiToken: config.confluence.apiToken ? '***' : undefined\n },\n artifactory: {\n ...config.artifactory,\n token: config.artifactory.token ? '***' : undefined\n },\n sonar: {\n ...config.sonar,\n token: config.sonar.token ? '***' : undefined\n },\n sde: {\n baseUrl: config.sde.baseUrl,\n token: config.sde.token ? '***' : undefined\n },\n ado: {\n ...config.ado,\n pat: config.ado.pat ? '***' : undefined\n },\n jenkins: {\n ...config.jenkins,\n apiToken: config.jenkins.apiToken ? '***' : undefined\n },\n udeploy: {\n ...config.udeploy,\n pat: config.udeploy.pat ? '***' : undefined,\n password: config.udeploy.password ? '***' : undefined\n },\n checkmarx: {\n ...config.checkmarx,\n password: config.checkmarx.password ? '***' : undefined\n },\n servicenow: {\n ...config.servicenow,\n password: config.servicenow.password ? '***' : undefined,\n apiToken: config.servicenow.apiToken ? '***' : undefined\n },\n contrast: {\n ...config.contrast,\n apiKey: config.contrast.apiKey ? '***' : undefined,\n serviceKey: config.contrast.serviceKey ? '***' : undefined\n },\n sonatypeiq: {\n ...config.sonatypeiq,\n passcode: config.sonatypeiq.passcode ? '***' : undefined\n },\n openshift: {\n ...config.openshift,\n token: config.openshift.token ? '***' : undefined\n }\n };\n}\n\nexport { getGlobalConfigPath, loadJsonFile };\n"],"mappings":"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","names":[]}
|
|
@@ -36,13 +36,16 @@ function exitCodeFromStatus(httpStatus) {
|
|
|
36
36
|
// src/lib/output.ts
|
|
37
37
|
import fs from "fs";
|
|
38
38
|
import chalk from "chalk";
|
|
39
|
-
var globalOptions = { pretty: false, verbose: false };
|
|
39
|
+
var globalOptions = { pretty: false, verbose: false, debug: false };
|
|
40
40
|
var globalUser = { email: void 0, userId: void 0 };
|
|
41
41
|
var outputFile;
|
|
42
42
|
function setGlobalOptions(opts) {
|
|
43
|
-
globalOptions = { pretty: opts.pretty, verbose: opts.verbose };
|
|
43
|
+
globalOptions = { pretty: opts.pretty, verbose: opts.verbose, debug: opts.debug ?? false };
|
|
44
44
|
outputFile = opts.outputFile;
|
|
45
45
|
}
|
|
46
|
+
function isDebugEnabled() {
|
|
47
|
+
return globalOptions.debug;
|
|
48
|
+
}
|
|
46
49
|
function setGlobalUser(user) {
|
|
47
50
|
globalUser = user;
|
|
48
51
|
}
|
|
@@ -120,6 +123,13 @@ function log(message) {
|
|
|
120
123
|
);
|
|
121
124
|
}
|
|
122
125
|
}
|
|
126
|
+
function debug(message) {
|
|
127
|
+
if (globalOptions.debug) {
|
|
128
|
+
process.stderr.write(
|
|
129
|
+
(globalOptions.pretty ? chalk.cyan("\u2B21 ") : "") + message + "\n"
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
123
133
|
function warn(message) {
|
|
124
134
|
process.stderr.write(
|
|
125
135
|
(globalOptions.pretty ? chalk.yellow("\u26A0 ") : "") + message + "\n"
|
|
@@ -212,6 +222,21 @@ function buildCheckmarxFetcher(config) {
|
|
|
212
222
|
}
|
|
213
223
|
|
|
214
224
|
// src/lib/http.ts
|
|
225
|
+
var SENSITIVE_HEADERS = /* @__PURE__ */ new Set(["authorization", "api-key"]);
|
|
226
|
+
function redactHeaders(headers) {
|
|
227
|
+
if (!headers) return {};
|
|
228
|
+
let entries;
|
|
229
|
+
if (headers instanceof Headers) {
|
|
230
|
+
entries = [...headers.entries()];
|
|
231
|
+
} else if (Array.isArray(headers)) {
|
|
232
|
+
entries = headers;
|
|
233
|
+
} else {
|
|
234
|
+
entries = Object.entries(headers);
|
|
235
|
+
}
|
|
236
|
+
return Object.fromEntries(
|
|
237
|
+
entries.map(([k, v]) => [k, SENSITIVE_HEADERS.has(k.toLowerCase()) ? "[REDACTED]" : v])
|
|
238
|
+
);
|
|
239
|
+
}
|
|
215
240
|
function buildUrl(base, path, params) {
|
|
216
241
|
const url = new URL(path, base.endsWith("/") ? base : base + "/");
|
|
217
242
|
if (params) {
|
|
@@ -234,17 +259,26 @@ async function fetchWithTimeout(url, init, timeoutMs, fetcher = fetch) {
|
|
|
234
259
|
}
|
|
235
260
|
async function request(url, init, timeoutMs, fetcher = fetch) {
|
|
236
261
|
let lastError;
|
|
262
|
+
if (isDebugEnabled()) {
|
|
263
|
+
const method = (init.method ?? "GET").toUpperCase();
|
|
264
|
+
const safeHeaders = redactHeaders(init.headers);
|
|
265
|
+
debug(`\u2192 ${method} ${url}`);
|
|
266
|
+
debug(` Headers: ${JSON.stringify(safeHeaders)}`);
|
|
267
|
+
}
|
|
237
268
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
238
269
|
let response;
|
|
270
|
+
const reqStart = Date.now();
|
|
239
271
|
try {
|
|
240
272
|
response = await fetchWithTimeout(url, init, timeoutMs, fetcher);
|
|
241
273
|
} catch (err) {
|
|
274
|
+
debug(` Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
242
275
|
throw new PncliError(
|
|
243
276
|
`Request failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
244
277
|
0,
|
|
245
278
|
url
|
|
246
279
|
);
|
|
247
280
|
}
|
|
281
|
+
debug(`\u2190 ${response.status} ${response.statusText} (${Date.now() - reqStart}ms)`);
|
|
248
282
|
if (response.status === 429) {
|
|
249
283
|
const retryAfter = response.headers.get("Retry-After");
|
|
250
284
|
const waitMs = retryAfter ? parseInt(retryAfter, 10) * 1e3 : (attempt + 1) * 1e3;
|
|
@@ -322,6 +356,17 @@ var HttpClient = class {
|
|
|
322
356
|
"Connection": "close"
|
|
323
357
|
};
|
|
324
358
|
}
|
|
359
|
+
githubHeaders() {
|
|
360
|
+
const { token } = this.config.github;
|
|
361
|
+
if (!token) throw new PncliError("GitHub credentials not configured. Run: pncli config init");
|
|
362
|
+
return {
|
|
363
|
+
"Authorization": `Bearer ${token}`,
|
|
364
|
+
"Content-Type": "application/json",
|
|
365
|
+
"Accept": "application/vnd.github+json",
|
|
366
|
+
"X-GitHub-Api-Version": "2022-11-28",
|
|
367
|
+
"Connection": "close"
|
|
368
|
+
};
|
|
369
|
+
}
|
|
325
370
|
async jira(path, opts = {}) {
|
|
326
371
|
const baseUrl = this.config.jira.baseUrl;
|
|
327
372
|
if (!baseUrl) throw new PncliError("Jira baseUrl not configured. Run: pncli config init");
|
|
@@ -423,6 +468,71 @@ Body: <multipart/form-data>
|
|
|
423
468
|
}
|
|
424
469
|
return request(url, { method: "POST", headers, body: formData }, opts.timeoutMs ?? 6e4);
|
|
425
470
|
}
|
|
471
|
+
async github(path, opts = {}) {
|
|
472
|
+
const baseUrl = this.config.github.baseUrl;
|
|
473
|
+
if (!baseUrl) throw new PncliError("GitHub baseUrl not configured. Run: pncli config init");
|
|
474
|
+
const url = buildUrl(baseUrl, path, opts.params);
|
|
475
|
+
const headers = this.githubHeaders();
|
|
476
|
+
const init = {
|
|
477
|
+
method: opts.method ?? "GET",
|
|
478
|
+
headers,
|
|
479
|
+
body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0
|
|
480
|
+
};
|
|
481
|
+
if (this.dryRun) {
|
|
482
|
+
const safeHeaders = { ...headers, Authorization: "[REDACTED]" };
|
|
483
|
+
const msg = `DRY RUN: ${init.method} ${url}
|
|
484
|
+
Headers: ${JSON.stringify(safeHeaders, null, 2)}
|
|
485
|
+
` + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}
|
|
486
|
+
` : "");
|
|
487
|
+
fs2.writeSync(process.stderr.fd, msg);
|
|
488
|
+
process.exitCode = ExitCode.SUCCESS;
|
|
489
|
+
throw new PncliError("dry-run", 0);
|
|
490
|
+
}
|
|
491
|
+
return request(url, init, opts.timeoutMs ?? 3e4);
|
|
492
|
+
}
|
|
493
|
+
async githubText(path, opts = {}) {
|
|
494
|
+
const baseUrl = this.config.github.baseUrl;
|
|
495
|
+
if (!baseUrl) throw new PncliError("GitHub baseUrl not configured. Run: pncli config init");
|
|
496
|
+
const url = buildUrl(baseUrl, path, opts.params);
|
|
497
|
+
const headers = {
|
|
498
|
+
...this.githubHeaders(),
|
|
499
|
+
"Accept": "application/vnd.github.v3.diff"
|
|
500
|
+
};
|
|
501
|
+
if (this.dryRun) {
|
|
502
|
+
const safeHeaders = { ...headers, Authorization: "[REDACTED]" };
|
|
503
|
+
fs2.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? "GET"} ${url}
|
|
504
|
+
Headers: ${JSON.stringify(safeHeaders, null, 2)}
|
|
505
|
+
`);
|
|
506
|
+
process.exitCode = ExitCode.SUCCESS;
|
|
507
|
+
throw new PncliError("dry-run", 0);
|
|
508
|
+
}
|
|
509
|
+
const response = await fetchWithTimeout(url, {
|
|
510
|
+
method: opts.method ?? "GET",
|
|
511
|
+
headers
|
|
512
|
+
}, opts.timeoutMs ?? 3e4);
|
|
513
|
+
if (!response.ok) {
|
|
514
|
+
let message = `HTTP ${response.status} ${response.statusText}`;
|
|
515
|
+
try {
|
|
516
|
+
const parsed = JSON.parse(await response.text());
|
|
517
|
+
if (parsed.message) message = String(parsed.message);
|
|
518
|
+
} catch {
|
|
519
|
+
}
|
|
520
|
+
throw new PncliError(message, response.status, url);
|
|
521
|
+
}
|
|
522
|
+
return response.text();
|
|
523
|
+
}
|
|
524
|
+
async githubPaginate(fetchPage) {
|
|
525
|
+
const results = [];
|
|
526
|
+
let page = 1;
|
|
527
|
+
const perPage = 100;
|
|
528
|
+
while (true) {
|
|
529
|
+
const items = await fetchPage(page, perPage);
|
|
530
|
+
results.push(...items);
|
|
531
|
+
if (items.length < perPage) break;
|
|
532
|
+
page++;
|
|
533
|
+
}
|
|
534
|
+
return results;
|
|
535
|
+
}
|
|
426
536
|
async bitbucket(path, opts = {}) {
|
|
427
537
|
const baseUrl = this.config.bitbucket.baseUrl;
|
|
428
538
|
if (!baseUrl) throw new PncliError("Bitbucket baseUrl not configured. Run: pncli config init");
|
|
@@ -1030,7 +1140,7 @@ Headers: ${JSON.stringify(safeHeaders, null, 2)}
|
|
|
1030
1140
|
const url = buildUrl(baseUrl, path, params);
|
|
1031
1141
|
const headers = {
|
|
1032
1142
|
"Authorization": this.openshiftHeaders()["Authorization"],
|
|
1033
|
-
"Accept": "
|
|
1143
|
+
"Accept": "*/*",
|
|
1034
1144
|
"Connection": "close"
|
|
1035
1145
|
};
|
|
1036
1146
|
if (this.dryRun) {
|
|
@@ -1091,4 +1201,4 @@ export {
|
|
|
1091
1201
|
HttpClient,
|
|
1092
1202
|
createHttpClient
|
|
1093
1203
|
};
|
|
1094
|
-
//# sourceMappingURL=chunk-
|
|
1204
|
+
//# sourceMappingURL=chunk-XPPEXJBP.js.map
|