@camunda8/cli 2.8.0-alpha.9 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/EXAMPLES.md +22 -5
  2. package/PLUGIN-HELP.md +26 -0
  3. package/README.md +37 -4
  4. package/dist/command-dispatch.d.ts.map +1 -1
  5. package/dist/command-dispatch.js +2 -1
  6. package/dist/command-dispatch.js.map +1 -1
  7. package/dist/command-registry.d.ts +30 -0
  8. package/dist/command-registry.d.ts.map +1 -1
  9. package/dist/command-registry.js +34 -1
  10. package/dist/command-registry.js.map +1 -1
  11. package/dist/commands/plugins.d.ts +21 -0
  12. package/dist/commands/plugins.d.ts.map +1 -1
  13. package/dist/commands/plugins.js +74 -1
  14. package/dist/commands/plugins.js.map +1 -1
  15. package/dist/commands/resource-extensions.d.ts +12 -0
  16. package/dist/commands/resource-extensions.d.ts.map +1 -1
  17. package/dist/commands/resource-extensions.js +13 -1
  18. package/dist/commands/resource-extensions.js.map +1 -1
  19. package/dist/commands/run.d.ts.map +1 -1
  20. package/dist/commands/run.js +5 -3
  21. package/dist/commands/run.js.map +1 -1
  22. package/dist/commands/watch.d.ts.map +1 -1
  23. package/dist/commands/watch.js +21 -12
  24. package/dist/commands/watch.js.map +1 -1
  25. package/dist/completion.d.ts.map +1 -1
  26. package/dist/completion.js +140 -13
  27. package/dist/completion.js.map +1 -1
  28. package/dist/default-plugins/bpmn/README.md +69 -0
  29. package/dist/default-plugins/bpmn/c8ctl-plugin.js +125 -0
  30. package/dist/default-plugins/bpmn/c8ctl-plugin.js.map +1 -0
  31. package/dist/default-plugins/bpmn/lint.js +259 -0
  32. package/dist/default-plugins/bpmn/lint.js.map +1 -0
  33. package/dist/default-plugins/bpmn/package.json +8 -0
  34. package/dist/default-plugins/cluster/package.json +1 -1
  35. package/dist/default-plugins/element-template/AGENTS.md +65 -0
  36. package/dist/default-plugins/element-template/README.md +331 -0
  37. package/dist/default-plugins/element-template/c8ctl-plugin.js +247 -0
  38. package/dist/default-plugins/element-template/c8ctl-plugin.js.map +1 -0
  39. package/dist/default-plugins/element-template/commands/apply.js +298 -0
  40. package/dist/default-plugins/element-template/commands/apply.js.map +1 -0
  41. package/dist/default-plugins/element-template/commands/get-properties.js +344 -0
  42. package/dist/default-plugins/element-template/commands/get-properties.js.map +1 -0
  43. package/dist/default-plugins/element-template/commands/get.js +107 -0
  44. package/dist/default-plugins/element-template/commands/get.js.map +1 -0
  45. package/dist/default-plugins/element-template/commands/info.js +189 -0
  46. package/dist/default-plugins/element-template/commands/info.js.map +1 -0
  47. package/dist/default-plugins/element-template/commands/search.js +101 -0
  48. package/dist/default-plugins/element-template/commands/search.js.map +1 -0
  49. package/dist/default-plugins/element-template/commands/sync.js +36 -0
  50. package/dist/default-plugins/element-template/commands/sync.js.map +1 -0
  51. package/dist/default-plugins/element-template/docs/design.md +145 -0
  52. package/dist/default-plugins/element-template/helpers.js +404 -0
  53. package/dist/default-plugins/element-template/helpers.js.map +1 -0
  54. package/dist/default-plugins/element-template/marketplace.js +396 -0
  55. package/dist/default-plugins/element-template/marketplace.js.map +1 -0
  56. package/dist/default-plugins/element-template/package.json +8 -0
  57. package/dist/default-plugins/element-template/template-ref.js +232 -0
  58. package/dist/default-plugins/element-template/template-ref.js.map +1 -0
  59. package/dist/default-plugins/element-template/vendor-src/bundle-entry.js +44 -0
  60. package/dist/default-plugins/feel/README.md +163 -0
  61. package/dist/default-plugins/feel/c8ctl-plugin.js +616 -0
  62. package/dist/default-plugins/feel/c8ctl-plugin.js.map +1 -0
  63. package/dist/default-plugins/feel/package.json +8 -0
  64. package/dist/deployments.d.ts +1 -0
  65. package/dist/deployments.d.ts.map +1 -1
  66. package/dist/deployments.js +89 -20
  67. package/dist/deployments.js.map +1 -1
  68. package/dist/help.d.ts.map +1 -1
  69. package/dist/help.js +156 -5
  70. package/dist/help.js.map +1 -1
  71. package/dist/ignore.d.ts +16 -1
  72. package/dist/ignore.d.ts.map +1 -1
  73. package/dist/ignore.js +55 -3
  74. package/dist/ignore.js.map +1 -1
  75. package/dist/index.d.ts +23 -0
  76. package/dist/index.d.ts.map +1 -1
  77. package/dist/index.js +294 -25
  78. package/dist/index.js.map +1 -1
  79. package/dist/plugin-loader.d.ts +168 -7
  80. package/dist/plugin-loader.d.ts.map +1 -1
  81. package/dist/plugin-loader.js +284 -21
  82. package/dist/plugin-loader.js.map +1 -1
  83. package/dist/runtime.d.ts +10 -0
  84. package/dist/runtime.d.ts.map +1 -1
  85. package/dist/runtime.js +6 -0
  86. package/dist/runtime.js.map +1 -1
  87. package/dist/vendor/bpmn-element-templates.cjs +59639 -0
  88. package/package.json +20 -7
