@camunda8/cli 2.6.0-alpha.17 → 2.6.0-alpha.19

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 (132) hide show
  1. package/README.md +4 -1
  2. package/dist/client.d.ts +10 -2
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/client.js +7 -17
  5. package/dist/client.js.map +1 -1
  6. package/dist/commands/completion.d.ts.map +1 -1
  7. package/dist/commands/completion.js +41 -41
  8. package/dist/commands/completion.js.map +1 -1
  9. package/dist/commands/deployments.d.ts.map +1 -1
  10. package/dist/commands/deployments.js +158 -131
  11. package/dist/commands/deployments.js.map +1 -1
  12. package/dist/commands/forms.d.ts.map +1 -1
  13. package/dist/commands/forms.js +52 -28
  14. package/dist/commands/forms.js.map +1 -1
  15. package/dist/commands/help.d.ts.map +1 -1
  16. package/dist/commands/help.js +587 -169
  17. package/dist/commands/help.js.map +1 -1
  18. package/dist/commands/identity-authorizations.d.ts +1 -1
  19. package/dist/commands/identity-authorizations.d.ts.map +1 -1
  20. package/dist/commands/identity-authorizations.js +45 -33
  21. package/dist/commands/identity-authorizations.js.map +1 -1
  22. package/dist/commands/identity-groups.d.ts +2 -1
  23. package/dist/commands/identity-groups.d.ts.map +1 -1
  24. package/dist/commands/identity-groups.js +24 -21
  25. package/dist/commands/identity-groups.js.map +1 -1
  26. package/dist/commands/identity-mapping-rules.d.ts +1 -1
  27. package/dist/commands/identity-mapping-rules.d.ts.map +1 -1
  28. package/dist/commands/identity-mapping-rules.js +23 -24
  29. package/dist/commands/identity-mapping-rules.js.map +1 -1
  30. package/dist/commands/identity-roles.d.ts +2 -1
  31. package/dist/commands/identity-roles.d.ts.map +1 -1
  32. package/dist/commands/identity-roles.js +23 -20
  33. package/dist/commands/identity-roles.js.map +1 -1
  34. package/dist/commands/identity-tenants.d.ts +1 -1
  35. package/dist/commands/identity-tenants.d.ts.map +1 -1
  36. package/dist/commands/identity-tenants.js +22 -22
  37. package/dist/commands/identity-tenants.js.map +1 -1
  38. package/dist/commands/identity-users.d.ts +1 -1
  39. package/dist/commands/identity-users.d.ts.map +1 -1
  40. package/dist/commands/identity-users.js +24 -26
  41. package/dist/commands/identity-users.js.map +1 -1
  42. package/dist/commands/identity.d.ts +6 -6
  43. package/dist/commands/identity.d.ts.map +1 -1
  44. package/dist/commands/identity.js +170 -105
  45. package/dist/commands/identity.js.map +1 -1
  46. package/dist/commands/incidents.d.ts +1 -1
  47. package/dist/commands/incidents.d.ts.map +1 -1
  48. package/dist/commands/incidents.js +19 -17
  49. package/dist/commands/incidents.js.map +1 -1
  50. package/dist/commands/jobs.d.ts +1 -1
  51. package/dist/commands/jobs.d.ts.map +1 -1
  52. package/dist/commands/jobs.js +39 -39
  53. package/dist/commands/jobs.js.map +1 -1
  54. package/dist/commands/mcp-proxy.d.ts +2 -2
  55. package/dist/commands/mcp-proxy.d.ts.map +1 -1
  56. package/dist/commands/mcp-proxy.js +34 -33
  57. package/dist/commands/mcp-proxy.js.map +1 -1
  58. package/dist/commands/messages.d.ts.map +1 -1
  59. package/dist/commands/messages.js +23 -21
  60. package/dist/commands/messages.js.map +1 -1
  61. package/dist/commands/open.d.ts +2 -1
  62. package/dist/commands/open.d.ts.map +1 -1
  63. package/dist/commands/open.js +29 -20
  64. package/dist/commands/open.js.map +1 -1
  65. package/dist/commands/plugins.d.ts.map +1 -1
  66. package/dist/commands/plugins.js +184 -140
  67. package/dist/commands/plugins.js.map +1 -1
  68. package/dist/commands/process-definitions.d.ts +1 -1
  69. package/dist/commands/process-definitions.d.ts.map +1 -1
  70. package/dist/commands/process-definitions.js +10 -10
  71. package/dist/commands/process-definitions.js.map +1 -1
  72. package/dist/commands/process-instances.d.ts +2 -2
  73. package/dist/commands/process-instances.d.ts.map +1 -1
  74. package/dist/commands/process-instances.js +49 -45
  75. package/dist/commands/process-instances.js.map +1 -1
  76. package/dist/commands/profiles.d.ts.map +1 -1
  77. package/dist/commands/profiles.js +27 -27
  78. package/dist/commands/profiles.js.map +1 -1
  79. package/dist/commands/run.d.ts.map +1 -1
  80. package/dist/commands/run.js +21 -17
  81. package/dist/commands/run.js.map +1 -1
  82. package/dist/commands/search.d.ts +3 -3
  83. package/dist/commands/search.d.ts.map +1 -1
  84. package/dist/commands/search.js +227 -145
  85. package/dist/commands/search.js.map +1 -1
  86. package/dist/commands/session.d.ts.map +1 -1
  87. package/dist/commands/session.js +8 -8
  88. package/dist/commands/session.js.map +1 -1
  89. package/dist/commands/topology.d.ts.map +1 -1
  90. package/dist/commands/topology.js +2 -2
  91. package/dist/commands/topology.js.map +1 -1
  92. package/dist/commands/user-tasks.d.ts +1 -1
  93. package/dist/commands/user-tasks.d.ts.map +1 -1
  94. package/dist/commands/user-tasks.js +25 -23
  95. package/dist/commands/user-tasks.js.map +1 -1
  96. package/dist/commands/watch.d.ts.map +1 -1
  97. package/dist/commands/watch.js +25 -21
  98. package/dist/commands/watch.js.map +1 -1
  99. package/dist/config.d.ts +3 -3
  100. package/dist/config.d.ts.map +1 -1
  101. package/dist/config.js +95 -89
  102. package/dist/config.js.map +1 -1
  103. package/dist/date-filter.d.ts.map +1 -1
  104. package/dist/date-filter.js +10 -8
  105. package/dist/date-filter.js.map +1 -1
  106. package/dist/errors.d.ts +1 -1
  107. package/dist/errors.d.ts.map +1 -1
  108. package/dist/errors.js +1 -1
  109. package/dist/errors.js.map +1 -1
  110. package/dist/ignore.d.ts +1 -1
  111. package/dist/ignore.d.ts.map +1 -1
  112. package/dist/ignore.js +9 -13
  113. package/dist/ignore.js.map +1 -1
  114. package/dist/index.d.ts +5 -1
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +591 -475
  117. package/dist/index.js.map +1 -1
  118. package/dist/logger.d.ts +7 -7
  119. package/dist/logger.d.ts.map +1 -1
  120. package/dist/logger.js +78 -55
  121. package/dist/logger.js.map +1 -1
  122. package/dist/plugin-loader.d.ts.map +1 -1
  123. package/dist/plugin-loader.js +37 -34
  124. package/dist/plugin-loader.js.map +1 -1
  125. package/dist/plugin-registry.d.ts.map +1 -1
  126. package/dist/plugin-registry.js +22 -12
  127. package/dist/plugin-registry.js.map +1 -1
  128. package/dist/runtime.d.ts +2 -2
  129. package/dist/runtime.d.ts.map +1 -1
  130. package/dist/runtime.js +10 -9
  131. package/dist/runtime.js.map +1 -1
  132. package/package.json +4 -2
