@camunda8/cli 3.1.0 → 3.2.0-alpha.10

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 (311) hide show
  1. package/CONTEXT.md +7 -15
  2. package/EXAMPLES.md +253 -1
  3. package/PLUGIN-HELP.md +1 -1
  4. package/README.md +50 -180
  5. package/dist/command-dispatch.d.ts +1 -1
  6. package/dist/command-dispatch.d.ts.map +1 -1
  7. package/dist/command-dispatch.js +1 -1
  8. package/dist/command-dispatch.js.map +1 -1
  9. package/dist/commands/completion.d.ts +1 -1
  10. package/dist/commands/completion.d.ts.map +1 -1
  11. package/dist/commands/completion.js +2 -3
  12. package/dist/commands/completion.js.map +1 -1
  13. package/dist/commands/deploy.d.ts +13 -0
  14. package/dist/commands/deploy.d.ts.map +1 -0
  15. package/dist/commands/deploy.js +328 -0
  16. package/dist/commands/deploy.js.map +1 -0
  17. package/dist/commands/forms.d.ts +1 -1
  18. package/dist/commands/forms.d.ts.map +1 -1
  19. package/dist/commands/forms.js +8 -8
  20. package/dist/commands/forms.js.map +1 -1
  21. package/dist/commands/helpers/deploy-helpers.d.ts +120 -0
  22. package/dist/commands/helpers/deploy-helpers.d.ts.map +1 -0
  23. package/dist/{deployments.js → commands/helpers/deploy-helpers.js} +307 -155
  24. package/dist/commands/helpers/deploy-helpers.js.map +1 -0
  25. package/dist/commands/identity-authorizations.d.ts +5 -18
  26. package/dist/commands/identity-authorizations.d.ts.map +1 -1
  27. package/dist/commands/identity-authorizations.js +8 -10
  28. package/dist/commands/identity-authorizations.js.map +1 -1
  29. package/dist/commands/identity-groups.d.ts +5 -5
  30. package/dist/commands/identity-groups.d.ts.map +1 -1
  31. package/dist/commands/identity-groups.js +7 -8
  32. package/dist/commands/identity-groups.js.map +1 -1
  33. package/dist/commands/identity-mapping-rules.d.ts +5 -5
  34. package/dist/commands/identity-mapping-rules.d.ts.map +1 -1
  35. package/dist/commands/identity-mapping-rules.js +7 -8
  36. package/dist/commands/identity-mapping-rules.js.map +1 -1
  37. package/dist/commands/identity-roles.d.ts +5 -5
  38. package/dist/commands/identity-roles.d.ts.map +1 -1
  39. package/dist/commands/identity-roles.js +7 -8
  40. package/dist/commands/identity-roles.js.map +1 -1
  41. package/dist/commands/identity-tenants.d.ts +5 -5
  42. package/dist/commands/identity-tenants.d.ts.map +1 -1
  43. package/dist/commands/identity-tenants.js +7 -8
  44. package/dist/commands/identity-tenants.js.map +1 -1
  45. package/dist/commands/identity-users.d.ts +5 -5
  46. package/dist/commands/identity-users.d.ts.map +1 -1
  47. package/dist/commands/identity-users.js +7 -8
  48. package/dist/commands/identity-users.js.map +1 -1
  49. package/dist/commands/identity.d.ts +11 -31
  50. package/dist/commands/identity.d.ts.map +1 -1
  51. package/dist/commands/identity.js +15 -15
  52. package/dist/commands/identity.js.map +1 -1
  53. package/dist/commands/incidents.d.ts +3 -3
  54. package/dist/commands/incidents.d.ts.map +1 -1
  55. package/dist/commands/incidents.js +6 -6
  56. package/dist/commands/incidents.js.map +1 -1
  57. package/dist/commands/jobs.d.ts +4 -4
  58. package/dist/commands/jobs.d.ts.map +1 -1
  59. package/dist/commands/jobs.js +7 -7
  60. package/dist/commands/jobs.js.map +1 -1
  61. package/dist/commands/mcp-proxy.d.ts +1 -1
  62. package/dist/commands/mcp-proxy.d.ts.map +1 -1
  63. package/dist/commands/mcp-proxy.js +5 -9
  64. package/dist/commands/mcp-proxy.js.map +1 -1
  65. package/dist/commands/messages.d.ts +2 -2
  66. package/dist/commands/messages.d.ts.map +1 -1
  67. package/dist/commands/messages.js +4 -4
  68. package/dist/commands/messages.js.map +1 -1
  69. package/dist/commands/open.d.ts +4 -4
  70. package/dist/commands/open.d.ts.map +1 -1
  71. package/dist/commands/open.js +6 -6
  72. package/dist/commands/open.js.map +1 -1
  73. package/dist/commands/plugins.d.ts +9 -9
  74. package/dist/commands/plugins.d.ts.map +1 -1
  75. package/dist/commands/plugins.js +2 -7
  76. package/dist/commands/plugins.js.map +1 -1
  77. package/dist/commands/process-definitions.d.ts +2 -2
  78. package/dist/commands/process-definitions.d.ts.map +1 -1
  79. package/dist/commands/process-definitions.js +5 -5
  80. package/dist/commands/process-definitions.js.map +1 -1
  81. package/dist/commands/process-instances.d.ts +5 -5
  82. package/dist/commands/process-instances.d.ts.map +1 -1
  83. package/dist/commands/process-instances.js +8 -9
  84. package/dist/commands/process-instances.js.map +1 -1
  85. package/dist/commands/profiles.d.ts +4 -36
  86. package/dist/commands/profiles.d.ts.map +1 -1
  87. package/dist/commands/profiles.js +43 -41
  88. package/dist/commands/profiles.js.map +1 -1
  89. package/dist/commands/run.d.ts +2 -2
  90. package/dist/commands/run.d.ts.map +1 -1
  91. package/dist/commands/run.js +4 -4
  92. package/dist/commands/run.js.map +1 -1
  93. package/dist/commands/search.d.ts +7 -7
  94. package/dist/commands/search.d.ts.map +1 -1
  95. package/dist/commands/search.js +9 -11
  96. package/dist/commands/search.js.map +1 -1
  97. package/dist/commands/session.d.ts +4 -4
  98. package/dist/commands/session.d.ts.map +1 -1
  99. package/dist/commands/session.js +26 -5
  100. package/dist/commands/session.js.map +1 -1
  101. package/dist/commands/topology.d.ts +1 -1
  102. package/dist/commands/topology.d.ts.map +1 -1
  103. package/dist/commands/topology.js +2 -2
  104. package/dist/commands/topology.js.map +1 -1
  105. package/dist/commands/user-tasks.d.ts +2 -2
  106. package/dist/commands/user-tasks.d.ts.map +1 -1
  107. package/dist/commands/user-tasks.js +5 -5
  108. package/dist/commands/user-tasks.js.map +1 -1
  109. package/dist/commands/variables.d.ts +1 -1
  110. package/dist/commands/variables.d.ts.map +1 -1
  111. package/dist/commands/variables.js +3 -3
  112. package/dist/commands/variables.js.map +1 -1
  113. package/dist/commands/watch.d.ts +2 -2
  114. package/dist/commands/watch.d.ts.map +1 -1
  115. package/dist/commands/watch.js +86 -19
  116. package/dist/commands/watch.js.map +1 -1
  117. package/dist/core/client.d.ts.map +1 -0
  118. package/dist/core/client.js.map +1 -0
  119. package/dist/{config.d.ts → core/config.d.ts} +28 -2
  120. package/dist/core/config.d.ts.map +1 -0
  121. package/dist/{config.js → core/config.js} +61 -5
  122. package/dist/core/config.js.map +1 -0
  123. package/dist/core/errors.d.ts.map +1 -0
  124. package/dist/core/errors.js.map +1 -0
  125. package/dist/core/index.d.ts +7 -0
  126. package/dist/core/index.d.ts.map +1 -0
  127. package/dist/core/index.js +13 -0
  128. package/dist/core/index.js.map +1 -0
  129. package/dist/core/logger.d.ts.map +1 -0
  130. package/dist/core/logger.js.map +1 -0
  131. package/dist/core/runtime.d.ts.map +1 -0
  132. package/dist/{runtime.js → core/runtime.js} +2 -2
  133. package/dist/core/runtime.js.map +1 -0
  134. package/dist/core/update-check.d.ts.map +1 -0
  135. package/dist/core/update-check.js.map +1 -0
  136. package/dist/default-plugins/bpmn/README.md +12 -3
  137. package/dist/default-plugins/bpmn/c8ctl-plugin.js +7376 -108
  138. package/dist/default-plugins/bpmn/package.json +8 -1
  139. package/dist/default-plugins/cluster/c8ctl-plugin.js +66 -9
  140. package/dist/default-plugins/element-template/README.md +6 -3
  141. package/dist/default-plugins/element-template/c8ctl-plugin.js +10195 -229
  142. package/dist/default-plugins/element-template/docs/design.md +1 -1
  143. package/dist/default-plugins/element-template/package.json +11 -1
  144. package/dist/default-plugins/feel/c8ctl-plugin.js +14030 -584
  145. package/dist/default-plugins/feel/package.json +4 -1
  146. package/dist/{command-framework.d.ts → framework/command-framework.d.ts} +23 -9
  147. package/dist/framework/command-framework.d.ts.map +1 -0
  148. package/dist/{command-framework.js → framework/command-framework.js} +16 -29
  149. package/dist/framework/command-framework.js.map +1 -0
  150. package/dist/{command-registry.d.ts → framework/command-registry.d.ts} +35 -8
  151. package/dist/framework/command-registry.d.ts.map +1 -0
  152. package/dist/{command-registry.js → framework/command-registry.js} +74 -9
  153. package/dist/framework/command-registry.js.map +1 -0
  154. package/dist/{command-validation.d.ts → framework/command-validation.d.ts} +0 -14
  155. package/dist/framework/command-validation.d.ts.map +1 -0
  156. package/dist/{command-validation.js → framework/command-validation.js} +1 -34
  157. package/dist/framework/command-validation.js.map +1 -0
  158. package/dist/framework/index.d.ts +10 -0
  159. package/dist/framework/index.d.ts.map +1 -0
  160. package/dist/framework/index.js +16 -0
  161. package/dist/framework/index.js.map +1 -0
  162. package/dist/{plugin-loader.d.ts → framework/plugins/plugin-loader.d.ts} +30 -5
  163. package/dist/framework/plugins/plugin-loader.d.ts.map +1 -0
  164. package/dist/{plugin-loader.js → framework/plugins/plugin-loader.js} +26 -10
  165. package/dist/framework/plugins/plugin-loader.js.map +1 -0
  166. package/dist/framework/plugins/plugin-registry.d.ts.map +1 -0
  167. package/dist/{plugin-registry.js → framework/plugins/plugin-registry.js} +1 -1
  168. package/dist/framework/plugins/plugin-registry.js.map +1 -0
  169. package/dist/framework/plugins/plugin-version.d.ts.map +1 -0
  170. package/dist/framework/plugins/plugin-version.js.map +1 -0
  171. package/dist/{completion.d.ts → framework/ui/completion.d.ts} +2 -2
  172. package/dist/framework/ui/completion.d.ts.map +1 -0
  173. package/dist/{completion.js → framework/ui/completion.js} +7 -9
  174. package/dist/framework/ui/completion.js.map +1 -0
  175. package/dist/framework/ui/help.d.ts.map +1 -0
  176. package/dist/{help.js → framework/ui/help.js} +4 -4
  177. package/dist/framework/ui/help.js.map +1 -0
  178. package/dist/framework/ui/prompt.d.ts +132 -0
  179. package/dist/framework/ui/prompt.d.ts.map +1 -0
  180. package/dist/framework/ui/prompt.js +298 -0
  181. package/dist/framework/ui/prompt.js.map +1 -0
  182. package/dist/index.d.ts.map +1 -1
  183. package/dist/index.js +24 -20
  184. package/dist/index.js.map +1 -1
  185. package/dist/utils/command-local/deploy-version.d.ts +21 -0
  186. package/dist/utils/command-local/deploy-version.d.ts.map +1 -0
  187. package/dist/utils/command-local/deploy-version.js +31 -0
  188. package/dist/utils/command-local/deploy-version.js.map +1 -0
  189. package/dist/{mcp-proxy-helpers.d.ts → utils/command-local/mcp-proxy-helpers.d.ts} +1 -1
  190. package/dist/utils/command-local/mcp-proxy-helpers.d.ts.map +1 -0
  191. package/dist/{mcp-proxy-helpers.js → utils/command-local/mcp-proxy-helpers.js} +1 -1
  192. package/dist/utils/command-local/mcp-proxy-helpers.js.map +1 -0
  193. package/dist/utils/command-local/open-helpers.d.ts.map +1 -0
  194. package/dist/{open-helpers.js → utils/command-local/open-helpers.js} +2 -2
  195. package/dist/utils/command-local/open-helpers.js.map +1 -0
  196. package/dist/{search-helpers.d.ts → utils/command-local/search-helpers.d.ts} +1 -1
  197. package/dist/utils/command-local/search-helpers.d.ts.map +1 -0
  198. package/dist/utils/command-local/search-helpers.js.map +1 -0
  199. package/dist/utils/command-local/watch-constants.d.ts.map +1 -0
  200. package/dist/utils/command-local/watch-constants.js.map +1 -0
  201. package/dist/utils/index.d.ts +10 -0
  202. package/dist/utils/index.d.ts.map +1 -0
  203. package/dist/utils/index.js +16 -0
  204. package/dist/utils/index.js.map +1 -0
  205. package/dist/utils/shared/date-filter.d.ts.map +1 -0
  206. package/dist/utils/shared/date-filter.js.map +1 -0
  207. package/dist/{ignore.d.ts → utils/shared/ignore.d.ts} +19 -1
  208. package/dist/utils/shared/ignore.d.ts.map +1 -0
  209. package/dist/utils/shared/ignore.js +234 -0
  210. package/dist/utils/shared/ignore.js.map +1 -0
  211. package/dist/utils/shared/resource-extensions.d.ts.map +1 -0
  212. package/dist/utils/shared/resource-extensions.js.map +1 -0
  213. package/dist/utils/shared/validation.d.ts +23 -0
  214. package/dist/utils/shared/validation.d.ts.map +1 -0
  215. package/dist/utils/shared/validation.js +43 -0
  216. package/dist/utils/shared/validation.js.map +1 -0
  217. package/dist/vendor/bpmnlint.cjs +25907 -0
  218. package/package.json +12 -14
  219. package/dist/client.d.ts.map +0 -1
  220. package/dist/client.js.map +0 -1
  221. package/dist/command-framework.d.ts.map +0 -1
  222. package/dist/command-framework.js.map +0 -1
  223. package/dist/command-registry.d.ts.map +0 -1
  224. package/dist/command-registry.js.map +0 -1
  225. package/dist/command-validation.d.ts.map +0 -1
  226. package/dist/command-validation.js.map +0 -1
  227. package/dist/commands/resource-extensions.d.ts.map +0 -1
  228. package/dist/commands/resource-extensions.js.map +0 -1
  229. package/dist/completion.d.ts.map +0 -1
  230. package/dist/completion.js.map +0 -1
  231. package/dist/config.d.ts.map +0 -1
  232. package/dist/config.js.map +0 -1
  233. package/dist/date-filter.d.ts.map +0 -1
  234. package/dist/date-filter.js.map +0 -1
  235. package/dist/default-plugins/bpmn/c8ctl-plugin.js.map +0 -1
  236. package/dist/default-plugins/bpmn/lint.js +0 -320
  237. package/dist/default-plugins/bpmn/lint.js.map +0 -1
  238. package/dist/default-plugins/element-template/c8ctl-plugin.js.map +0 -1
  239. package/dist/default-plugins/element-template/commands/apply.js +0 -336
  240. package/dist/default-plugins/element-template/commands/apply.js.map +0 -1
  241. package/dist/default-plugins/element-template/commands/get-properties.js +0 -344
  242. package/dist/default-plugins/element-template/commands/get-properties.js.map +0 -1
  243. package/dist/default-plugins/element-template/commands/get.js +0 -107
  244. package/dist/default-plugins/element-template/commands/get.js.map +0 -1
  245. package/dist/default-plugins/element-template/commands/info.js +0 -189
  246. package/dist/default-plugins/element-template/commands/info.js.map +0 -1
  247. package/dist/default-plugins/element-template/commands/search.js +0 -102
  248. package/dist/default-plugins/element-template/commands/search.js.map +0 -1
  249. package/dist/default-plugins/element-template/commands/sync.js +0 -36
  250. package/dist/default-plugins/element-template/commands/sync.js.map +0 -1
  251. package/dist/default-plugins/element-template/helpers.js +0 -429
  252. package/dist/default-plugins/element-template/helpers.js.map +0 -1
  253. package/dist/default-plugins/element-template/marketplace.js +0 -586
  254. package/dist/default-plugins/element-template/marketplace.js.map +0 -1
  255. package/dist/default-plugins/element-template/template-ref.js +0 -232
  256. package/dist/default-plugins/element-template/template-ref.js.map +0 -1
  257. package/dist/default-plugins/feel/c8ctl-plugin.js.map +0 -1
  258. package/dist/default-plugins/hello-world/README.md +0 -161
  259. package/dist/default-plugins/hello-world/c8ctl-plugin.js +0 -69
  260. package/dist/default-plugins/hello-world/package.json +0 -8
  261. package/dist/deployments.d.ts +0 -42
  262. package/dist/deployments.d.ts.map +0 -1
  263. package/dist/deployments.js.map +0 -1
  264. package/dist/errors.d.ts.map +0 -1
  265. package/dist/errors.js.map +0 -1
  266. package/dist/help.d.ts.map +0 -1
  267. package/dist/help.js.map +0 -1
  268. package/dist/ignore.d.ts.map +0 -1
  269. package/dist/ignore.js +0 -101
  270. package/dist/ignore.js.map +0 -1
  271. package/dist/logger.d.ts.map +0 -1
  272. package/dist/logger.js.map +0 -1
  273. package/dist/mcp-proxy-helpers.d.ts.map +0 -1
  274. package/dist/mcp-proxy-helpers.js.map +0 -1
  275. package/dist/open-helpers.d.ts.map +0 -1
  276. package/dist/open-helpers.js.map +0 -1
  277. package/dist/plugin-loader.d.ts.map +0 -1
  278. package/dist/plugin-loader.js.map +0 -1
  279. package/dist/plugin-registry.d.ts.map +0 -1
  280. package/dist/plugin-registry.js.map +0 -1
  281. package/dist/plugin-version.d.ts.map +0 -1
  282. package/dist/plugin-version.js.map +0 -1
  283. package/dist/runtime.d.ts.map +0 -1
  284. package/dist/runtime.js.map +0 -1
  285. package/dist/search-helpers.d.ts.map +0 -1
  286. package/dist/search-helpers.js.map +0 -1
  287. package/dist/update-check.d.ts.map +0 -1
  288. package/dist/update-check.js.map +0 -1
  289. package/dist/watch-constants.d.ts.map +0 -1
  290. package/dist/watch-constants.js.map +0 -1
  291. /package/dist/{client.d.ts → core/client.d.ts} +0 -0
  292. /package/dist/{client.js → core/client.js} +0 -0
  293. /package/dist/{errors.d.ts → core/errors.d.ts} +0 -0
  294. /package/dist/{errors.js → core/errors.js} +0 -0
  295. /package/dist/{logger.d.ts → core/logger.d.ts} +0 -0
  296. /package/dist/{logger.js → core/logger.js} +0 -0
  297. /package/dist/{runtime.d.ts → core/runtime.d.ts} +0 -0
  298. /package/dist/{update-check.d.ts → core/update-check.d.ts} +0 -0
  299. /package/dist/{update-check.js → core/update-check.js} +0 -0
  300. /package/dist/{plugin-registry.d.ts → framework/plugins/plugin-registry.d.ts} +0 -0
  301. /package/dist/{plugin-version.d.ts → framework/plugins/plugin-version.d.ts} +0 -0
  302. /package/dist/{plugin-version.js → framework/plugins/plugin-version.js} +0 -0
  303. /package/dist/{help.d.ts → framework/ui/help.d.ts} +0 -0
  304. /package/dist/{open-helpers.d.ts → utils/command-local/open-helpers.d.ts} +0 -0
  305. /package/dist/{search-helpers.js → utils/command-local/search-helpers.js} +0 -0
  306. /package/dist/{watch-constants.d.ts → utils/command-local/watch-constants.d.ts} +0 -0
  307. /package/dist/{watch-constants.js → utils/command-local/watch-constants.js} +0 -0
  308. /package/dist/{date-filter.d.ts → utils/shared/date-filter.d.ts} +0 -0
  309. /package/dist/{date-filter.js → utils/shared/date-filter.js} +0 -0
  310. /package/dist/{commands → utils/shared}/resource-extensions.d.ts +0 -0
  311. /package/dist/{commands → utils/shared}/resource-extensions.js +0 -0
