@kolatts/pncli 1.25.1 → 2.0.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
@@ -5,7 +5,9 @@
5
5
 
6
6
  > One command does what three meetings couldn't.
7
7
 
8
- pncli gives AI coding agents (and humans) structured CLI access to Jira, Bitbucket, Confluence, SonarQube, SDElements, Azure DevOps Server, Jenkins, JFrog Artifactory, IBM UrbanCode Deploy, and Checkmarx. No MCP servers required. No meetings to schedule. No forms to fill out.
8
+ pncli gives AI coding agents (and humans) structured CLI access to the enterprise tools your org actually runs — Jira, Bitbucket, Confluence, SonarQube, SDElements, Azure DevOps Server, Jenkins, JFrog Artifactory, Checkmarx, and more. No MCP servers required. No meetings to schedule. No forms to fill out.
9
+
10
+ The service list grows. Any enterprise tool that authenticates with a personal access token is a candidate — issue trackers and CI/CD, but equally design, docs, observability, and collaboration tools your agents need context from. [Request one](https://kolatts.github.io/pncli/feedback/).
9
11
 
10
12
  ## Why?
11
13
 
@@ -64,10 +66,6 @@ pncli uses a three-layer config system (highest priority wins):
64
66
  | `PNCLI_ARTIFACTORY_REPO_NPM` | Artifactory virtual npm repository name |
65
67
  | `PNCLI_ARTIFACTORY_REPO_NUGET` | Artifactory virtual NuGet repository name |
66
68
  | `PNCLI_ARTIFACTORY_REPO_MAVEN` | Artifactory virtual Maven repository name |
67
- | `PNCLI_UDEPLOY_BASE_URL` | IBM UrbanCode Deploy base URL |
68
- | `PNCLI_UDEPLOY_PAT` | IBM UrbanCode Deploy personal access token |
69
- | `PNCLI_UDEPLOY_USERNAME` | IBM UrbanCode Deploy username (alternative to PAT) |
70
- | `PNCLI_UDEPLOY_PASSWORD` | IBM UrbanCode Deploy password (used with `PNCLI_UDEPLOY_USERNAME`) |
71
69
  | `PNCLI_CHECKMARX_BASE_URL` | Checkmarx One API base URL |
72
70
  | `PNCLI_CHECKMARX_TENANT_NAME` | Checkmarx One tenant name |
73
71
  | `PNCLI_CHECKMARX_API_KEY` | Checkmarx One API key |
@@ -111,11 +109,16 @@ This project uses Conventional Commits for automatic versioning:
111
109
  | SonarQube | ✅ Active | SonarQube Server 9.x / 10.x | user token |
112
110
  | SDElements | ✅ Active | SDElements cloud + on-prem (REST API v2) | connection string (`token@hostname`) |
113
111
  | Azure DevOps Server | ✅ Active | ADO Server 2020+ (REST API 7.1) | personal access token (PAT) |
114
- | Jenkins | ✅ Active | Jenkins 2.x LTS (Data Center) | username + API token |
112
+ | Jenkins | ✅ Active | Jenkins 2.x LTS | username + API token |
115
113
  | JFrog Artifactory | ✅ Active | Artifactory 7.x | bearer token |
116
- | IBM UrbanCode Deploy | ✅ Active | UCD 7.x | PAT **or** username + password |
117
114
  | Checkmarx | ✅ Active | CxSAST 9.x (on-prem) | username + password (OAuth2 password grant — pncli handles token exchange) |
118
115
 
116
+ ### Adding a service
117
+
118
+ Requests for new integrations are welcome for **any enterprise tool**, not just the SDLC categories above — design, documentation, observability, ITSM, and collaboration tools all count.
119
+
120
+ The one hard requirement is authentication: the tool must support a **personal access token** — a long-lived static credential you generate in its own UI and paste into an env var or config file. Vendor naming doesn't matter (API token, user token, PAT). Tools whose only auth is interactive OAuth, SSO/SAML, username+password, a registered OAuth app, a cloud IAM credential chain, or mTLS can't be supported. The Checkmarx row above predates this rule and is grandfathered. IBM UrbanCode Deploy was removed in v2.0.0 for exactly this reason — UCD tokens are not usable as a standalone credential the way pncli requires, so its only workable auth was username + password.
121
+
119
122
  ## License
120
123
 
121
124
  Apache 2.0 — see [LICENSE](./LICENSE) and [NOTICE](./NOTICE).
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## What is pncli?
6
6
 
7
- pncli is a CLI tool that provides structured JSON access to Jira, Bitbucket, Confluence, SonarQube, SDElements, Azure DevOps Server, Jenkins, JFrog Artifactory, IBM UrbanCode Deploy, Checkmarx, and local git state. Use it for all interactions with these services. It exists because MCP servers aren't available in this environment — pncli is your agent-friendly shim layer.
7
+ pncli is a CLI tool that provides structured JSON access to the enterprise tools your org runs — Jira, Bitbucket, Confluence, SonarQube, SDElements, Azure DevOps Server, Jenkins, JFrog Artifactory, Checkmarx, and local git state, among others. Use it for all interactions with these services. It exists because MCP servers aren't available in this environment — pncli is your agent-friendly shim layer.
8
8
 
9
9
  ## Important
10
10
 
@@ -1069,41 +1069,6 @@ pncli artifactory build-runs
1069
1069
  pncli artifactory build-info
1070
1070
  ```
1071
1071
 
1072
- ### Udeploy
1073
-
1074
- ```
1075
- pncli udeploy apps
1076
-
1077
- pncli udeploy environments
1078
-
1079
- pncli udeploy components
1080
-
1081
- pncli udeploy versions
1082
- --component <name> Component name or ID
1083
-
1084
- pncli udeploy import-version
1085
- --component <name> Component name or ID
1086
- --name <name> Version name
1087
- --no-finish Skip marking the version as finished importing
1088
-
1089
- pncli udeploy run
1090
- --process <name> Application process name or ID
1091
- --component <name> Component name (repeatable) (default: [])
1092
- --component-version <name> Component version (repeatable; positionally paired
1093
- with --component) (default: [])
1094
- --snapshot <name> Snapshot name or ID (alternative to specifying
1095
- versions)
1096
- --only-changed Deploy only changed components (default: false)
1097
- --wait Poll until the process completes (default: false)
1098
- --timeout <ms> Max wait time in milliseconds (default: "600000")
1099
-
1100
- pncli udeploy request-status
1101
- --request-id <id> Request ID returned by udeploy run
1102
-
1103
- pncli udeploy request-info
1104
- --request-id <id> Request ID returned by udeploy run
1105
- ```
1106
-
1107
1072
  ### Checkmarx
1108
1073
 
1109
1074
  ```
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/lib/output.ts
4
+ import fs from "fs";
5
+ import chalk from "chalk";
6
+
7
+ // src/lib/errors.ts
8
+ var PncliError = class extends Error {
9
+ status;
10
+ url;
11
+ constructor(message, status = 1, url) {
12
+ super(message);
13
+ this.name = "PncliError";
14
+ this.status = status;
15
+ this.url = url;
16
+ }
17
+ };
18
+
19
+ // src/lib/exitCodes.ts
20
+ var ExitCode = {
21
+ SUCCESS: 0,
22
+ GENERAL_ERROR: 1,
23
+ USAGE_ERROR: 2,
24
+ NETWORK_ERROR: 69,
25
+ // EX_UNAVAILABLE from sysexits.h
26
+ AUTH_ERROR: 77,
27
+ // EX_NOPERM from sysexits.h
28
+ CONFIG_ERROR: 78
29
+ // EX_CONFIG from sysexits.h
30
+ };
31
+ function exitCodeFromStatus(httpStatus) {
32
+ if (httpStatus === 401 || httpStatus === 403) return ExitCode.AUTH_ERROR;
33
+ if (httpStatus === 0) return ExitCode.NETWORK_ERROR;
34
+ return ExitCode.GENERAL_ERROR;
35
+ }
36
+
37
+ // src/lib/output.ts
38
+ var globalOptions = { pretty: false, verbose: false, debug: false };
39
+ var globalUser = { email: void 0, userId: void 0 };
40
+ var outputFile;
41
+ function setGlobalOptions(opts) {
42
+ globalOptions = { pretty: opts.pretty, verbose: opts.verbose, debug: opts.debug ?? false };
43
+ outputFile = opts.outputFile;
44
+ }
45
+ function isDebugEnabled() {
46
+ return globalOptions.debug;
47
+ }
48
+ function setGlobalUser(user) {
49
+ globalUser = user;
50
+ }
51
+ function buildMeta(service, action, startTime, overrides) {
52
+ return {
53
+ service,
54
+ action,
55
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
56
+ duration_ms: Date.now() - startTime,
57
+ user: globalUser.email ?? globalUser.userId ? globalUser : void 0,
58
+ overrides: overrides && overrides.length > 0 ? overrides : void 0
59
+ };
60
+ }
61
+ function writeToFile(filePath, content) {
62
+ try {
63
+ fs.writeFileSync(filePath, content, "utf8");
64
+ } catch (writeErr) {
65
+ process.stderr.write(
66
+ `Warning: could not write to output file "${filePath}": ${writeErr.message}
67
+ `
68
+ );
69
+ process.exitCode = ExitCode.GENERAL_ERROR;
70
+ }
71
+ }
72
+ function success(data, service, action, startTime, overrides) {
73
+ const envelope = {
74
+ ok: true,
75
+ data,
76
+ meta: buildMeta(service, action, startTime, overrides)
77
+ };
78
+ const out = (globalOptions.pretty ? JSON.stringify(envelope, null, 2) : JSON.stringify(envelope)) + "\n";
79
+ if (outputFile) {
80
+ writeToFile(outputFile, out);
81
+ } else {
82
+ process.stdout.write(out);
83
+ }
84
+ }
85
+ function fail(err, service, action, startTime) {
86
+ const errorDetail = {
87
+ status: err instanceof PncliError ? err.status : 1,
88
+ message: err instanceof Error ? err.message : String(err),
89
+ url: err instanceof PncliError ? err.url ?? null : null
90
+ };
91
+ const envelope = {
92
+ ok: false,
93
+ error: errorDetail,
94
+ meta: buildMeta(service, action, startTime)
95
+ };
96
+ const msg = globalOptions.pretty ? chalk.red("\u2717 Error: ") + errorDetail.message : null;
97
+ if (msg) process.stderr.write(msg + "\n");
98
+ const output = (globalOptions.pretty ? JSON.stringify(envelope, null, 2) : JSON.stringify(envelope)) + "\n";
99
+ const exitCode = err instanceof PncliError ? exitCodeFromStatus(err.status) : ExitCode.GENERAL_ERROR;
100
+ if (outputFile) {
101
+ writeToFile(outputFile, output);
102
+ } else {
103
+ try {
104
+ fs.writeSync(process.stdout.fd, output);
105
+ } catch (writeErr) {
106
+ if (writeErr.code !== "EPIPE") throw writeErr;
107
+ }
108
+ }
109
+ process.exitCode = exitCode;
110
+ throw new PncliError(errorDetail.message, errorDetail.status);
111
+ }
112
+ function writeRawOutput(content) {
113
+ if (outputFile) {
114
+ writeToFile(outputFile, content);
115
+ } else {
116
+ process.stdout.write(content);
117
+ }
118
+ }
119
+ function log(message) {
120
+ if (globalOptions.verbose) {
121
+ process.stderr.write(
122
+ (globalOptions.pretty ? chalk.gray("\u25B8 ") : "") + message + "\n"
123
+ );
124
+ }
125
+ }
126
+ function debug(message) {
127
+ if (globalOptions.debug) {
128
+ process.stderr.write(
129
+ (globalOptions.pretty ? chalk.cyan("\u2B21 ") : "") + message + "\n"
130
+ );
131
+ }
132
+ }
133
+ function warn(message) {
134
+ process.stderr.write(
135
+ (globalOptions.pretty ? chalk.yellow("\u26A0 ") : "") + message + "\n"
136
+ );
137
+ }
138
+
139
+ export {
140
+ PncliError,
141
+ ExitCode,
142
+ setGlobalOptions,
143
+ isDebugEnabled,
144
+ setGlobalUser,
145
+ success,
146
+ fail,
147
+ writeRawOutput,
148
+ log,
149
+ debug,
150
+ warn
151
+ };
152
+ //# sourceMappingURL=chunk-HZF6WQPU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/output.ts","../src/lib/errors.ts","../src/lib/exitCodes.ts"],"sourcesContent":["import fs from 'fs';\nimport chalk from 'chalk';\nimport type { Meta, SuccessEnvelope, ErrorEnvelope, ErrorDetail } from '../types/common.js';\nimport { PncliError } from './errors.js';\nimport { ExitCode, exitCodeFromStatus } from './exitCodes.js';\n\nlet globalOptions = { pretty: false, verbose: false, debug: false };\nlet globalUser: { email: string | undefined; userId: string | undefined } = { email: undefined, userId: undefined };\nlet outputFile: string | undefined;\n\nexport function setGlobalOptions(opts: { pretty: boolean; verbose: boolean; debug?: boolean; outputFile?: string }): void {\n globalOptions = { pretty: opts.pretty, verbose: opts.verbose, debug: opts.debug ?? false };\n outputFile = opts.outputFile;\n}\n\nexport function isDebugEnabled(): boolean {\n return globalOptions.debug;\n}\n\nexport function setGlobalUser(user: { email: string | undefined; userId: string | undefined }): void {\n globalUser = user;\n}\n\nfunction buildMeta(service: string, action: string, startTime: number, overrides?: string[]): Meta {\n return {\n service,\n action,\n timestamp: new Date().toISOString(),\n duration_ms: Date.now() - startTime,\n user: (globalUser.email ?? globalUser.userId) ? globalUser : undefined,\n overrides: overrides && overrides.length > 0 ? overrides : undefined\n };\n}\n\nfunction writeToFile(filePath: string, content: string): void {\n try {\n fs.writeFileSync(filePath, content, 'utf8');\n } catch (writeErr) {\n process.stderr.write(\n `Warning: could not write to output file \"${filePath}\": ${(writeErr as NodeJS.ErrnoException).message}\\n`\n );\n process.exitCode = ExitCode.GENERAL_ERROR;\n }\n}\n\nexport function success<T>(data: T, service: string, action: string, startTime: number, overrides?: string[]): void {\n const envelope: SuccessEnvelope<T> = {\n ok: true,\n data,\n meta: buildMeta(service, action, startTime, overrides)\n };\n const out = (globalOptions.pretty ? JSON.stringify(envelope, null, 2) : JSON.stringify(envelope)) + '\\n';\n if (outputFile) {\n writeToFile(outputFile, out);\n } else {\n process.stdout.write(out);\n }\n}\n\nexport function fail(\n err: unknown,\n service: string,\n action: string,\n startTime: number\n): never {\n const errorDetail: ErrorDetail = {\n status: err instanceof PncliError ? err.status : 1,\n message: err instanceof Error ? err.message : String(err),\n url: err instanceof PncliError ? (err.url ?? null) : null\n };\n\n const envelope: ErrorEnvelope = {\n ok: false,\n error: errorDetail,\n meta: buildMeta(service, action, startTime)\n };\n\n const msg = globalOptions.pretty\n ? chalk.red('✗ Error: ') + errorDetail.message\n : null;\n\n if (msg) process.stderr.write(msg + '\\n');\n\n const output = (globalOptions.pretty ? JSON.stringify(envelope, null, 2) : JSON.stringify(envelope)) + '\\n';\n const exitCode = err instanceof PncliError ? exitCodeFromStatus(err.status) : ExitCode.GENERAL_ERROR;\n if (outputFile) {\n writeToFile(outputFile, output);\n } else {\n try {\n fs.writeSync(process.stdout.fd, output);\n } catch (writeErr) {\n if ((writeErr as NodeJS.ErrnoException).code !== 'EPIPE') throw writeErr;\n }\n }\n process.exitCode = exitCode;\n throw new PncliError(errorDetail.message, errorDetail.status);\n}\n\nexport function writeRawOutput(content: string): void {\n if (outputFile) {\n writeToFile(outputFile, content);\n } else {\n process.stdout.write(content);\n }\n}\n\nexport function log(message: string): void {\n if (globalOptions.verbose) {\n process.stderr.write(\n (globalOptions.pretty ? chalk.gray('▸ ') : '') + message + '\\n'\n );\n }\n}\n\nexport function debug(message: string): void {\n if (globalOptions.debug) {\n process.stderr.write(\n (globalOptions.pretty ? chalk.cyan('⬡ ') : '') + message + '\\n'\n );\n }\n}\n\nexport function warn(message: string): void {\n process.stderr.write(\n (globalOptions.pretty ? chalk.yellow('⚠ ') : '') + message + '\\n'\n );\n}\n","export class PncliError extends Error {\n status: number;\n url?: string;\n\n constructor(message: string, status: number = 1, url?: string) {\n super(message);\n this.name = 'PncliError';\n this.status = status;\n this.url = url;\n }\n}\n","export const ExitCode = {\n SUCCESS: 0,\n GENERAL_ERROR: 1,\n USAGE_ERROR: 2,\n NETWORK_ERROR: 69, // EX_UNAVAILABLE from sysexits.h\n AUTH_ERROR: 77, // EX_NOPERM from sysexits.h\n CONFIG_ERROR: 78, // EX_CONFIG from sysexits.h\n} as const;\n\nexport type ExitCode = (typeof ExitCode)[keyof typeof ExitCode];\n\nexport function exitCodeFromStatus(httpStatus: number): ExitCode {\n if (httpStatus === 401 || httpStatus === 403) return ExitCode.AUTH_ERROR;\n if (httpStatus === 0) return ExitCode.NETWORK_ERROR;\n return ExitCode.GENERAL_ERROR;\n}\n"],"mappings":"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","names":[]}
@@ -36,10 +36,6 @@ var ENV_KEYS = {
36
36
  JENKINS_BASE_URL: "PNCLI_JENKINS_BASE_URL",
37
37
  JENKINS_USERNAME: "PNCLI_JENKINS_USERNAME",
38
38
  JENKINS_API_TOKEN: "PNCLI_JENKINS_API_TOKEN",
39
- UDEPLOY_BASE_URL: "PNCLI_UDEPLOY_BASE_URL",
40
- UDEPLOY_PAT: "PNCLI_UDEPLOY_PAT",
41
- UDEPLOY_USERNAME: "PNCLI_UDEPLOY_USERNAME",
42
- UDEPLOY_PASSWORD: "PNCLI_UDEPLOY_PASSWORD",
43
39
  CHECKMARX_BASE_URL: "PNCLI_CHECKMARX_BASE_URL",
44
40
  CHECKMARX_TENANT_NAME: "PNCLI_CHECKMARX_TENANT_NAME",
45
41
  CHECKMARX_API_KEY: "PNCLI_CHECKMARX_API_KEY",
@@ -65,6 +61,10 @@ var ENV_KEYS = {
65
61
  DYNATRACE_PLATFORM_TOKEN: "PNCLI_DYNATRACE_PLATFORM_TOKEN",
66
62
  LOGSCALE_BASE_URL: "PNCLI_LOGSCALE_BASE_URL",
67
63
  LOGSCALE_TOKEN: "PNCLI_LOGSCALE_TOKEN",
64
+ SPLITIO_BASE_URL: "PNCLI_SPLITIO_BASE_URL",
65
+ SPLITIO_ADMIN_API_KEY: "PNCLI_SPLITIO_ADMIN_API_KEY",
66
+ FIGMA_BASE_URL: "PNCLI_FIGMA_BASE_URL",
67
+ FIGMA_TOKEN: "PNCLI_FIGMA_TOKEN",
68
68
  CONFIG_PATH: "PNCLI_CONFIG_PATH"
69
69
  };
70
70
  function getGlobalConfigPath(overridePath) {
@@ -110,7 +110,6 @@ function mergeDefaults(global, repo) {
110
110
  sonar: { ...global?.sonar, ...repo?.sonar },
111
111
  sde: { ...global?.sde, ...repo?.sde },
112
112
  ado: { ...global?.ado, ...repo?.ado },
113
- udeploy: { ...global?.udeploy, ...repo?.udeploy },
114
113
  jenkins: { ...global?.jenkins, ...repo?.jenkins }
115
114
  };
116
115
  }
@@ -174,12 +173,7 @@ function loadConfig(opts = {}) {
174
173
  username: process.env[ENV_KEYS.JENKINS_USERNAME] ?? globalConfig.jenkins?.username,
175
174
  apiToken: process.env[ENV_KEYS.JENKINS_API_TOKEN] ?? globalConfig.jenkins?.apiToken
176
175
  },
177
- udeploy: {
178
- baseUrl: process.env[ENV_KEYS.UDEPLOY_BASE_URL] ?? globalConfig.udeploy?.baseUrl,
179
- pat: process.env[ENV_KEYS.UDEPLOY_PAT] ?? globalConfig.udeploy?.pat,
180
- username: process.env[ENV_KEYS.UDEPLOY_USERNAME] ?? globalConfig.udeploy?.username,
181
- password: process.env[ENV_KEYS.UDEPLOY_PASSWORD] ?? globalConfig.udeploy?.password
182
- },
176
+ jenkinsInstances: Array.isArray(globalConfig.jenkinsInstances) ? globalConfig.jenkinsInstances : [],
183
177
  checkmarx: {
184
178
  baseUrl: process.env[ENV_KEYS.CHECKMARX_BASE_URL] ?? globalConfig.checkmarx?.baseUrl,
185
179
  tenantName: process.env[ENV_KEYS.CHECKMARX_TENANT_NAME] ?? globalConfig.checkmarx?.tenantName,
@@ -219,9 +213,22 @@ function loadConfig(opts = {}) {
219
213
  baseUrl: process.env[ENV_KEYS.LOGSCALE_BASE_URL] ?? globalConfig.logscale?.baseUrl,
220
214
  token: process.env[ENV_KEYS.LOGSCALE_TOKEN] ?? globalConfig.logscale?.token
221
215
  },
216
+ splitio: {
217
+ baseUrl: process.env[ENV_KEYS.SPLITIO_BASE_URL] ?? globalConfig.splitio?.baseUrl,
218
+ adminApiKey: process.env[ENV_KEYS.SPLITIO_ADMIN_API_KEY] ?? globalConfig.splitio?.adminApiKey
219
+ },
220
+ figma: {
221
+ baseUrl: process.env[ENV_KEYS.FIGMA_BASE_URL] ?? globalConfig.figma?.baseUrl,
222
+ token: process.env[ENV_KEYS.FIGMA_TOKEN] ?? globalConfig.figma?.token
223
+ },
222
224
  defaults: mergedDefaults
223
225
  };
224
226
  }
227
+ function normalizeBaseUrl(raw) {
228
+ const trimmed = raw.trim();
229
+ if (!trimmed) return trimmed;
230
+ return /^https?:\/\//i.test(trimmed) ? trimmed : `https://${trimmed}`;
231
+ }
225
232
  function writeGlobalConfig(config, configPath) {
226
233
  const filePath = getGlobalConfigPath(configPath);
227
234
  const dir = path.dirname(filePath);
@@ -317,11 +324,10 @@ function maskConfig(config) {
317
324
  ...config.jenkins,
318
325
  apiToken: config.jenkins.apiToken ? "***" : void 0
319
326
  },
320
- udeploy: {
321
- ...config.udeploy,
322
- pat: config.udeploy.pat ? "***" : void 0,
323
- password: config.udeploy.password ? "***" : void 0
324
- },
327
+ jenkinsInstances: config.jenkinsInstances.map((inst) => ({
328
+ ...inst,
329
+ apiToken: inst.apiToken ? "***" : void 0
330
+ })),
325
331
  checkmarx: {
326
332
  ...config.checkmarx,
327
333
  apiKey: config.checkmarx.apiKey ? "***" : void 0,
@@ -353,6 +359,14 @@ function maskConfig(config) {
353
359
  logscale: {
354
360
  ...config.logscale,
355
361
  token: config.logscale.token ? "***" : void 0
362
+ },
363
+ splitio: {
364
+ ...config.splitio,
365
+ adminApiKey: config.splitio.adminApiKey ? "***" : void 0
366
+ },
367
+ figma: {
368
+ ...config.figma,
369
+ token: config.figma.token ? "***" : void 0
356
370
  }
357
371
  };
358
372
  }
@@ -361,10 +375,11 @@ export {
361
375
  getGlobalConfigPath,
362
376
  loadJsonFile,
363
377
  loadConfig,
378
+ normalizeBaseUrl,
364
379
  writeGlobalConfig,
365
380
  writeRepoConfig,
366
381
  setConfigValue,
367
382
  setRepoConfigValue,
368
383
  maskConfig
369
384
  };
370
- //# sourceMappingURL=chunk-JOAWUILY.js.map
385
+ //# sourceMappingURL=chunk-PXKUQPPF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/config.ts"],"sourcesContent":["import fs from 'fs';\nimport os from 'os';\nimport path from 'path';\nimport { execSync } from 'child_process';\nimport type { GlobalConfig, RepoConfig, ResolvedConfig, JiraDefaults, BitbucketDefaults, GitHubDefaults, SonarDefaults, SdeDefaults, AdoDefaults, JenkinsDefaults, JenkinsInstanceConfig } from '../types/config.js';\nimport type { CustomFieldDefinition } from '../types/jira.js';\n\nconst ENV_KEYS = {\n EMAIL: 'PNCLI_EMAIL',\n USERID: 'PNCLI_USERID',\n JIRA_BASE_URL: 'PNCLI_JIRA_BASE_URL',\n JIRA_API_TOKEN: 'PNCLI_JIRA_API_TOKEN',\n BITBUCKET_BASE_URL: 'PNCLI_BITBUCKET_BASE_URL',\n BITBUCKET_PAT: 'PNCLI_BITBUCKET_PAT',\n GITHUB_BASE_URL: 'PNCLI_GITHUB_BASE_URL',\n GITHUB_TOKEN: 'PNCLI_GITHUB_TOKEN',\n // Well-known vars CI platforms provide without any pncli-specific setup.\n GITHUB_TOKEN_FALLBACK: 'GITHUB_TOKEN',\n GITHUB_API_URL_FALLBACK: 'GITHUB_API_URL',\n CONFLUENCE_BASE_URL: 'PNCLI_CONFLUENCE_BASE_URL',\n CONFLUENCE_API_TOKEN: 'PNCLI_CONFLUENCE_API_TOKEN',\n ARTIFACTORY_BASE_URL: 'PNCLI_ARTIFACTORY_BASE_URL',\n ARTIFACTORY_TOKEN: 'PNCLI_ARTIFACTORY_TOKEN',\n ARTIFACTORY_REPO_NPM: 'PNCLI_ARTIFACTORY_REPO_NPM',\n ARTIFACTORY_REPO_NUGET: 'PNCLI_ARTIFACTORY_REPO_NUGET',\n ARTIFACTORY_REPO_MAVEN: 'PNCLI_ARTIFACTORY_REPO_MAVEN',\n SONAR_BASE_URL: 'PNCLI_SONAR_BASE_URL',\n SONAR_TOKEN: 'PNCLI_SONAR_TOKEN',\n // SonarSource's own scanner CLI standard var name — see the comment above GITHUB_TOKEN_FALLBACK.\n SONAR_TOKEN_FALLBACK: 'SONAR_TOKEN',\n SDE_CONNECTION: 'PNCLI_SDE_CONNECTION',\n ADO_BASE_URL: 'PNCLI_ADO_BASE_URL',\n ADO_PAT: 'PNCLI_ADO_PAT',\n // Azure Pipelines' conventional name for $(System.AccessToken) — see the comment above GITHUB_TOKEN_FALLBACK.\n ADO_PAT_FALLBACK: 'SYSTEM_ACCESSTOKEN',\n JENKINS_BASE_URL: 'PNCLI_JENKINS_BASE_URL',\n JENKINS_USERNAME: 'PNCLI_JENKINS_USERNAME',\n JENKINS_API_TOKEN: 'PNCLI_JENKINS_API_TOKEN',\n CHECKMARX_BASE_URL: 'PNCLI_CHECKMARX_BASE_URL',\n CHECKMARX_TENANT_NAME: 'PNCLI_CHECKMARX_TENANT_NAME',\n CHECKMARX_API_KEY: 'PNCLI_CHECKMARX_API_KEY',\n CHECKMARX_CLIENT_ID: 'PNCLI_CHECKMARX_CLIENT_ID',\n CHECKMARX_CLIENT_SECRET: 'PNCLI_CHECKMARX_CLIENT_SECRET',\n SERVICENOW_BASE_URL: 'PNCLI_SERVICENOW_BASE_URL',\n SERVICENOW_USERNAME: 'PNCLI_SERVICENOW_USERNAME',\n SERVICENOW_PASSWORD: 'PNCLI_SERVICENOW_PASSWORD',\n SERVICENOW_API_TOKEN: 'PNCLI_SERVICENOW_API_TOKEN',\n CONTRAST_BASE_URL: 'PNCLI_CONTRAST_BASE_URL',\n CONTRAST_ORG_UUID: 'PNCLI_CONTRAST_ORG_UUID',\n CONTRAST_API_KEY: 'PNCLI_CONTRAST_API_KEY',\n CONTRAST_SERVICE_KEY: 'PNCLI_CONTRAST_SERVICE_KEY',\n CONTRAST_USERNAME: 'PNCLI_CONTRAST_USERNAME',\n SONATYPEIQ_BASE_URL: 'PNCLI_SONATYPEIQ_BASE_URL',\n SONATYPEIQ_USER_CODE: 'PNCLI_SONATYPEIQ_USER_CODE',\n SONATYPEIQ_PASSCODE: 'PNCLI_SONATYPEIQ_PASSCODE',\n OPENSHIFT_BASE_URL: 'PNCLI_OPENSHIFT_BASE_URL',\n OPENSHIFT_TOKEN: 'PNCLI_OPENSHIFT_TOKEN',\n DYNATRACE_BASE_URL: 'PNCLI_DYNATRACE_BASE_URL',\n DYNATRACE_API_TOKEN: 'PNCLI_DYNATRACE_API_TOKEN',\n DYNATRACE_PLATFORM_URL: 'PNCLI_DYNATRACE_PLATFORM_URL',\n DYNATRACE_PLATFORM_TOKEN: 'PNCLI_DYNATRACE_PLATFORM_TOKEN',\n LOGSCALE_BASE_URL: 'PNCLI_LOGSCALE_BASE_URL',\n LOGSCALE_TOKEN: 'PNCLI_LOGSCALE_TOKEN',\n SPLITIO_BASE_URL: 'PNCLI_SPLITIO_BASE_URL',\n SPLITIO_ADMIN_API_KEY: 'PNCLI_SPLITIO_ADMIN_API_KEY',\n FIGMA_BASE_URL: 'PNCLI_FIGMA_BASE_URL',\n FIGMA_TOKEN: 'PNCLI_FIGMA_TOKEN',\n CONFIG_PATH: 'PNCLI_CONFIG_PATH'\n} as const;\n\nfunction getGlobalConfigPath(overridePath?: string): string {\n if (overridePath) return overridePath;\n const envPath = process.env[ENV_KEYS.CONFIG_PATH];\n if (envPath) return envPath;\n return path.join(os.homedir(), '.pncli', 'config.json');\n}\n\nfunction loadJsonFile<T>(filePath: string): T | null {\n try {\n const content = fs.readFileSync(filePath, 'utf8');\n return JSON.parse(content) as T;\n } catch {\n return null;\n }\n}\n\nfunction getRepoRoot(): string | null {\n try {\n return execSync('git rev-parse --show-toplevel', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();\n } catch {\n return null;\n }\n}\n\nfunction parseSdeConnection(connection: string): { token: string; baseUrl: string } | null {\n const idx = connection.indexOf('@');\n if (idx <= 0) return null;\n const token = connection.slice(0, idx);\n const host = connection.slice(idx + 1);\n const baseUrl = /^https?:\\/\\//i.test(host) ? host : `https://${host}`;\n return { token, baseUrl };\n}\n\nfunction mergeCustomFields(\n global: CustomFieldDefinition[] | undefined,\n repo: CustomFieldDefinition[] | undefined\n): CustomFieldDefinition[] {\n const map = new Map<string, CustomFieldDefinition>();\n for (const f of global ?? []) map.set(f.id, f);\n for (const f of repo ?? []) map.set(f.id, f); // repo wins\n return Array.from(map.values());\n}\n\nfunction mergeDefaults(\n global: GlobalConfig['defaults'],\n repo: RepoConfig['defaults']\n): { jira: JiraDefaults; bitbucket: BitbucketDefaults; github: GitHubDefaults; sonar: SonarDefaults; sde: SdeDefaults; ado: AdoDefaults; jenkins: JenkinsDefaults } {\n return {\n jira: { ...global?.jira, ...repo?.jira },\n bitbucket: { ...global?.bitbucket, ...repo?.bitbucket },\n github: { ...global?.github, ...repo?.github },\n sonar: { ...global?.sonar, ...repo?.sonar },\n sde: { ...global?.sde, ...repo?.sde },\n ado: { ...global?.ado, ...repo?.ado },\n jenkins: { ...global?.jenkins, ...repo?.jenkins }\n };\n}\n\nexport interface LoadConfigOptions {\n configPath?: string;\n}\n\nexport function loadConfig(opts: LoadConfigOptions = {}): ResolvedConfig {\n const globalConfigPath = getGlobalConfigPath(opts.configPath);\n const globalConfig = loadJsonFile<GlobalConfig>(globalConfigPath) ?? {};\n\n const repoRoot = getRepoRoot();\n let repoConfig: RepoConfig = {};\n if (repoRoot) {\n repoConfig = loadJsonFile<RepoConfig>(path.join(repoRoot, '.pncli.json')) ?? {};\n }\n\n const mergedDefaults = mergeDefaults(globalConfig.defaults, repoConfig.defaults);\n\n return {\n user: {\n email: process.env[ENV_KEYS.EMAIL] ?? globalConfig.user?.email,\n userId: process.env[ENV_KEYS.USERID] ?? globalConfig.user?.userId\n },\n jira: {\n baseUrl: process.env[ENV_KEYS.JIRA_BASE_URL] ?? globalConfig.jira?.baseUrl,\n apiToken: process.env[ENV_KEYS.JIRA_API_TOKEN] ?? globalConfig.jira?.apiToken,\n customFields: mergeCustomFields(globalConfig.jira?.customFields, repoConfig.jira?.customFields)\n },\n bitbucket: {\n baseUrl: process.env[ENV_KEYS.BITBUCKET_BASE_URL] ?? globalConfig.bitbucket?.baseUrl,\n pat: process.env[ENV_KEYS.BITBUCKET_PAT] ?? globalConfig.bitbucket?.pat\n },\n github: {\n baseUrl: process.env[ENV_KEYS.GITHUB_BASE_URL] ?? process.env[ENV_KEYS.GITHUB_API_URL_FALLBACK] ?? globalConfig.github?.baseUrl,\n token: process.env[ENV_KEYS.GITHUB_TOKEN] ?? process.env[ENV_KEYS.GITHUB_TOKEN_FALLBACK] ?? globalConfig.github?.token\n },\n confluence: {\n baseUrl: process.env[ENV_KEYS.CONFLUENCE_BASE_URL] ?? globalConfig.confluence?.baseUrl,\n apiToken: process.env[ENV_KEYS.CONFLUENCE_API_TOKEN] ?? globalConfig.confluence?.apiToken\n ?? process.env[ENV_KEYS.JIRA_API_TOKEN] ?? globalConfig.jira?.apiToken,\n apiTokenExplicit: !!(\n process.env[ENV_KEYS.CONFLUENCE_API_TOKEN] ?? globalConfig.confluence?.apiToken\n )\n },\n artifactory: {\n baseUrl: process.env[ENV_KEYS.ARTIFACTORY_BASE_URL] ?? globalConfig.artifactory?.baseUrl,\n token: process.env[ENV_KEYS.ARTIFACTORY_TOKEN] ?? globalConfig.artifactory?.token,\n npmRepo: process.env[ENV_KEYS.ARTIFACTORY_REPO_NPM] ?? globalConfig.artifactory?.npmRepo,\n nugetRepo: process.env[ENV_KEYS.ARTIFACTORY_REPO_NUGET] ?? globalConfig.artifactory?.nugetRepo,\n mavenRepo: process.env[ENV_KEYS.ARTIFACTORY_REPO_MAVEN] ?? globalConfig.artifactory?.mavenRepo\n },\n sonar: {\n baseUrl: process.env[ENV_KEYS.SONAR_BASE_URL] ?? globalConfig.sonar?.baseUrl,\n token: process.env[ENV_KEYS.SONAR_TOKEN] ?? process.env[ENV_KEYS.SONAR_TOKEN_FALLBACK] ?? globalConfig.sonar?.token\n },\n sde: (() => {\n const raw = process.env[ENV_KEYS.SDE_CONNECTION] ?? globalConfig.sde?.connection;\n const parsed = raw ? parseSdeConnection(raw) : null;\n return { baseUrl: parsed?.baseUrl, token: parsed?.token };\n })(),\n ado: {\n baseUrl: process.env[ENV_KEYS.ADO_BASE_URL] ?? globalConfig.ado?.baseUrl,\n pat: process.env[ENV_KEYS.ADO_PAT] ?? process.env[ENV_KEYS.ADO_PAT_FALLBACK] ?? globalConfig.ado?.pat,\n fieldAliases: globalConfig.ado?.fieldAliases ?? {},\n discoveredFields: globalConfig.ado?.discoveredFields ?? [],\n discoveredTypes: globalConfig.ado?.discoveredTypes ?? []\n },\n jenkins: {\n baseUrl: repoConfig.defaults?.jenkins?.baseUrl ?? process.env[ENV_KEYS.JENKINS_BASE_URL] ?? globalConfig.jenkins?.baseUrl,\n username: process.env[ENV_KEYS.JENKINS_USERNAME] ?? globalConfig.jenkins?.username,\n apiToken: process.env[ENV_KEYS.JENKINS_API_TOKEN] ?? globalConfig.jenkins?.apiToken\n },\n jenkinsInstances: (Array.isArray(globalConfig.jenkinsInstances) ? globalConfig.jenkinsInstances : []) as JenkinsInstanceConfig[],\n checkmarx: {\n baseUrl: process.env[ENV_KEYS.CHECKMARX_BASE_URL] ?? globalConfig.checkmarx?.baseUrl,\n tenantName: process.env[ENV_KEYS.CHECKMARX_TENANT_NAME] ?? globalConfig.checkmarx?.tenantName,\n apiKey: process.env[ENV_KEYS.CHECKMARX_API_KEY] ?? globalConfig.checkmarx?.apiKey,\n clientId: process.env[ENV_KEYS.CHECKMARX_CLIENT_ID] ?? globalConfig.checkmarx?.clientId,\n clientSecret: process.env[ENV_KEYS.CHECKMARX_CLIENT_SECRET] ?? globalConfig.checkmarx?.clientSecret,\n },\n servicenow: {\n baseUrl: process.env[ENV_KEYS.SERVICENOW_BASE_URL] ?? globalConfig.servicenow?.baseUrl,\n username: process.env[ENV_KEYS.SERVICENOW_USERNAME] ?? globalConfig.servicenow?.username,\n password: process.env[ENV_KEYS.SERVICENOW_PASSWORD] ?? globalConfig.servicenow?.password,\n apiToken: process.env[ENV_KEYS.SERVICENOW_API_TOKEN] ?? globalConfig.servicenow?.apiToken,\n },\n contrast: {\n baseUrl: process.env[ENV_KEYS.CONTRAST_BASE_URL] ?? globalConfig.contrast?.baseUrl,\n orgUuid: process.env[ENV_KEYS.CONTRAST_ORG_UUID] ?? globalConfig.contrast?.orgUuid,\n apiKey: process.env[ENV_KEYS.CONTRAST_API_KEY] ?? globalConfig.contrast?.apiKey,\n serviceKey: process.env[ENV_KEYS.CONTRAST_SERVICE_KEY] ?? globalConfig.contrast?.serviceKey,\n username: process.env[ENV_KEYS.CONTRAST_USERNAME] ?? globalConfig.contrast?.username,\n },\n sonatypeiq: {\n baseUrl: process.env[ENV_KEYS.SONATYPEIQ_BASE_URL] ?? globalConfig.sonatypeiq?.baseUrl,\n userCode: process.env[ENV_KEYS.SONATYPEIQ_USER_CODE] ?? globalConfig.sonatypeiq?.userCode,\n passcode: process.env[ENV_KEYS.SONATYPEIQ_PASSCODE] ?? globalConfig.sonatypeiq?.passcode,\n },\n openshift: {\n baseUrl: process.env[ENV_KEYS.OPENSHIFT_BASE_URL] ?? globalConfig.openshift?.baseUrl,\n token: process.env[ENV_KEYS.OPENSHIFT_TOKEN] ?? globalConfig.openshift?.token,\n },\n 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 },\n logscale: {\n baseUrl: process.env[ENV_KEYS.LOGSCALE_BASE_URL] ?? globalConfig.logscale?.baseUrl,\n token: process.env[ENV_KEYS.LOGSCALE_TOKEN] ?? globalConfig.logscale?.token,\n },\n splitio: {\n baseUrl: process.env[ENV_KEYS.SPLITIO_BASE_URL] ?? globalConfig.splitio?.baseUrl,\n adminApiKey: process.env[ENV_KEYS.SPLITIO_ADMIN_API_KEY] ?? globalConfig.splitio?.adminApiKey,\n },\n figma: {\n baseUrl: process.env[ENV_KEYS.FIGMA_BASE_URL] ?? globalConfig.figma?.baseUrl,\n token: process.env[ENV_KEYS.FIGMA_TOKEN] ?? globalConfig.figma?.token,\n },\n defaults: mergedDefaults\n };\n}\n\nexport function normalizeBaseUrl(raw: string): string {\n const trimmed = raw.trim();\n if (!trimmed) return trimmed;\n return /^https?:\\/\\//i.test(trimmed) ? trimmed : `https://${trimmed}`;\n}\n\nexport function writeGlobalConfig(config: GlobalConfig, configPath?: string): void {\n const filePath = getGlobalConfigPath(configPath);\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(filePath, JSON.stringify(config, null, 2) + '\\n', 'utf8');\n}\n\nexport function writeRepoConfig(config: RepoConfig): void {\n const repoRoot = getRepoRoot();\n const targetDir = repoRoot ?? process.cwd();\n fs.writeFileSync(path.join(targetDir, '.pncli.json'), JSON.stringify(config, null, 2) + '\\n', 'utf8');\n}\n\nfunction parseConfigValue(value: string): unknown {\n try {\n const parsed = JSON.parse(value);\n if (typeof parsed === 'object' && parsed !== null) {\n return parsed;\n }\n } catch {\n // not valid JSON — fall through to raw string\n }\n return value;\n}\n\nexport function setConfigValue(key: string, value: string, configPath?: string): void {\n const filePath = getGlobalConfigPath(configPath);\n const existing = loadJsonFile<GlobalConfig>(filePath) ?? {};\n\n const parts = key.split('.');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let current: any = existing;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]!;\n if (typeof current[part] !== 'object' || current[part] === null) {\n current[part] = {};\n }\n current = current[part];\n }\n current[parts[parts.length - 1]!] = parseConfigValue(value);\n\n writeGlobalConfig(existing, configPath);\n}\n\nexport function setRepoConfigValue(key: string, value: string): void {\n const repoRoot = getRepoRoot();\n const targetDir = repoRoot ?? process.cwd();\n const filePath = path.join(targetDir, '.pncli.json');\n const existing = loadJsonFile<RepoConfig>(filePath) ?? {};\n\n const parts = key.split('.');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n let current: any = existing;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i]!;\n if (typeof current[part] !== 'object' || current[part] === null) {\n current[part] = {};\n }\n current = current[part];\n }\n current[parts[parts.length - 1]!] = parseConfigValue(value);\n\n writeRepoConfig(existing);\n}\n\nexport function maskConfig(config: ResolvedConfig): unknown {\n return {\n ...config,\n jira: {\n ...config.jira,\n apiToken: config.jira.apiToken ? '***' : undefined,\n customFields: config.jira.customFields\n },\n bitbucket: {\n ...config.bitbucket,\n pat: config.bitbucket.pat ? '***' : undefined\n },\n github: {\n ...config.github,\n token: config.github.token ? '***' : undefined\n },\n confluence: {\n ...config.confluence,\n apiToken: config.confluence.apiToken ? '***' : undefined\n },\n artifactory: {\n ...config.artifactory,\n token: config.artifactory.token ? '***' : undefined\n },\n sonar: {\n ...config.sonar,\n token: config.sonar.token ? '***' : undefined\n },\n sde: {\n baseUrl: config.sde.baseUrl,\n token: config.sde.token ? '***' : undefined\n },\n ado: {\n ...config.ado,\n pat: config.ado.pat ? '***' : undefined\n },\n jenkins: {\n ...config.jenkins,\n apiToken: config.jenkins.apiToken ? '***' : undefined\n },\n jenkinsInstances: config.jenkinsInstances.map(inst => ({\n ...inst,\n apiToken: inst.apiToken ? '***' : undefined\n })),\n checkmarx: {\n ...config.checkmarx,\n apiKey: config.checkmarx.apiKey ? '***' : undefined,\n clientSecret: config.checkmarx.clientSecret ? '***' : undefined\n },\n servicenow: {\n ...config.servicenow,\n password: config.servicenow.password ? '***' : undefined,\n apiToken: config.servicenow.apiToken ? '***' : undefined\n },\n contrast: {\n ...config.contrast,\n apiKey: config.contrast.apiKey ? '***' : undefined,\n serviceKey: config.contrast.serviceKey ? '***' : undefined\n },\n sonatypeiq: {\n ...config.sonatypeiq,\n passcode: config.sonatypeiq.passcode ? '***' : undefined\n },\n openshift: {\n ...config.openshift,\n token: config.openshift.token ? '***' : undefined\n },\n dynatrace: {\n ...config.dynatrace,\n apiToken: config.dynatrace.apiToken ? '***' : undefined,\n platformToken: config.dynatrace.platformToken ? '***' : undefined\n },\n logscale: {\n ...config.logscale,\n token: config.logscale.token ? '***' : undefined\n },\n splitio: {\n ...config.splitio,\n adminApiKey: config.splitio.adminApiKey ? '***' : undefined\n },\n figma: {\n ...config.figma,\n token: config.figma.token ? '***' : undefined\n }\n };\n}\n\nexport { getGlobalConfigPath, loadJsonFile };\n"],"mappings":";;;AAAA,OAAO,QAAQ;AACf,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,gBAAgB;AAIzB,IAAM,WAAW;AAAA,EACf,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,oBAAoB;AAAA,EACpB,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,cAAc;AAAA;AAAA,EAEd,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,gBAAgB;AAAA,EAChB,aAAa;AAAA;AAAA,EAEb,sBAAsB;AAAA,EACtB,gBAAgB;AAAA,EAChB,cAAc;AAAA,EACd,SAAS;AAAA;AAAA,EAET,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,yBAAyB;AAAA,EACzB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,sBAAsB;AAAA,EACtB,mBAAmB;AAAA,EACnB,qBAAqB;AAAA,EACrB,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,iBAAiB;AAAA,EACjB,oBAAoB;AAAA,EACpB,qBAAqB;AAAA,EACrB,wBAAwB;AAAA,EACxB,0BAA0B;AAAA,EAC1B,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,aAAa;AACf;AAEA,SAAS,oBAAoB,cAA+B;AAC1D,MAAI,aAAc,QAAO;AACzB,QAAM,UAAU,QAAQ,IAAI,SAAS,WAAW;AAChD,MAAI,QAAS,QAAO;AACpB,SAAO,KAAK,KAAK,GAAG,QAAQ,GAAG,UAAU,aAAa;AACxD;AAEA,SAAS,aAAgB,UAA4B;AACnD,MAAI;AACF,UAAM,UAAU,GAAG,aAAa,UAAU,MAAM;AAChD,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,cAA6B;AACpC,MAAI;AACF,WAAO,SAAS,iCAAiC,EAAE,UAAU,QAAQ,OAAO,CAAC,QAAQ,QAAQ,MAAM,EAAE,CAAC,EAAE,KAAK;AAAA,EAC/G,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,mBAAmB,YAA+D;AACzF,QAAM,MAAM,WAAW,QAAQ,GAAG;AAClC,MAAI,OAAO,EAAG,QAAO;AACrB,QAAM,QAAQ,WAAW,MAAM,GAAG,GAAG;AACrC,QAAM,OAAO,WAAW,MAAM,MAAM,CAAC;AACrC,QAAM,UAAU,gBAAgB,KAAK,IAAI,IAAI,OAAO,WAAW,IAAI;AACnE,SAAO,EAAE,OAAO,QAAQ;AAC1B;AAEA,SAAS,kBACP,QACA,MACyB;AACzB,QAAM,MAAM,oBAAI,IAAmC;AACnD,aAAW,KAAK,UAAU,CAAC,EAAG,KAAI,IAAI,EAAE,IAAI,CAAC;AAC7C,aAAW,KAAK,QAAQ,CAAC,EAAG,KAAI,IAAI,EAAE,IAAI,CAAC;AAC3C,SAAO,MAAM,KAAK,IAAI,OAAO,CAAC;AAChC;AAEA,SAAS,cACP,QACA,MACkK;AAClK,SAAO;AAAA,IACL,MAAM,EAAE,GAAG,QAAQ,MAAM,GAAG,MAAM,KAAK;AAAA,IACvC,WAAW,EAAE,GAAG,QAAQ,WAAW,GAAG,MAAM,UAAU;AAAA,IACtD,QAAQ,EAAE,GAAG,QAAQ,QAAQ,GAAG,MAAM,OAAO;AAAA,IAC7C,OAAO,EAAE,GAAG,QAAQ,OAAO,GAAG,MAAM,MAAM;AAAA,IAC1C,KAAK,EAAE,GAAG,QAAQ,KAAK,GAAG,MAAM,IAAI;AAAA,IACpC,KAAK,EAAE,GAAG,QAAQ,KAAK,GAAG,MAAM,IAAI;AAAA,IACpC,SAAS,EAAE,GAAG,QAAQ,SAAS,GAAG,MAAM,QAAQ;AAAA,EAClD;AACF;AAMO,SAAS,WAAW,OAA0B,CAAC,GAAmB;AACvE,QAAM,mBAAmB,oBAAoB,KAAK,UAAU;AAC5D,QAAM,eAAe,aAA2B,gBAAgB,KAAK,CAAC;AAEtE,QAAM,WAAW,YAAY;AAC7B,MAAI,aAAyB,CAAC;AAC9B,MAAI,UAAU;AACZ,iBAAa,aAAyB,KAAK,KAAK,UAAU,aAAa,CAAC,KAAK,CAAC;AAAA,EAChF;AAEA,QAAM,iBAAiB,cAAc,aAAa,UAAU,WAAW,QAAQ;AAE/E,SAAO;AAAA,IACL,MAAM;AAAA,MACJ,OAAO,QAAQ,IAAI,SAAS,KAAK,KAAK,aAAa,MAAM;AAAA,MACzD,QAAQ,QAAQ,IAAI,SAAS,MAAM,KAAK,aAAa,MAAM;AAAA,IAC7D;AAAA,IACA,MAAM;AAAA,MACJ,SAAS,QAAQ,IAAI,SAAS,aAAa,KAAK,aAAa,MAAM;AAAA,MACnE,UAAU,QAAQ,IAAI,SAAS,cAAc,KAAK,aAAa,MAAM;AAAA,MACrE,cAAc,kBAAkB,aAAa,MAAM,cAAc,WAAW,MAAM,YAAY;AAAA,IAChG;AAAA,IACA,WAAW;AAAA,MACT,SAAS,QAAQ,IAAI,SAAS,kBAAkB,KAAK,aAAa,WAAW;AAAA,MAC7E,KAAK,QAAQ,IAAI,SAAS,aAAa,KAAK,aAAa,WAAW;AAAA,IACtE;AAAA,IACA,QAAQ;AAAA,MACN,SAAS,QAAQ,IAAI,SAAS,eAAe,KAAK,QAAQ,IAAI,SAAS,uBAAuB,KAAK,aAAa,QAAQ;AAAA,MACxH,OAAO,QAAQ,IAAI,SAAS,YAAY,KAAK,QAAQ,IAAI,SAAS,qBAAqB,KAAK,aAAa,QAAQ;AAAA,IACnH;AAAA,IACA,YAAY;AAAA,MACV,SAAS,QAAQ,IAAI,SAAS,mBAAmB,KAAK,aAAa,YAAY;AAAA,MAC/E,UAAU,QAAQ,IAAI,SAAS,oBAAoB,KAAK,aAAa,YAAY,YAC5E,QAAQ,IAAI,SAAS,cAAc,KAAK,aAAa,MAAM;AAAA,MAChE,kBAAkB,CAAC,EACjB,QAAQ,IAAI,SAAS,oBAAoB,KAAK,aAAa,YAAY;AAAA,IAE3E;AAAA,IACA,aAAa;AAAA,MACX,SAAS,QAAQ,IAAI,SAAS,oBAAoB,KAAK,aAAa,aAAa;AAAA,MACjF,OAAO,QAAQ,IAAI,SAAS,iBAAiB,KAAK,aAAa,aAAa;AAAA,MAC5E,SAAS,QAAQ,IAAI,SAAS,oBAAoB,KAAK,aAAa,aAAa;AAAA,MACjF,WAAW,QAAQ,IAAI,SAAS,sBAAsB,KAAK,aAAa,aAAa;AAAA,MACrF,WAAW,QAAQ,IAAI,SAAS,sBAAsB,KAAK,aAAa,aAAa;AAAA,IACvF;AAAA,IACA,OAAO;AAAA,MACL,SAAS,QAAQ,IAAI,SAAS,cAAc,KAAK,aAAa,OAAO;AAAA,MACrE,OAAO,QAAQ,IAAI,SAAS,WAAW,KAAK,QAAQ,IAAI,SAAS,oBAAoB,KAAK,aAAa,OAAO;AAAA,IAChH;AAAA,IACA,MAAM,MAAM;AACV,YAAM,MAAM,QAAQ,IAAI,SAAS,cAAc,KAAK,aAAa,KAAK;AACtE,YAAM,SAAS,MAAM,mBAAmB,GAAG,IAAI;AAC/C,aAAO,EAAE,SAAS,QAAQ,SAAS,OAAO,QAAQ,MAAM;AAAA,IAC1D,GAAG;AAAA,IACH,KAAK;AAAA,MACH,SAAS,QAAQ,IAAI,SAAS,YAAY,KAAK,aAAa,KAAK;AAAA,MACjE,KAAK,QAAQ,IAAI,SAAS,OAAO,KAAK,QAAQ,IAAI,SAAS,gBAAgB,KAAK,aAAa,KAAK;AAAA,MAClG,cAAc,aAAa,KAAK,gBAAgB,CAAC;AAAA,MACjD,kBAAkB,aAAa,KAAK,oBAAoB,CAAC;AAAA,MACzD,iBAAiB,aAAa,KAAK,mBAAmB,CAAC;AAAA,IACzD;AAAA,IACA,SAAS;AAAA,MACP,SAAS,WAAW,UAAU,SAAS,WAAW,QAAQ,IAAI,SAAS,gBAAgB,KAAK,aAAa,SAAS;AAAA,MAClH,UAAU,QAAQ,IAAI,SAAS,gBAAgB,KAAK,aAAa,SAAS;AAAA,MAC1E,UAAU,QAAQ,IAAI,SAAS,iBAAiB,KAAK,aAAa,SAAS;AAAA,IAC7E;AAAA,IACA,kBAAmB,MAAM,QAAQ,aAAa,gBAAgB,IAAI,aAAa,mBAAmB,CAAC;AAAA,IACnG,WAAW;AAAA,MACT,SAAS,QAAQ,IAAI,SAAS,kBAAkB,KAAK,aAAa,WAAW;AAAA,MAC7E,YAAY,QAAQ,IAAI,SAAS,qBAAqB,KAAK,aAAa,WAAW;AAAA,MACnF,QAAQ,QAAQ,IAAI,SAAS,iBAAiB,KAAK,aAAa,WAAW;AAAA,MAC3E,UAAU,QAAQ,IAAI,SAAS,mBAAmB,KAAK,aAAa,WAAW;AAAA,MAC/E,cAAc,QAAQ,IAAI,SAAS,uBAAuB,KAAK,aAAa,WAAW;AAAA,IACzF;AAAA,IACA,YAAY;AAAA,MACV,SAAS,QAAQ,IAAI,SAAS,mBAAmB,KAAK,aAAa,YAAY;AAAA,MAC/E,UAAU,QAAQ,IAAI,SAAS,mBAAmB,KAAK,aAAa,YAAY;AAAA,MAChF,UAAU,QAAQ,IAAI,SAAS,mBAAmB,KAAK,aAAa,YAAY;AAAA,MAChF,UAAU,QAAQ,IAAI,SAAS,oBAAoB,KAAK,aAAa,YAAY;AAAA,IACnF;AAAA,IACA,UAAU;AAAA,MACR,SAAS,QAAQ,IAAI,SAAS,iBAAiB,KAAK,aAAa,UAAU;AAAA,MAC3E,SAAS,QAAQ,IAAI,SAAS,iBAAiB,KAAK,aAAa,UAAU;AAAA,MAC3E,QAAQ,QAAQ,IAAI,SAAS,gBAAgB,KAAK,aAAa,UAAU;AAAA,MACzE,YAAY,QAAQ,IAAI,SAAS,oBAAoB,KAAK,aAAa,UAAU;AAAA,MACjF,UAAU,QAAQ,IAAI,SAAS,iBAAiB,KAAK,aAAa,UAAU;AAAA,IAC9E;AAAA,IACA,YAAY;AAAA,MACV,SAAS,QAAQ,IAAI,SAAS,mBAAmB,KAAK,aAAa,YAAY;AAAA,MAC/E,UAAU,QAAQ,IAAI,SAAS,oBAAoB,KAAK,aAAa,YAAY;AAAA,MACjF,UAAU,QAAQ,IAAI,SAAS,mBAAmB,KAAK,aAAa,YAAY;AAAA,IAClF;AAAA,IACA,WAAW;AAAA,MACT,SAAS,QAAQ,IAAI,SAAS,kBAAkB,KAAK,aAAa,WAAW;AAAA,MAC7E,OAAO,QAAQ,IAAI,SAAS,eAAe,KAAK,aAAa,WAAW;AAAA,IAC1E;AAAA,IACA,WAAW;AAAA,MACT,SAAS,QAAQ,IAAI,SAAS,kBAAkB,KAAK,aAAa,WAAW;AAAA,MAC7E,UAAU,QAAQ,IAAI,SAAS,mBAAmB,KAAK,aAAa,WAAW;AAAA,MAC/E,aAAa,QAAQ,IAAI,SAAS,sBAAsB,KAAK,aAAa,WAAW;AAAA,MACrF,eAAe,QAAQ,IAAI,SAAS,wBAAwB,KAAK,aAAa,WAAW;AAAA,IAC3F;AAAA,IACA,UAAU;AAAA,MACR,SAAS,QAAQ,IAAI,SAAS,iBAAiB,KAAK,aAAa,UAAU;AAAA,MAC3E,OAAO,QAAQ,IAAI,SAAS,cAAc,KAAK,aAAa,UAAU;AAAA,IACxE;AAAA,IACA,SAAS;AAAA,MACP,SAAS,QAAQ,IAAI,SAAS,gBAAgB,KAAK,aAAa,SAAS;AAAA,MACzE,aAAa,QAAQ,IAAI,SAAS,qBAAqB,KAAK,aAAa,SAAS;AAAA,IACpF;AAAA,IACA,OAAO;AAAA,MACL,SAAS,QAAQ,IAAI,SAAS,cAAc,KAAK,aAAa,OAAO;AAAA,MACrE,OAAO,QAAQ,IAAI,SAAS,WAAW,KAAK,aAAa,OAAO;AAAA,IAClE;AAAA,IACA,UAAU;AAAA,EACZ;AACF;AAEO,SAAS,iBAAiB,KAAqB;AACpD,QAAM,UAAU,IAAI,KAAK;AACzB,MAAI,CAAC,QAAS,QAAO;AACrB,SAAO,gBAAgB,KAAK,OAAO,IAAI,UAAU,WAAW,OAAO;AACrE;AAEO,SAAS,kBAAkB,QAAsB,YAA2B;AACjF,QAAM,WAAW,oBAAoB,UAAU;AAC/C,QAAM,MAAM,KAAK,QAAQ,QAAQ;AACjC,MAAI,CAAC,GAAG,WAAW,GAAG,GAAG;AACvB,OAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AAAA,EACvC;AACA,KAAG,cAAc,UAAU,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,MAAM,MAAM;AAC3E;AAEO,SAAS,gBAAgB,QAA0B;AACxD,QAAM,WAAW,YAAY;AAC7B,QAAM,YAAY,YAAY,QAAQ,IAAI;AAC1C,KAAG,cAAc,KAAK,KAAK,WAAW,aAAa,GAAG,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,MAAM,MAAM;AACtG;AAEA,SAAS,iBAAiB,OAAwB;AAChD,MAAI;AACF,UAAM,SAAS,KAAK,MAAM,KAAK;AAC/B,QAAI,OAAO,WAAW,YAAY,WAAW,MAAM;AACjD,aAAO;AAAA,IACT;AAAA,EACF,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAEO,SAAS,eAAe,KAAa,OAAe,YAA2B;AACpF,QAAM,WAAW,oBAAoB,UAAU;AAC/C,QAAM,WAAW,aAA2B,QAAQ,KAAK,CAAC;AAE1D,QAAM,QAAQ,IAAI,MAAM,GAAG;AAE3B,MAAI,UAAe;AACnB,WAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,OAAO,QAAQ,IAAI,MAAM,YAAY,QAAQ,IAAI,MAAM,MAAM;AAC/D,cAAQ,IAAI,IAAI,CAAC;AAAA,IACnB;AACA,cAAU,QAAQ,IAAI;AAAA,EACxB;AACA,UAAQ,MAAM,MAAM,SAAS,CAAC,CAAE,IAAI,iBAAiB,KAAK;AAE1D,oBAAkB,UAAU,UAAU;AACxC;AAEO,SAAS,mBAAmB,KAAa,OAAqB;AACnE,QAAM,WAAW,YAAY;AAC7B,QAAM,YAAY,YAAY,QAAQ,IAAI;AAC1C,QAAM,WAAW,KAAK,KAAK,WAAW,aAAa;AACnD,QAAM,WAAW,aAAyB,QAAQ,KAAK,CAAC;AAExD,QAAM,QAAQ,IAAI,MAAM,GAAG;AAE3B,MAAI,UAAe;AACnB,WAAS,IAAI,GAAG,IAAI,MAAM,SAAS,GAAG,KAAK;AACzC,UAAM,OAAO,MAAM,CAAC;AACpB,QAAI,OAAO,QAAQ,IAAI,MAAM,YAAY,QAAQ,IAAI,MAAM,MAAM;AAC/D,cAAQ,IAAI,IAAI,CAAC;AAAA,IACnB;AACA,cAAU,QAAQ,IAAI;AAAA,EACxB;AACA,UAAQ,MAAM,MAAM,SAAS,CAAC,CAAE,IAAI,iBAAiB,KAAK;AAE1D,kBAAgB,QAAQ;AAC1B;AAEO,SAAS,WAAW,QAAiC;AAC1D,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM;AAAA,MACJ,GAAG,OAAO;AAAA,MACV,UAAU,OAAO,KAAK,WAAW,QAAQ;AAAA,MACzC,cAAc,OAAO,KAAK;AAAA,IAC5B;AAAA,IACA,WAAW;AAAA,MACT,GAAG,OAAO;AAAA,MACV,KAAK,OAAO,UAAU,MAAM,QAAQ;AAAA,IACtC;AAAA,IACA,QAAQ;AAAA,MACN,GAAG,OAAO;AAAA,MACV,OAAO,OAAO,OAAO,QAAQ,QAAQ;AAAA,IACvC;AAAA,IACA,YAAY;AAAA,MACV,GAAG,OAAO;AAAA,MACV,UAAU,OAAO,WAAW,WAAW,QAAQ;AAAA,IACjD;AAAA,IACA,aAAa;AAAA,MACX,GAAG,OAAO;AAAA,MACV,OAAO,OAAO,YAAY,QAAQ,QAAQ;AAAA,IAC5C;AAAA,IACA,OAAO;AAAA,MACL,GAAG,OAAO;AAAA,MACV,OAAO,OAAO,MAAM,QAAQ,QAAQ;AAAA,IACtC;AAAA,IACA,KAAK;AAAA,MACH,SAAS,OAAO,IAAI;AAAA,MACpB,OAAO,OAAO,IAAI,QAAQ,QAAQ;AAAA,IACpC;AAAA,IACA,KAAK;AAAA,MACH,GAAG,OAAO;AAAA,MACV,KAAK,OAAO,IAAI,MAAM,QAAQ;AAAA,IAChC;AAAA,IACA,SAAS;AAAA,MACP,GAAG,OAAO;AAAA,MACV,UAAU,OAAO,QAAQ,WAAW,QAAQ;AAAA,IAC9C;AAAA,IACA,kBAAkB,OAAO,iBAAiB,IAAI,WAAS;AAAA,MACrD,GAAG;AAAA,MACH,UAAU,KAAK,WAAW,QAAQ;AAAA,IACpC,EAAE;AAAA,IACF,WAAW;AAAA,MACT,GAAG,OAAO;AAAA,MACV,QAAQ,OAAO,UAAU,SAAS,QAAQ;AAAA,MAC1C,cAAc,OAAO,UAAU,eAAe,QAAQ;AAAA,IACxD;AAAA,IACA,YAAY;AAAA,MACV,GAAG,OAAO;AAAA,MACV,UAAU,OAAO,WAAW,WAAW,QAAQ;AAAA,MAC/C,UAAU,OAAO,WAAW,WAAW,QAAQ;AAAA,IACjD;AAAA,IACA,UAAU;AAAA,MACR,GAAG,OAAO;AAAA,MACV,QAAQ,OAAO,SAAS,SAAS,QAAQ;AAAA,MACzC,YAAY,OAAO,SAAS,aAAa,QAAQ;AAAA,IACnD;AAAA,IACA,YAAY;AAAA,MACV,GAAG,OAAO;AAAA,MACV,UAAU,OAAO,WAAW,WAAW,QAAQ;AAAA,IACjD;AAAA,IACA,WAAW;AAAA,MACT,GAAG,OAAO;AAAA,MACV,OAAO,OAAO,UAAU,QAAQ,QAAQ;AAAA,IAC1C;AAAA,IACA,WAAW;AAAA,MACT,GAAG,OAAO;AAAA,MACV,UAAU,OAAO,UAAU,WAAW,QAAQ;AAAA,MAC9C,eAAe,OAAO,UAAU,gBAAgB,QAAQ;AAAA,IAC1D;AAAA,IACA,UAAU;AAAA,MACR,GAAG,OAAO;AAAA,MACV,OAAO,OAAO,SAAS,QAAQ,QAAQ;AAAA,IACzC;AAAA,IACA,SAAS;AAAA,MACP,GAAG,OAAO;AAAA,MACV,aAAa,OAAO,QAAQ,cAAc,QAAQ;AAAA,IACpD;AAAA,IACA,OAAO;AAAA,MACL,GAAG,OAAO;AAAA,MACV,OAAO,OAAO,MAAM,QAAQ,QAAQ;AAAA,IACtC;AAAA,EACF;AACF;","names":[]}