@@ -1,22 +1,23 @@
1
1
  /**
2
2
  * Deployment commands with building-block folder prioritization
3
3
  */
4
- import { getLogger } from "../logger.js";
4
+ import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
5
+ import { basename, dirname, extname, join, relative, resolve } from "node:path";
6
+ import { TenantId } from "@camunda8/orchestration-cluster-api";
5
7
  import { createClient } from "../client.js";
6
- import { resolveTenantId, resolveClusterConfig } from "../config.js";
7
- import { TenantId } from '@camunda8/orchestration-cluster-api';
8
+ import { resolveClusterConfig, resolveTenantId } from "../config.js";
9
+ import { isIgnored, loadIgnoreRules } from "../ignore.js";
10
+ import { isRecord } from "../index.js";
11
+ import { getLogger } from "../logger.js";
8
12
  import { c8ctl } from "../runtime.js";
9
- import { readFileSync, readdirSync, statSync, existsSync } from 'node:fs';
10
- import { join, dirname, extname, basename, relative, resolve } from 'node:path';
11
- import { loadIgnoreRules, isIgnored } from "../ignore.js";
12
- const RESOURCE_EXTENSIONS = ['.bpmn', '.dmn', '.form'];
13
- const PROCESS_APPLICATION_FILE = '.process-application';
13
+ const RESOURCE_EXTENSIONS = [".bpmn", ".dmn", ".form"];
14
+ const PROCESS_APPLICATION_FILE = ".process-application";
14
15
  /**
15
16
  * Helper to output messages that respect JSON mode for Unix pipe compatibility
16
17
  */
