@kolatts/pncli 6.0.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -140,6 +140,7 @@ This project uses Conventional Commits for automatic versioning:
140
140
  | Sonatype IQ | ⚪ Untested | Dependency policy enforcement |
141
141
  | OpenShift | ⚪ Untested | Pods, events, logs, metrics |
142
142
  | LogScale | ⚪ Untested | Log queries, repositories |
143
+ | Elasticsearch | ⚪ Untested | Search, count, indices, cluster health |
143
144
  | Figma | ⚪ Untested | Design files, comments, history |
144
145
  | Split.IO | ⚪ Untested | Feature flags, change requests |
145
146
  | Alation | ⚪ Untested | Catalog metadata, search, documents |
@@ -578,6 +578,8 @@ var ENV_KEYS = {
578
578
  DYNATRACE_PLATFORM_TOKEN: "PNCLI_DYNATRACE_PLATFORM_TOKEN",
579
579
  LOGSCALE_BASE_URL: "PNCLI_LOGSCALE_BASE_URL",
580
580
  LOGSCALE_TOKEN: "PNCLI_LOGSCALE_TOKEN",
581
+ ELASTICSEARCH_BASE_URL: "PNCLI_ELASTICSEARCH_BASE_URL",
582
+ ELASTICSEARCH_API_KEY: "PNCLI_ELASTICSEARCH_API_KEY",
581
583
  SPLITIO_BASE_URL: "PNCLI_SPLITIO_BASE_URL",
582
584
  SPLITIO_ADMIN_API_KEY: "PNCLI_SPLITIO_ADMIN_API_KEY",
583
585
  FIGMA_BASE_URL: "PNCLI_FIGMA_BASE_URL",
@@ -663,6 +665,7 @@ var SECRET_ENV_OVERRIDES = [
663
665
  ["dynatrace.apiToken", [ENV_KEYS.DYNATRACE_API_TOKEN]],
664
666
  ["dynatrace.platformToken", [ENV_KEYS.DYNATRACE_PLATFORM_TOKEN]],
665
667
  ["logscale.token", [ENV_KEYS.LOGSCALE_TOKEN]],
668
+ ["elasticsearch.apiKey", [ENV_KEYS.ELASTICSEARCH_API_KEY]],
666
669
  ["splitio.adminApiKey", [ENV_KEYS.SPLITIO_ADMIN_API_KEY]],
667
670
  ["figma.token", [ENV_KEYS.FIGMA_TOKEN]],
668
671
  ["alation.refreshToken", [ENV_KEYS.ALATION_REFRESH_TOKEN]],
@@ -773,6 +776,10 @@ function loadConfig(opts = {}) {
773
776
  baseUrl: process.env[ENV_KEYS.LOGSCALE_BASE_URL] ?? globalConfig.logscale?.baseUrl,
774
777
  token: process.env[ENV_KEYS.LOGSCALE_TOKEN] ?? globalConfig.logscale?.token
775
778
  },
779
+ elasticsearch: {
780
+ baseUrl: process.env[ENV_KEYS.ELASTICSEARCH_BASE_URL] ?? globalConfig.elasticsearch?.baseUrl,
781
+ apiKey: process.env[ENV_KEYS.ELASTICSEARCH_API_KEY] ?? globalConfig.elasticsearch?.apiKey
782
+ },
776
783
  splitio: {
777
784
  baseUrl: process.env[ENV_KEYS.SPLITIO_BASE_URL] ?? globalConfig.splitio?.baseUrl,
778
785
  adminApiKey: process.env[ENV_KEYS.SPLITIO_ADMIN_API_KEY] ?? globalConfig.splitio?.adminApiKey
@@ -948,6 +955,10 @@ function maskConfig(config) {
948
955
  ...config.logscale,
949
956
  token: config.logscale.token ? "***" : void 0
950
957
  },
958
+ elasticsearch: {
959
+ ...config.elasticsearch,
960
+ apiKey: config.elasticsearch.apiKey ? "***" : void 0
961
+ },
951
962
  splitio: {
952
963
  ...config.splitio,
953
964
  adminApiKey: config.splitio.adminApiKey ? "***" : void 0
@@ -998,4 +1009,4 @@ export {
998
1009
  setRepoConfigValue,
999
1010
  maskConfig
1000
1011
  };
1001
- //# sourceMappingURL=chunk-WDWAPTVC.js.map
1012
+ //# sourceMappingURL=chunk-GHZMFNSX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/config.ts","../src/types/jira.ts","../src/lib/validate-custom-fields.ts","../src/lib/keychain.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';\nimport { assertValidCustomFields } from './validate-custom-fields.js';\nimport { resolveKeychainRefs } from './keychain.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 ELASTICSEARCH_BASE_URL: 'PNCLI_ELASTICSEARCH_BASE_URL',\n ELASTICSEARCH_API_KEY: 'PNCLI_ELASTICSEARCH_API_KEY',\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 ALATION_BASE_URL: 'PNCLI_ALATION_BASE_URL',\n ALATION_REFRESH_TOKEN: 'PNCLI_ALATION_REFRESH_TOKEN',\n ALATION_USER_ID: 'PNCLI_ALATION_USER_ID',\n SAUCELABS_BASE_URL: 'PNCLI_SAUCELABS_BASE_URL',\n SAUCELABS_USERNAME: 'PNCLI_SAUCELABS_USERNAME',\n SAUCELABS_ACCESS_KEY: 'PNCLI_SAUCELABS_ACCESS_KEY',\n // The names saucectl, Sauce Connect and Sauce's own CI docs read — see the comment above GITHUB_TOKEN_FALLBACK.\n SAUCELABS_USERNAME_FALLBACK: 'SAUCE_USERNAME',\n SAUCELABS_ACCESS_KEY_FALLBACK: 'SAUCE_ACCESS_KEY',\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 if (global != null) {\n assertValidCustomFields(global, { source: 'global config' });\n for (const f of global) map.set(f.id, f);\n }\n if (repo != null) {\n assertValidCustomFields(repo, { source: 'repo config (.pncli.json)', repo: true });\n for (const f of repo) map.set(f.id, f); // repo wins\n }\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\n/** Secret fields and the env vars that override them (PNCLI_* first, then the CI fallback). */\nconst SECRET_ENV_OVERRIDES: [string, string[]][] = [\n ['jira.apiToken', [ENV_KEYS.JIRA_API_TOKEN]],\n ['bitbucket.pat', [ENV_KEYS.BITBUCKET_PAT]],\n ['github.token', [ENV_KEYS.GITHUB_TOKEN, ENV_KEYS.GITHUB_TOKEN_FALLBACK]],\n ['confluence.apiToken', [ENV_KEYS.CONFLUENCE_API_TOKEN]],\n ['artifactory.token', [ENV_KEYS.ARTIFACTORY_TOKEN]],\n ['sonar.token', [ENV_KEYS.SONAR_TOKEN, ENV_KEYS.SONAR_TOKEN_FALLBACK]],\n ['ado.pat', [ENV_KEYS.ADO_PAT, ENV_KEYS.ADO_PAT_FALLBACK]],\n ['jenkins.apiToken', [ENV_KEYS.JENKINS_API_TOKEN]],\n ['checkmarx.apiKey', [ENV_KEYS.CHECKMARX_API_KEY]],\n ['checkmarx.clientSecret', [ENV_KEYS.CHECKMARX_CLIENT_SECRET]],\n ['contrast.apiKey', [ENV_KEYS.CONTRAST_API_KEY]],\n ['contrast.serviceKey', [ENV_KEYS.CONTRAST_SERVICE_KEY]],\n ['sonatypeiq.passcode', [ENV_KEYS.SONATYPEIQ_PASSCODE]],\n ['openshift.token', [ENV_KEYS.OPENSHIFT_TOKEN]],\n ['dynatrace.apiToken', [ENV_KEYS.DYNATRACE_API_TOKEN]],\n ['dynatrace.platformToken', [ENV_KEYS.DYNATRACE_PLATFORM_TOKEN]],\n ['logscale.token', [ENV_KEYS.LOGSCALE_TOKEN]],\n ['elasticsearch.apiKey', [ENV_KEYS.ELASTICSEARCH_API_KEY]],\n ['splitio.adminApiKey', [ENV_KEYS.SPLITIO_ADMIN_API_KEY]],\n ['figma.token', [ENV_KEYS.FIGMA_TOKEN]],\n ['alation.refreshToken', [ENV_KEYS.ALATION_REFRESH_TOKEN]],\n ['saucelabs.accessKey', [ENV_KEYS.SAUCELABS_ACCESS_KEY, ENV_KEYS.SAUCELABS_ACCESS_KEY_FALLBACK]],\n];\n\n/** Config paths whose value an environment variable is currently overriding. */\nexport function envOverriddenSecretPaths(env: NodeJS.ProcessEnv = process.env): Set<string> {\n return new Set(SECRET_ENV_OVERRIDES.filter(([, keys]) => keys.some(k => env[k] !== undefined)).map(([p]) => p));\n}\n\nexport interface LoadConfigOptions {\n configPath?: string;\n /** Resolve only these `keychain:` config paths (e.g. `github.token`); every other one stays unread. */\n keychainPaths?: string[];\n}\n\nexport function loadConfig(opts: LoadConfigOptions = {}): ResolvedConfig {\n const globalConfigPath = getGlobalConfigPath(opts.configPath);\n // `keychain:<account>` values are swapped for the OS-keychain secret here, below every env var\n // in precedence — env vars are read directly from process.env further down and still win, and a\n // field an env var overrides is not looked up at all.\n const globalConfig = resolveKeychainRefs(loadJsonFile<GlobalConfig>(globalConfigPath) ?? {}, undefined, {\n skipPaths: envOverriddenSecretPaths(),\n ...(opts.keychainPaths ? { onlyPaths: new Set(opts.keychainPaths) } : {})\n });\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 elasticsearch: {\n baseUrl: process.env[ENV_KEYS.ELASTICSEARCH_BASE_URL] ?? globalConfig.elasticsearch?.baseUrl,\n apiKey: process.env[ENV_KEYS.ELASTICSEARCH_API_KEY] ?? globalConfig.elasticsearch?.apiKey,\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 alation: {\n baseUrl: process.env[ENV_KEYS.ALATION_BASE_URL] ?? globalConfig.alation?.baseUrl,\n refreshToken: process.env[ENV_KEYS.ALATION_REFRESH_TOKEN] ?? globalConfig.alation?.refreshToken,\n userId: process.env[ENV_KEYS.ALATION_USER_ID] ?? globalConfig.alation?.userId,\n },\n saucelabs: {\n baseUrl: process.env[ENV_KEYS.SAUCELABS_BASE_URL] ?? globalConfig.saucelabs?.baseUrl,\n username: process.env[ENV_KEYS.SAUCELABS_USERNAME]\n ?? process.env[ENV_KEYS.SAUCELABS_USERNAME_FALLBACK]\n ?? globalConfig.saucelabs?.username,\n accessKey: process.env[ENV_KEYS.SAUCELABS_ACCESS_KEY]\n ?? process.env[ENV_KEYS.SAUCELABS_ACCESS_KEY_FALLBACK]\n ?? globalConfig.saucelabs?.accessKey,\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 elasticsearch: {\n ...config.elasticsearch,\n apiKey: config.elasticsearch.apiKey ? '***' : 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 alation: {\n ...config.alation,\n refreshToken: config.alation.refreshToken ? '***' : undefined\n },\n saucelabs: {\n ...config.saucelabs,\n accessKey: config.saucelabs.accessKey ? '***' : undefined\n }\n };\n}\n\nexport { getGlobalConfigPath, loadJsonFile };\n","// Phase 3 — Jira Data Cloud types\n\nexport const CUSTOM_FIELD_TYPES = [\n 'string',\n 'number',\n 'date',\n 'datetime',\n 'select',\n 'multi-select',\n 'option-id',\n 'cascading-select',\n 'user',\n 'labels',\n 'url',\n 'textarea'\n] as const;\n\nexport type CustomFieldType = (typeof CUSTOM_FIELD_TYPES)[number];\n\nexport interface CustomFieldDefinition {\n id: string;\n name: string;\n /** Drives how a `--field` value is shaped for Jira's API. Omitted = raw string. */\n type?: CustomFieldType;\n description?: string;\n examples?: string[];\n}\n\nexport interface CustomFieldMap {\n byName: Map<string, CustomFieldDefinition>;\n byId: Map<string, CustomFieldDefinition>;\n}\n\nexport interface JiraUser {\n name: string;\n displayName: string;\n}\n\nexport interface JiraFieldInfo {\n id: string;\n name: string;\n custom: boolean;\n schema?: { type: string; custom?: string };\n allowedValues?: Array<{ id: string; value?: string; name?: string; children?: Array<{ id: string; value: string }> }>;\n /** Suggested pncli config type inferred from the Jira field schema. */\n pncliType?: CustomFieldType;\n}\n\nexport interface JiraIssue {\n id: string;\n key: string;\n fields: {\n summary: string;\n description?: unknown;\n status: { name: string };\n priority?: { name: string };\n assignee?: JiraUser | null;\n reporter?: JiraUser;\n labels?: string[];\n issuetype: { name: string };\n project: { key: string; name: string };\n created: string;\n updated: string;\n [key: string]: unknown;\n };\n}\n\nexport interface JiraTransition {\n id: string;\n name: string;\n to: { name: string };\n}\n\nexport interface JiraComment {\n id: string;\n author: JiraUser;\n body: unknown;\n created: string;\n updated: string;\n}\n\nexport interface JiraSearchResult {\n issues: JiraIssue[];\n total: number;\n startAt: number;\n maxResults: number;\n}\n\nexport interface JiraAttachment {\n id: string;\n filename: string;\n author: JiraUser;\n created: string;\n size: number;\n mimeType: string;\n content: string;\n}\n\nexport interface JiraBoard {\n id: number;\n name: string;\n type: string;\n}\n\nexport interface JiraSprint {\n id: number;\n name: string;\n state: string;\n startDate?: string;\n endDate?: string;\n goal?: string;\n}\n\nexport interface JiraWorklog {\n id: string;\n author: JiraUser;\n comment?: unknown;\n started: string;\n timeSpent: string;\n timeSpentSeconds: number;\n created: string;\n updated: string;\n}\n","import { PncliError } from './errors.js';\nimport { CUSTOM_FIELD_TYPES } from '../types/jira.js';\nimport type { CustomFieldDefinition } from '../types/jira.js';\n\nexport interface ValidateCustomFieldsOptions {\n /** Where the value came from, for the error message — e.g. `global config`. */\n source?: string;\n /** Append `--repo` to the suggested fix, for values read from `.pncli.json`. */\n repo?: boolean;\n}\n\nconst EXAMPLE = '[{\"id\":\"customfield_10032\",\"name\":\"Epic Link\",\"type\":\"select\"}]';\n\n/**\n * Validates `jira.customFields` before it's indexed or merged. The value comes straight\n * off disk (or a `config set` value that fell back to a raw string when JSON.parse failed —\n * e.g. mangled shell quoting), so it isn't guaranteed to match CustomFieldDefinition at\n * runtime even though the type says it does. Shared by `loadConfig` (which names the\n * offending config file) and `buildFieldMap` (which doesn't know where the value came from).\n */\nexport function assertValidCustomFields(\n fields: unknown,\n opts: ValidateCustomFieldsOptions = {}\n): asserts fields is CustomFieldDefinition[] {\n const where = opts.source ? `in ${opts.source}` : 'config';\n const fix = (value: string) => `Fix with: pncli config set jira.customFields '${value}'${opts.repo ? ' --repo' : ''}`;\n\n if (!Array.isArray(fields)) {\n throw new PncliError(\n `Invalid jira.customFields ${where}: expected an array, got ${JSON.stringify(fields)}. ${fix('[]')}`,\n 1\n );\n }\n for (const f of fields) {\n const entry = f as { id?: unknown; name?: unknown; type?: unknown } | null;\n if (typeof entry !== 'object' || entry === null || typeof entry.id !== 'string' || typeof entry.name !== 'string') {\n throw new PncliError(\n `Invalid jira.customFields ${where}: each entry must be an object with string \"id\" and \"name\" fields. Got: ${JSON.stringify(f)}. ${fix(EXAMPLE)}`,\n 1\n );\n }\n // `type` is optional (omitted = raw string, per skills/pncli/jira.md), but when present it\n // must be a known CustomFieldType — otherwise formatFieldValue silently falls through.\n if (entry.type !== undefined && (typeof entry.type !== 'string' || !(CUSTOM_FIELD_TYPES as readonly string[]).includes(entry.type))) {\n throw new PncliError(\n `Invalid jira.customFields ${where}: entry \"${entry.name}\" has unknown \"type\" ${JSON.stringify(entry.type)}; expected one of ${CUSTOM_FIELD_TYPES.join(', ')}. ${fix(EXAMPLE)}`,\n 1\n );\n }\n }\n}\n","import { spawnSync } from 'child_process';\n\n/**\n * OS keychain storage for pncli secrets.\n *\n * Any string value in the global config can be a reference of the form `keychain:<account>`\n * instead of the secret itself. `loadConfig` resolves those references through the platform's\n * own credential store, so a token never has to sit in plaintext in `~/.pncli/config.json`:\n *\n * macOS → login Keychain, via the built-in `security` tool\n * Windows → Credential Manager, via the built-in Windows PowerShell and advapi32\n * Linux → Secret Service (GNOME Keyring / KWallet), via `secret-tool` (libsecret-tools)\n *\n * This is opt-in storage, never a requirement: plaintext config and `PNCLI_*` env vars keep\n * working exactly as before, and env vars still win over anything stored here. Secrets always\n * travel to the helper process over stdin, never argv, because argv is visible to every other\n * process on the machine.\n */\n\nexport const KEYCHAIN_PREFIX = 'keychain:';\nexport const KEYCHAIN_SERVICE = 'pncli';\n\n/** Account names are config-path-like: `github.token`, `marketplaces.internal-ai.token`. */\nconst ACCOUNT_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;\n\nexport type KeychainBackendName = 'macos' | 'windows' | 'linux' | 'none';\n\nexport interface RunResult {\n status: number | null;\n stdout: string;\n stderr: string;\n error?: Error;\n}\n\n/** Spawns a helper process. Injected so tests can assert the exact invocation without a real keychain. */\nexport type Runner = (command: string, args: string[], input?: string) => RunResult;\n\nexport const defaultRunner: Runner = (command, args, input) => {\n const r = spawnSync(command, args, { input, encoding: 'utf8', windowsHide: true, timeout: 30_000 });\n return { status: r.status, stdout: r.stdout ?? '', stderr: r.stderr ?? '', error: r.error };\n};\n\nexport interface KeychainBackend {\n name: KeychainBackendName;\n /** Human-readable name of the store, for status output. */\n store: string;\n available(): boolean;\n /** Returns a map of account → secret (null when the account has no entry). */\n getMany(accounts: string[]): Record<string, string | null>;\n set(account: string, secret: string): void;\n /** Returns false when there was nothing to delete. */\n delete(account: string): boolean;\n}\n\nexport class KeychainError extends Error {}\n\n/**\n * Some accounts in a batch lookup failed (locked item, access denied) while others were read. The\n * readable ones are in `partial`, so one bad entry never takes every other reference down with it.\n */\nexport class KeychainBatchError extends KeychainError {\n constructor(public partial: Record<string, string | null>, public errors: Record<string, string>) {\n super(Object.entries(errors).map(([a, e]) => `${a}: ${e}`).join('; '));\n }\n}\n\n/** Runs a per-account lookup, collecting failures instead of stopping at the first one. */\nfunction lookupEach(accounts: string[], lookup: (account: string) => string | null): Record<string, string | null> {\n const out: Record<string, string | null> = {};\n const errors: Record<string, string> = {};\n for (const account of accounts) {\n try {\n out[account] = lookup(account);\n } catch (err) {\n errors[account] = err instanceof Error ? err.message : String(err);\n }\n }\n if (Object.keys(errors).length > 0) throw new KeychainBatchError(out, errors);\n return out;\n}\n\nexport function isKeychainRef(value: unknown): value is string {\n return typeof value === 'string' && value.startsWith(KEYCHAIN_PREFIX);\n}\n\nexport function keychainRef(account: string): string {\n assertValidAccount(account);\n return `${KEYCHAIN_PREFIX}${account}`;\n}\n\nexport function accountFromRef(ref: string): string {\n const account = ref.slice(KEYCHAIN_PREFIX.length);\n assertValidAccount(account);\n return account;\n}\n\nexport function assertValidAccount(account: string): void {\n if (!ACCOUNT_PATTERN.test(account)) {\n throw new KeychainError(`Invalid keychain account name \"${account}\" — use letters, digits, '.', '_' or '-' (max 128 chars).`);\n }\n}\n\nfunction assertStorableSecret(secret: string): void {\n if (!secret) throw new KeychainError('Refusing to store an empty secret.');\n if (/[\\r\\n]/.test(secret)) throw new KeychainError('Secrets containing newlines cannot be stored in the keychain.');\n}\n\nfunction failure(backend: string, action: string, r: RunResult): KeychainError {\n const detail = r.error?.message ?? (r.stderr.trim() || `exit code ${r.status}`);\n return new KeychainError(`${backend}: could not ${action}: ${detail}`);\n}\n\n// ─── macOS ──────────────────────────────────────────────────────────────────\n\nexport function macosBackend(run: Runner = defaultRunner): KeychainBackend {\n return {\n name: 'macos',\n store: 'macOS login Keychain',\n available() {\n const r = run('security', ['help']);\n return !r.error;\n },\n getMany(accounts) {\n return lookupEach(accounts, account => {\n assertValidAccount(account);\n const r = run('security', ['find-generic-password', '-s', KEYCHAIN_SERVICE, '-a', account, '-w']);\n // 44 = errSecItemNotFound\n if (r.status === 44) return null;\n if (r.status !== 0) throw failure('macOS Keychain', `read \"${account}\"`, r);\n return r.stdout.replace(/\\r?\\n$/, '');\n });\n },\n set(account, secret) {\n assertValidAccount(account);\n assertStorableSecret(secret);\n // `security -i` reads commands from stdin, so the secret never appears in argv. Hex (-X)\n // sidesteps security's quoting rules for secrets containing quotes or backslashes.\n const hex = Buffer.from(secret, 'utf8').toString('hex');\n const r = run('security', ['-i'], `add-generic-password -U -s ${KEYCHAIN_SERVICE} -a ${account} -l \"pncli ${account}\" -X ${hex}\\n`);\n if (r.status !== 0 || /error/i.test(r.stderr)) throw failure('macOS Keychain', `store \"${account}\"`, r);\n },\n delete(account) {\n assertValidAccount(account);\n const r = run('security', ['delete-generic-password', '-s', KEYCHAIN_SERVICE, '-a', account]);\n if (r.status === 44) return false;\n if (r.status !== 0) throw failure('macOS Keychain', `delete \"${account}\"`, r);\n return true;\n },\n };\n}\n\n// ─── Windows ────────────────────────────────────────────────────────────────\n\n/**\n * Windows Credential Manager has no built-in CLI that can read a secret back (`cmdkey` only\n * writes and lists), so this goes through advapi32 from the Windows PowerShell that ships with\n * every Windows install. All data — targets and secrets — is passed as JSON on stdin; the script\n * text is constant, so nothing user-controlled is ever interpolated into PowerShell.\n */\nexport const WINDOWS_CREDMAN_SCRIPT = String.raw`\n$ErrorActionPreference = 'Stop'\n# Redirected console streams default to the OEM code page; secrets are UTF-8 JSON both ways.\n[Console]::InputEncoding = New-Object System.Text.UTF8Encoding $false\n[Console]::OutputEncoding = New-Object System.Text.UTF8Encoding $false\nAdd-Type -TypeDefinition @'\nusing System;\nusing System.Runtime.InteropServices;\nusing System.Text;\npublic static class PncliCredMan {\n [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]\n private struct CREDENTIAL {\n public int Flags; public int Type; public string TargetName; public string Comment;\n public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;\n public int CredentialBlobSize; public IntPtr CredentialBlob; public int Persist;\n public int AttributeCount; public IntPtr Attributes; public string TargetAlias; public string UserName;\n }\n [DllImport(\"advapi32.dll\", CharSet = CharSet.Unicode, SetLastError = true)]\n private static extern bool CredReadW(string target, int type, int flags, out IntPtr cred);\n [DllImport(\"advapi32.dll\", CharSet = CharSet.Unicode, SetLastError = true)]\n private static extern bool CredWriteW(ref CREDENTIAL cred, int flags);\n [DllImport(\"advapi32.dll\", CharSet = CharSet.Unicode, SetLastError = true)]\n private static extern bool CredDeleteW(string target, int type, int flags);\n [DllImport(\"advapi32.dll\")]\n private static extern void CredFree(IntPtr cred);\n [DllImport(\"advapi32.dll\", CharSet = CharSet.Unicode, SetLastError = true)]\n private static extern bool CredEnumerateW(string filter, int flags, out int count, out IntPtr creds);\n private const int NotFound = 1168;\n public static string Read(string target) {\n IntPtr p;\n if (!CredReadW(target, 1, 0, out p)) {\n int err = Marshal.GetLastWin32Error();\n if (err == NotFound) return null;\n throw new System.ComponentModel.Win32Exception(err);\n }\n try {\n CREDENTIAL c = (CREDENTIAL)Marshal.PtrToStructure(p, typeof(CREDENTIAL));\n if (c.CredentialBlobSize == 0) return \"\";\n byte[] bytes = new byte[c.CredentialBlobSize];\n Marshal.Copy(c.CredentialBlob, bytes, 0, c.CredentialBlobSize);\n return Encoding.UTF8.GetString(bytes);\n } finally { CredFree(p); }\n }\n public static void Write(string target, string user, string secret) {\n byte[] bytes = Encoding.UTF8.GetBytes(secret);\n CREDENTIAL c = new CREDENTIAL();\n c.Type = 1; c.TargetName = target; c.UserName = user; c.Persist = 2;\n c.CredentialBlobSize = bytes.Length;\n c.CredentialBlob = Marshal.AllocHGlobal(bytes.Length);\n try {\n Marshal.Copy(bytes, 0, c.CredentialBlob, bytes.Length);\n if (!CredWriteW(ref c, 0)) throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error());\n } finally { Marshal.FreeHGlobal(c.CredentialBlob); }\n }\n // Git Credential Manager writes UTF-16LE blobs; pncli and git-credential-wincred write UTF-8.\n // Tokens are ASCII, so \"every odd byte is zero\" reliably identifies UTF-16.\n private static string Decode(byte[] bytes) {\n bool utf16 = bytes.Length % 2 == 0 && bytes.Length > 0;\n for (int i = 1; utf16 && i < bytes.Length; i += 2) if (bytes[i] != 0) utf16 = false;\n return utf16 ? Encoding.Unicode.GetString(bytes) : Encoding.UTF8.GetString(bytes);\n }\n // Flattened [target, user, secret] triples for every credential matching the filter (e.g. \"git:*\").\n public static string[] List(string filter) {\n int count; IntPtr list;\n if (!CredEnumerateW(filter, 0, out count, out list)) {\n int err = Marshal.GetLastWin32Error();\n if (err == NotFound) return new string[0];\n throw new System.ComponentModel.Win32Exception(err);\n }\n try {\n string[] outp = new string[count * 3];\n for (int i = 0; i < count; i++) {\n IntPtr item = Marshal.ReadIntPtr(list, i * IntPtr.Size);\n CREDENTIAL c = (CREDENTIAL)Marshal.PtrToStructure(item, typeof(CREDENTIAL));\n string secret = \"\";\n if (c.CredentialBlobSize > 0) {\n byte[] bytes = new byte[c.CredentialBlobSize];\n Marshal.Copy(c.CredentialBlob, bytes, 0, c.CredentialBlobSize);\n secret = Decode(bytes);\n }\n outp[i * 3] = c.TargetName; outp[i * 3 + 1] = c.UserName; outp[i * 3 + 2] = secret;\n }\n return outp;\n } finally { CredFree(list); }\n }\n public static bool Delete(string target) {\n if (CredDeleteW(target, 1, 0)) return true;\n int err = Marshal.GetLastWin32Error();\n if (err == NotFound) return false;\n throw new System.ComponentModel.Win32Exception(err);\n }\n}\n'@\n$req = [Console]::In.ReadToEnd() | ConvertFrom-Json\nswitch ($req.op) {\n 'get' {\n $out = @{}\n foreach ($t in $req.targets) { $out[$t] = [PncliCredMan]::Read($t) }\n [Console]::Out.Write((ConvertTo-Json -InputObject $out -Compress))\n }\n 'set' { [PncliCredMan]::Write($req.target, $req.user, $req.secret); [Console]::Out.Write('{\"ok\":true}') }\n 'delete' { $d = [PncliCredMan]::Delete($req.target); [Console]::Out.Write((ConvertTo-Json -InputObject @{ deleted = $d } -Compress)) }\n 'list' {\n $flat = [PncliCredMan]::List($req.filter)\n $items = @()\n for ($i = 0; $i -lt $flat.Length; $i += 3) { $items += @{ target = $flat[$i]; user = $flat[$i + 1]; secret = $flat[$i + 2] } }\n [Console]::Out.Write((ConvertTo-Json -InputObject @($items) -Compress -Depth 3))\n }\n 'ping' { [Console]::Out.Write('{\"ok\":true}') }\n}\n`;\n\nexport interface StoredCredential {\n target: string;\n user: string;\n /** Returned to the caller for fingerprinting and validation only — never printed. */\n secret: string;\n}\n\n/**\n * Every Windows Credential Manager entry whose target matches `filter` (e.g. `git:*`, which covers\n * what Git Credential Manager and git-credential-wincred store). Read-only.\n */\nexport function windowsListCredentials(filter: string, run: Runner = defaultRunner): StoredCredential[] {\n const encoded = Buffer.from(WINDOWS_CREDMAN_SCRIPT, 'utf16le').toString('base64');\n const r = run('powershell.exe', ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-EncodedCommand', encoded], JSON.stringify({ op: 'list', filter }));\n if (r.status !== 0) throw failure('Windows Credential Manager', 'list credentials', r);\n const parsed: unknown = JSON.parse(r.stdout.trim() || '[]');\n const items = Array.isArray(parsed) ? parsed : [parsed];\n return items\n .filter((x): x is { target?: unknown; user?: unknown; secret?: unknown } => !!x && typeof x === 'object')\n .map(x => ({ target: String(x.target ?? ''), user: String(x.user ?? ''), secret: String(x.secret ?? '') }));\n}\n\nexport function windowsTarget(account: string): string {\n return `${KEYCHAIN_SERVICE}:${account}`;\n}\n\nexport function windowsBackend(run: Runner = defaultRunner): KeychainBackend {\n const encoded = Buffer.from(WINDOWS_CREDMAN_SCRIPT, 'utf16le').toString('base64');\n const invoke = (payload: object, action: string): unknown => {\n const r = run('powershell.exe', ['-NoProfile', '-NonInteractive', '-ExecutionPolicy', 'Bypass', '-EncodedCommand', encoded], JSON.stringify(payload));\n if (r.status !== 0) throw failure('Windows Credential Manager', action, r);\n try {\n return JSON.parse(r.stdout.trim() || '{}');\n } catch {\n throw new KeychainError(`Windows Credential Manager: unexpected output while trying to ${action}.`);\n }\n };\n return {\n name: 'windows',\n store: 'Windows Credential Manager',\n available() {\n try { invoke({ op: 'ping' }, 'start PowerShell'); return true; } catch { return false; }\n },\n getMany(accounts) {\n accounts.forEach(assertValidAccount);\n if (accounts.length === 0) return {};\n const raw = invoke({ op: 'get', targets: accounts.map(windowsTarget) }, 'read credentials') as Record<string, string | null>;\n return Object.fromEntries(accounts.map(a => [a, raw[windowsTarget(a)] ?? null]));\n },\n set(account, secret) {\n assertValidAccount(account);\n assertStorableSecret(secret);\n invoke({ op: 'set', target: windowsTarget(account), user: account, secret }, `store \"${account}\"`);\n },\n delete(account) {\n assertValidAccount(account);\n const r = invoke({ op: 'delete', target: windowsTarget(account) }, `delete \"${account}\"`) as { deleted?: boolean };\n return !!r.deleted;\n },\n };\n}\n\n// ─── Linux ──────────────────────────────────────────────────────────────────\n\nexport function linuxBackend(run: Runner = defaultRunner): KeychainBackend {\n return {\n name: 'linux',\n store: 'Secret Service (secret-tool)',\n available() {\n const r = run('secret-tool', ['--version']);\n return !r.error;\n },\n getMany(accounts) {\n return lookupEach(accounts, account => {\n assertValidAccount(account);\n const r = run('secret-tool', ['lookup', 'service', KEYCHAIN_SERVICE, 'account', account]);\n if (r.error) throw failure('Secret Service', `read \"${account}\"`, r);\n // secret-tool exits 1 with empty output when nothing matches.\n if (r.status !== 0) return null;\n return r.stdout.replace(/\\r?\\n$/, '');\n });\n },\n set(account, secret) {\n assertValidAccount(account);\n assertStorableSecret(secret);\n const r = run('secret-tool', ['store', `--label=pncli ${account}`, 'service', KEYCHAIN_SERVICE, 'account', account], secret);\n if (r.status !== 0) throw failure('Secret Service', `store \"${account}\"`, r);\n },\n delete(account) {\n assertValidAccount(account);\n const existing = this.getMany([account])[account];\n if (existing === null) return false;\n const r = run('secret-tool', ['clear', 'service', KEYCHAIN_SERVICE, 'account', account]);\n if (r.status !== 0) throw failure('Secret Service', `delete \"${account}\"`, r);\n return true;\n },\n };\n}\n\n// ─── Selection ──────────────────────────────────────────────────────────────\n\nexport function noneBackend(): KeychainBackend {\n const unsupported = (): never => {\n throw new KeychainError(`No OS keychain backend is available on ${process.platform}. Set PNCLI_KEYCHAIN_BACKEND to macos, windows, or linux if one should be.`);\n };\n return { name: 'none', store: 'none', available: () => false, getMany: unsupported, set: unsupported, delete: unsupported };\n}\n\n/**\n * Picks the backend for this platform. `PNCLI_KEYCHAIN_BACKEND` overrides it — `none` disables\n * keychain resolution entirely (useful on a CI runner that inherits a developer config).\n */\nexport function getKeychainBackend(run: Runner = defaultRunner, platform: NodeJS.Platform = process.platform): KeychainBackend {\n const override = (process.env.PNCLI_KEYCHAIN_BACKEND || undefined) as KeychainBackendName | undefined;\n const name: KeychainBackendName = override\n ?? (platform === 'darwin' ? 'macos' : platform === 'win32' ? 'windows' : platform === 'linux' ? 'linux' : 'none');\n switch (name) {\n case 'macos': return macosBackend(run);\n case 'windows': return windowsBackend(run);\n case 'linux': return linuxBackend(run);\n case 'none': return noneBackend();\n default: throw new KeychainError(`Unknown PNCLI_KEYCHAIN_BACKEND \"${String(override)}\" — use macos, windows, linux, or none.`);\n }\n}\n\n// ─── Config integration ─────────────────────────────────────────────────────\n\n/** Leaf field names in the config that hold secrets. Used by `config keychain migrate` and doctor. */\nexport const SECRET_FIELD_NAMES = new Set([\n 'token', 'apiToken', 'pat', 'apiKey', 'clientSecret', 'serviceKey', 'passcode',\n 'refreshToken', 'adminApiKey', 'platformToken', 'password', 'connection', 'accessKey',\n]);\n\nexport interface ConfigSecretLocation {\n /** Path segments from the config root, e.g. ['marketplaces', 0, 'token']. */\n path: (string | number)[];\n value: string;\n}\n\n/**\n * Walks a parsed config object and returns every string leaf matching `predicate`. Arrays are\n * walked by index so `marketplaces[]` and `jenkinsInstances[]` entries are covered.\n */\nexport function findConfigStrings(\n root: unknown,\n predicate: (key: string | number, value: string) => boolean,\n prefix: (string | number)[] = []\n): ConfigSecretLocation[] {\n const found: ConfigSecretLocation[] = [];\n if (Array.isArray(root)) {\n root.forEach((item, i) => found.push(...findConfigStrings(item, predicate, [...prefix, i])));\n } else if (root && typeof root === 'object') {\n for (const [key, value] of Object.entries(root as Record<string, unknown>)) {\n if (typeof value === 'string') {\n if (predicate(key, value)) found.push({ path: [...prefix, key], value });\n } else {\n found.push(...findConfigStrings(value, predicate, [...prefix, key]));\n }\n }\n }\n return found;\n}\n\n/** Deletes keychain entries that no remaining reference in `config` points at. Returns the accounts deleted. */\nexport function purgeEntries(config: unknown, backend: KeychainBackend, accounts: string[]): string[] {\n const stillReferenced = new Set(findKeychainRefs(config).map(r => r.value.slice(KEYCHAIN_PREFIX.length)));\n const purged: string[] = [];\n for (const account of new Set(accounts)) {\n if (stillReferenced.has(account)) continue;\n if (backend.delete(account)) purged.push(account);\n }\n return purged;\n}\n\n/** Every `keychain:` reference in a config object. */\nexport function findKeychainRefs(root: unknown): ConfigSecretLocation[] {\n return findConfigStrings(root, (_k, v) => isKeychainRef(v));\n}\n\n/** Every plaintext secret (a secret-named field that is not already a keychain reference). */\nexport function findPlaintextSecrets(root: unknown): ConfigSecretLocation[] {\n return findConfigStrings(root, (k, v) => typeof k === 'string' && SECRET_FIELD_NAMES.has(k) && v.length > 0 && !isKeychainRef(v));\n}\n\n/**\n * Suggested keychain account for a config path. Array entries use a `name` field when the entry\n * has one (`marketplaces.internal-ai.token`), so the account survives reordering the array.\n */\nexport function accountForPath(root: unknown, segments: (string | number)[]): string {\n const parts: string[] = [];\n let node: unknown = root;\n for (const seg of segments) {\n if (typeof seg === 'number') {\n const entry = Array.isArray(node) ? node[seg] : undefined;\n const name = entry && typeof entry === 'object' ? (entry as { name?: unknown }).name : undefined;\n parts.push(typeof name === 'string' && /^[A-Za-z0-9._-]+$/.test(name) ? name : String(seg));\n } else {\n parts.push(seg);\n }\n node = node && typeof node === 'object' ? (node as Record<string | number, unknown>)[seg] : undefined;\n }\n return parts.join('.');\n}\n\nexport function setAtPath(root: Record<string, unknown>, segments: (string | number)[], value: unknown): void {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let node: any = root;\n for (const seg of segments.slice(0, -1)) node = node[seg];\n node[segments[segments.length - 1]!] = value;\n}\n\nexport interface UnresolvedRef {\n path: string;\n account: string;\n reason: string;\n}\n\nconst resolvedCache = new Map<string, string | null>();\nlet lastUnresolved: UnresolvedRef[] = [];\nlet warnedUnresolved = false;\n\n/** Refs the most recent resolution pass could not satisfy. Read by doctor. */\nexport function getUnresolvedKeychainRefs(): UnresolvedRef[] {\n return lastUnresolved;\n}\n\n/** Test hook: forget cached lookups between tests. */\nexport function resetKeychainCache(): void {\n resolvedCache.clear();\n lastUnresolved = [];\n warnedUnresolved = false;\n}\n\n/**\n * Returns a deep copy of `config` with every `keychain:` reference replaced by the stored secret.\n * One backend call covers all refs (a single PowerShell start on Windows), and results are cached\n * for the life of the process because `loadConfig` runs many times per command.\n *\n * A reference that cannot be resolved becomes `undefined` — the same as an unset key — so the\n * service that needs it reports \"not configured\" instead of sending the literal `keychain:...`\n * string as a credential. A single stderr warning names the refs; doctor reports them in detail.\n */\nexport function resolveKeychainRefs<T>(config: T, backend?: KeychainBackend, opts: { skipPaths?: Set<string>; onlyPaths?: Set<string> } = {}): T {\n const all = findKeychainRefs(config);\n if (all.length === 0) return config;\n\n const copy = JSON.parse(JSON.stringify(config)) as Record<string, unknown>;\n // A field an env var overrides is never used, so never ask the OS store for it — no process spawn\n // on a CI runner that inherited a developer's config, and no warning about a value nobody reads.\n const refs = all.filter(r => {\n const key = r.path.join('.');\n // onlyPaths: the caller reads just these fields, so no other reference is looked up.\n if (!opts.skipPaths?.has(key) && (!opts.onlyPaths || opts.onlyPaths.has(key))) return true;\n setAtPath(copy, r.path, undefined);\n return false;\n });\n if (refs.length === 0) return copy as T;\n const unresolved: UnresolvedRef[] = [];\n const accounts = new Map<string, (string | number)[][]>();\n for (const ref of refs) {\n try {\n const account = accountFromRef(ref.value);\n accounts.set(account, [...(accounts.get(account) ?? []), ref.path]);\n } catch (err) {\n unresolved.push({ path: ref.path.join('.'), account: ref.value.slice(KEYCHAIN_PREFIX.length), reason: (err as Error).message });\n setAtPath(copy, ref.path, undefined);\n }\n }\n\n const activeBackend = backend ?? getKeychainBackend();\n if (activeBackend.name === 'none') {\n // PNCLI_KEYCHAIN_BACKEND=none (or an unsupported platform): references are ignored on purpose,\n // so no warning — doctor still lists them.\n for (const [account, paths] of accounts) {\n for (const p of paths) {\n setAtPath(copy, p, undefined);\n unresolved.push({ path: p.join('.'), account, reason: 'keychain disabled (PNCLI_KEYCHAIN_BACKEND=none or unsupported platform)' });\n }\n }\n lastUnresolved = unresolved;\n return copy as T;\n }\n\n const missing = [...accounts.keys()].filter(a => !resolvedCache.has(a));\n if (missing.length > 0) {\n let failed: Record<string, string> = {};\n try {\n const found = activeBackend.getMany(missing);\n for (const a of missing) resolvedCache.set(a, found[a] ?? null);\n } catch (err) {\n if (err instanceof KeychainBatchError) {\n // Keep what was readable; only the accounts that actually failed are unresolved.\n for (const a of missing) if (!(a in err.errors)) resolvedCache.set(a, err.partial[a] ?? null);\n failed = err.errors;\n } else {\n failed = Object.fromEntries(missing.map(a => [a, (err as Error).message]));\n }\n }\n for (const [account, paths] of accounts) {\n if (resolvedCache.has(account) || !(account in failed)) continue;\n for (const p of paths) unresolved.push({ path: p.join('.'), account, reason: failed[account]! });\n }\n }\n\n for (const [account, paths] of accounts) {\n const secret = resolvedCache.get(account);\n for (const p of paths) {\n if (secret != null) {\n setAtPath(copy, p, secret);\n } else {\n setAtPath(copy, p, undefined);\n if (resolvedCache.has(account)) unresolved.push({ path: p.join('.'), account, reason: 'no entry in the keychain' });\n }\n }\n }\n\n lastUnresolved = unresolved;\n if (unresolved.length > 0 && !warnedUnresolved) {\n warnedUnresolved = true;\n process.stderr.write(`Warning: ${unresolved.length} keychain reference(s) could not be resolved (${unresolved.map(u => u.path).join(', ')}). Run: pncli doctor\\n`);\n }\n return copy as T;\n}\n\n/**\n * Stores a secret and reads it back before returning — the caller only then points config at it,\n * so a backend that silently drops writes can never leave a reference that resolves to nothing.\n */\nexport function storeVerified(backend: KeychainBackend, account: string, secret: string): void {\n backend.set(account, secret);\n let readBack: string | null | undefined;\n try {\n readBack = backend.getMany([account])[account];\n } catch (err) {\n throw new KeychainError(`Stored \"${account}\" but could not read it back to verify: ${err instanceof Error ? err.message : String(err)}`);\n }\n if (readBack !== secret) throw new KeychainError(`Stored \"${account}\" but reading it back did not return the same secret — config was not changed.`);\n}\n\n/** Resolves a single value that may be a keychain reference (e.g. a marketplace token read from raw config). */\nexport function resolveSecretValue(value: string | undefined, backend?: KeychainBackend): string | undefined {\n if (!isKeychainRef(value)) return value;\n const resolved = resolveKeychainRefs({ v: value }, backend);\n return resolved.v;\n}\n"],"mappings":"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","names":[]}
@@ -39,7 +39,9 @@ async function buildAdoFetcher(config) {
39
39
 
40
40
  // src/lib/tls.ts
41
41
  import tls from "tls";
42
+ var INSECURE_TLS_WARNING = "warning: NODE_TLS_REJECT_UNAUTHORIZED=0 is set, so pncli will NOT verify server certificates. Anyone on the network path can read or alter requests and responses, including your credentials and any writes. Unset it and trust the proxy or internal CA instead: install its root certificate in the OS store or set NODE_EXTRA_CA_CERTS=/path/to/ca.pem.\n";
42
43
  function configureTls(env = process.env, api = tls) {
44
+ if (env.NODE_TLS_REJECT_UNAUTHORIZED === "0") process.stderr.write(INSECURE_TLS_WARNING);
43
45
  if (env.NODE_USE_SYSTEM_CA !== void 0) return;
44
46
  try {
45
47
  const merged = /* @__PURE__ */ new Set([...api.getCACertificates("default"), ...api.getCACertificates("system")]);
@@ -1313,6 +1315,38 @@ Headers: ${JSON.stringify(safeHeaders, null, 2)}
1313
1315
  const msg = `DRY RUN: ${init.method} ${url}
1314
1316
  Headers: ${JSON.stringify(safeHeaders, null, 2)}
1315
1317
  ` + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}
1318
+ ` : "");
1319
+ fs.writeSync(process.stderr.fd, msg);
1320
+ process.exitCode = ExitCode.SUCCESS;
1321
+ throw new PncliError("dry-run", 0);
1322
+ }
1323
+ return request(url, init, opts.timeoutMs ?? 3e4);
1324
+ }
1325
+ elasticsearchHeaders() {
1326
+ const { apiKey } = this.config.elasticsearch;
1327
+ if (!apiKey) throw new PncliError("Elasticsearch credentials not configured. Run: pncli config init");
1328
+ return {
1329
+ "Authorization": `ApiKey ${apiKey}`,
1330
+ "Content-Type": "application/json",
1331
+ "Accept": "application/json",
1332
+ "Connection": "close"
1333
+ };
1334
+ }
1335
+ async elasticsearch(path, opts = {}) {
1336
+ const baseUrl = this.config.elasticsearch.baseUrl;
1337
+ if (!baseUrl) throw new PncliError("Elasticsearch baseUrl not configured. Run: pncli config init");
1338
+ const url = buildUrl(baseUrl, path, opts.params);
1339
+ const headers = this.elasticsearchHeaders();
1340
+ const init = {
1341
+ method: opts.method ?? "GET",
1342
+ headers,
1343
+ body: opts.body !== void 0 ? JSON.stringify(opts.body) : void 0
1344
+ };
1345
+ if (this.dryRun) {
1346
+ const safeHeaders = { ...headers, Authorization: "[REDACTED]" };
1347
+ const msg = `DRY RUN: ${init.method} ${url}
1348
+ Headers: ${JSON.stringify(safeHeaders, null, 2)}
1349
+ ` + (opts.body ? `Body: ${JSON.stringify(opts.body, null, 2)}
1316
1350
  ` : "");
1317
1351
  fs.writeSync(process.stderr.fd, msg);
1318
1352
  process.exitCode = ExitCode.SUCCESS;
@@ -1514,4 +1548,4 @@ export {
1514
1548
  HttpClient,
1515
1549
  createHttpClient
1516
1550
  };
1517
- //# sourceMappingURL=chunk-4FR4WGNR.js.map
1551
+ //# sourceMappingURL=chunk-Y3PO2RTO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/http.ts","../src/lib/adoFetch.ts","../src/lib/tls.ts","../src/lib/checkmarxFetch.ts","../src/lib/alationFetch.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';\nimport { buildAlationFetcher } from './alationFetch.js';\nimport { describeFetchError } from './tls.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', '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 } catch (err) {\n // Every caller — JSON, buffer and text helpers alike — gets the real cause\n // (ECONNREFUSED, DNS, TLS) and a fix hint for certificate errors instead of\n // Node's bare \"fetch failed\". A PncliError from a token-exchanging fetcher\n // (Checkmarx, Alation) already carries its own status and message.\n if (err instanceof PncliError) throw err;\n throw new PncliError(`Request failed: ${describeFetchError(err)}`, 0, url);\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 debug(` Error: ${err instanceof Error ? err.message : String(err)}`);\n throw err;\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 // FastAPI-style { detail: \"...\" } (Sauce Labs' v2 and rdc APIs)\n if (parts.length === 0 && typeof parsed.detail === 'string') {\n parts.push(parsed.detail);\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 private alationFetcher: 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 getAlationFetcher(): typeof fetch {\n if (!this.alationFetcher) {\n this.alationFetcher = buildAlationFetcher(this.config);\n }\n return this.alationFetcher;\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 elasticsearchHeaders(): Record<string, string> {\n const { apiKey } = this.config.elasticsearch;\n if (!apiKey) throw new PncliError('Elasticsearch credentials not configured. Run: pncli config init');\n return {\n 'Authorization': `ApiKey ${apiKey}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n async elasticsearch<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.elasticsearch.baseUrl;\n if (!baseUrl) throw new PncliError('Elasticsearch baseUrl not configured. Run: pncli config init');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = this.elasticsearchHeaders();\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 private saucelabsHeaders(): Record<string, string> {\n const { username, accessKey } = this.config.saucelabs;\n if (!username || !accessKey) {\n throw new PncliError('Sauce Labs credentials not configured. Run: pncli config set saucelabs.username <username> && pncli config set saucelabs.accessKey <access-key>');\n }\n const creds = Buffer.from(`${username}:${accessKey}`).toString('base64');\n return {\n 'Authorization': `Basic ${creds}`,\n 'Content-Type': 'application/json',\n 'Accept': 'application/json',\n 'Connection': 'close'\n };\n }\n\n /** The configured Sauce Labs username; most v1 paths are scoped to it. */\n saucelabsUsername(): string {\n const { username } = this.config.saucelabs;\n if (!username) throw new PncliError('Sauce Labs username not configured. Run: pncli config set saucelabs.username <username>');\n return username;\n }\n\n async saucelabs<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.saucelabs.baseUrl;\n if (!baseUrl) throw new PncliError('Sauce Labs baseUrl not configured. Run: pncli config set saucelabs.baseUrl https://api.us-west-1.saucelabs.com');\n\n const url = buildUrl(baseUrl, path, opts.params);\n const headers = { ...this.saucelabsHeaders(), ...opts.headers };\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 * Alation. The refresh token configured by the user is exchanged for a\n * short-lived API access token inside the fetcher (see alationFetch.ts) and\n * sent as the `TOKEN` header; no static credential goes on the wire here.\n * Alation's paths are Django routes — keep the trailing slash.\n */\n async alation<T>(\n path: string,\n opts: HttpRequestOptions = {}\n ): Promise<T> {\n const baseUrl = this.config.alation.baseUrl;\n if (!baseUrl) throw new PncliError('Alation baseUrl not configured. Run: pncli config set alation.baseUrl https://alation.imagile.dev');\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.getAlationFetcher();\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\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","/**\n * TLS trust setup, run once at startup before any request is made.\n *\n * Certificate verification is always on; pncli has no switch to turn it off.\n * To keep that working behind corporate SSL-inspection proxies, pncli trusts\n * the OS certificate store in addition to Node's bundled Mozilla CAs — the\n * same thing `NODE_USE_SYSTEM_CA=1` does. Corporate root CAs are pushed to the\n * OS store by IT (Group Policy, MDM, update-ca-certificates), so this makes\n * pncli trust whatever the user's browser already trusts, with no setup.\n *\n * `NODE_USE_SYSTEM_CA` is read by Node only at process start, so setting it\n * from here would do nothing. `tls.setDefaultCACertificates` (Node 22.19+,\n * which is why `engines.node` is pinned there) changes the default trust store\n * at runtime instead, and both the built-in fetch and the undici proxy agent\n * pick it up because neither passes its own `ca`.\n */\nimport tls from 'node:tls';\n\ntype TlsApi = Pick<typeof tls, 'getCACertificates' | 'setDefaultCACertificates'>;\n\nexport const INSECURE_TLS_WARNING =\n 'warning: NODE_TLS_REJECT_UNAUTHORIZED=0 is set, so pncli will NOT verify server certificates. ' +\n 'Anyone on the network path can read or alter requests and responses, including your credentials and any writes. ' +\n 'Unset it and trust the proxy or internal CA instead: install its root certificate in the OS store ' +\n 'or set NODE_EXTRA_CA_CERTS=/path/to/ca.pem.\\n';\n\nexport function configureTls(env: NodeJS.ProcessEnv = process.env, api: TlsApi = tls): void {\n // pncli never sets this, but a shell profile or CI image may. Node's own\n // one-line warning does not say what is at risk or what to do instead.\n if (env.NODE_TLS_REJECT_UNAUTHORIZED === '0') process.stderr.write(INSECURE_TLS_WARNING);\n\n // Any explicit value is the user's decision: `1` means Node already loaded\n // the system store at startup, and anything else (`0`) opts out of it.\n if (env.NODE_USE_SYSTEM_CA !== undefined) return;\n\n try {\n // 'default' already includes NODE_EXTRA_CA_CERTS, so that keeps working.\n const merged = new Set([...api.getCACertificates('default'), ...api.getCACertificates('system')]);\n api.setDefaultCACertificates([...merged]);\n } catch (err: unknown) {\n // Verification stays on with Node's bundled CAs; say why a corporate CA\n // might now be rejected rather than failing later with no context.\n const msg = err instanceof Error ? err.message : String(err);\n process.stderr.write(`warning: could not load the OS certificate store (${msg}); only Node's bundled CAs are trusted.\\n`);\n }\n}\n\n/**\n * Hints for certificate errors, keyed by the `code` Node puts on the cause of\n * a failed fetch. Only chain-of-trust failures are fixed by trusting a CA; a\n * hostname mismatch or an expired certificate needs a different fix.\n */\nconst UNTRUSTED_HINT =\n 'The certificate is not trusted by Node\\'s bundled CAs or the OS certificate store. ' +\n 'If your network uses an SSL-inspecting proxy or an internal CA, install its root certificate in the OS store ' +\n 'or set NODE_EXTRA_CA_CERTS=/path/to/ca.pem. For a self-signed server, export its certificate from the browser ' +\n 'and point NODE_EXTRA_CA_CERTS at that file.';\n\nconst TLS_ERROR_HINTS: Record<string, string> = {\n SELF_SIGNED_CERT_IN_CHAIN: UNTRUSTED_HINT,\n DEPTH_ZERO_SELF_SIGNED_CERT: UNTRUSTED_HINT,\n UNABLE_TO_VERIFY_LEAF_SIGNATURE: UNTRUSTED_HINT,\n UNABLE_TO_GET_ISSUER_CERT: UNTRUSTED_HINT,\n UNABLE_TO_GET_ISSUER_CERT_LOCALLY: UNTRUSTED_HINT,\n CERT_UNTRUSTED: UNTRUSTED_HINT,\n ERR_TLS_CERT_ALTNAME_INVALID:\n 'The certificate does not match the host in the URL. Use the hostname the certificate was issued for ' +\n '(usually the fully qualified name, not a short alias or IP address) in baseUrl.',\n CERT_HAS_EXPIRED:\n 'The server\\'s certificate has expired. Check the system clock; otherwise the server owner needs to renew it.',\n CERT_NOT_YET_VALID:\n 'The server\\'s certificate is not valid yet. Check the system clock.',\n};\n\nconst NODE_SYSTEM_CA_ADVICE = /;? ?if the root CA is installed locally, try running Node\\.js with --use-system-ca\\.?/;\n\n/**\n * Describe a rejected fetch. Node's built-in fetch reports every network\n * failure as \"fetch failed\" and hides the real reason (ECONNREFUSED, DNS,\n * TLS) in `err.cause`; this surfaces it and, for certificate errors, adds how\n * to fix it.\n */\nexport function describeFetchError(err: unknown): string {\n const topMsg = err instanceof Error ? err.message : String(err);\n const cause = err instanceof Error ? err.cause : undefined;\n const causeMsg = cause instanceof Error ? cause.message : undefined;\n const causeCode = cause && typeof cause === 'object' ? (cause as { code?: unknown }).code : undefined;\n const hint = typeof causeCode === 'string' ? TLS_ERROR_HINTS[causeCode] : undefined;\n // Node 24 appends its own \"try running Node.js with --use-system-ca\" advice to\n // untrusted-chain errors. pncli already trusts the system store, so drop it.\n const detail = hint && causeMsg ? causeMsg.replace(NODE_SYSTEM_CA_ADVICE, '') : causeMsg;\n return (detail ? `${topMsg}: ${detail}` : topMsg) + (hint ? `. ${hint}` : '');\n}\n","import type { ResolvedConfig } from '../types/config.js';\nimport type { CxOneTokenResponse } from '../types/checkmarx.js';\nimport { PncliError } from './errors.js';\nimport { describeFetchError } from './tls.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 let response: Response;\n try {\n response = await fetch(tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString()\n });\n } catch (err) {\n throw new PncliError(`Checkmarx token exchange failed: ${describeFetchError(err)}`, 0, tokenUrl);\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","import type { ResolvedConfig } from '../types/config.js';\nimport { PncliError } from './errors.js';\nimport { describeFetchError } from './tls.js';\n\n/** Response of POST /integration/v1/createAPIAccessToken/ (and validateAPIAccessToken). */\nexport interface AlationAccessTokenResponse {\n api_access_token: string;\n user_id: number;\n created_at?: string;\n /** Timezone-aware ISO 8601 timestamp; Alation's default lifetime is 24 hours. */\n token_expires_at?: string;\n token_status?: string;\n}\n\ninterface TokenCache {\n value: string;\n expiresAt: number;\n}\n\n/** Re-exchange when the cached token is within this window of expiring. */\nconst REFRESH_MARGIN_MS = 60_000;\n/** Alation's documented default API access token lifetime, used only if the response omits an expiry. */\nconst DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;\n\nexport const ALATION_CONFIG_HINT =\n 'Run: pncli config set alation.baseUrl https://alation.imagile.dev && pncli config set alation.refreshToken <token> && pncli config set alation.userId <id>';\n\n/**\n * Parse the user ID Alation needs alongside the refresh token. Config files\n * written by hand may hold a number or a string; env vars are always strings.\n * Anything that is not a positive integer is a config error with a fix, never a\n * TypeError from deep inside a request.\n */\nexport function parseAlationUserId(raw: string | number | undefined): number | undefined {\n if (raw === undefined || raw === '') return undefined;\n const text = String(raw).trim();\n if (!/^[1-9]\\d*$/.test(text)) {\n throw new PncliError(\n `Alation userId must be a positive integer (the numeric ID Alation returned when the refresh token was created), got \"${text}\". ${ALATION_CONFIG_HINT}`,\n 1\n );\n }\n return Number(text);\n}\n\nfunction requireAlationConfig(config: ResolvedConfig): { baseUrl: string; refreshToken: string; userId: number } {\n const { baseUrl, refreshToken } = config.alation;\n if (!baseUrl) throw new PncliError(`Alation baseUrl not configured. ${ALATION_CONFIG_HINT}`, 1);\n if (!refreshToken) throw new PncliError(`Alation refreshToken not configured. ${ALATION_CONFIG_HINT}`, 1);\n const userId = parseAlationUserId(config.alation.userId);\n if (userId === undefined) throw new PncliError(`Alation userId not configured. ${ALATION_CONFIG_HINT}`, 1);\n return { baseUrl, refreshToken, userId };\n}\n\n/** Alation's endpoints are Django routes: the trailing slash is significant. */\nfunction alationUrl(baseUrl: string, path: string): string {\n return `${baseUrl.replace(/\\/+$/, '')}/${path.replace(/^\\/+/, '')}`;\n}\n\n/**\n * Exchange the long-lived refresh token for a short-lived (default 24h) API\n * access token. This is the one HTTP hop between the credential the user\n * configured and an authenticated data-API request; it is never interactive.\n */\nexport async function createAlationAccessToken(config: ResolvedConfig): Promise<AlationAccessTokenResponse> {\n const { baseUrl, refreshToken, userId } = requireAlationConfig(config);\n const tokenUrl = alationUrl(baseUrl, 'integration/v1/createAPIAccessToken/');\n\n let response: Response;\n try {\n response = await fetch(tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },\n body: JSON.stringify({ refresh_token: refreshToken, user_id: userId })\n });\n } catch (err) {\n throw new PncliError(\n `Alation token exchange failed: ${describeFetchError(err)}`,\n 0,\n tokenUrl\n );\n }\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new PncliError(\n `Alation token exchange failed (${response.status}): ${text || response.statusText}. `\n + 'Check alation.refreshToken and alation.userId; refresh tokens expire after 60 days by default.',\n response.status,\n tokenUrl\n );\n }\n\n const data = await response.json() as Partial<AlationAccessTokenResponse>;\n if (!data.api_access_token) {\n throw new PncliError('Alation token endpoint returned no api_access_token', response.status, tokenUrl);\n }\n return data as AlationAccessTokenResponse;\n}\n\n/**\n * Validate the currently minted API access token without exposing it. Used by\n * `alation token status` so a user can see when the short-lived token expires\n * and confirm the refresh token still works.\n */\nexport async function validateAlationAccessToken(config: ResolvedConfig): Promise<Omit<AlationAccessTokenResponse, 'api_access_token'>> {\n const { baseUrl, userId } = requireAlationConfig(config);\n const minted = await createAlationAccessToken(config);\n const validateUrl = alationUrl(baseUrl, 'integration/v1/validateAPIAccessToken/');\n let response: Response;\n try {\n response = await fetch(validateUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },\n body: JSON.stringify({ api_access_token: minted.api_access_token, user_id: userId })\n });\n } catch (err) {\n throw new PncliError(\n `Alation token validation failed: ${describeFetchError(err)}`,\n 0,\n validateUrl\n );\n }\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new PncliError(`Alation token validation failed (${response.status}): ${text || response.statusText}`, response.status, validateUrl);\n }\n const data = await response.json() as AlationAccessTokenResponse;\n const { api_access_token: _omit, ...rest } = data;\n void _omit;\n return rest;\n}\n\n/**\n * Returns a fetch-compatible function for Alation requests with the\n * refresh-token → API-access-token exchange and the `TOKEN` header injected\n * into every call. The access token is cached for the lifetime of the returned\n * fetcher and re-minted when within 60s of expiry. It is never persisted.\n */\nexport function buildAlationFetcher(config: ResolvedConfig): typeof fetch {\n requireAlationConfig(config);\n let cache: TokenCache | null = null;\n\n async function getToken(): Promise<string> {\n const now = Date.now();\n if (cache && cache.expiresAt - now > REFRESH_MARGIN_MS) {\n return cache.value;\n }\n const data = await createAlationAccessToken(config);\n const parsedExpiry = data.token_expires_at ? Date.parse(data.token_expires_at) : NaN;\n cache = {\n value: data.api_access_token,\n expiresAt: Number.isNaN(parsedExpiry) ? now + DEFAULT_TTL_MS : parsedExpiry\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 'TOKEN': token\n }\n });\n };\n}\n"],"mappings":"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","names":[]}