@@ -1,23 +1,22 @@
1
1
  /**
2
- * Deployment commands with building-block folder prioritization
2
+ * Shared deployment helpers resource collection, deployment execution,
3
+ * and process-application detection.
4
+ *
5
+ * Consumed by:
6
+ * - `src/commands/deploy.ts` (the `deployCommand` handler)
7
+ * - `src/commands/watch.ts` (change-triggered re-deploys)
3
8
  */
4
- import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
5
- import { basename, dirname, extname, join, relative } from "node:path";
9
+ import { existsSync, readdirSync, readFileSync, realpathSync, statSync, } from "node:fs";
10
+ import { basename, dirname, extname, join, relative, resolve } from "node:path";
6
11
  import { TenantId } from "@camunda8/orchestration-cluster-api";
7
- import { createClient } from "./client.js";
8
- import { defineCommand, dryRun } from "./command-framework.js";
9
- import { ALL_DEPLOYABLE_EXTENSIONS, DEPLOYABLE_EXTENSIONS, } from "./commands/resource-extensions.js";
10
- import { resolveTenantId } from "./config.js";
11
- import { normalizeToError, SilentError } from "./errors.js";
12
- import { isIgnored, loadIgnoreRules, resolveIgnoreBaseDir } from "./ignore.js";
13
- import { getLogger, isRecord } from "./logger.js";
14
- import { c8ctl } from "./runtime.js";
12
+ import { createClient, getLogger, isRecord, normalizeToError, resolveTenantId, SilentError, } from "../../core/index.js";
13
+ import { DEPLOYABLE_EXTENSIONS, isIgnored, loadDeployAlwaysRules, loadIgnoreRules, meetsMinExtensionVersion, resolveIgnoreBaseDir, } from "../../utils/index.js";
15
14
  const PROCESS_APPLICATION_FILE = ".process-application";