@@ -0,0 +1,65 @@
1
+ # AGENTS.md — `element-template` plugin
2
+
3
+ Read [docs/design.md](./docs/design.md) before changing this plugin. It
4
+ covers the **why**: vendor bundle, marketplace endpoint choice, cache
5
+ strategy (`upstreamRef`-keyed dedup), lazy bootstrap, and semver-based
6
+ version resolution.
7
+
8
+ ## Where things live
9
+
10
+ | File | Purpose |
11
+ | --- | --- |
12
+ | `c8ctl-plugin.ts` | Plugin API (metadata + commands export), subcommand dispatch table |
13
+ | `commands/<name>.ts` | One file per subcommand: `apply`, `get`, `get-properties`, `info`, `search`, `sync` |
14
+ | `template-ref.ts` | `parseTemplateRef`, `readBpmnInput`, `getExecutionPlatformVersion`, `resolveOotbTemplate`, `loadTemplate` |
15
+ | `marketplace.ts` | Cache I/O, `/ootb-connectors` fetch, sync, search, version resolution |
16
+ | `helpers.ts` | `--set` parsing, file/URL fetch, glob → regex, multi-binding lookup, condition warnings |
17
+ | `vendor-src/bundle-entry.js` | esbuild entry — re-exports `Modeler`, `CloudElementTemplatesCoreModule`, `ZeebeModdleExtension` |
18
+
19
+ ## Things to know before editing
20
+
21
+ - **Touching anything bpmn-js related requires `npm run build:vendor`.**
22
+ The plugin loads `dist/vendor/bpmn-element-templates.cjs`, not the
23
+ source. `vendor-src/bundle-entry.js` is the only entry point that
24
+ esbuild bundles.
25
+ - **Cache file shape mirrors Desktop Modeler's
26
+ `.camunda-connector-templates.json`.** Don't change the format
27
+ without reason — `metadata.upstreamRef` is the dedup key for
28
+ incremental sync.
29
+ - **`get` deliberately does NOT auto-bootstrap.** Bootstrap progress
30
+ goes through `logger.info`, which writes to stdout in text mode —
31
+ that would corrupt `get <id> > template.json` redirects. Cache miss
32
+ surfaces as an explicit error pointing at `sync`. Don't add a
33
+ bootstrap call to `getSubcommand` without changing the logger story
34
+ first.
35
+ - **Path/URL apply paths must not trigger the index bootstrap.**
36
+ Detection happens in `parseTemplateRef()` in `template-ref.ts`
37
+ before any cache call.
38
+ - **JSON output uses element-templates schema field names verbatim.**
39
+ No invented derivations — `binding`, `optional`, `value`, `condition`,
40
+ `group` (id), `elementType: { value }`, `engines: { camunda }`. The
41
+ only c8ctl-internal extension is `metadata.upstreamRef`, which `get`
42
+ strips before serializing.
43
+ - **Property dedup is by object reference, not by `binding.name|type`.**
44
+ Template authors sometimes attach two properties with the same binding
45
+ name + type but different `condition` clauses (operation-conditional
46
+ duplicates); the engine drops inactive ones at apply time. The
47
+ WeakMap-based `sourceByDetail` side table in `loadTemplate` preserves
48
+ this identity so `get-properties` doesn't collapse them and `--set`
49
+ writes to all matching duplicates.
50
+ - **Marketplace endpoint URL is overridable via
51
+ `C8CTL_OOTB_ELEMENT_TEMPLATES_URL`** — useful for tests against a
52
+ local fixture server.
53
+
54
+ ## Testing
55
+
56
+ ```bash
57
+ npm run build:vendor && node --experimental-strip-types --test tests/unit/element-template.test.ts
58
+ ```
59
+
60
+ Smoke-test against the live marketplace (writes to a throwaway dir):
61
+
62
+ ```bash
63
+ C8CTL_DATA_DIR=/tmp/c8ctl-smoke node --experimental-strip-types src/index.ts \
64
+ element-template search "AWS S3"
65
+ ```
@@ -0,0 +1,331 @@
1
+ # c8ctl-plugin-element-template
2
+
3
+ A default [c8ctl](https://github.com/camunda/c8ctl) plugin for applying
4
+ Camunda element templates to BPMN diagrams, inspecting their properties,
5
+ and exporting raw template JSON. Supports out-of-the-box (OOTB)
6
+ connector templates by id (downloaded on demand from the Camunda
7
+ marketplace), plus arbitrary local paths and URLs.
8
+
9
+ ## Subcommands
10
+
11
+ The verb is organized as a workflow: discover → inspect → act → export → maintain.
12
+
13
+ | Subcommand | Purpose |
14
+ |------------|---------|
15
+ | `search <query>` | Find OOTB templates by keyword (deprecated entries hidden). |
16
+ | `info <template>` | Show the template metadata card (id, version, applies-to, engines, docs). |
17
+ | `get-properties <template> [<name>...]` | List settable properties — condensed by default, `--detailed` for full cards. |
18
+ | `apply <template> <element-id> [<file.bpmn>]` | Apply a template to a BPMN element (in place, or to stdout). |
19
+ | `get <template>` | Print the raw template JSON to stdout (pipe-friendly). |
20
+ | `sync` | Refresh the local OOTB template cache. |
21
+
22
+ `<template>` is a local path, an `https://` URL, or an OOTB template id
23
+ (optionally pinned: `<id>@<version>`). GitHub blob URLs are
24
+ auto-rewritten to raw content URLs — paste straight from the address bar.
25
+
26
+ ## Usage
27
+
28
+ ```bash
29
+ # Search OOTB templates
30
+ c8ctl element-template search "AWS S3"
31
+ c8ctl element-template search "http"
32
+ c8ctl element-template search "AWS" --limit 5 # cap results (default 20)
33
+
34
+ # Show the template metadata card
35
+ c8ctl element-template info io.camunda.connectors.HttpJson.v2
36
+
37
+ # List every settable property as a condensed name + description row
38
+ c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2
39
+
40
+ # Filter by name (positional, supports shell-style globs — quote them)
41
+ c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2 url method
42
+ c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2 'authentication.*'
43
+
44
+ # Filter by group id (repeatable; ids come from `get-properties` group headings)
45
+ c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2 \
46
+ --group authentication --group endpoint
47
+
48
+ # Drill into specific properties as full detail cards
49
+ c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2 \
50
+ --detailed authentication.token url
51
+
52
+ # Apply by OOTB id — version is auto-resolved against the BPMN's
53
+ # modeler:executionPlatformVersion (highest compatible version wins)
54
+ c8ctl element-template apply io.camunda.connectors.HttpJson.v2 \
55
+ ServiceTask_1 process.bpmn
56
+
57
+ # Pin a specific version
58
+ c8ctl element-template apply io.camunda.connectors.HttpJson.v2@13 \
59
+ ServiceTask_1 process.bpmn
60
+
61
+ # Apply from a local file or URL
62
+ c8ctl element-template apply ./templates/my-task.json ServiceTask_1 process.bpmn
63
+ c8ctl element-template apply https://example.com/template.json ServiceTask_1 process.bpmn
64
+
65
+ # GitHub blob URLs are auto-rewritten to the raw content URL
66
+ c8ctl element-template apply \
67
+ https://github.com/camunda/connectors/blob/main/connectors/http/rest/element-templates/http-json-connector.json \
68
+ ServiceTask_1 process.bpmn
69
+
70
+ # Modify the BPMN file in place (default writes the result to stdout)
71
+ c8ctl element-template apply -i io.camunda.connectors.HttpJson.v2 \
72
+ ServiceTask_1 process.bpmn
73
+
74
+ # Stream BPMN through stdin, get the modified BPMN on stdout. Works
75
+ # with slow upstream producers (lint, apply chained together, etc.) —
76
+ # stdin is consumed asynchronously and waits for the writer to finish.
77
+ cat process.bpmn | c8ctl element-template apply io.camunda.connectors.HttpJson.v2 ServiceTask_1 \
78
+ > out.bpmn
79
+
80
+ # Chain with bpmn lint
81
+ c8ctl element-template apply io.camunda.connectors.HttpJson.v2 ServiceTask_1 process.bpmn \
82
+ | c8ctl bpmn lint
83
+
84
+ # Save a template's raw JSON to a file (works for ids, URLs, and local paths)
85
+ c8ctl element-template get io.camunda.connectors.HttpJson.v2 > template.json
86
+ c8ctl element-template get https://example.com/template.json > template.json
87
+ c8ctl element-template get ./template.json > copy.json # passthrough — bytes preserved
88
+ c8ctl element-template get io.camunda.connectors.HttpJson.v2 --no-icon # drop the base64 icon blob
89
+
90
+ # Refresh the local OOTB template cache
91
+ c8ctl element-template sync
92
+ c8ctl element-template sync --prune # also drop entries no longer in the index
93
+ ```
94
+
95
+ ## Inspecting a template
96
+
97
+ `info` and `get-properties` separate the two questions an agent or human
98
+ typically asks of a template — *what is this thing?* (metadata) and
99
+ *what knobs can I turn?* (properties).
100
+
101
+ ### `info` — metadata card
102
+
103
+ ```bash
104
+ c8ctl element-template info io.camunda.connectors.HttpJson.v2
105
+ ```
106
+
107
+ ```
108
+ REST Outbound Connector
109
+ ID io.camunda.connectors.HttpJson.v2
110
+ Version 13 (latest; @<n> to pin)
111
+ Applies to bpmn:Task → bpmn:ServiceTask
112
+ Engines ^8.9
113
+ Description Invoke REST API
114
+ Docs https://docs.camunda.io/docs/components/connectors/protocol/rest/
115
+
116
+ For settable properties, run:
117
+ c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2
118
+ ```
119
+
120
+ When you give an OOTB id without `@<version>`, the auto-resolved version
121
+ is annotated with a dim `(latest; @<n> to pin)` parenthetical so you
122
+ know what was picked.
123
+
124
+ ### `get-properties` — condensed listing
125
+
126
+ The default density is one row per property: name + description, grouped
127
+ by template group. Group headings include the `id` for use with `--group`.
128
+
129
+ ```bash
130
+ c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2
131
+ ```
132
+
133
+ ```
134
+ Showing 28 of 28 properties.
135
+
136
+ Authentication (authentication)
137
+ authentication.type Choose the authentication type. Select 'None' if no authentication is necessary
138
+ authentication.token Bearer token
139
+ ...
140
+
141
+ HTTP endpoint (endpoint)
142
+ method Method
143
+ url URL
144
+ ...
145
+
146
+ Filter by name (supports globs):
147
+ c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2 'auth*' url
148
+ For full details on each property:
149
+ c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2 --detailed
150
+ ```
151
+
152
+ Positional names filter the listing — pass one or more names, with
153
+ optional shell-style globs. `--group <id>` (repeatable) intersects with
154
+ the name filter. Both filters error on no-match instead of silently
155
+ empty so typos surface.
156
+
157
+ ### `get-properties --detailed` — full cards
158
+
159
+ Same filter semantics, but every property is rendered as a keyed card
160
+ with its full descriptor:
161
+
162
+ ```bash
163
+ c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2 \
164
+ --detailed authentication.token
165
+ ```
166
+
167
+ ```
168
+ Showing 1 of 28 properties.
169
+
170
+ authentication.token (Authentication)
171
+ Id authentication.token
172
+ Type String
173
+ Required yes
174
+ FEEL optional
175
+ Binding zeebe:input
176
+ Description Bearer token
177
+ Active when authentication.type = "bearer"
178
+ ```
179
+
180
+ Cards surface everything `--set` needs to pick a value — type, required,
181
+ FEEL support, binding, full active-when expression, pattern + error
182
+ message, and the choice list for dropdowns.
183
+
184
+ ### Machine-readable output
185
+
186
+ Switch the session into JSON mode and the same commands emit shapes
187
+ that mirror the text output (and use upstream
188
+ [element-templates JSON schema](https://unpkg.com/@camunda/zeebe-element-templates-json-schema)
189
+ field names verbatim — no invented names like `bindingType` or
190
+ `required`):
191
+
192
+ ```bash
193
+ c8ctl output json
194
+ c8ctl element-template info io.camunda.connectors.HttpJson.v2
195
+ # → {"name":"REST Outbound Connector","id":"io.camunda.connectors.HttpJson.v2",
196
+ # "version":13,"description":"Invoke REST API",
197
+ # "documentationRef":"https://docs.camunda.io/...",
198
+ # "appliesTo":["bpmn:Task"],"elementType":{"value":"bpmn:ServiceTask"},
199
+ # "engines":{"camunda":"^8.9"}}
200
+
201
+ c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2 url
202
+ # → {"count":1,"total":28,"groups":[{"id":"authentication","label":"Authentication"}, ...],
203
+ # "properties":[{"id":"url","binding":{"name":"url","type":"zeebe:input"},
204
+ # "label":"URL","group":"endpoint"}]}
205
+
206
+ c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2 \
207
+ --detailed authentication.token
208
+ # → {"count":1,"total":28,"groups":[...],
209
+ # "properties":[{"id":"authentication.token",
210
+ # "binding":{"name":"authentication.token","type":"zeebe:input"},
211
+ # "type":"String","optional":false,"feel":"optional","group":"authentication",
212
+ # "condition":{"property":"authentication.type","equals":"bearer","type":"simple"},
213
+ # "label":"Bearer token","constraints":{"notEmpty":true}}]}
214
+ ```
215
+
216
+ `get-properties` JSON keeps the same `{ count, total, groups, properties }`
217
+ envelope across both density modes — `count` is rendered properties,
218
+ `total` is the unfiltered count, `groups` is the full group table so
219
+ consumers can resolve any group id (not just those of rendered properties).
220
+
221
+ ## Setting input mappings with `--set`
222
+
223
+ `apply` supports repeatable `--set key=value` flags to populate
224
+ template properties at apply time — input mappings, output mappings,
225
+ task headers, task definitions, and arbitrary template properties.
226
+ Use it to wire up a connector in one shot from the CLI:
227
+
228
+ ```bash
229
+ # Apply the HTTP JSON connector and configure the request inline
230
+ c8ctl element-template apply -i io.camunda.connectors.HttpJson.v2 \
231
+ ServiceTask_1 process.bpmn \
232
+ --set authentication.type=noAuth \
233
+ --set method=POST \
234
+ --set url=https://api.example.com/v1/orders \
235
+ --set body='={ "orderId": orderId, "amount": 42 }' \
236
+ --set resultExpression='={ "status": response.statusCode }'
237
+ ```
238
+
239
+ ### How `--set` resolves a name
240
+
241
+ `key` is matched against the template's settable property
242
+ **binding names** (the field a template property writes to in the
243
+ resulting BPMN). Discover them with `get-properties`, then pick a value
244
+ using the badges on the detail card (Required, FEEL, Default, Active when).
245
+
246
+ ### Disambiguation prefixes
247
+
248
+ When the same name lives on multiple binding types (e.g. an `input` and
249
+ a `header` both called `correlationKey`), prefix the key with the
250
+ binding type:
251
+
252
+ | Prefix | Binding type |
253
+ |---------------------|------------------------|
254
+ | `input:` | `zeebe:input` |
255
+ | `output:` | `zeebe:output` |
256
+ | `header:` | `zeebe:taskHeader` |
257
+ | `property:` | `zeebe:property` |
258
+ | `taskDefinition:` | `zeebe:taskDefinition` |
259
+
260
+ ```bash
261
+ --set input:correlationKey='=order.id'
262
+ --set header:correlationKey=staticHeaderValue
263
+ ```
264
+
265
+ The plugin errors with the list of qualified names when a bare key is
266
+ ambiguous, and with the list of available property names when the key
267
+ is unknown.
268
+
269
+ When two settable properties share the same binding name **and** binding
270
+ type but differ by `condition` (template authors use this for
271
+ operation-conditional duplicates), `--set` writes to all of them — the
272
+ engine drops the inactive duplicates at runtime.
273
+
274
+ ### Conditional properties
275
+
276
+ Templates often hide properties behind a "show this only when X" rule
277
+ (e.g. `authentication.username` is conditional on
278
+ `authentication.type=basic`). `--set` first sets the dependency, then
279
+ follow-up properties:
280
+
281
+ ```bash
282
+ c8ctl element-template apply io.camunda.connectors.HttpJson.v2 \
283
+ ServiceTask_1 process.bpmn \
284
+ --set authentication.type=basic \
285
+ --set authentication.username=alice \
286
+ --set authentication.password=secret \
287
+ --set method=GET \
288
+ --set url=https://api.example.com/me
289
+ ```
290
+
291
+ If a `--set` targets a property whose condition is unmet, you'll get a
292
+ warning at the end (the property won't be applied).
293
+
294
+ ## How OOTB templates are resolved
295
+
296
+ 1. **Index**: fetched from the Camunda marketplace
297
+ (`https://marketplace.cloud.camunda.io/api/v1/ootb-connectors`) — the
298
+ same source Desktop Modeler uses. Override via
299
+ `C8CTL_OOTB_ELEMENT_TEMPLATES_URL` for testing.
300
+ 2. **First use** of `search`, `info`, `get-properties`, `apply`, or
301
+ `sync`: a one-shot bootstrap downloads ~459 templates with visible
302
+ progress; per-template failures are logged but don't abort the run.
303
+ 3. **`get` does NOT auto-bootstrap.** It exits with a hint to run
304
+ `sync` first if the cache is missing — bootstrap progress would
305
+ otherwise corrupt redirected stdout (`get <id> > template.json`).
306
+ 4. **Local file or URL** template args (paths containing `/` or `\`,
307
+ starting with `.`, ending in `.json`, or starting with `http(s)://`)
308
+ skip the index entirely.
309
+ 5. **Version selection** uses `semver.satisfies` against the BPMN's
310
+ `modeler:executionPlatformVersion` and each template's
311
+ `engines.camunda` constraint. Without `@<version>`, the highest
312
+ compatible version wins.
313
+ 6. **Stale cache** (>7 days) prints a hint to run `sync`. No automatic
314
+ refresh — `sync` only fetches refs not already cached (commit-pinned
315
+ URLs make incremental sync free).
316
+
317
+ ### Cache locations
318
+
319
+ | Platform | Path |
320
+ |----------|------|
321
+ | macOS | `~/Library/Application Support/c8ctl/element-templates/` |
322
+ | Linux | `${XDG_CONFIG_HOME:-~/.config}/c8ctl/element-templates/` |
323
+ | Windows | `%APPDATA%\c8ctl\element-templates\` |
324
+
325
+ Set `C8CTL_DATA_DIR` to override.
326
+
327
+ ## Design
328
+
329
+ See [`docs/design.md`](./docs/design.md) for the full reasoning behind
330
+ the marketplace endpoint choice, the vendor bundle, the cache strategy
331
+ (mirrored from Desktop Modeler), and version resolution.
@@ -0,0 +1,247 @@
1
+ /**
2
+ * c8ctl-plugin-element-template
3
+ *
4
+ * Apply Camunda element templates to BPMN elements and inspect template properties.
5
+ *
6
+ * Usage:
7
+ * c8ctl element-template apply <template> <element-id> [<file.bpmn>] [--in-place] [--set key=value]
8
+ * c8ctl element-template info <template>
9
+ * c8ctl element-template get-properties <template> [<name>...] [--group <id>] [--detailed]
10
+ * c8ctl element-template get <template>
11
+ * c8ctl element-template search <query>
12
+ * c8ctl element-template sync [--prune]
13
+ *
14
+ * <template> can be a local path, an https:// URL, or an OOTB template id
15
+ * (optionally pinned, e.g. io.camunda.connectors.HttpJson.v2@13).
16
+ * GitHub blob URLs are auto-rewritten to raw.githubusercontent.com.
17
+ */
18
+ import { applySubcommand } from "./commands/apply.js";
19
+ import { getSubcommand } from "./commands/get.js";
20
+ import { getPropertiesSubcommand } from "./commands/get-properties.js";
21
+ import { infoSubcommand } from "./commands/info.js";
22
+ import { searchSubcommand } from "./commands/search.js";
23
+ import { syncSubcommand } from "./commands/sync.js";
24
+ if (!globalThis.c8ctl)
25
+ throw new Error("c8ctl runtime not initialised");
26
+ const c8ctl = globalThis.c8ctl;
27
+ /**
28
+ * Reinject flags pre-parsed by the host (#366/#367) back into the args
29
+ * array as `--name value` / `--name` tokens, so the plugin's hand-rolled
30
+ * `parseArgs` still sees them. Repeated string flags arrive as arrays.
31
+ */
32
+ function injectFlagsIntoArgs(args, flags) {
33
+ const out = [...args];
34
+ if (!flags) {
35
+ return out;
36
+ }
37
+ for (const [name, value] of Object.entries(flags)) {
38
+ if (value === undefined || value === null) {
39
+ continue;
40
+ }
41
+ if (typeof value === "boolean") {
42
+ if (value) {
43
+ out.push(`--${name}`);
44
+ }
45
+ }
46
+ else if (Array.isArray(value)) {
47
+ for (const item of value) {
48
+ if (item !== undefined && item !== null) {
49
+ out.push(`--${name}`, String(item));
50
+ }
51
+ }
52
+ }
53
+ else {
54
+ out.push(`--${name}`, String(value));
55
+ }
56
+ }
57
+ return out;
58
+ }
59
+ /**
60
+ * Exhaustive dispatch table. The `Record<Subcommand, ...>` constraint
61
+ * makes adding a metadata subcommand without a matching handler a type
62
+ * error.
63
+ */
64
+ const subcommandHandlers = {
65
+ search: searchSubcommand,
66
+ info: infoSubcommand,
67
+ "get-properties": getPropertiesSubcommand,
68
+ apply: applySubcommand,
69
+ get: getSubcommand,
70
+ sync: syncSubcommand,
71
+ };
72
+ function isSubcommand(name) {
73
+ return Object.hasOwn(subcommandHandlers, name);
74
+ }
75
+ async function elementTemplateHandler(args, flags) {
76
+ const reinjected = injectFlagsIntoArgs(args ?? [], flags);
77
+ const subcommand = reinjected[0];
78
+ const subArgs = reinjected.slice(1);
79
+ if (!subcommand || !isSubcommand(subcommand)) {
80
+ const logger = c8ctl.getLogger();
81
+ const lead = subcommand
82
+ ? `Unknown subcommand '${subcommand}'.`
83
+ : "c8ctl element-template requires a subcommand.";
84
+ const validSubcommands = Object.keys(subcommandHandlers);
85
+ logger.info(`${lead} Available: ${validSubcommands.join(", ")}`);
86
+ logger.info("Run 'c8ctl element-template --help' for full usage.");
87
+ process.exitCode = 1;
88
+ return;
89
+ }
90
+ try {
91
+ await subcommandHandlers[subcommand](subArgs);
92
+ }
93
+ catch (error) {
94
+ const message = error instanceof Error ? error.message : String(error);
95
+ const logger = c8ctl.getLogger();
96
+ logger.error(`Failed to element-template ${subcommand}: ${message}`);
97
+ process.exitCode = 1;
98
+ }
99
+ }
100
+ // ---------------------------------------------------------------------------
101
+ // Plugin API
102
+ // ---------------------------------------------------------------------------
103
+ export const metadata = {
104
+ name: "element-template",
105
+ description: "Apply, inspect, and export Camunda element templates",
106
+ commands: {
107
+ "element-template": {
108
+ description: "Apply, inspect, and export Camunda element templates",
109
+ helpDescription: "Apply Camunda element templates to BPMN elements, inspect template metadata and properties, " +
110
+ "search the out-of-the-box template catalogue, export raw template JSON, " +
111
+ "and manage the local template cache.\n\n" +
112
+ "<template> is a local path, an https:// URL, or an OOTB template id (optionally @<version>).\n\n" +
113
+ "apply --set name=value targets a property by binding name (run `get-properties` to discover names). " +
114
+ "Pass --set multiple times to set multiple properties. " +
115
+ "Prefix with a binding type (input | output | header | property | taskDefinition) when the same name " +
116
+ "is bound across multiple types — e.g. --set input:correlationKey=order-42.",
117
+ subcommands: [
118
+ {
119
+ name: "search",
120
+ description: "Search out-of-the-box element templates",
121
+ },
122
+ {
123
+ name: "info",
124
+ description: "Show template metadata (id, version, applies-to, description) and a pointer to get-properties",
125
+ },
126
+ {
127
+ name: "get-properties",
128
+ description: "List settable properties (use --detailed for full detail cards)",
129
+ },
130
+ {
131
+ name: "apply",
132
+ description: "Apply a Camunda element template to a BPMN element",
133
+ },
134
+ {
135
+ name: "get",
136
+ description: "Print the raw template JSON to stdout (pipe-friendly)",
137
+ },
138
+ {
139
+ name: "sync",
140
+ description: "Refresh the local OOTB element template cache",
141
+ },
142
+ ],
143
+ examples: [
144
+ {
145
+ command: 'c8ctl element-template search "AWS S3"',
146
+ description: "Search OOTB templates by name",
147
+ },
148
+ {
149
+ command: 'c8ctl element-template search "AWS" --limit 5',
150
+ description: "Cap the number of results (default 20)",
151
+ },
152
+ {
153
+ command: "c8ctl element-template info io.camunda.connectors.HttpJson.v2",
154
+ description: "Show the template metadata card (id, version, applies-to, engines, docs)",
155
+ },
156
+ {
157
+ command: "c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2",
158
+ description: "List every settable property as a condensed name + description row",
159
+ },
160
+ {
161
+ command: "c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2 --detailed 'authentication.*'",
162
+ description: "Drill into specific properties as full detail cards (quote globs to avoid shell expansion)",
163
+ },
164
+ {
165
+ command: "c8ctl element-template get-properties io.camunda.connectors.HttpJson.v2 --group authentication --group endpoint",
166
+ description: "Filter to one or more group ids (use the id, not the label — group ids appear as headings in `get-properties` output)",
167
+ },
168
+ {
169
+ command: "c8ctl element-template apply io.camunda.connectors.HttpJson.v2 Task_1 process.bpmn",
170
+ description: "Apply an OOTB template (latest compatible with the BPMN engine version)",
171
+ },
172
+ {
173
+ command: "c8ctl element-template apply io.camunda.connectors.HttpJson.v2@13 Task_1 process.bpmn",
174
+ description: "Apply a specific OOTB template version",
175
+ },
176
+ {
177
+ command: "c8ctl element-template apply template.json Task_1 process.bpmn",
178
+ description: "Apply a template from a local file or URL",
179
+ },
180
+ {
181
+ command: "c8ctl element-template apply io.camunda.connectors.HttpJson.v2 Task_1 process.bpmn --set method=POST --set url=https://api.example.com",
182
+ description: "Set property values via --set name=value (one per --set; discover names via get-properties)",
183
+ },
184
+ {
185
+ command: "c8ctl element-template apply io.camunda.connectors.HttpJson.v2 Task_1 process.bpmn --set authentication.type=basic --set authentication.username=alice",
186
+ description: "Conditional properties: child controls (e.g. authentication.username) apply only when the gating property is also set",
187
+ },
188
+ {
189
+ command: "c8ctl element-template apply io.camunda.connectors.HttpJson.v2 Task_1 process.bpmn --set input:method=POST",
190
+ description: "Qualify with <binding-type>:name=value when the same name is bound across multiple types",
191
+ },
192
+ {
193
+ command: "c8ctl element-template get io.camunda.connectors.HttpJson.v2 > template.json",
194
+ description: "Print the raw template JSON to stdout (redirect to save a copy)",
195
+ },
196
+ {
197
+ command: "c8ctl element-template get io.camunda.connectors.HttpJson.v2 --no-icon",
198
+ description: "Drop the icon field (large base64 blob) for pipe-friendly output",
199
+ },
200
+ {
201
+ command: "c8ctl element-template sync",
202
+ description: "Refresh the local OOTB element template cache",
203
+ },
204
+ ],
205
+ },
206
+ },
207
+ };
208
+ export const commands = {
209
+ "element-template": {
210
+ flags: {
211
+ "in-place": {
212
+ type: "boolean",
213
+ short: "i",
214
+ description: "Modify the BPMN file in place [apply]",
215
+ },
216
+ set: {
217
+ type: "string",
218
+ multiple: true,
219
+ description: "Set a property value: name=value (repeatable; binding name from get-properties) [apply]",
220
+ },
221
+ detailed: {
222
+ type: "boolean",
223
+ short: "d",
224
+ description: "Render full detail cards instead of the condensed list [get-properties]",
225
+ },
226
+ group: {
227
+ type: "string",
228
+ multiple: true,
229
+ description: "Filter to one or more group ids (repeatable) [get-properties]",
230
+ },
231
+ prune: {
232
+ type: "boolean",
233
+ description: "Drop cached entries no longer in the index [sync]",
234
+ },
235
+ "no-icon": {
236
+ type: "boolean",
237
+ description: "Drop the icon field (often a large base64 blob) from the output [get]",
238
+ },
239
+ limit: {
240
+ type: "string",
241
+ description: "Cap the number of matches (default 20) [search]",
242
+ },
243
+ },
244
+ handler: elementTemplateHandler,
245
+ },
246
+ };
247
+ //# sourceMappingURL=c8ctl-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"c8ctl-plugin.js","sourceRoot":"","sources":["../../../default-plugins/element-template/c8ctl-plugin.ts"],"names":[],"mappings":"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"}