17
18
  function logMessage(message) {
18
- if (c8ctl.outputMode === 'json') {
19
- console.error(JSON.stringify({ type: 'message', message }));
19
+ if (c8ctl.outputMode === "json") {
20
+ console.error(JSON.stringify({ type: "message", message }));
20
21
  }
21
22
  else {
22
23
  console.error(message);
@@ -26,18 +27,18 @@ function logMessage(message) {
26
27
  * Extract process/decision IDs from BPMN/DMN files to detect duplicates
27
28
  */
28
29
  function extractDefinitionId(content, extension) {
29
- const text = content.toString('utf-8');
30
- if (extension === '.bpmn') {
30
+ const text = content.toString("utf-8");
31
+ if (extension === ".bpmn") {
31
32
  // Extract bpmn:process id attribute
32
33
  const match = text.match(/<bpmn\d?:process[^>]+id="([^"]+)"/);
33
34
  return match ? match[1] : null;
34
35
  }
35
- else if (extension === '.dmn') {
36
+ else if (extension === ".dmn") {
36
37
  // Extract decision id attribute
37
38
  const match = text.match(/<decision[^>]+id="([^"]+)"/);
38
39
  return match ? match[1] : null;
39
40
  }
40
- else if (extension === '.form') {
41
+ else if (extension === ".form") {
41
42
  // Forms are identified by filename, not internal ID
42
43
  return null;
43
44
  }
@@ -47,7 +48,7 @@ function extractDefinitionId(content, extension) {
47
48
  * Check if a path is a building block folder (contains _bb- in name)
48
49
  */
49
50
  function isBuildingBlockFolder(path) {
50
- return basename(path).includes('_bb-');
51
+ return basename(path).includes("_bb-");
51
52
  }
52
53
  /**
53
54
  * Check if a directory contains a .process-application file
@@ -66,16 +67,16 @@ function findGroupRoot(filePath, basePath) {
66
67
  while (true) {
67
68
  // Check if we've gone outside the basePath
68
69
  const rel = relative(basePath, currentDir);
69
- if (rel.startsWith('..') || rel === '') {
70
+ if (rel.startsWith("..") || rel === "") {
70
71
  break;
71
72
  }
72
73
  // Check if this directory is a building block
73
74
  if (isBuildingBlockFolder(currentDir)) {
74
- return { type: 'bb', root: currentDir };
75
+ return { type: "bb", root: currentDir };
75
76
  }
76
77
  // Check if this directory has a .process-application file
77
78
  if (hasProcessApplicationFile(currentDir)) {
78
- return { type: 'pa', root: currentDir };
79
+ return { type: "pa", root: currentDir };
79
80
  }
80
81
  // Move up one level
81
82
  const parentDir = dirname(currentDir);
@@ -108,8 +109,8 @@ function collectResourceFiles(dirPath, collected = [], basePath, ig, ignoreBaseD
108
109
  path: dirPath,
109
110
  name: basename(dirPath),
110
111
  content: readFileSync(dirPath),
111
- isBuildingBlock: groupInfo.type === 'bb',
112
- isProcessApplication: groupInfo.type === 'pa',
112
+ isBuildingBlock: groupInfo.type === "bb",
113
+ isProcessApplication: groupInfo.type === "pa",
113
114
  groupPath: groupInfo.root || undefined,
114
115
  });
115
116
  }
@@ -117,7 +118,7 @@ function collectResourceFiles(dirPath, collected = [], basePath, ig, ignoreBaseD
117
118
  }
118
119
  if (stat.isDirectory()) {
119
120
  // Skip entire directory if it matches an ignore rule
120
- if (ig && ignoreBaseDir && isIgnored(ig, dirPath + '/', ignoreBaseDir)) {
121
+ if (ig && ignoreBaseDir && isIgnored(ig, `${dirPath}/`, ignoreBaseDir)) {
121
122
  return collected;
122
123
  }
123
124
  const entries = readdirSync(dirPath);
@@ -125,12 +126,14 @@ function collectResourceFiles(dirPath, collected = [], basePath, ig, ignoreBaseD
125
126
  const bbFolders = [];
126
127
  const regularFolders = [];
127
128
  const files = [];
128
- entries.forEach(entry => {
129
+ entries.forEach((entry) => {
129
130
  const fullPath = join(dirPath, entry);
130
131
  const entryStat = statSync(fullPath);
131
132
  if (entryStat.isDirectory()) {
132
133
  // Skip ignored directories early to avoid descending into them
133
- if (ig && ignoreBaseDir && isIgnored(ig, fullPath + '/', ignoreBaseDir)) {
134
+ if (ig &&
135
+ ignoreBaseDir &&
136
+ isIgnored(ig, `${fullPath}/`, ignoreBaseDir)) {
134
137
  return;
135
138
  }
136
139
  if (isBuildingBlockFolder(entry)) {
@@ -149,7 +152,7 @@ function collectResourceFiles(dirPath, collected = [], basePath, ig, ignoreBaseD
149
152
  }
150
153
  });
151
154
  // Process files in current directory first
152
- files.forEach(file => {
155
+ files.forEach((file) => {
153
156
  const ext = extname(file);
154
157
  if (RESOURCE_EXTENSIONS.includes(ext)) {
155
158
  const groupInfo = findGroupRoot(file, basePath);
@@ -157,18 +160,18 @@ function collectResourceFiles(dirPath, collected = [], basePath, ig, ignoreBaseD
157
160
  path: file,
158
161
  name: basename(file),
159
162
  content: readFileSync(file),
160
- isBuildingBlock: groupInfo.type === 'bb',
161
- isProcessApplication: groupInfo.type === 'pa',
163
+ isBuildingBlock: groupInfo.type === "bb",
164
+ isProcessApplication: groupInfo.type === "pa",
162
165
  groupPath: groupInfo.root || undefined,
163
166
  });
164
167
  }
165
168
  });
166
169
  // Process building block folders first (prioritized)
167
- bbFolders.forEach(bbFolder => {
170
+ bbFolders.forEach((bbFolder) => {
168
171
  collectResourceFiles(bbFolder, collected, basePath, ig, ignoreBaseDir);
169
172
  });
170
173
  // Then process regular folders
171
- regularFolders.forEach(regularFolder => {
174
+ regularFolders.forEach((regularFolder) => {
172
175
  collectResourceFiles(regularFolder, collected, basePath, ig, ignoreBaseDir);
173
176
  });
174
177
  }
@@ -180,7 +183,7 @@ function collectResourceFiles(dirPath, collected = [], basePath, ig, ignoreBaseD
180
183
  function findDuplicateDefinitionIds(resources) {
181
184
  const idMap = resources.reduce((map, r) => {
182
185
  const ext = extname(r.path);
183
- if (ext === '.bpmn' || ext === '.dmn') {
186
+ if (ext === ".bpmn" || ext === ".dmn") {
184
187
  const defId = extractDefinitionId(r.content, ext);
185
188
  if (defId)
186
189
  map.set(defId, [...(map.get(defId) ?? []), r.path]);
@@ -200,18 +203,18 @@ export async function deploy(paths, options) {
200
203
  // Store the base paths for relative path calculation
201
204
  const basePaths = paths.length === 0 ? [process.cwd()] : paths;
202
205
  if (paths.length === 0) {
203
- logger.error('No paths provided. Use: c8 deploy <path> or c8 deploy (for current directory)');
206
+ logger.error("No paths provided. Use: c8 deploy <path> or c8 deploy (for current directory)");
204
207
  process.exit(1);
205
208
  }
206
209
  // Load .c8ignore rules from the working directory
207
210
  const ignoreBaseDir = resolve(process.cwd());
208
211
  const ig = loadIgnoreRules(ignoreBaseDir);
209
212
  // Collect all resource files (respecting .c8ignore)
210
- paths.forEach(path => {
213
+ paths.forEach((path) => {
211
214
  collectResourceFiles(path, resources, undefined, ig, ignoreBaseDir);
212
215
  });
213
216
  if (resources.length === 0) {
214
- logger.error('No BPMN/DMN/Form files found in the specified paths');
217
+ logger.error("No BPMN/DMN/Form files found in the specified paths");
215
218
  process.exit(1);
216
219
  }
217
220
  // Dry-run: emit the would-be API request without executing
@@ -219,12 +222,12 @@ export async function deploy(paths, options) {
219
222
  const config = resolveClusterConfig(options.profile);
220
223
  logger.json({
221
224
  dryRun: true,
222
- command: 'deploy',
223
- method: 'POST',
225
+ command: "deploy",
226
+ method: "POST",
224
227
  url: `${config.baseUrl}/deployments`,
225
228
  body: {
226
229
  tenantId,
227
- resources: resources.map(r => ({ name: r.name })),
230
+ resources: resources.map((r) => ({ name: r.name })),
228
231
  },
229
232
  });
230
233
  return;
@@ -232,7 +235,7 @@ export async function deploy(paths, options) {
232
235
  const client = createClient(options.profile);
233
236
  // Calculate relative paths for display
234
237
  const basePath = basePaths.length === 1 ? basePaths[0] : process.cwd();
235
- resources.forEach(r => {
238
+ resources.forEach((r) => {
236
239
  r.relativePath = relative(basePath, r.path) || r.name;
237
240
  });
238
241
  // Sort: group resources by their group, with building blocks first, then process applications, then standalone
@@ -271,77 +274,84 @@ export async function deploy(paths, options) {
271
274
  // Validate for duplicate process/decision IDs
272
275
  const duplicates = findDuplicateDefinitionIds(resources);
273
276
  if (duplicates.size > 0) {
274
- logger.error('Cannot deploy: Multiple files with the same process/decision ID in one deployment');
275
- duplicates.forEach((paths, id) => logMessage(` Process/Decision ID "${id}" found in: ${paths.join(', ')}`));
276
- logMessage('\nCamunda does not allow deploying multiple resources with the same definition ID in a single deployment.');
277
- logMessage('Please deploy these files separately or ensure each process/decision has a unique ID.');
277
+ logger.error("Cannot deploy: Multiple files with the same process/decision ID in one deployment");
278
+ duplicates.forEach((paths, id) => {
279
+ logMessage(` Process/Decision ID "${id}" found in: ${paths.join(", ")}`);
280
+ });
281
+ logMessage("\nCamunda does not allow deploying multiple resources with the same definition ID in a single deployment.");
282
+ logMessage("Please deploy these files separately or ensure each process/decision has a unique ID.");
278
283
  process.exit(1);
279
284
  }
280
285
  logger.info(`Deploying ${resources.length} resource(s)...`);
281
286
  // Create a mapping from definition ID to resource file for later reference
282
287
  const definitionIdToResource = new Map();
283
288
  const formNameToResource = new Map();
284
- resources.forEach(r => {
289
+ resources.forEach((r) => {
285
290
  const ext = extname(r.path);
286
- if (ext === '.bpmn' || ext === '.dmn') {
291
+ if (ext === ".bpmn" || ext === ".dmn") {
287
292
  const defId = extractDefinitionId(r.content, ext);
288
293
  if (defId) {
289
294
  definitionIdToResource.set(defId, r);
290
295
  }
291
296
  }
292
- else if (ext === '.form') {
297
+ else if (ext === ".form") {
293
298
  // Forms are matched by filename (without extension)
294
- const formId = basename(r.name, '.form');
299
+ const formId = basename(r.name, ".form");
295
300
  formNameToResource.set(formId, r);
296
301
  }
297
302
  });
298
303
  // Create deployment request - convert buffers to File objects with proper MIME types
299
304
  const result = await client.createDeployment({
300
305
  tenantId: TenantId.assumeExists(tenantId),
301
- resources: resources.map(r => {
306
+ resources: resources.map((r) => {
302
307
  // Determine MIME type based on extension
303
- const ext = r.name.split('.').pop()?.toLowerCase();
304
- const mimeType = ext === 'bpmn' ? 'application/xml' :
305
- ext === 'dmn' ? 'application/xml' :
306
- ext === 'form' ? 'application/json' :
307
- 'application/octet-stream';
308
+ const ext = r.name.split(".").pop()?.toLowerCase();
309
+ const mimeType = ext === "bpmn"
310
+ ? "application/xml"
311
+ : ext === "dmn"
312
+ ? "application/xml"
313
+ : ext === "form"
314
+ ? "application/json"
315
+ : "application/octet-stream";
308
316
  // Convert Buffer to Uint8Array for File constructor
309
- return new File([new Uint8Array(r.content)], r.name, { type: mimeType });
317
+ return new File([new Uint8Array(r.content)], r.name, {
318
+ type: mimeType,
319
+ });
310
320
  }),
311
321
  });
312
- logger.success('Deployment successful', result.deploymentKey.toString());
322
+ logger.success("Deployment successful", result.deploymentKey.toString());
313
323
  // Normalize all deployed resources into a common structure
314
324
  const allResources = [
315
- ...result.processes.map(proc => ({
316
- type: 'Process',
325
+ ...result.processes.map((proc) => ({
326
+ type: "Process",
317
327
  id: proc.processDefinitionId,
318
328
  version: proc.processDefinitionVersion,
319
329
  key: proc.processDefinitionKey.toString(),
320
330
  resource: definitionIdToResource.get(proc.processDefinitionId),
321
331
  })),
322
- ...result.decisions.map(dec => ({
323
- type: 'Decision',
324
- id: dec.decisionDefinitionId || '-',
325
- version: dec.version ?? '-',
326
- key: dec.decisionDefinitionKey?.toString() || '-',
327
- resource: definitionIdToResource.get(dec.decisionDefinitionId || ''),
332
+ ...result.decisions.map((dec) => ({
333
+ type: "Decision",
334
+ id: dec.decisionDefinitionId || "-",
335
+ version: dec.version ?? "-",
336
+ key: dec.decisionDefinitionKey?.toString() || "-",
337
+ resource: definitionIdToResource.get(dec.decisionDefinitionId || ""),
328
338
  })),
329
- ...result.forms.map(form => ({
330
- type: 'Form',
331
- id: form.formId || '-',
332
- version: form.version ?? '-',
333
- key: form.formKey?.toString() || '-',
334
- resource: formNameToResource.get(form.formId || ''),
339
+ ...result.forms.map((form) => ({
340
+ type: "Form",
341
+ id: form.formId || "-",
342
+ version: form.version ?? "-",
343
+ key: form.formKey?.toString() || "-",
344
+ resource: formNameToResource.get(form.formId || ""),
335
345
  })),
336
346
  ];
337
347
  const tableData = allResources.map(({ type, id, version, key, resource }) => {
338
348
  const fileDisplay = resource
339
- ? `${resource.isBuildingBlock ? '🧱 ' : ''}${resource.isProcessApplication ? '📦 ' : ''}${resource.relativePath || resource.name}`
340
- : '-';
349
+ ? `${resource.isBuildingBlock ? "🧱 " : ""}${resource.isProcessApplication ? "📦 " : ""}${resource.relativePath || resource.name}`
350
+ : "-";
341
351
  // Extract directory path for grouping (e.g., "bla/_bb-building-block" or "pa")
342
352
  const sortKey = resource?.relativePath
343
- ? resource.relativePath.substring(0, resource.relativePath.lastIndexOf('/') + 1) || resource.relativePath
344
- : 'zzz'; // Resources without paths go last
353
+ ? resource.relativePath.substring(0, resource.relativePath.lastIndexOf("/") + 1) || resource.relativePath
354
+ : "zzz"; // Resources without paths go last
345
355
  return {
346
356
  File: fileDisplay,
347
357
  Type: type,
@@ -359,7 +369,13 @@ export async function deploy(paths, options) {
359
369
  return a.File.localeCompare(b.File);
360
370
  });
361
371
  // Remove sortKey before displaying
362
- const displayData = tableData.map(({ File, Type, ID, Version, Key }) => ({ File, Type, ID, Version, Key }));
372
+ const displayData = tableData.map(({ File, Type, ID, Version, Key }) => ({
373
+ File,
374
+ Type,
375
+ ID,
376
+ Version,
377
+ Key,
378
+ }));
363
379
  if (displayData.length > 0) {
364
380
  logger.table(displayData);
365
381
  }
@@ -373,9 +389,9 @@ export async function deploy(paths, options) {
373
389
  */
374
390
  function handleDeploymentError(error, resources, logger, continueOnError, continueOnUserError) {
375
391
  // Extract problem title early to determine whether this is a user-fixable error
376
- const raw = (error && typeof error === 'object') ? error : {};
377
- const problemTitle = typeof raw.title === 'string' ? raw.title : undefined;
378
- const isUserFixable = problemTitle === 'INVALID_ARGUMENT';
392
+ const raw = isRecord(error) ? error : {};
393
+ const problemTitle = typeof raw.title === "string" ? raw.title : undefined;
394
+ const isUserFixable = problemTitle === "INVALID_ARGUMENT";
379
395
  const shouldContinue = continueOnError || (continueOnUserError && isUserFixable);
380
396
  if (c8ctl.verbose) {
381
397
  if (shouldContinue) {
@@ -387,56 +403,56 @@ function handleDeploymentError(error, resources, logger, continueOnError, contin
387
403
  }
388
404
  // Try to interpret common transport/network issues first for actionable guidance
389
405
  const deriveNetworkErrorTitle = (err) => {
390
- const anyErr = err;
391
- const code = typeof anyErr?.code === 'string'
406
+ const anyErr = isRecord(err) ? err : {};
407
+ const code = typeof anyErr.code === "string"
392
408
  ? anyErr.code
393
- : (typeof anyErr?.cause?.code === 'string'
409
+ : isRecord(anyErr.cause) && typeof anyErr.cause.code === "string"
394
410
  ? anyErr.cause.code
395
- : undefined);
396
- if (!code && typeof anyErr?.name === 'string') {
411
+ : undefined;
412
+ if (!code && typeof anyErr?.name === "string") {
397
413
  // Handle fetch/abort style errors
398
- if (anyErr.name === 'AbortError') {
399
- return 'Request to Camunda cluster timed out or was aborted. Please check your network connection and try again.';
414
+ if (anyErr.name === "AbortError") {
415
+ return "Request to Camunda cluster timed out or was aborted. Please check your network connection and try again.";
400
416
  }
401
417
  }
402
418
  switch (code) {
403
- case 'ECONNREFUSED':
404
- return 'Cannot connect to Camunda cluster (connection refused). Verify the endpoint URL and that the cluster is reachable.';
405
- case 'ENOTFOUND':
406
- return 'Cannot resolve Camunda cluster host. Check the cluster URL and your DNS/network configuration.';
407
- case 'EHOSTUNREACH':
408
- return 'Camunda cluster host is unreachable. Check VPN/proxy settings and your network connectivity.';
409
- case 'ECONNRESET':
410
- return 'Connection to Camunda cluster was reset. Retry the operation and check for intermittent network issues.';
411
- case 'ETIMEDOUT':
412
- return 'Request to Camunda cluster timed out. Check your network connection and consider retrying.';
419
+ case "ECONNREFUSED":
420
+ return "Cannot connect to Camunda cluster (connection refused). Verify the endpoint URL and that the cluster is reachable.";
421
+ case "ENOTFOUND":
422
+ return "Cannot resolve Camunda cluster host. Check the cluster URL and your DNS/network configuration.";
423
+ case "EHOSTUNREACH":
424
+ return "Camunda cluster host is unreachable. Check VPN/proxy settings and your network connectivity.";
425
+ case "ECONNRESET":
426
+ return "Connection to Camunda cluster was reset. Retry the operation and check for intermittent network issues.";
427
+ case "ETIMEDOUT":
428
+ return "Request to Camunda cluster timed out. Check your network connection and consider retrying.";
413
429
  default:
414
430
  return undefined;
415
431
  }
416
432
  };
417
433
  // Extract RFC 9457 Problem Detail fields and other useful signals
418
434
  const networkTitle = deriveNetworkErrorTitle(error);
419
- const errorInstanceTitle = error instanceof Error && typeof error.message === 'string' && error.message
435
+ const errorInstanceTitle = error instanceof Error && typeof error.message === "string" && error.message
420
436
  ? error.message
421
437
  : undefined;
422
- const messageFieldTitle = typeof raw.message === 'string' ? raw.message : undefined;
438
+ const messageFieldTitle = typeof raw.message === "string" ? raw.message : undefined;
423
439
  const title = problemTitle ??
424
440
  networkTitle ??
425
441
  errorInstanceTitle ??
426
442
  messageFieldTitle ??
427
- 'Unknown error (unexpected error format; re-run with increased logging or check network configuration).';
428
- const detail = typeof raw.detail === 'string' ? raw.detail : undefined;
429
- const status = typeof raw.status === 'number' ? raw.status : undefined;
443
+ "Unknown error (unexpected error format; re-run with increased logging or check network configuration).";
444
+ const detail = typeof raw.detail === "string" ? raw.detail : undefined;
445
+ const status = typeof raw.status === "number" ? raw.status : undefined;
430
446
  // Display the main error
431
- logger.error('Deployment failed', new Error(title));
447
+ logger.error("Deployment failed", new Error(title));
432
448
  // Display the detailed error message if available
433
449
  if (detail) {
434
- logMessage('\n' + formatDeploymentErrorDetail(detail));
450
+ logMessage(`\n${formatDeploymentErrorDetail(detail)}`);
435
451
  }
436
452
  // Provide actionable hints based on error type
437
- logMessage('');
453
+ logMessage("");
438
454
  printDeploymentHints(title, detail, status, resources);
439
- logMessage('For more details on the error, run with the --verbose flag');
455
+ logMessage("For more details on the error, run with the --verbose flag");
440
456
  if (shouldContinue) {
441
457
  return;
442
458
  }
@@ -447,78 +463,89 @@ function handleDeploymentError(error, resources, logger, continueOnError, contin
447
463
  */
448
464
  function formatDeploymentErrorDetail(detail) {
449
465
  // The detail often contains embedded newlines, format them nicely
450
- const lines = detail.split('\n').map(line => line.trim()).filter(Boolean);
466
+ const lines = detail
467
+ .split("\n")
468
+ .map((line) => line.trim())
469
+ .filter(Boolean);
451
470
  // Find the main message and the file-specific errors
452
471
  const result = [];
453
472
  let inFileError = false;
454
473
  for (const line of lines) {
455
- if (line.startsWith("'") && (line.includes('.bpmn') || line.includes('.dmn') || line.includes('.form'))) {
474
+ if (line.startsWith("'") &&
475
+ (line.includes(".bpmn") ||
476
+ line.includes(".dmn") ||
477
+ line.includes(".form"))) {
456
478
  // This is a file-specific error
457
479
  inFileError = true;
458
480
  result.push(` 📄 ${line}`);
459
481
  }
460
- else if (line.startsWith('- Element:')) {
482
+ else if (line.startsWith("- Element:")) {
461
483
  result.push(` ${line}`);
462
484
  }
463
- else if (line.startsWith('- ERROR:') || line.startsWith('- WARNING:')) {
464
- const icon = line.startsWith('- ERROR:') ? '' : '⚠️';
485
+ else if (line.startsWith("- ERROR:") || line.startsWith("- WARNING:")) {
486
+ const icon = line.startsWith("- ERROR:") ? "" : "⚠️";
465
487
  result.push(` ${icon} ${line.substring(2)}`);
466
488
  }
467
- else if (inFileError && line.startsWith('-')) {
489
+ else if (inFileError && line.startsWith("-")) {
468
490
  result.push(` ${line}`);
469
491
  }
470
492
  else {
471
493
  result.push(` ${line}`);
472
494
  }
473
495
  }
474
- return result.join('\n');
496
+ return result.join("\n");
475
497
  }
476
498
  /**
477
499
  * Print actionable hints based on the error type
478
500
  */
479
501
  function printDeploymentHints(title, detail, status, resources) {
480
502
  const hints = [];
481
- if (title === 'INVALID_ARGUMENT') {
482
- if (detail?.includes('Must reference a message')) {
483
- hints.push('💡 A message start event or intermediate catch event is missing a message reference.');
484
- hints.push(' Open the BPMN file in Camunda Modeler and configure the message name.');
503
+ if (title === "INVALID_ARGUMENT") {
504
+ if (detail?.includes("Must reference a message")) {
505
+ hints.push("💡 A message start event or intermediate catch event is missing a message reference.");
506
+ hints.push(" Open the BPMN file in Camunda Modeler and configure the message name.");
485
507
  }
486
- if (detail?.includes('duplicate')) {
487
- hints.push('💡 Resource IDs must be unique within a deployment.');
488
- hints.push(' Check for duplicate process/decision IDs in your files.');
508
+ if (detail?.includes("duplicate")) {
509
+ hints.push("💡 Resource IDs must be unique within a deployment.");
510
+ hints.push(" Check for duplicate process/decision IDs in your files.");
489
511
  }
490
- if (detail?.includes('parsing') || detail?.includes('syntax')) {
491
- hints.push('💡 The resource file contains syntax errors.');
492
- hints.push(' Validate the file in Camunda Modeler or check the XML/JSON structure.');
512
+ if (detail?.includes("parsing") || detail?.includes("syntax")) {
513
+ hints.push("💡 The resource file contains syntax errors.");
514
+ hints.push(" Validate the file in Camunda Modeler or check the XML/JSON structure.");
493
515
  }
494
516
  }
495
- else if (title === 'RESOURCE_EXHAUSTED') {
496
- hints.push('💡 The server is under heavy load (backpressure).');
497
- hints.push(' Wait a moment and retry the deployment.');
517
+ else if (title === "RESOURCE_EXHAUSTED") {
518
+ hints.push("💡 The server is under heavy load (backpressure).");
519
+ hints.push(" Wait a moment and retry the deployment.");
498
520
  }
499
- else if (title === 'NOT_FOUND' || status === 404) {
500
- hints.push('💡 The Camunda server could not be reached or the endpoint was not found.');
501
- hints.push(' Check your connection settings with: c8 list profiles');
521
+ else if (title === "NOT_FOUND" || status === 404) {
522
+ hints.push("💡 The Camunda server could not be reached or the endpoint was not found.");
523
+ hints.push(" Check your connection settings with: c8 list profiles");
502
524
  }
503
- else if (title === 'UNAUTHENTICATED' || title === 'PERMISSION_DENIED' || status === 401 || status === 403) {
504
- hints.push('💡 Authentication or authorization failed.');
505
- hints.push(' Check your credentials and permissions for the current profile.');
525
+ else if (title === "UNAUTHENTICATED" ||
526
+ title === "PERMISSION_DENIED" ||
527
+ status === 401 ||
528
+ status === 403) {
529
+ hints.push("💡 Authentication or authorization failed.");
530
+ hints.push(" Check your credentials and permissions for the current profile.");
506
531
  }
507
532
  else {
508
- hints.push('💡 Review the error message above for specific issues.');
509
- hints.push(' You may need to fix the resource files before deploying.');
533
+ hints.push("💡 Review the error message above for specific issues.");
534
+ hints.push(" You may need to fix the resource files before deploying.");
510
535
  }
511
536
  // Show which files were being deployed
512
537
  if (resources.length > 0) {
513
- hints.push('');
538
+ hints.push("");
514
539
  hints.push(`📁 Resources attempted (${resources.length}):`);
515
- resources.slice(0, 5).forEach(r => {
540
+ resources.slice(0, 5).forEach((r) => {
516
541
  hints.push(` - ${r.relativePath || r.name}`);
517
542
  });
518
543
  if (resources.length > 5) {
519
544
  hints.push(` ... and ${resources.length - 5} more`);
520
545
  }
521
546
  }
522
- hints.forEach(h => logMessage(h));
547
+ hints.forEach((h) => {
548
+ logMessage(h);
549
+ });
523
550
  }
524
551
  //# sourceMappingURL=deployments.js.map