@kolatts/pncli 4.1.1 → 5.0.1

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 CHANGED
@@ -120,7 +120,6 @@ This project uses Conventional Commits for automatic versioning:
120
120
  | Dependencies | 🟡 Basic | CVE detection, license audit |
121
121
  | Checkmarx | ⚪ Untested | Vulnerability scanning (SAST) |
122
122
  | Contrast IAST | ⚪ Untested | Runtime application security |
123
- | ServiceNow | ⚪ Untested | IT service management |
124
123
  | Sonatype IQ | ⚪ Untested | Dependency policy enforcement |
125
124
  | OpenShift | ⚪ Untested | Pods, events, logs, metrics |
126
125
  | LogScale | ⚪ Untested | Log queries, repositories |
@@ -129,7 +128,7 @@ This project uses Conventional Commits for automatic versioning:
129
128
 
130
129
  Status reflects validation against a **real instance**, not code maturity: **Live** — used routinely day-to-day · **Beta** — exercised across several commands and instances · **Basic** — smoke-tested against one instance · **Untested** — shipped, not yet run against a live server. The [homepage](https://kolatts.github.io/pncli/) shows the same grid.
131
130
 
132
- Removed integrations: IBM UrbanCode Deploy (v2.0.0) — see the [changelog](https://kolatts.github.io/pncli/changelog/) for why.
131
+ Removed integrations: ServiceNow (v5.0.0), IBM UrbanCode Deploy (v2.0.0) — see the [changelog](https://kolatts.github.io/pncli/changelog/) for why.
133
132
  <!-- services-table:end -->
134
133
 
135
134
  Auth specifics and supported server versions for each service live in its [`skills/pncli/<service>.md`](./skills/pncli/) file.
@@ -138,7 +137,7 @@ Auth specifics and supported server versions for each service live in its [`skil
138
137
 
139
138
  Requests for new integrations are welcome for **any enterprise tool**, not just the SDLC categories above — design, documentation, observability, ITSM, and collaboration tools all count.
140
139
 
141
- The one hard requirement is authentication: the tool must support a **personal access token** — a long-lived static credential you generate in its own UI and paste into an env var or config file. Vendor naming doesn't matter (API token, user token, PAT). Tools whose only auth is interactive OAuth, SSO/SAML, username+password, a registered OAuth app, a cloud IAM credential chain, or mTLS can't be supported. Checkmarx (username + password via an OAuth2 password grant that pncli handles natively) predates this rule and is grandfathered. IBM UrbanCode Deploy was removed in v2.0.0 for exactly this reason — UCD tokens are not usable as a standalone credential the way pncli requires, so its only workable auth was username + password.
140
+ The one hard requirement is authentication: the tool must support a **personal access token** — a long-lived static credential you generate in its own UI and paste into an env var or config file. Vendor naming doesn't matter (API token, user token, PAT). Tools whose only auth is interactive OAuth, SSO/SAML, username+password, a registered OAuth app, a cloud IAM credential chain, or mTLS can't be supported. Checkmarx (username + password via an OAuth2 password grant that pncli handles natively) predates this rule and is grandfathered. Two integrations have been removed for exactly this reason. ServiceNow went in v5.0.0: its personal access tokens are an opt-in instance feature many enterprises never enable, so in practice the integration authenticated with a username + password. IBM UrbanCode Deploy went in v2.0.0: UCD tokens are not usable as a standalone credential the way pncli requires, so its only workable auth was username + password.
142
141
 
143
142
  ## License
144
143
 
@@ -41,10 +41,6 @@ var ENV_KEYS = {
41
41
  CHECKMARX_API_KEY: "PNCLI_CHECKMARX_API_KEY",
42
42
  CHECKMARX_CLIENT_ID: "PNCLI_CHECKMARX_CLIENT_ID",
43
43
  CHECKMARX_CLIENT_SECRET: "PNCLI_CHECKMARX_CLIENT_SECRET",
44
- SERVICENOW_BASE_URL: "PNCLI_SERVICENOW_BASE_URL",
45
- SERVICENOW_USERNAME: "PNCLI_SERVICENOW_USERNAME",
46
- SERVICENOW_PASSWORD: "PNCLI_SERVICENOW_PASSWORD",
47
- SERVICENOW_API_TOKEN: "PNCLI_SERVICENOW_API_TOKEN",
48
44
  CONTRAST_BASE_URL: "PNCLI_CONTRAST_BASE_URL",
49
45
  CONTRAST_ORG_UUID: "PNCLI_CONTRAST_ORG_UUID",
50
46
  CONTRAST_API_KEY: "PNCLI_CONTRAST_API_KEY",
@@ -181,12 +177,6 @@ function loadConfig(opts = {}) {
181
177
  clientId: process.env[ENV_KEYS.CHECKMARX_CLIENT_ID] ?? globalConfig.checkmarx?.clientId,
182
178
  clientSecret: process.env[ENV_KEYS.CHECKMARX_CLIENT_SECRET] ?? globalConfig.checkmarx?.clientSecret
183
179
  },
184
- servicenow: {
185
- baseUrl: process.env[ENV_KEYS.SERVICENOW_BASE_URL] ?? globalConfig.servicenow?.baseUrl,
186
- username: process.env[ENV_KEYS.SERVICENOW_USERNAME] ?? globalConfig.servicenow?.username,
187
- password: process.env[ENV_KEYS.SERVICENOW_PASSWORD] ?? globalConfig.servicenow?.password,
188
- apiToken: process.env[ENV_KEYS.SERVICENOW_API_TOKEN] ?? globalConfig.servicenow?.apiToken
189
- },
190
180
  contrast: {
191
181
  baseUrl: process.env[ENV_KEYS.CONTRAST_BASE_URL] ?? globalConfig.contrast?.baseUrl,
192
182
  orgUuid: process.env[ENV_KEYS.CONTRAST_ORG_UUID] ?? globalConfig.contrast?.orgUuid,
@@ -338,11 +328,6 @@ function maskConfig(config) {
338
328
  apiKey: config.checkmarx.apiKey ? "***" : void 0,
339
329
  clientSecret: config.checkmarx.clientSecret ? "***" : void 0
340
330
  },
341
- servicenow: {
342
- ...config.servicenow,
343
- password: config.servicenow.password ? "***" : void 0,
344
- apiToken: config.servicenow.apiToken ? "***" : void 0
345
- },
346
331
  contrast: {
347
332
  ...config.contrast,
348
333
  apiKey: config.contrast.apiKey ? "***" : void 0,
@@ -410,4 +395,4 @@ export {
410
395
  setRepoConfigValue,
411
396
  maskConfig
412
397
  };
413
- //# sourceMappingURL=chunk-LH7WBP7W.js.map
398
+ //# sourceMappingURL=chunk-3JICA4FZ.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, JenkinsDefaults, JenkinsInstanceConfig } 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 // Well-known vars CI platforms provide without any pncli-specific setup.\n GITHUB_TOKEN_FALLBACK: 'GITHUB_TOKEN',\n GITHUB_API_URL_FALLBACK: 'GITHUB_API_URL',\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 // SonarSource's own scanner CLI standard var name — see the comment above GITHUB_TOKEN_FALLBACK.\n SONAR_TOKEN_FALLBACK: 'SONAR_TOKEN',\n SDE_CONNECTION: 'PNCLI_SDE_CONNECTION',\n ADO_BASE_URL: 'PNCLI_ADO_BASE_URL',\n ADO_PAT: 'PNCLI_ADO_PAT',\n // Azure Pipelines' conventional name for $(System.AccessToken) — see the comment above GITHUB_TOKEN_FALLBACK.\n ADO_PAT_FALLBACK: 'SYSTEM_ACCESSTOKEN',\n JENKINS_BASE_URL: 'PNCLI_JENKINS_BASE_URL',\n JENKINS_USERNAME: 'PNCLI_JENKINS_USERNAME',\n JENKINS_API_TOKEN: 'PNCLI_JENKINS_API_TOKEN',\n CHECKMARX_BASE_URL: 'PNCLI_CHECKMARX_BASE_URL',\n CHECKMARX_TENANT_NAME: 'PNCLI_CHECKMARX_TENANT_NAME',\n CHECKMARX_API_KEY: 'PNCLI_CHECKMARX_API_KEY',\n CHECKMARX_CLIENT_ID: 'PNCLI_CHECKMARX_CLIENT_ID',\n CHECKMARX_CLIENT_SECRET: 'PNCLI_CHECKMARX_CLIENT_SECRET',\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 DYNATRACE_BASE_URL: 'PNCLI_DYNATRACE_BASE_URL',\n DYNATRACE_API_TOKEN: 'PNCLI_DYNATRACE_API_TOKEN',\n DYNATRACE_PLATFORM_URL: 'PNCLI_DYNATRACE_PLATFORM_URL',\n DYNATRACE_PLATFORM_TOKEN: 'PNCLI_DYNATRACE_PLATFORM_TOKEN',\n LOGSCALE_BASE_URL: 'PNCLI_LOGSCALE_BASE_URL',\n LOGSCALE_TOKEN: 'PNCLI_LOGSCALE_TOKEN',\n SPLITIO_BASE_URL: 'PNCLI_SPLITIO_BASE_URL',\n SPLITIO_ADMIN_API_KEY: 'PNCLI_SPLITIO_ADMIN_API_KEY',\n FIGMA_BASE_URL: 'PNCLI_FIGMA_BASE_URL',\n FIGMA_TOKEN: 'PNCLI_FIGMA_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; jenkins: JenkinsDefaults } {\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 jenkins: { ...global?.jenkins, ...repo?.jenkins }\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] ?? process.env[ENV_KEYS.GITHUB_API_URL_FALLBACK] ?? globalConfig.github?.baseUrl,\n token: process.env[ENV_KEYS.GITHUB_TOKEN] ?? process.env[ENV_KEYS.GITHUB_TOKEN_FALLBACK] ?? 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] ?? process.env[ENV_KEYS.SONAR_TOKEN_FALLBACK] ?? 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] ?? process.env[ENV_KEYS.ADO_PAT_FALLBACK] ?? globalConfig.ado?.pat,\n fieldAliases: globalConfig.ado?.fieldAliases ?? {},\n discoveredFields: globalConfig.ado?.discoveredFields ?? [],\n discoveredTypes: globalConfig.ado?.discoveredTypes ?? []\n },\n jenkins: {\n baseUrl: repoConfig.defaults?.jenkins?.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 jenkinsInstances: (Array.isArray(globalConfig.jenkinsInstances) ? globalConfig.jenkinsInstances : []) as JenkinsInstanceConfig[],\n checkmarx: {\n baseUrl: process.env[ENV_KEYS.CHECKMARX_BASE_URL] ?? globalConfig.checkmarx?.baseUrl,\n tenantName: process.env[ENV_KEYS.CHECKMARX_TENANT_NAME] ?? globalConfig.checkmarx?.tenantName,\n apiKey: process.env[ENV_KEYS.CHECKMARX_API_KEY] ?? globalConfig.checkmarx?.apiKey,\n clientId: process.env[ENV_KEYS.CHECKMARX_CLIENT_ID] ?? globalConfig.checkmarx?.clientId,\n clientSecret: process.env[ENV_KEYS.CHECKMARX_CLIENT_SECRET] ?? globalConfig.checkmarx?.clientSecret,\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 defaultEnvironment: globalConfig.openshift?.defaultEnvironment,\n defaultInstance: globalConfig.openshift?.defaultInstance,\n environments: (typeof globalConfig.openshift?.environments === 'object' && globalConfig.openshift.environments !== null)\n ? globalConfig.openshift.environments\n : {},\n },\n dynatrace: {\n baseUrl: process.env[ENV_KEYS.DYNATRACE_BASE_URL] ?? globalConfig.dynatrace?.baseUrl,\n apiToken: process.env[ENV_KEYS.DYNATRACE_API_TOKEN] ?? globalConfig.dynatrace?.apiToken,\n platformUrl: process.env[ENV_KEYS.DYNATRACE_PLATFORM_URL] ?? globalConfig.dynatrace?.platformUrl,\n platformToken: process.env[ENV_KEYS.DYNATRACE_PLATFORM_TOKEN] ?? globalConfig.dynatrace?.platformToken,\n defaultEnvironment: globalConfig.dynatrace?.defaultEnvironment,\n environments: (typeof globalConfig.dynatrace?.environments === 'object' && globalConfig.dynatrace.environments !== null)\n ? globalConfig.dynatrace.environments\n : {},\n },\n logscale: {\n baseUrl: process.env[ENV_KEYS.LOGSCALE_BASE_URL] ?? globalConfig.logscale?.baseUrl,\n token: process.env[ENV_KEYS.LOGSCALE_TOKEN] ?? globalConfig.logscale?.token,\n },\n splitio: {\n baseUrl: process.env[ENV_KEYS.SPLITIO_BASE_URL] ?? globalConfig.splitio?.baseUrl,\n adminApiKey: process.env[ENV_KEYS.SPLITIO_ADMIN_API_KEY] ?? globalConfig.splitio?.adminApiKey,\n },\n figma: {\n baseUrl: process.env[ENV_KEYS.FIGMA_BASE_URL] ?? globalConfig.figma?.baseUrl,\n token: process.env[ENV_KEYS.FIGMA_TOKEN] ?? globalConfig.figma?.token,\n },\n defaults: mergedDefaults\n };\n}\n\nexport function normalizeBaseUrl(raw: string): string {\n const trimmed = raw.trim();\n if (!trimmed) return trimmed;\n return /^https?:\\/\\//i.test(trimmed) ? trimmed : `https://${trimmed}`;\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\nfunction parseConfigValue(value: string): unknown {\n try {\n const parsed = JSON.parse(value);\n if (typeof parsed === 'object' && parsed !== null) {\n return parsed;\n }\n } catch {\n // not valid JSON — fall through to raw string\n }\n return value;\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]!] = parseConfigValue(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]!] = parseConfigValue(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 jenkinsInstances: config.jenkinsInstances.map(inst => ({\n ...inst,\n apiToken: inst.apiToken ? '***' : undefined\n })),\n checkmarx: {\n ...config.checkmarx,\n apiKey: config.checkmarx.apiKey ? '***' : undefined,\n clientSecret: config.checkmarx.clientSecret ? '***' : 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 environments: Object.fromEntries(\n Object.entries(config.openshift.environments).map(([envName, envCfg]) => [\n envName,\n {\n instances: Object.fromEntries(\n Object.entries(envCfg.instances ?? {}).map(([instName, instCfg]) => [\n instName,\n { ...instCfg, token: instCfg.token ? '***' : undefined }\n ])\n )\n }\n ])\n )\n },\n dynatrace: {\n ...config.dynatrace,\n apiToken: config.dynatrace.apiToken ? '***' : undefined,\n platformToken: config.dynatrace.platformToken ? '***' : undefined,\n environments: Object.fromEntries(\n Object.entries(config.dynatrace.environments).map(([name, env]) => [\n name,\n {\n ...env,\n apiToken: env.apiToken ? '***' : undefined,\n platformToken: env.platformToken ? '***' : undefined\n }\n ])\n )\n },\n logscale: {\n ...config.logscale,\n token: config.logscale.token ? '***' : undefined\n },\n splitio: {\n ...config.splitio,\n adminApiKey: config.splitio.adminApiKey ? '***' : undefined\n },\n figma: {\n ...config.figma,\n token: config.figma.token ? '***' : undefined\n }\n };\n}\n\nexport { getGlobalConfigPath, loadJsonFile };\n"],"mappings":"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","names":[]}
@@ -8,11 +8,13 @@ import chalk from "chalk";
8
8
  var PncliError = class extends Error {
9
9
  status;
10
10
  url;
11
- constructor(message, status = 1, url) {
11
+ retryAfterSeconds;
12
+ constructor(message, status = 1, url, retryAfterSeconds) {
12
13
  super(message);
13
14
  this.name = "PncliError";
14
15
  this.status = status;
15
16
  this.url = url;
17
+ this.retryAfterSeconds = retryAfterSeconds;
16
18
  }
17
19
  };
18
20
 
@@ -86,7 +88,8 @@ function fail(err, service, action, startTime) {
86
88
  const errorDetail = {
87
89
  status: err instanceof PncliError ? err.status : 1,
88
90
  message: err instanceof Error ? err.message : String(err),
89
- url: err instanceof PncliError ? err.url ?? null : null
91
+ url: err instanceof PncliError ? err.url ?? null : null,
92
+ retryAfterSeconds: err instanceof PncliError ? err.retryAfterSeconds : void 0
90
93
  };
91
94
  const envelope = {
92
95
  ok: false,
@@ -149,4 +152,4 @@ export {
149
152
  debug,
150
153
  warn
151
154
  };
152
- //# sourceMappingURL=chunk-HZF6WQPU.js.map
155
+ //# sourceMappingURL=chunk-BHZORLOF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/output.ts","../src/lib/errors.ts","../src/lib/exitCodes.ts"],"sourcesContent":["import fs from 'fs';\nimport chalk from 'chalk';\nimport type { Meta, SuccessEnvelope, ErrorEnvelope, ErrorDetail } from '../types/common.js';\nimport { PncliError } from './errors.js';\nimport { ExitCode, exitCodeFromStatus } from './exitCodes.js';\n\nlet globalOptions = { pretty: false, verbose: false, debug: false };\nlet globalUser: { email: string | undefined; userId: string | undefined } = { email: undefined, userId: undefined };\nlet outputFile: string | undefined;\n\nexport function setGlobalOptions(opts: { pretty: boolean; verbose: boolean; debug?: boolean; outputFile?: string }): void {\n globalOptions = { pretty: opts.pretty, verbose: opts.verbose, debug: opts.debug ?? false };\n outputFile = opts.outputFile;\n}\n\nexport function isDebugEnabled(): boolean {\n return globalOptions.debug;\n}\n\nexport function setGlobalUser(user: { email: string | undefined; userId: string | undefined }): void {\n globalUser = user;\n}\n\nfunction buildMeta(service: string, action: string, startTime: number, overrides?: string[]): Meta {\n return {\n service,\n action,\n timestamp: new Date().toISOString(),\n duration_ms: Date.now() - startTime,\n user: (globalUser.email ?? globalUser.userId) ? globalUser : undefined,\n overrides: overrides && overrides.length > 0 ? overrides : undefined\n };\n}\n\nfunction writeToFile(filePath: string, content: string): void {\n try {\n fs.writeFileSync(filePath, content, 'utf8');\n } catch (writeErr) {\n process.stderr.write(\n `Warning: could not write to output file \"${filePath}\": ${(writeErr as NodeJS.ErrnoException).message}\\n`\n );\n process.exitCode = ExitCode.GENERAL_ERROR;\n }\n}\n\nexport function success<T>(data: T, service: string, action: string, startTime: number, overrides?: string[]): void {\n const envelope: SuccessEnvelope<T> = {\n ok: true,\n data,\n meta: buildMeta(service, action, startTime, overrides)\n };\n const out = (globalOptions.pretty ? JSON.stringify(envelope, null, 2) : JSON.stringify(envelope)) + '\\n';\n if (outputFile) {\n writeToFile(outputFile, out);\n } else {\n process.stdout.write(out);\n }\n}\n\nexport function fail(\n err: unknown,\n service: string,\n action: string,\n startTime: number\n): never {\n const errorDetail: ErrorDetail = {\n status: err instanceof PncliError ? err.status : 1,\n message: err instanceof Error ? err.message : String(err),\n url: err instanceof PncliError ? (err.url ?? null) : null,\n retryAfterSeconds: err instanceof PncliError ? err.retryAfterSeconds : undefined\n };\n\n const envelope: ErrorEnvelope = {\n ok: false,\n error: errorDetail,\n meta: buildMeta(service, action, startTime)\n };\n\n const msg = globalOptions.pretty\n ? chalk.red('✗ Error: ') + errorDetail.message\n : null;\n\n if (msg) process.stderr.write(msg + '\\n');\n\n const output = (globalOptions.pretty ? JSON.stringify(envelope, null, 2) : JSON.stringify(envelope)) + '\\n';\n const exitCode = err instanceof PncliError ? exitCodeFromStatus(err.status) : ExitCode.GENERAL_ERROR;\n if (outputFile) {\n writeToFile(outputFile, output);\n } else {\n try {\n fs.writeSync(process.stdout.fd, output);\n } catch (writeErr) {\n if ((writeErr as NodeJS.ErrnoException).code !== 'EPIPE') throw writeErr;\n }\n }\n process.exitCode = exitCode;\n throw new PncliError(errorDetail.message, errorDetail.status);\n}\n\nexport function writeRawOutput(content: string): void {\n if (outputFile) {\n writeToFile(outputFile, content);\n } else {\n process.stdout.write(content);\n }\n}\n\nexport function log(message: string): void {\n if (globalOptions.verbose) {\n process.stderr.write(\n (globalOptions.pretty ? chalk.gray('▸ ') : '') + message + '\\n'\n );\n }\n}\n\nexport function debug(message: string): void {\n if (globalOptions.debug) {\n process.stderr.write(\n (globalOptions.pretty ? chalk.cyan('⬡ ') : '') + message + '\\n'\n );\n }\n}\n\nexport function warn(message: string): void {\n process.stderr.write(\n (globalOptions.pretty ? chalk.yellow('⚠ ') : '') + message + '\\n'\n );\n}\n","export class PncliError extends Error {\n status: number;\n url?: string;\n retryAfterSeconds?: number;\n\n constructor(message: string, status: number = 1, url?: string, retryAfterSeconds?: number) {\n super(message);\n this.name = 'PncliError';\n this.status = status;\n this.url = url;\n this.retryAfterSeconds = retryAfterSeconds;\n }\n}\n","export const ExitCode = {\n SUCCESS: 0,\n GENERAL_ERROR: 1,\n USAGE_ERROR: 2,\n NETWORK_ERROR: 69, // EX_UNAVAILABLE from sysexits.h\n AUTH_ERROR: 77, // EX_NOPERM from sysexits.h\n CONFIG_ERROR: 78, // EX_CONFIG from sysexits.h\n} as const;\n\nexport type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];\n\nexport function exitCodeFromStatus(httpStatus: number): ExitCode {\n if (httpStatus === 401 || httpStatus === 403) return ExitCode.AUTH_ERROR;\n if (httpStatus === 0) return ExitCode.NETWORK_ERROR;\n return ExitCode.GENERAL_ERROR;\n}\n"],"mappings":"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","names":[]}
@@ -5,7 +5,7 @@ import {
5
5
  debug,
6
6
  isDebugEnabled,
7
7
  log
8
- } from "./chunk-HZF6WQPU.js";
8
+ } from "./chunk-BHZORLOF.js";
9
9
 
10
10
  // src/lib/http.ts
11
11
  import fs from "fs";
@@ -111,6 +111,17 @@ function getApiKeyClientId(apiKey) {
111
111
 
112
112
  // src/lib/http.ts
113
113
  var SENSITIVE_HEADERS = /* @__PURE__ */ new Set(["authorization", "api-key", "x-figma-token"]);
114
+ var MAX_RETRY_AFTER_SECONDS = 30;
115
+ function parseRetryAfter(value) {
116
+ if (!value) return void 0;
117
+ const trimmed = value.trim();
118
+ if (/^\d+$/.test(trimmed)) {
119
+ return Math.min(Number(trimmed), Number.MAX_VALUE);
120
+ }
121
+ if (!/^[A-Za-z]+[, ]/.test(trimmed)) return void 0;
122
+ const date = Date.parse(trimmed);
123
+ return Number.isFinite(date) ? Math.max(0, Math.ceil((date - Date.now()) / 1e3)) : void 0;
124
+ }
114
125
  function redactHeaders(headers) {
115
126
  if (!headers) return {};
116
127
  let entries;
@@ -172,11 +183,20 @@ async function requestRaw(url, init, timeoutMs, fetcher = fetch) {
172
183
  }
173
184
  debug(`\u2190 ${response.status} ${response.statusText} (${Date.now() - reqStart}ms)`);
174
185
  if (response.status === 429) {
175
- const retryAfter = response.headers.get("Retry-After");
176
- const waitMs = retryAfter ? parseInt(retryAfter, 10) * 1e3 : (attempt + 1) * 1e3;
186
+ const retryAfterSeconds = parseRetryAfter(response.headers.get("Retry-After"));
187
+ if (retryAfterSeconds !== void 0 && retryAfterSeconds > MAX_RETRY_AFTER_SECONDS) {
188
+ throw new PncliError(
189
+ `Rate limited: server requested a ${retryAfterSeconds}s retry delay, which exceeds the ${MAX_RETRY_AFTER_SECONDS}s cap`,
190
+ 429,
191
+ url,
192
+ retryAfterSeconds
193
+ );
194
+ }
195
+ lastError = new PncliError("Rate limited", 429, url, retryAfterSeconds);
196
+ if (attempt === 2) break;
197
+ const waitMs = retryAfterSeconds !== void 0 ? retryAfterSeconds * 1e3 : (attempt + 1) * 1e3;
177
198
  log(`Rate limited. Retrying after ${waitMs}ms...`);
178
199
  await new Promise((resolve) => setTimeout(resolve, waitMs));
179
- lastError = new PncliError("Rate limited", 429, url);
180
200
  continue;
181
201
  }
182
202
  if (!response.ok) {
@@ -956,45 +976,6 @@ Body: <multipart/form-data>
956
976
  }
957
977
  return this.checkmarxFetcher;
958
978
  }
959
- servicenowHeaders() {
960
- const { username, password, apiToken } = this.config.servicenow;
961
- let encoded;
962
- if (username && apiToken) {
963
- encoded = Buffer.from(`${username}:${apiToken}`).toString("base64");
964
- } else if (username && password) {
965
- encoded = Buffer.from(`${username}:${password}`).toString("base64");
966
- } else {
967
- throw new PncliError("ServiceNow credentials not configured. Run: pncli config init");
968
- }
969
- return {
970
- "Authorization": `Basic ${encoded}`,
971
- "Content-Type": "application/json",
972
- "Accept": "application/json",
973
- "Connection": "close"
974
- };
975
- }
976
- async servicenow(path, opts = {}) {
977
- const baseUrl = this.config.servicenow.baseUrl;
978
- if (!baseUrl) throw new PncliError("ServiceNow baseUrl not configured. Run: pncli config init");
979
- const url = buildUrl(baseUrl, path, opts.params);
980
- const headers = this.servicenowHeaders();
981
- const init = {
982
- method: opts.method ?? "GET",
983
- headers,
984
- body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0
985
- };
986
- if (this.dryRun) {
987
- const safeHeaders = { ...headers, Authorization: "[REDACTED]" };
988
- const msg = `DRY RUN: ${init.method} ${url}
989
- Headers: ${JSON.stringify(safeHeaders, null, 2)}
990
- ` + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}
991
- ` : "");
992
- fs.writeSync(process.stderr.fd, msg);
993
- process.exitCode = ExitCode.SUCCESS;
994
- throw new PncliError("dry-run", 0);
995
- }
996
- return request(url, init, opts.timeoutMs ?? 3e4);
997
- }
998
979
  contrastHeaders() {
999
980
  const { apiKey, serviceKey, username } = this.config.contrast;
1000
981
  if (!apiKey || !serviceKey || !username) {
@@ -1298,4 +1279,4 @@ export {
1298
1279
  HttpClient,
1299
1280
  createHttpClient
1300
1281
  };
1301
- //# sourceMappingURL=chunk-7MFRRV5V.js.map
1282
+ //# sourceMappingURL=chunk-VCECVN3F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/http.ts","../src/lib/adoFetch.ts","../src/lib/checkmarxFetch.ts"],"sourcesContent":["import fs from 'fs';\nimport type { ResolvedConfig } from '../types/config.js';\nimport { PncliError } from './errors.js';\nimport { ExitCode } from './exitCodes.js';\nimport { log, debug, isDebugEnabled } from './output.js';\nimport { buildAdoFetcher } from './adoFetch.js';\nimport { buildCheckmarxFetcher } from './checkmarxFetch.js';\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\nexport interface HttpRequestOptions {\n method?: HttpMethod;\n body?: unknown;\n params?: Record<string, string | number | boolean | undefined>;\n timeoutMs?: number;\n headers?: Record<string, string>;\n}\n\nexport interface HttpError {\n error: true;\n status: number;\n message: string;\n url: string;\n}\n\nconst SENSITIVE_HEADERS = new Set(['authorization', 'api-key', 'x-figma-token']);\n\n// A Retry-After above this would otherwise block the process for that long — long\n// enough that a large value (misconfigured server, abuse-prevention lockout) makes\n// the CLI look hung rather than rate-limited. Fail fast with a structured error instead.\nconst MAX_RETRY_AFTER_SECONDS = 30;\n\nfunction parseRetryAfter(value: string | null): number | undefined {\n if (!value) return undefined;\n const trimmed = value.trim();\n if (/^\\d+$/.test(trimmed)) {\n // Keep even overflowing delays above the cap and JSON-serializable.\n return Math.min(Number(trimmed), Number.MAX_VALUE);\n }\n // HTTP dates start with a weekday. Avoid Date.parse's permissive handling\n // of malformed numeric delays such as \"-1\" or \"1.5\".\n if (!/^[A-Za-z]+[, ]/.test(trimmed)) return undefined;\n const date = Date.parse(trimmed);\n return Number.isFinite(date) ? Math.max(0, Math.ceil((date - Date.now()) / 1000)) : undefined;\n}\n\nfunction redactHeaders(headers: RequestInit['headers']): Record<string, string> {\n if (!headers) return {};\n let entries: [string, string][];\n if (headers instanceof Headers) {\n entries = [...headers.entries()];\n } else if (Array.isArray(headers)) {\n entries = (headers as string[][]) as [string, string][];\n } else {\n entries = Object.entries(headers as Record<string, string>);\n }\n return Object.fromEntries(\n entries.map(([k, v]) => [k, SENSITIVE_HEADERS.has(k.toLowerCase()) ? '[REDACTED]' : v])\n );\n}\n\nfunction buildUrl(base: string, path: string, params?: Record<string, string | number | boolean | undefined>): string {\n const normalizedBase = base.endsWith('/') ? base : base + '/';\n // Strip a leading '/' so that new URL(path, base) resolves relative to base's full\n // path rather than the origin. Per the WHATWG URL spec, an absolute-path reference\n // (starting with '/') resolves against the origin and discards any path already\n // present in base — which silently drops path segments like '/e/<environment-id>'\n // from Dynatrace Managed or Artifactory-with-context-root base URLs.\n const normalizedPath = path.startsWith('/') ? path.slice(1) : path;\n const url = new URL(normalizedPath, normalizedBase);\n if (params) {\n for (const [key, val] of Object.entries(params)) {\n if (val !== undefined) {\n url.searchParams.set(key, String(val));\n }\n }\n }\n // URLSearchParams serializes via application/x-www-form-urlencoded, which\n // encodes commas as %2C. REST APIs like Confluence's /rest/api/content require\n // literal commas for multi-value params such as ?expand=body.storage,version.\n // Commas are valid unencoded characters in URL query strings (RFC 3986 §3.4),\n // so restoring them here is safe for all services. Scope the replacement to the\n // query string only — a percent-encoded comma in a path segment is significant\n // and must be left alone.\n if (url.search) {\n url.search = url.search.replace(/%2C/gi, ',');\n }\n return url.toString();\n}\n\nasync function fetchWithTimeout(url: string, init: RequestInit, timeoutMs: number, fetcher: typeof fetch = fetch): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n return await fetcher(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n}\n\nasync function requestRaw<T>(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n fetcher: typeof fetch = fetch\n): Promise<{ data: T; headers: Headers }> {\n let lastError: unknown;\n\n if (isDebugEnabled()) {\n const method = (init.method ?? 'GET').toUpperCase();\n const safeHeaders = redactHeaders(init.headers);\n debug(`→ ${method} ${url}`);\n debug(` Headers: ${JSON.stringify(safeHeaders)}`);\n }\n\n for (let attempt = 0; attempt < 3; attempt++) {\n let response: Response;\n const reqStart = Date.now();\n try {\n response = await fetchWithTimeout(url, init, timeoutMs, fetcher);\n } catch (err) {\n const topMsg = err instanceof Error ? err.message : String(err);\n // Node's built-in fetch wraps network errors: err.message is \"fetch failed\"\n // and the real cause (ECONNREFUSED, TLS error, DNS failure, etc.) is in\n // err.cause. Surface it so users can distinguish a proxy-routing problem\n // from bad credentials without having to reproduce the request externally.\n const causeMsg = err instanceof Error && err.cause instanceof Error ? err.cause.message : undefined;\n const fullMsg = causeMsg ? `${topMsg}: ${causeMsg}` : topMsg;\n debug(` Error: ${fullMsg}`);\n throw new PncliError(`Request failed: ${fullMsg}`, 0, url);\n }\n\n debug(`← ${response.status} ${response.statusText} (${Date.now() - reqStart}ms)`);\n\n if (response.status === 429) {\n const retryAfterSeconds = parseRetryAfter(response.headers.get('Retry-After'));\n\n if (retryAfterSeconds !== undefined && retryAfterSeconds > MAX_RETRY_AFTER_SECONDS) {\n throw new PncliError(\n `Rate limited: server requested a ${retryAfterSeconds}s retry delay, which exceeds the ${MAX_RETRY_AFTER_SECONDS}s cap`,\n 429,\n url,\n retryAfterSeconds\n );\n }\n\n lastError = new PncliError('Rate limited', 429, url, retryAfterSeconds);\n if (attempt === 2) break;\n\n const waitMs = retryAfterSeconds !== undefined ? retryAfterSeconds * 1000 : (attempt + 1) * 1000;\n log(`Rate limited. Retrying after ${waitMs}ms...`);\n await new Promise(resolve => setTimeout(resolve, waitMs));\n continue;\n }\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const body = await response.text();\n const parsed = JSON.parse(body);\n const parts: string[] = [];\n // Jira: errorMessages is string[]\n if (Array.isArray(parsed.errorMessages)) {\n parts.push(...(parsed.errorMessages as string[]).filter(Boolean));\n }\n // errors as object map (Jira: Record<string, string>)\n if (parsed.errors && typeof parsed.errors === 'object' && !Array.isArray(parsed.errors)) {\n for (const [field, msg] of Object.entries(parsed.errors as Record<string, string>)) {\n parts.push(`${field}: ${msg}`);\n }\n }\n // errors as array of objects with message or msg field (SonarQube uses msg)\n if (Array.isArray(parsed.errors)) {\n for (const e of parsed.errors as Array<{ message?: string; msg?: string }>) {\n if (e?.message) parts.push(e.message);\n else if (e?.msg) parts.push(e.msg);\n }\n }\n // Generic APIs: { message: \"...\" }\n if (parts.length === 0 && parsed.message) {\n parts.push(String(parsed.message));\n }\n if (parts.length > 0) message = parts.join('; ');\n } catch {\n // ignore parse errors\n }\n throw new PncliError(message, response.status, url);\n }\n\n if (response.status === 204) {\n return { data: undefined as T, headers: response.headers };\n }\n\n const text = await response.text();\n if (!text) return { data: undefined as T, headers: response.headers };\n return { data: JSON.parse(text) as T, headers: response.headers };\n }\n\n throw lastError ?? new PncliError('Request failed after retries', 1, url);\n}\n\nasync function request<T>(\n url: string,\n init: RequestInit,\n timeoutMs: number,\n fetcher: typeof fetch = fetch\n): Promise<T> {\n const { data } = await requestRaw<T>(url, init, timeoutMs, fetcher);\n return data;\n}\n\nexport class HttpClient {\n private config: ResolvedConfig;\n private dryRun: boolean;\n private adoFetcher: typeof fetch | null = null;\n private checkmarxFetcher: typeof fetch | null = null;\n\n constructor(config: ResolvedConfig, dryRun = false) {\n this.config = config;\n this.dryRun = dryRun;\n }\n\n private jiraToken(): string {\n const { apiToken } = this.config.jira;\n if (!apiToken) throw new PncliError('Jira credentials not configured. Run: pncli config init');\n return apiToken;\n }\n\n private jiraHeaders(): Record<string, string> {\n return {\n 'Authorization': `Bearer ${this.jiraToken()}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n private bitbucketHeaders(): Record<string, string> {\n const { pat } = this.config.bitbucket;\n if (!pat) throw new PncliError('Bitbucket credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${pat}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n private githubHeaders(): Record<string, string> {\n const { token } = this.config.github;\n if (!token) throw new PncliError('GitHub credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n 'Connection': 'close'\n };\n }\n\n async jira<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.jira.baseUrl;\n if (!baseUrl) throw new PncliError('Jira baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.jiraHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async jiraBuffer(absoluteUrl: string, opts: { timeoutMs?: number } = {}): Promise<Buffer> {\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.jiraToken()}`,\n 'Connection': 'close'\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: GET ${absoluteUrl}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`;\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(absoluteUrl, { headers }, opts.timeoutMs ?? 60000);\n if (!response.ok) {\n throw new PncliError(`HTTP ${response.status} ${response.statusText}`, response.status, absoluteUrl);\n }\n return Buffer.from(await response.arrayBuffer());\n }\n\n async adoUpload<T>(\n path: string,\n buffer: Buffer,\n contentType: string,\n opts: { timeoutMs?: number } = {}\n ): Promise<T> {\n const baseUrl = this.config.ado.baseUrl;\n if (!baseUrl) throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path);\n\n if (this.dryRun) {\n fs.writeSync(process.stderr.fd, `DRY RUN: POST ${url}\\nBody: <binary ${buffer.length} bytes>\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n return request<T>(url, {\n method: 'POST',\n headers: { 'Accept': 'application/json', 'Content-Type': contentType },\n body: buffer\n }, opts.timeoutMs ?? 60000, fetcher);\n }\n\n async adoBuffer(absoluteUrl: string, opts: { timeoutMs?: number } = {}): Promise<Buffer> {\n if (this.dryRun) {\n fs.writeSync(process.stderr.fd, `DRY RUN: GET ${absoluteUrl}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n const response = await fetchWithTimeout(\n absoluteUrl,\n { headers: { Accept: 'application/octet-stream' } },\n opts.timeoutMs ?? 60000,\n fetcher\n );\n if (!response.ok) {\n throw new PncliError(`HTTP ${response.status} ${response.statusText}`, response.status, absoluteUrl);\n }\n return Buffer.from(await response.arrayBuffer());\n }\n\n async jiraUpload<T>(\n path: string,\n formData: FormData,\n opts: { timeoutMs?: number } = {}\n ): Promise<T> {\n const baseUrl = this.config.jira.baseUrl;\n if (!baseUrl) throw new PncliError('Jira baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path);\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.jiraToken()}`,\n 'X-Atlassian-Token': 'no-check',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: POST ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\nBody: <multipart/form-data>\\n`;\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, { method: 'POST', headers, body: formData }, opts.timeoutMs ?? 60000);\n }\n\n async github<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.github.baseUrl;\n if (!baseUrl) throw new PncliError('GitHub baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.githubHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async githubText(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<string> {\n const baseUrl = this.config.github.baseUrl;\n if (!baseUrl) throw new PncliError('GitHub baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n // Reuse githubHeaders() (which enforces the token check) and override Accept so\n // GitHub returns the raw unified diff instead of JSON.\n const headers: Record<string, string> = {\n ...this.githubHeaders(),\n 'Accept': 'application/vnd.github.v3.diff'\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n fs.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? 'GET'} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(url, {\n method: opts.method ?? 'GET',\n headers\n }, opts.timeoutMs ?? 30000);\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return response.text();\n }\n\n async githubGraphQL<T>(query: string, variables?: Record<string, unknown>): Promise<T> {\n const baseUrl = this.config.github.baseUrl;\n if (!baseUrl) throw new PncliError('GitHub baseUrl not configured. Run: pncli config init');\n\n // Derive GraphQL endpoint:\n // github.com: 'https://api.github.com' → 'https://api.github.com/graphql'\n // GHES: 'https://ghe.imagile.dev/api/v3' → 'https://ghe.imagile.dev/api/graphql'\n // Trailing slashes are trimmed first — config does not normalize them away, so\n // '.../api/v3/' must still be recognized as a GHES REST root.\n const trimmed = baseUrl.replace(/\\/+$/, '');\n const stripped = trimmed.endsWith('/v3') ? trimmed.slice(0, -3) : trimmed;\n const url = stripped.endsWith('/') ? `${stripped}graphql` : `${stripped}/graphql`;\n\n const headers = this.githubHeaders();\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: POST ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\nBody: ${JSON.stringify({ query, variables }, null, 2)}\\n`;\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const result = await request<{ data?: T; errors?: Array<{ message: string }> }>(\n url,\n {\n method: 'POST',\n headers,\n body: JSON.stringify({ query, variables })\n },\n 30000\n );\n\n if (result.errors?.length) {\n throw new PncliError(result.errors.map(e => e.message).join('; '), 1, url);\n }\n\n // GitHub can return a null/absent `data` with no `errors` array (e.g. an\n // inaccessible or deleted repository). Fail cleanly instead of letting the\n // caller dereference null.\n if (result.data === null || result.data === undefined) {\n throw new PncliError('GraphQL response contained no data', 1, url);\n }\n\n return result.data;\n }\n\n async githubPaginate<T>(\n fetchPage: (page: number, perPage: number) => Promise<T[]>\n ): Promise<T[]> {\n const results: T[] = [];\n let page = 1;\n const perPage = 100;\n\n while (true) {\n const items = await fetchPage(page, perPage);\n results.push(...items);\n if (items.length < perPage) break;\n page++;\n }\n\n return results;\n }\n\n async bitbucket<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.bitbucket.baseUrl;\n if (!baseUrl) throw new PncliError('Bitbucket baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.bitbucketHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n /**\n * Same as {@link bitbucket}, but also returns the raw response headers.\n * Bitbucket Server stamps every authenticated response with X-AUSERNAME,\n * which is how getCurrentUser() resolves the caller.\n */\n async bitbucketRaw<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<{ data: T; headers: Headers }> {\n const baseUrl = this.config.bitbucket.baseUrl;\n if (!baseUrl) throw new PncliError('Bitbucket baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.bitbucketHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return requestRaw<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private confluenceToken(): string {\n const { apiToken } = this.config.confluence;\n if (!apiToken) throw new PncliError('Confluence credentials not configured. Run: pncli config init');\n return apiToken;\n }\n\n private confluenceHeaders(): Record<string, string> {\n return {\n 'Authorization': `Bearer ${this.confluenceToken()}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async confluence<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.confluence.baseUrl;\n if (!baseUrl) throw new PncliError('Confluence baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.confluenceHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private sdeHeaders(): Record<string, string> {\n const { token } = this.config.sde;\n if (!token) throw new PncliError('SDElements credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Token ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async sde<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.sde.baseUrl;\n if (!baseUrl) throw new PncliError('SDElements baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.sdeHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async sdePaginate<T>(\n fetchPage: (page: number, pageSize: number) => Promise<{ count: number; results: T[] }>\n ): Promise<T[]> {\n const results: T[] = [];\n let page = 1;\n const pageSize = 100;\n\n while (true) {\n const response = await fetchPage(page, pageSize);\n results.push(...response.results);\n if (results.length >= response.count || response.results.length === 0) break;\n page++;\n }\n\n return results;\n }\n\n private async getAdoFetcher(): Promise<typeof fetch> {\n if (!this.adoFetcher) {\n this.adoFetcher = await buildAdoFetcher(this.config);\n }\n return this.adoFetcher;\n }\n\n async ado<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.ado.baseUrl;\n if (!baseUrl) throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n const msg = `DRY RUN: ${opts.method ?? 'GET'} ${url}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n const defaultHeaders: Record<string, string> = {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json',\n ...opts.headers\n };\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers: defaultHeaders,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n return request<T>(url, init, opts.timeoutMs ?? 30000, fetcher);\n }\n\n async adoText(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<string> {\n const baseUrl = this.config.ado.baseUrl;\n if (!baseUrl) throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n fs.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? 'GET'} ${url}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n const response = await fetchWithTimeout(url, {\n method: opts.method ?? 'GET',\n headers: { 'Accept': 'text/plain', ...opts.headers }\n }, opts.timeoutMs ?? 30000, fetcher);\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return response.text();\n }\n\n async adoRaw(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<{ data: unknown; headers: Headers }> {\n const baseUrl = this.config.ado.baseUrl;\n if (!baseUrl) throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n fs.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? 'GET'} ${url}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = await this.getAdoFetcher();\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? 30000);\n let response: Response;\n try {\n response = await fetcher(url, {\n method: opts.method ?? 'GET',\n headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', ...opts.headers },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: controller.signal\n });\n } finally {\n clearTimeout(timer);\n }\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n const text = await response.text();\n const data = text ? JSON.parse(text) : undefined;\n return { data, headers: response.headers };\n }\n\n async adoPaginate<T>(\n fetchPage: (continuationToken?: string) => Promise<{ data: { value: T[] }; headers: Headers }>\n ): Promise<T[]> {\n const results: T[] = [];\n let token: string | undefined;\n\n while (true) {\n const { data, headers } = await fetchPage(token);\n results.push(...(data.value ?? []));\n const next = headers.get('x-ms-continuationtoken');\n if (!next) break;\n token = next;\n }\n\n return results;\n }\n\n private jenkinsHeaders(): Record<string, string> {\n const { username, apiToken } = this.config.jenkins;\n if (!username || !apiToken) throw new PncliError('Jenkins credentials not configured. Run: pncli config init');\n const creds = Buffer.from(`${username}:${apiToken}`).toString('base64');\n return {\n 'Authorization': `Basic ${creds}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n private artifactoryHeaders(): Record<string, string> {\n const { token } = this.config.artifactory;\n if (!token) throw new PncliError('Artifactory credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async jenkins<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.jenkins.baseUrl;\n if (!baseUrl) throw new PncliError('Jenkins baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.jenkinsHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async jenkinsRaw(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<{ status: number; headers: Headers; text: string }> {\n const baseUrl = this.config.jenkins.baseUrl;\n if (!baseUrl) throw new PncliError('Jenkins baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.jenkinsHeaders();\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${opts.method ?? 'GET'} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(url, {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n }, opts.timeoutMs ?? 30000);\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return { status: response.status, headers: response.headers, text: await response.text() };\n }\n\n async artifactory<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.artifactory.baseUrl;\n if (!baseUrl) throw new PncliError('Artifactory baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = { ...this.artifactoryHeaders(), ...opts.headers };\n\n // AQL search uses text/plain body — don't JSON-serialize it\n const body = opts.body !== undefined\n ? (typeof opts.body === 'string' ? opts.body : JSON.stringify(opts.body))\n : undefined;\n\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${typeof opts.body === 'string' ? opts.body : JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async artifactoryText(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<string> {\n const baseUrl = this.config.artifactory.baseUrl;\n if (!baseUrl) throw new PncliError('Artifactory baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = { ...this.artifactoryHeaders(), Accept: 'text/plain', ...opts.headers };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n fs.writeSync(process.stderr.fd, `DRY RUN: ${opts.method ?? 'GET'} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(url, {\n method: opts.method ?? 'GET',\n headers\n }, opts.timeoutMs ?? 30000);\n\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return response.text();\n }\n\n\n\n private sonarHeaders(): Record<string, string> {\n const { token } = this.config.sonar;\n if (!token) throw new PncliError('SonarQube credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async sonar<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.sonar.baseUrl;\n if (!baseUrl) throw new PncliError('SonarQube baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.sonarHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async sonarPaginate<T>(\n fetchPage: (page: number, pageSize: number) => Promise<{ total: number; p: number; ps: number; items: T[] }>\n ): Promise<T[]> {\n const results: T[] = [];\n let page = 1;\n const pageSize = 500;\n\n while (true) {\n const response = await fetchPage(page, pageSize);\n results.push(...response.items);\n if (results.length >= response.total || response.items.length === 0) break;\n page++;\n }\n\n return results;\n }\n\n async confluenceBuffer(path: string, opts: { timeoutMs?: number } = {}): Promise<Buffer> {\n const baseUrl = this.config.confluence.baseUrl;\n if (!baseUrl) throw new PncliError('Confluence baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path);\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.confluenceToken()}`,\n 'Connection': 'close'\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: GET ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`;\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(url, { headers }, opts.timeoutMs ?? 60000);\n if (!response.ok) {\n throw new PncliError(`HTTP ${response.status} ${response.statusText}`, response.status, url);\n }\n return Buffer.from(await response.arrayBuffer());\n }\n\n async confluenceUpload<T>(\n path: string,\n formData: FormData,\n opts: { timeoutMs?: number } = {}\n ): Promise<T> {\n const baseUrl = this.config.confluence.baseUrl;\n if (!baseUrl) throw new PncliError('Confluence baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path);\n const headers: Record<string, string> = {\n 'Authorization': `Bearer ${this.confluenceToken()}`,\n 'X-Atlassian-Token': 'no-check',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: POST ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\nBody: <multipart/form-data>\\n`;\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, { method: 'POST', headers, body: formData }, opts.timeoutMs ?? 60000);\n }\n\n async confluencePaginate<T>(\n fetchPage: (start: number, limit: number) => Promise<{ results: T[]; start: number; limit: number; size: number; _links: { next?: string } }>,\n maxTotal?: number\n ): Promise<T[]> {\n const results: T[] = [];\n let start = 0;\n const defaultPageSize = 25;\n\n while (true) {\n const pageLimit = maxTotal !== undefined\n ? Math.min(maxTotal - results.length, defaultPageSize)\n : defaultPageSize;\n const page = await fetchPage(start, pageLimit);\n results.push(...page.results);\n if (maxTotal !== undefined && results.length >= maxTotal) break;\n if (!page._links.next) break;\n start += page.size;\n }\n\n return maxTotal !== undefined ? results.slice(0, maxTotal) : results;\n }\n\n async paginate<T>(\n fetchPage: (start: number, limit: number) => Promise<{ values: T[]; isLastPage: boolean; nextPageStart?: number }>\n ): Promise<T[]> {\n const results: T[] = [];\n let start = 0;\n const limit = 100;\n\n while (true) {\n const page = await fetchPage(start, limit);\n results.push(...page.values);\n if (page.isLastPage) break;\n start = page.nextPageStart ?? start + limit;\n }\n\n return results;\n }\n\n async jiraPaginate<T>(\n fetchPage: (startAt: number, maxResults: number) => Promise<{ issues?: T[]; values?: T[]; total: number; startAt: number; maxResults: number }>\n ): Promise<T[]> {\n const results: T[] = [];\n let startAt = 0;\n const maxResults = 100;\n\n while (true) {\n const page = await fetchPage(startAt, maxResults);\n const items = (page.issues ?? page.values ?? []) as T[];\n results.push(...items);\n startAt += items.length;\n if (startAt >= page.total || items.length === 0) break;\n }\n\n return results;\n }\n\n private getCheckmarxFetcher(): typeof fetch {\n if (!this.checkmarxFetcher) {\n this.checkmarxFetcher = buildCheckmarxFetcher(this.config);\n }\n return this.checkmarxFetcher;\n }\n\n private contrastHeaders(): Record<string, string> {\n const { apiKey, serviceKey, username } = this.config.contrast;\n if (!apiKey || !serviceKey || !username) {\n throw new PncliError('Contrast credentials not configured. Run: pncli config init');\n }\n const authorization = Buffer.from(`${username}:${serviceKey}`).toString('base64');\n return {\n 'Authorization': authorization,\n 'API-Key': apiKey,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async contrast<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const { baseUrl } = this.config.contrast;\n if (!baseUrl) throw new PncliError('Contrast base URL not configured. Run: pncli config set contrast.baseUrl <url>');\n\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.contrastHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]', 'API-Key': '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private sonatypeiqHeaders(): Record<string, string> {\n const { userCode, passcode } = this.config.sonatypeiq;\n if (!userCode || !passcode) throw new PncliError('Sonatype IQ credentials not configured. Run: pncli config init');\n const encoded = Buffer.from(`${userCode}:${passcode}`).toString('base64');\n return {\n 'Authorization': `Basic ${encoded}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async sonatypeiq<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.sonatypeiq.baseUrl;\n if (!baseUrl) throw new PncliError('Sonatype IQ Server baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.sonatypeiqHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private openshiftHeaders(): Record<string, string> {\n const { token } = this.config.openshift;\n if (!token) throw new PncliError('OpenShift credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async openshift<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.openshift.baseUrl;\n if (!baseUrl) throw new PncliError('OpenShift baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.openshiftHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private dynatraceHeaders(platform = false): Record<string, string> {\n const token = platform ? this.config.dynatrace.platformToken : this.config.dynatrace.apiToken;\n if (!token) {\n throw new PncliError(\n `${platform ? 'Dynatrace platform' : 'Dynatrace'} credentials not configured. Run: pncli config init`\n );\n }\n return {\n 'Authorization': `${platform ? 'Bearer' : 'Api-Token'} ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async dynatrace<T>(path: string, opts: HttpRequestOptions = {}): Promise<T> {\n return this.dynatraceRequest<T>(false, path, opts);\n }\n\n async dynatracePlatform<T>(path: string, opts: HttpRequestOptions = {}): Promise<T> {\n return this.dynatraceRequest<T>(true, path, opts);\n }\n\n private async dynatraceRequest<T>(\n platform: boolean,\n path: string,\n opts: HttpRequestOptions\n ): Promise<T> {\n const baseUrl = platform ? this.config.dynatrace.platformUrl : this.config.dynatrace.baseUrl;\n if (!baseUrl) {\n throw new PncliError(\n `${platform ? 'Dynatrace platformUrl' : 'Dynatrace baseUrl'} not configured. Run: pncli config init`\n );\n }\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.dynatraceHeaders(platform);\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private logscaleHeaders(): Record<string, string> {\n const { token } = this.config.logscale;\n if (!token) throw new PncliError('LogScale credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${token}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async logscale<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.logscale.baseUrl;\n if (!baseUrl) throw new PncliError('LogScale baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.logscaleHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n private splitioHeaders(): Record<string, string> {\n const { adminApiKey } = this.config.splitio;\n if (!adminApiKey) throw new PncliError('Split.IO credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `Bearer ${adminApiKey}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async splitio<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.splitio.baseUrl;\n if (!baseUrl) throw new PncliError('Split.IO baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.splitioHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n\n async openshiftText(\n path: string,\n opts: HttpRequestOptions & { lines?: number } = {}\n ): Promise<string> {\n const baseUrl = this.config.openshift.baseUrl;\n if (!baseUrl) throw new PncliError('OpenShift baseUrl not configured. Run: pncli config init');\n\n const params: Record<string, string | number | boolean | undefined> = { ...opts.params };\n if (opts.lines !== undefined) params['tailLines'] = opts.lines;\n\n const url = buildUrl(baseUrl, path, params);\n const headers: Record<string, string> = {\n 'Authorization': this.openshiftHeaders()['Authorization'],\n 'Accept': '*/*',\n 'Connection': 'close'\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, Authorization: '[REDACTED]' };\n fs.writeSync(process.stderr.fd, `DRY RUN: GET ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const response = await fetchWithTimeout(url, { method: 'GET', headers }, opts.timeoutMs ?? 30000);\n if (!response.ok) {\n let message = `HTTP ${response.status} ${response.statusText}`;\n try {\n const parsed = JSON.parse(await response.text());\n if (parsed.message) message = String(parsed.message);\n } catch { /* ignore */ }\n throw new PncliError(message, response.status, url);\n }\n\n return response.text();\n }\n\n async checkmarx<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.checkmarx.baseUrl;\n if (!baseUrl) throw new PncliError('Checkmarx baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n\n if (this.dryRun) {\n const msg = `DRY RUN: ${opts.method ?? 'GET'} ${url}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n const fetcher = this.getCheckmarxFetcher();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', ...opts.headers },\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n return request<T>(url, init, opts.timeoutMs ?? 30000, fetcher);\n }\n\n private figmaHeaders(): Record<string, string> {\n const { token } = this.config.figma;\n if (!token) throw new PncliError('Figma credentials not configured. Run: pncli config set figma.token <token>');\n return {\n 'X-Figma-Token': token,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async figma<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.figma.baseUrl;\n if (!baseUrl) throw new PncliError('Figma baseUrl not configured. Run: pncli config set figma.baseUrl https://api.figma.com');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.figmaHeaders();\n const init: RequestInit = {\n method: opts.method ?? 'GET',\n headers,\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined\n };\n\n if (this.dryRun) {\n const safeHeaders = { ...headers, 'X-Figma-Token': '[REDACTED]' };\n const msg = `DRY RUN: ${init.method} ${url}\\nHeaders: ${JSON.stringify(safeHeaders, null, 2)}\\n`\n + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}\\n` : '');\n fs.writeSync(process.stderr.fd, msg);\n process.exitCode = ExitCode.SUCCESS;\n throw new PncliError('dry-run', 0);\n }\n\n return request<T>(url, init, opts.timeoutMs ?? 30000);\n }\n}\n\nexport function createHttpClient(config: ResolvedConfig, dryRun = false): HttpClient {\n return new HttpClient(config, dryRun);\n}\n","import type { ResolvedConfig } from '../types/config.js';\nimport { PncliError } from './errors.js';\n\n/**\n * Returns a fetch-compatible function for Azure DevOps Server requests,\n * with Basic auth (PAT) injected into every call.\n */\nexport async function buildAdoFetcher(\n config: ResolvedConfig\n): Promise<typeof fetch> {\n const { pat, baseUrl } = config.ado;\n\n if (!baseUrl) {\n throw new PncliError('Azure DevOps baseUrl not configured. Run: pncli config init', 1);\n }\n\n if (!pat) {\n throw new PncliError(\n 'Azure DevOps PAT not configured. Set a PAT via pncli config init or PNCLI_ADO_PAT env var.',\n 1\n );\n }\n\n const encoded = Buffer.from(':' + pat).toString('base64');\n const authHeader = `Basic ${encoded}`;\n return (url: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]) =>\n fetch(url, {\n ...init,\n headers: {\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n ...(init?.headers as Record<string, string> | undefined),\n 'Authorization': authHeader\n }\n });\n}\n","import type { ResolvedConfig } from '../types/config.js';\nimport type { CxOneTokenResponse } from '../types/checkmarx.js';\nimport { PncliError } from './errors.js';\n\ninterface TokenCache {\n value: string;\n expiresAt: number;\n}\n\n/**\n * Returns a fetch-compatible function for Checkmarx One requests,\n * with Checkmarx API key or OAuth2 client_credentials token exchange and bearer auth\n * injected into every call.\n * The token is cached for the lifetime of the returned fetcher and refreshed\n * when within 60s of expiry.\n */\nexport function buildCheckmarxFetcher(config: ResolvedConfig): typeof fetch {\n const { baseUrl, tenantName, apiKey, clientId, clientSecret } = config.checkmarx;\n\n if (!baseUrl) throw new PncliError('Checkmarx baseUrl not configured. Run: pncli config init', 1);\n if (!tenantName) throw new PncliError('Checkmarx tenantName not configured. Run: pncli config init', 1);\n if (!apiKey && (!clientId || !clientSecret)) {\n throw new PncliError(\n 'Checkmarx credentials not configured. Set apiKey or clientId and clientSecret. Run: pncli config init',\n 1\n );\n }\n\n const apiHost = new URL(baseUrl).hostname;\n const iamHost = apiHost.replace(/(^|\\.)ast\\./, '$1iam.');\n const tokenUrl = `https://${iamHost}/auth/realms/${tenantName}/protocol/openid-connect/token`;\n let cache: TokenCache | null = null;\n\n async function getToken(): Promise<string> {\n const now = Date.now();\n if (cache && cache.expiresAt - now > 60_000) {\n return cache.value;\n }\n\n const body = apiKey\n ? new URLSearchParams({\n grant_type: 'refresh_token',\n client_id: getApiKeyClientId(apiKey),\n refresh_token: apiKey\n })\n : new URLSearchParams({\n grant_type: 'client_credentials',\n client_id: clientId!,\n client_secret: clientSecret!\n });\n\n const response = await fetch(tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString()\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new PncliError(\n `Checkmarx token exchange failed (${response.status}): ${text || response.statusText}`,\n response.status\n );\n }\n\n const data = await response.json() as CxOneTokenResponse;\n if (!data.access_token) {\n throw new PncliError('Checkmarx token endpoint returned no access_token', response.status);\n }\n cache = {\n value: data.access_token,\n expiresAt: now + data.expires_in * 1000\n };\n return cache.value;\n }\n\n return async (url: Parameters<typeof fetch>[0], init?: Parameters<typeof fetch>[1]): Promise<Response> => {\n const token = await getToken();\n return fetch(url, {\n ...init,\n headers: {\n ...(init?.headers as Record<string, string> | undefined),\n 'Authorization': `Bearer ${token}`\n }\n });\n };\n}\n\nfunction getApiKeyClientId(apiKey: string): string {\n try {\n const payload = apiKey.split('.')[1];\n if (!payload) return 'ast-app';\n const normalized = payload.replace(/-/g, '+').replace(/_/g, '/');\n const claims = JSON.parse(Buffer.from(normalized, 'base64').toString('utf8')) as { azp?: unknown };\n return typeof claims.azp === 'string' && claims.azp ? claims.azp : 'ast-app';\n } catch {\n return 'ast-app';\n }\n}\n"],"mappings":"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","names":[]}