@pipeline-builder/pipeline-manager 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (222) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +145 -0
  3. package/cdk.json +91 -0
  4. package/config.yml +94 -0
  5. package/dist/agent/ai.d.ts +48 -0
  6. package/dist/agent/ai.d.ts.map +1 -0
  7. package/dist/agent/ai.js +149 -0
  8. package/dist/agent/bootstrap.d.ts +39 -0
  9. package/dist/agent/bootstrap.d.ts.map +1 -0
  10. package/dist/agent/bootstrap.js +66 -0
  11. package/dist/agent/env-file.d.ts +17 -0
  12. package/dist/agent/env-file.d.ts.map +1 -0
  13. package/dist/agent/env-file.js +47 -0
  14. package/dist/agent/executor.d.ts +30 -0
  15. package/dist/agent/executor.d.ts.map +1 -0
  16. package/dist/agent/executor.js +60 -0
  17. package/dist/agent/health.d.ts +43 -0
  18. package/dist/agent/health.d.ts.map +1 -0
  19. package/dist/agent/health.js +109 -0
  20. package/dist/agent/ports.d.ts +26 -0
  21. package/dist/agent/ports.d.ts.map +1 -0
  22. package/dist/agent/ports.js +132 -0
  23. package/dist/agent/post-steps.d.ts +61 -0
  24. package/dist/agent/post-steps.d.ts.map +1 -0
  25. package/dist/agent/post-steps.js +131 -0
  26. package/dist/agent/prereqs.d.ts +26 -0
  27. package/dist/agent/prereqs.d.ts.map +1 -0
  28. package/dist/agent/prereqs.js +134 -0
  29. package/dist/agent/targets.d.ts +128 -0
  30. package/dist/agent/targets.d.ts.map +1 -0
  31. package/dist/agent/targets.js +265 -0
  32. package/dist/agent/tools.d.ts +13 -0
  33. package/dist/agent/tools.d.ts.map +1 -0
  34. package/dist/agent/tools.js +75 -0
  35. package/dist/agent/troubleshoot.d.ts +30 -0
  36. package/dist/agent/troubleshoot.d.ts.map +1 -0
  37. package/dist/agent/troubleshoot.js +87 -0
  38. package/dist/boilerplate.d.ts +3 -0
  39. package/dist/boilerplate.d.ts.map +1 -0
  40. package/dist/boilerplate.js +54 -0
  41. package/dist/cdk.json +91 -0
  42. package/dist/cli.d.ts +62 -0
  43. package/dist/cli.d.ts.map +1 -0
  44. package/dist/cli.js +463 -0
  45. package/dist/commands/audit-stacks.d.ts +24 -0
  46. package/dist/commands/audit-stacks.d.ts.map +1 -0
  47. package/dist/commands/audit-stacks.js +182 -0
  48. package/dist/commands/audit-tokens.d.ts +21 -0
  49. package/dist/commands/audit-tokens.d.ts.map +1 -0
  50. package/dist/commands/audit-tokens.js +153 -0
  51. package/dist/commands/bootstrap.d.ts +11 -0
  52. package/dist/commands/bootstrap.d.ts.map +1 -0
  53. package/dist/commands/bootstrap.js +159 -0
  54. package/dist/commands/create-pat.d.ts +27 -0
  55. package/dist/commands/create-pat.d.ts.map +1 -0
  56. package/dist/commands/create-pat.js +194 -0
  57. package/dist/commands/create-pipeline.d.ts +12 -0
  58. package/dist/commands/create-pipeline.d.ts.map +1 -0
  59. package/dist/commands/create-pipeline.js +315 -0
  60. package/dist/commands/deploy.d.ts +15 -0
  61. package/dist/commands/deploy.d.ts.map +1 -0
  62. package/dist/commands/deploy.js +157 -0
  63. package/dist/commands/entity-get.d.ts +51 -0
  64. package/dist/commands/entity-get.d.ts.map +1 -0
  65. package/dist/commands/entity-get.js +69 -0
  66. package/dist/commands/entity-list.d.ts +39 -0
  67. package/dist/commands/entity-list.d.ts.map +1 -0
  68. package/dist/commands/entity-list.js +88 -0
  69. package/dist/commands/get-pipeline.d.ts +13 -0
  70. package/dist/commands/get-pipeline.d.ts.map +1 -0
  71. package/dist/commands/get-pipeline.js +49 -0
  72. package/dist/commands/get-plugin.d.ts +13 -0
  73. package/dist/commands/get-plugin.d.ts.map +1 -0
  74. package/dist/commands/get-plugin.js +51 -0
  75. package/dist/commands/instantiate-template.d.ts +20 -0
  76. package/dist/commands/instantiate-template.d.ts.map +1 -0
  77. package/dist/commands/instantiate-template.js +274 -0
  78. package/dist/commands/list-pipelines.d.ts +20 -0
  79. package/dist/commands/list-pipelines.d.ts.map +1 -0
  80. package/dist/commands/list-pipelines.js +99 -0
  81. package/dist/commands/list-plugins.d.ts +20 -0
  82. package/dist/commands/list-plugins.d.ts.map +1 -0
  83. package/dist/commands/list-plugins.js +92 -0
  84. package/dist/commands/login.d.ts +21 -0
  85. package/dist/commands/login.d.ts.map +1 -0
  86. package/dist/commands/login.js +174 -0
  87. package/dist/commands/new-plugin.d.ts +12 -0
  88. package/dist/commands/new-plugin.d.ts.map +1 -0
  89. package/dist/commands/new-plugin.js +129 -0
  90. package/dist/commands/org-export.d.ts +25 -0
  91. package/dist/commands/org-export.d.ts.map +1 -0
  92. package/dist/commands/org-export.js +100 -0
  93. package/dist/commands/provision.d.ts +122 -0
  94. package/dist/commands/provision.d.ts.map +1 -0
  95. package/dist/commands/provision.js +867 -0
  96. package/dist/commands/redrive-events.d.ts +24 -0
  97. package/dist/commands/redrive-events.d.ts.map +1 -0
  98. package/dist/commands/redrive-events.js +127 -0
  99. package/dist/commands/register.d.ts +38 -0
  100. package/dist/commands/register.d.ts.map +1 -0
  101. package/dist/commands/register.js +160 -0
  102. package/dist/commands/setup-events.d.ts +15 -0
  103. package/dist/commands/setup-events.d.ts.map +1 -0
  104. package/dist/commands/setup-events.js +168 -0
  105. package/dist/commands/status.d.ts +11 -0
  106. package/dist/commands/status.d.ts.map +1 -0
  107. package/dist/commands/status.js +81 -0
  108. package/dist/commands/store-token.d.ts +26 -0
  109. package/dist/commands/store-token.d.ts.map +1 -0
  110. package/dist/commands/store-token.js +305 -0
  111. package/dist/commands/synth.d.ts +21 -0
  112. package/dist/commands/synth.d.ts.map +1 -0
  113. package/dist/commands/synth.js +158 -0
  114. package/dist/commands/upload-plugin.d.ts +21 -0
  115. package/dist/commands/upload-plugin.d.ts.map +1 -0
  116. package/dist/commands/upload-plugin.js +275 -0
  117. package/dist/commands/validate-plugin.d.ts +12 -0
  118. package/dist/commands/validate-plugin.d.ts.map +1 -0
  119. package/dist/commands/validate-plugin.js +175 -0
  120. package/dist/commands/validate-templates.d.ts +11 -0
  121. package/dist/commands/validate-templates.d.ts.map +1 -0
  122. package/dist/commands/validate-templates.js +116 -0
  123. package/dist/commands/version.d.ts +12 -0
  124. package/dist/commands/version.d.ts.map +1 -0
  125. package/dist/commands/version.js +216 -0
  126. package/dist/config/cli.constants.d.ts +116 -0
  127. package/dist/config/cli.constants.d.ts.map +1 -0
  128. package/dist/config/cli.constants.js +194 -0
  129. package/dist/config.yml +94 -0
  130. package/dist/lambda/token-renew-handler.d.ts +2 -0
  131. package/dist/lambda/token-renew-handler.d.ts.map +1 -0
  132. package/dist/lambda/token-renew-handler.js +125 -0
  133. package/dist/templates/events-stack.json +174 -0
  134. package/dist/templates/token-renew-stack.json +122 -0
  135. package/dist/types/config.d.ts +53 -0
  136. package/dist/types/config.d.ts.map +1 -0
  137. package/dist/types/config.js +4 -0
  138. package/dist/types/error.d.ts +61 -0
  139. package/dist/types/error.d.ts.map +1 -0
  140. package/dist/types/error.js +35 -0
  141. package/dist/types/index.d.ts +9 -0
  142. package/dist/types/index.d.ts.map +1 -0
  143. package/dist/types/index.js +11 -0
  144. package/dist/types/pipeline-template.d.ts +48 -0
  145. package/dist/types/pipeline-template.d.ts.map +1 -0
  146. package/dist/types/pipeline-template.js +4 -0
  147. package/dist/types/pipeline.d.ts +121 -0
  148. package/dist/types/pipeline.d.ts.map +1 -0
  149. package/dist/types/pipeline.js +4 -0
  150. package/dist/types/plugin.d.ts +135 -0
  151. package/dist/types/plugin.d.ts.map +1 -0
  152. package/dist/types/plugin.js +4 -0
  153. package/dist/utils/api-client.d.ts +26 -0
  154. package/dist/utils/api-client.d.ts.map +1 -0
  155. package/dist/utils/api-client.js +151 -0
  156. package/dist/utils/audit-log.d.ts +8 -0
  157. package/dist/utils/audit-log.d.ts.map +1 -0
  158. package/dist/utils/audit-log.js +57 -0
  159. package/dist/utils/auth-guard.d.ts +20 -0
  160. package/dist/utils/auth-guard.d.ts.map +1 -0
  161. package/dist/utils/auth-guard.js +22 -0
  162. package/dist/utils/auth-utils.d.ts +68 -0
  163. package/dist/utils/auth-utils.d.ts.map +1 -0
  164. package/dist/utils/auth-utils.js +77 -0
  165. package/dist/utils/aws-env.d.ts +21 -0
  166. package/dist/utils/aws-env.d.ts.map +1 -0
  167. package/dist/utils/aws-env.js +34 -0
  168. package/dist/utils/aws-secrets.d.ts +48 -0
  169. package/dist/utils/aws-secrets.d.ts.map +1 -0
  170. package/dist/utils/aws-secrets.js +115 -0
  171. package/dist/utils/banner.d.ts +19 -0
  172. package/dist/utils/banner.d.ts.map +1 -0
  173. package/dist/utils/banner.js +52 -0
  174. package/dist/utils/cdk-utils.d.ts +74 -0
  175. package/dist/utils/cdk-utils.d.ts.map +1 -0
  176. package/dist/utils/cdk-utils.js +152 -0
  177. package/dist/utils/command-utils.d.ts +75 -0
  178. package/dist/utils/command-utils.d.ts.map +1 -0
  179. package/dist/utils/command-utils.js +155 -0
  180. package/dist/utils/config-loader.d.ts +33 -0
  181. package/dist/utils/config-loader.d.ts.map +1 -0
  182. package/dist/utils/config-loader.js +154 -0
  183. package/dist/utils/cron.d.ts +28 -0
  184. package/dist/utils/cron.d.ts.map +1 -0
  185. package/dist/utils/cron.js +119 -0
  186. package/dist/utils/deploy-runner.d.ts +38 -0
  187. package/dist/utils/deploy-runner.d.ts.map +1 -0
  188. package/dist/utils/deploy-runner.js +112 -0
  189. package/dist/utils/error-handler.d.ts +29 -0
  190. package/dist/utils/error-handler.d.ts.map +1 -0
  191. package/dist/utils/error-handler.js +302 -0
  192. package/dist/utils/list-command-utils.d.ts +23 -0
  193. package/dist/utils/list-command-utils.d.ts.map +1 -0
  194. package/dist/utils/list-command-utils.js +57 -0
  195. package/dist/utils/output-utils.d.ts +40 -0
  196. package/dist/utils/output-utils.d.ts.map +1 -0
  197. package/dist/utils/output-utils.js +250 -0
  198. package/dist/utils/pipeline-config.d.ts +33 -0
  199. package/dist/utils/pipeline-config.d.ts.map +1 -0
  200. package/dist/utils/pipeline-config.js +55 -0
  201. package/dist/utils/platform-secret.d.ts +27 -0
  202. package/dist/utils/platform-secret.d.ts.map +1 -0
  203. package/dist/utils/platform-secret.js +92 -0
  204. package/dist/utils/plugin-resolver.d.ts +17 -0
  205. package/dist/utils/plugin-resolver.d.ts.map +1 -0
  206. package/dist/utils/plugin-resolver.js +101 -0
  207. package/dist/utils/preflight.d.ts +26 -0
  208. package/dist/utils/preflight.d.ts.map +1 -0
  209. package/dist/utils/preflight.js +59 -0
  210. package/dist/utils/rate-limiter.d.ts +15 -0
  211. package/dist/utils/rate-limiter.d.ts.map +1 -0
  212. package/dist/utils/rate-limiter.js +164 -0
  213. package/dist/utils/registry.d.ts +86 -0
  214. package/dist/utils/registry.d.ts.map +1 -0
  215. package/dist/utils/registry.js +140 -0
  216. package/dist/utils/response-utils.d.ts +21 -0
  217. package/dist/utils/response-utils.d.ts.map +1 -0
  218. package/dist/utils/response-utils.js +70 -0
  219. package/dist/utils/tls.d.ts +52 -0
  220. package/dist/utils/tls.d.ts.map +1 -0
  221. package/dist/utils/tls.js +88 -0
  222. package/package.json +181 -0