16
15
  /**
17
16
  * Helper to output messages that respect JSON mode for Unix pipe compatibility
18
17
  */
19
- function logMessage(message) {
20
- if (c8ctl.outputMode === "json") {
18
+ export function logMessage(message) {
19
+ if (getLogger().mode === "json") {
21
20
  console.error(JSON.stringify({ type: "message", message }));
22
21
  }
23
22
  else {
@@ -29,13 +28,38 @@ function logMessage(message) {
29
28
  * Shared between the dry-run preview and the execute path so the
30
29
  * message stays consistent. See https://github.com/camunda/c8ctl/issues/350
31
30
  */
32
- function logSkippedExtensions(skippedExtensions) {
31
+ export function logSkippedExtensions(skippedExtensions) {
33
32
  if (skippedExtensions.size === 0)
34
33
  return;
35
34
  const exts = [...skippedExtensions].sort().join(", ");
36
35
  logMessage(`Skipped files with extensions not in the allow-list (${exts}). ` +
37
36
  `Use --extensions=<ext> to add specific types, or --all-extensions to include all server-supported types.`);
38
37
  }
38
+ /**
39
+ * Check whether the connected Camunda server supports extended file extensions.
40
+ * Returns `true` for 8.10+, `false` for older versions.
41
+ * Falls back to `false` on any error (network, auth, unparseable version)
42
+ * so unsupported resource types are not deployed to older clusters.
43
+ */
44
+ export async function checkServerSupportsExtensions(client) {
45
+ const logger = getLogger();
46
+ try {
47
+ const topology = await client.getTopology();
48
+ const version = String(topology.gatewayVersion ?? "");
49
+ const result = meetsMinExtensionVersion(version);
50
+ if (result === null) {
51
+ logger.warn(`Could not parse server version "${version}" — assuming extended extensions are NOT supported.`);
52
+ return false;
53
+ }
54
+ return result;
55
+ }
56
+ catch {
57
+ logger.warn("Could not reach the server to check its version (topology call failed).");
58
+ logger.warn("This can happen with OAuth/SaaS clusters before the first token is fetched, " +
59
+ "or if the server is not yet ready. Assuming extended extensions are NOT supported.");
60
+ return false;
61
+ }
62
+ }
39
63
  /**
40
64
  * Extract process/decision IDs from BPMN/DMN files to detect duplicates
41
65
  */
@@ -68,7 +92,12 @@ function isBuildingBlockFolder(path) {
68
92
  */
69
93
  function hasProcessApplicationFile(dirPath) {
70
94
  const paFilePath = join(dirPath, PROCESS_APPLICATION_FILE);
71
- return existsSync(paFilePath);
95
+ try {
96
+ return statSync(paFilePath).isFile();
97
+ }
98
+ catch {
99
+ return false;
100
+ }
72
101
  }
73
102
  /**
74
103
  * Find the root building block or process application folder by traversing up the path
@@ -78,11 +107,6 @@ function findGroupRoot(filePath, basePath) {
78
107
  let currentDir = dirname(filePath);
79
108
  // Traverse up the directory tree until we reach or go outside basePath
80
109
  while (true) {
81
- // Check if we've gone outside the basePath
82
- const rel = relative(basePath, currentDir);
83
- if (rel.startsWith("..") || rel === "") {
84
- break;
85
- }
86
110
  // Check if this directory is a building block
87
111
  if (isBuildingBlockFolder(currentDir)) {
88
112
  return { type: "bb", root: currentDir };
@@ -91,6 +115,11 @@ function findGroupRoot(filePath, basePath) {
91
115
  if (hasProcessApplicationFile(currentDir)) {
92
116
  return { type: "pa", root: currentDir };
93
117
  }
118
+ // Check if we've reached or gone outside the basePath
119
+ const rel = relative(basePath, currentDir);
120
+ if (rel.startsWith("..") || rel === "") {
121
+ break;
122
+ }
94
123
  // Move up one level
95
124
  const parentDir = dirname(currentDir);
96
125
  if (parentDir === currentDir)
@@ -99,6 +128,33 @@ function findGroupRoot(filePath, basePath) {
99
128
  }
100
129
  return { type: null, root: null };
101
130
  }
131
+ /**
132
+ * Walk up from `startDir` looking for a `.process-application` marker
133
+ * file. Returns the directory that contains the marker, or `null` if
134
+ * none is found before reaching the filesystem root.
135
+ *
136
+ * `startDir` may be a file path — the walk starts from its parent
137
+ * directory in that case (the initial `hasProcessApplicationFile` call
138
+ * harmlessly returns false for non-directories).
139
+ *
140
+ * Unlike `findGroupRoot()` (which tags individual files for display),
141
+ * this function determines the *deploy scope*: when a PA root is found,
142
+ * `collectResourcesForPaths` expands the input to the PA root so that
143
+ * the entire application is deployed.
144
+ */
145
+ export function findProcessApplicationRoot(startDir) {
146
+ let currentDir = resolve(startDir);
147
+ while (true) {
148
+ if (hasProcessApplicationFile(currentDir)) {
149
+ return currentDir;
150
+ }
151
+ const parentDir = dirname(currentDir);
152
+ if (parentDir === currentDir)
153
+ break; // Reached filesystem root
154
+ currentDir = parentDir;
155
+ }
156
+ return null;
157
+ }
102
158
  /**
103
159
  * Recursively collect resource files from a directory.
104
160
  *
@@ -109,15 +165,16 @@ function findGroupRoot(filePath, basePath) {
109
165
  * @param skippedExtensions - Mutable set that accumulates extensions
110
166
  * skipped during directory walks, so the caller can log them.
111
167
  */
112
- function collectResourceFiles(dirPath, collected = [], basePath, ig, ignoreBaseDir, force, extensionList, skippedExtensions) {
168
+ function collectResourceFiles(dirPath, collected = [], basePath, ig, ignoreBaseDir, force, extensionList, skippedExtensions, skippedFiles, deployAlways) {
113
169
  if (!existsSync(dirPath)) {
114
170
  return collected;
115
171
  }
116
- // Set basePath to dirPath on first call
172
+ const stat = statSync(dirPath);
173
+ // Set basePath to a directory on first call — when the initial input
174
+ // is a file, use its parent so findGroupRoot can walk up correctly.
117
175
  if (!basePath) {
118
- basePath = dirPath;
176
+ basePath = stat.isFile() ? dirname(dirPath) : dirPath;
119
177
  }
120
- const stat = statSync(dirPath);
121
178
  if (stat.isFile()) {
122
179
  if (ig && ignoreBaseDir && isIgnored(ig, dirPath, ignoreBaseDir)) {
123
180
  return collected;
@@ -176,10 +233,21 @@ function collectResourceFiles(dirPath, collected = [], basePath, ig, ignoreBaseD
176
233
  if (!force &&
177
234
  extensionList &&
178
235
  !extensionList.includes(extname(fullPath))) {
236
+ // Check deploy-always negation rules from .c8ignore
237
+ if (deployAlways &&
238
+ ignoreBaseDir &&
239
+ isIgnored(deployAlways, fullPath, ignoreBaseDir)) {
240
+ // File matches a !path negation — include it
241
+ files.push(fullPath);
242
+ return;
243
+ }
179
244
  if (skippedExtensions) {
180
245
  const ext = extname(fullPath);
181
246
  skippedExtensions.add(ext || "<no extension>");
182
247
  }
248
+ if (skippedFiles) {
249
+ skippedFiles.push(fullPath);
250
+ }
183
251
  return;
184
252
  }
185
253
  files.push(fullPath);
@@ -199,11 +267,11 @@ function collectResourceFiles(dirPath, collected = [], basePath, ig, ignoreBaseD
199
267
  });
200
268
  // Process building block folders first (prioritized)
201
269
  bbFolders.forEach((bbFolder) => {
202
- collectResourceFiles(bbFolder, collected, basePath, ig, ignoreBaseDir, force, extensionList, skippedExtensions);
270
+ collectResourceFiles(bbFolder, collected, basePath, ig, ignoreBaseDir, force, extensionList, skippedExtensions, skippedFiles, deployAlways);
203
271
  });
204
272
  // Then process regular folders
205
273
  regularFolders.forEach((regularFolder) => {
206
- collectResourceFiles(regularFolder, collected, basePath, ig, ignoreBaseDir, force, extensionList, skippedExtensions);
274
+ collectResourceFiles(regularFolder, collected, basePath, ig, ignoreBaseDir, force, extensionList, skippedExtensions, skippedFiles, deployAlways);
207
275
  });
208
276
  }
209
277
  return collected;
@@ -235,32 +303,118 @@ function findDuplicateDefinitionIds(resources) {
235
303
  * @param extensionList - Active allow-list for directory discovery.
236
304
  * Defaults to `DEPLOYABLE_EXTENSIONS` (.bpmn, .dmn, .form).
237
305
  */
238
- function collectResourcesForPaths(paths, force, extensionList = DEPLOYABLE_EXTENSIONS) {
306
+ export function collectResourcesForPaths(paths, force, extensionList = DEPLOYABLE_EXTENSIONS,
307
+ /** When false, skip loading deploy-always negation rules from .c8ignore.
308
+ * Used to suppress them on servers <8.10 that don't support extended extensions. */
309
+ loadDeployAlways = true) {
239
310
  if (paths.length === 0) {
240
311
  throw new Error("No paths provided. Use: c8 deploy <path> or c8 deploy (for current directory)");
241
312
  }
242
- // Load .c8ignore rules from the target directory (not cwd) so that
243
- // `c8 deploy <target>` picks up the .c8ignore inside the target. (#258)
244
- const ignoreBaseDir = resolveIgnoreBaseDir(paths);
313
+ // ── Process-application auto-detection (#227) ──────────────────────
314
+ // For each directory path, walk up looking for a .process-application
315
+ // marker. If found, expand to the PA root so the entire application
316
+ // is deployed — matching Desktop Modeler behaviour.
317
+ // File paths are NOT expanded so that watch-mode single-file deploys
318
+ // remain scoped to the changed file.
319
+ const effectivePaths = [];
320
+ const seenRoots = new Set();
321
+ for (const p of paths) {
322
+ const abs = resolve(p);
323
+ let isFile = false;
324
+ try {
325
+ isFile = statSync(abs).isFile();
326
+ }
327
+ catch {
328
+ // Path does not exist — skip PA detection and keep the
329
+ // absolute path so collectResourceFiles (which silently
330
+ // skips missing paths) falls through to the "No deployable
331
+ // files found" guard.
332
+ effectivePaths.push(abs);
333
+ continue;
334
+ }
335
+ if (isFile) {
336
+ effectivePaths.push(abs);
337
+ continue;
338
+ }
339
+ const paRoot = findProcessApplicationRoot(abs);
340
+ if (paRoot) {
341
+ // Deduplicate: multiple input dirs inside the same PA should
342
+ // only trigger one resource walk from the PA root. Use
343
+ // realpathSync for the dedup key to handle symlinks/case.
344
+ let canonical = paRoot;
345
+ try {
346
+ canonical = realpathSync(paRoot);
347
+ }
348
+ catch {
349
+ // Best-effort fallback.
350
+ }
351
+ if (!seenRoots.has(canonical)) {
352
+ seenRoots.add(canonical);
353
+ effectivePaths.push(paRoot);
354
+ }
355
+ }
356
+ else {
357
+ effectivePaths.push(abs);
358
+ }
359
+ }
360
+ // Load .c8ignore rules from the effective target directory (which may
361
+ // be the PA root) so that `c8 deploy <target>` picks up the .c8ignore
362
+ // inside the target. (#258)
363
+ const ignoreBaseDir = resolveIgnoreBaseDir(effectivePaths);
245
364
  const ig = loadIgnoreRules(ignoreBaseDir);
365
+ // Load !path negation patterns from .c8ignore. Files matching a
366
+ // negation bypass extension filtering ("deploy them always").
367
+ // Skipped on servers <8.10 where extended extensions aren't supported.
368
+ const deployAlways = loadDeployAlways
369
+ ? loadDeployAlwaysRules(ignoreBaseDir)
370
+ : null;
246
371
  const resources = [];
247
372
  const skippedExtensions = new Set();
248
- paths.forEach((path) => {
249
- collectResourceFiles(path, resources, undefined, ig, ignoreBaseDir, force, extensionList, skippedExtensions);
373
+ const skippedFiles = [];
374
+ effectivePaths.forEach((path) => {
375
+ collectResourceFiles(path, resources, undefined, ig, ignoreBaseDir, force, extensionList, skippedExtensions, skippedFiles, deployAlways ?? undefined);
250
376
  });
251
- if (resources.length === 0) {
377
+ // Deduplicate resources by canonical path — can happen when an explicit
378
+ // file path is also covered by a PA-root or scoped-directory walk, or
379
+ // when the same file is reachable via symlinks. The canonical path is
380
+ // used only as the dedup key; the original path/name are preserved for
381
+ // display and relative-path calculations.
382
+ const seen = new Set();
383
+ const deduped = [];
384
+ for (const r of resources) {
385
+ let canonical = r.path;
386
+ try {
387
+ canonical = realpathSync(r.path);
388
+ }
389
+ catch {
390
+ // Best-effort: fall back to the original path if realpath
391
+ // fails (e.g. broken symlink).
392
+ }
393
+ if (!seen.has(canonical)) {
394
+ seen.add(canonical);
395
+ deduped.push(r);
396
+ }
397
+ }
398
+ if (deduped.length === 0) {
252
399
  logSkippedExtensions(skippedExtensions);
253
- throw new Error("No deployable files found in the specified paths");
400
+ throw new Error(skippedFiles.length > 0
401
+ ? `No files with allowed extensions found. ${skippedFiles.length} file(s) were skipped (${[...skippedExtensions].sort().join(", ")}). Use --force to include all files, or --extensions to expand the allow-list.`
402
+ : "No deployable files found in the specified paths");
254
403
  }
255
- return { resources, skippedExtensions };
404
+ return {
405
+ resources: deduped,
406
+ skippedExtensions,
407
+ skippedFiles,
408
+ effectivePaths,
409
+ };
256
410
  }
257
411
  /**
258
412
  * Internal helper: deploy the given paths to the cluster and render the
259
413
  * result table. Used by `deployCommand` (the standard CLI entry point)
260
414
  * and by `watchCommand` (for change-triggered re-deploys).
261
415
  *
262
- * Does NOT consult `c8ctl.dryRun` — dry-run handling lives in the
263
- * `deployCommand` handler so the framework's `dryRun()` helper owns
416
+ * Does NOT consult dry-run state — dry-run handling lives in the
417
+ * `deployCommand` handler so the context's `ctx.dryRun()` helper owns
264
418
  * preview emission. Watch never triggers a dry-run, so this split also
265
419
  * removes a footgun where a stale dry-run flag could suppress a watch
266
420
  * deploy.
@@ -273,15 +427,16 @@ export async function deployResources(paths, options) {
273
427
  // straight to the framework's `handleCommandError`. Only the actual
274
428
  // HTTP deploy call (further down) is wrapped in a catch that routes
275
429
  // through `handleDeploymentError` for rich Problem-Detail rendering.
276
- const { resources, skippedExtensions } = collectResourcesForPaths(paths, options.force, options.extensionList ?? DEPLOYABLE_EXTENSIONS);
277
- logSkippedExtensions(skippedExtensions);
278
- // Store the base paths for relative path calculation. Safe to assign
279
- // directly now: the empty-paths guard inside `collectResourcesForPaths`
280
- // has already thrown.
281
- const basePaths = paths;
430
+ const { resources, skippedExtensions, effectivePaths } = collectResourcesForPaths(paths, options.force, options.extensionList ?? DEPLOYABLE_EXTENSIONS, options.loadDeployAlways ?? true);
431
+ if (!options.suppressSkippedLog) {
432
+ logSkippedExtensions(skippedExtensions);
433
+ }
434
+ // Use the effective paths (which may have been expanded to a PA root)
435
+ // for relative path calculation so display paths make sense.
436
+ const basePaths = effectivePaths;
282
437
  const client = createClient(options.profile);
283
438
  // Calculate relative paths for display
284
- const basePath = basePaths.length === 1 ? basePaths[0] : process.cwd();
439
+ const basePath = options.basePath ?? (basePaths.length === 1 ? basePaths[0] : process.cwd());
285
440
  resources.forEach((r) => {
286
441
  r.relativePath = relative(basePath, r.path) || r.name;
287
442
  });
@@ -341,7 +496,19 @@ export async function deployResources(paths, options) {
341
496
  // Create a mapping from definition ID to resource file for later reference
342
497
  const definitionIdToResource = new Map();
343
498
  const formNameToResource = new Map();
499
+ // Map basename → ResourceFile[]: multiple files can share a basename
500
+ // across directories (e.g. sub-a/model.dmn, sub-b/model.dmn). When
501
+ // the API returns a resourceName, we pop the first matching entry so
502
+ // each response record resolves to a distinct local file.
503
+ const resourcesByName = new Map();
344
504
  resources.forEach((r) => {
505
+ const existing = resourcesByName.get(r.name);
506
+ if (existing) {
507
+ existing.push(r);
508
+ }
509
+ else {
510
+ resourcesByName.set(r.name, [r]);
511
+ }
345
512
  const ext = extname(r.path);
346
513
  if (ext === ".bpmn" || ext === ".dmn") {
347
514
  const defId = extractDefinitionId(r.content, ext);
@@ -350,11 +517,28 @@ export async function deployResources(paths, options) {
350
517
  }
351
518
  }
352
519
  else if (ext === ".form") {
353
- // Forms are matched by filename (without extension)
354
- const formId = basename(r.name, ".form");
520
+ // Forms are matched by their internal ID from the JSON content.
521
+ // Fall back to filename (without extension) if the ID can't be parsed.
522
+ let formId = basename(r.name, ".form");
523
+ try {
524
+ const parsed = JSON.parse(r.content.toString("utf-8"));
525
+ if (isRecord(parsed) && typeof parsed.id === "string") {
526
+ formId = parsed.id;
527
+ }
528
+ }
529
+ catch {
530
+ // Not valid JSON — use filename
531
+ }
355
532
  formNameToResource.set(formId, r);
356
533
  }
357
534
  });
535
+ /** Pop the first resource with a matching basename, or return undefined. */
536
+ function popResourceByName(name) {
537
+ const bucket = resourcesByName.get(name);
538
+ if (!bucket || bucket.length === 0)
539
+ return undefined;
540
+ return bucket.shift();
541
+ }
358
542
  // ─── API call ────────────────────────────────────────────────────────
359
543
  // Only this section is wrapped in a catch that routes through
360
544
  // `handleDeploymentError`. Pre-API errors above bubble to the
@@ -408,7 +592,7 @@ export async function deployResources(paths, options) {
408
592
  if (options.signal?.aborted) {
409
593
  return;
410
594
  }
411
- handleDeploymentError(error, resources, logger, options.continueOnError, options.continueOnUserError);
595
+ handleDeploymentError(error, resources, logger, options.continueOnError, options.continueOnUserError, options.verbose === true);
412
596
  // `handleDeploymentError` either throws (terminal) or returns
413
597
  // (continue-on-error). On the continue path, skip the success
414
598
  // render below — there's no result to render.
@@ -417,27 +601,80 @@ export async function deployResources(paths, options) {
417
601
  options.signal?.removeEventListener("abort", onAbort);
418
602
  logger.success("Deployment successful", result.deploymentKey.toString());
419
603
  // Normalize all deployed resources into a common structure
604
+ const knownResources = new Set();
420
605
  const allResources = [
421
- ...result.processes.map((proc) => ({
422
- type: "Process",
423
- id: proc.processDefinitionId,
424
- version: proc.processDefinitionVersion,
425
- key: proc.processDefinitionKey.toString(),
426
- resource: definitionIdToResource.get(proc.processDefinitionId),
427
- })),
428
- ...result.decisions.map((dec) => ({
429
- type: "Decision",
430
- id: dec.decisionDefinitionId || "-",
431
- version: dec.version ?? "-",
432
- key: dec.decisionDefinitionKey?.toString() || "-",
433
- resource: definitionIdToResource.get(dec.decisionDefinitionId || ""),
434
- })),
435
- ...result.forms.map((form) => ({
436
- type: "Form",
437
- id: form.formId || "-",
438
- version: form.version ?? "-",
439
- key: form.formKey?.toString() || "-",
440
- resource: formNameToResource.get(form.formId || ""),
606
+ ...result.processes.map((proc) => {
607
+ const resource = definitionIdToResource.get(proc.processDefinitionId);
608
+ if (resource)
609
+ knownResources.add(resource);
610
+ return {
611
+ type: "Process",
612
+ id: proc.processDefinitionId,
613
+ version: proc.processDefinitionVersion,
614
+ key: proc.processDefinitionKey.toString(),
615
+ resource,
616
+ };
617
+ }),
618
+ ...result.decisions.map((dec) => {
619
+ const resource = definitionIdToResource.get(dec.decisionDefinitionId || "");
620
+ if (resource)
621
+ knownResources.add(resource);
622
+ return {
623
+ type: "Decision",
624
+ id: dec.decisionDefinitionId || "-",
625
+ version: dec.version ?? "-",
626
+ key: dec.decisionDefinitionKey?.toString() || "-",
627
+ resource,
628
+ };
629
+ }),
630
+ ...result.decisionRequirements.map((dr) => {
631
+ const resource = popResourceByName(dr.resourceName || "");
632
+ if (resource)
633
+ knownResources.add(resource);
634
+ return {
635
+ type: "Decision Requirements",
636
+ id: dr.decisionRequirementsId || "-",
637
+ version: dr.version ?? "-",
638
+ key: dr.decisionRequirementsKey?.toString() || "-",
639
+ resource,
640
+ };
641
+ }),
642
+ ...result.forms.map((form) => {
643
+ const resource = formNameToResource.get(form.formId || "");
644
+ if (resource)
645
+ knownResources.add(resource);
646
+ return {
647
+ type: "Form",
648
+ id: form.formId || "-",
649
+ version: form.version ?? "-",
650
+ key: form.formKey?.toString() || "-",
651
+ resource,
652
+ };
653
+ }),
654
+ // Generic resources (not processes, decisions, or forms)
655
+ // are returned in the `resources` array by 8.10+.
656
+ ...result.resources.map((res) => {
657
+ const resource = popResourceByName(res.resourceName || "");
658
+ if (resource)
659
+ knownResources.add(resource);
660
+ return {
661
+ type: "Resource",
662
+ id: res.resourceId || "-",
663
+ version: res.version ?? "-",
664
+ key: res.resourceKey?.toString() || "-",
665
+ resource,
666
+ };
667
+ }),
668
+ // Supplementary resources not returned in any response array.
669
+ // Show them in the table so the user knows they were deployed.
670
+ ...resources
671
+ .filter((r) => !knownResources.has(r))
672
+ .map((r) => ({
673
+ type: "Resource",
674
+ id: "-",
675
+ version: "-",
676
+ key: "-",
677
+ resource: r,
441
678
  })),
442
679
  ];
443
680
  const tableData = allResources.map(({ type, id, version, key, resource }) => {
@@ -479,13 +716,13 @@ export async function deployResources(paths, options) {
479
716
  /**
480
717
  * Format and display deployment errors with actionable guidance
481
718
  */
482
- function handleDeploymentError(error, resources, logger, continueOnError, continueOnUserError) {
719
+ function handleDeploymentError(error, resources, logger, continueOnError, continueOnUserError, verbose) {
483
720
  // Extract problem title early to determine whether this is a user-fixable error
484
721
  const raw = isRecord(error) ? error : {};
485
722
  const problemTitle = typeof raw.title === "string" ? raw.title : undefined;
486
723
  const isUserFixable = problemTitle === "INVALID_ARGUMENT";
487
724
  const shouldContinue = continueOnError || (continueOnUserError && isUserFixable);
488
- if (c8ctl.verbose) {
725
+ if (verbose) {
489
726
  if (shouldContinue) {
490
727
  throw error;
491
728
  }
@@ -645,89 +882,4 @@ function printDeploymentHints(title, detail, status, resources) {
645
882
  logMessage(h);
646
883
  });
647
884
  }
648
- // ─── defineCommand ───────────────────────────────────────────────────────────
649
- /**
650
- * Resolve the effective extension allow-list from the deploy flags.
651
- *
652
- * Priority: --force (no filtering) > --all-extensions > --extensions > default
653
- *
654
- * When `--extensions` is provided, the custom list is *merged* with the
655
- * default (.bpmn, .dmn, .form) so users add to the baseline rather than
656
- * replacing it.
657
- */
658
- function resolveExtensionList(flags) {
659
- // When --force is set the allow-list is irrelevant — downstream code
660
- // skips filtering entirely. Return the default so callers always get a
661
- // valid list, but the value is never consulted.
662
- if (flags.force)
663
- return DEPLOYABLE_EXTENSIONS;
664
- // --all-extensions: use the full server-supported list
665
- if (flags["all-extensions"])
666
- return ALL_DEPLOYABLE_EXTENSIONS;
667
- // --extensions: merge custom extensions with the default set
668
- if (flags.extensions && String(flags.extensions).trim()) {
669
- const custom = String(flags.extensions)
670
- .split(",")
671
- .map((e) => e.trim())
672
- .filter(Boolean)
673
- .map((e) => (e.startsWith(".") ? e : `.${e}`));
674
- const merged = [...new Set([...DEPLOYABLE_EXTENSIONS, ...custom])];
675
- return merged;
676
- }
677
- return DEPLOYABLE_EXTENSIONS;
678
- }
679
- /**
680
- * Side-effectful: collects files, validates, deploys, and renders its own
681
- * table output.
682
- *
683
- * The body lives directly in the handler (per #288): argument-shape
684
- * resolution, dry-run preview via the framework's `dryRun()` helper,
685
- * and the call into the shared `deployResources` helper that watch also
686
- * uses for change-triggered re-deploys.
687
- */
688
- export const deployCommand = defineCommand("deploy", "", async (ctx, flags) => {
689
- // Argument shape: `c8 deploy [path...]`. With no positional, default
690
- // to cwd. Pinned by tests/unit/deploy-behaviour.test.ts.
691
- const paths = ctx.resource
692
- ? [ctx.resource, ...ctx.positionals]
693
- : ctx.positionals.length > 0
694
- ? ctx.positionals
695
- : ["."];
696
- // Resolve the active extension allow-list from flags.
697
- // Priority: --force (no filtering) > --all-extensions > --extensions > default
698
- const extensionList = resolveExtensionList(flags);
699
- // Dry-run preview. Collect resources first so the preview body
700
- // reflects what would actually be sent — and so the empty-paths /
701
- // no-files guards still surface as thrown errors before we emit.
702
- // Uses `ctx.dryRun` and `ctx.tenantId` from the framework rather
703
- // than reaching into the global runtime/config layer.
704
- if (ctx.dryRun) {
705
- const { resources: previewResources, skippedExtensions } = collectResourcesForPaths(paths, flags.force, extensionList);
706
- logSkippedExtensions(skippedExtensions);
707
- const dr = dryRun({
708
- command: "deploy",
709
- method: "POST",
710
- endpoint: "/deployments",
711
- profile: ctx.profile,
712
- body: {
713
- tenantId: ctx.tenantId,
714
- resources: previewResources.map((r) => ({ name: r.name })),
715
- },
716
- });
717
- if (dr)
718
- return dr;
719
- }
720
- // Execute path: only reached when not in dry-run mode (the branch
721
- // above returns early). `deployResources` runs its own
722
- // `collectResourcesForPaths` internally and renders the success
723
- // table. Keeping the helper self-contained avoids threading
724
- // pre-collected state between the handler and the shared helper
725
- // used by `watch`.
726
- await deployResources(paths, {
727
- profile: ctx.profile,
728
- force: flags.force,
729
- extensionList,
730
- });
731
- return { kind: "none" };
732
- });
733
- //# sourceMappingURL=deployments.js.map
885
+ //# sourceMappingURL=deploy-helpers.js.map