@@ -0,0 +1,112 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import * as path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import pico from 'picocolors';
6
+ import { executeCdkShellCommand, resolveBoilerplatePath } from './cdk-utils.js';
7
+ import { ensureOutputDirectory, printInfo, printKeyValue, printSection, printSuccess, printWarning } from './output-utils.js';
8
+ import { buildRegistryPayload, writePendingIntent } from './registry.js';
9
+ import { assertShellSafe, shellQuote } from '../config/cli.constants.js';
10
+ import {} from '../types/index.js';
11
+ const { bold, cyan, dim } = pico;
12
+ // ESM has no __dirname; derive it from this module's URL. `resolveBoilerplatePath`
13
+ // returns `../boilerplate.js`, which is the same target whether resolved from
14
+ // src/commands or src/utils (both are siblings under src/), so this stays correct.
15
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
16
+ /**
17
+ * Run `cdk deploy` for an already-resolved pipeline, then register the deployed
18
+ * ARN for event reporting (best-effort). Shared by `pipeline deploy` and
19
+ * `pipeline create --deploy` so the two entry points never drift.
20
+ *
21
+ * THROWS on CDK failure (the caller maps it to a non-zero exit and, for the
22
+ * create path, keeps the created record and prints the `deploy --id` retry).
23
+ * Registry failures are NON-fatal — they're queued to a pending-intent file for
24
+ * `pipeline register` to drain later.
25
+ */
26
+ export async function runDeploy(input) {
27
+ const { pipeline, propsWithIds, profile, region, requireApproval, output, debug, executionId } = input;
28
+ const encoded = Buffer.from(JSON.stringify(propsWithIds), 'utf-8').toString('base64');
29
+ printInfo('Preparing output directory', { path: output });
30
+ ensureOutputDirectory(output);
31
+ // Validate EVERY input that flows into the shell (interpolated unquoted below).
32
+ if (profile)
33
+ assertShellSafe(profile, 'profile');
34
+ assertShellSafe(output, 'output');
35
+ assertShellSafe(requireApproval, 'require-approval');
36
+ // `assertShellSafe` rejects shell metacharacters but ALLOWS spaces, so quote
37
+ // every interpolated value (a path/profile with a space would otherwise split
38
+ // into extra cdk args — matching how the agent path quotes them).
39
+ const scriptPath = resolveBoilerplatePath(__dirname);
40
+ const profileArg = profile ? `--profile=${shellQuote(profile)}` : '';
41
+ const outputArg = `--output=${shellQuote(output)}`;
42
+ const appArg = `--app="node ${scriptPath}"`;
43
+ const command = `cdk deploy ${profileArg} --require-approval=${shellQuote(requireApproval)} ${outputArg} --notices=false ${appArg}`;
44
+ printSection('CDK Execution');
45
+ console.log(cyan(bold('Command:')), dim(command.split(' --')[0] + ' ...'));
46
+ console.log('');
47
+ // Forward the resolved platform base URL into the CDK synth subprocess (it reads
48
+ // only process.env) for the PluginLookup Lambda endpoint + registry pull-host
49
+ // fallback. Absent in local-spec mode.
50
+ const cdkEnv = { PIPELINE_PROPS: encoded };
51
+ if (input.platformBaseUrl)
52
+ cdkEnv.PLATFORM_BASE_URL = input.platformBaseUrl;
53
+ // Throws on failure — surfaced by the caller as a non-zero exit.
54
+ const result = executeCdkShellCommand(command, { debug, showOutput: true, env: cdkEnv });
55
+ console.log('');
56
+ printSection('Deployment Complete');
57
+ printKeyValue({
58
+ 'Execution ID': executionId,
59
+ 'Duration': `${result.duration}ms`,
60
+ 'Output Directory': output,
61
+ 'Status': '✓ Success',
62
+ });
63
+ // Register the pipeline ARN for event reporting (non-blocking). Skipped when
64
+ // there's no platform client (local-spec) or no orgId to scope it to.
65
+ if (!input.platformClient || !input.platformPipelineUrl) {
66
+ printInfo('Skipping pipeline registry (no platform client)');
67
+ return;
68
+ }
69
+ if (!pipeline.orgId) {
70
+ printWarning('Pipeline has no orgId — skipping registration');
71
+ return;
72
+ }
73
+ // Build the payload up-front so a POST failure can persist the SAME payload as a
74
+ // pending intent for `pipeline register` to drain later (STS lookups aren't retried).
75
+ let payload;
76
+ try {
77
+ payload = await buildRegistryPayload({
78
+ id: pipeline.id,
79
+ orgId: pipeline.orgId,
80
+ pipelineName: pipeline.pipelineName,
81
+ project: pipeline.project,
82
+ organization: pipeline.organization,
83
+ }, region);
84
+ }
85
+ catch (buildError) {
86
+ printWarning('Could not build registry payload — skipping registration', {
87
+ error: buildError instanceof Error ? buildError.message : String(buildError),
88
+ });
89
+ return;
90
+ }
91
+ try {
92
+ await input.platformClient.post(`${input.platformPipelineUrl}/registry`, payload);
93
+ printSuccess('Pipeline registered for event reporting', { pipelineId: payload.pipelineId });
94
+ }
95
+ catch (regError) {
96
+ try {
97
+ const intentPath = await writePendingIntent(payload);
98
+ printWarning('Pipeline registry update failed; queued for retry', {
99
+ error: regError instanceof Error ? regError.message : String(regError),
100
+ retry: 'pipeline-manager pipeline register',
101
+ intent: intentPath,
102
+ });
103
+ }
104
+ catch (writeErr) {
105
+ printWarning('Pipeline registry update failed (retry queue also failed)', {
106
+ error: regError instanceof Error ? regError.message : String(regError),
107
+ queueError: writeErr instanceof Error ? writeErr.message : String(writeErr),
108
+ });
109
+ }
110
+ }
111
+ }
112
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVwbG95LXJ1bm5lci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9kZXBsb3ktcnVubmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUM7QUFDbEMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUN6QyxPQUFPLElBQUksTUFBTSxZQUFZLENBQUM7QUFDOUIsT0FBTyxFQUFFLHNCQUFzQixFQUFFLHNCQUFzQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEYsT0FBTyxFQUFFLHFCQUFxQixFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM5SCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekUsT0FBTyxFQUFFLGVBQWUsRUFBRSxVQUFVLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN6RSxPQUFPLEVBQWlCLE1BQU0sbUJBQW1CLENBQUM7QUFFbEQsTUFBTSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRWpDLG1GQUFtRjtBQUNuRiw4RUFBOEU7QUFDOUUsbUZBQW1GO0FBQ25GLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUE0Qi9EOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsU0FBUyxDQUFDLEtBQXFCO0lBQ25ELE1BQU0sRUFBRSxRQUFRLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsV0FBVyxFQUFFLEdBQUcs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Q3hFLEtBQUssRUFBRSxRQUFRLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO2dCQUN0RSxVQUFVLEVBQUUsUUFBUSxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQzthQUM1RSxDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHsgZmlsZVVSTFRvUGF0aCB9IGZyb20gJ25vZGU6dXJsJztcbmltcG9ydCBwaWNvIGZyb20gJ3BpY29jb2xvcnMnO1xuaW1wb3J0IHsgZXhlY3V0ZUNka1NoZWxsQ29tbWFuZCwgcmVzb2x2ZUJvaWxlcnBsYXRlUGF0aCB9IGZyb20gJy4vY2RrLXV0aWxzLmpzJztcbmltcG9ydCB7IGVuc3VyZU91dHB1dERpcmVjdG9yeSwgcHJpbnRJbmZvLCBwcmludEtleVZhbHVlLCBwcmludFNlY3Rpb24sIHByaW50U3VjY2VzcywgcHJpbnRXYXJuaW5nIH0gZnJvbSAnLi9vdXRwdXQtdXRpbHMuanMnO1xuaW1wb3J0IHsgYnVpbGRSZWdpc3RyeVBheWxvYWQsIHdyaXRlUGVuZGluZ0ludGVudCB9IGZyb20gJy4vcmVnaXN0cnkuanMnO1xuaW1wb3J0IHsgYXNzZXJ0U2hlbGxTYWZlLCBzaGVsbFF1b3RlIH0gZnJvbSAnLi4vY29uZmlnL2NsaS5jb25zdGFudHMuanMnO1xuaW1wb3J0IHsgdHlwZSBQaXBlbGluZSB9IGZyb20gJy4uL3R5cGVzL2luZGV4LmpzJztcblxuY29uc3QgeyBib2xkLCBjeWFuLCBkaW0gfSA9IHBpY287XG5cbi8vIEVTTSBoYXMgbm8gX19kaXJuYW1lOyBkZXJpdmUgaXQgZnJvbSB0aGlzIG1vZHVsZSdzIFVSTC4gYHJlc29sdmVCb2lsZXJwbGF0ZVBhdGhgXG4vLyByZXR1cm5zIGAuLi9ib2lsZXJwbGF0ZS5qc2AsIHdoaWNoIGlzIHRoZSBzYW1lIHRhcmdldCB3aGV0aGVyIHJlc29sdmVkIGZyb21cbi8vIHNyYy9jb21tYW5kcyBvciBzcmMvdXRpbHMgKGJvdGggYXJlIHNpYmxpbmdzIHVuZGVyIHNyYy8pLCBzbyB0aGlzIHN0YXlzIGNvcnJlY3QuXG5jb25zdCBfX2Rpcm5hbWUgPSBwYXRoLmRpcm5hbWUoZmlsZVVSTFRvUGF0aChpbXBvcnQubWV0YS51cmwpKTtcblxuLyoqIE1pbmltYWwgcGxhdGZvcm0gY2xpZW50IHNoYXBlIG5lZWRlZCB0byByZWdpc3RlciBhIGRlcGxveWVkIEFSTi4gKi9cbmludGVyZmFjZSBSZWdpc3RyeUNsaWVudCB7XG4gIHBvc3Q6ICh1cmw6IHN0cmluZywgYm9keTogdW5rbm93bikgPT4gUHJvbWlzZTx1bmtub3duPjtcbn1cblxuLyoqIElucHV0cyBmb3Ige0BsaW5rIHJ1bkRlcGxveX0g4oCUIGFuIGFscmVhZHktcmVzb2x2ZWQgcGlwZWxpbmUgKyBwcm9wcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUnVuRGVwbG95SW5wdXQge1xuICAvKiogVGhlIHBpcGVsaW5lIGJlaW5nIGRlcGxveWVkIChpZC9vcmdJZC9uYW1lL3Byb2plY3Qvb3JnIGRyaXZlIHJlZ2lzdHJhdGlvbikuICovXG4gIHBpcGVsaW5lOiBQaWNrPFBpcGVsaW5lLCAnaWQnIHwgJ29yZ0lkJyB8ICdwaXBlbGluZU5hbWUnIHwgJ3Byb2plY3QnIHwgJ29yZ2FuaXphdGlvbic+O1xuICAvKiogRnVsbHktcmVzb2x2ZWQgcHJvcHMgKHBsdWdpbnMgcHJlLXJlc29sdmVkLCByZWdpc3RyeSBob3N0IGJha2VkLCBpZHMgaW5jbHVkZWQpLiAqL1xuICBwcm9wc1dpdGhJZHM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAvKiogQVdTIHByb2ZpbGUgLyByZWdpb24gZm9yIHRoZSBkZXBsb3kgKyByZWdpc3RyeSBwYXlsb2FkLiAqL1xuICBwcm9maWxlPzogc3RyaW5nO1xuICByZWdpb24/OiBzdHJpbmc7XG4gIC8qKiBgY2RrIGRlcGxveSAtLXJlcXVpcmUtYXBwcm92YWxgIGxldmVsIGFuZCBgLS1vdXRwdXRgIGRpci4gKi9cbiAgcmVxdWlyZUFwcHJvdmFsOiBzdHJpbmc7XG4gIG91dHB1dDogc3RyaW5nO1xuICBkZWJ1Zz86IGJvb2xlYW47XG4gIC8qKiBGb3IgdGhlIGNvbW1hbmQgaGVhZGVyIC8gc3VtbWFyeSBsaW5lLiAqL1xuICBleGVjdXRpb25JZDogc3RyaW5nO1xuICAvKiogUmVnaXN0cnkgY2FsbGJhY2sg4oCUIG9taXQgKGUuZy4gLS1sb2NhbC1zcGVjKSB0byBza2lwIEFSTiByZWdpc3RyYXRpb24uICovXG4gIHBsYXRmb3JtQ2xpZW50PzogUmVnaXN0cnlDbGllbnQ7XG4gIHBsYXRmb3JtUGlwZWxpbmVVcmw/OiBzdHJpbmc7XG4gIHBsYXRmb3JtQmFzZVVybD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBSdW4gYGNkayBkZXBsb3lgIGZvciBhbiBhbHJlYWR5LXJlc29sdmVkIHBpcGVsaW5lLCB0aGVuIHJlZ2lzdGVyIHRoZSBkZXBsb3llZFxuICogQVJOIGZvciBldmVudCByZXBvcnRpbmcgKGJlc3QtZWZmb3J0KS4gU2hhcmVkIGJ5IGBwaXBlbGluZSBkZXBsb3lgIGFuZFxuICogYHBpcGVsaW5lIGNyZWF0ZSAtLWRlcGxveWAgc28gdGhlIHR3byBlbnRyeSBwb2ludHMgbmV2ZXIgZHJpZnQuXG4gKlxuICogVEhST1dTIG9uIENESyBmYWlsdXJlICh0aGUgY2FsbGVyIG1hcHMgaXQgdG8gYSBub24temVybyBleGl0IGFuZCwgZm9yIHRoZVxuICogY3JlYXRlIHBhdGgsIGtlZXBzIHRoZSBjcmVhdGVkIHJlY29yZCBhbmQgcHJpbnRzIHRoZSBgZGVwbG95IC0taWRgIHJldHJ5KS5cbiAqIFJlZ2lzdHJ5IGZhaWx1cmVzIGFyZSBOT04tZmF0YWwg4oCUIHRoZXkncmUgcXVldWVkIHRvIGEgcGVuZGluZy1pbnRlbnQgZmlsZSBmb3JcbiAqIGBwaXBlbGluZSByZWdpc3RlcmAgdG8gZHJhaW4gbGF0ZXIuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBydW5EZXBsb3koaW5wdXQ6IFJ1bkRlcGxveUlucHV0KTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgcGlwZWxpbmUsIHByb3BzV2l0aElkcywgcHJvZmlsZSwgcmVnaW9uLCByZXF1aXJlQXBwcm92YWwsIG91dHB1dCwgZGVidWcsIGV4ZWN1dGlvbklkIH0gPSBpbnB1dDtcblxuICBjb25zdCBlbmNvZGVkID0gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkocHJvcHNXaXRoSWRzKSwgJ3V0Zi04JykudG9TdHJpbmcoJ2Jhc2U2NCcpO1xuXG4gIHByaW50SW5mbygnUHJlcGFyaW5nIG91dHB1dCBkaXJlY3RvcnknLCB7IHBhdGg6IG91dHB1dCB9KTtcbiAgZW5zdXJlT3V0cHV0RGlyZWN0b3J5KG91dHB1dCk7XG5cbiAgLy8gVmFsaWRhdGUgRVZFUlkgaW5wdXQgdGhhdCBmbG93cyBpbnRvIHRoZSBzaGVsbCAoaW50ZXJwb2xhdGVkIHVucXVvdGVkIGJlbG93KS5cbiAgaWYgKHByb2ZpbGUpIGFzc2VydFNoZWxsU2FmZShwcm9maWxlLCAncHJvZmlsZScpO1xuICBhc3NlcnRTaGVsbFNhZmUob3V0cHV0LCAnb3V0cHV0Jyk7XG4gIGFzc2VydFNoZWxsU2FmZShyZXF1aXJlQXBwcm92YWwsICdyZXF1aXJlLWFwcHJvdmFsJyk7XG5cbiAgLy8gYGFzc2VydFNoZWxsU2FmZWAgcmVqZWN0cyBzaGVsbCBtZXRhY2hhcmFjdGVycyBidXQgQUxMT1dTIHNwYWNlcywgc28gcXVvdGVcbiAgLy8gZXZlcnkgaW50ZXJwb2xhdGVkIHZhbHVlIChhIHBhdGgvcHJvZmlsZSB3aXRoIGEgc3BhY2Ugd291bGQgb3RoZXJ3aXNlIHNwbGl0XG4gIC8vIGludG8gZXh0cmEgY2RrIGFyZ3Mg4oCUIG1hdGNoaW5nIGhvdyB0aGUgYWdlbnQgcGF0aCBxdW90ZXMgdGhlbSkuXG4gIGNvbnN0IHNjcmlwdFBhdGggPSByZXNvbHZlQm9pbGVycGxhdGVQYXRoKF9fZGlybmFtZSk7XG4gIGNvbnN0IHByb2ZpbGVBcmcgPSBwcm9maWxlID8gYC0tcHJvZmlsZT0ke3NoZWxsUXVvdGUocHJvZmlsZSl9YCA6ICcnO1xuICBjb25zdCBvdXRwdXRBcmcgPSBgLS1vdXRwdXQ9JHtzaGVsbFF1b3RlKG91dHB1dCl9YDtcbiAgY29uc3QgYXBwQXJnID0gYC0tYXBwPVwibm9kZSAke3NjcmlwdFBhdGh9XCJgO1xuICBjb25zdCBjb21tYW5kID0gYGNkayBkZXBsb3kgJHtwcm9maWxlQXJnfSAtLXJlcXVpcmUtYXBwcm92YWw9JHtzaGVsbFF1b3RlKHJlcXVpcmVBcHByb3ZhbCl9ICR7b3V0cHV0QXJnfSAtLW5vdGljZXM9ZmFsc2UgJHthcHBBcmd9YDtcblxuICBwcmludFNlY3Rpb24oJ0NESyBFeGVjdXRpb24nKTtcbiAgY29uc29sZS5sb2coY3lhbihib2xkKCdDb21tYW5kOicpKSwgZGltKGNvbW1hbmQuc3BsaXQoJyAtLScpWzBdICsgJyAuLi4nKSk7XG4gIGNvbnNvbGUubG9nKCcnKTtcblxuICAvLyBGb3J3YXJkIHRoZSByZXNvbHZlZCBwbGF0Zm9ybSBiYXNlIFVSTCBpbnRvIHRoZSBDREsgc3ludGggc3VicHJvY2VzcyAoaXQgcmVhZHNcbiAgLy8gb25seSBwcm9jZXNzLmVudikgZm9yIHRoZSBQbHVnaW5Mb29rdXAgTGFtYmRhIGVuZHBvaW50ICsgcmVnaXN0cnkgcHVsbC1ob3N0XG4gIC8vIGZhbGxiYWNrLiBBYnNlbnQgaW4gbG9jYWwtc3BlYyBtb2RlLlxuICBjb25zdCBjZGtFbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7IFBJUEVMSU5FX1BST1BTOiBlbmNvZGVkIH07XG4gIGlmIChpbnB1dC5wbGF0Zm9ybUJhc2VVcmwpIGNka0Vudi5QTEFURk9STV9CQVNFX1VSTCA9IGlucHV0LnBsYXRmb3JtQmFzZVVybDtcblxuICAvLyBUaHJvd3Mgb24gZmFpbHVyZSDigJQgc3VyZmFjZWQgYnkgdGhlIGNhbGxlciBhcyBhIG5vbi16ZXJvIGV4aXQuXG4gIGNvbnN0IHJlc3VsdCA9IGV4ZWN1dGVDZGtTaGVsbENvbW1hbmQoY29tbWFuZCwgeyBkZWJ1Zywgc2hvd091dHB1dDogdHJ1ZSwgZW52OiBjZGtFbnYgfSk7XG5cbiAgY29uc29sZS5sb2coJycpO1xuICBwcmludFNlY3Rpb24oJ0RlcGxveW1lbnQgQ29tcGxldGUnKTtcbiAgcHJpbnRLZXlWYWx1ZSh7XG4gICAgJ0V4ZWN1dGlvbiBJRCc6IGV4ZWN1dGlvbklkLFxuICAgICdEdXJhdGlvbic6IGAke3Jlc3VsdC5kdXJhdGlvbn1tc2AsXG4gICAgJ091dHB1dCBEaXJlY3RvcnknOiBvdXRwdXQsXG4gICAgJ1N0YXR1cyc6ICfinJMgU3VjY2VzcycsXG4gIH0pO1xuXG4gIC8vIFJlZ2lzdGVyIHRoZSBwaXBlbGluZSBBUk4gZm9yIGV2ZW50IHJlcG9ydGluZyAobm9uLWJsb2NraW5nKS4gU2tpcHBlZCB3aGVuXG4gIC8vIHRoZXJlJ3Mgbm8gcGxhdGZvcm0gY2xpZW50IChsb2NhbC1zcGVjKSBvciBubyBvcmdJZCB0byBzY29wZSBpdCB0by5cbiAgaWYgKCFpbnB1dC5wbGF0Zm9ybUNsaWVudCB8fCAhaW5wdXQucGxhdGZvcm1QaXBlbGluZVVybCkge1xuICAgIHByaW50SW5mbygnU2tpcHBpbmcgcGlwZWxpbmUgcmVnaXN0cnkgKG5vIHBsYXRmb3JtIGNsaWVudCknKTtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKCFwaXBlbGluZS5vcmdJZCkge1xuICAgIHByaW50V2FybmluZygnUGlwZWxpbmUgaGFzIG5vIG9yZ0lkIOKAlCBza2lwcGluZyByZWdpc3RyYXRpb24nKTtcbiAgICByZXR1cm47XG4gIH1cblxuICAvLyBCdWlsZCB0aGUgcGF5bG9hZCB1cC1mcm9udCBzbyBhIFBPU1QgZmFpbHVyZSBjYW4gcGVyc2lzdCB0aGUgU0FNRSBwYXlsb2FkIGFzIGFcbiAgLy8gcGVuZGluZyBpbnRlbnQgZm9yIGBwaXBlbGluZSByZWdpc3RlcmAgdG8gZHJhaW4gbGF0ZXIgKFNUUyBsb29rdXBzIGFyZW4ndCByZXRyaWVkKS5cbiAgbGV0IHBheWxvYWQ7XG4gIHRyeSB7XG4gICAgcGF5bG9hZCA9IGF3YWl0IGJ1aWxkUmVnaXN0cnlQYXlsb2FkKFxuICAgICAge1xuICAgICAgICBpZDogcGlwZWxpbmUuaWQsXG4gICAgICAgIG9yZ0lkOiBwaXBlbGluZS5vcmdJZCxcbiAgICAgICAgcGlwZWxpbmVOYW1lOiBwaXBlbGluZS5waXBlbGluZU5hbWUsXG4gICAgICAgIHByb2plY3Q6IHBpcGVsaW5lLnByb2plY3QsXG4gICAgICAgIG9yZ2FuaXphdGlvbjogcGlwZWxpbmUub3JnYW5pemF0aW9uLFxuICAgICAgfSxcbiAgICAgIHJlZ2lvbixcbiAgICApO1xuICB9IGNhdGNoIChidWlsZEVycm9yKSB7XG4gICAgcHJpbnRXYXJuaW5nKCdDb3VsZCBub3QgYnVpbGQgcmVnaXN0cnkgcGF5bG9hZCDigJQgc2tpcHBpbmcgcmVnaXN0cmF0aW9uJywge1xuICAgICAgZXJyb3I6IGJ1aWxkRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGJ1aWxkRXJyb3IubWVzc2FnZSA6IFN0cmluZyhidWlsZEVycm9yKSxcbiAgICB9KTtcbiAgICByZXR1cm47XG4gIH1cblxuICB0cnkge1xuICAgIGF3YWl0IGlucHV0LnBsYXRmb3JtQ2xpZW50LnBvc3QoYCR7aW5wdXQucGxhdGZvcm1QaXBlbGluZVVybH0vcmVnaXN0cnlgLCBwYXlsb2FkKTtcbiAgICBwcmludFN1Y2Nlc3MoJ1BpcGVsaW5lIHJlZ2lzdGVyZWQgZm9yIGV2ZW50IHJlcG9ydGluZycsIHsgcGlwZWxpbmVJZDogcGF5bG9hZC5waXBlbGluZUlkIH0pO1xuICB9IGNhdGNoIChyZWdFcnJvcikge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBpbnRlbnRQYXRoID0gYXdhaXQgd3JpdGVQZW5kaW5nSW50ZW50KHBheWxvYWQpO1xuICAgICAgcHJpbnRXYXJuaW5nKCdQaXBlbGluZSByZWdpc3RyeSB1cGRhdGUgZmFpbGVkOyBxdWV1ZWQgZm9yIHJldHJ5Jywge1xuICAgICAgICBlcnJvcjogcmVnRXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IHJlZ0Vycm9yLm1lc3NhZ2UgOiBTdHJpbmcocmVnRXJyb3IpLFxuICAgICAgICByZXRyeTogJ3BpcGVsaW5lLW1hbmFnZXIgcGlwZWxpbmUgcmVnaXN0ZXInLFxuICAgICAgICBpbnRlbnQ6IGludGVudFBhdGgsXG4gICAgICB9KTtcbiAgICB9IGNhdGNoICh3cml0ZUVycikge1xuICAgICAgcHJpbnRXYXJuaW5nKCdQaXBlbGluZSByZWdpc3RyeSB1cGRhdGUgZmFpbGVkIChyZXRyeSBxdWV1ZSBhbHNvIGZhaWxlZCknLCB7XG4gICAgICAgIGVycm9yOiByZWdFcnJvciBpbnN0YW5jZW9mIEVycm9yID8gcmVnRXJyb3IubWVzc2FnZSA6IFN0cmluZyhyZWdFcnJvciksXG4gICAgICAgIHF1ZXVlRXJyb3I6IHdyaXRlRXJyIGluc3RhbmNlb2YgRXJyb3IgPyB3cml0ZUVyci5tZXNzYWdlIDogU3RyaW5nKHdyaXRlRXJyKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1,29 @@
1
+ import { ERROR_CODES, type ErrorCode, type ErrorHandlerOptions } from '../types/index.js';
2
+ export { ERROR_CODES };
3
+ export type { ErrorCode };
4
+ /**
5
+ * Format and handle errors with colored output
6
+ */
7
+ export declare function handleError(err: unknown, code?: ErrorCode, options?: ErrorHandlerOptions): never;
8
+ /**
9
+ * Validation error class
10
+ */
11
+ export declare class ValidationError extends Error {
12
+ field?: string | undefined;
13
+ value?: unknown;
14
+ rule?: string | undefined;
15
+ expected?: string | undefined;
16
+ constructor(message: string, field?: string | undefined, value?: unknown, rule?: string | undefined, expected?: string | undefined);
17
+ }
18
+ /**
19
+ * Network error class
20
+ */
21
+ export declare class NetworkError extends Error {
22
+ url?: string | undefined;
23
+ cause?: Error | undefined;
24
+ timeout?: number | undefined;
25
+ requestMade: boolean;
26
+ responseReceived: boolean;
27
+ constructor(message: string, url?: string | undefined, cause?: Error | undefined, timeout?: number | undefined, requestMade?: boolean, responseReceived?: boolean);
28
+ }
29
+ //# sourceMappingURL=error-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-handler.d.ts","sourceRoot":"","sources":["../../src/utils/error-handler.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,WAAW,EACX,KAAK,SAAS,EACd,KAAK,mBAAmB,EAEzB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,WAAW,EAAE,CAAC;AACvB,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B;;GAEG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EACZ,IAAI,GAAE,SAA+B,EACrC,OAAO,GAAE,mBAAwB,GAChC,KAAK,CAiHP;AAID;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IAG/B,KAAK,CAAC,EAAE,MAAM;IACd,KAAK,CAAC,EAAE,OAAO;IACf,IAAI,CAAC,EAAE,MAAM;IACb,QAAQ,CAAC,EAAE,MAAM;IAL1B,YACE,OAAO,EAAE,MAAM,EACR,KAAK,CAAC,EAAE,MAAM,YAAA,EACd,KAAK,CAAC,EAAE,OAAO,EACf,IAAI,CAAC,EAAE,MAAM,YAAA,EACb,QAAQ,CAAC,EAAE,MAAM,YAAA,EAKzB;CACF;AAED;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;IAG5B,GAAG,CAAC,EAAE,MAAM;IACZ,KAAK,CAAC,EAAE,KAAK;IACb,OAAO,CAAC,EAAE,MAAM;IAChB,WAAW,EAAE,OAAO;IACpB,gBAAgB,EAAE,OAAO;IANlC,YACE,OAAO,EAAE,MAAM,EACR,GAAG,CAAC,EAAE,MAAM,YAAA,EACZ,KAAK,CAAC,EAAE,KAAK,YAAA,EACb,OAAO,CAAC,EAAE,MAAM,YAAA,EAChB,WAAW,GAAE,OAAc,EAC3B,gBAAgB,GAAE,OAAe,EAKzC;CACF"}
@@ -0,0 +1,302 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import pico from 'picocolors';
4
+ import { generateExecutionId } from '../config/cli.constants.js';
5
+ import { ERROR_CODES, } from '../types/index.js';
6
+ const { bold, dim, red, yellow, cyan } = pico;
7
+ // Re-export for convenience
8
+ export { ERROR_CODES };
9
+ /**
10
+ * Format and handle errors with colored output
11
+ */
12
+ export function handleError(err, code = ERROR_CODES.GENERAL, options = {}) {
13
+ const { debug = false, exit = true, logToConsole = true, context, correlationId = generateExecutionId(), } = options;
14
+ // Derive the canonical exit code from the ACTUAL error (see resolveExitCode),
15
+ // falling back to the caller's `code` for anything unclassifiable. This is what
16
+ // makes every command emit the SAME exit code for the same class of failure,
17
+ // rather than a blanket API_REQUEST/GENERAL. Used for display, the suggestion,
18
+ // and the process exit below.
19
+ const resolvedCode = resolveExitCode(err, code);
20
+ if (logToConsole) {
21
+ const divider = '─'.repeat(process.stdout.columns || 80);
22
+ const errorId = `ERR-${correlationId}`;
23
+ console.error('\n' + red(bold('✗ ERROR')) + dim(` [${errorId}]`) + '\n');
24
+ console.error(dim(divider));
25
+ if (err instanceof Error) {
26
+ console.error(red(bold('Message:')), err.message);
27
+ if (err.name !== 'Error') {
28
+ console.error(red('Type:'), err.name);
29
+ }
30
+ // Show Validation error details
31
+ if (err instanceof ValidationError) {
32
+ if (err.field)
33
+ console.error(red('Field:'), err.field);
34
+ if (err.value !== undefined)
35
+ console.error(red('Value:'), sanitizeValue(err.value));
36
+ if (err.rule)
37
+ console.error(red('Rule:'), err.rule);
38
+ if (err.expected)
39
+ console.error(red('Expected:'), err.expected);
40
+ }
41
+ // Show Network error details
42
+ if (err instanceof NetworkError) {
43
+ if (err.url)
44
+ console.error(red('URL:'), sanitizeUrl(err.url));
45
+ if (err.timeout)
46
+ console.error(red('Timeout:'), `${err.timeout}ms`);
47
+ console.error(red('Request Made:'), err.requestMade ? 'Yes' : 'No');
48
+ console.error(red('Response Received:'), err.responseReceived ? 'Yes' : 'No');
49
+ if (err.cause)
50
+ console.error(red('Caused by:'), err.cause.message);
51
+ }
52
+ // Show Axios error details
53
+ if (isAxiosError(err)) {
54
+ const status = err.response?.status;
55
+ const url = err.config?.url;
56
+ if (status) {
57
+ console.error(red('Status:'), status);
58
+ console.error(red('Status Text:'), getHttpStatusText(status));
59
+ }
60
+ if (url)
61
+ console.error(red('URL:'), sanitizeUrl(url));
62
+ if (err.response?.data) {
63
+ console.error(red('Response:'));
64
+ console.error(dim(sanitizeErrorData(err.response.data)));
65
+ }
66
+ }
67
+ // Show CDK/execSync error details (stderr captured from child process)
68
+ if ('stderr' in err && err.stderr) {
69
+ const stderr = err.stderr.toString().trim();
70
+ if (stderr) {
71
+ console.error(red('CDK Output:'));
72
+ console.error(dim(stderr));
73
+ }
74
+ }
75
+ console.error(red('Code:'), getErrorCodeName(resolvedCode));
76
+ console.error(dim('Error ID:'), dim(errorId));
77
+ if (context && Object.keys(context).length > 0) {
78
+ console.error('');
79
+ console.error(red('Context:'));
80
+ Object.entries(context).forEach(([key, value]) => {
81
+ console.error(` ${cyan(key)}:`, dim(sanitizeValue(value)));
82
+ });
83
+ }
84
+ if (debug && err.stack) {
85
+ console.error('');
86
+ console.error(dim('Stack trace:'));
87
+ console.error(dim(sanitizeStackTrace(err.stack)));
88
+ }
89
+ }
90
+ else {
91
+ console.error(red('Error:'), String(err));
92
+ console.error(red('Code:'), getErrorCodeName(resolvedCode));
93
+ console.error(dim('Error ID:'), dim(errorId));
94
+ }
95
+ console.error(dim(divider));
96
+ if (!debug) {
97
+ console.error(yellow('💡 Tip:'), dim('Run with --debug flag to see full stack trace'));
98
+ }
99
+ const suggestion = getErrorSuggestion(err, resolvedCode);
100
+ if (suggestion) {
101
+ console.error(yellow('💡 Suggestion:'), dim(suggestion));
102
+ }
103
+ console.error('');
104
+ }
105
+ if (exit) {
106
+ process.exitCode = resolvedCode;
107
+ process.exit(resolvedCode);
108
+ }
109
+ throw err;
110
+ }
111
+ // --- Error classes (only those actually used) ---
112
+ /**
113
+ * Validation error class
114
+ */
115
+ export class ValidationError extends Error {
116
+ field;
117
+ value;
118
+ rule;
119
+ expected;
120
+ constructor(message, field, value, rule, expected) {
121
+ super(message);
122
+ this.field = field;
123
+ this.value = value;
124
+ this.rule = rule;
125
+ this.expected = expected;
126
+ this.name = 'ValidationError';
127
+ Error.captureStackTrace(this, this.constructor);
128
+ }
129
+ }
130
+ /**
131
+ * Network error class
132
+ */
133
+ export class NetworkError extends Error {
134
+ url;
135
+ cause;
136
+ timeout;
137
+ requestMade;
138
+ responseReceived;
139
+ constructor(message, url, cause, timeout, requestMade = true, responseReceived = false) {
140
+ super(message);
141
+ this.url = url;
142
+ this.cause = cause;
143
+ this.timeout = timeout;
144
+ this.requestMade = requestMade;
145
+ this.responseReceived = responseReceived;
146
+ this.name = 'NetworkError';
147
+ Error.captureStackTrace(this, this.constructor);
148
+ }
149
+ }
150
+ // --- Private helpers ---
151
+ /**
152
+ * Map the ACTUAL error to a canonical exit code so every command exits with the
153
+ * SAME code for the same class of failure. The caller-supplied `fallback` (e.g.
154
+ * API_REQUEST) is used only for errors this can't classify. Codes (src/types/error.ts):
155
+ *
156
+ * 1 GENERAL · 2 VALIDATION · 3 API_REQUEST · 4 AUTHENTICATION · 5 AUTHORIZATION
157
+ * 6 NOT_FOUND · 7 NETWORK · 8 CONFIGURATION · 9 FILE_SYSTEM · 10 TIMEOUT
158
+ *
159
+ * Precedence: typed CLI errors → HTTP status → Node system error `code` → fallback.
160
+ */
161
+ function resolveExitCode(err, fallback) {
162
+ if (err instanceof ValidationError)
163
+ return ERROR_CODES.VALIDATION;
164
+ if (err instanceof NetworkError)
165
+ return err.timeout ? ERROR_CODES.TIMEOUT : ERROR_CODES.NETWORK;
166
+ if (isAxiosError(err)) {
167
+ const status = err.response?.status;
168
+ if (status === 400 || status === 422)
169
+ return ERROR_CODES.VALIDATION;
170
+ if (status === 401)
171
+ return ERROR_CODES.AUTHENTICATION;
172
+ if (status === 403)
173
+ return ERROR_CODES.AUTHORIZATION;
174
+ if (status === 404)
175
+ return ERROR_CODES.NOT_FOUND;
176
+ if (status === 408 || status === 504)
177
+ return ERROR_CODES.TIMEOUT;
178
+ if (status && status >= 500)
179
+ return ERROR_CODES.API_REQUEST;
180
+ // A request that got no HTTP response never reached the server (DNS / refused
181
+ // / reset) — that's a network failure, not an API-response error.
182
+ if (!err.response)
183
+ return ERROR_CODES.NETWORK;
184
+ return fallback;
185
+ }
186
+ // Node system errors (fs + sockets) carry a string `code`.
187
+ const sysCode = err?.code;
188
+ if (typeof sysCode === 'string') {
189
+ if (['ENOENT', 'EACCES', 'EISDIR', 'ENOTDIR', 'EEXIST', 'EPERM', 'ENOSPC', 'EMFILE'].includes(sysCode)) {
190
+ return ERROR_CODES.FILE_SYSTEM;
191
+ }
192
+ if (sysCode === 'ETIMEDOUT')
193
+ return ERROR_CODES.TIMEOUT;
194
+ if (['ECONNREFUSED', 'ENOTFOUND', 'ECONNRESET', 'EHOSTUNREACH', 'ENETUNREACH', 'EAI_AGAIN', 'EPIPE'].includes(sysCode)) {
195
+ return ERROR_CODES.NETWORK;
196
+ }
197
+ }
198
+ return fallback;
199
+ }
200
+ function getErrorCodeName(code) {
201
+ const entry = Object.entries(ERROR_CODES).find(([_, value]) => value === code);
202
+ return entry ? `${entry[0]} (${code})` : String(code);
203
+ }
204
+ function getHttpStatusText(status) {
205
+ const statusTexts = {
206
+ 400: 'Bad Request',
207
+ 401: 'Unauthorized',
208
+ 403: 'Forbidden',
209
+ 404: 'Not Found',
210
+ 408: 'Request Timeout',
211
+ 409: 'Conflict',
212
+ 422: 'Unprocessable Entity',
213
+ 429: 'Too Many Requests',
214
+ 500: 'Internal Server Error',
215
+ 502: 'Bad Gateway',
216
+ 503: 'Service Unavailable',
217
+ 504: 'Gateway Timeout',
218
+ };
219
+ return statusTexts[status] || 'Unknown';
220
+ }
221
+ function getErrorSuggestion(err, code) {
222
+ if (code === ERROR_CODES.AUTHENTICATION) {
223
+ return 'Check that PLATFORM_TOKEN environment variable is set correctly';
224
+ }
225
+ if (code === ERROR_CODES.NETWORK) {
226
+ return 'Check your internet connection and API endpoint URL';
227
+ }
228
+ if (code === ERROR_CODES.CONFIGURATION) {
229
+ return 'Run "cli version --check-config" to verify configuration';
230
+ }
231
+ if (code === ERROR_CODES.NOT_FOUND) {
232
+ return 'Verify the resource ID exists and you have access to it';
233
+ }
234
+ if (err instanceof Error && err.message.includes('cdk')) {
235
+ return 'Check the CDK output above for CloudFormation errors. Run with --debug for full details';
236
+ }
237
+ if (err instanceof ValidationError && err.field) {
238
+ return `Check the value provided for "${err.field}"`;
239
+ }
240
+ if (isAxiosError(err)) {
241
+ const status = err.response?.status;
242
+ if (status === 401 || status === 403)
243
+ return 'Check your authentication token and permissions';
244
+ if (status === 429)
245
+ return 'Rate limit exceeded - wait a moment before retrying';
246
+ if (status && status >= 500)
247
+ return 'Server error - try again later or contact support';
248
+ }
249
+ return null;
250
+ }
251
+ function sanitizeErrorData(data) {
252
+ if (typeof data === 'string')
253
+ return data;
254
+ if (typeof data === 'object' && data !== null) {
255
+ const sanitized = { ...data };
256
+ ['token', 'password', 'secret', 'apiKey', 'authorization', 'jwt', 'credential', 'bearer'].forEach(field => {
257
+ if (field in sanitized)
258
+ sanitized[field] = '[REDACTED]';
259
+ });
260
+ return JSON.stringify(sanitized, null, 2);
261
+ }
262
+ return String(data);
263
+ }
264
+ function sanitizeUrl(url) {
265
+ try {
266
+ const urlObj = new URL(url);
267
+ ['token', 'key', 'secret', 'password', 'apiKey'].forEach(param => {
268
+ if (urlObj.searchParams.has(param))
269
+ urlObj.searchParams.set(param, '[REDACTED]');
270
+ });
271
+ return urlObj.toString();
272
+ }
273
+ catch {
274
+ return url;
275
+ }
276
+ }
277
+ function sanitizeValue(value) {
278
+ if (value === null)
279
+ return 'null';
280
+ if (value === undefined)
281
+ return 'undefined';
282
+ if (typeof value === 'string') {
283
+ if (value.length > 20 && /^[A-Za-z0-9+/=_-]+$/.test(value)) {
284
+ return `${value.substring(0, 8)}...[REDACTED]`;
285
+ }
286
+ return value.length > 100 ? value.substring(0, 97) + '...' : value;
287
+ }
288
+ if (typeof value === 'object')
289
+ return sanitizeErrorData(value);
290
+ const str = String(value);
291
+ return str.length > 100 ? str.substring(0, 97) + '...' : str;
292
+ }
293
+ function sanitizeStackTrace(stack) {
294
+ return stack.split('\n').slice(0, 10).map(line => line.replace(/\/.*?\//g, '.../')).join('\n');
295
+ }
296
+ function isAxiosError(err) {
297
+ return (typeof err === 'object' &&
298
+ err !== null &&
299
+ 'isAxiosError' in err &&
300
+ err.isAxiosError === true);
301
+ }
302
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3ItaGFuZGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9lcnJvci1oYW5kbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLCtDQUErQztBQUMvQyxzQ0FBc0M7QUFFdEMsT0FBTyxJQUFJLE1BQU0sWUFBWSxDQUFDO0FBQzlCLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2pFLE9BQU8sRUFDTCxXQUFXLEdBSVosTUFBTSxtQkFBbUIsQ0FBQztBQUUzQixNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQztBQUU5Qyw0QkFBNEI7QUFDNUIsT0FBTyxFQUFFLFdBQVcsRUFBRSxDQUFDO0FBR3ZCOztHQUVHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FDekIsR0FBWSxFQUNaLElBQUksR0FBYyxXQUFXLENBQUMsT0FBTyxFQUNyQyxPQUFPLEdBQXdCLEVBQUU7SUFFakMsTUFBTSxFQUNKLEtBQUssR0FBRyxLQUFLLEVBQ2IsSUFBSSxHQUFHLElBQUksRUFDWCxZQUFZLEdBQUcsSUFBSSxFQUNuQixPQUFPLEVBQ1AsYUFBYSxHQUFHLG1CQUFtQixFQUFFLEdBQ3RDLEdBQUcsT0FBTyxDQUFDO0lBRVosOEVBQThFO0lBQzlFLGdGQUFnRjtJQUNoRiw2RUFBNkU7SUFDN0UsK0VBQStFO0lBQy9FLDhCQUE4QjtJQUM5QixNQUFNLFlBQVksR0FBRyxlQUFlLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBRWhELElBQUksWUFBWSxFQUFFLENBQUM7UUFDakIsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN6RCxNQUFNLE9BQU8sR0FBRyxPQUFPLGFBQWEsRUFBRSxDQUFDO1FBRXZDLE9B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bi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCBwaWNvIGZyb20gJ3BpY29jb2xvcnMnO1xuaW1wb3J0IHsgZ2VuZXJhdGVFeGVjdXRpb25JZCB9IGZyb20gJy4uL2NvbmZpZy9jbGkuY29uc3RhbnRzLmpzJztcbmltcG9ydCB7XG4gIEVSUk9SX0NPREVTLFxuICB0eXBlIEVycm9yQ29kZSxcbiAgdHlwZSBFcnJvckhhbmRsZXJPcHRpb25zLFxuICB0eXBlIEF4aW9zRXJyb3JMaWtlLFxufSBmcm9tICcuLi90eXBlcy9pbmRleC5qcyc7XG5cbmNvbnN0IHsgYm9sZCwgZGltLCByZWQsIHllbGxvdywgY3lhbiB9ID0gcGljbztcblxuLy8gUmUtZXhwb3J0IGZvciBjb252ZW5pZW5jZVxuZXhwb3J0IHsgRVJST1JfQ09ERVMgfTtcbmV4cG9ydCB0eXBlIHsgRXJyb3JDb2RlIH07XG5cbi8qKlxuICogRm9ybWF0IGFuZCBoYW5kbGUgZXJyb3JzIHdpdGggY29sb3JlZCBvdXRwdXRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhbmRsZUVycm9yKFxuICBlcnI6IHVua25vd24sXG4gIGNvZGU6IEVycm9yQ29kZSA9IEVSUk9SX0NPREVTLkdFTkVSQUwsXG4gIG9wdGlvbnM6IEVycm9ySGFuZGxlck9wdGlvbnMgPSB7fSxcbik6IG5ldmVyIHtcbiAgY29uc3Qge1xuICAgIGRlYnVnID0gZmFsc2UsXG4gICAgZXhpdCA9IHRydWUsXG4gICAgbG9nVG9Db25zb2xlID0gdHJ1ZSxcbiAgICBjb250ZXh0LFxuICAgIGNvcnJlbGF0aW9uSWQgPSBnZW5lcmF0ZUV4ZWN1dGlvbklkKCksXG4gIH0gPSBvcHRpb25zO1xuXG4gIC8vIERlcml2ZSB0aGUgY2Fub25pY2FsIGV4aXQgY29kZSBmcm9tIHRoZSBBQ1RVQUwgZXJyb3IgKHNlZSByZXNvbHZlRXhpdENvZGUpLFxuICAvLyBmYWxsaW5nIGJhY2sgdG8gdGhlIGNhbGxlcidzIGBjb2RlYCBmb3IgYW55dGhpbmcgdW5jbGFzc2lmaWFibGUuIFRoaXMgaXMgd2hhdFxuICAvLyBtYWtlcyBldmVyeSBjb21tYW5kIGVtaXQgdGhlIFNBTUUgZXhpdCBjb2RlIGZvciB0aGUgc2FtZSBjbGFzcyBvZiBmYWlsdXJlLFxuICAvLyByYXRoZXIgdGhhbiBhIGJsYW5rZXQgQVBJX1JFUVVFU1QvR0VORVJBTC4gVXNlZCBmb3IgZGlzcGxheSwgdGhlIHN1Z2dlc3Rpb24sXG4gIC8vIGFuZCB0aGUgcHJvY2VzcyBleGl0IGJlbG93LlxuICBjb25zdCByZXNvbHZlZENvZGUgPSByZXNvbHZlRXhpdENvZGUoZXJyLCBjb2RlKTtcblxuICBpZiAobG9nVG9Db25zb2xlKSB7XG4gICAgY29uc3QgZGl2aWRlciA9ICfilIAnLnJlcGVhdChwcm9jZXNzLnN0ZG91dC5jb2x1bW5zIHx8IDgwKTtcbiAgICBjb25zdCBlcnJvcklkID0gYEVSUi0ke2NvcnJlbGF0aW9uSWR9YDtcblxuICAgIGNvbnNvbGUuZXJyb3IoJ1xcbicgKyByZWQoYm9sZCgn4pyXIEVSUk9SJykpICsgZGltKGAgWyR7ZXJyb3JJZH1dYCkgKyAnXFxuJyk7XG4gICAgY29uc29sZS5lcnJvcihkaW0oZGl2aWRlcikpO1xuXG4gICAgaWYgKGVyciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKHJlZChib2xkKCdNZXNzYWdlOicpKSwgZXJyLm1lc3NhZ2UpO1xuXG4gICAgICBpZiAoZXJyLm5hbWUgIT09ICdFcnJvcicpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihyZWQoJ1R5cGU6JyksIGVyci5uYW1lKTtcbiAgICAgIH1cblxuICAgICAgLy8gU2hvdyBWYWxpZGF0aW9uIGVycm9yIGRldGFpbHNcbiAgICAgIGlmIChlcnIgaW5zdGFuY2VvZiBWYWxpZGF0aW9uRXJyb3IpIHtcbiAgICAgICAgaWYgKGVyci5maWVsZCkgY29uc29sZS5lcnJvcihyZWQoJ0ZpZWxkOicpLCBlcnIuZmllbGQpO1xuICAgICAgICBpZiAoZXJyLnZhbHVlICE9PSB1bmRlZmluZWQpIGNvbnNvbGUuZXJyb3IocmVkKCdWYWx1ZTonKSwgc2FuaXRpemVWYWx1ZShlcnIudmFsdWUpKTtcbiAgICAgICAgaWYgKGVyci5ydWxlKSBjb25zb2xlLmVycm9yKHJlZCgnUnVsZTonKSwgZXJyLnJ1bGUpO1xuICAgICAgICBpZiAoZXJyLmV4cGVjdGVkKSBjb25zb2xlLmVycm9yKHJlZCgnRXhwZWN0ZWQ6JyksIGVyci5leHBlY3RlZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNob3cgTmV0d29yayBlcnJvciBkZXRhaWxzXG4gICAgICBpZiAoZXJyIGluc3RhbmNlb2YgTmV0d29ya0Vycm9yKSB7XG4gICAgICAgIGlmIChlcnIudXJsKSBjb25zb2xlLmVycm9yKHJlZCgnVVJMOicpLCBzYW5pdGl6ZVVybChlcnIudXJsKSk7XG4gICAgICAgIGlmIChlcnIudGltZW91dCkgY29uc29sZS5lcnJvcihyZWQoJ1RpbWVvdXQ6JyksIGAke2Vyci50aW1lb3V0fW1zYCk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IocmVkKCdSZXF1ZXN0IE1hZGU6JyksIGVyci5yZXF1ZXN0TWFkZSA/ICdZZXMnIDogJ05vJyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IocmVkKCdSZXNwb25zZSBSZWNlaXZlZDonKSwgZXJyLnJlc3BvbnNlUmVjZWl2ZWQgPyAnWWVzJyA6ICdObycpO1xuICAgICAgICBpZiAoZXJyLmNhdXNlKSBjb25zb2xlLmVycm9yKHJlZCgnQ2F1c2VkIGJ5OicpLCBlcnIuY2F1c2UubWVzc2FnZSk7XG4gICAgICB9XG5cbiAgICAgIC8vIFNob3cgQXhpb3MgZXJyb3IgZGV0YWlsc1xuICAgICAgaWYgKGlzQXhpb3NFcnJvcihlcnIpKSB7XG4gICAgICAgIGNvbnN0IHN0YXR1cyA9IGVyci5yZXNwb25zZT8uc3RhdHVzO1xuICAgICAgICBjb25zdCB1cmwgPSBlcnIuY29uZmlnPy51cmw7XG4gICAgICAgIGlmIChzdGF0dXMpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKHJlZCgnU3RhdHVzOicpLCBzdGF0dXMpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IocmVkKCdTdGF0dXMgVGV4dDonKSwgZ2V0SHR0cFN0YXR1c1RleHQoc3RhdHVzKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVybCkgY29uc29sZS5lcnJvcihyZWQoJ1VSTDonKSwgc2FuaXRpemVVcmwodXJsKSk7XG4gICAgICAgIGlmIChlcnIucmVzcG9uc2U/LmRhdGEpIHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKHJlZCgnUmVzcG9uc2U6JykpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZGltKHNhbml0aXplRXJyb3JEYXRhKGVyci5yZXNwb25zZS5kYXRhKSkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIFNob3cgQ0RLL2V4ZWNTeW5jIGVycm9yIGRldGFpbHMgKHN0ZGVyciBjYXB0dXJlZCBmcm9tIGNoaWxkIHByb2Nlc3MpXG4gICAgICBpZiAoJ3N0ZGVycicgaW4gZXJyICYmIGVyci5zdGRlcnIpIHtcbiAgICAgICAgY29uc3Qgc3RkZXJyID0gKGVyci5zdGRlcnIgYXMgQnVmZmVyIHwgc3RyaW5nKS50b1N0cmluZygpLnRyaW0oKTtcbiAgICAgICAgaWYgKHN0ZGVycikge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IocmVkKCdDREsgT3V0cHV0OicpKTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGRpbShzdGRlcnIpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zb2xlLmVycm9yKHJlZCgnQ29kZTonKSwgZ2V0RXJyb3JDb2RlTmFtZShyZXNvbHZlZENvZGUpKTtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZGltKCdFcnJvciBJRDonKSwgZGltKGVycm9ySWQpKTtcblxuICAgICAgaWYgKGNvbnRleHQgJiYgT2JqZWN0LmtleXMoY29udGV4dCkubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zb2xlLmVycm9yKCcnKTtcbiAgICAgICAgY29uc29sZS5lcnJvcihyZWQoJ0NvbnRleHQ6JykpO1xuICAgICAgICBPYmplY3QuZW50cmllcyhjb250ZXh0KS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGAgICR7Y3lhbihrZXkpfTpgLCBkaW0oc2FuaXRpemVWYWx1ZSh2YWx1ZSkpKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGlmIChkZWJ1ZyAmJiBlcnIuc3RhY2spIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignJyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZGltKCdTdGFjayB0cmFjZTonKSk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZGltKHNhbml0aXplU3RhY2tUcmFjZShlcnIuc3RhY2spKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IocmVkKCdFcnJvcjonKSwgU3RyaW5nKGVycikpO1xuICAgICAgY29uc29sZS5lcnJvcihyZWQoJ0NvZGU6JyksIGdldEVycm9yQ29kZU5hbWUocmVzb2x2ZWRDb2RlKSk7XG4gICAgICBjb25zb2xlLmVycm9yKGRpbSgnRXJyb3IgSUQ6JyksIGRpbShlcnJvcklkKSk7XG4gICAgfVxuXG4gICAgY29uc29sZS5lcnJvcihkaW0oZGl2aWRlcikpO1xuXG4gICAgaWYgKCFkZWJ1Zykge1xuICAgICAgY29uc29sZS5lcnJvcih5ZWxsb3coJ/CfkqEgVGlwOicpLCBkaW0oJ1J1biB3aXRoIC0tZGVidWcgZmxhZyB0byBzZWUgZnVsbCBzdGFjayB0cmFjZScpKTtcbiAgICB9XG5cbiAgICBjb25zdCBzdWdnZXN0aW9uID0gZ2V0RXJyb3JTdWdnZXN0aW9uKGVyciwgcmVzb2x2ZWRDb2RlKTtcbiAgICBpZiAoc3VnZ2VzdGlvbikge1xuICAgICAgY29uc29sZS5lcnJvcih5ZWxsb3coJ/CfkqEgU3VnZ2VzdGlvbjonKSwgZGltKHN1Z2dlc3Rpb24pKTtcbiAgICB9XG5cbiAgICBjb25zb2xlLmVycm9yKCcnKTtcbiAgfVxuXG4gIGlmIChleGl0KSB7XG4gICAgcHJvY2Vzcy5leGl0Q29kZSA9IHJlc29sdmVkQ29kZTtcbiAgICBwcm9jZXNzLmV4aXQocmVzb2x2ZWRDb2RlKTtcbiAgfVxuXG4gIHRocm93IGVycjtcbn1cblxuLy8gLS0tIEVycm9yIGNsYXNzZXMgKG9ubHkgdGhvc2UgYWN0dWFsbHkgdXNlZCkgLS0tXG5cbi8qKlxuICogVmFsaWRhdGlvbiBlcnJvciBjbGFzc1xuICovXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICBjb25zdHJ1Y3RvcihcbiAgICBtZXNzYWdlOiBzdHJpbmcsXG4gICAgcHVibGljIGZpZWxkPzogc3RyaW5nLFxuICAgIHB1YmxpYyB2YWx1ZT86IHVua25vd24sXG4gICAgcHVibGljIHJ1bGU/OiBzdHJpbmcsXG4gICAgcHVibGljIGV4cGVjdGVkPzogc3RyaW5nLFxuICApIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSAnVmFsaWRhdGlvbkVycm9yJztcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgfVxufVxuXG4vKipcbiAqIE5ldHdvcmsgZXJyb3IgY2xhc3NcbiAqL1xuZXhwb3J0IGNsYXNzIE5ldHdvcmtFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZTogc3RyaW5nLFxuICAgIHB1YmxpYyB1cmw/OiBzdHJpbmcsXG4gICAgcHVibGljIGNhdXNlPzogRXJyb3IsXG4gICAgcHVibGljIHRpbWVvdXQ/OiBudW1iZXIsXG4gICAgcHVibGljIHJlcXVlc3RNYWRlOiBib29sZWFuID0gdHJ1ZSxcbiAgICBwdWJsaWMgcmVzcG9uc2VSZWNlaXZlZDogYm9vbGVhbiA9IGZhbHNlLFxuICApIHtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLm5hbWUgPSAnTmV0d29ya0Vycm9yJztcbiAgICBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZSh0aGlzLCB0aGlzLmNvbnN0cnVjdG9yKTtcbiAgfVxufVxuXG4vLyAtLS0gUHJpdmF0ZSBoZWxwZXJzIC0tLVxuXG4vKipcbiAqIE1hcCB0aGUgQUNUVUFMIGVycm9yIHRvIGEgY2Fub25pY2FsIGV4aXQgY29kZSBzbyBldmVyeSBjb21tYW5kIGV4aXRzIHdpdGggdGhlXG4gKiBTQU1FIGNvZGUgZm9yIHRoZSBzYW1lIGNsYXNzIG9mIGZhaWx1cmUuIFRoZSBjYWxsZXItc3VwcGxpZWQgYGZhbGxiYWNrYCAoZS5nLlxuICogQVBJX1JFUVVFU1QpIGlzIHVzZWQgb25seSBmb3IgZXJyb3JzIHRoaXMgY2FuJ3QgY2xhc3NpZnkuIENvZGVzIChzcmMvdHlwZXMvZXJyb3IudHMpOlxuICpcbiAqICAgMSBHRU5FUkFMIMK3IDIgVkFMSURBVElPTiDCtyAzIEFQSV9SRVFVRVNUIMK3IDQgQVVUSEVOVElDQVRJT04gwrcgNSBBVVRIT1JJWkFUSU9OXG4gKiAgIDYgTk9UX0ZPVU5EIMK3IDcgTkVUV09SSyDCtyA4IENPTkZJR1VSQVRJT04gwrcgOSBGSUxFX1NZU1RFTSDCtyAxMCBUSU1FT1VUXG4gKlxuICogUHJlY2VkZW5jZTogdHlwZWQgQ0xJIGVycm9ycyDihpIgSFRUUCBzdGF0dXMg4oaSIE5vZGUgc3lzdGVtIGVycm9yIGBjb2RlYCDihpIgZmFsbGJhY2suXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVFeGl0Q29kZShlcnI6IHVua25vd24sIGZhbGxiYWNrOiBFcnJvckNvZGUpOiBFcnJvckNvZGUge1xuICBpZiAoZXJyIGluc3RhbmNlb2YgVmFsaWRhdGlvbkVycm9yKSByZXR1cm4gRVJST1JfQ09ERVMuVkFMSURBVElPTjtcbiAgaWYgKGVyciBpbnN0YW5jZW9mIE5ldHdvcmtFcnJvcikgcmV0dXJuIGVyci50aW1lb3V0ID8gRVJST1JfQ09ERVMuVElNRU9VVCA6IEVSUk9SX0NPREVTLk5FVFdPUks7XG5cbiAgaWYgKGlzQXhpb3NFcnJvcihlcnIpKSB7XG4gICAgY29uc3Qgc3RhdHVzID0gZXJyLnJlc3BvbnNlPy5zdGF0dXM7XG4gICAgaWYgKHN0YXR1cyA9PT0gNDAwIHx8IHN0YXR1cyA9PT0gNDIyKSByZXR1cm4gRVJST1JfQ09ERVMuVkFMSURBVElPTjtcbiAgICBpZiAoc3RhdHVzID09PSA0MDEpIHJldHVybiBFUlJPUl9DT0RFUy5BVVRIRU5USUNBVElPTjtcbiAgICBpZiAoc3RhdHVzID09PSA0MDMpIHJldHVybiBFUlJPUl9DT0RFUy5BVVRIT1JJWkFUSU9OO1xuICAgIGlmIChzdGF0dXMgPT09IDQwNCkgcmV0dXJuIEVSUk9SX0NPREVTLk5PVF9GT1VORDtcbiAgICBpZiAoc3RhdHVzID09PSA0MDggfHwgc3RhdHVzID09PSA1MDQpIHJldHVybiBFUlJPUl9DT0RFUy5USU1FT1VUO1xuICAgIGlmIChzdGF0dXMgJiYgc3RhdHVzID49IDUwMCkgcmV0dXJuIEVSUk9SX0NPREVTLkFQSV9SRVFVRVNUO1xuICAgIC8vIEEgcmVxdWVzdCB0aGF0IGdvdCBubyBIVFRQIHJlc3BvbnNlIG5ldmVyIHJlYWNoZWQgdGhlIHNlcnZlciAoRE5TIC8gcmVmdXNlZFxuICAgIC8vIC8gcmVzZXQpIOKAlCB0aGF0J3MgYSBuZXR3b3JrIGZhaWx1cmUsIG5vdCBhbiBBUEktcmVzcG9uc2UgZXJyb3IuXG4gICAgaWYgKCFlcnIucmVzcG9uc2UpIHJldHVybiBFUlJPUl9DT0RFUy5ORVRXT1JLO1xuICAgIHJldHVybiBmYWxsYmFjaztcbiAgfVxuXG4gIC8vIE5vZGUgc3lzdGVtIGVycm9ycyAoZnMgKyBzb2NrZXRzKSBjYXJyeSBhIHN0cmluZyBgY29kZWAuXG4gIGNvbnN0IHN5c0NvZGUgPSAoZXJyIGFzIHsgY29kZT86IHVua25vd24gfSB8IG51bGwpPy5jb2RlO1xuICBpZiAodHlwZW9mIHN5c0NvZGUgPT09ICdzdHJpbmcnKSB7XG4gICAgaWYgKFsnRU5PRU5UJywgJ0VBQ0NFUycsICdFSVNESVInLCAnRU5PVERJUicsICdFRVhJU1QnLCAnRVBFUk0nLCAnRU5PU1BDJywgJ0VNRklMRSddLmluY2x1ZGVzKHN5c0NvZGUpKSB7XG4gICAgICByZXR1cm4gRVJST1JfQ09ERVMuRklMRV9TWVNURU07XG4gICAgfVxuICAgIGlmIChzeXNDb2RlID09PSAnRVRJTUVET1VUJykgcmV0dXJuIEVSUk9SX0NPREVTLlRJTUVPVVQ7XG4gICAgaWYgKFsnRUNPTk5SRUZVU0VEJywgJ0VOT1RGT1VORCcsICdFQ09OTlJFU0VUJywgJ0VIT1NUVU5SRUFDSCcsICdFTkVUVU5SRUFDSCcsICdFQUlfQUdBSU4nLCAnRVBJUEUnXS5pbmNsdWRlcyhzeXNDb2RlKSkge1xuICAgICAgcmV0dXJuIEVSUk9SX0NPREVTLk5FVFdPUks7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZhbGxiYWNrO1xufVxuXG5mdW5jdGlvbiBnZXRFcnJvckNvZGVOYW1lKGNvZGU6IEVycm9yQ29kZSk6IHN0cmluZyB7XG4gIGNvbnN0IGVudHJ5ID0gT2JqZWN0LmVudHJpZXMoRVJST1JfQ09ERVMpLmZpbmQoKFtfLCB2YWx1ZV0pID0+IHZhbHVlID09PSBjb2RlKTtcbiAgcmV0dXJuIGVudHJ5ID8gYCR7ZW50cnlbMF19ICgke2NvZGV9KWAgOiBTdHJpbmcoY29kZSk7XG59XG5cbmZ1bmN0aW9uIGdldEh0dHBTdGF0dXNUZXh0KHN0YXR1czogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3Qgc3RhdHVzVGV4dHM6IFJlY29yZDxudW1iZXIsIHN0cmluZz4gPSB7XG4gICAgNDAwOiAnQmFkIFJlcXVlc3QnLFxuICAgIDQwMTogJ1VuYXV0aG9yaXplZCcsXG4gICAgNDAzOiAnRm9yYmlkZGVuJyxcbiAgICA0MDQ6ICdOb3QgRm91bmQnLFxuICAgIDQwODogJ1JlcXVlc3QgVGltZW91dCcsXG4gICAgNDA5OiAnQ29uZmxpY3QnLFxuICAgIDQyMjogJ1VucHJvY2Vzc2FibGUgRW50aXR5JyxcbiAgICA0Mjk6ICdUb28gTWFueSBSZXF1ZXN0cycsXG4gICAgNTAwOiAnSW50ZXJuYWwgU2VydmVyIEVycm9yJyxcbiAgICA1MDI6ICdCYWQgR2F0ZXdheScsXG4gICAgNTAzOiAnU2VydmljZSBVbmF2YWlsYWJsZScsXG4gICAgNTA0OiAnR2F0ZXdheSBUaW1lb3V0JyxcbiAgfTtcbiAgcmV0dXJuIHN0YXR1c1RleHRzW3N0YXR1c10gfHwgJ1Vua25vd24nO1xufVxuXG5mdW5jdGlvbiBnZXRFcnJvclN1Z2dlc3Rpb24oZXJyOiB1bmtub3duLCBjb2RlOiBFcnJvckNvZGUpOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKGNvZGUgPT09IEVSUk9SX0NPREVTLkFVVEhFTlRJQ0FUSU9OKSB7XG4gICAgcmV0dXJuICdDaGVjayB0aGF0IFBMQVRGT1JNX1RPS0VOIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIHNldCBjb3JyZWN0bHknO1xuICB9XG4gIGlmIChjb2RlID09PSBFUlJPUl9DT0RFUy5ORVRXT1JLKSB7XG4gICAgcmV0dXJuICdDaGVjayB5b3VyIGludGVybmV0IGNvbm5lY3Rpb24gYW5kIEFQSSBlbmRwb2ludCBVUkwnO1xuICB9XG4gIGlmIChjb2RlID09PSBFUlJPUl9DT0RFUy5DT05GSUdVUkFUSU9OKSB7XG4gICAgcmV0dXJuICdSdW4gXCJjbGkgdmVyc2lvbiAtLWNoZWNrLWNvbmZpZ1wiIHRvIHZlcmlmeSBjb25maWd1cmF0aW9uJztcbiAgfVxuICBpZiAoY29kZSA9PT0gRVJST1JfQ09ERVMuTk9UX0ZPVU5EKSB7XG4gICAgcmV0dXJuICdWZXJpZnkgdGhlIHJlc291cmNlIElEIGV4aXN0cyBhbmQgeW91IGhhdmUgYWNjZXNzIHRvIGl0JztcbiAgfVxuICBpZiAoZXJyIGluc3RhbmNlb2YgRXJyb3IgJiYgZXJyLm1lc3NhZ2UuaW5jbHVkZXMoJ2NkaycpKSB7XG4gICAgcmV0dXJuICdDaGVjayB0aGUgQ0RLIG91dHB1dCBhYm92ZSBmb3IgQ2xvdWRGb3JtYXRpb24gZXJyb3JzLiBSdW4gd2l0aCAtLWRlYnVnIGZvciBmdWxsIGRldGFpbHMnO1xuICB9XG4gIGlmIChlcnIgaW5zdGFuY2VvZiBWYWxpZGF0aW9uRXJyb3IgJiYgZXJyLmZpZWxkKSB7XG4gICAgcmV0dXJuIGBDaGVjayB0aGUgdmFsdWUgcHJvdmlkZWQgZm9yIFwiJHtlcnIuZmllbGR9XCJgO1xuICB9XG4gIGlmIChpc0F4aW9zRXJyb3IoZXJyKSkge1xuICAgIGNvbnN0IHN0YXR1cyA9IGVyci5yZXNwb25zZT8uc3RhdHVzO1xuICAgIGlmIChzdGF0dXMgPT09IDQwMSB8fCBzdGF0dXMgPT09IDQwMykgcmV0dXJuICdDaGVjayB5b3VyIGF1dGhlbnRpY2F0aW9uIHRva2VuIGFuZCBwZXJtaXNzaW9ucyc7XG4gICAgaWYgKHN0YXR1cyA9PT0gNDI5KSByZXR1cm4gJ1JhdGUgbGltaXQgZXhjZWVkZWQgLSB3YWl0IGEgbW9tZW50IGJlZm9yZSByZXRyeWluZyc7XG4gICAgaWYgKHN0YXR1cyAmJiBzdGF0dXMgPj0gNTAwKSByZXR1cm4gJ1NlcnZlciBlcnJvciAtIHRyeSBhZ2FpbiBsYXRlciBvciBjb250YWN0IHN1cHBvcnQnO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBzYW5pdGl6ZUVycm9yRGF0YShkYXRhOiB1bmtub3duKTogc3RyaW5nIHtcbiAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykgcmV0dXJuIGRhdGE7XG4gIGlmICh0eXBlb2YgZGF0YSA9PT0gJ29iamVjdCcgJiYgZGF0YSAhPT0gbnVsbCkge1xuICAgIGNvbnN0IHNhbml0aXplZCA9IHsgLi4uZGF0YSB9IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuICAgIFsndG9rZW4nLCAncGFzc3dvcmQnLCAnc2VjcmV0JywgJ2FwaUtleScsICdhdXRob3JpemF0aW9uJywgJ2p3dCcsICdjcmVkZW50aWFsJywgJ2JlYXJlciddLmZvckVhY2goZmllbGQgPT4ge1xuICAgICAgaWYgKGZpZWxkIGluIHNhbml0aXplZCkgc2FuaXRpemVkW2ZpZWxkXSA9ICdbUkVEQUNURURdJztcbiAgICB9KTtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoc2FuaXRpemVkLCBudWxsLCAyKTtcbiAgfVxuICByZXR1cm4gU3RyaW5nKGRhdGEpO1xufVxuXG5mdW5jdGlvbiBzYW5pdGl6ZVVybCh1cmw6IHN0cmluZyk6IHN0cmluZyB7XG4gIHRyeSB7XG4gICAgY29uc3QgdXJsT2JqID0gbmV3IFVSTCh1cmwpO1xuICAgIFsndG9rZW4nLCAna2V5JywgJ3NlY3JldCcsICdwYXNzd29yZCcsICdhcGlLZXknXS5mb3JFYWNoKHBhcmFtID0+IHtcbiAgICAgIGlmICh1cmxPYmouc2VhcmNoUGFyYW1zLmhhcyhwYXJhbSkpIHVybE9iai5zZWFyY2hQYXJhbXMuc2V0KHBhcmFtLCAnW1JFREFDVEVEXScpO1xuICAgIH0pO1xuICAgIHJldHVybiB1cmxPYmoudG9TdHJpbmcoKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHVybDtcbiAgfVxufVxuXG5mdW5jdGlvbiBzYW5pdGl6ZVZhbHVlKHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHtcbiAgaWYgKHZhbHVlID09PSBudWxsKSByZXR1cm4gJ251bGwnO1xuICBpZiAodmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuICd1bmRlZmluZWQnO1xuICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgIGlmICh2YWx1ZS5sZW5ndGggPiAyMCAmJiAvXltBLVphLXowLTkrLz1fLV0rJC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBgJHt2YWx1ZS5zdWJzdHJpbmcoMCwgOCl9Li4uW1JFREFDVEVEXWA7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZS5sZW5ndGggPiAxMDAgPyB2YWx1ZS5zdWJzdHJpbmcoMCwgOTcpICsgJy4uLicgOiB2YWx1ZTtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JykgcmV0dXJuIHNhbml0aXplRXJyb3JEYXRhKHZhbHVlKTtcbiAgY29uc3Qgc3RyID0gU3RyaW5nKHZhbHVlKTtcbiAgcmV0dXJuIHN0ci5sZW5ndGggPiAxMDAgPyBzdHIuc3Vic3RyaW5nKDAsIDk3KSArICcuLi4nIDogc3RyO1xufVxuXG5mdW5jdGlvbiBzYW5pdGl6ZVN0YWNrVHJhY2Uoc3RhY2s6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBzdGFjay5zcGxpdCgnXFxuJykuc2xpY2UoMCwgMTApLm1hcChsaW5lID0+IGxpbmUucmVwbGFjZSgvXFwvLio/XFwvL2csICcuLi4vJykpLmpvaW4oJ1xcbicpO1xufVxuXG5mdW5jdGlvbiBpc0F4aW9zRXJyb3IoZXJyOiB1bmtub3duKTogZXJyIGlzIEF4aW9zRXJyb3JMaWtlIHtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgZXJyID09PSAnb2JqZWN0JyAmJlxuICAgIGVyciAhPT0gbnVsbCAmJlxuICAgICdpc0F4aW9zRXJyb3InIGluIGVyciAmJlxuICAgIChlcnIgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pLmlzQXhpb3NFcnJvciA9PT0gdHJ1ZVxuICApO1xufVxuIl19
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Common filter parameters shared by all list commands.
3
+ */
4
+ export interface CommonFilterParams {
5
+ id?: string | string[];
6
+ isActive?: boolean;
7
+ limit?: number;
8
+ offset?: number;
9
+ sort?: string;
10
+ }
11
+ /**
12
+ * Extract common filter parameters (id, isActive, limit, offset, sort) from CLI options.
13
+ */
14
+ export declare function buildCommonFilters(options: Record<string, unknown>): CommonFilterParams;
15
+ /**
16
+ * Display pagination settings for a list command.
17
+ */
18
+ export declare function displayPaginationInfo(filterParams: CommonFilterParams): void;
19
+ /**
20
+ * Display result summary after a list query completes.
21
+ */
22
+ export declare function displayListResults(items: unknown[], total: number | undefined, hasMore: boolean, entityName: string, duration: number, filterParams: CommonFilterParams): void;
23
+ //# sourceMappingURL=list-command-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list-command-utils.d.ts","sourceRoot":"","sources":["../../src/utils/list-command-utils.ts"],"names":[],"mappings":"AASA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB,CAmBvF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAQ5E;AAGD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,OAAO,EAAE,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,kBAAkB,GAC/B,IAAI,CAgBN"}
@@ -0,0 +1,57 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { printInfo, printKeyValue } from './output-utils.js';
4
+ import { formatDuration, validateBoolean, validateNumber, validateSort } from '../config/cli.constants.js';
5
+ /** Default page size when a list command's caller omits --limit. */
6
+ const DEFAULT_LIST_LIMIT = 50;
7
+ /**
8
+ * Extract common filter parameters (id, isActive, limit, offset, sort) from CLI options.
9
+ */
10
+ export function buildCommonFilters(options) {
11
+ const params = {};
12
+ if (options.id) {
13
+ const idValue = options.id;
14
+ params.id = idValue.includes(',') ? idValue.split(',').map((s) => s.trim()) : idValue;
15
+ }
16
+ if (options.isActive !== undefined) {
17
+ params.isActive = validateBoolean(options.isActive, 'is-active');
18
+ }
19
+ params.limit = validateNumber(options.limit, 'limit', 1, 1000);
20
+ params.offset = validateNumber(options.offset, 'offset', 0);
21
+ const sort = validateSort(options.sort);
22
+ if (sort)
23
+ params.sort = sort;
24
+ return params;
25
+ }
26
+ /**
27
+ * Display pagination settings for a list command.
28
+ */
29
+ export function displayPaginationInfo(filterParams) {
30
+ console.log('');
31
+ printInfo('Pagination Settings');
32
+ printKeyValue({
33
+ Limit: (filterParams.limit ?? DEFAULT_LIST_LIMIT).toString(),
34
+ Offset: (filterParams.offset ?? 0).toString(),
35
+ Sort: filterParams.sort || 'createdAt:desc',
36
+ });
37
+ }
38
+ /**
39
+ * Display result summary after a list query completes.
40
+ */
41
+ export function displayListResults(items, total, hasMore, entityName, duration, filterParams) {
42
+ printKeyValue({
43
+ [`${entityName} Found`]: items.length.toString(),
44
+ 'Total Available': total !== undefined ? total.toString() : 'Unknown',
45
+ 'Has More': hasMore ? 'Yes' : 'No',
46
+ 'Request Duration': formatDuration(duration),
47
+ });
48
+ if (hasMore) {
49
+ const currentOffset = filterParams.offset || 0;
50
+ const nextOffset = currentOffset + (filterParams.limit || DEFAULT_LIST_LIMIT);
51
+ console.log('');
52
+ printInfo('More results available', {
53
+ hint: `Use --offset ${nextOffset} to see next page`,
54
+ });
55
+ }
56
+ }
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC1jb21tYW5kLXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0aWxzL2xpc3QtY29tbWFuZC11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBRXRDLE9BQU8sRUFBRSxTQUFTLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDN0QsT0FBTyxFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsY0FBYyxFQUFFLFlBQVksRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRTNHLG9FQUFvRTtBQUNwRSxNQUFNLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztBQWE5Qjs7R0FFRztBQUNILE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxPQUFnQztJQUNqRSxNQUFNLE1BQU0sR0FBdUIsRUFBRSxDQUFDO0lBRXRDLElBQUksT0FBTyxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ2YsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLEVBQVksQ0FBQztRQUNyQyxNQUFNLENBQUMsRUFBRSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBUyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQ2hHLENBQUM7SUFFRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDbkMsTUFBTSxDQUFDLFFBQVEsR0FBRyxlQUFlLENBQUMsT0FBTyxDQUFDLFFBQWtCLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDN0UsQ0FBQztJQUVELE1BQU0sQ0FBQyxLQUFLLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxLQUF3QixFQUFFLE9BQU8sRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDbEYsTUFBTSxDQUFDLE1BQU0sR0FBRyxjQUFjLENBQUMsT0FBTyxDQUFDLE1BQXlCLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRS9FLE1BQU0sSUFBSSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsSUFBMEIsQ0FBQyxDQUFDO0lBQzlELElBQUksSUFBSTtRQUFFLE1BQU0sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0lBRTdCLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxZQUFnQztJQUNwRSxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ2hCLFNBQVMsQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO0lBQ2pDLGFBQWEsQ0FBQztRQUNaLEtBQUssRUFBRSxDQUFDLFlBQVksQ0FBQyxLQUFLLElBQUksa0JBQWtCLENBQUMsQ0FBQyxRQUFRLEVBQUU7UUFDNUQsTUFBTSxFQUFFLENBQUMsWUFBWSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUU7UUFDN0MsSUFBSSxFQUFFLFlBQVksQ0FBQyxJQUFJLElBQUksZ0JBQWdCO0tBQzVDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFHRDs7R0FFRztBQUNILE1BQU0sVUFBVSxrQkFBa0IsQ0FDaEMsS0FBZ0IsRUFDaEIsS0FBeUIsRUFDekIsT0FBZ0IsRUFDaEIsVUFBa0IsRUFDbEIsUUFBZ0IsRUFDaEIsWUFBZ0M7SUFFaEMsYUFBYSxDQUFDO1FBQ1osQ0FBQyxHQUFHLFVBQVUsUUFBUSxDQUFDLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUU7UUFDaEQsaUJBQWlCLEVBQUUsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTO1FBQ3JFLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSTtRQUNsQyxrQkFBa0IsRUFBRSxjQUFjLENBQUMsUUFBUSxDQUFDO0tBQzdDLENBQUMsQ0FBQztJQUVILElBQUksT0FBTyxFQUFFLENBQUM7UUFDWixNQUFNLGFBQWEsR0FBRyxZQUFZLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQztRQUMvQyxNQUFNLFVBQVUsR0FBRyxhQUFhLEdBQUcsQ0FBQyxZQUFZLENBQUMsS0FBSyxJQUFJLGtCQUFrQixDQUFDLENBQUM7UUFDOUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNoQixTQUFTLENBQUMsd0JBQXdCLEVBQUU7WUFDbEMsSUFBSSxFQUFFLGdCQUFnQixVQUFVLG1CQUFtQjtTQUNwRCxDQUFDLENBQUM7SUFDTCxDQUFDO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5pbXBvcnQgeyBwcmludEluZm8sIHByaW50S2V5VmFsdWUgfSBmcm9tICcuL291dHB1dC11dGlscy5qcyc7XG5pbXBvcnQgeyBmb3JtYXREdXJhdGlvbiwgdmFsaWRhdGVCb29sZWFuLCB2YWxpZGF0ZU51bWJlciwgdmFsaWRhdGVTb3J0IH0gZnJvbSAnLi4vY29uZmlnL2NsaS5jb25zdGFudHMuanMnO1xuXG4vKiogRGVmYXVsdCBwYWdlIHNpemUgd2hlbiBhIGxpc3QgY29tbWFuZCdzIGNhbGxlciBvbWl0cyAtLWxpbWl0LiAqL1xuY29uc3QgREVGQVVMVF9MSVNUX0xJTUlUID0gNTA7XG5cbi8qKlxuICogQ29tbW9uIGZpbHRlciBwYXJhbWV0ZXJzIHNoYXJlZCBieSBhbGwgbGlzdCBjb21tYW5kcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb21tb25GaWx0ZXJQYXJhbXMge1xuICBpZD86IHN0cmluZyB8IHN0cmluZ1tdO1xuICBpc0FjdGl2ZT86IGJvb2xlYW47XG4gIGxpbWl0PzogbnVtYmVyO1xuICBvZmZzZXQ/OiBudW1iZXI7XG4gIHNvcnQ/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogRXh0cmFjdCBjb21tb24gZmlsdGVyIHBhcmFtZXRlcnMgKGlkLCBpc0FjdGl2ZSwgbGltaXQsIG9mZnNldCwgc29ydCkgZnJvbSBDTEkgb3B0aW9ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkQ29tbW9uRmlsdGVycyhvcHRpb25zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IENvbW1vbkZpbHRlclBhcmFtcyB7XG4gIGNvbnN0IHBhcmFtczogQ29tbW9uRmlsdGVyUGFyYW1zID0ge307XG5cbiAgaWYgKG9wdGlvbnMuaWQpIHtcbiAgICBjb25zdCBpZFZhbHVlID0gb3B0aW9ucy5pZCBhcyBzdHJpbmc7XG4gICAgcGFyYW1zLmlkID0gaWRWYWx1ZS5pbmNsdWRlcygnLCcpID8gaWRWYWx1ZS5zcGxpdCgnLCcpLm1hcCgoczogc3RyaW5nKSA9PiBzLnRyaW0oKSkgOiBpZFZhbHVlO1xuICB9XG5cbiAgaWYgKG9wdGlvbnMuaXNBY3RpdmUgIT09IHVuZGVmaW5lZCkge1xuICAgIHBhcmFtcy5pc0FjdGl2ZSA9IHZhbGlkYXRlQm9vbGVhbihvcHRpb25zLmlzQWN0aXZlIGFzIHN0cmluZywgJ2lzLWFjdGl2ZScpO1xuICB9XG5cbiAgcGFyYW1zLmxpbWl0ID0gdmFsaWRhdGVOdW1iZXIob3B0aW9ucy5saW1pdCBhcyBzdHJpbmcgfCBudW1iZXIsICdsaW1pdCcsIDEsIDEwMDApO1xuICBwYXJhbXMub2Zmc2V0ID0gdmFsaWRhdGVOdW1iZXIob3B0aW9ucy5vZmZzZXQgYXMgc3RyaW5nIHwgbnVtYmVyLCAnb2Zmc2V0JywgMCk7XG5cbiAgY29uc3Qgc29ydCA9IHZhbGlkYXRlU29ydChvcHRpb25zLnNvcnQgYXMgc3RyaW5nIHwgdW5kZWZpbmVkKTtcbiAgaWYgKHNvcnQpIHBhcmFtcy5zb3J0ID0gc29ydDtcblxuICByZXR1cm4gcGFyYW1zO1xufVxuXG4vKipcbiAqIERpc3BsYXkgcGFnaW5hdGlvbiBzZXR0aW5ncyBmb3IgYSBsaXN0IGNvbW1hbmQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXNwbGF5UGFnaW5hdGlvbkluZm8oZmlsdGVyUGFyYW1zOiBDb21tb25GaWx0ZXJQYXJhbXMpOiB2b2lkIHtcbiAgY29uc29sZS5sb2coJycpO1xuICBwcmludEluZm8oJ1BhZ2luYXRpb24gU2V0dGluZ3MnKTtcbiAgcHJpbnRLZXlWYWx1ZSh7XG4gICAgTGltaXQ6IChmaWx0ZXJQYXJhbXMubGltaXQgPz8gREVGQVVMVF9MSVNUX0xJTUlUKS50b1N0cmluZygpLFxuICAgIE9mZnNldDogKGZpbHRlclBhcmFtcy5vZmZzZXQgPz8gMCkudG9TdHJpbmcoKSxcbiAgICBTb3J0OiBmaWx0ZXJQYXJhbXMuc29ydCB8fCAnY3JlYXRlZEF0OmRlc2MnLFxuICB9KTtcbn1cblxuXG4vKipcbiAqIERpc3BsYXkgcmVzdWx0IHN1bW1hcnkgYWZ0ZXIgYSBsaXN0IHF1ZXJ5IGNvbXBsZXRlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRpc3BsYXlMaXN0UmVzdWx0cyhcbiAgaXRlbXM6IHVua25vd25bXSxcbiAgdG90YWw6IG51bWJlciB8IHVuZGVmaW5lZCxcbiAgaGFzTW9yZTogYm9vbGVhbixcbiAgZW50aXR5TmFtZTogc3RyaW5nLFxuICBkdXJhdGlvbjogbnVtYmVyLFxuICBmaWx0ZXJQYXJhbXM6IENvbW1vbkZpbHRlclBhcmFtcyxcbik6IHZvaWQge1xuICBwcmludEtleVZhbHVlKHtcbiAgICBbYCR7ZW50aXR5TmFtZX0gRm91bmRgXTogaXRlbXMubGVuZ3RoLnRvU3RyaW5nKCksXG4gICAgJ1RvdGFsIEF2YWlsYWJsZSc6IHRvdGFsICE9PSB1bmRlZmluZWQgPyB0b3RhbC50b1N0cmluZygpIDogJ1Vua25vd24nLFxuICAgICdIYXMgTW9yZSc6IGhhc01vcmUgPyAnWWVzJyA6ICdObycsXG4gICAgJ1JlcXVlc3QgRHVyYXRpb24nOiBmb3JtYXREdXJhdGlvbihkdXJhdGlvbiksXG4gIH0pO1xuXG4gIGlmIChoYXNNb3JlKSB7XG4gICAgY29uc3QgY3VycmVudE9mZnNldCA9IGZpbHRlclBhcmFtcy5vZmZzZXQgfHwgMDtcbiAgICBjb25zdCBuZXh0T2Zmc2V0ID0gY3VycmVudE9mZnNldCArIChmaWx0ZXJQYXJhbXMubGltaXQgfHwgREVGQVVMVF9MSVNUX0xJTUlUKTtcbiAgICBjb25zb2xlLmxvZygnJyk7XG4gICAgcHJpbnRJbmZvKCdNb3JlIHJlc3VsdHMgYXZhaWxhYmxlJywge1xuICAgICAgaGludDogYFVzZSAtLW9mZnNldCAke25leHRPZmZzZXR9IHRvIHNlZSBuZXh0IHBhZ2VgLFxuICAgIH0pO1xuICB9XG59XG4iXX0=